diff --git a/bombsquad_server b/bombsquad_server new file mode 100644 index 0000000..939b429 --- /dev/null +++ b/bombsquad_server @@ -0,0 +1,912 @@ +#!/usr/bin/env -S python3.10 -O + +# Released under the MIT License. See LICENSE for details. + +from __future__ import annotations +import os,signal,subprocess, sys, time, _thread, logging, platform, shutil, json +from pathlib import Path +from threading import Lock, Thread, current_thread, Timer +from typing import TYPE_CHECKING +from nbstreamreader import NonBlockingStreamReader as NBSR +from datetime import datetime +#import requests + +ERROR_LOGGING=False + +def migrate_to_aarch(): + maps = ["BridgitMash.so","FloatingIsland.so","InTheAir.so"] + games = ["CanonFight.so","DuelElimination.so","FlappyBird.so","LaserTracer.so","MonkeyClimb.so","OneNightNoStand.so","RealSoccer.so", + "SquidRace.so","StumbleRace.so","SubwayRun.so","UFOAttackGame.so"] + features = ["StumbledScoreScreen.so"] + tools = ["corelib.so"] + root = os.path.realpath(".")+"/dist/ba_root" + for map in maps: + shutil.copy(root+"/mods/aarch64/"+map,root+'/mods/maps/'+map) + for game in games: + shutil.copyfile(root+"/mods/aarch64/"+game,root+'/mods/games/'+game) + for f in features: + shutil.copyfile(root+"/mods/aarch64/"+f,root+'/mods/features/'+f) + for t in tools: + shutil.copyfile(root+"/mods/aarch64/"+t,root+'/mods/tools/'+t) + with open(".we_are_good","w") as f: + pass + +# by default we have x86_64 setup +# if we found aarch64 system copy required files +if platform.processor() == 'aarch64': + print("We are on aarch64 system") + if os.path.exists(".we_are_good"): + pass + else: + migrate_to_aarch() + +# We make use of the bacommon and efro packages as well as site-packages +# included with our bundled Ballistica dist, so we need to add those paths +# before we import them. +sys.path += [ + str(Path(Path(__file__).parent, 'dist', 'ba_data', 'python')), + str(Path(Path(__file__).parent, 'dist', 'ba_data', 'python-site-packages')) +] + +from bacommon.servermanager import ServerConfig, StartServerModeCommand +from efro.dataclassio import dataclass_from_dict, dataclass_validate +from efro.error import CleanError +from efro.terminal import Clr + +if TYPE_CHECKING: + from typing import Optional, Union + from types import FrameType + from bacommon.servermanager import ServerCommand + +VERSION_STR = '1.3' +print("----------------------------------------------------------------------------------------------------------------------------------------") +print() + + +class ServerManagerApp: + """ An app which manages BallisticaCore server execution. + + Handles configuring, launching, re-launching, and otherwise + managing BallisticaCore operating in server mode. + """ + + # How many seconds we wait after asking our subprocess to do an immediate + # shutdown before bringing down the hammer. + IMMEDIATE_SHUTDOWN_TIME_LIMIT = 5.0 + + def __init__(self) -> None: + self._config_path = 'config.yaml' + self._user_provided_config_path = False + self._config = ServerConfig() + self._ba_root_path = os.path.abspath('dist/ba_root') + self._interactive = sys.stdin.isatty() + self._wrapper_shutdown_desired = False + self._done = False + self._subprocess_commands: list[Union[str, ServerCommand]] = [] + self._subprocess_commands_lock = Lock() + self._subprocess_force_kill_time: Optional[float] = None + self._auto_restart = True + self._config_auto_restart = True + self._config_mtime: Optional[float] = None + self._last_config_mtime_check_time: Optional[float] = None + self._should_report_subprocess_error = False + self._running = False + self._interpreter_start_time: Optional[float] = None + self._subprocess: Optional[subprocess.Popen[bytes]] = None + self._subprocess_launch_time: Optional[float] = None + self._subprocess_sent_config_auto_restart = False + self._subprocess_sent_clean_exit = False + self._subprocess_sent_unclean_exit = False + self._subprocess_thread: Optional[Thread] = None + self._subprocess_exited_cleanly: Optional[bool] = None + self.nbsr = None + # This may override the above defaults. + self._parse_command_line_args() + + # Do an initial config-load. If the config is invalid at this point + # we can cleanly die (we're more lenient later on reloads). + self.load_config(strict=True, print_confirmation=False) + + @property + def config(self) -> ServerConfig: + """The current config for the app.""" + return self._config + + @config.setter + def config(self, value: ServerConfig) -> None: + dataclass_validate(value) + self._config = value + + def _prerun(self) -> None: + """Common code at the start of any run.""" + + # Make sure we don't call run multiple times. + if self._running: + raise RuntimeError('Already running.') + self._running = True + + dbgstr = 'debug' if __debug__ else 'opt' + logging.info(f'{Clr.CYN}{Clr.BLD}ROCKY AND VORTEX OFFICIAL is {VERSION_STR}' + f' starting up in ({dbgstr} mode).{Clr.RST}') + + # Python will handle SIGINT for us (as KeyboardInterrupt) but we + # need to register a SIGTERM handler so we have a chance to clean + # up our subprocess when someone tells us to die. (and avoid + # zombie processes) + signal.signal(signal.SIGTERM, self._handle_term_signal) + + # During a run, we make the assumption that cwd is the dir + # containing this script, so make that so. Up until now that may + # not be the case (we support being called from any location). + os.chdir(os.path.abspath(os.path.dirname(__file__))) + + # Fire off a background thread to wrangle our server binaries. + self._subprocess_thread = Thread(target=self._bg_thread_main) + self._subprocess_thread.start() + + def _postrun(self) -> None: + """Common code at the end of any run.""" + logging.info(f"{Clr.RED}{Clr.BLD}Server is shutting down.. Please wait!{Clr.RST}") + + assert self._subprocess_thread is not None + if self._subprocess_thread.is_alive(): + logging.info(f"{Clr.RED}{Clr.BLD}Killing all subprocess safely..{Clr.RST}") + + # Mark ourselves as shutting down and wait for the process to wrap up. + self._done = True + self._subprocess_thread.join() + + # If there's a server error we should care about, exit the + # entire wrapper uncleanly. + if self._should_report_subprocess_error: + raise CleanError('Server subprocess exited uncleanly.') + + def run(self) -> None: + """Do the thing.""" + if self._interactive: + self._run_interactive() + else: + self._run_noninteractive() + + def _run_noninteractive(self) -> None: + """Run the app loop to completion noninteractively.""" + self._prerun() + try: + while True: + time.sleep(1.234) + except KeyboardInterrupt: + # Gracefully bow out if we kill ourself via keyboard. + pass + except SystemExit: + # We get this from the builtin quit(), our signal handler, etc. + # Need to catch this so we can clean up, otherwise we'll be + # left in limbo with our process thread still running. + pass + self._postrun() + + def _run_interactive(self) -> None: + """Run the app loop to completion interactively.""" + import code + self._prerun() + + # Print basic usage info for interactive mode. + logging.info(f"{Clr.CYN}{Clr.BLD}Interactive mode enabled use the 'mgr' object to interact with the server. Type 'help(mgr)' for more information.{Clr.RST}") + context = {'__name__': '__console__', '__doc__': None, 'mgr': self} + + # Enable tab-completion if possible. + self._enable_tab_completion(context) + + # Now just sit in an interpreter. + # TODO: make it possible to use IPython if the user has it available. + try: + self._interpreter_start_time = time.time() + code.interact(local=context, banner='', exitmsg='') + except SystemExit: + # We get this from the builtin quit(), our signal handler, etc. + # Need to catch this so we can clean up, otherwise we'll be + # left in limbo with our process thread still running. + pass + except BaseException as exc: + print( + f'Unexpected interpreter exception:' + f' {exc} ({type(exc)})', + flush=True) + + self._postrun() + + def cmd(self, statement: str) -> None: + """Exec a Python command on the current running server subprocess. + + Note that commands are executed asynchronously and no status or + return value is accessible from this manager app. + """ + if not isinstance(statement, str): + raise TypeError(f'Expected a string arg; got {type(statement)}') + with self._subprocess_commands_lock: + self._subprocess_commands.append(statement) + self._block_for_command_completion() + + def _block_for_command_completion(self) -> None: + # Ideally we'd block here until the command was run so our prompt would + # print after it's results. We currently don't get any response from + # the app so the best we can do is block until our bg thread has sent + # it. In the future we can perhaps add a proper 'command port' + # interface for proper blocking two way communication. + while True: + with self._subprocess_commands_lock: + if not self._subprocess_commands: + break + time.sleep(0.1) + + # One last short delay so if we come out *just* as the command is sent + # we'll hopefully still give it enough time to process/print. + time.sleep(0.1) + + def screenmessage(self, + message: str, + color: Optional[tuple[float, float, float]] = None, + clients: Optional[list[int]] = None) -> None: + """Display a screen-message. + + This will have no name attached and not show up in chat history. + They will show up in replays, however (unless clients is passed). + """ + from bacommon.servermanager import ScreenMessageCommand + self._enqueue_server_command( + ScreenMessageCommand(message=message, color=color, + clients=clients)) + + def chatmessage(self, + message: str, + clients: Optional[list[int]] = None) -> None: + """Send a chat message from the server. + + This will have the server's name attached and will be logged + in client chat windows, just like other chat messages. + """ + from bacommon.servermanager import ChatMessageCommand + self._enqueue_server_command( + ChatMessageCommand(message=message, clients=clients)) + + def clientlist(self) -> None: + """Print a list of connected clients.""" + from bacommon.servermanager import ClientListCommand + self._enqueue_server_command(ClientListCommand()) + self._block_for_command_completion() + + def kick(self, client_id: int, ban_time: Optional[int] = None) -> None: + """Kick the client with the provided id. + + If ban_time is provided, the client will be banned for that + length of time in seconds. If it is None, ban duration will + be determined automatically. Pass 0 or a negative number for no + ban time. + """ + from bacommon.servermanager import KickCommand + self._enqueue_server_command( + KickCommand(client_id=client_id, ban_time=ban_time)) + + def restart(self, immediate: bool = True) -> None: + """Restart the server subprocess. + + By default, the current server process will exit immediately. + If 'immediate' is passed as False, however, it will instead exit at + the next clean transition point (the end of a series, etc). + """ + from bacommon.servermanager import ShutdownCommand, ShutdownReason + self._enqueue_server_command( + ShutdownCommand(reason=ShutdownReason.RESTARTING, + immediate=immediate)) + + # If we're asking for an immediate restart but don't get one within + # the grace period, bring down the hammer. + if immediate: + self._subprocess_force_kill_time = ( + time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT) + + def shutdown(self, immediate: bool = True) -> None: + """Shut down the server subprocess and exit the wrapper. + + By default, the current server process will exit immediately. + If 'immediate' is passed as False, however, it will instead exit at + the next clean transition point (the end of a series, etc). + """ + from bacommon.servermanager import ShutdownCommand, ShutdownReason + self._enqueue_server_command( + ShutdownCommand(reason=ShutdownReason.NONE, immediate=immediate)) + + # An explicit shutdown means we know to bail completely once this + # subprocess completes. + self._wrapper_shutdown_desired = True + + # If we're asking for an immediate shutdown but don't get one within + # the grace period, bring down the hammer. + if immediate: + self._subprocess_force_kill_time = ( + time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT) + + def _parse_command_line_args(self) -> None: + """Parse command line args.""" + # pylint: disable=too-many-branches + + i = 1 + argc = len(sys.argv) + did_set_interactive = False + while i < argc: + arg = sys.argv[i] + if arg == '--help': + self.print_help() + sys.exit(0) + elif arg == '--config': + if i + 1 >= argc: + raise CleanError('Expected a config path as next arg.') + path = sys.argv[i + 1] + if not os.path.exists(path): + raise CleanError( + f"Supplied path does not exist: '{path}'.") + # We need an abs path because we may be in a different + # cwd currently than we will be during the run. + self._config_path = os.path.abspath(path) + self._user_provided_config_path = True + i += 2 + elif arg == '--root': + if i + 1 >= argc: + raise CleanError('Expected a path as next arg.') + path = sys.argv[i + 1] + # Unlike config_path, this one doesn't have to exist now. + # We do however need an abs path because we may be in a + # different cwd currently than we will be during the run. + self._ba_root_path = os.path.abspath(path) + i += 2 + elif arg == '--interactive': + if did_set_interactive: + raise CleanError('interactive/noninteractive can only' + ' be specified once.') + self._interactive = True + did_set_interactive = True + i += 1 + elif arg == '--noninteractive': + if did_set_interactive: + raise CleanError('interactive/noninteractive can only' + ' be specified once.') + self._interactive = False + did_set_interactive = True + i += 1 + elif arg == '--no-auto-restart': + self._auto_restart = False + i += 1 + elif arg == '--no-config-auto-restart': + self._config_auto_restart = False + i += 1 + else: + raise CleanError(f"Invalid arg: '{arg}'.") + + @classmethod + def _par(cls, txt: str) -> str: + """Spit out a pretty paragraph for our help text.""" + import textwrap + ind = ' ' * 2 + out = textwrap.fill(txt, 80, initial_indent=ind, subsequent_indent=ind) + return f'{out}\n' + + @classmethod + def print_help(cls) -> None: + """Print app help.""" + filename = os.path.basename(__file__) + out = ( + f'{Clr.BLD}{filename} usage:{Clr.RST}\n' + cls._par( + 'This script handles configuring, launching, re-launching,' + ' and otherwise managing BallisticaCore operating' + ' in server mode. It can be run with no arguments, but' + ' accepts the following optional ones:') + f'\n' + f'{Clr.BLD}--help:{Clr.RST}\n' + f' Show this help.\n' + f'\n' + f'{Clr.BLD}--config [path]{Clr.RST}\n' + cls._par( + 'Set the config file read by the server script. The config' + ' file contains most options for what kind of game to host.' + ' It should be in yaml format. Note that yaml is backwards' + ' compatible with json so you can just write json if you' + ' want to. If not specified, the script will look for a' + ' file named \'config.yaml\' in the same directory as the' + ' script.') + '\n' + f'{Clr.BLD}--root [path]{Clr.RST}\n' + cls._par( + 'Set the ballistica root directory. This is where the server' + ' binary will read and write its caches, state files,' + ' downloaded assets to, etc. It needs to be a writable' + ' directory. If not specified, the script will use the' + ' \'dist/ba_root\' directory relative to itself.') + '\n' + f'{Clr.BLD}--interactive{Clr.RST}\n' + f'{Clr.BLD}--noninteractive{Clr.RST}\n' + cls._par( + 'Specify whether the script should run interactively.' + ' In interactive mode, the script creates a Python interpreter' + ' and reads commands from stdin, allowing for live interaction' + ' with the server. The server script will then exit when ' + 'end-of-file is reached in stdin. Noninteractive mode creates' + ' no interpreter and is more suited to being run in automated' + ' scenarios. By default, interactive mode will be used if' + ' a terminal is detected and noninteractive mode otherwise.') + + '\n' + f'{Clr.BLD}--no-auto-restart{Clr.RST}\n' + + cls._par('Auto-restart is enabled by default, which means the' + ' server manager will restart the server binary whenever' + ' it exits (even when uncleanly). Disabling auto-restart' + ' will cause the server manager to instead exit after a' + ' single run and also to return error codes if the' + ' server binary did so.') + '\n' + f'{Clr.BLD}--no-config-auto-restart{Clr.RST}\n' + cls._par( + 'By default, when auto-restart is enabled, the server binary' + ' will be automatically restarted if changes to the server' + ' config file are detected. This disables that behavior.')) + print(out) + + def load_config(self, strict: bool, print_confirmation: bool) -> None: + """Load the config. + + If strict is True, errors will propagate upward. + Otherwise, warnings will be printed and repeated attempts will be + made to load the config. Eventually the function will give up + and leave the existing config as-is. + """ + retry_seconds = 3 + maxtries = 11 + for trynum in range(maxtries): + try: + self._config = self._load_config_from_file( + print_confirmation=print_confirmation) + return + except Exception as exc: + if strict: + raise CleanError( + f'Error loading config file:\n{exc}') from exc + print(f'{Clr.RED}Error loading config file:\n{exc}.{Clr.RST}', + flush=True) + if trynum == maxtries - 1: + print( + f'{Clr.RED}Max-tries reached; giving up.' + f' Existing config values will be used.{Clr.RST}', + flush=True) + break + print( + f'{Clr.CYN}Please correct the error.' + f' Will re-attempt load in {retry_seconds}' + f' seconds. (attempt {trynum + 1} of' + f' {maxtries - 1}).{Clr.RST}', + flush=True) + + for _j in range(retry_seconds): + # If the app is trying to die, drop what we're doing. + if self._done: + return + time.sleep(1) + + def _load_config_from_file(self, print_confirmation: bool) -> ServerConfig: + + out: Optional[ServerConfig] = None + + if not os.path.exists(self._config_path): + + # Special case: + # If the user didn't specify a particular config file, allow + # gracefully falling back to defaults if the default one is + # missing. + if not self._user_provided_config_path: + if print_confirmation: + print( + f'{Clr.YLW}Default config file not found' + f' (\'{self._config_path}\'); using default' + f' settings.{Clr.RST}', + flush=True) + self._config_mtime = None + self._last_config_mtime_check_time = time.time() + return ServerConfig() + + # Don't be so lenient if the user pointed us at one though. + raise RuntimeError( + f"Config file not found: '{self._config_path}'.") + + import yaml + with open(self._config_path, encoding='utf-8') as infile: + user_config_raw = yaml.safe_load(infile.read()) + + # An empty config file will yield None, and that's ok. + if user_config_raw is not None: + out = dataclass_from_dict(ServerConfig, user_config_raw) + + # Update our known mod-time since we know it exists. + self._config_mtime = Path(self._config_path).stat().st_mtime + self._last_config_mtime_check_time = time.time() + + # Go with defaults if we weren't able to load anything. + if out is None: + out = ServerConfig() + + if print_confirmation: + logging.info(f"{Clr.CYN}{Clr.BLD}Loaded all server configuration files successfully.{Clr.RST}") + return out + + def _enable_tab_completion(self, locs: dict) -> None: + """Enable tab-completion on platforms where available (linux/mac).""" + try: + import readline + import rlcompleter + readline.set_completer(rlcompleter.Completer(locs).complete) + readline.parse_and_bind('tab:complete') + except ImportError: + # This is expected (readline doesn't exist under windows). + pass + + def _bg_thread_main(self) -> None: + """Top level method run by our bg thread.""" + while not self._done: + self._run_server_cycle() + + def _handle_term_signal(self, sig: int, frame: FrameType) -> None: + """Handle signals (will always run in the main thread).""" + del sig, frame # Unused. + sys.exit(1 if self._should_report_subprocess_error else 0) + + def _run_server_cycle(self) -> None: + """Spin up the server subprocess and run it until exit.""" + # pylint: disable=consider-using-with + + # Reload our config, and update our overall behavior based on it. + # We do non-strict this time to give the user repeated attempts if + # if they mess up while modifying the config on the fly. + self.load_config(strict=False, print_confirmation=True) + + self._prep_subprocess_environment() + + # Launch the binary and grab its stdin; + # we'll use this to feed it commands. + self._subprocess_launch_time = time.time() + + # Set an environment var so the server process knows its being + # run under us. This causes it to ignore ctrl-c presses and other + # slight behavior tweaks. Hmm; should this be an argument instead? + os.environ['BA_SERVER_WRAPPER_MANAGED'] = '1' + os.environ['BA_DEVICE_NAME'] = self._config.party_name + logging.info(f"{Clr.CYN}{Clr.BLD}Launching server sub-process. Hang tight!{Clr.RST}") + binary_name = ('BallisticaCoreHeadless.exe' + if os.name == 'nt' else './bombsquad_headless') + if platform.processor() == 'aarch64': + binary_name = './bombsquad_headless_aarch64' + assert self._ba_root_path is not None + self._subprocess = None + + # Launch! + try: + if ERROR_LOGGING: + self._subprocess = subprocess.Popen( + [binary_name, '-cfgdir', self._ba_root_path], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd='dist') + + self.nbsr = NBSR(self._subprocess.stdout) + self.nbsrerr = NBSR(self._subprocess.stderr) + else: + self._subprocess = subprocess.Popen( + [binary_name, '-cfgdir', self._ba_root_path], + stdin=subprocess.PIPE, + cwd='dist') + + except Exception as exc: + self._subprocess_exited_cleanly = False + print( + f'{Clr.RED}Error launching server subprocess: {exc}{Clr.RST}', + flush=True) + + # Do the thing. + try: + self._run_subprocess_until_exit() + + except Exception as exc: + print(f'{Clr.RED}Error running server subprocess: {exc}{Clr.RST}', + flush=True) + + self._kill_subprocess() + + assert self._subprocess_exited_cleanly is not None + + # EW: it seems that if we die before the main thread has fully started + # up the interpreter, its possible that it will not break out of its + # loop via the usual SystemExit that gets sent when we die. + if self._interactive: + while (self._interpreter_start_time is None + or time.time() - self._interpreter_start_time < 0.5): + time.sleep(0.1) + + # Avoid super fast death loops. + if (not self._subprocess_exited_cleanly and self._auto_restart + and not self._done): + time.sleep(5.0) + + # If they don't want auto-restart, we'll exit the whole wrapper. + # (and with an error code if things ended badly). + if not self._auto_restart: + self._wrapper_shutdown_desired = True + if not self._subprocess_exited_cleanly: + self._should_report_subprocess_error = True + + self._reset_subprocess_vars() + + # If we want to die completely after this subprocess has ended, + # tell the main thread to die. + if self._wrapper_shutdown_desired: + + # Only do this if the main thread is not already waiting for + # us to die; otherwise it can lead to deadlock. + # (we hang in os.kill while main thread is blocked in Thread.join) + if not self._done: + self._done = True + + # This should break the main thread out of its blocking + # interpreter call. + os.kill(os.getpid(), signal.SIGTERM) + + def _prep_subprocess_environment(self) -> None: + """Write files that must exist at process launch.""" + + assert self._ba_root_path is not None + os.makedirs(self._ba_root_path, exist_ok=True) + cfgpath = os.path.join(self._ba_root_path, 'config.json') + if os.path.exists(cfgpath): + with open(cfgpath, encoding='utf-8') as infile: + bincfg = json.loads(infile.read()) + else: + bincfg = {} + + # Some of our config values translate directly into the + # ballisticacore config file; the rest we pass at runtime. + bincfg['Port'] = self._config.port + bincfg['Auto Balance Teams'] = self._config.auto_balance_teams + bincfg['Show Tutorial'] = self._config.show_tutorial + + if self._config.team_names is not None: + bincfg['Custom Team Names'] = self._config.team_names + elif 'Custom Team Names' in bincfg: + del bincfg['Custom Team Names'] + + if self._config.team_colors is not None: + bincfg['Custom Team Colors'] = self._config.team_colors + elif 'Custom Team Colors' in bincfg: + del bincfg['Custom Team Colors'] + + bincfg['Idle Exit Minutes'] = self._config.idle_exit_minutes + with open(cfgpath, 'w', encoding='utf-8') as outfile: + outfile.write(json.dumps(bincfg)) + + def _enqueue_server_command(self, command: ServerCommand) -> None: + """Enqueue a command to be sent to the server. + + Can be called from any thread. + """ + with self._subprocess_commands_lock: + self._subprocess_commands.append(command) + + def _send_server_command(self, command: ServerCommand) -> None: + """Send a command to the server. + + Must be called from the server process thread. + """ + import pickle + assert current_thread() is self._subprocess_thread + assert self._subprocess is not None + assert self._subprocess.stdin is not None + val = repr(pickle.dumps(command)) + assert '\n' not in val + execcode = (f'import ba._servermode;' + f' ba._servermode._cmd({val})\n').encode() + self._subprocess.stdin.write(execcode) + self._subprocess.stdin.flush() + + def _run_subprocess_until_exit(self) -> None: + if self._subprocess is None: + return + + assert current_thread() is self._subprocess_thread + assert self._subprocess.stdin is not None + + # Send the initial server config which should kick things off. + # (but make sure its values are still valid first) + dataclass_validate(self._config) + self._send_server_command(StartServerModeCommand(self._config)) + + while True: + + # If the app is trying to shut down, nope out immediately. + if self._done: + break + # output=self._subprocess.stdout.readline() + # print(output) + if ERROR_LOGGING: + out = self.nbsr.readline(0.1) + out2 = self.nbsrerr.readline(0.1) + if out: + sys.stdout.write(out.decode("utf-8")) + _thread.start_new_thread(dump_logs, (out.decode("utf-8"),)) + if out2: + sys.stdout.write(out2.decode("utf-8")) + _thread.start_new_thread(dump_logs, (out2.decode("utf-8"),)) + # Pass along any commands to our process. + with self._subprocess_commands_lock: + for incmd in self._subprocess_commands: + # If we're passing a raw string to exec, no need to wrap it + # in any proper structure. + if isinstance(incmd, str): + self._subprocess.stdin.write((incmd + '\n').encode()) + self._subprocess.stdin.flush() + else: + self._send_server_command(incmd) + self._subprocess_commands = [] + + # Request restarts/shut-downs for various reasons. + self._request_shutdowns_or_restarts() + + # If they want to force-kill our subprocess, simply exit this + # loop; the cleanup code will kill the process if its still + # alive. + + if (self._subprocess_force_kill_time is not None + and time.time() > self._subprocess_force_kill_time): + print( + f'{Clr.CYN}Immediate shutdown time limit' + f' ({self.IMMEDIATE_SHUTDOWN_TIME_LIMIT:.1f} seconds)' + f' expired; force-killing subprocess...{Clr.RST}', + flush=True) + break + + # Watch for the server process exiting.. + code: Optional[int] = self._subprocess.poll() + if code is not None: + clr = Clr.CYN if code == 0 else Clr.RED + print( + f'{clr}Server subprocess exited' + f' with code {code}.{Clr.RST}', + flush=True) + self._subprocess_exited_cleanly = (code == 0) + break + + time.sleep(0.25) + + def _request_shutdowns_or_restarts(self) -> None: + # pylint: disable=too-many-branches + assert current_thread() is self._subprocess_thread + assert self._subprocess_launch_time is not None + now = time.time() + minutes_since_launch = (now - self._subprocess_launch_time) / 60.0 + + # If we're doing auto-restart with config changes, handle that. + if (self._auto_restart and self._config_auto_restart + and not self._subprocess_sent_config_auto_restart): + if (self._last_config_mtime_check_time is None + or (now - self._last_config_mtime_check_time) > 3.123): + self._last_config_mtime_check_time = now + mtime: Optional[float] + if os.path.isfile(self._config_path): + mtime = Path(self._config_path).stat().st_mtime + else: + mtime = None + if mtime != self._config_mtime: + print( + f'{Clr.CYN}Config-file change detected;' + f' requesting immediate restart.{Clr.RST}', + flush=True) + self.restart(immediate=True) + self._subprocess_sent_config_auto_restart = True + + # Attempt clean exit if our clean-exit-time passes. + # (and enforce a 6 hour max if not provided) + clean_exit_minutes = 360.0 + if self._config.clean_exit_minutes is not None: + clean_exit_minutes = min(clean_exit_minutes, + self._config.clean_exit_minutes) + if clean_exit_minutes is not None: + if (minutes_since_launch > clean_exit_minutes + and not self._subprocess_sent_clean_exit): + opname = 'restart' if self._auto_restart else 'shutdown' + print( + f'{Clr.CYN}clean_exit_minutes' + f' ({clean_exit_minutes})' + f' elapsed; requesting soft' + f' {opname}.{Clr.RST}', + flush=True) + if self._auto_restart: + self.restart(immediate=False) + else: + self.shutdown(immediate=False) + self._subprocess_sent_clean_exit = True + + # Attempt unclean exit if our unclean-exit-time passes. + # (and enforce a 7 hour max if not provided) + unclean_exit_minutes = 420.0 + if self._config.unclean_exit_minutes is not None: + unclean_exit_minutes = min(unclean_exit_minutes, + self._config.unclean_exit_minutes) + if unclean_exit_minutes is not None: + if (minutes_since_launch > unclean_exit_minutes + and not self._subprocess_sent_unclean_exit): + opname = 'restart' if self._auto_restart else 'shutdown' + print( + f'{Clr.CYN}unclean_exit_minutes' + f' ({unclean_exit_minutes})' + f' elapsed; requesting immediate' + f' {opname}.{Clr.RST}', + flush=True) + if self._auto_restart: + self.restart(immediate=True) + else: + self.shutdown(immediate=True) + self._subprocess_sent_unclean_exit = True + + def _reset_subprocess_vars(self) -> None: + self._subprocess = None + self._subprocess_launch_time = None + self._subprocess_sent_config_auto_restart = False + self._subprocess_sent_clean_exit = False + self._subprocess_sent_unclean_exit = False + self._subprocess_force_kill_time = None + self._subprocess_exited_cleanly = None + + def _kill_subprocess(self) -> None: + """End the server subprocess if it still exists.""" + assert current_thread() is self._subprocess_thread + if self._subprocess is None: + return + + # First, ask it nicely to die and give it a moment. + # If that doesn't work, bring down the hammer. + self._subprocess.terminate() + try: + self._subprocess.wait(timeout=10) + self._subprocess_exited_cleanly = ( + self._subprocess.returncode == 0) + except subprocess.TimeoutExpired: + self._subprocess_exited_cleanly = False + self._subprocess.kill() + logging.info(f"{Clr.RED}{Clr.BLD}Server shut down completed successfully!{Clr.RST}") + + +#PING THE SERVER STATUS SERVER +#WE NEED TO AGREE ON THE SERVER ID'S +# import requests +# from threading import Timer + +# def ping_online_server(): +# try: +# r = requests.get(url="https://serverstatus.professorfish.repl.co/statuses") +# data = r.json() +# except Exception as e: +# print(e) +# print("FAILED TO PING THE SERVER STATUS SERVER") +# finally: +# Timer(10, ping_online_server).start() +def main() -> None: + """Run the BallisticaCore server manager.""" + try: + # ping_online_server() + ServerManagerApp().run() + + + except CleanError as exc: + # For clean errors, do a simple print and fail; no tracebacks/etc. + # Any others will bubble up and give us the usual mess. + exc.pretty_print() + sys.exit(1) + + +def dump_logs(msg): + if os.path.isfile('logs.log'): + size = os.path.getsize('logs.log') + + if size > 2000000: + os.remove('logs.log') + + with open("logs.log", "a") as f: + f.write(msg) + + +if __name__ == '__main__': + main() diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..af30e5c --- /dev/null +++ b/config.yaml @@ -0,0 +1,133 @@ +# To configure your server, create a config.yaml file in the same directory +# as the ballisticacore_server script. The config_template.yaml file can be +# copied or renamed as a convenient starting point. + +# Uncomment any of these values to override defaults. + +# Name of our server in the public parties list. +party_name: "VORTEX AND HONOR BANG xD" + +# If true, your party will show up in the global public party list +# Otherwise it will still be joinable via LAN or connecting by IP address. +party_is_public: true + +# If true, all connecting clients will be authenticated through the master +# server to screen for fake account info. Generally this should always +# be enabled unless you are hosting on a LAN with no internet connection. +authenticate_clients: true + +# IDs of server admins. Server admins are not kickable through the default +# kick vote system and they are able to kick players without a vote. To get +# your account id, enter 'getaccountid' in settings->advanced->enter-code. +admins: +- pb-JiNJARFeXENAVF5FEkFQXFVBGUJWTlVH + +# Whether the default kick-voting system is enabled. +enable_default_kick_voting: true + +# UDP port to host on. Change this to work around firewalls or run multiple +# servers on one machine. +# 43210 is the default and the only port that will show up in the LAN +# browser tab. +port: 43211 + +# Max devices in the party. Note that this does *NOT* mean max players. +# Any device in the party can have more than one player on it if they have +# multiple controllers. Also, this number currently includes the server so +# generally make it 1 bigger than you need. Max-players is not currently +# exposed but I'll try to add that soon. +max_party_size: 12 + +# Options here are 'ffa' (free-for-all), 'teams' and 'coop' (cooperative) +# This value is ignored if you supply a playlist_code (see below). +#session_type: ffa + +# Playlist-code for teams or free-for-all mode sessions. +# To host your own custom playlists, use the 'share' functionality in the +# playlist editor in the regular version of the game. +# This will give you a numeric code you can enter here to host that +# playlist. +playlist_code: 445446 + +# Alternately, you can embed playlist data here instead of using codes. +# Make sure to set session_type to the correct type for the data here. +#playlist_inline: [] + +# Whether to shuffle the playlist or play its games in designated order. +#playlist_shuffle: true + +# If true, keeps team sizes equal by disallowing joining the largest team +# (teams mode only). +#auto_balance_teams: true + +# The campaign used when in co-op session mode. +# Do print(ba.app.campaigns) to see available campaign names. +#coop_campaign: Easy + +# The level name within the campaign used in co-op session mode. +# For campaign name FOO, do print(ba.app.campaigns['FOO'].levels) to see +# available level names. +#coop_level: Onslaught Training + +# Whether to enable telnet access. +# IMPORTANT: This option is no longer available, as it was being used +# for exploits. Live access to the running server is still possible through +# the mgr.cmd() function in the server script. Run your server through +# tools such as 'screen' or 'tmux' and you can reconnect to it remotely +# over a secure ssh connection. +#enable_telnet: false + +# Series length in teams mode (7 == 'best-of-7' series; a team must +# get 4 wins) +teams_series_length: 7 + +# Points to win in free-for-all mode (Points are awarded per game based on +# performance) +ffa_series_length: 24 + +# If you have a custom stats webpage for your server, you can use this +# to provide a convenient in-game link to it in the server-browser +# alongside the server name. +# if ${ACCOUNT} is present in the string, it will be replaced by the +# currently-signed-in account's id. To fetch info about an account, +# your back-end server can use the following url: +# http://bombsquadgame.com/accountquery?id=ACCOUNT_ID_HERE +stats_url: https://discord.gg/MUj97D2QMZ + +# If present, the server subprocess will attempt to gracefully exit after +# this amount of time. A graceful exit can occur at the end of a series +# or other opportune time. Server-managers set to auto-restart (the +# default) will then spin up a fresh subprocess. This mechanism can be +# useful to clear out any memory leaks or other accumulated bad state +# in the server subprocess. +#clean_exit_minutes: 60 + +# If present, the server subprocess will shut down immediately after this +# amount of time. This can be useful as a fallback for clean_exit_time. +# The server manager will then spin up a fresh server subprocess if +# auto-restart is enabled (the default). +#unclean_exit_minutes: 90 + +# If present, the server subprocess will shut down immediately if this +# amount of time passes with no activity from any players. The server +# manager will then spin up a fresh server subprocess if auto-restart is +# enabled (the default). +#idle_exit_minutes: 20 + +# Should the tutorial be shown at the beginning of games? +#show_tutorial: false + +# Team names (teams mode only). +team_names: +- vortex +- Honor + +# Team colors (teams mode only). +team_colors: +- [0.8, 0.0, 0.6] +- [0, 1, 0.8] + +# Whether to enable the queue where players can line up before entering +# your server. Disabling this can be used as a workaround to deal with +# queue spamming attacks. +#enable_queue: true diff --git a/dist/.keys b/dist/.keys new file mode 100644 index 0000000..2845409 --- /dev/null +++ b/dist/.keys @@ -0,0 +1 @@ +{"private_key": "iB3jjwHM1sDlk7_gyOH6ix26x6xiI70af0XLAxSlQwY", "public_key": "BNH1Bw4rzMMfDEXRZ8CsgIve7oe7gd8hzfgDXANAv1S1r_goQ1PpbqFUyjcHX5mOEJhG0qhNd14bZ8lbOJqwNSc"} \ No newline at end of file diff --git a/dist/ba_data/data/langdata.json b/dist/ba_data/data/langdata.json new file mode 100644 index 0000000..8da0fc0 --- /dev/null +++ b/dist/ba_data/data/langdata.json @@ -0,0 +1,1813 @@ +{ + "lang_names_translated": { + "Arabic": "العربية", + "Belarussian": "Беларуская", + "Chinese": "简体中文", + "ChineseTraditional": "繁體中文", + "Croatian": "Hrvatski", + "Czech": "Čeština", + "Danish": "Dansk", + "Dutch": "Nederlands", + "Esperanto": "Esperanto", + "Filipino": "Tagalog ", + "French": "Français", + "German": "Deutsch", + "Gibberish": "Gibberish", + "Greek": "Ελληνικά", + "Hindi": "हिंदी", + "Hungarian": "Magyar", + "Indonesian": "Bahasa Indonesia", + "Italian": "Italiano", + "Japanese": "日本語", + "Korean": "한국어", + "Malay": "Melayu", + "Persian": "فارسی‎", + "Polish": "Polski", + "Portuguese": "Português", + "Romanian": "Română", + "Russian": "Русский", + "Serbian": "Српски", + "Slovak": "Slovenčina ", + "Spanish": "Español", + "Swedish": "Svenska", + "Tamil": "தமிழ்", + "Thai": "ภาษาไทย", + "Turkish": "Türkçe", + "Ukrainian": "Українська", + "Venetian": "Veneto", + "Vietnamese": "Tiếng Việt " + }, + "translation_contributors": [ + "!edMedic💊", + "!ParkuristTurist!", + "\"9۝ÅℳЇℜρℜѺ۝ƬǀGΞЯ", + "/in/dev/", + "1.4.139", + "123", + "123123123", + "228варенье", + "233", + "26885", + "43210", + "5PH3X", + "99", + "@sametsunal", + "_DraXX", + "_Fami", + "Omar a", + "Bruno A.", + "aaalligator", + "aadesh", + "Aaron", + "Erik Abbevik", + "Abdo", + "Abduh", + "Abdul", + "Abdulloh", + "Abe", + "Ahmed abed", + "abhi", + "AbhinaY", + "Gifasa abidjahsi", + "Abinav", + "Abir", + "Abolfadl", + "Abolfazl", + "Abraham", + "Roman Abramov", + "AC", + "Achref", + "adan", + "Adeel (AdeZ {@adez_})", + "Adel", + "Rio Adi", + "Rayhan Adiansyah", + "Yonas Adiel", + "admin", + "Adonay", + "AdOwn69", + "Adrián", + "Aely", + "Aenigmus", + "Aether", + "Afrizal", + "Aga<3", + "Carlos Mario Agamez", + "ageng", + "Dimitris Aggelou", + "ariyan ahir", + "AHMAD", + "Aufan Ahmad", + "Ahmed", + "ahmedzabara", + "Collin Ainge", + "Akash", + "Akbar", + "Bekir Akdemir", + "Akhanyile", + "Aki", + "Abdullah Akkan", + "Berk Akkaya", + "AKYG", + "mohammed al-abri", + "Ali Al-Gattan", + "alaa", + "Ahmad Alahmad", + "Anna Alanis", + "Manuel Alanis", + "alanjijuoo7fudu@gmail.com", + "albertojesusvaldesdelrey@gmail.com", + "Alej0hio", + "Pedro Alejandro", + "Gabrijel Aleksić", + "Alex", + "Alexander", + "Gros Alexandre", + "Alexey", + "Alexgmihai", + "Alexis", + "Alexistb2904", + "Alexyze", + "Algene123456", + "ALI", + "Shadiq Ali", + "alireza", + "alirezaalidokht", + "ALISSON", + "Virgile Allard", + "Allinol", + "ahmed alomari", + "Alonso", + "Alper", + "Alpha", + "AlphaT", + "Althaf", + "altidor", + "Oguz Altindal", + "aly", + "Shahin Amani", + "Amar", + "alfredo jasper a ambel", + "Amedeo", + "ameen", + "Kidane Amen-Allah", + "amin.ir", + "Amir", + "amir22games", + "amir234", + "amir80sas", + "AmirMahdi.D :P", + "Amirul", + "Ange Kevin Amlaman", + "amr", + "Anandchaursiya", + "Anas", + "Anastasija", + "AnatoliyanChubukov", + "AnatoliyanChybycov", + "Bryan Enrique Perez de Anda", + "Wodson de Andrade", + "Andre", + "andrea", + "AndreaF", + "David Andrei", + "Andres", + "Andrew", + "Andria", + "Andria.J", + "Andriawan", + "Lazib andriyanto", + "Android", + "Android44561650", + "Andru", + "André", + "Andy", + "krish angad", + "Krishna D Angad", + "vân anh", + "Aniol", + "Daniel Felipe Silva dos Anjos", + "Anmol", + "anonymous", + "Alok. R. Anoop", + "Antonio", + "Antoniom", + "Lucas Antunes", + "wassim aoufi", + "apis", + "Sagar April", + "Fernando Araise", + "arda", + "Hellmann Arias", + "Muhammad Arief", + "Arimaru", + "Arin", + "arjanex", + "Arroz", + "ARSHAD", + "ArshiyDLn", + "Artem", + "Valentino Artizzu", + "Arxyma", + "Ashik", + "Ashish", + "AskarBink", + "Asraf", + "Asshold", + "Eliane Santos de assis", + "Atalanta", + "Atilla", + "Atom", + "Audacious7214", + "Aufaghifari", + "Ausiàs", + "autismo", + "Autoskip", + "Ryan Auxil", + "Avamander", + "Tel Aviv", + "awase2020@gmail.com", + "sev alaslam Awd", + "Axel", + "ayub", + "masoud azad(fireboy)", + "Md azar", + "Azlan", + "Azoz", + "Burak Karadeniz (Myth B)", + "Myth B.", + "B4likeBefore", + "Praveen Babu", + "Baechu", + "Balage8", + "BalaguerM", + "Peter Balind", + "Levalia Ball", + "Balqis", + "Balraj", + "Smutny Bambol", + "Alex Ban", + "Ryan Bandura", + "Bank", + "Ibrahim Baraka", + "Kamil Barański", + "Leonan Barcelos", + "Bardiaghasedipour", + "William Barnak", + "William Barnakk", + "Danillo Rodrigues Barros", + "Zalán Barta", + "Lorenzo Bartolini", + "Petr Barták", + "Basel", + "Bashkot", + "Matthias Bastron", + "Ralph Bathmann", + "Emanuel Almeida Batista", + "Bato", + "Florian Bauernfeind", + "David BAUMANN", + "bayanus", + "Wojtek Bałut", + "Hi bbbbbbbbb", + "Eduardo Beascochea", + "Eduan Bekker", + "бравлер Андрей Belarus", + "ben", + "Mohamed benchrifa", + "Bendy", + "Sérgio Benevides", + "Simon Bengtsson", + "Alfano Beniamino", + "Benjamin", + "Benjamín", + "benjapol", + "Ori bennov", + "BenVectorgames", + "benybrot96", + "berkay", + "Silvio Berlusconi", + "Bernardiny", + "Anton Bang Berner", + "Felix Bernhard", + "Davide Bigotto", + "bilibili@Medic药", + "Bima", + "Biytremni", + "Blackcat2960", + "BlackShadowQ", + "Daniel Block", + "BlueBlur", + "bob bobber", + "BomBillo", + "The Bomboler 💣", + "bombsquad", + "Bombsquadzueira", + "Bomby", + "Zeleni bomby", + "Alex BONYOMA", + "Book", + "Guilherme Borges", + "Lucas Borges", + "Gianfranco Del Borrello", + "Abel Borso", + "Plasma Boson", + "Cristian Bote", + "Cristián Bote", + "botris", + "Botte", + "bouabdellah", + "Antoine Boulanger", + "Thomas Bouwmeester", + "Ali x boy", + "Bořivoj", + "Paul braga", + "Sammy Braun", + "Brayk", + "Brendan", + "Federico Brigante", + "Anderson Brito", + "Broi", + "Brojas", + "Brojasko", + "BrotheRuzz11", + "Brunoazocar", + "bsam", + "Bsamhero", + "BSODPK", + "Marvin Bublitz", + "Vincent R. Buenaventura", + "Buskebam", + "Buto11", + "ByAdrianYT", + "Semih Byzts", + "Mohamad Hossein BZ", + "Christoffer Bünner", + "mvp aka cactus", + "mvp aka legend (aka cactus) 🌵", + "Cadødø", + "Chris Laurence Cagoco", + "Calet", + "Kenneth Callaghan", + "Federico Campagnolo", + "Henry Abraham Kumul Canche", + "CandyMan101", + "Nicola Canigiani", + "Fabio Cannavacciuolo", + "CANOVER", + "Fedrigo Canpanjoło", + "Yan Carlos", + "CarlosE.", + "mark Dave a carposo", + "Fabricio de Carvalho", + "Joshua Castañeda", + "Lisandro Castellanos", + "Catjuanda05", + "CatMax", + "Arthur Cazes", + "CerdoGordo", + "Ceren", + "chang", + "Charlie", + "kalpesh chauhan", + "chausony", + "CheesySquad", + "Chicken", + "ChocolateComrade", + "choi", + "Vadim Choi", + "Chris71/Chris71x", + "Hans Christensen", + "Attilio Cianci", + "Kajus Cibulskis", + "Mateusz Ciochoń", + "Citytrain", + "Nick Clime", + "Jerome Collet", + "probably my. com", + "Comrade", + "Stefano Corona", + "Corrolot", + "Francisco Law Cortez", + "David Cot", + "Nayib Méndez Coto", + "Dylan cotten", + "covcheg", + "COVER", + "crac", + "CrazyBear", + "Frederick Cretton", + "crisroco10", + "Cristhian", + "Cristian", + "Cristóbal", + "Criz", + "Cpt crook", + "Prashanth CrossFire", + "Cryfter", + "cuddles98", + "cukomus", + "CYCL0YT", + "D", + "D-Mega", + "Dada", + "Daivaras", + "Dajo6596YT", + "Dakkat", + "Mikkel Damgaard", + "Danco", + "Dani", + "Daniel", + "Daniel3505", + "DaniesAlex007", + "Dančo", + "Iman Darius", + "DarkAnarcy", + "DarkEnergon8", + "DarshaN", + "Shibin das", + "Dasto", + "David", + "Davide", + "DavidPlayzLol", + "DavidPlayzloll", + "DaymanLP", + "Ddávid", + "Die or Dead", + "Привет от детей DeadLine", + "deepjith", + "dekarl", + "deliciouspudding43", + "delshe", + "Denis", + "Dennis", + "Dennys", + "Alex Derbenew", + "df", + "Santanu Dhar", + "Guilherme Dias", + "Diase7en", + "ferbie Dicen", + "Diego788", + "DiegoGD", + "DiGGDaGG", + "dikivan2000", + "Dimitriy", + "Martin Dimitrov", + "DinoWattz", + "Diprone", + "djaber djafer", + "Fadhil djibran", + "Alexis Dk", + "DKua", + "dlw", + "DMarci", + "Dmirus", + "Dmitriy", + "Savchenko Dmitriy", + "Count Su Doku", + "DominikSikora!", + "Kai Dominique", + "Gerardo Doro", + "DottorMorte", + "Dragomir", + "Drellsan", + "DrGhast", + "Dron009", + "drov.drov", + "Davide DST", + "Bruno Duarte", + "Johann Duco", + "Dudow", + "Dustin", + "Paul Duvernay", + "Emir İslam Dündar", + "E.R.A.L", + "Ebutahapro07tr", + "Edson", + "Glen Edwards", + "Amr Wassiem Eessa", + "ef", + "Ali ehs", + "Eiva", + "EK", + "EKFH", + "avatar por reina del carnaval en la que te lo mando el", + "Rezk ElAdawy", + "ElCatCaesar", + "ElderLink", + "elfree", + "Elian", + "Elsans320_YT", + "Elskoser", + "ElVolKo", + "ali emad", + "Ramy Emad", + "Emil", + "Kürti Emil", + "Muhammed emir", + "Muhammet Emir", + "EmirSametEr", + "emm", + "EnderDust123", + "EnderKay", + "EnglandFirst", + "Enrico", + "enzo", + "Era", + "Erick", + "Erkam", + "Jonas Ernst", + "NO es", + "Shayan Eskandari", + "Esmael", + "Jose espinoza", + "ethanmigueltrinidad", + "ExaYT", + "Exelendary", + "Abdullatif Badinjki ExPeRt 1420", + "ExplosiveDinosaurs.com", + "EXTENDOO", + "Eyder", + "fa9oly9", + "Fabian", + "Luca Facchinetti", + "Facundo", + "Jakub Fafek", + "Syed Fahrin (Mr.Lemoyne)", + "faizal.faiz.ms@gmail.com", + "Fakih", + "FanDolz.", + "Faqih", + "Muhammad Faqih ''None''", + "Syed Irfan Farhan", + "Luiz Henrique Faria", + "Syed Fahrin Farihin", + "Fatih", + "FaultyAdventure", + "Putra Riski Fauzi", + "fauziozan.23@gmail.com", + "Shaikh Fazal", + "Fea", + "FearLessCuBer", + "Federico", + "Fedrigo", + "Marco Fabián Feijoó", + "Fenyx", + "Fernando", + "David Fernández", + "FerranC", + "FertileChannelHD", + "FightBiscuit", + "filip", + "Filip117", + "Fillowskyy", + "Firdaus", + "Daffa Firdaus", + "Aldereus Fire", + "Robert Fischer", + "Kai Fleischmann", + "Iancu Florin", + "FluffyPal", + "FLᎧRᏋᏁTIᏁᎧ", + "Angelo Fontana", + "FortKing", + "Freaku", + "Golden Freddy", + "FREÂK", + "Andrey Fridholm", + "FriskTheHuman303", + "Froshlee14", + "FuckIndoDick", + "Lukas Funk", + "Gustavo FunnyGuard28", + "Erick G", + "Roberto G", + "George G.", + "Fabian G.L.", + "G192", + "MZ G4MES", + "Gabriel", + "João Gabriel", + "Gabriele", + "Nihar Gajare", + "GalaxyNinja2003", + "AP - Pro Gamer", + "Proff Gamer", + "Eduardo Gamer05", + "Taufiq Gamera", + "Altangerel Ganbaatar", + "Quentin Gangler", + "RUSLAN ABDUL GANI", + "Gaspard", + "krish gator", + "gene.mTs", + "GeoMatHeo", + "Gerry", + "GG (9.2)", + "Onkar Ghagarum", + "GHAIS", + "Omar Ghali", + "GhOsT_St3p", + "GhostGamer", + "Gian", + "Gianfranco", + "Gianluca11", + "Aldi gibran", + "Aidan Gil", + "Noe Marley Ginting", + "Giovalli99", + "Giovanny", + "Dc superhero girl", + "Givij", + "Gleb", + "Glu10free", + "Mr. Glu10free", + "Jhon Zion N. delos reyes gmail", + "gman_4815", + "God丶烛龙", + "Colin Goeieman", + "박준서(PJS GoodNews)", + "gowthamvelkarthik.k", + "Nicola Grassi", + "Gerrit Grobler", + "Oliver Grosskloss", + "Alexis Guijarro", + "Guilherme", + "Victor Guillemot", + "Guillermo", + "SHOBHIT GUPTA", + "Gurad", + "Max Guskov", + "Rachmat Gusti", + "Aditya Gwala", + "Tódor Gábor", + "Tymoteusz Górski", + "Thomas Günther", + "H.J.N", + "Haasaani", + "Hack", + "HackPlayer697", + "hadi", + "hafzanpajan", + "Haidar", + "Joud haidar", + "جود حيدر/joud haidar", + "Halox", + "HamCam1015", + "hamed", + "Zulfikar Hanif", + "Happaphus", + "Hariq", + "harojan", + "Harsh", + "Abdi Haryadi", + "Hasan", + "Mohammad hasan", + "Hisham bin Hashim", + "Emil Hauge", + "Arian Haxhijaj", + "Ergin Haxhijaj", + "Florian Haxhijaj", + "Hayate", + "Hayate16", + "hehhwushh", + "Lukas Heim", + "Hugues Heitz", + "HellisWrath", + "hellobro", + "Christoffer Helmfridsson", + "Hemra", + "Julian Henkes", + "henry", + "Heraltes", + "boy hero", + "bsam hero", + "herosteve22jajs", + "heymaxi", + "HiImBrala", + "Ayra Hikari", + "Hiking", + "Himesh", + "Yazan Hinnawi", + "Daffaa Hisyaam", + "Trung Hiếu", + "Nabil Hm", + "Nguyen Dang Hieu Hoa", + "Minh Hoang", + "Robin Hofmann", + "hola", + "Sebasian Varela Holguin", + "Holystone", + "Jeremy Horbul", + "Hosein", + "hoseinا", + "Phan Lê Minh Hoàng", + "Jorge Isaac Huertero", + "Hussain", + "Umair Hussain", + "Hussam", + "Adrian Höfer", + "Davide Iaccarino", + "iBearzGaming", + "Iboyindyza", + "Ibrahim", + "Ignacio", + "IgnUp21", + "Igomen15", + "Igor", + "IL_SERGIO", + "!YamGila (Syed Ilham)", + "Iliya_bomB", + "illonis", + "Syed Ilham Ilman", + "Ily77788", + "Ilya", + "IlyxaGold", + "d imitris", + "Nik ali imran", + "IND_PIYUSH", + "Indecisive", + "indieGEARgames", + "Darkness indo", + "Indohuman", + "IniSaya6666", + "inkMedic", + "inkMedic💊", + "InvisibleDude", + "Anestis Ioakimidis", + "Dragomir Ioan", + "Isa", + "Israelme03", + "Tobias Dencker Israelsen", + "Kegyes István", + "Itamar", + "ivan", + "iViietZ", + "MOHD IZWAN", + "JaaJ", + "Al jabbar", + "Jacek", + "Jack556", + "Jhon Jairo", + "wahid jamaludin", + "Tarun Jangra", + "Aleksandar Janic", + "Martin Jansson", + "JasimGamer", + "Jason", + "Javvaed", + "Jbo", + "JCIBravo", + "Jd", + "JDOG253", + "Jeemboo", + "Jembhut", + "CrackerKSR (Kishor Jena)", + "CrackerKSR (Kishor Jena))", + "Jenqa", + "Jeroen", + "jesus", + "Jetty", + "Jeulis", + "Jewellbenj", + "jgst2007@gmail.com", + "Zhou Jianchu", + "jimmy", + "Jiren", + "jitues", + "JM", + "Joan", + "JoaoVitorBF", + "joaquin", + "Lex Johannes", + "John", + "Ksteven john", + "Steven john", + "Johnny", + "joke", + "Jonatas", + "Jop", + "JoseANG3L", + "Joseetion", + "Joseph", + "Joshep", + "Rudransh Joshi (FireHead)", + "joshuapiper", + "Jossiney", + "juanramirez", + "Jules", + "juse", + "Justine", + "JYLE", + "Jyothish", + "Oliver Jõgar", + "Nackter Jörg", + "Calvin Jünemann", + "Luis K", + "Sayooj k", + "K'veen", + "Kacper", + "kadaradam", + "Efe Kahraman", + "KalakCZ", + "Adam Kalousek", + "kalpesh", + "Kalyan", + "Kamal", + "Aiman Aryan Kamarajan", + "Kamil (Limak09)", + "Kamilkampfwagen", + "Kaneki", + "Smurfit Kappa", + "Mustafa Karabacak", + "karabin", + "Burak karadeniz", + "Burak Karadeniz(MythB)", + "Daniel Karami", + "Karim", + "Kasra", + "Kaushik", + "KawaiiON", + "KD", + "Kejuxs", + "Mani kelidari", + "Kelly", + "Kelmine", + "Kenjie", + "Kerfix", + "Kerim", + "Kevinga2533a", + "Khaild1717", + "muh khairul", + "Khalid", + "KhalidPlaysYT", + "khalio", + "$RICO$ KhevenMito", + "Khwezi", + "kibro", + "Joop Kiefte", + "killer", + "killer313", + "King", + "KingCreeps", + "kinnie", + "kira", + "kirill", + "KirillMasich", + "Kittycat41", + "Andrew Kmitto", + "Philipp Koch", + "Kolmat", + "komasio", + "komasio71", + "KomodoRec", + "Niko Koren", + "Nikolay Korolyov", + "Kostas", + "Viktor Kostohryz", + "Kozmo909", + "Mikhail Krasovsky", + "kripanshu", + "kris", + "krishAngad", + "krishuroy", + "kroш)", + "Patel krumil", + "Krunal", + "Alok Kumar", + "sarath kumar", + "Aapeli Kumpulainen", + "Aldhiza Kurniawan", + "Arif Kurniawan", + "Rasyid Kurniawan", + "Wahyu Kurniawan", + "KurtWagner", + "Daanii Kusnanta", + "Kyle", + "Jan Kölling", + "L_JK", + "John Patrick Lachica", + "laikrai", + "m a lakum", + "Dmitry Lamperujev", + "K. Larsen", + "Nicklas Larsen", + "Shin Lasung", + "Sampo Launonen", + "Lazered", + "Lazydog", + "Elia Lazzari", + "이지민 (Ji-Min Lee)", + "Mick Lemmens", + "Leo", + "Lester", + "Szajkajkó Levente", + "Szajkajó Levente", + "Johannes Lex", + "Gastón Lezcano", + "Shuaibing Li", + "Tred Li", + "Juan Liao", + "LickyBeeYT", + "Nicola Ligas", + "Limak09", + "lin", + "Dustin Lin", + "Kyle Lin", + "Linus", + "Linux44313", + "LiteBalt", + "LittleNyanCat", + "Juunhao Liu", + "Lizz", + "Lizzetc", + "Lkham", + "Lobinhofs", + "Loex", + "Loko", + "Longkencok", + "looooooooou", + "LordHiohi", + "Lordigno", + "lorenzo", + "Lostguybrazil", + "mian louw", + "69 lover", + "Jordan Vega Loza", + "Chenging Lu", + "Chengming Lu", + "João Lucas", + "Simone Luconi", + "Ludicrouswizard", + "satrio ludji", + "Ludovico", + "Luis (GalaxyM4)", + "Jose Luis", + "Luis(GalaxtM4)", + "luislinares", + "luispro25", + "Luka", + "Luke", + "Luke994", + "Lukman", + "Hermanni Luosujärvi", + "Lurã", + "Luthy", + "Geogre Lyu", + "Be aware that m", + "M.R.T", + "M5TF4", + "Mac 143338", + "MaceracıMS", + "Samuel Maciel", + "Djawad madi", + "Mads Beier Madsen", + "Mahan", + "Ondřej Mahdalík", + "mahdi", + "mahdimahabadi", + "Mahmoud", + "maicol", + "Majestozão", + "Makar", + "Maks1212", + "Malaysian", + "EMILIO MALQUIN", + "MAMAD", + "Mani", + "Manimutharu", + "Ahmed Mansy", + "Manu", + "Mapk58", + "Marcel", + "Marchella", + "Marcin", + "Marco", + "Marcolino", + "Filip Marek", + "Marcin Marek", + "Mariel", + "Marin", + "mariuxoGaming", + "Stefan Markovic", + "Marouene", + "Marošsko", + "martin", + "Philip Martin", + "MartinZG007", + "Martín", + "Taobao Mascot", + "Masood", + "MasterRyan", + "Mateusz", + "Mathias", + "Mathieu", + "matias", + "matj1", + "Eduardo de Matos", + "Matteo", + "Matthias", + "Ihsan Maulana ( @ihsanm27)", + "Muhammad Akbar Maulana", + "Mavook", + "Federico Mazzone", + "Andrea Mazzucchelli", + "Medic", + "Medic别闹我有药", + "German Medin", + "Martin Medina", + "Mehret Mehanzel", + "Mehmet", + "Mehrdad", + "Kevin Mejía", + "Mell", + "MereCrack", + "Mert", + "Meryu07", + "Meysam", + "MGH", + "Davis Michelle", + "Mick", + "Miguel", + "Miguelterrazas123", + "Mikael", + "mike", + "Milaner", + "Milk3n", + "Fabio Milocco", + "mimis", + "Mina", + "minh123456789thcsvk", + "MinhAn19203", + "Azfar Ahmed Mirza", + "Deepak Mishra", + "Mistetas3002", + "Skramh Miugrik", + "Mizzzzon", + "Mk", + "MKG", + "mobin", + "Mobina", + "Moh", + "Mohamadali", + "Mohamadamin", + "Mohamed", + "Mohammad", + "Mohammad11dembele", + "MOHAMMADERFAN", + "Mohammadhosain", + "Mohammed", + "MOHAMMEDTALAL1ST", + "1n Mohhaamad", + "Moin", + "MONIRIE", + "Carlos Montalvo", + "Ederson Moraes", + "Eduardo Moreira", + "Danteo Moriarty", + "Kabir morya", + "Moses", + "mr", + "mr.Dark", + "Mr.Smoothy", + "MrDaniel715", + "MrGlu10free", + "Mrmaxmeier", + "MrNexis", + "MrS0meone", + "Ivan Ms", + "MSampic", + "Msta", + "MT", + "MT2087", + "Muhammed Muhsin", + "MujtabaFR", + "Muni", + "mustardb", + "Hisham Musthafa", + "Mohammed Musthafa", + "MUZAMMIL", + "Mwss", + "MYSENIOR", + "mythbrk00@gmail.com", + "Sajti Márk", + "Samuel Mörling", + "Luca Müller", + "nacho", + "Nagaarjun(pongal)", + "Nahuelgomez1607", + "Nasser", + "Natasja", + "Nathan", + "naveentamizhan123456", + "Navid (Nasa)", + "Nayan", + "Nazar", + "Nazar_1232", + "Behnam Nazemi", + "nazroy", + "Ndrio°o", + "NecroMeerkat", + "Neel", + "Nel", + "Nemeil", + "Era (Spazton neo)", + "Mattia Nepote", + "The nerd", + "Gabriel Del Nero", + "nevergpdia", + "Andrew Nevero", + "Newt", + "Hamid Neyzar", + "Nicholas", + "NichtEnno", + "Nico", + "Nico-iVekko", + "Nicola", + "Nicolas", + "Niels", + "Frederik Nielsen", + "Nifujini", + "Nikali2007", + "Nima", + "XU NING", + "طارق محمد رضا سعيد NinjaStarXD", + "nino", + "Nintendero65", + "Nizril", + "Nnubes256", + "Bu nny", + "Noam", + "Simone Nobili", + "NofaseCZ", + "Max Noisa", + "Noisb", + "None", + "Noobslaya101", + "noorjandle1", + "Petter Nordlander", + "NotBrojasAgain", + "Ntinakos555", + "NullWizard", + "Dhimas Wildan Nz", + "*** Adel NZ. ***", + "Ognjen", + "okko", + "Bastián Olea", + "Nikita Oleshko", + "Omar", + "OmarBv", + "On3GaMs", + "No One", + "Adam Oros", + "Andrés Ortega", + "Zangar Orynbetov", + "Osmanlı2002", + "Osmanys", + "OyUnBoZaN (NEMUTLUTURKUMDİYENE)", + "pack", + "PALASH", + "Giorgio Palmieri", + "Abhinay Pandey", + "PangpondTH", + "PanKonKezo", + "PantheRoP", + "ParadoxPlayz", + "Gavin Park", + "Parkurist", + "Pascal17", + "Pastis69", + "Sagar patil", + "pato", + "patrick", + "paulo", + "Dominik Pavešić", + "BARLAS PAVLOS-IASON", + "Payu", + "PC189085", + "PC192082", + "pc192089", + "PC261133", + "PC295933", + "PC432736", + "pebikristia", + "Pedro", + "Jiren/Juan Pedro", + "Penta :D", + "Peque", + "Rode Liliana Miranda Pereira", + "Jura Perić", + "Panumas Perkpin", + "Pero", + "Khoi Pete", + "Kacper Petryczko", + "pett", + "Petulakulina", + "Pez", + "PGIGM", + "Đào Xuân Phi", + "Philip", + "Philipp", + "piga", + "Stefano Pigozzi", + "Mario Donato Pilla", + "Pinchidino", + "Danilo \"Logan\" Pirrone", + "PivotStickfigure12", + "Pixelcube", + "PixelStudio", + "pixil", + "PizzaSlayer64", + "Elian Pj", + "Broi PL", + "Ziomek PL", + "Anestis Plithos", + "Pluisbaard", + "Jaideep Kumar PM", + "podolianyn", + "poggersCat", + "Pong", + "Pooya", + "pouriya", + "Pouya", + "Pranav", + "Luca Preibsch", + "Prem", + "Fabian Prinz", + "Private0201", + "Priyanshu", + "Brayk pro 2.0", + "Sus propios", + "psychatrickivi12", + "pszlklismo", + "Pulidomedia.com", + "haris purnama", + "GABRIEL PUTRICK", + "Bodnár Péter", + "Gangler Quentin", + "Qwsa", + "QŴE", + "Anbarasan R", + "efvdtrrgvvfygttty5 5 r", + "Felo Raafat", + "Tim Rabatr", + "Radfrom", + "RadicalGamer", + "Radicool", + "RafieMY", + "raghul", + "khaled rahma", + "Rayhan Rahmats", + "Ralfreengz", + "1. Ramagister", + "Rostislav RAMAGISTER", + "Ростислав RAMAGISTER", + "Lucas Ramalho", + "Rahul Raman", + "Vicente Ramirez", + "ramon", + "Randlator", + "Random_artz__", + "Rares", + "rashid", + "Yudha Febri Rastuama", + "Mayank Ravariya", + "Serious796 (Mayank Ravariya)", + "Ravi", + "Dhafin Rayhan", + "RayonLaser", + "Rayze", + "Razil", + "Jaiden Razo", + "RCSV159", + "RCTwerk", + "Re", + "realSamy", + "RECRUTA", + "REDEJCR", + "redyan", + "De'Viren Reed", + "Cornelius Reimann", + "releaseHUN", + "renas", + "Renārs", + "Repressive20", + "Devair Restani", + "RetroB", + "Torsten Reuters", + "rexKis", + "Victor Jesus Arroyo Reyes", + "Mohammad Reza", + "Joel RG (Plar&Teporingo)", + "rian", + "Bruno Ricardo", + "Riccardo", + "Richard Lévai (aka ricinoob)", + "Rico", + "Ridzuan", + "Samuel Rieger", + "RieJoemar", + "Jeroen Rinzema", + "RioAdir", + "Max Rios", + "Rio枫叶", + "RiPe16", + "Rishabh", + "Rivki", + "rizaldy", + "Rodbert", + "Rodrigo", + "Giovanni Rodríguez", + "Marco Rodríguez", + "Rohan", + "Rohit", + "Bihary Roland", + "Jericho roldan", + "Roma :D", + "Roman", + "Mathias Romano", + "Ronald", + "Ronianagranada", + "roninjhie@gmail.com", + "Rori", + "Mario Roveda", + "Roy", + "Rubanen", + "Kaj Rumpff", + "Dosta Rumson", + "Hong Ruoyong", + "Philip Ruppert", + "Ryan", + "LiÇViN:Cviatkoú Kanstançin Rygoravič", + "Ricky Joe S.Flores", + "Rami Sabbagh", + "Justin Saephan", + "sahel", + "Abdullah Saim", + "Audinta Sakti", + "Bassam bu salh", + "Bsam bu salh", + "M. Rizki Agus Salim", + "Salted", + "Matteo Salvini", + "Salvo04", + "San", + "SaNt0RiNiKits577YT", + "Guilherme Santana", + "Santiago", + "Ivan Santos :)", + "Diamond Sanwich", + "SAO_OMH", + "Dimas Saptandi", + "Sara", + "ahmad sarnazih", + "sathish", + "sattar", + "Saverio", + "Jhon Rodel Sayo", + "Christiaan Schriel", + "Hendrik Schur", + "SEBASTIAN2059", + "Semen", + "Mihai Serbanica", + "Daniel Balam Cabrera Serrano", + "Yefta Aditya Setiawan", + "Sg", + "sgx", + "Black Shadow", + "ShadowQ", + "shafay", + "Manan Shah", + "shakesm", + "Sharvesh", + "Nalam Shashwath", + "Haige Shi", + "ShockedGaming", + "Shogun", + "Shayan Shokry", + "Dominik Sikora", + "Leonardo Henrique da Silva", + "Sebastian Silva", + "Simotoring", + "Pawan Singh sisodiya", + "Skick", + "sks", + "Max Sky", + "SlayTaniK", + "Igor Slobodchuk", + "Rasim Smaili", + "Nicola Smaniotto", + "smertfhg", + "Nico Smit", + "Snack", + "Snobbish", + "Mahteus Soares", + "Matheus Soares", + "sobhan", + "Nikhil sohan", + "SoK", + "SoldierBS", + "Unnamed Solicitude", + "SPT Sosat", + "Soto", + "spacechase26", + "SpacingBat3", + "Jack sparrow", + "speddy16", + "Spielfreake (Garke)", + "Spielfream", + "Spy", + "SqdDoom", + "sss", + "ST", + "Danny Stalman", + "stampycat", + "Bartosz Staniszewski", + "Stare", + "StarFighter", + "Rz Stazzy", + "Stealives", + "Steffo", + "stelios", + "Stephanie", + "stephen", + "Aleksa Stevčić", + "Janis Stolzenwald", + "Storm", + "STPayoube", + "Stratex", + "SYED EPIC STUDIOS", + "sun.4810", + "Samet Sunal", + "sundar", + "Suprcat", + "Indo sus", + "Sven", + "Shannon Sy", + "syaifudib", + "Daniel Sykora", + "Sz™", + "Jorge Luis Sánchez", + "Daniel Sýkora", + "Aleksandar Tadic", + "Arung Taftazani", + "taha", + "Rasim Eren TAHMAZ", + "Juancho Talarga", + "Emre Talha(Alienus)", + "talopl123", + "Talrev134", + "Kaustubh Tando", + "Kaustubh Tandon", + "Tania", + "Dmytro Tarasenko", + "Tarma", + "tarun", + "Tauras", + "tcnuhgv", + "tdho", + "Teals53", + "Teapoth", + "Michael Tebbe", + "Teforteem7395", + "Tejas", + "Nemanja Tekić", + "Marcel Teleznob", + "TempVolcano3200", + "TerfulFellowship47", + "Yan Teryokhin", + "TestGame1", + "TestGame1👽🔥", + "testwindows8189", + "tgd4", + "Than", + "Thanakorn7215", + "thatFlaviooo", + "The_Blinded", + "Eugene (a.k.a TheBomber3000)", + "Thebosslol66", + "thejoker190101", + "TheLLage", + "TheMikirog", + "Theo", + "Thiago_TRZ", + "ThisIsBad", + "Trevon Thrasher", + "Tiberiu", + "Cristian Ticu", + "Robert Tieber", + "TIGEE", + "Tim", + "Tingis2", + "Thura Tint", + "Nishant Tiwari", + "tjkffndeupwfbkh", + "Toloche", + "Tom", + "Juan Pablo Montoya Tomalá", + "TomasNoobCz", + "tomo", + "tongtong", + "Top 999", + "Tory", + "TozeLeal", + "Trung Hieu Le Tran", + "Translator", + "Trivago", + "El Trolax", + "tseringlama", + "Konstantin Tsvetkov", + "Kontantin Tsvetkov", + "Tudikk", + "Jan Tymll", + "Zacker Tz", + "Zoltán Tóth", + "uDinnoo", + "Cristian Ugalde", + "Atchy-Dalama--Ancelly Ulrich", + "Syed Umar", + "Unknown", + "Uros", + "clarins usap", + "utyrrwq", + "Uzinerz", + "Shohrux V", + "Vader", + "Valentin", + "Valkan1975", + "Ante Vekić", + "Malte van het Veld", + "veme312", + "Venemos", + "Dmitry \"SqdDoom\" Verigo", + "Deepanshu Verma", + "Jop Vernooij", + "Via", + "Victor", + "paulo victor", + "Vigosl", + "vijay", + "vinicius", + "Robin Vinith", + "vinoth", + "Vishal", + "VoidNumberZero", + "Voxel", + "Voxel25", + "VTOR", + "Fernando Véliz", + "Vít", + "Steven Völker", + "O mae wa", + "Nick Waas", + "Alland Christian Wagan", + "Julian Wagner", + "Shaiful Nezan Bin Abdul Wahid", + "wahyu", + "Vaibhav Wakchaure", + "Simon Wang", + "Will Wang", + "Tilman Weber", + "webparham", + "Wesley", + "whitipet", + "wibi9424", + "Wido2000", + "wildanae", + "Will", + "william", + "Windyy", + "wither", + "Tobias Wohlfarth", + "wojtekpolska", + "Doni Wolf", + "Tommy Wong", + "WonkaWoe", + "Moury ji world", + "wsltshh", + "Wurstkatze", + "WurstSaft", + "Xavier", + "Francisco Xavier", + "xbarix123897", + "Peque XD", + "Xem", + "Xizruh", + "xxonx8", + "Ajeet yadav", + "yahya", + "Arda Yalın", + "Yamir", + "YannSonic", + "Yantohrmnt401", + "Halil Yarkin", + "amr yasser", + "YellowTractor", + "Yasin YILMAZ", + "Ymgfr", + "yoksoudraft", + "Kenneth Yoneyama", + "yossef", + "youcef", + "Youssef", + "Yousuf", + "Yovan182Sunbreaker", + "Yrtking", + "All Star YT", + "Dark Fgg5 YT", + "Yudhis", + "yugo", + "yullian", + "Yuslendo", + "NEEROOA Muhammad Yusuf", + "Yuuki", + "Yy", + "yyr_rs", + "z", + "Sam Z", + "Z@p€g@m€r", + "Zac", + "Dawn Zac", + "Zaidan64GT", + "Zain", + "Zajle", + "Zakaria\"Colonel_Bill\"Amtoug", + "Karol Zalewski", + "Zangar", + "ZaraMax", + "zecharaiah", + "Daniele Zennaro", + "zfuw668", + "Alex Zhao", + "Doge Zhao", + "Riven Zhao", + "jim ZHOU", + "Mohammad ziar", + "ZioFesteeeer", + "zJairO", + "ZkyweR", + "Nagy Zoltán", + "Lukáš Zounek", + "ZpeedTube", + "|_Jenqa_|", + "¥¥S.A.N.A¥", + "Danijel Ćelić", + "Štěpán", + "Cristian Țicu", + "Μπαρλάς Παύλος-Ιάσονας", + "Ανέστης Πλήθος", + "Роман Абрамо", + "Роман Абрамов", + "Андрей (Krays)", + "Андрій", + "Богдан", + "опять Вильян", + "Тот самый Вильян", + "Влад", + "Даниил", + "данил", + "дибисяра", + "Дмитрий 228", + "Евгений(Eugene)", + "Артём Зобков (KoLenka)", + "Юстин Иглин", + "Игор", + "Кирилл", + "клаудкубес", + "Климов", + "Кирилл Климов", + "Андрей Коваленко", + "куатжан", + "Ваня Марков", + "Драган Милановић", + "Игор Милановић", + "Марко Милановић", + "Снежана Милановић", + "михаил", + "boba (Бодік) доперекладав Укр мову", + "Арсений Мостовщиков", + "Принцип", + "Пук-пук пук-пук", + "Пупсєль", + "Піптик💖", + "Михаил Радионов", + "Даниил Рахов \"DaNiiRuSPlay\"", + "Рома", + "Ромашка :3", + "Кирилл Рябцев", + "ZEPT\"Александр Фартунов\"", + "Эмир", + "Өмүрзаков Эрсултан", + "Ярослав \"Noiseaholic\"", + "қуатжан", + "اا", + "احمدرضا", + "احمد اسامه", + "احمد سني اسماعيل", + "الأول", + "مُحمَّد الأول", + "البطل", + "بسام البطل", + "رفيق العشي", + "ابو العواصف2020", + "عبدالرحمن النجم", + "امیرعلی", + "اوتاكوDZ", + "ایلی", + "بساام", + "جود", + "حسين حساني", + "جود حيدر", + "محمد خالد", + "امیرحسین دهقان", + "امید رضازاده", + "فاطمه عباس زاده ۸۴", + "فاطمه عباس زاده۸۴", + "ستسپ", + "سلطان سروش", + "محمد وائل سلطان", + "ص", + "عبداللہ صائم", + "boy hero بسام بو صالح", + "Adel NZ. | عادل", + "عبده", + "محمد کیان عرفان", + "محمد حسن عزیزی", + "علی", + "سيد عمر", + "عيسى", + "اللهم صل على محمد وآل محمد", + "امیر محمد", + "هادی مرادی", + "سعید مهجوری", + "مهدی", + "سید احمد موسوی", + "عادل ن.", + "نریمان", + "عادل نوروزی", + "ه۶۹", + "حسین وفایی‌فرد", + "انا يا عمر انا بران يا عمر انا بران يا عمر انا بران يا عمر انا بران يا عمر انا بران يا عمر انا بران يا عمر انا بران يا عمر انا بران يا عمر انا بران يا عمر انا بران يا عمر انا بران يا", + "١٢٣٤٥", + "٦٤٦٦٤٦٤٦", + "علیرضا پودینه", + "वेदाँश त्यागी", + "അർഷഖ് ഹസ്സൻ", + "วีรภัทร", + "แมวผงาด(JuniorMeowMeow)", + "๖̶ζ͜͡zephyro", + "ᗪ|乃|丂Я尺卂", + "✰ℭØØҜĬ£$✰", + "JPnatu なつ", + "クリーバー", + "ㅇㅇ", + "丁光正", + "中国玩家(日文区)", + "中国玩家ChinesePlayer", + "刘铭威", + "别闹我有药", + "别闹我有药/Medic", + "别闹我有药Medic", + "南宫銷子()", + "哔哩哔哩@Medic药", + "夏神(后期汉化修正)", + "小黑猫", + "张帅", + "徐安博", + "志夏", + "志夏。", + "志夏君deron", + "枫夜", + "毛毛毛大毛", + "炸弹朋友和Medic药", + "熊老三", + "盐焗汽水er", + "神仙", + "药药Medic", + "蔚蓝枫叶", + "陈星宇你就是歌姬吧", + "随风飘姚", + "鲨鱼服·Medic", + "鲲鹏元帅", + "꧁ℤephyro꧂", + "가라사대", + "공팔이", + "권찬근", + "김원재", + "넌", + "먹꾸리", + "박건희", + "김대중 부관참시", + "붐추", + "사람사는 세상", + "신라성", + "이지민", + "일베저장소", + "전감호", + "BombsquadKorea 네이버 카페", + "Zona-BombSquad", + "CrazySquad", + "Stazzy" + ] +} diff --git a/dist/ba_data/data/languages/arabic.json b/dist/ba_data/data/languages/arabic.json new file mode 100644 index 0000000..974917c --- /dev/null +++ b/dist/ba_data/data/languages/arabic.json @@ -0,0 +1,1882 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "لا يمكن لاسماء الحِسابَات أن تحتوي على رموز تعبيرية أو حروف غير ألفبائية", + "accountProfileText": "معلومات اللاعبين", + "accountsText": "حسابات", + "achievementProgressText": "${TOTAL} من أصل ${COUNT} إنجازاتك: أنجزت", + "campaignProgressText": "تقدم الحملة [HARD]:${PROGRESS}", + "changeOncePerSeason": "يمكنك تغييره مرة واحدة في الموسم", + "changeOncePerSeasonError": "يجب عليك الانتظار حتى الموسم القادم لتغيير هذا مجددا (${NUM} أيام )", + "customName": "الاسم المخصص", + "googlePlayGamesAccountSwitchText": "اذا اردت استخدام حساب غوغل بلاي اخر،\nقم بإستعمال تطبيق غوغل بلاي العاب لتحويله.", + "linkAccountsEnterCodeText": "ادخل الرمز", + "linkAccountsGenerateCodeText": "انشئ رمز", + "linkAccountsInfoText": "(مشاركة تقدمك مع الاجهزة الاخرى)", + "linkAccountsInstructionsNewText": "لربط حسابين،- انشئ رمز من الجهاز المراد انشاء الحساب فيه\n- وقم بإدخال الرمز في الجهاز الآخر\n\nالبيانات من الحساب الأول سوف يتم مشاركتها بين الجهازين\n\n من الحسابات كحد أقصى ${COUNT} يمكنك انشاء\n\n تنويه : فقط اربط الحسابات التي تملكها، إذا ربطت حسابك مع الأصدقاء،\n\n .لن يمكنكما اللعب معًا في نفس الوقت", + "linkAccountsInstructionsText": "لربط حسابين, انتج كود على احد الحسابين \nو ادخل هذا الكود على الاخر.\nالتقدم و المخزون سيشتركا.\nيمكنك ربط حتى ${COUNT} حسابات.\n\nكن حذراً; هذا لا يمكن استرجاعه", + "linkAccountsText": "ربط حساب", + "linkedAccountsText": ": حساباتي المرتبطة", + "manageAccountText": "إدارة الحساب", + "nameChangeConfirm": "هل تريد تغيير اسم حسابك إلى ${NAME}؟", + "resetProgressConfirmNoAchievementsText": "سوف يحذف هذا الخيار تقدمك في الحملات التعاونية ولن يحذف تذاكرك\nلا يمكن إلغاء هذا الخيار\nهل أنت متأكد ؟", + "resetProgressConfirmText": ":عند موافقتك على هذا الاخيار سوف يتم\n(حذف انجازاتك وتقدمك الحالي(لكن لن تخسر تَذَاكِرك\nإذا وافقت على هذا القرار لا يمكنك تراجع عنه\nهل أنت متأكد؟", + "resetProgressText": "امسح تقدمك", + "setAccountName": "حدد اسم للحساب", + "setAccountNameDesc": "اختر اسم لحسابك\nيمكنك استعمال الاسم من أحد حساباتك المرتبطة\nأو إنشاء اسم فريد.", + "signInInfoText": "،قم بتسجيل دخولك لتجمع بطاقات، وتتحدى اللاعبين حول العالم\n.ولمشاركة تقدمك عبر الأجهزة", + "signInText": "تسجيل الدخول", + "signInWithDeviceInfoText": "الحساب التلقائي متوفر فقط على هذا الجهاز", + "signInWithDeviceText": "سجل دخولك بحساب الجهاز", + "signInWithGameCircleText": "Game Circle سجل دخولك بواسطة", + "signInWithGooglePlayText": "Google Play سجل دخولك عبر", + "signInWithTestAccountInfoText": "(حساب موجود على هاتفك; استخدم حساب الهاتف للمتابعة)", + "signInWithTestAccountText": "تسجيل الدخول بحساب تجريبي", + "signInWithV2InfoText": "حساب يعمل على جميع المنصات", + "signInWithV2Text": "قم بتسجيل الدخول باستخدام حساب BombSquad", + "signOutText": "تسجيل الخروج", + "signingInText": "...جارٍ تسجيل دخولك", + "signingOutText": "...جارٍ تسجيل خروجك", + "testAccountWarningOculusText": "تحذير: انت تقوم بتسجيل الدخول باستخدام حساب تجريبي.\nسيستبدل بحساب حقيقي خلال هذا العام الذي من خلاله\nسوف تقدر على شراء البطاقات ومزايا أخرى.\n\nإلى الان يمكنك الحصول على جميع البطافات في اللعبة.\n(على الرغم من ذلك، قم بالحصول على حساب متقدم مجانا)", + "ticketsText": "بطاقاتك الحالية:${COUNT}", + "titleText": "الحساب", + "unlinkAccountsInstructionsText": "حدد حسابا لإلغاء ربطه", + "unlinkAccountsText": "إلغاء ربط الحسابات", + "unlinkLegacyV1AccountsText": "إلغاء ربط الحسابات القديمة (V1)", + "v2LinkInstructionsText": "استخدم هذا الارتباط لإنشاء حساب أو تسجيل الدخول.", + "viaAccount": "(${NAME} عبر الحساب)", + "youAreSignedInAsText": ": قمت بتسجيل الدخول كـ" + }, + "achievementChallengesText": "إنجازات التحديات", + "achievementText": "إنجاز", + "achievements": { + "Boom Goes the Dynamite": { + "description": "اقتل 3 أشخاص وضيعين باستخدام صندوق المتفجرات", + "descriptionComplete": "تم قتل 3 أشخاص وضيعين باستخدام صندوق متفجرات", + "descriptionFull": "${LEVEL} اقتل 3 وضيعين بالمتفجِّرات في", + "descriptionFullComplete": "${LEVEL} تم قتل 3 وضيعين بالمتفجِّرات في", + "name": "انفجار قادم من الديناميت" + }, + "Boxer": { + "description": "فز بدون استخدامك للقنابل", + "descriptionComplete": "لقد فزت بدون استخدام القنابل", + "descriptionFull": "بدون استخدام اي قنابل${LEVEL} قم بإكمال", + "descriptionFullComplete": "دون استخدام اي قنابل${LEVEL} اكمل", + "name": "مُلاكِمْ" + }, + "Dual Wielding": { + "descriptionFull": "وصل قطعتي تحكم (بالعتاد أو تطبيق)", + "descriptionFullComplete": "متصل بجهازي تحكم (بالعتاد أو تطبيق)", + "name": "اللكمة المزدوجة" + }, + "Flawless Victory": { + "description": "انتصر بدون التعرض للأذى", + "descriptionComplete": "لقد فزت بدون تعرضك للأذى", + "descriptionFull": "دون تعرضك للأذى${LEVEL} فُزْ", + "descriptionFullComplete": "دون تعرضك للأذى ${LEVEL} لقد فُزتَ", + "name": "الفوز المستحق" + }, + "Free Loader": { + "descriptionFull": "ابدأ بلعب الوضع الحر للجميع مع لاعبين أو أكثر", + "descriptionFullComplete": "تم بدء لعبة بوضع الحرية للجميع مع لاعِبَيْنْ أو أكثر", + "name": "الفريق المجاني" + }, + "Gold Miner": { + "description": "اقتل 6 خصوم بأستخدام الألغام الأرضيَّة", + "descriptionComplete": "تمَّ قتل 6 خصوم باستخدام الألغام الأرضيِّة", + "descriptionFull": "بأستخدام الألغام الأرضيَّة ${LEVEL} اقتل 6 خصوم في", + "descriptionFullComplete": "بأستخدام الألغام الأرضيَّة ${LEVEL} تمَّ قتل 6 خصوم في", + "name": "منقب الذهب" + }, + "Got the Moves": { + "description": "انتصر بدون استخدام اللكمات أو القنابل", + "descriptionComplete": "لقد انتصرت بدون استخدامك للكمات او القنابل", + "descriptionFull": "بدون استخدام اللكمات أو القنابل ${LEVEL} فز في", + "descriptionFullComplete": "بدون استخدام اللكمات أو القنابل ${LEVEL} لقد ربحت في", + "name": "حصلت على الحركات" + }, + "In Control": { + "descriptionFull": "(قم بتوصيل جهاز تحكم (جهاز أو تطبيق", + "descriptionFullComplete": "(تم توصيل جهاز تحكم (جهاز أو تطبيق", + "name": "تحت التحكم" + }, + "Last Stand God": { + "description": "سجل 1000 نقطة", + "descriptionComplete": "!لقد سجلت 1000 نقطة", + "descriptionFull": "${LEVEL} سجِّل 1000 نقطة في", + "descriptionFullComplete": "${LEVEL} لقد سجَّلت 1000 نقطة في", + "name": "القائد ${LEVEL}" + }, + "Last Stand Master": { + "description": "سجل 250 نقطة", + "descriptionComplete": "!سجلت 250 نقطة", + "descriptionFull": "${LEVEL} سجِّل 250 نقطة في", + "descriptionFullComplete": "${LEVEL} لقد سجَّلت 250 نقطة في", + "name": "معَلِّم ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "سجل 500 نقطة", + "descriptionComplete": "لقد سجَّلتَ 500 نقطة", + "descriptionFull": "${LEVEL} سجِّل 500 نقطة في", + "descriptionFullComplete": "${LEVEL} لقد سجَّلت 500 نقطة في", + "name": "ساحر ${LEVEL}" + }, + "Mine Games": { + "description": "اقتل 3 خصوم بإستخدام الالغام الأرضيَّة", + "descriptionComplete": "لقد قتلت 3 خصوم بلألغام الأرضيَّة", + "descriptionFull": "${LEVEL} اقتل 3 خصوم باستخدام الألغام الأرضيَّة في", + "descriptionFullComplete": "${LEVEL} لقد قتلت 3 خصوم بإستخدام الألغام الأرضيَّة في", + "name": "ألعاب الألغام" + }, + "Off You Go Then": { + "description": "إرمِ 3 خصوم خارج الحلبة", + "descriptionComplete": "لقد رميت 3 خصوم خارج الحلبة", + "descriptionFull": "${LEVEL} ارمِ 3 خصوم خارج الحلبة في", + "descriptionFullComplete": "${LEVEL} لقد رميت 3 خصوم خارج الحلبة في", + "name": "المنجنيق البشري" + }, + "Onslaught God": { + "description": "سجل 5000 نقطة", + "descriptionComplete": "!لقد سجلت 5000 نقطة", + "descriptionFull": "${LEVEL} سجِّل 5000 نقطة في", + "descriptionFullComplete": "${LEVEL} لقد سجَّلتَ 5000 نقطة في", + "name": "زعيم ${LEVEL}" + }, + "Onslaught Master": { + "description": "سجل 500 نقطة", + "descriptionComplete": "لقد سجَّلتَ 500 نقطة", + "descriptionFull": "${LEVEL} سجِّل 500 نقطة في", + "descriptionFullComplete": "${LEVEL} لقد سجَّلتَ 500 نقطة في", + "name": "${LEVEL} معلِّم" + }, + "Onslaught Training Victory": { + "description": "اهزم كل الموجات", + "descriptionComplete": "لقد هزمت كل الموجات", + "descriptionFull": "${LEVEL} اهزم كل الموجات في", + "descriptionFullComplete": "${LEVEL} اهزم كل الموجات في", + "name": "${LEVEL} انتصار" + }, + "Onslaught Wizard": { + "description": "سجل 1000 نقطة", + "descriptionComplete": "لقد سجَّلت 1000 نقطة", + "descriptionFull": "${LEVEL} سجِّل 1000 نقطة في", + "descriptionFullComplete": "${LEVEL} سجِّل 1000 نقطة في", + "name": "${LEVEL} ساحر" + }, + "Precision Bombing": { + "description": "فُزْ بدون اي قوى خارقة", + "descriptionComplete": "لقد فزتَ بدون أي قوى خارقة", + "descriptionFull": "بدون اي قوى خارقة${LEVEL} فز في", + "descriptionFullComplete": "بدون اي قوى خارقة${LEVEL} لقد فزتَ في", + "name": "دقة القصف" + }, + "Pro Boxer": { + "description": "فز دون استخدام أي قنابل", + "descriptionComplete": "لقد فُزْتَ بدون استخدام أي قنابل", + "descriptionFull": "بدون استخدام اي قنابل ${LEVEL} اكمل", + "descriptionFullComplete": "بدون استخدام أي قنابل ${LEVEL} لقد اكْمَلْتَ", + "name": "الملاكم البارع" + }, + "Pro Football Shutout": { + "description": "فز بدون ان تسمح للاشرار بالتسجيل", + "descriptionComplete": "لقد فُزْتَ بدون السَّماح للأشرار بالتَّسجيل", + "descriptionFull": "بدون أن تسمح للأشرار بالتَّسجيل ${LEVEL} فز في", + "descriptionFullComplete": "بدون السَّماح للأشرار بالتَّسجيل ${LEVEL} لقد فُزْتَ في", + "name": "${LEVEL} انتصار ساحق في" + }, + "Pro Football Victory": { + "description": "فز في اللعبة", + "descriptionComplete": "لقد فُزْتَ في اللعبة", + "descriptionFull": "${LEVEL} فز في اللعبة في", + "descriptionFullComplete": "${LEVEL} لقد فُزْتَ في اللعبة في", + "name": "${LEVEL} النصر" + }, + "Pro Onslaught Victory": { + "description": "اهزم كل الموجات", + "descriptionComplete": "لقد هزمْتَ كل الموجات", + "descriptionFull": "${LEVEL} اهزم كل الموجات في", + "descriptionFullComplete": "${LEVEL} لقد هزمتَ كل الموجات في", + "name": "${LEVEL} نصر" + }, + "Pro Runaround Victory": { + "description": "اكمل كل الموجات", + "descriptionComplete": "اكمل كل الموجات", + "descriptionFull": "${LEVEL} اكمل كل الموجات في", + "descriptionFullComplete": "${LEVEL} لقد اكملتَ كل الموجات في", + "name": "${LEVEL} النصر" + }, + "Rookie Football Shutout": { + "description": "فز بدون السماح للأشرار بإحراز النقاط", + "descriptionComplete": "لقد فُزْتَ بدون السَّماح للأشرار بإحراز النِّقاط", + "descriptionFull": "بدون السَّماح للأشرار بإحراز النِّقاط ${LEVEL} فُزْ في", + "descriptionFullComplete": "بدون السَّماح للأشرار بإحراز النِّقاط ${LEVEL} لقد فُزْتَ في", + "name": "${LEVEL} إنتصار ساحق" + }, + "Rookie Football Victory": { + "description": "فز في المباراة", + "descriptionComplete": "فاز في المباراة", + "descriptionFull": "${LEVEL} فز المباراة في", + "descriptionFullComplete": "${LEVEL} فاز المباراة في", + "name": "${LEVEL} النصر" + }, + "Rookie Onslaught Victory": { + "description": "هزيمة كل الجولات", + "descriptionComplete": "هزم كل الجولات", + "descriptionFull": "${LEVEL} اهزم كل الجولات في", + "descriptionFullComplete": "${LEVEL} هزم كل الجولات في", + "name": "${LEVEL} لقد انتصرت" + }, + "Runaround God": { + "description": "أحرز 2000 نقطة", + "descriptionComplete": "أحرزت 2000 نقطة", + "descriptionFull": "${LEVEL} أحرز 2000 نقطة في", + "descriptionFullComplete": "${LEVEL} أحرزت 2000 نقطة في", + "name": "${LEVEL} ملك" + }, + "Runaround Master": { + "description": "أحرز 500 نقطة", + "descriptionComplete": "أحرزت 500 نقطة", + "descriptionFull": "${LEVEL} أحرز 500 نقطة في", + "descriptionFullComplete": "${LEVEL} أحرزت 500 نقطة في", + "name": "${LEVEL} استاذ" + }, + "Runaround Wizard": { + "description": "أحرز 1000 نقطة", + "descriptionComplete": "أحرزت 1000 نقطة", + "descriptionFull": "${LEVEL} أحرز 1000 نقطة في", + "descriptionFullComplete": "${LEVEL} أحرزت 1000 نقطة في", + "name": "${LEVEL} ساحر" + }, + "Sharing is Caring": { + "descriptionFull": "شارك اللعبة مع صديق بنجاح", + "descriptionFullComplete": "شارك اللعبة مع صديق بنجاح", + "name": "المشاركة اهتمام" + }, + "Stayin' Alive": { + "description": "فز بدون أن تموت", + "descriptionComplete": "لقد فُزت بدون ان تموت", + "descriptionFull": "بدون أن تموت ${LEVEL} فز", + "descriptionFullComplete": "بدون أن يموت ${LEVEL} لقد فزت", + "name": "البقاء حيا" + }, + "Super Mega Punch": { + "description": "إلحاق الضرر 100٪ بلكمة واحدة", + "descriptionComplete": "ألحق الضرر 100٪ بلكمة واحدة", + "descriptionFull": "${LEVEL} إلحاق الضرر 100٪ بلكمة واحدة في", + "descriptionFullComplete": "${LEVEL} ألحق الضرر 100٪ بلكمة واحدة في", + "name": "لكمة خارقة جبارة" + }, + "Super Punch": { + "description": "إلحاق الضرر 50٪ بلكمة واحدة", + "descriptionComplete": "ألحق الضرر 50٪ بلكمة واحدة", + "descriptionFull": "${LEVEL} إلحاق الضرر 50٪ بلكمة واحدة في", + "descriptionFullComplete": "${LEVEL} ألحق الضرر 50٪ بلكمة واحدة في", + "name": "لكمة خارقة" + }, + "TNT Terror": { + "description": "TNT أقتل 6 من الأشرار بواسطة", + "descriptionComplete": "TNT قتل 6 من الأشرار بواسطة", + "descriptionFull": "${LEVEL} في TNT أقتل 6 من الأشرار بواسطة", + "descriptionFullComplete": "${LEVEL} في TNT أقتل 6 من الأشرار بواسطة", + "name": "TNT رعب" + }, + "Team Player": { + "descriptionFull": "بدء لعبة الفريق مع 4+ اللاعبين", + "descriptionFullComplete": "بدء لعبة الفرق مع 4+ اللاعبين", + "name": "لاعب فريق" + }, + "The Great Wall": { + "description": "أوقف كل الأشخاص السيئين", + "descriptionComplete": "أوقف كل شخص سيء", + "descriptionFull": "${LEVEL} أوقف كل شخص سيء في", + "descriptionFullComplete": "${LEVEL} أوقف كل شخص سيء في", + "name": "السور العظيم" + }, + "The Wall": { + "description": "أوقف كل شخص سيء", + "descriptionComplete": "أوقف كل شخص سيء", + "descriptionFull": "${LEVEL} أوقف كل شخص سيء في", + "descriptionFullComplete": "${LEVEL} أوقف كل شخص سيء في", + "name": "الجدار" + }, + "Uber Football Shutout": { + "description": "فز بدون السماح للأشرار بإحراز النقاط", + "descriptionComplete": "فاز بدون السماح للأشرار بإحراز النقاط", + "descriptionFull": "بدون السماح للأشرار بإحراز النقاط ${LEVEL} فز", + "descriptionFullComplete": "بدون السماح للأشرار بإحراز النقاط ${LEVEL} فاز", + "name": "${LEVEL} إنتصار ساحق" + }, + "Uber Football Victory": { + "description": "فز بالمباراة", + "descriptionComplete": "فاز بالمباراة", + "descriptionFull": "${LEVEL} فز بالمباراة في", + "descriptionFullComplete": "${LEVEL} فاز بالمباراة في", + "name": "${LEVEL} إنتصار" + }, + "Uber Onslaught Victory": { + "description": "انتصر في كل الجولات", + "descriptionComplete": "هَزَم كل الجولات", + "descriptionFull": "${LEVEL} اهزم كل الجولات في", + "descriptionFullComplete": "${LEVEL} هزم كل الجولات في", + "name": "${LEVEL} إنتصار" + }, + "Uber Runaround Victory": { + "description": "أكمل كل الجولات", + "descriptionComplete": "أكملت كل الجولات", + "descriptionFull": "اكمل كل الجولات في ${LEVEL}", + "descriptionFullComplete": "أكملت كل الجولات في ${LEVEL}", + "name": "${LEVEL} النصر" + } + }, + "achievementsRemainingText": "الإنجازات المتبقية", + "achievementsText": "الإنجازات", + "achievementsUnavailableForOldSeasonsText": "المعذرة، الإنجازات للمواسم القديمة غير متوفرة", + "activatedText": "${THING} تم تفعيله.", + "addGameWindow": { + "getMoreGamesText": "الحصول على المزيد من الألعاب", + "titleText": "إضافة لعبة" + }, + "allowText": "السماح", + "alreadySignedInText": "تم تسجيل الدخول من حسابك من جهاز آخر.\n يرجى تبديل الحسابات أو إغلاق اللعبة على الأجهزة الأخرى\n وحاول مرة أخرى.", + "apiVersionErrorText": "خطأ في تحميل الجزء ${NAME}; انه مخصص للإصدار رقم ${VERSION_USED}; يجب استخدام الإصدار ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"ذاتي\" فعله فقط عندما تكون سماعات الأذن موصولة", + "headRelativeVRAudioText": "صوت VR موافق مع حركة الرأس", + "musicVolumeText": "مستوى الموسيقى", + "soundVolumeText": "مستوى الموسيقى", + "soundtrackButtonText": "المقاطع الصوتية", + "soundtrackDescriptionText": "(اختر موسيقاك الخاصة لتعمل خلال اللعب)", + "titleText": "الصوت" + }, + "autoText": "ذاتي الاختيار", + "backText": "للخلف", + "banThisPlayerText": "حظر هاذا الاعب", + "bestOfFinalText": "الافضل في ${COUNT}", + "bestOfSeriesText": "من السلسلة ${COUNT}الأفضل في", + "bestOfUseFirstToInstead": 0, + "bestRankText": "افضل ما أحرزت #${RANK}", + "bestRatingText": "أفضل معدّل قد أحرزته ${RATING}", + "bombBoldText": "قنبلة", + "bombText": "قنبلة", + "boostText": "تقوية", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} تمّ ضبطه بالتطبيق ذاته", + "buttonText": "زر", + "canWeDebugText": "هل ترغب ان تقوم فرقة القنبلة تلقائيا بالتبليغ عن المشاكل والاخطاء التقنية \nوالفنيه وبعض المعلومات الاساسية الى موفر اللعبة ؟ \n\nهذه البيانات لا تحتوي على اي معلومات شخصيه و هي تساعد على ابقاء\n اللعبه تعمل بشكل سلس و بدون اخطاء.", + "cancelText": "إلغاء الأمر", + "cantConfigureDeviceText": "المعذرة، ${DEVICE} لا يمكن تخصيصه", + "challengeEndedText": "هذا التحدي قد انتهى", + "chatMuteText": "اسكات الدردشة", + "chatMutedText": "تم اسكات الدردشة", + "chatUnMuteText": "تحرير الدردشة", + "choosingPlayerText": "<يختار لاعب>", + "completeThisLevelToProceedText": "يجب أن تكمل هذه المرحلة ليتم الاجراء", + "completionBonusText": "علاوة الاكمال", + "configControllersWindow": { + "configureControllersText": "ضبط قبضات التحكّم", + "configureKeyboard2Text": "ضبط لوحة مفاتيح اللاعب الثاني", + "configureKeyboardText": "ضبط لوحة المفاتيخ", + "configureMobileText": "أجهزة المحمول كقبضة تحكّم", + "configureTouchText": "ضبط شاشة اللمس", + "ps3Text": "قبضات تحكّم PS3", + "titleText": "قبضات التحكم", + "wiimotesText": "Wiimotes", + "xbox360Text": "يد ألعاب أكس بوكس 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "ملاحظة: إن دعم قبضات التحكم يتباين تبعاً للجهاز و نظام ال Android", + "pressAnyButtonText": "اضغط أيّ زر على قبضة التحكّم التي تريد أن تضبطها", + "titleText": "ضبط قبضات التحكّم" + }, + "configGamepadWindow": { + "advancedText": "خيارات متطوّرة", + "advancedTitleText": "اعداد متقدم ليد الألعاب", + "analogStickDeadZoneDescriptionText": "(فعّل هذه إذا كانت شخصيّتك 'تنحرف' تحرّر عصى التحكّم)", + "analogStickDeadZoneText": "مجال الموت للعصى التماثلية", + "appliesToAllText": "(تنطبق على جميع قبضات التحكّم من هذا النوع)", + "autoRecalibrateDescriptionText": "(فعّل هذه إذا كانت شخصيّتك لاتتحرّك بالسرعة العظما)", + "autoRecalibrateText": "ضبط آلي للعصى التماثلية", + "axisText": "محور", + "clearText": "محو", + "dpadText": "أزرار أسهم", + "extraStartButtonText": "زر بدء إضافي", + "ifNothingHappensTryAnalogText": "اذا لم يحدث شيء، جرّب الاسناد للعصى التماثلية.", + "ifNothingHappensTryDpadText": "اذا لم يحدث شيء، جرّب الاسناد لأزرار الأسهم.", + "ignoreCompletelyDescriptionText": "(امنع هذه القبضة من التأثير على أحد العبة أو القوائم)", + "ignoreCompletelyText": "تجاهل كاملاً", + "ignoredButton1Text": "تمّ تجاهل الزر 1", + "ignoredButton2Text": "تمّ تجاهل الزرّ 2", + "ignoredButton3Text": "تمّ تجاهل الزر 3", + "ignoredButton4Text": "تمّ تجاهل الزر 4", + "ignoredButtonDescriptionText": "(استخدم هذه لتجنّب 'home' أو 'sync' من التأثير على واجهة المستخدم)", + "pressAnyAnalogTriggerText": "اضغط على أي محفّز تماثلي...", + "pressAnyButtonOrDpadText": "اضغط على أي زر أو أحد أزرار الأسهم", + "pressAnyButtonText": "اضغط أيّ زر...", + "pressLeftRightText": "اضغط لليمين أو لليسار", + "pressUpDownText": "اضغط للأعلى أو للأسفل", + "runButton1Text": "زر الركض 1", + "runButton2Text": "زر الركض 2", + "runTrigger1Text": "محفّز الركض 1", + "runTrigger2Text": "محفّز الركض 2", + "runTriggerDescriptionText": "(المحفّز التماثلي يسمح لك الركض بسرعات مختلفة)", + "secondHalfText": "استخدم هذه لضبط النصف الثاني من جهاز قبضتين في واحد الذي يظهر كقبضة واحدة.", + "secondaryEnableText": "تفعيل", + "secondaryText": "قبضة تحكّم ثانويّة", + "startButtonActivatesDefaultDescriptionText": "(الغي تفعيل هذه اذا كان زر البدء خاصّتك هو أكثر من زر 'قائمة')", + "startButtonActivatesDefaultText": "زر البدء يفعل الأداة الافتراضية", + "titleText": "اعداد يد التحكم", + "twoInOneSetupText": "إعدادات أداة التحكم 2 في 1", + "uiOnlyDescriptionText": "(منع هذا المراقب من الانضمام في الواقع لعبة)", + "uiOnlyText": "الحد من استخدام القائمة", + "unassignedButtonsRunText": "جميع الأزرار غير المعينة تشغيل", + "unsetText": "<إلغاء تعيين>", + "vrReorientButtonText": "VR زر إعادة التوجيه" + }, + "configKeyboardWindow": { + "configuringText": "تكوين ${DEVICE}", + "keyboard2NoteText": "ملاحظة: يمكن لمعظم لوحات المفاتيح تسجيل عدد قليل من ضغطات المفاتيح في\nمرة واحدة، لذلك وجود لاعب لوحة المفاتيح الثانية قد تعمل بشكل أفضل\nإذا كان هناك لوحة مفاتيح منفصلة تعلق لهم لاستخدامها.\nلاحظ أنك ستظل بحاجة إلى تعيين مفاتيح فريدة إلى\nلاعبين اثنين حتى في هذه الحالة." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "مقياس التحكم في العمل", + "actionsText": "أفعال", + "buttonsText": "الأزرار", + "dragControlsText": "< اسحب عناصر التحكم لإعادة وضعها >", + "joystickText": "عصا التحكم", + "movementControlScaleText": "مقياس مراقبة الحركة", + "movementText": "حركة", + "resetText": "إعادة تعيين", + "swipeControlsHiddenText": "إخفاء أيقونات السحب", + "swipeInfoText": "'انتقاد' الضوابط أسلوب تأخذ قليلا التعود على ولكن\nتجعل من السهل للعب دون النظر إلى الضوابط.", + "swipeText": "مسحة", + "titleText": "تهيئة شاشة اللمس" + }, + "configureItNowText": "هل تريد تهيئته الآن؟", + "configureText": "تهيئة", + "connectMobileDevicesWindow": { + "amazonText": "متجر تطبيقات أمازون", + "appStoreText": "المتجر", + "bestResultsText": "لتحقيق أفضل النتائح ستحتاج اتصال انترنت سريع .. يمكنك \nزيادة السرعة بايقاف الاجهزة الاخرة المتصلة بالشبكة، أو اللعب \nقرب موزع الشبكة، أو الاتصال بمخدم اللعبة باستخدام الكابل \nالمباشر الى الشبكة", + "explanationText": "لاستخدام الهاتف الذكي أو الكمبيوتر اللوحي باعتبارها وحدة تحكم لاسلكية،\nتثبيت التطبيق \"${REMOTE_APP_NAME}\"عليه. أي عدد من الأجهزة\nيمكن الاتصال لعبة ${APP_NAME}عبر واي-في، وأنه مجاني!", + "forAndroidText": "لأجهزة الأندرويد:", + "forIOSText": "لنظام التشغيل أيفون:", + "getItForText": "احصل على ${REMOTE_APP_NAME} لنظام التشغيل يوس في أبل أب ستور\nأو للأندرويد في متجر جوجل بلاي أو الأمازون أبستور", + "googlePlayText": "جوجل بلاي", + "titleText": "استخدام أجهزة الجوال كأجهزة تحكم:" + }, + "continuePurchaseText": "${PRICE}?اكمل ل", + "continueText": "تابع", + "controlsText": "ضوابط", + "coopSelectWindow": { + "activenessAllTimeInfoText": "هذا لا ينطبق على الترتيب في جميع الأوقات.", + "activenessInfoText": "هذا المضاعف يرتفع في أيام عندما كنت\nواللعب وقطرات على أيام عندما كنت لا.", + "activityText": "نشاط", + "campaignText": "حملة", + "challengesInfoText": "كسب الجوائز لاستكمال الألعاب المصغرة.\n\nالجوائز ومستويات صعوبة زيادة\nفي كل مرة يتم الانتهاء من التحدي و\nتنخفض عندما تنتهي صلاحية واحدة أو يتم مصادرتها.", + "challengesText": "التحديات", + "currentBestText": "الحالي أفضل", + "customText": "العادة", + "entryFeeText": "دخول", + "forfeitConfirmText": "هل تريد التخلي عن هذا التحدي؟", + "forfeitNotAllowedYetText": "ولا يمكن التغلب على هذا التحدي بعد.", + "forfeitText": "مصادرة", + "multipliersText": "مضاعفات", + "nextChallengeText": "التحدي القادم", + "nextPlayText": "اللعب التالي", + "ofTotalTimeText": "من ${TOTAL}", + "playNowText": "العب الان", + "pointsText": "نقاط", + "powerRankingFinishedSeasonUnrankedText": "(موسم مكتمل بدون ترتيب)", + "powerRankingNotInTopText": "( ليس في أول ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} نقطة", + "powerRankingPointsMultText": "(x ${NUMBER} النقاط)", + "powerRankingPointsText": "${NUMBER} النقاط", + "powerRankingPointsToRankedText": "{اجمع} من {المتبقي} النقاط", + "powerRankingText": "ترتيب الطاقة", + "prizesText": "الجوائز", + "proMultInfoText": "اللاعبين الذين لديهم الترقية ${PRO}\nالحصول على ${PERCENT}٪ بوينت بوست هنا.", + "seeMoreText": "المزيد . . .", + "skipWaitText": "تخطي الإنتظار", + "timeRemainingText": "الوقت المتبقي", + "toRankedText": "إلى المرتبة", + "totalText": "مجموع", + "tournamentInfoText": "تنافس على درجات عالية مع\nلاعبين آخرين في الدوري الخاص بك.\n\nيتم منح الجوائز إلى أعلى نقاط\nاللاعبين عند انتهاء وقت البطولة.", + "welcome1Text": "مرحبا بك في ${LEAGUE}. يمكنك تحسين الخاص بك\nترتيب الدوري من خلال كسب تقييمات النجوم، والانتهاء\nوالإنجازات، والفوز بالجوائز في البطولات.", + "welcome2Text": "يمكنك أيضا الحصول على تذاكر من العديد من الأنشطة نفسها.\nتذاكر يمكن استخدامها لفتح شخصيات جديدة، والخرائط، و\nالألعاب المصغرة، للدخول البطولات، وأكثر من ذلك.", + "yourPowerRankingText": "تصنيف الطاقة:" + }, + "copyConfirmText": "نسخ إلى اللوحة", + "copyOfText": "${NAME} نسخ", + "copyText": "ينسخ", + "createEditPlayerText": "<اصنع او عدل حساب>", + "createText": "اصنع", + "creditsWindow": { + "additionalAudioArtIdeasText": "الأصوات الإضافية، الأعمال المبتكرة، والأفكار من قبل ${NAME}", + "additionalMusicFromText": "المعازف الإضافية من ${NAME}", + "allMyFamilyText": "كل أصدقائي وعائلتي التي ساعدتني لتجربة اللعبة", + "codingGraphicsAudioText": "البرمجة، والرسومات، والأصوات انشأها ${NAME}", + "languageTranslationsText": "مترجمي اللُّغات", + "legalText": ":الحقوق القانونية", + "publicDomainMusicViaText": "معازف النطاق العام بواسطة ${NAME}", + "softwareBasedOnText": "هذه البرمجيات تعتمد على جزء من عمل ${NAME}", + "songCreditText": "${PERFORMER} تم تأديتها من قبل ${TITLE}\n نشر بواسطة ${PUBLISHER}،توزيع ${ARRANGER}، تم التأليف من قبل ${COMPOSER}\nبتصريح من ${SOURCE}", + "soundAndMusicText": "الأصوات والمعازف:", + "soundsText": "تأثيرات الصوت من: (${SOURCE})", + "specialThanksText": "شكر خاص:", + "thanksEspeciallyToText": "والشكر خاصةً لـ${NAME}", + "titleText": "فريق عمل ${APP_NAME}", + "whoeverInventedCoffeeText": "الشخص الذي اخترع القهوة" + }, + "currentStandingText": "تصنيفك الحالي هو #${RANK}", + "customizeText": "تعديل...", + "deathsTallyText": "${COUNT} وفيات", + "deathsText": "موت", + "debugText": "التصحيح", + "debugWindow": { + "reloadBenchmarkBestResultsText": "ملاحظة: فمن المستحسن أن قمت بتعيين إعدادات-> الرسومات-> القوام إلى 'عالية' أثناء اختبار هذا.", + "runCPUBenchmarkText": "قياس أداء المعالج", + "runGPUBenchmarkText": "قياس أداء معالج الرسوميات", + "runMediaReloadBenchmarkText": "قياس أداء وحدة تحميل الوسائط", + "runStressTestText": "تشغيل اختبار الإجهاد", + "stressTestPlayerCountText": "عدد اللاعبين", + "stressTestPlaylistDescriptionText": "اختبار الإجهاد قائمة التشغيل", + "stressTestPlaylistNameText": "اسم قائمة التشغيل", + "stressTestPlaylistTypeText": "نوع قائمة التشغيل", + "stressTestRoundDurationText": "مدة الجولة", + "stressTestTitleText": "اختبار الإجهاد", + "titleText": "معايير واختبارات الإجهاد", + "totalReloadTimeText": "إجمالي وقت إعادة التحميل: ${TIME} (راجع سجل للحصول على التفاصيل)" + }, + "defaultGameListNameText": "الافتراضي ${PLAYMODE} قائمة التشغيل", + "defaultNewGameListNameText": "قائمة تشغيل ${PLAYMODE}", + "deleteText": "حذف", + "demoText": "عرض", + "denyText": "رفض", + "deprecatedText": "إهمال", + "desktopResText": "جودة سطح المكتب", + "deviceAccountUpgradeText": "تحذير:\nانت مسجل الدهول بحساب الجهاز (${NAME}).\nحسابات الجهاز (Device) سيتم حذفها في المستقبل.\nقم بالتطوير الى حساب V2 اذا اردت ان تقوم بحفظ تقدمك.", + "difficultyEasyText": "سهل", + "difficultyHardOnlyText": "الوضع الصعب فقط", + "difficultyHardText": "صعب", + "difficultyHardUnlockOnlyText": "لا يمكن فتح هذا المستوى إلا في الوضع الصعب.\n هل تعتقد أن لديك ما يلزم!؟!؟!", + "directBrowserToURLText": "وجه متصفح الشابكة إلى العنوان التالي:", + "disableRemoteAppConnectionsText": "تعطيل اتصالات التطبيق عن بعد", + "disableXInputDescriptionText": "يسمح أكثر من 4 وحدات تحكم ولكن قد لا تعمل كذلك.", + "disableXInputText": "xinput تعطيل", + "doneText": "تم", + "drawText": "تعادل", + "duplicateText": "مكرر", + "editGameListWindow": { + "addGameText": "إضافة\nلعبة", + "cantOverwriteDefaultText": "لا يمكن استبدال قائمة التشغيل الافتراضية!", + "cantSaveAlreadyExistsText": "قائمة تشغيل بهذا الاسم موجودة من قبل!", + "cantSaveEmptyListText": "لا يمكن حفظ قائمة تشغيل فارغة!", + "editGameText": "اضافة\nلعبه", + "listNameText": "قائمة اسماء الالعاب", + "nameText": "اسم", + "removeGameText": "محو\nالعبه", + "saveText": "قائمة الحفظ", + "titleText": "قائمة تشغيل محرر" + }, + "editProfileWindow": { + "accountProfileInfoText": "يحتوي هذا الملف الشخصي الفريد على اسم\nوأيقونة تعتمد على حسابك.\n\n${ICONS}\n\nانشئ ملف شخصي مخصص لاستعمال\nاسماء مختلفة أو أيقونات مخصصة.", + "accountProfileText": "(ملف تعريف الحساب)", + "availableText": "الاسم \"${NAME}\" متاح.", + "characterText": "الشخصية", + "checkingAvailabilityText": "جار التحقق من التوفر ل \"${NAME}\" ...", + "colorText": "اللون", + "getMoreCharactersText": "الحصول على المزيد من الشخصيات ...", + "getMoreIconsText": "الحصول على المزيد من الرموز ...", + "globalProfileInfoText": "ملفات اللاعب العالمية مصممة لتملك\nاسم عالمي فريد. وأيضًا تتضمن أيقونات مخصصة", + "globalProfileText": "(ملف شخصي عالمي)", + "highlightText": "تسليط الضوء", + "iconText": "أيقونة", + "localProfileInfoText": "ملامح لاعب المحلي ليس لديهم رموز وأسمائهم\nغير مضمونة لتكون فريدة من نوعها. الترقية إلى ملف شخصي عام\nلحجز اسم فريد وإضافة رمز مخصص.", + "localProfileText": "(الملف الشخصي المحلي)", + "nameDescriptionText": "اسم اللاعب", + "nameText": "الاسم", + "randomText": "عشوائي", + "titleEditText": "تعديل الملف الشخصي", + "titleNewText": "ملف شخصي جديد", + "unavailableText": "\"${NAME}\" غير متوفر؛ حاول اسم آخر.", + "upgradeProfileInfoText": "هذا سيحفظ اسم لاعب في جميع أنحاء العالم\nوتسمح لك بتعيين رمز مخصص لها.", + "upgradeToGlobalProfileText": "الترقية إلى الملف الشخصي العالمي" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "لا يمكنك حذف الصوت الافتراضي.", + "cantEditDefaultText": "لا يمكن التعديل على تسجيل الصوت الاساسي. قم بنسخه او أنشئ واحدا جديدا", + "cantOverwriteDefaultText": "لا يمكن الكتابة فوق الصوت الافتراضي", + "cantSaveAlreadyExistsText": "يوجد مقطع صوتي بهذا الاسم من قبل.", + "defaultGameMusicText": "<موسيقى اللعبة الافتراضية>", + "defaultSoundtrackNameText": "الصوت الافتراضي", + "deleteConfirmText": "حذف الموسيقى التصويرية:\n\n'${NAME}'؟", + "deleteText": "حذف\nتسجيل صوتي", + "duplicateText": "مكرر\nتسجيل صوتي", + "editSoundtrackText": "محرر الموسيقى التصويرية", + "editText": "تصحيح\nتسجيل صوتي", + "fetchingITunesText": "جارٍ جلب قوائم تشغيل تطبيق الموسيقى ...", + "musicVolumeZeroWarning": "تحذير: يتم ضبط مستوى صوت الموسيقى على 0", + "nameText": "اسم", + "newSoundtrackNameText": "الموسيقى التصويرية ${COUNT}", + "newSoundtrackText": "موسيقى تصويرية جديدة:", + "newText": "الجديد\nتسجيل صوتي", + "selectAPlaylistText": "حدد قائمة تشغيل", + "selectASourceText": "مصدر الموسيقى", + "testText": "اختبار", + "titleText": "الموسيقى التصويرية", + "useDefaultGameMusicText": "الافتراضي لعبة الموسيقى", + "useITunesPlaylistText": "قائمة تشغيل تطبيق الموسيقى", + "useMusicFileText": "ملف الموسيقى (mp3، الخ)", + "useMusicFolderText": "مجلد ملفات الموسيقى" + }, + "editText": "تعديل", + "endText": "إنهاء", + "enjoyText": "استمتع", + "epicDescriptionFilterText": "${DESCRIPTION} بحركة ملحمية بطيئة", + "epicNameFilterText": "الملحمي ${NAME}", + "errorAccessDeniedText": "تم الرفض", + "errorDeviceTimeIncorrectText": ".من الساعات ${HOURS} وقت جهازك غير صحيح بمقدار\n.هذا سوف يتسبب بمشاكل\nمن فضلك قم بالتحقق من اعدادات الوقت.", + "errorOutOfDiskSpaceText": "انتهت مساحة التخزين", + "errorSecureConnectionFailText": "تعذر انشاء اتصال سحابي أمن; قد تفشل وظائف الشبكة.", + "errorText": "خطا", + "errorUnknownText": "خطا غير معروف", + "exitGameText": "هل تريد الخروج من ${APP_NAME}؟", + "exportSuccessText": "تم تصدير ${NAME} '.", + "externalStorageText": "تخزين خارجي", + "failText": "فشل", + "fatalErrorText": "آه؛ شيء مفقود أو مكسور.\nالرجاء محاولة إعادة تثبيت التطبيق أو\nاتصل ${EMAIL} للحصول على مساعدة.", + "fileSelectorWindow": { + "titleFileFolderText": "حدد ملف أو مجلد", + "titleFileText": "اختر ملف", + "titleFolderText": "اختر مجلد", + "useThisFolderButtonText": "استخدم هاذا المجلد" + }, + "filterText": "مصفاة", + "finalScoreText": "النتيجة النهائية", + "finalScoresText": "النتيجة النهائية", + "finalTimeText": "الوقت النهائي", + "finishingInstallText": "الانتهاء من التثبيت؛ لحظة واحدة ..", + "fireTVRemoteWarningText": "* للحصول على تجربة أفضل، واستخدام\nلعبة تحكم أو تثبيت\n'${REMOTE_APP_NAME}' التطبيق على الخاص بك\nالهواتف والأجهزة اللوحية.", + "firstToFinalText": "من الأول إلى - ${COUNT} نهائي", + "firstToSeriesText": "من الأول إلى - ${COUNT} السلسلة", + "fiveKillText": "خمسة قتل !!!", + "flawlessWaveText": "موجة لا تشوبه شائبة!", + "fourKillText": "قتل رباعي !!!", + "friendScoresUnavailableText": ".نقاط الأصدقاء غير متوفرة", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "لعبة ${COUNT} قادة", + "gameListWindow": { + "cantDeleteDefaultText": "لا يمكنك حذف قائمة التشغيل الافتراضية.", + "cantEditDefaultText": "لا يمكن تعديل قائمة التشغيل الافتراضية! تكراره أو إنشاء واحدة جديدة.", + "cantShareDefaultText": "لا يمكنك مشاركة قائمة التشغيل الافتراضية.", + "deleteConfirmText": "ازالة \"${LIST}\"?", + "deleteText": "محو\nقائمة العب", + "duplicateText": "مكرر\nقائمة التشغيل", + "editText": "تصحيح\nقائمة التشغيل", + "newText": "الجديد\nقائمة التشغيل", + "showTutorialText": "عرض البرنامج التعليمي", + "shuffleGameOrderText": "ترتيب لعبة المراوغة", + "titleText": "تخصيص ${TYPE} قوائم تشغيل" + }, + "gameSettingsWindow": { + "addGameText": "اضف لعبه" + }, + "gamesToText": "${WINCOUNT} من الألعاب إلى ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "تذكر: يمكن لأي جهاز في الحفلة الحصول علي\nاكثر من لاعب واحد إذا كان لديك ما يكفي من وحدات التحكم.", + "aboutDescriptionText": "استخدم علامات التبويب هذه لتجميع أحد الحفلات.\n\nتتيح لك الأطراف لعب الألعاب والبطولات\nمع أصدقائك عبر الأجهزة المختلفة.\n\nاستخدم الزر ${PARTY} في أعلى اليسار\nدردشة والتفاعل مع حزبكم.\n(على وحدة تحكم، اضغط ${BUTTON} بينما في القائمة)", + "aboutText": "حول", + "addressFetchErrorText": "<خطأ في جلب العناوين>", + "appInviteMessageText": "أرسل ${NAME} تذاكر ${COUNT} في ${APP_NAME}", + "appInviteSendACodeText": "إرسال لهم رمز", + "appInviteTitleText": "${APP_NAME} دعوة التطبيق", + "bluetoothAndroidSupportText": "(يعمل مع أي جهاز الروبوت دعم بلوتوث)", + "bluetoothDescriptionText": "المضيف / الانضمام إلى طرف عبر البلوتوث:", + "bluetoothHostText": "المضيف عبر البلوتوث", + "bluetoothJoinText": "الانضمام عبر البلوتوث", + "bluetoothText": "بلوتوث", + "checkingText": "تدقيق...", + "copyCodeConfirmText": "تم نسخ الرمز الى الحافظة", + "copyCodeText": "نسخ الرمز", + "dedicatedServerInfoText": "للحصول على أفضل النتائج، قم بإعداد خادم مخصص. اطلع على bombsquadgame.com/server لمعرفة كيفية إجراء ذلك.", + "disconnectClientsText": "سيؤدي هذا إلى فصل المشغل ${COUNT}\nفي حزبكم. هل أنت واثق؟", + "earnTicketsForRecommendingAmountText": "سيتلقى الأصدقاء تذاكر بقيمة ${COUNT} إذا جربو اللعبة\n(وستتلقى ${YOU_COUNT} لكل من يفعل)", + "earnTicketsForRecommendingText": "مشاركة اللعبة\nلتذاكر مجانية ...", + "emailItText": "البريد الإلكتروني", + "favoritesSaveText": "حفظ كمفضلة", + "favoritesText": "المفضلة", + "freeCloudServerAvailableMinutesText": "السيرفر التالي متوفر في ${MINUTES} من الدقائق", + "freeCloudServerAvailableNowText": "السيرفر التالي متوفر الأن!", + "freeCloudServerNotAvailableText": "لا توجد أي سيرفرات متاحة", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} تذاكر من ${NAME}", + "friendPromoCodeAwardText": "سوف تتلقى تذاكر ${COUNT} في كل مرة يتم استخدامها.", + "friendPromoCodeExpireText": "ستنتهي صلاحية الشفرة خلال ${EXPIRE_HOURS} ساعة وتعمل فقط للاعبين الجدد.", + "friendPromoCodeInstructionsText": "لاستخدامها ، افتح ${APP_NAME} وانتقل إلى \"الإعدادات-> متقدم-> إدخال الرمز\".\nانظر bombsquadgame.com للحصول على روابط التحميل لجميع المنصات المدعومة.", + "friendPromoCodeRedeemLongText": "ويمكن استرداد قيمتها بمبلغ ${MAX_USES} من التذاكر المجانية بقيمة ${COUNT}.", + "friendPromoCodeRedeemShortText": "ويمكن استبدالها ل ${COUNT} تذاكر في اللعبة.", + "friendPromoCodeWhereToEnterText": "(في \"الإعدادات -> متقدم -> أدخل الرمز\")", + "getFriendInviteCodeText": "احصل على كود دعوة من صديق", + "googlePlayDescriptionText": "دعوة لاعبين غوغل بلاي لحزبكم:", + "googlePlayInviteText": "دعوة", + "googlePlayReInviteText": "هناك ${COUNT} لاعب غوغل بلاي (s) في حفلك\nالذي سيتم فصله إذا قمت بدعوة دعوة جديدة.\nتضمينها في الدعوة الجديدة لاستعادتها.", + "googlePlaySeeInvitesText": "راجع الدعوات", + "googlePlayText": "غوغل بلاي", + "googlePlayVersionOnlyText": "(الروبوت / جوجل اللعب الإصدار)", + "hostPublicPartyDescriptionText": "صنع حفلة عامة", + "hostingUnavailableText": "صنع السيرفر غير متوفر", + "inDevelopmentWarningText": "ملحوظة:\n\nاللعب عبر الإنترنت هي ميزة لا تزال تحت التطوير.\nحاليًا، يفضل أن يكون جميع اللاعبين\nمتصلين على نفس شبكة WI-FI.", + "internetText": "انترنت", + "inviteAFriendText": "الأصدقاء ليس لديهم اللعبة؟ يمكنك دعوتهم إلى\nجربها وسيحصلون على ${COUNT} من التذاكر المجانية.", + "inviteFriendsText": "دعوة الاصدقاء", + "joinPublicPartyDescriptionText": "الإنضمام الى سيرفر عام", + "localNetworkDescriptionText": "(الإنضمام الى سيرفر بالقرب منك (وايفاي,بلوتوث,الخ", + "localNetworkText": "شبكة محليه", + "makePartyPrivateText": "اصنع حفلة خاصة", + "makePartyPublicText": "اصنع حزب بلدي العامة", + "manualAddressText": "العنوان", + "manualConnectText": "الاتصال", + "manualDescriptionText": "الانضمام إلى الحزب عن طريق العنوان:", + "manualJoinSectionText": "الإنضمام بواسطة العنوان", + "manualJoinableFromInternetText": "هل أنت مشترك من الإنترنت ؟:", + "manualJoinableNoWithAsteriskText": "لا*", + "manualJoinableYesText": "نعم", + "manualRouterForwardingText": "* لإصلاح ذلك، حاول تهيئة الموجه لإعادة توجيه منفذ أودب ${PORT} إلى عنوانك المحلي", + "manualText": "يدوي", + "manualYourAddressFromInternetText": "عنوانك من الإنترنت:", + "manualYourLocalAddressText": "عنوانك المباشر", + "nearbyText": "الأقرب", + "noConnectionText": "<لا يوجد اتصال>", + "otherVersionsText": "(اصدارات اخرى)", + "partyCodeText": "رمز السيرفر", + "partyInviteAcceptText": "قبول", + "partyInviteDeclineText": "رفض", + "partyInviteGooglePlayExtraText": "(see the 'Google Play' tab in the 'Gather' window)", + "partyInviteIgnoreText": "موافق", + "partyInviteText": "تمت دعوة ${NAME}\nلك للانضمام إلى حزبهم!", + "partyNameText": "اسم المجموعة", + "partyServerRunningText": "سيرفرك يعمل", + "partySizeText": "حجم المجموعه", + "partyStatusCheckingText": "جار التحقق من الحالة ...", + "partyStatusJoinableText": "حزبك الآن غير قابل للانضمام من الإنترنت", + "partyStatusNoConnectionText": "غير قادر على الإتصال بالسيرفر", + "partyStatusNotJoinableText": "حزبكم ليست قابلة للانضمام من الإنترنت", + "partyStatusNotPublicText": "حزبكم ليس عام", + "pingText": "Ping", + "portText": "البوابة", + "privatePartyCloudDescriptionText": "السيرفرات الخاصة تعمل على خادم في الهواء؛ لا تحتاج تجهيز الراوتر اودي بي", + "privatePartyHostText": "صنع حفلة خاصة", + "privatePartyJoinText": "دخول حفلة خاصة", + "privateText": "الخاص", + "publicHostRouterConfigText": "هذا قد يحتاج تجهيز منفذ اودي پي في الراوتر. لعمل اسهل، يمكنك صنع حفلة خاصة", + "publicText": "عام", + "requestingAPromoCodeText": "جار طلب رمز ...", + "sendDirectInvitesText": "إرسال دعوات مباشرة", + "shareThisCodeWithFriendsText": "شارك هذا الرمز مع الأصدقاء:", + "showMyAddressText": "عرض عنواني", + "startHostingPaidText": "صنع الحفلة الأن ب ${COST}", + "startHostingText": "صنع الحفل", + "startStopHostingMinutesText": "يمكنك بدأ وايقاف الحفلة مجانا خلال ${MINUTES} من الدقائق", + "stopHostingText": "ايقاف التشغيل", + "titleText": "متعدد الاعبين", + "wifiDirectDescriptionBottomText": "إذا كانت جميع الأجهزة تحتوي على لوحة \"واي-في مباشر\"، فيجب أن تكون قادرة على استخدامها للعثور عليها\nوالتواصل مع بعضها البعض. مرة واحدة يتم توصيل جميع الأجهزة، يمكنك تشكيل الأطراف\nهنا باستخدام علامة التبويب \"الشبكة المحلية\"، تماما كما هو الحال مع شبكة واي فاي العادية.\n\nللحصول على أفضل النتائج، يجب أن يكون مضيف واي-في ديريكت أيضا مضيف الطرف ${APP_NAME}.", + "wifiDirectDescriptionTopText": "واي فاي المباشر يمكن استخدامها لتوصيل أجهزة الروبوت مباشرة دون\nوالتي تحتاج إلى شبكة واي فاي. هذا يعمل بشكل أفضل على الروبوت 4.2 أو أحدث.\n\nلاستخدامه، افتح إعدادات واي-في وابحث عن \"واي-في ديريكت\" في القائمة.", + "wifiDirectOpenWiFiSettingsText": "افتح إعدادات واي-في", + "wifiDirectText": "واي فاي مباشر", + "worksBetweenAllPlatformsText": "(يعمل بين جميع المنصات)", + "worksWithGooglePlayDevicesText": "(يعمل مع الأجهزة التي تعمل على جوجل بلاي (أندرويد) نسخة من اللعبة)", + "youHaveBeenSentAPromoCodeText": "لقد تم إرسال رمز ترويجي بقيمة ${APP_NAME}:" + }, + "getTicketsWindow": { + "freeText": "مجانآ !", + "freeTicketsText": "تذاكر مجانية", + "inProgressText": "هناك معاملة قيد التنفيذ. يرجى المحاولة مرة أخرى في لحظة.", + "purchasesRestoredText": "تمت استعادة عمليات الشراء.", + "receivedTicketsText": "تم استلام تذاكر ${COUNT}!", + "restorePurchasesText": "استعادة المشتريات", + "ticketPack1Text": "حزمة تذكرة صغيرة", + "ticketPack2Text": "حزمة تذكرة متوسطة", + "ticketPack3Text": "حزمة تذكرة كبيرة", + "ticketPack4Text": "جمبو تذكرة حزمة", + "ticketPack5Text": "ماموث تذكرة حزمة", + "ticketPack6Text": "تذكرة حزمة هائلة", + "ticketsFromASponsorText": "شاهد اعلانا\nمن التذاكر ${COUNT} للحصول على", + "ticketsText": "${COUNT} بطاقات", + "titleText": "أحصل على تذاكر", + "unavailableLinkAccountText": "عذرا، لا تتوفر عمليات الشراء على هذا النظام الأساسي.\nوكحل بديل، يمكنك ربط هذا الحساب بحساب في\nمنصة أخرى وجعل عمليات الشراء هناك.", + "unavailableTemporarilyText": "هذا غير متوفر حاليا؛ الرجاء معاودة المحاولة في وقت لاحق.", + "unavailableText": "عذرا، هذا غير متوفر.", + "versionTooOldText": "عذرا، هذا الإصدار من اللعبة قديم جدا؛ يرجى تحديث إلى أحدث واحد.", + "youHaveShortText": "لديك ${COUNT}", + "youHaveText": "لديك ${COUNT} تذاكر" + }, + "googleMultiplayerDiscontinuedText": "عذرًا ، خدمة جوجل متعددة اللاعبين لم تعد متاحة.\n أنا أعمل على بديل بأسرع وقت ممكن.\n حتى ذلك الحين ، يرجى تجربة طريقة اتصال أخرى.\n -إريك", + "googlePlayPurchasesNotAvailableText": "عمليات شراء جوجل بلاي غير متوفرة.\nقد تحتاج لتحديث تطبيق المتجر.", + "googlePlayServicesNotAvailableText": "غوغل بلاي العاب غير متوفر.\nبعض المزايا لن تكون متوفرة.", + "googlePlayText": "جوجل بلاي", + "graphicsSettingsWindow": { + "alwaysText": "دائما", + "fullScreenCmdText": "ملء الشاشة (Cmd-F)", + "fullScreenCtrlText": "الشاشه كامله (Ctrl-F)", + "gammaText": "غاما", + "highText": "متوسط", + "higherText": "العالي", + "lowText": "منخفض", + "mediumText": "متوسط", + "neverText": "أبدا", + "resolutionText": "القرار", + "showFPSText": "اظهار عدد الكدرات في الثانية", + "texturesText": "القوام", + "titleText": "الرسومات", + "tvBorderText": "TV الحدود", + "verticalSyncText": "تزامن عمودي", + "visualsText": "صور" + }, + "helpWindow": { + "bombInfoText": "القنبلة\nأقوى من اللكمات، لكن من\nالممكن أن تؤدي لإيذاء النفس\nلأفضل النتائج، ارمها\nنحو العدو قبل أن ينفذ الفتيل.", + "canHelpText": "تستطيع مساعدتك ${APP_NAME}.", + "controllersInfoText": "يمكنك لعب ${APP_NAME} مع أصدقائك عبر الشبكة، أو يمكنكم\nجميعًا اللعب على نفس الجهاز إذا كنت تمتلك أذرع تحكم كافية.\n${APP_NAME} تدعم أنواع متعددة من أذرع التحكم؛ حتى الهواتف يمكن استعمالها\nكذراع تحكم من خلال تطبيق ${REMOTE_APP_NAME}.\nلمزيد من المعلومات اذهب للإعدادات>التحكم.", + "controllersInfoTextRemoteOnly": "You can play ${APP_NAME} with friends over a network, or you\n can all play on the same device by using phones as\n controllers via the free '${REMOTE_APP_NAME}' app.", + "controllersText": "التحكم", + "controlsSubtitleText": "شخصية ${APP_NAME} الخاصة بك تحتوي على العديد من الخصائص أهمها:", + "controlsText": "وحدات التحكم", + "devicesInfoText": "يمكن تشغيل إصدار فر الذي يبلغ ${APP_NAME} عبر الشبكة\nالنسخة العادية، حتى سوط خارج الهواتف الإضافية، وأقراص،\nوأجهزة الكمبيوتر والحصول على اللعبة الخاصة بك على. بل يمكن أن يكون مفيدا ل\nربط نسخة منتظمة من اللعبة إلى الإصدار فر فقط ل\nالسماح للناس خارج لمشاهدة العمل.", + "devicesText": "الأجهزة", + "friendsGoodText": "من الرائع أن تحظى بهم. ${APP_NAME} أكثر متعة عندما تلعب مع عدة لاعبين\nواللعبة تدعم اللعب مع 8 لاعبين في وقت واحد، مما يقودنا إلى:", + "friendsText": "الاصدقاء", + "jumpInfoText": "القفز\nقم بالقفز لعبور الحفر الصغيرة،\nولرمي الأشياء أبعد،\nوللتعبير عن مشاعر الفرح.", + "orPunchingSomethingText": ".أو ضرب شيء، ورميه من على الجرف، وتفجيره بالمرة بقنبلة لزجة", + "pickUpInfoText": "- امسك -\nالاستيلاء على الأعلام، والأعداء، أو أي شيء\nوإلا لا انسحب على الأرض.\nاضغط مرة أخرى لرمي.", + "powerupBombDescriptionText": "يتيح لك سوط من ثلاث قنابل\nفي صف واحد بدلا من واحد فقط.", + "powerupBombNameText": "قنابل ثلاثية", + "powerupCurseDescriptionText": "أعتقد من الجيد الإبتعاد عن هذا.\nإلا إذا كنت ستقوم بـ..؟", + "powerupCurseNameText": "لعنة", + "powerupHealthDescriptionText": "يشفيك بشكل كامل.\nكما كأن شيئًا لم يحدث.", + "powerupHealthNameText": "حقيبة إسعاف", + "powerupIceBombsDescriptionText": "أضعف من القنابل العادية\nلكن يُبقي أعدائك مجمدين\nويجعلهم هشين للغاية.", + "powerupIceBombsNameText": "قنابل الجليد", + "powerupImpactBombsDescriptionText": "أضعف قليلًا من القنابل التقليدية\nلكنها تنفجر بمجرد أن تلمس أي شيء.", + "powerupImpactBombsNameText": "قنابل الإستهداف", + "powerupLandMinesDescriptionText": "تأتي هذه الحزمة بثلاث قطع\nمن اللغم الأرضي مفيد للدفاع عن \nالقاعدة، وإيقاف الأعداء العدائين.", + "powerupLandMinesNameText": "ألغام-أرضية", + "powerupPunchDescriptionText": "يجعلك تلكم الأشياء بشكل أعمق،\nأسرع، أفضل، أقوى.", + "powerupPunchNameText": "قفازات الملاكمة", + "powerupShieldDescriptionText": "يحمي جسمك من الضرر\nلكي لا تضطر للتعرض للضرر.", + "powerupShieldNameText": "درع الطاقة", + "powerupStickyBombsDescriptionText": "امساك و ضرب الشي.\nلا يزال يجعلك سعيدا.", + "powerupStickyBombsNameText": "قنابل لاصقة", + "powerupsSubtitleText": "وبلا شك، لا توجد لعبة تكتمل بلا قدرات تعزيزية إضافية:", + "powerupsText": "حزم تعزيزية", + "punchInfoText": "اللكم\nعندما تجري بسرعة\nتعطي اللكمات ضرر أكبر،\nلذا اركض وقم بالدوران كالرجل المجنون.", + "runInfoText": "الركض\nاضغط مطولًا على أي زر أعلاه لتشغيله، أيضًا بإمكانك استعمال الزر الخلفي لذراع التحكم للركض.\nيُمكنك الركض من الوصول للأماكن بشكل أسرع لكنه يصعب الإستدارة، لذا انتبه من المنحدرات.", + "someDaysText": "في بعض الأحيان تشعر وكأنك تريد ضرب شيء ما. تفجير شيء ما.", + "titleText": "${APP_NAME} كيفية لعب", + "toGetTheMostText": "للحصول على أقصى استفادة من هذه اللعبة، ستحتاج إلى:", + "welcomeText": "مرحبا بك في ${APP_NAME}!" + }, + "holdAnyButtonText": "<اضغط على أي زر>", + "holdAnyKeyText": "<اضغط على أي مفتاح>", + "hostIsNavigatingMenusText": "- ${HOST} الرئيس يقوم بالتنقل في القوائم -", + "importPlaylistCodeInstructionsText": "استخدم الكود التالي لاستيراد قائمة التشغيل هذه في مكان آخر:", + "importPlaylistSuccessText": "تم استيراد ${TYPE} قائمة تشغيل \"${NAME}\"", + "importText": "استيراد", + "importingText": "استيراد ...", + "inGameClippedNameText": "في اللعبة سوف يكون\n\"${NAME}\"", + "installDiskSpaceErrorText": "خطأ: تعذر إكمال التثبيت.\nقد تكون نفذت مساحه التخزين على جهازك.\nامسح بعض المساحة وحاول مرة أخرى.", + "internal": { + "arrowsToExitListText": "اضغط ${LEFT} أو ${RIGHT} للخروج من القائمة", + "buttonText": "زر", + "cantKickHostError": "لا يمكنك طرد المضيف.", + "chatBlockedText": "${NAME} تم حظر الدردشة لمدة ${TIME} ثانية.", + "connectedToGameText": "انضم '${NAME}'", + "connectedToPartyText": "انضم إلى حفلة ${NAME}!", + "connectingToPartyText": "توصيل...", + "connectionFailedHostAlreadyInPartyText": "فشل الاتصال؛ المضيف في حفله اخرى.", + "connectionFailedPartyFullText": "فشل الاتصال؛ الحزب الكامل.", + "connectionFailedText": "فشل الاتصال.", + "connectionFailedVersionMismatchText": "فشل الاتصال؛ المضيف يقوم بتشغيل نسخة مختلفة من اللعبة.\nتأكد من أنك و المضيف لديكما نفس النسخه وحاول مرة أخرى.", + "connectionRejectedText": "تم رفض الاتصال.", + "controllerConnectedText": "${CONTROLLER} متصل.", + "controllerDetectedText": "تم اكتشاف وحدة تحكم واحدة.", + "controllerDisconnectedText": "${CONTROLLER} تم القطع.", + "controllerDisconnectedTryAgainText": "انقطع الاتصال ${CONTROLLER}.الرجاء اعاده محاولة الاتصال مرة أخرى.", + "controllerForMenusOnlyText": "لا يمكن استخدام هذا المراقب للعب. فقط للتنقل القوائم.", + "controllerReconnectedText": "تم إعادة ربط ${CONTROLLER}.", + "controllersConnectedText": "تم توصيل وحدات تحكم ${COUNT}.", + "controllersDetectedText": "تم اكتشاف وحدات تحكم ${COUNT}.", + "controllersDisconnectedText": "تم فصل وحدات تحكم ${COUNT}.", + "corruptFileText": "تم اكتشاف ملف (ملفات) فاسدة. الرجاء محاولة إعادة التثبيت أو البريد الإلكتروني ${EMAIL}", + "errorPlayingMusicText": "خطأ في تشغيل الموسيقى: ${MUSIC}", + "errorResettingAchievementsText": "يتعذر إعادة تعيين الإنجازات عبر الإنترنت؛ الرجاء معاودة المحاولة في وقت لاحق.", + "hasMenuControlText": "يحتوي ${NAME} على عنصر تحكم في القائمة.", + "incompatibleNewerVersionHostText": "يقوم المضيف بتشغيل إصدار أحدث من اللعبة.\nتحديث إلى أحدث إصدار وحاول مرة أخرى.", + "incompatibleVersionHostText": "المضيف يقوم بتشغيل نسخة مختلفة من اللعبة.\nتأكد من أنك انت و المضيف لديكما نفس النسخه وحاول مرة أخرى.", + "incompatibleVersionPlayerText": "يعمل ${NAME} على إصدار مختلف من اللعبة.\nتأكد من اصدار اللعبه لديكما او تغيل نفس الاصدار وحاول مرة أخرى.", + "invalidAddressErrorText": "خطأ: عنوان غير صالح.", + "invalidNameErrorText": "خطأ: اسم غير صالح.", + "invalidPortErrorText": "خطأ: منفذ غير صالح.", + "invitationSentText": "ارسلت الدعوه.", + "invitationsSentText": "تم إرسال دعوات ${COUNT}.", + "joinedPartyInstructionsText": "انضم شخص ما إلى حفلتك.\nانتقل إلى \"اللعب\" لبدء اللعبة.", + "keyboardText": "لوحة المفاتيح", + "kickIdlePlayersKickedText": "الركل ${NAME} لكونه خاملا.", + "kickIdlePlayersWarning1Text": "سيتم ركل ${NAME} بمبلغ ${COUNT} ثانية إذا ظلت خاملة.", + "kickIdlePlayersWarning2Text": "(يمكنك إيقاف هذا في إعدادات -> متقدم)", + "leftGameText": "يسار '${NAME}'.", + "leftPartyText": "غادر ${NAME} من الحفله.", + "noMusicFilesInFolderText": "المجلد لا يحتوي على ملفات الموسيقى.", + "playerJoinedPartyText": "انضم ${NAME} إلى الحفله!", + "playerLeftPartyText": "غادر ${NAME} الحفله.", + "rejectingInviteAlreadyInPartyText": "رفض الدعوة (موجود بالفعل في أحد الحفلات).", + "serverRestartingText": "السيرفر يعاد تشغيله . يرجى إعادة الدخول بعد لحظة ...", + "serverShuttingDownText": "الخادم يغلق...", + "signInErrorText": "حدث خطأ أثناء تسجيل الدخول.", + "signInNoConnectionText": "تعذر تسجيل الدخول. (بدون اتصال بالإنترنت؟)", + "telnetAccessDeniedText": "خطأ: لم يمنح المستخدم حق الوصول إلى تلنيت.", + "timeOutText": "(من المرات في ${TIME} ثانية)", + "touchScreenJoinWarningText": "لقد انضممت مع شاشة اللمس.\nإذا كان هذا خطأ، اضغط 'القائمة-> ترك لعبة' معها.", + "touchScreenText": "شاشة اللمس", + "unableToResolveHostText": "خطأ: غير قادر على حل المضيف.", + "unavailableNoConnectionText": "هذا غير متاح حاليا (لا يوجد اتصال بالإنترنت؟)", + "vrOrientationResetCardboardText": "استخدام هذا لإعادة توجيه فر.\nللعب اللعبة سوف تحتاج إلى وحدة تحكم خارجية.", + "vrOrientationResetText": "فر توجيه إعادة تعيين.", + "willTimeOutText": "(سوف تنقضي المهلة إذا توقفت عن الحركة)" + }, + "jumpBoldText": "اقفز", + "jumpText": "قفز", + "keepText": "احتفظ", + "keepTheseSettingsText": "هل تريد الاحتفاظ بهذه الإعدادات؟", + "keyboardChangeInstructionsText": "اضغط مرتين على مفتاح المسافة لبدل لوحات المفاتيح", + "keyboardNoOthersAvailableText": "لا لوحة مفاتيح ثان موجود", + "keyboardSwitchText": "يتم بدل لوحة مفاتيح ل\"${NAME}\".", + "kickOccurredText": "تم ركل ${NAME}.", + "kickQuestionText": "ركل ${NAME}?", + "kickText": "ركل", + "kickVoteCantKickAdminsText": "لا يمكن ركل المضيف", + "kickVoteCantKickSelfText": "يمكن ركل نفسك", + "kickVoteFailedNotEnoughVotersText": "عدد الاعبين لا يكفي للتصويت.", + "kickVoteFailedText": "أخفق التصويت بالركلة.", + "kickVoteStartedText": "تم بدء تصويت ركلة مقابل ${NAME}.", + "kickVoteText": "التصويت لركلة", + "kickVotingDisabledText": "التصويت بركلة غير مفعل", + "kickWithChatText": "اكتب ${YES} في الدردشة من أجل نعم و ${NO} من أجل لا.", + "killsTallyText": "${COUNT} يقتل", + "killsText": "يقتل", + "kioskWindow": { + "easyText": "سهل", + "epicModeText": "وضع ملحمي", + "fullMenuText": "قائمة كاملة", + "hardText": "الصعب", + "mediumText": "متوسط", + "singlePlayerExamplesText": "لاعب واحد / التعاونية أمثلة", + "versusExamplesText": "مقابل أمثلة" + }, + "languageSetText": "اللغة الآن \"${LANGUAGE}\".", + "lapNumberText": "جوله ${CURRENT}/${TOTAL}", + "lastGamesText": "(آخر ${COUNT} مباراة)", + "leaderboardsText": "المتصدرين", + "league": { + "allTimeText": "كل الوقت", + "currentSeasonText": "الموسم الحالي (${NUMBER})", + "leagueFullText": "${NAME} الدوري", + "leagueRankText": "رتبه الدوري", + "leagueText": "الدوري", + "rankInLeagueText": "#${RANK}, ${NAME} الدوري${SUFFIX}", + "seasonEndedDaysAgoText": "انتهى الموسم قبل ${NUMBER} يوم.", + "seasonEndsDaysText": "ينتهي الموسم بعد ${NUMBER} من الأيام.", + "seasonEndsHoursText": "ينتهي الموسم بعد ${NUMBER} ساعة.", + "seasonEndsMinutesText": "ينتهي الموسم بعد ${NUMBER} من الدقائق.", + "seasonText": "الموسم ${NUMBER}", + "tournamentLeagueText": "يجب أن تصل إلى الدوري ${NAME} للدخول في هذه البطولة.", + "trophyCountsResetText": "سيتم إعادة تعيين عدد الكوؤس في الموسم المقبل." + }, + "levelBestScoresText": "أفضل النقاط على ${LEVEL}", + "levelBestTimesText": "أفضل الأوقات على ${LEVEL}", + "levelIsLockedText": "تم قفل ${LEVEL}.", + "levelMustBeCompletedFirstText": "يجب إكمال ${LEVEL} أولا.", + "levelText": "المرحله ${NUMBER}", + "levelUnlockedText": "فتحت المرحله", + "livesBonusText": "يعيش مكافأة", + "loadingText": "جار التحميل", + "loadingTryAgainText": "جار التحميل؛ حاول مرة أخرى في لحظة ...", + "macControllerSubsystemBothText": "كلا (غير مستحسن)", + "macControllerSubsystemClassicText": "كلاسيكي", + "macControllerSubsystemDescriptionText": "(حاول تغيير هذا إذا وحدات التحكم الخاصة بك لا تعمل)", + "macControllerSubsystemMFiNoteText": "تم العثور على وحدة التحكم التي تم إنشاؤها لنظام التشغيل يوس / ماك؛\nقد تحتاج إلى تمكين هذه في إعدادات -> وحدات تحكم", + "macControllerSubsystemMFiText": "المصممة خصيصا اي او اس / ماك", + "macControllerSubsystemTitleText": "دعم جهاز التحكم", + "mainMenu": { + "creditsText": "معلومات", + "demoMenuText": "عرض القائمة", + "endGameText": "نهاية لعبة", + "endTestText": "الاختبار النهائي", + "exitGameText": "الخروج من اللعبة", + "exitToMenuText": "هل تريد الخروج من القائمة؟", + "howToPlayText": "كيف ألعب", + "justPlayerText": "(فقط ${NAME})", + "leaveGameText": "اترك اللعبة", + "leavePartyConfirmText": "هل تريد حقًا مغادرة الحفلة؟", + "leavePartyText": "مغادرة الحفلة", + "quitText": "مغادرة", + "resumeText": "استمرار", + "settingsText": "الإعدادات" + }, + "makeItSoText": "اجعلها كذلك", + "mapSelectGetMoreMapsText": "الحصول على المزيد من الخرائط ...", + "mapSelectText": "تحديد...", + "mapSelectTitleText": "${GAME} خرائط", + "mapText": "خرائط", + "maxConnectionsText": "اتصالات مكتمل", + "maxPartySizeText": "أقصى حجم للحفلة", + "maxPlayersText": "عدد لاعبين مكتمل", + "merchText": "ميرش!", + "modeArcadeText": "وضع اللهو", + "modeClassicText": "الوضع التقليدي", + "modeDemoText": "الوضع التجريبي", + "mostValuablePlayerText": "أفضل لاعب", + "mostViolatedPlayerText": "اللاعب الأكثر انتهاكاً", + "mostViolentPlayerText": "أعنف اللاعبين", + "moveText": "تحرك", + "multiKillText": "${COUNT}-قتل!!!", + "multiPlayerCountText": "${COUNT} لاعب", + "mustInviteFriendsText": "ملاحظة: يجب دعوة الأصدقاء في\nلوحة \"${GATHER}\" أو إرفاقها\nوحدات تحكم للعب متعددة.", + "nameBetrayedText": "${NAME} قام بخيانة ${VICTIM}", + "nameDiedText": "${NAME} توفي.", + "nameKilledText": "${NAME} قتل ${VICTIM}.", + "nameNotEmptyText": "لا يمكن أن يكون الاسم فارغًا!", + "nameScoresText": "${NAME} نقاط!", + "nameSuicideKidFriendlyText": "${NAME} توفي عن طريق الخطأ.", + "nameSuicideText": "${NAME} انتحر.", + "nameText": "اسم", + "nativeText": "محلي", + "newPersonalBestText": "أفضل شخصية جديدة!", + "newTestBuildAvailableText": "يتوفر اختبار اختبار أحدث! (${VERSION} بناء ${BUILD}).\nاحصل على ${ADDRESS}", + "newText": "الجديد", + "newVersionAvailableText": "يتوفر إصدار أحدث من ${APP_NAME}! (${VERSION})", + "nextAchievementsText": "الإنجازات التالية:", + "nextLevelText": "المرحلة التالية", + "noAchievementsRemainingText": "- لا شيء", + "noContinuesText": "(لا يستمر)", + "noExternalStorageErrorText": "لم يتم العثور على وحدة تخزين خارجية على هذا الجهاز", + "noGameCircleText": "خطأ: لم يتم تسجيل الدخول الئ gamecircle", + "noScoresYetText": "لا نقاط حتى الآن.", + "noThanksText": "لا شكرا", + "noTournamentsInTestBuildText": "تحذير: سيتم تجاهل نقاط البطولات في النسخة التجريبية", + "noValidMapsErrorText": "لا خرائط صالحة وجدت لهذا النوع اللعبة.", + "notEnoughPlayersRemainingText": "لا يكفي اللاعبين المتبقين؛ الخروج وبدء لعبة جديدة.", + "notEnoughPlayersText": "تحتاج على الأقل ${COUNT} لاعبين لبدء هذه اللعبة!", + "notNowText": "ليس الآن", + "notSignedInErrorText": "يجب ان تسجل الدخول لتفعل هذا", + "notSignedInGooglePlayErrorText": "عليك تسجيل الدخول لجوجل بلاي لتفعل هذا", + "notSignedInText": "لم تقم بتسجيل الدخول", + "notUsingAccountText": "ملاحظة: حساب ${SERVICE} متجاهل.\nقم بالتوجه الى 'الحساب -> تسجيل الدخول بواسطة ${SERVICE}' اذا اردت استعماله.", + "nothingIsSelectedErrorText": "لا شئ تم اختياره!", + "numberText": "#${NUMBER}", + "offText": "إيقاف", + "okText": "حسنا", + "onText": "تشغيل", + "oneMomentText": "لحظة واحدة...", + "onslaughtRespawnText": "${PLAYER} سيخرج مجددا في الموجة ${WAVE}", + "orText": "${A} أو ${B}", + "otherText": "آخر...", + "outOfText": "(#${RANK} خرج من ${ALL})", + "ownFlagAtYourBaseWarning": "يجب على العلم الخاص بك ان يكون في قاعدتك\n!لتسجل نقطة", + "packageModsEnabledErrorText": "(انظر الاعدادات ــ> متقدم) local-package-mods اللعب على الشبكة غير مسموح عندما يكون", + "partyWindow": { + "chatMessageText": "رسالة الدردشة", + "emptyText": "حفلتك فارغة", + "hostText": "(مضيف)", + "sendText": "إرسال", + "titleText": "الحفلة الخاصة بك" + }, + "pausedByHostText": "(متوقف مؤقتا من قبل المضيف )", + "perfectWaveText": "المرحله المثالية", + "pickUpText": "إلتقط", + "playModes": { + "coopText": "اللعب التعاوني", + "freeForAllText": "الحرية-للجميع", + "multiTeamText": "فرق متعددة", + "singlePlayerCoopText": "لعب فردي / لعب تعاوني", + "teamsText": "فرق" + }, + "playText": "لعب", + "playWindow": { + "oneToFourPlayersText": "1-4 لاعبين", + "titleText": "إلعب", + "twoToEightPlayersText": "2-8 لاعبين" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} سيدخل ببداية الجولة القادمة", + "playerInfoText": "معلومات اللاعب", + "playerLeftText": "${PLAYER} ترك اللعبة", + "playerLimitReachedText": "حد اللاعب ${COUNT} وصل", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "لايمكنك حذف حساب الملف الشخصي الخاص بك", + "deleteButtonText": "حذف\nالملف الشخصي", + "deleteConfirmText": "حذف '${PROFILE}'?", + "editButtonText": "تعديل\nالملف الشخصي", + "explanationText": "(اللاعب المخصص و المباراة لهذا الحساب)", + "newButtonText": "ملف شخصي\nجديد", + "titleText": "ملفات اللاعب الشخصي" + }, + "playerText": "لاعب", + "playlistNoValidGamesErrorText": "قائمة التشغيل هذه لا تحتوي على ألعاب مفتوحة صالحة", + "playlistNotFoundText": "لم يتم العثور على قائمة التشغيل", + "playlistText": "قائمة التشغيل", + "playlistsText": "قائمة العب", + "pleaseRateText": "يرجى اتخاذ لحظة وتقييمه ${APP_NAME} اذا كنت تستمتع بلعبة\nاو كتابة مراجعة فهاذا يوفر معلومات مفيدة ويوفر التطوير\nفي المستقبل\n\n!شكرًا\nاريك—", + "pleaseWaitText": "الرجاء الانتظار . . .", + "pluginClassLoadErrorText": "فشل في تشغيل الاضافة '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "خطأ في بدء الاضافة '${PLUGIN}: ${ERROR}", + "pluginsDetectedText": "تم العثور على اضافات جديدة. اعد التشغيل لتفعيلها، او قم بتخصيصها في الاعدادات.", + "pluginsRemovedText": "${NUM} لم تعد الاضافة موجودة.", + "pluginsText": "اضافات", + "practiceText": "تدريب", + "pressAnyButtonPlayAgainText": "اضغط اي زر للعب مجددا...", + "pressAnyButtonText": "اظغط اي زر للإستمرار...", + "pressAnyButtonToJoinText": "اضغط اي زر للإنضمام", + "pressAnyKeyButtonPlayAgainText": "اضغط اي زر /اي مفتاح للعب مجددا...", + "pressAnyKeyButtonText": "اضغظ اي مفتاح/زر للإستمرار", + "pressAnyKeyText": "اضغظ اي مفتاح...", + "pressJumpToFlyText": "** اضعط على القفز مرارا وتكرارا لطيران **", + "pressPunchToJoinText": "اضغط على زر اللكمة للإنضمام", + "pressToOverrideCharacterText": "اضغط ${BUTTONS} لتجاوز شخصيتك", + "pressToSelectProfileText": "اضغظ ${BUTTONS} لإختيار لاعب", + "pressToSelectTeamText": "اضغظ ${BUTTONS} لإختيار فريق", + "promoCodeWindow": { + "codeText": "كود", + "enterText": "ادخل" + }, + "promoSubmitErrorText": "خطأ في إرسال الكود: تحقق من اتصالك بالإنترنت", + "ps3ControllersWindow": { + "macInstructionsText": "إيقاف الطاقة على الجزء الخلفي من PS3 الخاص بك، تأكد\nيتم تمكين البلوتوث على جهاز ماك، ثم توصيل وحدة التحكم\nإلى ماك الخاص بك عن طريق كابل أوسب لإقران اثنين. من ذلك الحين، أنت\nيمكن استخدام زر المنزل وحدة تحكم لتوصيله إلى ماك الخاص بك\nفي أي من السلكي (أوسب) أو اللاسلكية (بلوتوث) واسطة.\n\nفي بعض أجهزة ماك قد يطلب منك رمز مرور عند الاقتران.\nفي حالة حدوث ذلك، راجع البرنامج التعليمي التالي أو غوغل للحصول على مساعدة.\n\n\n\n\nوحدات تحكم PS3 متصلة لاسلكيا يجب أن تظهر في الجهاز\nفي تفضيلات النظام -> بلوتوث. قد تحتاج إلى إزالتها\nمن تلك القائمة عندما تريد استخدامها مع PS3 الخاص بك مرة أخرى.\n\nتأكد أيضا من قطع الاتصال بهم من بلوتوث عندما لا تكون في\nاستخدام أو بطارياتهم سوف تستمر في استنزاف.\n\nبلوتوث يجب التعامل مع ما يصل إلى 7 أجهزة متصلة،\nعلى الرغم من عدد الكيلومترات قد تختلف.", + "ouyaInstructionsText": "لاستخدام وحدة تحكم PS3 مع أويا الخاص بك، ببساطة توصيله مع كابل أوسب\nمرة واحدة لإقران ذلك. القيام بذلك قد قطع وحدات التحكم الأخرى الخاصة بك، لذلك\nيجب عليك ثم إعادة تشغيل أويا وافصل كابل أوسب.\n\nمن ذلك الحين على يجب أن تكون قادرا على استخدام زر المنزل تحكم ل\nتوصيله لاسلكيا. عند الانتهاء من اللعب، اضغط على زر هوم\nلمدة 10 ثانية لتحويل وحدة تحكم قبالة؛ وإلا فإنه قد يبقى على\nو نفايات البطاريات.", + "pairingTutorialText": "الاقتران فيديو تعليمي", + "titleText": "استخدام وحدات تحكم PS3 مع ${APP_NAME}:" + }, + "punchBoldText": "لكمة", + "punchText": "لكمة", + "purchaseForText": "${PRICE} إشتري اللعبة", + "purchaseGameText": "إشتري اللعبة", + "purchasingText": "شراء...", + "quitGameText": "خروج ${APP_NAME}?", + "quittingIn5SecondsText": "جار الإقلاع خلال 5 ثوان ...", + "randomPlayerNamesText": "الأسماء الافتراضية", + "randomText": "عشوائي", + "rankText": "مرتبة", + "ratingText": "تقييم", + "reachWave2Text": "تصل موجة 2 إلى رتبة.", + "readyText": "جاهز", + "recentText": "الأخيرة", + "remoteAppInfoShortText": "${APP_NAME} أكثر متعة عندما يتم تشغيله مع العائلة والأصدقاء.\nقم بتوصيل وحدة تحكم أجهزة أو أكثر أو قم بتثبيت\n${REMOTE_APP_NAME} على الهواتف أو الأجهزة اللوحية لاستخدامها\nكما تحكم.", + "remote_app": { + "app_name": "بومبسكاد البعيد", + "app_name_short": "BSريموت", + "button_position": "زر الموضع", + "button_size": "حجم الزر", + "cant_resolve_host": "لا يمكن حل المضيف.", + "capturing": "اسر…", + "connected": "تم الاتصال", + "description": "استخدام الهاتف أو الكمبيوتر اللوحي كمحكم مع بومبسكاد.\nما يصل إلى 8 أجهزة يمكن الاتصال في وقت واحد ل ملحمة الجنون المحلي متعددة على جهاز تلفزيون واحد أو قرص.", + "disconnected": "قطع الاتصال من السيرفر.", + "dpad_fixed": "تم الاصلاح", + "dpad_floating": "يطفو على السطح", + "dpad_position": "D- الوسادة الموقف", + "dpad_size": "قياس اللوحة", + "dpad_type": "D- الوسادة نوع", + "enter_an_address": "أدخل عنوانا", + "game_full": "اللعبة كاملة أو لا تقبل الاتصالات.", + "game_shut_down": "العبة لقد اطفأة", + "hardware_buttons": "أزرار الأجهزة", + "join_by_address": "الانضمام بحسب العنوان ...", + "lag": "تاخر: ${SECONDS} الثانيه", + "reset": "إعادة تعيين إلى الافتراضي", + "run1": "تشغيل 1", + "run2": "تشغيل 2", + "searching": "جار البحث عن ألعاب بومبسكاد ...", + "searching_caption": "اضغط على اسم لعبة للانضمام إليه.\nتأكد من أنك على نفس شبكة واي فاي مثل اللعبة.", + "start": "بداية", + "version_mismatch": ".الإصداران لا يتطابقان\nتأكد من أن فرقة القنبلة و فرقة القنبلة للتحكم عن بعد\n.تم تحديثهما لآخر إصدار وحاول مجددًا" + }, + "removeInGameAdsText": "إلغاء تأمين \"${PRO}\" في المتجر لإزالة الإعلانات داخل اللعبة.", + "renameText": "إعادة تسمية", + "replayEndText": "نهاية الإعادة", + "replayNameDefaultText": "إعادة اللعبة الأخيرة", + "replayReadErrorText": "حدث خطأ أثناء قراءة ملف إعادة التشغيل.", + "replayRenameWarningText": "إعادة تسمية \"${REPLAY}\" بعد لعبة إذا كنت ترغب في الاحتفاظ بها. وإلا فإنه سيتم الكتابة فوقه.", + "replayVersionErrorText": "عذرا، تم إجراء هذا الإعادة في صورة مختلفة\nنسخة من اللعبة ولا يمكن استخدامها.", + "replayWatchText": "مشاهدة الإعادة", + "replayWriteErrorText": "حدث خطأ أثناء كتابة ملف إعادة التشغيل.", + "replaysText": "الإعادة", + "reportPlayerExplanationText": "استخدم هذه الرسالة الإلكترونية للإبلاغ عن الغش أو اللغة غير الملائمة أو أي سلوك سيئ آخر.\nيرجى وصف ما يلي:", + "reportThisPlayerCheatingText": "غش", + "reportThisPlayerLanguageText": "كلام مسيء", + "reportThisPlayerReasonText": "عن ماذا تريد أن تُبلغ؟", + "reportThisPlayerText": "الإبلاغ عن هذا اللاعب", + "requestingText": "...طلب", + "restartText": "إعادة التشغيل", + "retryText": "إعادة المحاولة", + "revertText": "العودة", + "runText": "ركض", + "saveText": "حفظ", + "scanScriptsErrorText": "حدث خطأ (أخطاء) في مسح النصوص البرمجية ؛ انظر السجل للحصول على التفاصيل.", + "scoreChallengesText": "نقاط التحديات", + "scoreListUnavailableText": ".قائمة النقاط غير متاحة", + "scoreText": "نتيجة", + "scoreUnits": { + "millisecondsText": "ميلي ثانية", + "pointsText": "نقاط", + "secondsText": "ثواني" + }, + "scoreWasText": "(كان ${COUNT})", + "selectText": "اختيار", + "seriesWinLine1PlayerText": "الفوز", + "seriesWinLine1TeamText": "الفوز", + "seriesWinLine1Text": "الفوز", + "seriesWinLine2Text": "سلسلة", + "settingsWindow": { + "accountText": "الحساب", + "advancedText": "المتقدمة", + "audioText": "صوت", + "controllersText": "التحكم", + "graphicsText": "رسوميات", + "playerProfilesMovedText": "ملاحظة: انتقلت ملفات تعريف اللاعب إلى نافذة الحساب في القائمة الرئيسية.", + "titleText": "اعدادات" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(بسيطة، وحدة تحكم ودية على الشاشة لوحة المفاتيح لتحرير النص)", + "alwaysUseInternalKeyboardText": "استخدم لوحة المفاتيح الداخلية دائما", + "benchmarksText": "المعايير و الإجهاد الاختبارات", + "disableCameraGyroscopeMotionText": "تعطيل الكاميرا جيروسكوب الحركة", + "disableCameraShakeText": "تعطيل اهتزاز الكاميرا", + "disableThisNotice": "(يمكنك تعطيل هذا الإشعار في الإعدادات المتقدمة)", + "enablePackageModsDescriptionText": "(تمكن قدرات التعديل الإضافية ولكن تعطيل شبكة اللعب)", + "enablePackageModsText": "تمكين تعديل الحزمة المحلية", + "enterPromoCodeText": "ادخل الرمز", + "forTestingText": "ملاحظة: هذه القيم هي فقط للاختبار وسيتم فقدانها عند خروج التطبيق.", + "helpTranslateText": "هي عبارة عن ترجمة ​${APP_NAME}الترجمات غير الإنجليزية ل\nجماعية، إذا أردت المساهمة أو تصحيح الأخطاء اللغوية والإملائية\n!قم بزيارة الرابط أدناه، وشكرًا لكم مقدمًا", + "kickIdlePlayersText": "طرد اللاعبين غير النشطين", + "kidFriendlyModeText": "وضع الأطفال (يقلل العنف، إلخ)", + "languageText": "لغة", + "moddingGuideText": "دليل التعديلات البرمجية", + "mustRestartText": ".يجب أن تقوم بإعادة تشغيل اللعبة لكي يعمل هذا", + "netTestingText": "اختبار الشبكة", + "resetText": "إعادة تعيين", + "showBombTrajectoriesText": "عرض مسارات القنبلة", + "showPlayerNamesText": "إظهار اسماء اللاعبين", + "showUserModsText": "عرض مجلد التعديل", + "titleText": "المتقدمة", + "translationEditorButtonText": "${APP_NAME} محرر الترجمة", + "translationFetchErrorText": "حالة الترجمة غير متاحة", + "translationFetchingStatusText": "جار التحقق من حالة الترجمة ...", + "translationInformMe": "ابلغني عندما تحتاج لغتي للتحديث", + "translationNoUpdateNeededText": "!اللُّغة العربية حتى الآن محدثة، هنيئًا لك", + "translationUpdateNeededText": "** !!اللُّغة الحالية بحاجةٍ إلى تحديث **", + "vrTestingText": "تجربة الواقع الإفتراضي" + }, + "shareText": "شارك", + "sharingText": "مشاركة...", + "showText": "عرض", + "signInForPromoCodeText": "يجب تسجيل الدخول إلى حساب لكي يتم تفعيل الرموز.", + "signInWithGameCenterText": "لاستخدام حساب مركز الألعاب،\nسجل الدخول باستخدام تطبيق مركز الألعاب.", + "singleGamePlaylistNameText": "فقط ${GAME}", + "singlePlayerCountText": "1 لاعب", + "soloNameFilterText": "منفردا ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "اختر شخصية", + "Chosen One": "المختار", + "Epic": "وضع اللعب الملحمي", + "Epic Race": "سباق ملحمي", + "FlagCatcher": "امسك العلم", + "Flying": "أفكار سعيدة", + "Football": "كرة القدم", + "ForwardMarch": "الاعتداءات", + "GrandRomp": "غزو", + "Hockey": "الهوكي", + "Keep Away": "ابتعد", + "Marching": "يركض حول", + "Menu": "القائمة الرئيسية", + "Onslaught": "هجوم", + "Race": "سباق", + "Scary": "ملك التل", + "Scores": "شاشة النتيجة", + "Survival": "الإقصاء", + "ToTheDeath": "مباراة الموت", + "Victory": "شاشة النتيجة النهائية" + }, + "spaceKeyText": "مسافة", + "statsText": "النتائج", + "storagePermissionAccessText": "وهذا يتطلب الوصول إلى التخزين", + "store": { + "alreadyOwnText": "!${NAME}أنت بالفعل تملك", + "bombSquadProNameText": "للمحترفين ${APP_NAME}", + "bombSquadProNewDescriptionText": "يزيل الإعلانات في اللعبة والشاشات المزعجة •\nيفتح المزيد من إعدادات اللعبة •\n:يتضمن هذا العرض أيضًا •", + "buyText": "شراء", + "charactersText": "الشخصيات", + "comingSoonText": "قريبا...", + "extrasText": "إضافات", + "freeBombSquadProText": "فرقة القنبلة الآن أصبحت مجانية، لكن بما أنك اشتريتها\nبطاقات كشكر لك ​${COUNT} ستتلقى فرقة القنبلة القنبلة للمحترفين و\n!استمتع بالميزات الجديدة، وشكرًا لدعمك\n-إيريك", + "holidaySpecialText": "خاص بالعطل", + "howToSwitchCharactersText": "(توجه الى \"${SETTINGS} -> ${PLAYER_PROFILES}\" لتخصيص الشخصيات)", + "howToUseIconsText": "(إنشاء ملفات تعريف لاعب العالمية (في إطار الحساب) لاستخدام هذه)", + "howToUseMapsText": "(استخدم هذه الخرائط في فرقك الخاصة / قوائم التشغيل المجانية للجميع)", + "iconsText": "رموز", + "loadErrorText": "تعذر تحميل الصفحة.\nتحقق من اتصالك بالإنترنت.", + "loadingText": "جار التحميل", + "mapsText": "خرائط", + "miniGamesText": "ألعاب مصغرة", + "oneTimeOnlyText": "(مرة واحدة فقط)", + "purchaseAlreadyInProgressText": "هناك شراء لهذا العنصر قيد التقدم.", + "purchaseConfirmText": "هل تريد شراء ${ITEM}؟", + "purchaseNotValidError": "الشراء غير صالح.\nاتصل بال ${EMAIL} إذا كان هذا خطأ.", + "purchaseText": "شراء", + "saleBundleText": "حزمة بيع!", + "saleExclaimText": "تخفيض السعر!", + "salePercentText": "(${PERCENT}٪ أقل)", + "saleText": "تخفيض السعر", + "searchText": "بحث", + "teamsFreeForAllGamesText": "فرق / مجانا للجميع الألعاب", + "totalWorthText": "*** ${TOTAL_WORTH} قيمة! ***", + "upgradeQuestionText": "ترقية؟", + "winterSpecialText": "عرض الشتاء", + "youOwnThisText": "- انت تملك هذا -" + }, + "storeDescriptionText": "لعبة لأكثر من 8 لاعبين!\n\nالعب مع اصدقائك (او الحاسوب) في بطولات من الميني جيمز المتفجرة كــإمساك بالعلم، الهوكي و المعركة البطيئة!\n\nتحكم بسيط و لعب باجهزة تحكم يجعلها سهلة لأكثر من 8 لاعبين ليدخلو المعركة; تستطيع ايضا استعمال اجهزة الهاتف كاجهزة تحكم من خلال التطبيق المجاني 'BombSquad Remote' !\n\nوقت رمي القنابل!\n\nتفقد www.froemling.net/bombsquad للمزيد من المعلومات.", + "storeDescriptions": { + "blowUpYourFriendsText": ".فجر أصدقائك", + "competeInMiniGamesText": "تنافس في الألعاب المصغرة بدءا من السباق للطيران.", + "customize2Text": "تخصيص الشخصيات، الألعاب المصغرة، وحتى الموسيقى التصويرية.", + "customizeText": "تخصيص الشخصيات وإنشاء قوائم التشغيل الخاصة بك لعبة صغيرة.", + "sportsMoreFunText": "الرياضة أكثر متعة مع المتفجرات.", + "teamUpAgainstComputerText": ".قم بالتعاون كفريق ضد الحاسوب" + }, + "storeText": "متجر", + "submitText": "ارسال", + "submittingPromoCodeText": "تقديم الكود ...", + "teamNamesColorText": "اسماء/الوان الفرق...", + "telnetAccessGrantedText": "تم تمكين الوصول تلنيت.", + "telnetAccessText": "تم الكشف عن الوصول تلنيت. السماح؟", + "testBuildErrorText": "لم يعد بناء الاختبار نشطا؛ يرجى التحقق من إصدار جديد.", + "testBuildText": "اختبار البناء", + "testBuildValidateErrorText": "تعذر التحقق من صلاحية اختبار الاختبار. (لا يوجد اتصال صافي؟)", + "testBuildValidatedText": "اختبار بناء تم التحقق منه؛ استمتع!", + "thankYouText": "شكرا لدعمكم! استمتع باللعبة!!", + "threeKillText": "القتل الثلاثي", + "timeBonusText": "مكافأة الوقت", + "timeElapsedText": "الوقت المنقضي", + "timeExpiredText": "انتهى الوقت", + "timeSuffixDaysText": "${COUNT}ي", + "timeSuffixHoursText": "${COUNT}س", + "timeSuffixMinutesText": "${COUNT}د", + "timeSuffixSecondsText": "${COUNT}ث", + "tipText": "تلميح", + "titleText": "فرقة القنبلة", + "titleVRText": "فرقة القنبلة وا", + "topFriendsText": "أفضل الأصدقاء", + "tournamentCheckingStateText": "التحقق من حالة البطولة. أرجو الإنتظار...", + "tournamentEndedText": "انتهت هذه البطولة. وسوف تبدأ واحدة جديدة قريبا.", + "tournamentEntryText": "دخول البطولة", + "tournamentResultsRecentText": "نتائج البطولة الأخيرة", + "tournamentStandingsText": "ترتيب البطولة", + "tournamentText": "المسابقة", + "tournamentTimeExpiredText": "انتهت مدة البطولة", + "tournamentsDisabledWorkspaceText": "البطولات لا تعمل عندما تكون فضائات العمل تعمل.\nلتشغيل البطولات مجددا، قم بإلغاء تشغيل فضاء العمل الخاص بك و اعادة تشغيل اللعبة.", + "tournamentsText": "البطولات", + "translations": { + "characterNames": { + "Agent Johnson": "العميل جونسون", + "B-9000": "B-9000", + "Bernard": "بيرنارد", + "Bones": "هيكل عظمي", + "Butch": "بوتش", + "Easter Bunny": "أرنب عيد الفصح", + "Flopsy": "فلوبسي", + "Frosty": "فروستي", + "Gretel": "جريتل", + "Grumbledorf": "الساحر", + "Jack Morgan": "جاك مورجان (قرصان)", + "Kronk": "كرونك", + "Lee": "لي", + "Lucky": "سعيد الحظ", + "Mel": "ميل", + "Middle-Man": "الرجل المتوسط", + "Minimus": "أدنى لا", + "Pascal": "پاسكال", + "Pixel": "بيكسل", + "Sammy Slam": "سامي سلام", + "Santa Claus": "سانتا كلوس", + "Snake Shadow": "نينجا", + "Spaz": "سپاز", + "Taobao Mascot": "ماسكوت تاوباو", + "Todd McBurton": "تود بيرتون", + "Zoe": "زوي", + "Zola": "زولا" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} التدريب", + "Infinite ${GAME}": "غير محدود ${GAME}", + "Infinite Onslaught": "هجمة لانهائية", + "Infinite Runaround": "لانهائي يركض حول", + "Onslaught Training": "التدريب هجمة", + "Pro ${GAME}": "برو ${GAME}", + "Pro Football": "كرة القدم الإحترافية", + "Pro Onslaught": "انقضاض احترافي", + "Pro Runaround": "جولة هروب احترافية", + "Rookie ${GAME}": "${GAME} للفراخ", + "Rookie Football": "فرخ كرة القدم", + "Rookie Onslaught": "انقضاض الفرخ", + "The Last Stand": "آخر من يقف", + "Uber ${GAME}": "${GAME} أوبر", + "Uber Football": "كرة القدم الغزيرة", + "Uber Onslaught": "هجمة غزيرة", + "Uber Runaround": "جولة جري غزيرة" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "يكون اختيار واحد لفترة من الوقت للفوز.\nقتل اختيار واحد لتصبح عليه.", + "Bomb as many targets as you can.": "فجر أكبر عدد من الأهداف على قدر استطاعتك.", + "Carry the flag for ${ARG1} seconds.": "حمل العلم مقابل ${ARG1} ثانية.", + "Carry the flag for a set length of time.": "احمل العلم لمدة محددة من الزمن", + "Crush ${ARG1} of your enemies.": "سحق ${ARG1} من أعدائك.", + "Defeat all enemies.": "هزيمة جميع الأعداء.", + "Dodge the falling bombs.": "تفادى القنابل.", + "Final glorious epic slow motion battle to the death.": "آخر معركة ملحمية بطيئة حتى الموت.", + "Gather eggs!": "جمع البيض!", + "Get the flag to the enemy end zone.": "الحصول على العلم إلى المنطقة نهاية العدو.", + "How fast can you defeat the ninjas?": "كم من الوقت ستحتاج لهزيمة النينجا؟", + "Kill a set number of enemies to win.": "قتل عدد معين من الأعداء للفوز.", + "Last one standing wins.": "آخر واحد يبقى يفوز.", + "Last remaining alive wins.": "آخر شخص يبقى حياً يفوز", + "Last team standing wins.": "آخر فريق يقف يفوز.", + "Prevent enemies from reaching the exit.": "امنع الأعداء من الوصول إلى النهاية", + "Reach the enemy flag to score.": "صِل إلى العلم العدو لتسجل", + "Return the enemy flag to score.": "عودة علم العدو ليسجل.", + "Run ${ARG1} laps.": "جري لفات ${ARG1}.", + "Run ${ARG1} laps. Your entire team has to finish.": "جري لفات ${ARG1}. يجب أن ينتهي الفريق بأكمله.", + "Run 1 lap.": "جري 1 اللفة.", + "Run 1 lap. Your entire team has to finish.": "جري 1 اللفة. يجب أن ينتهي الفريق بأكمله.", + "Run real fast!": "تشغيل سريع الحقيقي!", + "Score ${ARG1} goals.": "نقاط ${ARG1} اهداف.", + "Score ${ARG1} touchdowns.": "نقاط ${ARG1} الهبوط", + "Score a goal.": "سجل هدفا", + "Score a touchdown.": "يسجل هبوطا", + "Score some goals.": "تسجيل بعض الأهداف.", + "Secure all ${ARG1} flags.": "تأمين جميع أعلام ${ARG1}", + "Secure all flags on the map to win.": "تأمين جميع الأعلام على الخريطة للفوز.", + "Secure the flag for ${ARG1} seconds.": "تأمين العلم لمدة ${ARG1} ثانية.", + "Secure the flag for a set length of time.": "تأمين العلم لمدة محددة من الزمن.", + "Steal the enemy flag ${ARG1} times.": "سرقة العلم العدو ${ARG1} مرات.", + "Steal the enemy flag.": "سرقة علم العدو.", + "There can be only one.": "يمكن أن يكون هناك واحد فقط.", + "Touch the enemy flag ${ARG1} times.": "المس علم العدو ${ARG1} مرات.", + "Touch the enemy flag.": "المس علم العدو.", + "carry the flag for ${ARG1} seconds": "ثانية ${ARG1} احمل العلم لمدة", + "kill ${ARG1} enemies": "اعداء ${ARG1} اقتل", + "last one standing wins": "آخر من يقف يفوز", + "last team standing wins": "آخر فريق يتبقى يفوز", + "return ${ARG1} flags": "ارجاع ${ARG1} الاعلام", + "return 1 flag": "ارجاع 1 الاعلام", + "run ${ARG1} laps": "جري ${ARG1} لفات", + "run 1 lap": "جري 1 لفات", + "score ${ARG1} goals": "نقاط ${ARG1} اهداف", + "score ${ARG1} touchdowns": "نقاط ${ARG1} الهبوط", + "score a goal": "سجل هدفا", + "score a touchdown": "يسجل هبوطا", + "secure all ${ARG1} flags": "تأمين جميع أعلام $ {ARG1}", + "secure the flag for ${ARG1} seconds": "تأمين العلم مقابل ${ARG1} ثانية", + "touch ${ARG1} flags": "المس أعلام ${ARG1}", + "touch 1 flag": "المس 1 العلم" + }, + "gameNames": { + "Assault": "الاعتداءات", + "Capture the Flag": "أمسك العلم", + "Chosen One": "المختار", + "Conquest": "غزو", + "Death Match": "مباراة الموت", + "Easter Egg Hunt": "تم اصطياد بيضة فصح", + "Elimination": "إزالة", + "Football": "كرة القدم", + "Hockey": "الهوكي", + "Keep Away": "ابتعد", + "King of the Hill": "ملك التل", + "Meteor Shower": "دش النيازك", + "Ninja Fight": "قتال النينجا", + "Onslaught": "هجوم", + "Race": "السباق", + "Runaround": "يركض حول", + "Target Practice": "الممارسة المستهدفة", + "The Last Stand": "الموقف الأخير" + }, + "inputDeviceNames": { + "Keyboard": "لوحة المفاتيح", + "Keyboard P2": "لوحة المفاتيح P2" + }, + "languages": { + "Arabic": "العربية", + "Belarussian": "البيلاروسية", + "Chinese": "الصينية المبسطة", + "ChineseTraditional": "التقليدية الصينية", + "Croatian": "الكرواتية", + "Czech": "تشيكي", + "Danish": "دانماركي", + "Dutch": "هولندي", + "English": "الإنجليزية", + "Esperanto": "الاسبرانتو", + "Filipino": "الفلبينية", + "Finnish": "اللغة الفنلندية", + "French": "الفرنسية", + "German": "الألمانية", + "Gibberish": "رطانة", + "Greek": "الإغريقية", + "Hindi": "الهندية", + "Hungarian": "الهنغارية", + "Indonesian": "الأندونيسية", + "Italian": "الإيطالي", + "Japanese": "اليابانية", + "Korean": "الكورية", + "Malay": "لغة الملايو", + "Persian": "اللغة الفارسية", + "Polish": "البولندي", + "Portuguese": "البرتغالية", + "Romanian": "روماني", + "Russian": "الروسية", + "Serbian": "الصربية", + "Slovak": "السلوفاكية", + "Spanish": "الإسبانية", + "Swedish": "اللغة السويدية", + "Tamil": "اللغةالتاميلية", + "Thai": "تايلاندي", + "Turkish": "اللغة التركية", + "Ukrainian": "الأوكراني", + "Venetian": "فينيسي", + "Vietnamese": "الفيتنامية" + }, + "leagueNames": { + "Bronze": "البرونزي", + "Diamond": "الماسي", + "Gold": "الذهبي", + "Silver": "الفضي" + }, + "mapsNames": { + "Big G": "كبير G", + "Bridgit": "Bridgit", + "Courtyard": "فناء", + "Crag Castle": "قلعة كراغ", + "Doom Shroom": "الموت شروم", + "Football Stadium": "ملعب كرة القدم", + "Happy Thoughts": "أفكار سعيدة", + "Hockey Stadium": "ملعب الهوكي", + "Lake Frigid": "بحيرة فريجيد", + "Monkey Face": "وجه القرد", + "Rampage": "ثورة", + "Roundabout": "الدوار", + "Step Right Up": "خطوة إلى أعلى", + "The Pad": "الوسادة", + "Tip Top": "أعلى الحافة", + "Tower D": "برج D", + "Zigzag": "متعرج" + }, + "playlistNames": { + "Just Epic": "مجرد ملحمة", + "Just Sports": "الرياضة فقط" + }, + "scoreNames": { + "Flags": "أعلام", + "Goals": "الأهداف", + "Score": "أحرز هدفاً", + "Survived": "نجا", + "Time": "الوقت", + "Time Held": "وقت عقد" + }, + "serverResponses": { + "A code has already been used on this account.": "تم استخدام رمز بالفعل في هذا الحساب.", + "A reward has already been given for that address.": "وقد تم بالفعل إعطاء مكافأة لهذا العنوان.", + "Account linking successful!": "تم ربط الحساب بنجاح!", + "Account unlinking successful!": "تم إلغاء ربط الحساب بنجاح!", + "Accounts are already linked.": "الحسابات مرتبطة بالفعل.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "يمكن ان يكون الاعلان غير متحقق منه.\nمن فضلك تحقق بأنك بالفعل في نسخة رسمية و محذثة من اللعبة.", + "An error has occurred; (${ERROR})": "حدثت مشكلة; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "حدثت مشكلة; برجاء التواصل مع الدعم. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "حدث خطأ؛ يرجى الاتصال support@froemling.net.", + "An error has occurred; please try again later.": "حدث خطأ؛ الرجاء معاودة المحاولة في وقت لاحق.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "هل تريد بالتأكيد ربط هذه الحسابات؟\n\n$ {ACCOUNT1}\n$ {ACCOUNT2}\n\nهذا لا يمكن التراجع عنها!", + "BombSquad Pro unlocked!": "لقد فتحت bomb squad الإصدار الاحترافي!", + "Can't link 2 accounts of this type.": "لا يمكن ربط حسابين من هذا النوع.", + "Can't link 2 diamond league accounts.": "لا يمكن ربط 2 حسابات الدوري الماس.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "لا يمكن الارتباط؛ سيتجاوز الحد الأقصى للحسابات المرتبطة ب ${COUNT} من الحسابات.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "الغش الكشف عنها. تم تعليق العشرات والجوائز لمدة ${COUNT} من الأيام.", + "Could not establish a secure connection.": "تعذر إنشاء اتصال آمن.", + "Daily maximum reached.": "الحد الأقصى اليومي الذي تم الوصول إليه.", + "Entering tournament...": "جار دخول البطولة ...", + "Invalid code.": "الرمز غير صحيح.", + "Invalid payment; purchase canceled.": "دفعة غير صالحة؛ تم إلغاء الشراء.", + "Invalid promo code.": "الرمز الترويجي غير صالح.", + "Invalid purchase.": "عملية شراء غير صالحة.", + "Invalid tournament entry; score will be ignored.": "دخول البطولة غير صالح؛ سيتم تجاهل النتيجة.", + "Item unlocked!": "العنصر غير مقفلة!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ربط مرفوض. ${ACCOUNT} يحتوي علي\nبيانات كبيرة والتي سيتم فقدانها.\nتستطيع الربط بالامر المعاكس اذا احببت\n(و فقدان بيانات هذا الحساب بالمقابل)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "هل تريد ربط الحساب ${ACCOUNT} بهذا الحساب؟\nسيتم فقد جميع البيانات الموجودة في ${ACCOUNT}.\nهذا لا يمكن التراجع عنها. هل أنت واثق؟", + "Max number of playlists reached.": "تم الوصول إلى أقصى عدد من قوائم التشغيل.", + "Max number of profiles reached.": "تم الوصول إلى أقصى عدد من الملفات الشخصية.", + "Maximum friend code rewards reached.": "تم الوصول إلى الحد الأقصى لمكافآت الرمز الصديق.", + "Message is too long.": "الرسالة طويلة جدا", + "No servers are available. Please try again soon.": "لا توجد خوادم متاحة. من فضلك حاول لاحقا", + "Profile \"${NAME}\" upgraded successfully.": "تمت ترقية الملف الشخصي \"${NAME}\" بنجاح.", + "Profile could not be upgraded.": "تعذر ترقية الملف الشخصي.", + "Purchase successful!": "تم الشراء بنجاح!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "تم استلام ${COUNT} من التذاكر لتسجيل الدخول.\nارجع غدا لاستلام ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "لم تعد معتمدة وظيفة الخادم في هذا الإصدار من اللعبة.\nالرجاء التحديث إلى إصدار أحدث.", + "Sorry, there are no uses remaining on this code.": "عذرا، لا توجد أية استخدامات متبقية في هذه الشفرة.", + "Sorry, this code has already been used.": "عذرا، تم استخدام هذه الشفرة من قبل.", + "Sorry, this code has expired.": "عذرا، انتهت صلاحية هذا الرمز.", + "Sorry, this code only works for new accounts.": "عذرا، لا تعمل هذه الشفرة إلا لحسابات جديدة.", + "Still searching for nearby servers; please try again soon.": "يزال البحث عن سيرفرات قريبة; من فضلك كرر المحاولة لاحقا", + "Temporarily unavailable; please try again later.": "غير متاح مؤقتا؛ الرجاء معاودة المحاولة في وقت لاحق.", + "The tournament ended before you finished.": "انتهت البطولة قبل الانتهاء.", + "This account cannot be unlinked for ${NUM} days.": "لا يمكن إلغاء ربط هذا الحساب بمبلغ ${NUM} من الأيام.", + "This code cannot be used on the account that created it.": "لا يمكن استخدام هذا الرمز على الحساب الذي أنشأه.", + "This is currently unavailable; please try again later.": "ذلك غير متوفر حاليا؛ يرجى المحاولة لاحقا", + "This requires version ${VERSION} or newer.": "يتطلب هذا الإصدار ${VERSION} أو أحدث.", + "Tournaments disabled due to rooted device.": "تم تعطيل الدورات نظراً لوجود روت", + "Tournaments require ${VERSION} or newer": "تتطلب الدورات ${VERSION} أو أحدث", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "هل تريد إلغاء ربط ${ACCOUNT} من هذا الحساب؟\nسيتم إعادة تعيين جميع البيانات على ${ACCOUNT}.\n(باستثناء الإنجازات في بعض الحالات)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "تحذير: تم إصدار شكاوى تتعلق بالقرصنة ضد حسابك.\nسيتم حظر الحسابات التي تم العثور عليها عن طريق القرصنة. يرجى لعب عادل.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "هل تريد ربط حساب الجهاز بهذا الحساب؟\n\nحساب الجهاز هو ${ACCOUNT1}\nهذا الحساب هو ${ACCOUNT2}\n\nهذا سيسمح لك للحفاظ على التقدم المحرز الخاص بك.\nتحذير: لا يمكن التراجع عن ذلك!", + "You already own this!": "كنت تملك هذا بالفعل!", + "You can join in ${COUNT} seconds.": "يمكنك الانضمام في ${COUNT} ثانية.", + "You don't have enough tickets for this!": "ليس لديك ما يكفي من تذاكر لهذا!", + "You don't own that.": "أنت لا تملك ذلك.", + "You got ${COUNT} tickets!": "لقد حصلت على تذاكر ${COUNT}!", + "You got a ${ITEM}!": "لقد حصلت على ${ITEM}!", + "You have been promoted to a new league; congratulations!": "لقد تم ترقيتك إلى الدوري الجديد. تهانينا!", + "You must update to a newer version of the app to do this.": "يجب تحديث إلى إصدار أحدث من التطبيق للقيام بذلك.", + "You must update to the newest version of the game to do this.": "يجب عليك التحديث إلى الإصدار الأحدث من اللعبة للقيام بذلك.", + "You must wait a few seconds before entering a new code.": "يجب الانتظار بضع ثوان قبل إدخال رمز جديد.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "لقد حصلت على الترتيب # ${RANK} في البطولة الأخيرة. شكرا للعب!", + "Your account was rejected. Are you signed in?": "لقد حُذف حسابك.هل قمت بتسجيل دخولك?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "تم تعديل نسختك من اللعبة.\nيرجى إعادة أي تغييرات وإعادة المحاولة.", + "Your friend code was used by ${ACCOUNT}": "تم استخدام رمز صديقك بواسطة ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 دقيقة", + "1 Second": "1 ثانيه", + "10 Minutes": "10 دقائق", + "2 Minutes": "2 دقيقة", + "2 Seconds": "2 ثانية", + "20 Minutes": "20 دقيقة", + "4 Seconds": "4 ثوان", + "5 Minutes": "5 دقائق", + "8 Seconds": "8 ثوان", + "Allow Negative Scores": "السماح بالعشرات السلبية", + "Balance Total Lives": "توازن إجمالي الحياة", + "Bomb Spawning": "قنبلة التفريخ", + "Chosen One Gets Gloves": "اختيار واحد يحصل قفازات", + "Chosen One Gets Shield": "اختار واحد يحصل درع", + "Chosen One Time": "اختار مرة واحدة", + "Enable Impact Bombs": "تمكين القنابل الأثر", + "Enable Triple Bombs": "تمكين القنابل الثلاثي", + "Entire Team Must Finish": "فريق كامل يجب الانتهاء", + "Epic Mode": "وضع ملحمة", + "Flag Idle Return Time": "العلم الخمول وقت العودة", + "Flag Touch Return Time": "العلم لمس عودة الوقت", + "Hold Time": "تمسك بالوقت", + "Kills to Win Per Player": "يقتل للفوز لكل لاعب", + "Laps": "لفات", + "Lives Per Player": "يعيش لكل لاعب", + "Long": "طويل", + "Longer": "طويل", + "Mine Spawning": "منجم", + "No Mines": "لا مناجم", + "None": "لا شيء", + "Normal": "عادي", + "Pro Mode": "وضع المحترف", + "Respawn Times": "أوقات الفجر", + "Score to Win": "يسجل الفوز", + "Short": "قصيرة", + "Shorter": "أقصر", + "Solo Mode": "وضع فردي", + "Target Count": "عدد الأهداف", + "Time Limit": "الوقت المحدد" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "تم استبعاد ${TEAM} بسبب ترك ${PLAYER}", + "Killing ${NAME} for skipping part of the track!": "قتل ${NAME} لتخطي جزء من المسار!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "تحذير الي ${NAME}: السرعة غير العادية / تخريب الازرار يسقطك ارضا." + }, + "teamNames": { + "Bad Guys": "الأشرار", + "Blue": "ازرق", + "Good Guys": "الأخيار", + "Red": "أحمر" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "A توقيت تماما تشغيل القفز تدور لكمة يمكن أن تقتل في ضربة واحدة\nوكسب لك مدى الحياة الاحترام من أصدقائك.", + "Always remember to floss.": "تذكر دائما الخيط.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "إنشاء ملفات تعريف لاعب لنفسك وأصدقائك مع\nالأسماء المفضلة لديك ومظاهر بدلا من استخدام تلك العشوائية.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "صناديق لعنة تتحول لك في قنبلة موقوتة.\nالعلاج الوحيد هو الاستيلاء بسرعة على حزمة الصحية.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "على الرغم من مظهرها، وقدرات جميع الشخصيات متطابقة،\nحتى مجرد اختيار أيهما واحد كنت أقرب تشبه.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "لا تحصل على مبهرج جدا مع أن درع الطاقة؛ لا يزال بإمكانك الحصول على نفسك ألقيت قبالة الهاوية.", + "Don't run all the time. Really. You will fall off cliffs.": "لا تعمل في كل وقت. هل حقا. سوف تسقط المنحدرات.", + "Don't spin for too long; you'll become dizzy and fall.": "لا تدور لفترة طويلة جدا. عليك أن تصبح بالدوار والسقوط.", + "Hold any button to run. (Trigger buttons work well if you have them)": "عقد أي زر لتشغيل. (أزرار الزناد تعمل بشكل جيد إذا كان لديك لهم)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "اضغط باستمرار على أي زر لتشغيله. ستحصل على الأماكن بشكل أسرع\nولكن لن تتحول بشكل جيد للغاية، لذلك احترس من المنحدرات.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "القنابل الثلجية ليست قوية جدا، لكنها تجمد\nأيا كان ضربهم، مما يجعلهم عرضة للتلف.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "إذا كان شخص ما يختار لك، لكمة لهم وأنها سوف ترك.\nهذا يعمل في الحياة الحقيقية أيضا.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "إذا كنت قصيرا على وحدات التحكم، فثبت تطبيق '${REMOTE_APP_NAME}'\nعلى الأجهزة المحمولة الخاصة بك لاستخدامها كأجهزة تحكم.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "إذا كنت تحصل على قنبلة لزجة عالقة لك، والقفز حولها وتدور في الدوائر. يمكنك\nهز القنبلة قبالة، أو إذا كان أي شيء آخر لحظاتك الأخيرة ستكون مسلية.", + "If you kill an enemy in one hit you get double points for it.": "إذا كنت قتل عدو في ضربة واحدة تحصل على نقاط ضعف لذلك.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "إذا كنت تلتقط لعنة، الأمل الوحيد للبقاء على قيد الحياة هو\nالعثور على السلطة الصحية حتى في ثوان القليلة المقبلة.", + "If you stay in one place, you're toast. Run and dodge to survive..": "إذا كنت البقاء في مكان واحد، وكنت نخب. تشغيل ودودج من أجل البقاء ..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "إذا كنت قد حصلت على الكثير من اللاعبين القادمة والذهاب، بدوره على 'لصناعة السيارات في ركلة الخمول لاعبين'\nتحت إعدادات في حالة نسي أحد لمغادرة اللعبة.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "إذا كان جهازك يحصل دافئ جدا أو كنت ترغب في الحفاظ على طاقة البطارية،\nرفض \"المرئيات\" أو \"قرار\" في إعدادات-> الرسومات", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "إذا كان إطار الإطارات متقطع، فجرب رفض الدقة\nأو المرئيات في إعدادات الرسومات اللعبة.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "في القبض على العلم العلم الخاص بك يجب أن يكون في قاعدة الخاص بك ليسجل، إذا كان الآخر\nفريق على وشك أن يسجل، وسرقة علمهم يمكن أن يكون وسيلة جيدة لوقفها.", + "In hockey, you'll maintain more speed if you turn gradually.": "في الهوكي، عليك الحفاظ على مزيد من السرعة إذا قمت بتشغيل تدريجيا.", + "It's easier to win with a friend or two helping.": "فإنه من الأسهل للفوز مع صديق أو اثنين مساعدة.", + "Jump just as you're throwing to get bombs up to the highest levels.": "القفز تماما كما كنت رمي ​​للحصول على القنابل تصل إلى أعلى المستويات.", + "Land-mines are a good way to stop speedy enemies.": "إن الألغام وسيلة جيدة لوقف الأعداء السريعين.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "العديد من الأشياء يمكن التقاطها وألقيت، بما في ذلك لاعبين آخرين. القذف\nأعدائك قبالة المنحدرات يمكن أن تكون استراتيجية فعالة وعاطفيا الوفاء.", + "No, you can't get up on the ledge. You have to throw bombs.": "لا، لا يمكنك الحصول على ما يصل على الحافة. لديك لرمي القنابل.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "يمكن للاعبين الانضمام وترك في منتصف معظم المباريات،\nويمكنك أيضا سد وفصل وحدات التحكم على الطاير.", + "Practice using your momentum to throw bombs more accurately.": "ممارسة استخدام الخاص بك لرمي القنابل بشكل أكثر دقة.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "اللكمات تفعل المزيد من الضرر أسرع القبضات الخاصة بك تتحرك،\nوذلك في محاولة تشغيل، والقفز، والغزل مثل مجنون.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "تشغيل ذهابا وإيابا قبل رمي قنبلة\nإلى \"الاصابة\" عليه ورميها أبعد.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "إخراج مجموعة من الأعداء من قبل\nوإطلاق قنبلة بالقرب من مربع تي ان تي.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "الرأس هو المنطقة الأكثر ضعفا، لذلك قنبلة لزجة\nإلى نوجين يعني عادة لعبة أكثر.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "هذا المستوى لا تنتهي أبدا، ولكن على درجة عالية هنا\nسوف كسب لك الاحترام الأبدية في جميع أنحاء العالم.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "وتستند قوة رمي على الاتجاه الذي عقد.\nلإرم شيء برفق أمامك، لا تحمل أي اتجاه.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "تعبت من الموسيقى التصويرية؟ استبدالها بنفسك!\nانظر إعدادات-> الصوت-> الموسيقى التصويرية", + "Try 'Cooking off' bombs for a second or two before throwing them.": "محاولة 'الطبخ قبالة' القنابل لمدة ثانية أو اثنين قبل رمي لهم.", + "Try tricking enemies into killing eachother or running off cliffs.": "محاولة خداع الأعداء في قتل بعضهم البعض أو الجري المنحدرات.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "استخدم زر البيك اب للاستيلاء على العلم <${PICKUP}", + "Whip back and forth to get more distance on your throws..": "سوط ذهابا وإيابا للحصول على مزيد من المسافة على رميات الخاص بك", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "يمكنك 'تهدف' اللكمات الخاصة بك عن طريق الغزل اليسار أو اليمين.\nوهذا مفيد لضرب الأشرار من حواف أو التهديف في الهوكي.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "يمكنك تحديد وقت إنفجار القنبلة بناءً على لون الشرارة المنبعثة من فتيلها:\nأصفر..برتقالي..أحمر ثم بووم.", + "You can throw bombs higher if you jump just before throwing.": "يمكنك رمي القنابل أعلى إذا كنت القفز قبل رمي.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "كنت تأخذ الضرر عندما كنت اجتز رأسك على الأشياء،\nوذلك في محاولة لا اجتز رأسك على الأشياء.", + "Your punches do much more damage if you are running or spinning.": "لكماتك تؤثر بضرر اكبر اذا كنت تجري او تدور" + } + }, + "trophiesRequiredText": "جوائز ${NUMBER} هذا يحتاج على الاقل", + "trophiesText": "الجوائز", + "trophiesThisSeasonText": "جوائز هذا الموسم", + "tutorial": { + "cpuBenchmarkText": "(CPU تشغيل البرنامج التعليمي بالسرعة المثيرة للسخرية (رئيسيا لتجريب سرعة", + "phrase01Text": "!مرحبا", + "phrase02Text": "!${APP_NAME} أهلا بك في", + "phrase03Text": "إليك بعض النصائح للتحكم بشخصيتك", + "phrase04Text": "درست فرقة القنبلة كثيرا من الاشياء فيزيائيا ${APP_NAME}**", + "phrase05Text": "...,على سبيل المثال, عندما تلكم", + "phrase06Text": "الضرر مبني على سرعة لكماتك", + "phrase07Text": "${NAME} كما ترى, نحن لا نتحرك لهذا بالكاد نصيب", + "phrase08Text": "الآن قم بالقفز والدوران لكسب زخم اكثر", + "phrase09Text": "!آه هذا أفضل", + "phrase10Text": "الجري يساعد ايضا", + "phrase11Text": "استمر في الضغط على اي زر للجري", + "phrase12Text": "للحصول على لكمة رائعة اضافية, جرب الجري و الدوران", + "phrase13Text": "${NAME} أوبس؛ اعتذر بشأن هذا يا يا صاح", + "phrase14Text": "${NAME} يمكنك امساك ورمي الاشياء مثل الاعلام .. أو", + "phrase15Text": "أخيرا, هناك القنابل", + "phrase16Text": "رمي القنابل يحتاج للتدريب", + "phrase17Text": "اوو! لم تكن رمية جيدة", + "phrase18Text": "التحرك يساعدك على الرمي ابعد", + "phrase19Text": "القفز يساعدك على الرمي اعلى", + "phrase20Text": "فجر\"قنابلك لمدى حتى أبعد من ذلك\"", + "phrase21Text": "توقيت القنبلة يمكن أن يكون مخادعا", + "phrase22Text": "!بووم", + "phrase23Text": "جرب امساك القنبلة ليذوب الفتيل لثانية او اثنتين", + "phrase24Text": "مرحى! لقد تم شواؤه بشكل رائع", + "phrase25Text": "حسنا, هذا كل ما في الامر", + "phrase26Text": "!والآن؛ اذهب ونل منهم يا نمر", + "phrase27Text": "إن تذكرت تدريبك.. فستعود حيا", + "phrase28Text": "...حسنا, ربما...", + "phrase29Text": "!حظا سعيدا", + "randomName1Text": "فريد", + "randomName2Text": "هاني", + "randomName3Text": "باسل", + "randomName4Text": "كيفن", + "randomName5Text": "جوني", + "skipConfirmText": "حقا تريد تخطي البرنامج التعليمي؟ إلمس أو اضغط بإستمرار", + "skipVoteCountText": "تخطي اصوات ${COUNT}/${TOTAL}", + "skippingText": "جاري تخطي البرنامج التعليمي....", + "toSkipPressAnythingText": "(إلمس او إضغظ اي شئ لتخطي البرنامج التعليمي)" + }, + "twoKillText": "!قتل مزدوج", + "unavailableText": "غير متوفر", + "unconfiguredControllerDetectedText": ":تم الكشف على يد تحكم غير مهيئة", + "unlockThisInTheStoreText": "هذا يجب ان يفتح في المتجر", + "unlockThisProfilesText": "لإنشاء أكثر من ${NUM} من الملفات الشخصية، تحتاج إلى:", + "unlockThisText": ":لفتح هذا, تحتاج إلى", + "unsupportedHardwareText": "عفوا, هذه المعدات غير مدعومة في هذه النسخة من اللعبة", + "upFirstText": ":يصل اولا", + "upNextText": ":${COUNT}التالي في اللعبة", + "updatingAccountText": "تحديث الحساب الخاص بك....", + "upgradeText": "احصل على ترقية", + "upgradeToPlayText": "في متجر اللعبة لتلعب هذا \"${PRO}\" اشتري", + "useDefaultText": "استخدام الإفتراضي", + "usesExternalControllerText": "هذه اللعبة تستخدم يد تحكم خارجية للإدخال", + "usingItunesText": "...استخدام تطبيق الموسيقى للموسيقى التصويرية", + "v2AccountLinkingInfoText": "اذا اردت ربط حسابات V2، قم بالتوجه الى 'ادارة الحساب'.", + "validatingTestBuildText": "التحقق من صحة البناء", + "victoryText": "!النصر", + "voteDelayText": "ثانية ${NUMBER} لا يمكنك التصويت ثانية حتى", + "voteInProgressText": "التصويت بالفعل في التقدم", + "votedAlreadyText": "لقد صوت بالفعل", + "votesNeededText": "صوت مطلوب ${NUMBER}", + "vsText": "ضد", + "waitingForHostText": "(للإستمرار ${HOST} انتظار)", + "waitingForPlayersText": "...انتظار اللاعيبين للإنضمام", + "waitingInLineText": "الانتظار في السطر (الطرف ممتلئ) ...", + "watchAVideoText": "شاهد فيديو", + "watchAnAdText": "شاهد اعلان", + "watchWindow": { + "deleteConfirmText": "\"${REPLAY}\"? حذف", + "deleteReplayButtonText": "حذف\nالإعادة", + "myReplaysText": "إعاداتي", + "noReplaySelectedErrorText": "لايوجد إعادة تم اختيارها", + "playbackSpeedText": "سرعة الاعادة: ${SPEED}", + "renameReplayButtonText": "إعادة تسمبة \n الإعادة", + "renameReplayText": ":الى \"${REPLAY}\" اعادة تسمية", + "renameText": "إعادة تسمية", + "replayDeleteErrorText": "خطا في حذف الإعادة", + "replayNameText": "اسم الإعادة", + "replayRenameErrorAlreadyExistsText": "اسم الإعادة موجود بالفعل", + "replayRenameErrorInvalidName": "لايمكن اعادة تسمية الإعادة; الاسم غير صالح", + "replayRenameErrorText": "خطا في اعادة تسمية الإعادة", + "sharedReplaysText": "الإعادة المشاركة", + "titleText": "شاهد", + "watchReplayButtonText": "شاهد\nالإعادة" + }, + "waveText": "موجة", + "wellSureText": "!حسنا طبعا", + "whatIsThisText": "ما هذا؟", + "wiimoteLicenseWindow": { + "titleText": "DarwinRemoteحقوق التأليف والنشر ل" + }, + "wiimoteListenWindow": { + "listeningText": "الاستماع ل وييموتس ...", + "pressText": "رقم 1 و 2 معا Wiimote اضغط زري", + "pressText2": "الاحمر في الخلف بدلا من ذلك'sync' فيه,اضغط زر Motion Plus الاجهزة الجديدة مع خاصية Wiimotes في اجهزة" + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote حق نشر", + "listenText": "استمع", + "macInstructionsText": "الخاص بك مطفئا والبلوتوث مفعلا في الماك الخاص بك Wii تأكد ان\nقد لا يفعل من اول مرة Wiimote support 'Listen' ثم اضغظ \nقد يكون عليك التجريب عدة مرات قبل ان تحصل على اتصال\n\n\nيجب على البلوتوث ان يتعامل الى مايصل الى 7 اجهزة متصلة\nرغم ان المسافة قد تختلف\n\nالاصلية Wiimotes اللعبة تدعم اجهزة\nوالجهاز الافتراضي,Nunchuks,\nيعمل ايضا Wii Remote Plus جهاز \nولكن ليس مع المرفقات", + "thanksText": "DarwiinRemote شكرا لفريق\nلجعل هذا ممكنا", + "titleText": "wiimote تثبيت" + }, + "winsPlayerText": "${NAME} !يفوز", + "winsTeamText": "${NAME} !يفوز فريق", + "winsText": "${NAME} !يفوز", + "workspaceSyncErrorText": "فشل في مزامنة ${WORKSPACE}. القي نظرة على السجل للتفاصيل.", + "workspaceSyncReuseText": "لا يمكن مزامنة ${WORKSPACE}. اعادة استخدام النسخة المتزامنة السابقة.", + "worldScoresUnavailableText": "(النتيجة العالمية غير متوفرة (اتصل بالانترنت", + "worldsBestScoresText": "افضل نتيجة للعالم", + "worldsBestTimesText": "افضل اوقات العالم", + "xbox360ControllersWindow": { + "getDriverText": "احصل على تعريف", + "macInstructions2Text": "لاستخدام وحدات تحكم لاسلكيا، سوف تحتاج أيضا المتلقي ذلك\nيأتي مع \"تحكم اكس بوكس 360 اللاسلكية ويندوز\".\nواحد المتلقي يسمح لك لربط ما يصل إلى 4 وحدات تحكم.\n\nهام: لن تعمل أجهزة الاستقبال التابعة لجهة خارجية مع برنامج التشغيل هذا؛\nتأكد من جهاز الاستقبال يقول 'مايكروسوفت' على ذلك، وليس 'الاكس بوكس 360'.\nمايكروسوفت لم تعد تبيع هذه بشكل منفصل، لذلك سوف تحتاج إلى الحصول عليها\nواحد المجمعة مع وحدة تحكم أو البحث إيباي آخر.\n\nإذا وجدت هذا مفيد، يرجى النظر في التبرع ل\nمطور برامج في موقعه.", + "macInstructionsText": "لاستخدام وحدات تحكم الاكس بوكس 360، ستحتاج إلى تثبيت\nبرنامج تشغيل ماك متوفر على الرابط أدناه.\nوهو يعمل مع كل من وحدات تحكم السلكية واللاسلكية.", + "ouyaInstructionsText": "سلكية مع اللعبة Xbox 360 لإستخدام يد تحكم \nببساطة وصلها بمنفذ يو إس بي للجهاز. يمكنك استخدام محور يو إس بي \nلتوصيل عدة اجهزة\n\n\"Xbox 360 wireless Controller for Windows\"لتوصيل يد تحكم لاسلكية تحتاج لمتسقبل لاسلكي خاص\n, متوفرة في حزمة\nاو يمكنك شراءها منفردة.كل مستقبل يمكنك \nمن خلاله توصيل 4 ايدي تحكم لاسلكية", + "titleText": "استخدام يد تحكم Xbox 360 مع ${APP_NAME}:" + }, + "yesAllowText": "!نعم,اسمح", + "yourBestScoresText": "أفضل نقاطك", + "yourBestTimesText": "أفضل أوقاتك" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/belarussian.json b/dist/ba_data/data/languages/belarussian.json new file mode 100644 index 0000000..ce89a78 --- /dev/null +++ b/dist/ba_data/data/languages/belarussian.json @@ -0,0 +1,1876 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Імя акаўнта не можа ўтрымліваць эмоджы і іншыя спецыяльныя сымбалі", + "accountsText": "Акаўнты", + "achievementProgressText": "Дасягненні: ${COUNT} з ${TOTAL}", + "campaignProgressText": "Прагрэс кампаніі (Цяжка): ${PROGRESS}", + "changeOncePerSeason": "Вы можаце змяніць толькі адзін раз за сезон.", + "changeOncePerSeasonError": "Трэба пачакаць наступнага сезона, каб зноў змяніць гэта (${NUM} days)", + "customName": "Зрабіць імя", + "linkAccountsEnterCodeText": "Увесцi Код", + "linkAccountsGenerateCodeText": "Стварыць Код", + "linkAccountsInfoText": "(сінхранізацыя гульні паміж рознымі платформамі)", + "linkAccountsInstructionsNewText": "Для таго, каб звязаць два акаўнта, згенерыруйце код на першым\nі ўведзіце гэты код на другім. Прагрэс з\nдругога акаўнта будзе размяркоўвацца паміж абодвума.\n(Прагрэс з першага акаўнта будзе страчаны)\n\nВы можаце падключыць да ${COUNT} акаўнтаў.\n\nУВАГА: звязвайце толькі тыя акаўнты, якімі вы валодаеце;\nКалі вы звязваеце іх з акаўнтамі сяброў, вы не будзеце\nмець магчымасць гуляць онлайн ў той жа самы час.", + "linkAccountsInstructionsText": "Каб звязаць 2 акаўнта, стварыце код на першым\nз іх і увядзіце яго ў другім.\nПрагрэс і пакупкі будуць сінранізаваны.\nВы можаце звязаць да ${COUNT} акаўнтаў.\n\nАсцярожна! Гэта нельга адмяніць!", + "linkAccountsText": "Звязаць Акаўнты", + "linkedAccountsText": "Злучаныя Акаўнты:", + "nameChangeConfirm": "Змяніць імя акаўнта на ${NAME} ?", + "resetProgressConfirmNoAchievementsText": "Гэта скіне ўвесь ваш кааператыўны прагрэс\nды лакальныя лепшыя вынікі (акрамя білетаў).\nГэты працэс незваротны. Вы ўпэўнены?", + "resetProgressConfirmText": "Гэта скіне ўвесь ваш кааператыўны\nпрагрэс, дасягненні ды лакальныя вынікі\n(акрамя білетаў). Гэты працэс незваротны.\nВы ўпэўнены?", + "resetProgressText": "Скінуць прагрэс", + "setAccountName": "Усталяваць імя акаўнта", + "setAccountNameDesc": "Выберыце імя для адлюстравання для вашага ўліковага запісу.\nВы можаце выкарыстоўваць імя ў адным з звязаных\nуліковых запісаў альбо стварыць унікальнае прыстасаванае імя.", + "signInInfoText": "Увайдзіце, каб збіраць квіткі, удзельнічаць у спаборніцтвах \nі сінхранізіраваць прагрэс паміж рознымі прыладамі.", + "signInText": "Увайсці", + "signInWithDeviceInfoText": "(толькі аўтаматычны акаўнт даступны для гэтай прылады)", + "signInWithDeviceText": "Увайсці з акаўнта прылады", + "signInWithGameCircleText": "Увайсці з дапамогаю Game Circle", + "signInWithGooglePlayText": "Увайсці з дапамогаю Google Play", + "signInWithTestAccountInfoText": "(акаўнт, які ўжо існуе; спачатку увайдзіце з прылады)", + "signInWithTestAccountText": "Увайсці з тэст-акаўнта", + "signInWithV2InfoText": "(уліковы запіс, які працуе на ўсіх платформах)", + "signInWithV2Text": "Увайдзіце з уліковым запісам BombSquad", + "signOutText": "Выйсці", + "signingInText": "Уваход...", + "signingOutText": "Выхад...", + "testAccountWarningCardboardText": "Увага: вы ўваходзіце з \"тэст\"-акаунта.\nГэтыя дадзеныя будуць заменены акаунтамі Google, як толькі \nяны стануць падтрымлівацца ў cardboard прыладах.\n\nЗараз вам прыйдзецца зарабляць усе білеты толькі на гэтай прыладзе.\n(негледзячы на гэта, вы атрымаеце Pro-версію BombSquade бясплатна)", + "testAccountWarningOculusText": "Увага: вы ўваходзіце з \"тэст\"-акаунта.\nЁн будзе заменены акаунтамі Oculus пазней у гэтым годзе, \nякія будуць прапаноўваць куплю білетаў і іншыя магчымасці.\n\nЗараз вам прыйдзецца зарабляць усе білеты толькі на гэтай прыладзе.\n(негледзячы на гэта, вы атрымаеце Pro-версію BombSquade бясплатна)", + "testAccountWarningText": "Увага: вы ўваходзіце з \"тэст\"-акаунта.\nГэты акаунт захаваны толькі на гэтай прыладзе і\nможа часам выдаляцца. (таму калі ласка не марнуйце\nмнога часу, збіраючы білеты)\n\nКаб выкарыстоўваць сапраўдны акаунт (Game-Center, Google+\nі іншыя) запусціце платную версію гульні. Гэта таксама\nдазволіць вам захоўваць свой прагрэс ў воблацы і\nгуляць з ім на розных прыладах. ", + "ticketsText": "Квіткі: ${COUNT}", + "titleText": "Акаўнт", + "unlinkAccountsInstructionsText": "Выберыце ўліковы запіс, каб спыніць сувязь", + "unlinkAccountsText": "Адлучэнне акаунтау", + "v2LinkInstructionsText": "Выкарыстоўвайце гэтую спасылку, каб стварыць уліковы запіс або ўвайсці.", + "viaAccount": "(праз акаунт ${NAME})", + "youAreSignedInAsText": "Вы ўвайшлі як:" + }, + "achievementChallengesText": "Дасягненні", + "achievementText": "Дасягненне", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Забейце 3 злодзеяў з дапамогаю TNT", + "descriptionComplete": "З дапамогаю TNT забіты 3 злодзея", + "descriptionFull": "Забейце 3 злодзеяў з дапамогаю TNT на ўзроўні ${LEVEL}", + "descriptionFullComplete": "На ўзроўні ${LEVEL} з дапамогаю TNT забіты 3 злодзея", + "name": "Зараз падарвецца!" + }, + "Boxer": { + "description": "Перамажыце, не выкарыстоўвываючы бомбы", + "descriptionComplete": "Перамаглі, не выкарыстоўвываючы бомбы", + "descriptionFull": "Прайдзіце ${LEVEL}, не выкарыстоўвываючы бомбы", + "descriptionFullComplete": "Прайшлі ${LEVEL}, не выкарыстоўвываючы бомбы", + "name": "Баксёр" + }, + "Dual Wielding": { + "descriptionFull": "Падлучыце кантролера", + "descriptionFullComplete": "Падлучаны 2 кантролера", + "name": "Падваенне Зброі" + }, + "Flawless Victory": { + "description": "Перамажыце, не атрымліваючы пашкоджанні", + "descriptionComplete": "Перамаглі, не атрымліваючы пашкоджанні", + "descriptionFull": "Перамажыце ${LEVEL}, не атрымліваючы пашкоджанні", + "descriptionFullComplete": "Перамаглі ${LEVEL}, не атрымліваючы пашкоджанні", + "name": "Бездакорная перамога" + }, + "Free Loader": { + "descriptionFull": "Пачніце гульню з 2 і больш гульцамі", + "descriptionFullComplete": "Пачата гульня з 2 і больш гульцамі", + "name": "Свабодны Гулец" + }, + "Gold Miner": { + "description": "Забейце 6 злодзеяў з дапамогаю мін", + "descriptionComplete": "З дапамогаю мін забіты 6 злодзеяў", + "descriptionFull": "Забейце 6 злодзеяў з дапамогаю мін на узроўні ${LEVEL}", + "descriptionFullComplete": "На узроўні ${LEVEL} з дапамогаю мін забіты 6 злодзеяў", + "name": "Залаты мінёр" + }, + "Got the Moves": { + "description": "Перамажыце, не выкарыстоўваючы ўдары ці бомбы", + "descriptionComplete": "Перамаглі, не выкарыстоўваючы ўдары ці бомбы", + "descriptionFull": "Перамажыце на ўзроўні ${LEVEL}, не выкарыстоўваючы ўдары ці бомбы", + "descriptionFullComplete": "Перамаглі ўзровень ${LEVEL}, не выкарыстоўваючы ўдары ці бомбы", + "name": "Дакладныя Дзеянні" + }, + "In Control": { + "descriptionFull": "Падлучыце кантролер", + "descriptionFullComplete": "Падлучаны кантролер.", + "name": "Усё пад Кантролем" + }, + "Last Stand God": { + "description": "Набярыце 1000 ачкоў", + "descriptionComplete": "Набралі 1000 ачкоў", + "descriptionFull": "Набярыце 1000 ачкоў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Набралі 1000 ачкоў на ўзроўні ${LEVEL}", + "name": "Бог узроўня ${LEVEL}" + }, + "Last Stand Master": { + "description": "Набярыце 250 ачкоў", + "descriptionComplete": "Набралі 250 ачкоў", + "descriptionFull": "Набярыце 250 ачкоў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Набралі 250 ачкоў на ўзроўні ${LEVEL}", + "name": "Майстар узроўня ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Набярыце 500 ачкоў", + "descriptionComplete": "Набралі 500 ачкоў", + "descriptionFull": "Набярыце 500 ачкоў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Набралі 500 ачкоў на ўзроўні ${LEVEL}", + "name": "Чараўнік узроўня ${LEVEL}" + }, + "Mine Games": { + "description": "Забейце 3 злодзеяў мінамі", + "descriptionComplete": "Забілі 3 злодзеяў мінамі", + "descriptionFull": "Забейце 3 злодзеяў мінамі на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Забілі 3 злодзеяў мінамі на ўзроўні ${LEVEL}", + "name": "Гульні З Мінамі" + }, + "Off You Go Then": { + "description": "Скіньце 3 злодзеяў з мапы", + "descriptionComplete": "Скінулі 3 злодзеяў з мапы", + "descriptionFull": "Скіньце 3 злодзеяў з мапы на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Скінулі 3 злодзеяў з мапы на ўзроўні ${LEVEL}", + "name": "Давай Адсюль" + }, + "Onslaught God": { + "description": "Набярыце 5000 ачкоў", + "descriptionComplete": "Набралі 5000 ачкоў", + "descriptionFull": "Набярыце 5000 ачкоў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Набралі 5000 ачкоў на ўзроўні ${LEVEL}", + "name": "Бог узроўня ${LEVEL}" + }, + "Onslaught Master": { + "description": "Набярыце 500 ачкоў", + "descriptionComplete": "Набралі 500 ачкоў", + "descriptionFull": "Набярыце 500 ачкоў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Набралі 500 ачкоў на ўзроўні ${LEVEL}", + "name": "Майстар узроўня ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Перамажыце ўсе хвалі", + "descriptionComplete": "Перамаглі ўсе хвалі", + "descriptionFull": "Перамажыце ўсе хвалі на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Перамаглі ўсе хвалі на ўзроўні ${LEVEL}", + "name": "Перамога на ўзроўні ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Набярыце 1000 ачкоў", + "descriptionComplete": "Набралі 1000 ачкоў", + "descriptionFull": "Набярыце 1000 ачкоў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Набралі 1000 ачкоў на ўзроўні ${LEVEL}", + "name": "Чараўнік узроўня ${LEVEL}" + }, + "Precision Bombing": { + "description": "Перамажыце без узмацняльнікаў", + "descriptionComplete": "Перамаглі без узмацняльнікаў", + "descriptionFull": "Перамажыце ўзровень ${LEVEL} без узмацняльнікаў", + "descriptionFullComplete": "Перамаглі ўзровень ${LEVEL} без узмацняльнікаў", + "name": "Прыцэльнае Бомбакіданне" + }, + "Pro Boxer": { + "description": "Перамажыце без бомб", + "descriptionComplete": "Перамаглі без бомб", + "descriptionFull": "Перамажыце ўзровень ${LEVEL} без бомб", + "descriptionFullComplete": "Перамаглі ўзровень ${LEVEL} без бомб", + "name": "Баксёр Профі" + }, + "Pro Football Shutout": { + "description": "Перамажыце, не даўшы злодзеям набраць ачкі", + "descriptionComplete": "Перамаглі, не даўшы злодзеям набраць ачкі", + "descriptionFull": "Перамажыце на ўзроўні ${LEVEL}, не даўшы злодзеям набраць ачкі", + "descriptionFullComplete": "Перамаглі на ўзроўні ${LEVEL}, не даўшы злодзеям набраць ачкі", + "name": "Усухую на ўзроўні ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Перамажыце гульню", + "descriptionComplete": "Перамаглі гульню", + "descriptionFull": "Перамажыце гульню на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Перамаглі гульню на ўзроўні ${LEVEL}", + "name": "Перамога на ўзроўні ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Перамажыце ўсе хвалі", + "descriptionComplete": "Перамаглі ўсе хвалі", + "descriptionFull": "Перамажыце ўсе хвалі на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Перамаглі ўсе хвалі на ўзроўні ${LEVEL}", + "name": "Перамога на ўзроўні ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Перамажыце ўсе хвалі", + "descriptionComplete": "Перамаглі ўсе хвалі", + "descriptionFull": "Перамажыце ўсе хвалі на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Перамаглі ўсе хвалі на ўзроўні ${LEVEL}", + "name": "Перамога на узроўні ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Перамажыце, не даўшы злодзеям набраць ачкі", + "descriptionComplete": "Перамаглі, не даўшы злодзеям набраць ачкі", + "descriptionFull": "Перамажыце на ўзроўні ${LEVEL}, не даўшы злодзеям набраць ачкі", + "descriptionFullComplete": "Перамаглі на ўзроўні ${LEVEL}, не даўшы злодзеям набраць ачкі", + "name": "Усухую на узроўні ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Перамажыце матч", + "descriptionComplete": "Перамаглі матч", + "descriptionFull": "Перамажыце матч на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Перамаглі матч на ўзроўні ${LEVEL}", + "name": "Перамога на ўзроўні ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Перамажыце ўсе хвалі", + "descriptionComplete": "Перамаглі ўсе хвалі", + "descriptionFull": "Перамажыце ўсе хвалі на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Перамажыце ўсе хвалі на ўзроўні ${LEVEL}", + "name": "Перамога на ўзроўні ${LEVEL}" + }, + "Runaround God": { + "description": "Набярыце 2000 ачкоў", + "descriptionComplete": "Набралі 2000 ачкоў", + "descriptionFull": "Набярыце 2000 ачкоў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Набралі 2000 ачкоў на ўзроўні ${LEVEL}", + "name": "Бог узроўня ${LEVEL}" + }, + "Runaround Master": { + "description": "Набярыце 500 ачкоў", + "descriptionComplete": "Набралі 500 ачкоў", + "descriptionFull": "Набярыце 500 ачкоў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Набралі 500 ачкоў на ўзроўні ${LEVEL}", + "name": "Майстар узроўня ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Набярыце 1000 ачкоў", + "descriptionComplete": "Набралі 1000 ачкоў", + "descriptionFull": "Набярыце 1000 ачкоў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Набралі 1000 ачкоў на ўзроўні ${LEVEL}", + "name": "Чараўнік узроўня ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Падзяліцеся гульнёй з сябрам", + "descriptionFullComplete": "Падзяліліся гульнёй з сябрам", + "name": "Клопат аб Сябры" + }, + "Stayin' Alive": { + "description": "Перамажыце, не памірая", + "descriptionComplete": "Перамаглі, не памірая", + "descriptionFull": "Перамажыце на ўзроўні ${LEVEL}, не памірая", + "descriptionFullComplete": "Перамаглі на ўзроўні ${LEVEL}, не памірая", + "name": "Застацца Жывым" + }, + "Super Mega Punch": { + "description": "Забейце адным ударам", + "descriptionComplete": "Забілі адным ударам", + "descriptionFull": "Забейце адным ударам на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Забілі адным ударам на ўзроўні ${LEVEL}", + "name": "Супер Мега Ўдар" + }, + "Super Punch": { + "description": "Зніміце палову здароўя адным ударам", + "descriptionComplete": "Знялі палову здароўя адным ударам", + "descriptionFull": "Зніміце палову здароўя адным ударам на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Знялі палову здароўя адным ударам на ўзроўні ${LEVEL}", + "name": "Супер Удар" + }, + "TNT Terror": { + "description": "Забейце 6 злодзеяў з дапамогаю TNT", + "descriptionComplete": "Забілі 6 злодзеяў з дапамогаю TNT", + "descriptionFull": "Забейце 6 злодзеяў з дапамогаю TNT на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Забілі 6 злодзеяў з дапамогаю TNT на ўзроўні ${LEVEL}", + "name": "TNT Вар'яцтва" + }, + "Team Player": { + "descriptionFull": "Пачніце гульню з 4 і больш гульцамі", + "descriptionFullComplete": "Пачалі гульню з 4 і больш гульцамі", + "name": "Камандны Гулец" + }, + "The Great Wall": { + "description": "Спыніце ўсіх злодзеяў", + "descriptionComplete": "Спынілі ўсіх злодзеяў", + "descriptionFull": "Спыніце ўсіх злодзеяў на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Спынілі ўсіх злодзеяў на ўзроўні ${LEVEL}", + "name": "Магутная Сцяна" + }, + "The Wall": { + "description": "Спыніць кожнага злодзея", + "descriptionComplete": "Спынілі кожнага злодзея", + "descriptionFull": "Спыніць кожнага злодзея на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Спыніць кожнага злодзея на ўзроўні ${LEVEL}", + "name": "Сцяна" + }, + "Uber Football Shutout": { + "description": "Перамажыце, не даўшы злодзеям набраць ачкі", + "descriptionComplete": "Перамаглі, не даўшы злодзеям набраць ачкі", + "descriptionFull": "Перамажыце на ўзроўні ${LEVEL}, не даўшы злодзеям набраць ачкі", + "descriptionFullComplete": "Перамаглі на ўзроўні ${LEVEL}, не даўшы злодзеям набраць ачкі", + "name": "Усухую на ўзроўні ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Перамажыце гульню", + "descriptionComplete": "Перамог гульню", + "descriptionFull": "Перамажыце гульню на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Перамаглі гульню на ўзроўні ${LEVEL}", + "name": "Перамога на ўзроўні ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Перамажыце ўсе хвалі", + "descriptionComplete": "Перамаглі ўсе хвалі", + "descriptionFull": "Перамажыце ўсе хвалі на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Перамаглі ўсе хвалі на ўзроўні ${LEVEL}", + "name": "Перамога на ўзроўні ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Перамажыце ўсе хвалі", + "descriptionComplete": "Перамаглі ўсе хвалі", + "descriptionFull": "Перамажыце ўсе хвалі на ўзроўні ${LEVEL}", + "descriptionFullComplete": "Перамаглі ўсе хвалі на ўзроўні ${LEVEL}", + "name": "Перамога на ўзроўні ${LEVEL}" + } + }, + "achievementsRemainingText": "Дасягенні, Якія Засталіся", + "achievementsText": "Дасягненні", + "achievementsUnavailableForOldSeasonsText": "Прабачце, спецыфіка дасягненняў недаступна для старога сезона.", + "addGameWindow": { + "getMoreGamesText": "Атрымаць больш гульняў...", + "titleText": "Дадаць гульню" + }, + "allowText": "Дазволіць", + "alreadySignedInText": "Ваш уліковы запіс увайшоў з іншай прылады;\nкалі ласка, пераключыце ўліковыя запісы альбо зачыніце гульню на вашым\nіншыя прылады і паспрабуйце яшчэ раз", + "apiVersionErrorText": "Нельга загрузіць модуль ${NAME}; ён прапануецца для api-версіі ${VERSION_USED}; мы карыстаемся ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Аўтаматычна\" працуе толькі калі ўстаўлены навушнікі)", + "headRelativeVRAudioText": "H-R VR Аўдыя", + "musicVolumeText": "Гучнасць Музыкі", + "soundVolumeText": "Гучнасць", + "soundtrackButtonText": "Саўндтрэкі", + "soundtrackDescriptionText": "(дадайце сваю музыку, каб яна гучала падчас гульняў)", + "titleText": "Аўдыя" + }, + "autoText": "Аўтаматычна", + "backText": "Вярнуцца", + "banThisPlayerText": "Забараніць гэтага гульца", + "bestOfFinalText": "Фінал: Лепшыя з ${COUNT}", + "bestOfSeriesText": "Лепшы за ${COUNT} серыяў:", + "bestRankText": "Ваш найлепшы - #${RANK}", + "bestRatingText": "Ваш найлепшы рэйтынг - ${RATING}", + "bombBoldText": "БОМБА", + "bombText": "Бомба", + "boostText": "Павышэнне", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} наладзіцца сам.", + "buttonText": "Кнопка", + "canWeDebugText": "Ці жадаеце вы аўтаматычна паведамляць аб багах\nі аварыях распрацоўніку?\n\nГэтыя паведамленні не ўтрымліваюць асабістую інфармацыю\nі дапамагаюць палепшыць гульню.", + "cancelText": "Зачыніць", + "cantConfigureDeviceText": "Прабачце, ${DEVICE} не падтрымліваецца.", + "challengeEndedText": "Спаборніцтва скончылася.", + "chatMuteText": "Адключэнне гуку ў чаце", + "chatMutedText": "Чат адключон", + "chatUnMuteText": "Уключыць гук у чаце", + "choosingPlayerText": "<выбар гульца>", + "completeThisLevelToProceedText": "Вы павінны прайсці гэты\nўзровень, каб працягнуць!", + "completionBonusText": "Бонус за праходжанне", + "configControllersWindow": { + "configureControllersText": "Налады кантролераў", + "configureKeyboard2Text": "Налады клавіятуры 2-ога гульца", + "configureKeyboardText": "Налады клавіятуры", + "configureMobileText": "Мабільныя Прылады Ў Якасці Кантролераў", + "configureTouchText": "Налады Экрана", + "ps3Text": "Кантролеры PS3", + "titleText": "Кантролеры", + "wiimotesText": "Wiimotes", + "xbox360Text": "Кантролеры Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Падтрымка кантролераў залежыць ад прылады і версіі Android", + "pressAnyButtonText": "Націсніце любую кнопку на кантролеры,\n які вы жадаеце наладзіць...", + "titleText": "Налады Кантролераў" + }, + "configGamepadWindow": { + "advancedText": "Дадатковыя", + "advancedTitleText": "Дадатковыя Налады Кантролераў", + "analogStickDeadZoneDescriptionText": "(павялічце, калі персанаж працягвае рухацца пасля таго, як вы адпусцілі стык)", + "analogStickDeadZoneText": "Мёртвая Зона Аналагавага Сціка", + "appliesToAllText": "(адносіцца да ўсіх кантролераў гэтага тыпу)", + "autoRecalibrateDescriptionText": "(уключыце гэта, калі персанаж не рухаецца на поўнай хуткасці)", + "autoRecalibrateText": "Аўта-Перакабліроўка Аналагавых Стыкаў", + "axisText": "Вось", + "clearText": "Ачысціць", + "dpadText": "D-Pad", + "extraStartButtonText": "Дадатковая кнопка \"Старт\"", + "ifNothingHappensTryAnalogText": "Калі нічога не адбываецца, паспрабуйце прызначыць аналагавы стык.", + "ifNothingHappensTryDpadText": "Калі нічога не адбываецца, паспрабуйце прызначыць D-Pad.", + "ignoreCompletelyDescriptionText": "(Прасачыце, каб гэты кантролер не ўплываў на гульню ці меню)", + "ignoreCompletelyText": "Ігнараваць Цалкам", + "ignoredButton1Text": "Непатрэбная Кнопка 1", + "ignoredButton2Text": "Непатрэбная Кнопка 2", + "ignoredButton3Text": "Непатрэбная Кнопка 3", + "ignoredButton4Text": "Ігнаруецца Кнопка 4", + "ignoredButtonDescriptionText": "(карыстайцеся гэтым, каб не дазволіць кнопкам 'home' ці 'sync' удзейнічаць на гульню)", + "pressAnyAnalogTriggerText": "Націсніце на любы аналагавы трыгер...", + "pressAnyButtonOrDpadText": "Націсніце любую кнопку ці D-Pad...", + "pressAnyButtonText": "Націсніце любую кнопку...", + "pressLeftRightText": "Націсніце Ўправа ці Ўлева...", + "pressUpDownText": "Націсніце Ўверх ці Ўніз...", + "runButton1Text": "Кнопка для Бегу 1", + "runButton2Text": "Кнопка для Бегу 2", + "runTrigger1Text": "Трыгер для Бегу 1", + "runTrigger2Text": "Трыгер для Бегу 2", + "runTriggerDescriptionText": "(аналагавыя трыгеры дазволяць бегаць з рознымі хуткасцямі)", + "secondHalfText": "Выкарыстоўвайце гэта для наладжвання\n2-ой часткі двайнога кантролера, які\nпадаецца, як адзін кантролер.", + "secondaryEnableText": "Уключыць", + "secondaryText": "Другі Кантролер", + "startButtonActivatesDefaultDescriptionText": "(выключыце гэта, калі ваша кнопка \"старт\" больш падобна на \"меню\")", + "startButtonActivatesDefaultText": "Кнопка Старт Актывізуе Стандартны Віджэт", + "titleText": "Налады Кантролера", + "twoInOneSetupText": "Налады Двайнога Кантролера", + "uiOnlyDescriptionText": "( прадухіліць гэты кантролер ад далучаючыся гульню )", + "uiOnlyText": "Ліміт на выкарыстання меню", + "unassignedButtonsRunText": "Усе Неразмеркаваныя Кнопкі - для Бегу", + "unsetText": "<не ўсталявана>", + "vrReorientButtonText": "Кнопка рэарыентавання ВР" + }, + "configKeyboardWindow": { + "configuringText": "Наладжванне ${DEVICE}", + "keyboard2NoteText": "Амаль усе клавіятуры могуць перадаць толькі некалькі \nнаціскаў; таму будзе лепш, калі гульцы будуць мець \nкожны сваю клавіятуру. Але звярніце ўвагу на тое, што\nўсё роўна гульцы павінны будуць карыстацца рознымі \nкнопкамі для кіравання персанажам." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Памеры Кнопак Дзеянняў", + "actionsText": "Дзеянні", + "buttonsText": "Кнопкі", + "dragControlsText": "< каб перанесці элементы кіравання, перацягніце іх >", + "joystickText": "Джойсцік", + "movementControlScaleText": "Памеры Кнопак Руху", + "movementText": "Рух", + "resetText": "Скінуць", + "swipeControlsHiddenText": "Схаваць Іконкі Змахвання", + "swipeInfoText": "Да кантролераў, працуючых са змахваннямі, неабходна \nпрывыкнуць, але з імі будзе лягчэй гуляць.", + "swipeText": "змахванне", + "titleText": "Налады Экрана" + }, + "configureItNowText": "Наладзіць гэта зараз?", + "configureText": "Налады", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Для лепшых вынікаў вам спатрэбіцца добрая WiFi сетка. Вы можаце\nпалепшыць хуткасць WiFi, калі выключыце вашыя іншыя WiFi прылады,\nбудзеце гуляць каля WiFi-роўтэра ці калі вы падлучыцеся непасрэдна\nда інтэрнэт-сеткі.", + "explanationText": "Для ўжывання смартфона ці планшэта ў якасці кантролера\nўсталюйце прыкладанне \"${REMOTE_APP_NAME}\". Любая колькасць прылад \nможа далучыцца да гульні ${APP_NAME} праз Wi-Fi бясплатна!", + "forAndroidText": "для Android:", + "forIOSText": "для iOS:", + "getItForText": "Атрымайце ${REMOTE_APP_NAME} для iOS у Apple App Store\nці для Android у Google Play Store ці Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Выкарыстоўванне Мабільных Прылад як Кантролераў" + }, + "continuePurchaseText": "Працягнуць за ${PRICE}?", + "continueText": "Далей", + "controlsText": "Кнопкі", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Гэта не адносіцца да абсалютных рэкордаў.", + "activenessInfoText": "Гэты множнік павышаецца калі вы гуляеце\nі паніжаецца калі вы не гуляеце.", + "activityText": "Актыўнасць", + "campaignText": "Кампанія", + "challengesInfoText": "Зарабляйце прызы для завяршэння міні-гульняў.\n\nПрызы і ўзроўні складанасці павялічваюцца\nкожны раз, калі спаборніцтва завяршаецца, і\nзмяншаюцца, калі заканчваецца ці абнуляецца час.", + "challengesText": "Спаборніцтвы", + "currentBestText": "Зараз лепшы", + "customText": "Іншае", + "entryFeeText": "Удзельніцтва", + "forfeitConfirmText": "Прапусціць гэтае спаборніцтва?", + "forfeitNotAllowedYetText": "Пакуль нельга скончыць гэтае спаборніцтва.", + "forfeitText": "Прапусціць", + "multipliersText": "Множнікі", + "nextChallengeText": "Наступнае Спаборніцтва", + "nextPlayText": "Наступная Гульня", + "ofTotalTimeText": "з ${TOTAL}", + "playNowText": "Гуляць Зараз", + "pointsText": "Ачкі", + "powerRankingFinishedSeasonUnrankedText": "(сезон скончан не ў лізе)", + "powerRankingNotInTopText": "(не ў ${NUMBER} лепшых)", + "powerRankingPointsEqualsText": "= ${NUMBER} ачкоў", + "powerRankingPointsMultText": "(x ${NUMBER} ачкоў)", + "powerRankingPointsText": "${NUMBER} ачкоў", + "powerRankingPointsToRankedText": "(${CURRENT} of ${REMAINING} ачкоў)", + "powerRankingText": "Узровень Гульца", + "prizesText": "Прызы", + "proMultInfoText": "Гульцы з версіяй ${PRO}\nатрымліваюць ${PERCENT}% множнік тут.", + "seeMoreText": "Больш...", + "skipWaitText": "Прапусціць Чаканне", + "timeRemainingText": "Засталося Часу", + "toRankedText": "Атрымана", + "totalText": "за ўсё", + "tournamentInfoText": "Спаборнічайце з іншымі \nгульцамі вашай лігі.\n\nКалі турнір заканчваецца, гульцы з\nлепшымі вынікамі атрымліваюць прызы.", + "welcome1Text": "Рады бачыць вас у лізе ${LEAGUE}. Вы можаце палепшыць\nваш узровень лігі, калі будзеце зарабляць рэйтынг,\nвыконваць дасягненні і атрымліваць трафеі.", + "welcome2Text": "Вы таксама можаце зарабляць білеты многімі з такіх жа\nзаняткаў. Білеты дазваляюць адкрываць новых персанажаў, \nмапы, міні-гульні, удзельнічаць у турнірах і іншае.", + "yourPowerRankingText": "Ваш Узровень:" + }, + "copyOfText": "Копія ${NAME}", + "copyText": "Копія", + "createEditPlayerText": "<Стварыць/Змяніць Гульца>", + "createText": "Стварыць", + "creditsWindow": { + "additionalAudioArtIdeasText": "Дадатковыя Саўндтрэкі, Малюнкі і Ідэі - ${NAME}", + "additionalMusicFromText": "Дадатковыя саўндтрэкі з ${NAME}", + "allMyFamilyText": "Усім маім сябрам і сям'і, якія дапамагалі мне тэсціраваць гульню", + "codingGraphicsAudioText": "Праграміраванне, Графіка і Аўдыя - ${NAME}", + "languageTranslationsText": "Пераклады на іншыя мовы:", + "legalText": "Юрыдычная інфармацыя:", + "publicDomainMusicViaText": "Агульнадаступная музыка праз ${NAME}", + "softwareBasedOnText": "Гэтае праграмнае забеспячэнне заснована на працы ${NAME}", + "songCreditText": "${TITLE} выконвае ${PERFORMER}\nКампазітар - ${COMPOSER}, Аранжыроўка - ${ARRANGER}, Выданне - ${PUBLISHER},\nПрадастаўлена - ${SOURCE}", + "soundAndMusicText": "Гук і Музыка:", + "soundsText": "Гукі (${SOURCE}):", + "specialThanksText": "Асаблівая Падзяка:", + "thanksEspeciallyToText": "Асобная падзяка - ${NAME}", + "titleText": "Падзякі ад ${APP_NAME}", + "whoeverInventedCoffeeText": "Тым, хто вынайшаў каву" + }, + "currentStandingText": "Вашае бягучае месца - #${RANK}", + "customizeText": "Наладзіць...", + "deathsTallyText": "${COUNT} смерцяў", + "deathsText": "Смерці", + "debugText": "Адладка", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Рэкамендуецца ўсталяваць найвышэйшы ўзровень графікі (гл. Налады -> Графіка -> Тэкстуры).", + "runCPUBenchmarkText": "Запусціць Тэст Прадукцыйнасці CPU", + "runGPUBenchmarkText": "Запусціць Тэст Прадукцыйнасці GPU", + "runMediaReloadBenchmarkText": "Запусціць Тэст Прадукцыйнасці Медыя", + "runStressTestText": "Запусціць тэст-нагрузку", + "stressTestPlayerCountText": "Колькасць Гульцоў", + "stressTestPlaylistDescriptionText": "Плэйліст Тэста-Нагрузкі", + "stressTestPlaylistNameText": "Імя Плэйліста", + "stressTestPlaylistTypeText": "Тып Плэйліста", + "stressTestRoundDurationText": "Працягласць раўнда", + "stressTestTitleText": "Тэст-Нагрузка", + "titleText": "Тэсты Прадукцыйнасці і Нагрузкі", + "totalReloadTimeText": "Час загрузкі медыя: ${TIME} (падрабязнасці ў лозе)" + }, + "defaultGameListNameText": "Стандартны ${PLAYMODE} Плэйліст", + "defaultNewGameListNameText": "Мой \"${PLAYMODE}\" Плэйліст", + "deleteText": "Выдаліць", + "demoText": "Дэманстрацыя", + "denyText": "Адхіліць", + "desktopResText": "Дазвол Экрана", + "difficultyEasyText": "Лёгка", + "difficultyHardOnlyText": "Толькі на Складаным Узроўні", + "difficultyHardText": "Цяжка", + "difficultyHardUnlockOnlyText": "Гэты ўзровень можа быць адкрыт толькі на складаным\nузроўні. Вы гэтага не зрабілі!", + "directBrowserToURLText": "Калі ласка, накіруйце вэб-браўзер па наступным адрасе:", + "disableRemoteAppConnectionsText": "Адключыць злучэнні з аддаленым дадаткам", + "disableXInputDescriptionText": "Дазваляе больш за 4 кантролераў, але можа таксама не працаваць.", + "disableXInputText": "Адключыць XInput", + "doneText": "Зроблена", + "drawText": "Нічыя", + "duplicateText": "Дублікат", + "editGameListWindow": { + "addGameText": "Дадаць\nГульню", + "cantOverwriteDefaultText": "Нельга перазапісаць стандартны плэйліст!", + "cantSaveAlreadyExistsText": "Плэйліст з такім імем ужо існуе!", + "cantSaveEmptyListText": "Нельга захаваць пусты плэйліст!", + "editGameText": "Змяніць\nГульню", + "listNameText": "Назва плэйліста", + "nameText": "Назва", + "removeGameText": "Выдаліць\nГульню", + "saveText": "Захаваць Спіс", + "titleText": "Рэдактар плэйліста" + }, + "editProfileWindow": { + "accountProfileInfoText": "Гэта профіль, які заснаваны\nна вашым акаўнце.\n\n${ICONS}\n\nСтварайце іншыя профілі, калі вы жадаеце \nкарыстацца рознымі імёнамі і аватарамі.", + "accountProfileText": "(профіль акаўнта)", + "availableText": "Імя \"${NAME}\" даступна.", + "changesNotAffectText": "Увага: змены не паўплываюць на профілі, якія ўжо ў гульні", + "characterText": "персанаж", + "checkingAvailabilityText": "Праверка даступнасці \"${NAME}\"...", + "colorText": "колер", + "getMoreCharactersText": "Атрымаць больш герояў...", + "getMoreIconsText": "Атрымаць больш аватараў...", + "globalProfileInfoText": "Кожны глабальны профіль мае асабістае імя.\nЁн таксама ўтрымлівае свой аватар.", + "globalProfileText": "(глабальны профіль)", + "highlightText": "адценне", + "iconText": "аватар", + "localProfileInfoText": "Лакальныя профілі не маюць аватараў, а іх імёны не абавязкова\nўнікальныя. Палепшыце профіль да глабальнага, каб\nзахаваць сваё імя і выбраць аватар.", + "localProfileText": "(лакальны профіль)", + "nameDescriptionText": "Імя Гульца", + "nameText": "Імя", + "randomText": "выпадкова", + "titleEditText": "Рэдагаваць Профіль", + "titleNewText": "Новы Профіль", + "unavailableText": "Імя \"${NAME}\" недаступна; паспрабуйце іншае.", + "upgradeProfileInfoText": "Гэта захавае вашае імя гульца і дазволіць\nвыбраць аватар для профіля.", + "upgradeToGlobalProfileText": "Палепшыць да Глабальнага Профіля" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Вы не можаце выдаліць стандартны саўндтрэк.", + "cantEditDefaultText": "Нельга змяніць стандартны саўндтрэк. Прадублюйце яго ці стварыце новы.", + "cantOverwriteDefaultText": "Нельга перазапісаць стандартны саўндтрэк.", + "cantSaveAlreadyExistsText": "Саўндтрэк з такім імем ужо існуе!", + "defaultGameMusicText": "<стандартная музыка гульні>", + "defaultSoundtrackNameText": "Стандартны Саўндтрэк", + "deleteConfirmText": "Выдаліць Саўндтрэк:\n\n'${NAME}'?", + "deleteText": "Выдаліць\nСаўндтрэк", + "duplicateText": "Прадубляваць\nСаўндтрэк", + "editSoundtrackText": "Рэдактар Саўндтрэкаў", + "editText": "Рэдагаваць\nСаўндтрэк", + "fetchingITunesText": "Атрымліванне iTunes плэйлістаў...", + "musicVolumeZeroWarning": "Увага: гучнасць музыкі ўсталявана на 0", + "nameText": "Імя", + "newSoundtrackNameText": "Мой Саўндтрэк ${COUNT}", + "newSoundtrackText": "Новы Саўндтрэк:", + "newText": "Новы\nСаўндтрэк", + "selectAPlaylistText": "Выберыце Плэйліст", + "selectASourceText": "Крыніца Музыкі", + "testText": "тэст", + "titleText": "Саўндтрэкі", + "useDefaultGameMusicText": "Стандартная Музыка Гульні", + "useITunesPlaylistText": "Плэйліст iTunes", + "useMusicFileText": "Музычны Файл (mp3 і г.д.)", + "useMusicFolderText": "Тэчка з Музыкай" + }, + "editText": "Рэдагаваць", + "endText": "Канец", + "enjoyText": "Поспехаў!", + "epicDescriptionFilterText": "${DESCRIPTION} у эпічным рэжыме.", + "epicNameFilterText": "${NAME} у Эпічным Рэжыме", + "errorAccessDeniedText": "доступ забаронены", + "errorOutOfDiskSpaceText": "не хапае месца на дыске", + "errorText": "Памылка", + "errorUnknownText": "Невядомая памылка", + "exitGameText": "Зачыніць ${APP_NAME}?", + "exportSuccessText": "'${NAME}' экспартуецца.", + "externalStorageText": "Знешняя памяць", + "failText": "Правал", + "fatalErrorText": "Ой; штосьці зламалася.\nКалі ласка, пераўсталюйце гульню ці\nнапішыце на ${EMAIL} для дапамогі.", + "fileSelectorWindow": { + "titleFileFolderText": "Выберыце Файл ці Тэчку", + "titleFileText": "Выберыце Файл", + "titleFolderText": "Выберыце Тэчку", + "useThisFolderButtonText": "Карыстацца Гэтай Тэчкай" + }, + "filterText": "Фільтр", + "finalScoreText": "Канчатковы Вынік", + "finalScoresText": "Канчатковыя Вынікі", + "finalTimeText": "Канчатковы Час", + "finishingInstallText": "Канец усталёўкі... адзін момант...", + "fireTVRemoteWarningText": "* Для больш зручнай гульні карыстайцеся\nстандартнымі кантролерамі, ці ўсталюйце \nпрыкладанне '${REMOTE_APP_NAME}'\nна ваш тэлефон ці планшэт.", + "firstToFinalText": "Фінал да ${COUNT} Ачкоў", + "firstToSeriesText": "Серыя да ${COUNT} Ачкоў", + "fiveKillText": "ПЯЦЬ ЗАБОЙСТВ!!!", + "flawlessWaveText": "Бездакорная хваля!", + "fourKillText": "ЧАТЫРЫ ЗАБОЙСТВЫ!!!", + "friendScoresUnavailableText": "Вынікі сяброў недаступныя.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Лідэры ${COUNT} Гульні", + "gameListWindow": { + "cantDeleteDefaultText": "Вы не можаце выдаліць стандартны плэйліст.", + "cantEditDefaultText": "Нельга рэдагаваць стандартны плэйліст! Прадублюйце яго ці стварыце новы.", + "cantShareDefaultText": "Вы не можаце падзяліцца спісам прайгравання па змаўчанні.", + "deleteConfirmText": "Выдаліць \"${LIST}\"?", + "deleteText": "Выдаліць\nПлэйліст", + "duplicateText": "Прадубляваць\nПлэйліст", + "editText": "Рэдагаваць\nПлэйліст", + "newText": "Новы\nПлэйліст", + "showTutorialText": "Паказаць Туторыял", + "shuffleGameOrderText": "Выпадковы Парадак Гульняў", + "titleText": "Наладзіць ${TYPE} Плэйлісты" + }, + "gameSettingsWindow": { + "addGameText": "Дадаць Гульню" + }, + "gamesToText": "${WINCOUNT} гульняў супраць ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Кожная прылада ў лоббі можа мець больш за \nаднаго гульца, калі ў вас дастаткова кантролераў.", + "aboutDescriptionText": "Выкарыстоўвайце гэтыя раздзелы, каб стварыць лоббі.\n\nЛоббі дазваляюць вам праходзіць гульні і турніры\nз вашымі сябрамі, з некалькіх прылад адначасова.\n\nВыкарыстоўвайце кнопку ${PARTY}, каб зайсці ў чат\nі размаўляць з сябрамі (або націсніце кнопку \n${BUTTON} у меню кантролера)", + "aboutText": "Аб функцыі", + "addressFetchErrorText": "<памылка пры атрымліванні адрасоў>", + "appInviteInfoText": "Запрасіце сяброў у гульню, і яны атрымаюць\n${COUNT} бясплатных квіткоў. Вы таксама атрымаеце\n${YOU_COUNT} за кожнага сябра.", + "appInviteMessageText": "${NAME} даслаў вам ${COUNT} квіткоў у ${APP_NAME}", + "appInviteSendACodeText": "Даслаць Код", + "appInviteTitleText": "Запрашэнне ў ${APP_NAME}", + "bluetoothAndroidSupportText": "(працуе з любой Android-прыладай, якая падтрымлівае Bluetooth)", + "bluetoothDescriptionText": "Стварыць/далучыцца да гульні праз Bluetooth:", + "bluetoothHostText": "Стварыць", + "bluetoothJoinText": "Далучыцца", + "bluetoothText": "Bluetooth", + "checkingText": "праверка...", + "copyCodeConfirmText": "Код скапіяваны ў буфер абмену", + "copyCodeText": "Скапіяваць код", + "dedicatedServerInfoText": "Для дасягнення найлепшых вынікаў наладзьце спецыяльны сервер. Гл. Bombsquadgame.com/server, каб даведацца, як.", + "disconnectClientsText": "Гэта адлучыць ${COUNT} гульцоў з вашага\nлоббі. Вы ўпэўнены?", + "earnTicketsForRecommendingAmountText": "Сябры атрымаюць ${COUNT} квіткоў, калі яны паспрабуюць гульню\n(вы таксама атрымаеце ${YOU_COUNT} квіткоў за кожнага сябра)", + "earnTicketsForRecommendingText": "Падзяліцеся гульнёй, \nкаб атрымаць квіткі.", + "emailItText": "Паслаць", + "favoritesSaveText": "Захаваць як абранае", + "favoritesText": "Абранае", + "freeCloudServerAvailableMinutesText": "Наступны бясплатны воблачны сервер будзе абноўлены праз ${MINUTES} мінут", + "freeCloudServerAvailableNowText": "Бясплатны воблачны сервер абнавіўся!", + "freeCloudServerNotAvailableText": "Бясплатных воблачных сервераў няма.", + "friendHasSentPromoCodeText": "${COUNT} квіткоў ${APP_NAME} ад ${NAME}", + "friendPromoCodeAwardText": "Вы атрымаеце ${COUNT} квіткоў кожны раз, калі ён будзе выкарыстаны.", + "friendPromoCodeExpireText": "Код дзейнічае ${EXPIRE_HOURS} гадзін(ы) і працуе толькі для новых гульцоў.", + "friendPromoCodeInfoText": "Ён можа быць абменены на ${COUNT} квіткоў.\n\nЗайдзіце ў \"Налады->Дадатковыя->Увесці прома-код\", каб скарыстацца ім.\nНаведайце bombsquadgame.com, каб зладаваць гульню на любую платформу, якая падтрымліваецца.\nГэты код мінае праз ${EXPIRE_HOURS} гадзін(ы)(а) і ён дзейнічае толькі для новых гульцоў.", + "friendPromoCodeInstructionsText": "Каб выкарыстоўваць яго, адкрыйце ${APP_NAME} і перайдзіце ў раздзел \"Налады-> Дадатковыя-> Увесці код\".\nГлядзіце bombsquadgame.com для спасылкі на загрузку ўсіх падтрымліваемых платформаў.", + "friendPromoCodeRedeemLongText": "Ён можа быць абменены на ${COUNT} квіткоў максімум ${MAX_USES} гульцамі.", + "friendPromoCodeRedeemShortText": "Ён можа быць абменены на ${COUNT} квіткоў у гульні.", + "friendPromoCodeWhereToEnterText": "(у раздзеле \"Налады->Дадатковыя->Увядзіце код\")", + "getFriendInviteCodeText": "Атрымаць Код для Сяброў", + "googlePlayDescriptionText": "Запрасіце гульцоў з Google Play у вашае лоббі.", + "googlePlayInviteText": "Запрасіць", + "googlePlayReInviteText": "У вашым лоббі знаходзяцца ${COUNT} гульцоў з Google Play,\nякія будуць адключаны, калі вы створыце новае лоббі.\nУключыце іх у вашае запрашэнне, каб вярнуць іх назад.", + "googlePlaySeeInvitesText": "Паглядець запрашэнні", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / версія Google Play)", + "hostPublicPartyDescriptionText": "Прымае грамадскую вечарыну", + "hostingUnavailableText": "Хостынг недаступны", + "inDevelopmentWarningText": "Увага:\n\nГульня па сетцы - новая функцыя, якая зараз \nразвіваецца. На сённяшні дзень рэкамендуецца, \nкаб усе гульцы знаходзіліся ў адной WiFi сетцы.", + "internetText": "Інтэрнэт", + "inviteAFriendText": "У сяброў няма гульні? Запрасіце іх паспрабаваць,\nі яны атрымаюць ${COUNT} дадатковых квіткоў.", + "inviteFriendsText": "Запрасіць Сяброў", + "joinPublicPartyDescriptionText": "Далучайцеся да грамадскай вечарыны", + "localNetworkDescriptionText": "Далучайцеся да вечарыны побач (LAN, Bluetooth і г.д.)", + "localNetworkText": "Лакальная сетка", + "makePartyPrivateText": "Зрабіць Маё Лоббі Прыватным", + "makePartyPublicText": "Зрабіце маю партыю публічнай", + "manualAddressText": "Адрас", + "manualConnectText": "Далучыцца", + "manualDescriptionText": "Далучыцеся да лоббі па адрасе:", + "manualJoinSectionText": "Далучыцца по адрасу", + "manualJoinableFromInternetText": "Да вас можна далучыцца праз інтэрнэт?:", + "manualJoinableNoWithAsteriskText": "Не*", + "manualJoinableYesText": "Так", + "manualRouterForwardingText": "*каб выправіць гэта, паспрабуйце накіраваць ваш UDP-порт ${PORT} для вашага лакальнага адрасу", + "manualText": "Ручны", + "manualYourAddressFromInternetText": "Ваш адрас з інтэрнэту:", + "manualYourLocalAddressText": "Ваш лакальны адрас:", + "nearbyText": "Побач", + "noConnectionText": "<няма злучэння>", + "otherVersionsText": "(іншыя версіі)", + "partyCodeText": "Код вечарыны", + "partyInviteAcceptText": "Згадзіцца", + "partyInviteDeclineText": "Адмовіцца", + "partyInviteGooglePlayExtraText": "(зайдзіце ў укладку \"Google Play\" у раздзеле \"Сабраць\")", + "partyInviteIgnoreText": "Ігнараваць", + "partyInviteText": "${NAME} запрасіў\nвас у сваё лоббі!", + "partyNameText": "Назва Лоббі", + "partyServerRunningText": "Ваш сервер працуе", + "partySizeText": "Размер Лоббі", + "partyStatusCheckingText": "Правяраем статус...", + "partyStatusJoinableText": "Зараз твае Лоббі дасягаемае праз інтэрнэт", + "partyStatusNoConnectionText": "Не зпалучаецца дасягнуцца да серверу", + "partyStatusNotJoinableText": "Твае Лоббі не дасягаемае праз інтэрнэт", + "partyStatusNotPublicText": "Твае Лоббі не публічнае", + "pingText": "Пінг", + "portText": "Порт", + "privatePartyCloudDescriptionText": "Прыватныя вечарыны працуюць на выдзеленых воблачных серверах; канфігурацыя маршрутызатара не патрабуецца.", + "privatePartyHostText": "Арганізаваць прыватную вечарыну", + "privatePartyJoinText": "Далучыцца да прыватнай вечарыны", + "privateText": "Прыватны", + "publicHostRouterConfigText": "Для гэтага можа спатрэбіцца наладка перанакіравання порта на вашым маршрутызатары. Для больш простага варыянту арганізаваць прыватную вечарыну.", + "publicText": "Публічны", + "requestingAPromoCodeText": "Запыт кода...", + "sendDirectInvitesText": "Даслаць Запрашэнні", + "sendThisToAFriendText": "Адпраўце гэты код вашаму сябру:", + "shareThisCodeWithFriendsText": "Падзяліцца кодам з сябрамі:", + "showMyAddressText": "Паказаць мой адрас", + "startHostingPaidText": "Арганізаваць зараз за ${COST}", + "startHostingText": "Арганізаваць", + "startStopHostingMinutesText": "Вы можаце пачаць і спыніць хостынг бясплатна на працягу наступных ${MINUTES} мінут.", + "stopHostingText": "Спыніць хостынг", + "titleText": "Сабраць", + "wifiDirectDescriptionBottomText": "Калі ўсе прылады падтрымліваюць 'Wi-Fi Direct', яны могуць карыстацца ім, каб падключыцца\nадзін да другога. Калі ўсе прылады падключаны, вы можаце ствараць лоббі, карыстаючыся\nўкладкай \"Лакальная сетка\" так жа, як і з звычайнай WiFi сеткай.\n\nДля лепшых вынікаў хост Wi-Fi Direct павінен таксама быць хостам гульні ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct можа выкарыстоўвацца для злучэння Android прылад непасрэдна,\nбез WiFi сеткі. Гэта працуе лепш на Android 4.2 ці навей.\n\nКаб cкарыстацца гэтым, адчыніце налады і знайдзіце 'Wi-Fi Direct'.", + "wifiDirectOpenWiFiSettingsText": "Адкрыць налады WiFi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(працуе паміж усімі платформамі)", + "worksWithGooglePlayDevicesText": "(працуе з прыладамі, на якіх усталявана android-версія гульні)", + "youHaveBeenSentAPromoCodeText": "Вам адправілі прома-код ${APP_NAME}:" + }, + "getTicketsWindow": { + "freeText": "БЯСПЛАТНА!", + "freeTicketsText": "Бясплатныя Квіткі", + "inProgressText": "Транзакцыя выконваецца; калі ласка пачакайце хвіліну.", + "purchasesRestoredText": "Пакупкі адноўлены.", + "receivedTicketsText": "Атрымана ${COUNT} квіткоў!", + "restorePurchasesText": "Аднавіць пакупкі", + "ticketDoublerText": "Падваіцель Квіткоў", + "ticketPack1Text": "Малы Пакет Квіткоў", + "ticketPack2Text": "Сярэдні Пакет Квіткоў", + "ticketPack3Text": "Вялікі Пакет Квіткоў", + "ticketPack4Text": "Вельмі Вялікі Пакет Квіткоў", + "ticketPack5Text": "Гіганцкі Пакет Квіткоў", + "ticketPack6Text": "Максімальны Пакет Квіткоў", + "ticketsFromASponsorText": "Атрымаць ${COUNT} квіткоў\nад спонсара", + "ticketsText": "${COUNT} Квіткоў", + "titleText": "Атрымаць Квіткі", + "unavailableLinkAccountText": "Прабачце, пакупкі недаступныя на гэтай платформе.\nВы можаце злучыць гэты акаўнт з іншым акаўнтам на\nіншайплатформе і рабіць пакупкі на ім.", + "unavailableTemporarilyText": "Недаступна; калі ласка, паспрабуйце пазней.", + "unavailableText": "Прабачце, гэта недаступна.", + "versionTooOldText": "Прабачце, ваша версія гульні занадта старая; абнавіце яе.", + "youHaveShortText": "вы маеце ${COUNT}", + "youHaveText": "вы маеце ${COUNT} квіткоў" + }, + "googleMultiplayerDiscontinuedText": "Прабачце, мультігульны сервіс Гугл не даступны у гэты час.\nЯ клапачуся над гэтым з усёй скорасцю.\n\nДа таго часу, калі ласка паспрабуйце другое падключэнне", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Заўсёды", + "fullScreenCmdText": "Поўнаэкранны (Сmd-F)", + "fullScreenCtrlText": "Поўнаэкранны (Ctrl-F)", + "gammaText": "Гама", + "highText": "Высокае", + "higherText": "Найвышэйшае", + "lowText": "Нізкае", + "mediumText": "Сярэдняе", + "neverText": "Ніколі", + "resolutionText": "Дазвол", + "showFPSText": "Паказваць FPS", + "texturesText": "Тэкстуры", + "titleText": "Графіка", + "tvBorderText": "TV мяжа", + "verticalSyncText": "Вертыкальная Сінхранізацыя", + "visualsText": "Эфекты" + }, + "helpWindow": { + "bombInfoText": "- Бомба - \nМацней за ўдары, але можа нанесці\nшкоду і вам самім. Для лепшых\nвынікаў кідайце ў ворага, пакуль\nне згарэў кнот.", + "canHelpText": "${APP_NAME} можа дапамагчы.", + "controllersInfoText": "Вы можаце гуляць у ${APP_NAME} з сябрамі праз сетку або, калі\nвы маеце дастаткова кантролераў, на адной прыладзе.\n${APP_NAME} падтрымлівае мноства кантролераў - нават тэлефон \n(для гэтага спатрэбіцца прыкладанне '${REMOTE_APP_NAME}').\nГл. Налады -> Кантролеры для атрымання дадатковай інфармацыі.", + "controllersInfoTextRemoteOnly": "Вы можаце гуляць у ${APP_NAME} з сябраміпа сетцы,альбо вы\nможаце гуляць на адной прыладзе,выкарыстоўваючы тэлефоны ў якасц\nантролераў з дапамогай бясплатнай праграмы '${REMOTE_APP_NAME}'.", + "controllersText": "Кантролеры", + "controlsSubtitleText": "Ваш персанаж ${APP_NAME} валодае некалькімі базавымі прыёмамі:", + "controlsText": "Прыёмы", + "devicesInfoText": "Вы можаце гуляць гуляць у ${APP_NAME} па сетцы, таму\nдаставайце вашыя дадатковыя тэлефоны, планшэты, камп'ютары і\nгуляйце на ніх. Можна нават падключаць звычайную версію гульні\nда VR версіі, каб дазволіць іншым людзям назіраць за\nпадзеямі ў гульні.", + "devicesText": "Прылады", + "friendsGoodText": "Вельмі добра іх мець. У ${APP_NAME} весялей гуляць з некалькімі\nгульцамі, ён падтрымлівае да 8 гульцоў адначасова.", + "friendsText": "Сябры", + "jumpInfoText": "- Прыгаць -\nПрыгайце, каб пераадольваць\nперашкоды, кідаць рэчы вышэй\nці проста павесяліцца.", + "orPunchingSomethingText": "Ці ўдарыць, скінуць з абрыва і падарваць бомбай-ліпучкай па дарозе ўніз.", + "pickUpInfoText": "- Падняць -\nХапайце сцягі, ворагаў ці штосьці\nіншае, што не прыкручана да зямлі.\nНажміце яшчэ раз, каб кінуць.", + "powerupBombDescriptionText": "Дазваляе вам кінуць тры бомбы\nза адзін раз замест адной.", + "powerupBombNameText": "Патрайняльнік Бомб", + "powerupCurseDescriptionText": "Вы, напэўна, хаціце пазбегнуць гэтага.\n ...ці не?", + "powerupCurseNameText": "Смерць", + "powerupHealthDescriptionText": "Ніколі не здагадайцеся.\nВяртае поўнае здароўе.", + "powerupHealthNameText": "Аптэчка", + "powerupIceBombsDescriptionText": "Слабейшая за іншыя бомбы,\nале замарожвае вашых ворагаў\nі наносіць няшмат страт.", + "powerupIceBombsNameText": "Лядовая Бомба", + "powerupImpactBombsDescriptionText": "Нямнога слабейшая за звычайную,\nале падрываецца пры ўдары.", + "powerupImpactBombsNameText": "Ударная Бомба", + "powerupLandMinesDescriptionText": "Выдаюцца па 3 штукі.\nКарысныя для абароны базы\nці спынення хуткіх ворагаў.", + "powerupLandMinesNameText": "Міны", + "powerupPunchDescriptionText": "Робяць вашыя ўдары мацней,\nхутчэй, і ўвогуле лепш.", + "powerupPunchNameText": "Баксёрскія Пальчаткі", + "powerupShieldDescriptionText": "Бяруць усе страты на сябе,\nтаму вы застаецеся здаровымі.", + "powerupShieldNameText": "Энэргетычны Шчыт", + "powerupStickyBombsDescriptionText": "Прыліпае да ўсяго, да чаго \nдакранецца. І пачынаецца...", + "powerupStickyBombsNameText": "Бомба-Ліпучка", + "powerupsSubtitleText": "Канечне, ніякая гульня немагчыма без узмацняльнікаў:", + "powerupsText": "Узмацняльнікі", + "punchInfoText": "- Удар -\nУдары наносяць тым больш страт,\nчем хутчэй вы рухаецеся і \nкруціцеся як вар'ят.", + "runInfoText": "- Бяжаць -\nНацісніце ЛЮБУЮ кнопку, каб бяжаць. Трыгеры ці плечавыя кнопкі падыходзяць для гэтага.\nБег дапамагае рухацца хутчэй, але манёўры становяцца больш складанымі.", + "someDaysText": "Часам вам проста хочацца нешта ўдарыць. Ці падарваць.", + "titleText": "Дапамога па ${APP_NAME}", + "toGetTheMostText": "Каб атрымаць максімум ад гэтай гульні, вам спатрэбяцца:", + "welcomeText": "Прывітанне ў ${APP_NAME}!" + }, + "holdAnyButtonText": "<націсніце любую кнопку>", + "holdAnyKeyText": "<націсніце любую кнопку>", + "hostIsNavigatingMenusText": "- ${HOST} знаходзіцца ў меню навігацыі -", + "importPlaylistCodeInstructionsText": "Выкарыстоўвайце наступны код, каб імпартаваць гэты спіс прайгравання ў іншае месца:", + "importPlaylistSuccessText": "Імпартыраван ${TYPE} плэйліст '${NAME}'", + "importText": "імпарт", + "importingText": "Імпартырую...", + "inGameClippedNameText": "У гульне будзе\n\"${NAME}\"", + "installDiskSpaceErrorText": "ПАМЫЛКА: Немагчыма закончыць усталёўку.\nХутчэй за ўсё, у вас на прыладзе закончылася \nмесца. Вызваліце нямнога і паспрабуйце яшчэ раз.", + "internal": { + "arrowsToExitListText": "націсніце ${LEFT} ці ${RIGHT}, каб закрыць спіс", + "buttonText": "кнопка", + "cantKickHostError": "Вы ня можаце выкінуць хост.", + "chatBlockedText": "${NAME} заглушаны на ${TIME} сякунд.", + "connectedToGameText": "падключэнне да '${NAME}'", + "connectedToPartyText": "Далучыўся да лоббі ${NAME}!", + "connectingToPartyText": "Падключэнне...", + "connectionFailedHostAlreadyInPartyText": "Падключэнне не ўдалося; хост у іншым лоббі.", + "connectionFailedPartyFullText": "Не атрымалася далучыцца; пакой заплонен.", + "connectionFailedText": "Падключэнне не ўдалося.", + "connectionFailedVersionMismatchText": "Далучэнне немагчыма; хост карыстаецца іншай версіяй гульні.\nПеракагайцеся, што вы абодва абноўлены і паспрабуйце яшчэ раз.", + "connectionRejectedText": "Далучэнне адхілена.", + "controllerConnectedText": "${CONTROLLER} падключаны.", + "controllerDetectedText": "Знойдзены кантролер.", + "controllerDisconnectedText": "${CONTROLLER} адключаны.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} адключаны. Калі ласка, паспрабуйце яшчэ раз.", + "controllerForMenusOnlyText": "Гэты кантролер не можа быць выкарыстаны , каб гуляць ; толькі для навігацыі па меню.", + "controllerReconnectedText": "${CONTROLLER} перападключаны.", + "controllersConnectedText": "Падключана ${COUNT} кантролера(ў).", + "controllersDetectedText": "Знойдзена ${COUNT} кантролера(ў).", + "controllersDisconnectedText": "Адключана ${COUNT} кантролер(а)(аў).", + "corruptFileText": "Знойдзены пашкоджаныя файлы. Паспрабуйце пераўсталяваць ці звярніцеся на ${EMAIL}.", + "errorPlayingMusicText": "Памылка прайгравання музыкі: ${MUSIC}", + "errorResettingAchievementsText": "Немагчыма скінуць online-вынікі; паспрабуйце пазней.", + "hasMenuControlText": "${NAME} зараз кіруе ў меню.", + "incompatibleNewerVersionHostText": "Хост запушчаны на больш новай версіі гульні.\nАбнавіце гульню да апошняй версіі і паспрабуйце яшчэ раз.", + "incompatibleVersionHostText": "Хост працуе з іншай версіяй гульні. Пераканайцеся,\nшто вы абодва абноўлены і паспрабуйце яшчэ раз.", + "incompatibleVersionPlayerText": "${NAME} працуе з іншай версіяй гульні. Пераканайцеся,\nшто вы абодва абноўлены і паспрабуйце яшчэ раз.", + "invalidAddressErrorText": "Памылка: няправільны адрас.", + "invalidNameErrorText": "Памылка: няправільнае імя.", + "invalidPortErrorText": "Памылка: няправільны порт", + "invitationSentText": "Запрашэнне адпраўлена.", + "invitationsSentText": "${COUNT} запрашэння(ў) адпраўлена.", + "joinedPartyInstructionsText": "Хто-та далучыўся да вашага лоббі.\nЗайдзіце ў \"Гуляць\", каб пачаць гульню.", + "keyboardText": "Клавіятура", + "kickIdlePlayersKickedText": "${NAME} выкінуты за прастой.", + "kickIdlePlayersWarning1Text": "${NAME} будзе выкінуты праз ${COUNT} секунд з-за прастою.", + "kickIdlePlayersWarning2Text": "(вы можаце выключыць гэта ў Налады -> Дадатковыя)", + "leftGameText": "'${NAME}' выйшаў.", + "leftPartyText": "Выйшаў з лоббі ${NAME}.", + "noMusicFilesInFolderText": "У тэчцы няма ніводнага музычнага файла.", + "playerJoinedPartyText": "${NAME} далучыўся да лоббі!", + "playerLeftPartyText": "${NAME} выйшаў з лоббі.", + "rejectingInviteAlreadyInPartyText": "Запрашэнне адхілена (ужо ў лоббі).", + "serverRestartingText": "Сервер перазапускаецца. Калі ласка, зноў далучыцеся ...", + "serverShuttingDownText": "Сервер выключаецца ...", + "signInErrorText": "Памылка пры ўваходзе.", + "signInNoConnectionText": "Немагчыма ўвайсці (няма інтэрнэт-злучэння?)", + "telnetAccessDeniedText": "ПАМЫЛКА: карыстальнік не даў доступ Telnet.", + "timeOutText": "(засталося ${TIME} секунд(ы))", + "touchScreenJoinWarningText": "Вы зайшлі з сэнсарным экранам.\nКалі гэта была памылка, націсніце 'Меню -> Пакінуць Гульню'.", + "touchScreenText": "Сэнсарны Экран", + "unableToResolveHostText": "Памылка: немагчыма знайсцi хост.", + "unavailableNoConnectionText": "Зараз гэта недаступна (няма інтэрнэт-злучэння?)", + "vrOrientationResetCardboardText": "Скарыстайцеся гэтым, каб скінуць VR арыентацыю.\nКаб гуляць, вам спатрэбіцца знешні кантролер.", + "vrOrientationResetText": "Скідванне арыентацыі VR.", + "willTimeOutText": "(час скончыцца пры прастоі)" + }, + "jumpBoldText": "ПРЫГАЙЦЕ!", + "jumpText": "Прыгайце", + "keepText": "Захаваць", + "keepTheseSettingsText": "Захаваць гэтыя налады?", + "keyboardChangeInstructionsText": "Двойчы націсніце прабел, каб змяніць клавіятуру.", + "keyboardNoOthersAvailableText": "Іншых клавіятур няма.", + "keyboardSwitchText": "Пераключэнне клавіятуры на \"${NAME}\".", + "kickOccurredText": "${NAME} быў выкiнут.", + "kickQuestionText": "Выгнаць ${NAME}?", + "kickText": "Выгнаць", + "kickVoteCantKickAdminsText": "Мадэратараў нельга выкiдываць.", + "kickVoteCantKickSelfText": "вы ня можаце выкінуць самога сябе.", + "kickVoteFailedNotEnoughVotersText": "Не хапае гульцоў для галасавання.", + "kickVoteFailedText": "Галасаванне не адбылося.", + "kickVoteStartedText": "Было пачата галасаванне супраць ${NAME}.", + "kickVoteText": "Галасаваць за штоб выгнаць", + "kickVotingDisabledText": "Галасавання адключаны.", + "kickWithChatText": "Тып ${YES} у чаце так і ${NO} для няма.", + "killsTallyText": "${COUNT} забойств", + "killsText": "Забойствы", + "kioskWindow": { + "easyText": "Лёгка", + "epicModeText": "Эпічны Рэжым", + "fullMenuText": "Поўнае Меню", + "hardText": "Цяжка", + "mediumText": "Сярэдне", + "singlePlayerExamplesText": "Адзін гулец / Кааператыўныя гульні", + "versusExamplesText": "Адзін супраць аднаго" + }, + "languageSetText": "Мова зараз: ${LANGUAGE}.", + "lapNumberText": "Круг ${CURRENT}/${TOTAL}", + "lastGamesText": "(апошнія ${COUNT} гульні(яў))", + "leaderboardsText": "Лідары", + "league": { + "allTimeText": "За ўвесь час", + "currentSeasonText": "Гэты сезон (${NUMBER})", + "leagueFullText": "${NAME} Ліга", + "leagueRankText": "Месца ў Лізе", + "leagueText": "Ліга", + "rankInLeagueText": "#${RANK}, ${NAME} Ліга${SUFFIX}", + "seasonEndedDaysAgoText": "Сезон скончыўся ${NUMBER} дзён таму.", + "seasonEndsDaysText": "Сезон скончыцца праз ${NUMBER} дзён.", + "seasonEndsHoursText": "Сезон скончыцца праз ${NUMBER} гадзін.", + "seasonEndsMinutesText": "Сезон скончыцца праз ${NUMBER} мінут.", + "seasonText": "Сезон ${NUMBER}", + "tournamentLeagueText": "Вы павінны дасягнуць ${NAME} лігі, каб увайсці ў гэты турнір.", + "trophyCountsResetText": "Трафейныя ачкі знікнуць у наступным сезоне." + }, + "levelBestScoresText": "Лепшыя вынікі на ўзроўні ${LEVEL}", + "levelBestTimesText": "Лепшы час на ўзроўні ${LEVEL}", + "levelFastestTimesText": "Самы хуткі на уроўні ${LEVEL}", + "levelHighestScoresText": "Найлепшыя вынікі на ўзроўні ${LEVEL}", + "levelIsLockedText": "${LEVEL} узровень недаступны.", + "levelMustBeCompletedFirstText": "${LEVEL} узровень павінен быць скончаны спачатку.", + "levelText": "Узровень ${NUMBER}", + "levelUnlockedText": "Узровень Адкрыт!", + "livesBonusText": "Бонус", + "loadingText": "Ладаванне...", + "loadingTryAgainText": "Загрузка; паспрабуйце яшчэ раз праз хвіліну ...", + "macControllerSubsystemBothText": "Абодва (не рэкамендуецца)", + "macControllerSubsystemClassicText": "класічны", + "macControllerSubsystemDescriptionText": "(паспрабуйце змяніць гэта, калі вашы кантролеры не працуюць)", + "macControllerSubsystemMFiNoteText": "Выяўлены кантролер, зроблены для iOS / Mac;\nВы можаце ўключыць іх у Наладах -> Кантролеры", + "macControllerSubsystemMFiText": "Зроблена для iOS / Mac", + "macControllerSubsystemTitleText": "Падтрымка кантролера", + "mainMenu": { + "creditsText": "Падзякі", + "demoMenuText": "Дэма-Меню", + "endGameText": "Скончыць Гульню", + "exitGameText": "Зачыніць Гульню", + "exitToMenuText": "Выйсці ў меню?", + "howToPlayText": "Як Гуляць", + "justPlayerText": "(Толькі ${NAME})", + "leaveGameText": "Пакінуць Гульню", + "leavePartyConfirmText": "Сапраўды пакінуць лоббі?", + "leavePartyText": "Пакінуць Лоббі", + "quitText": "Выйсці", + "resumeText": "Працягнуць", + "settingsText": "Налады" + }, + "makeItSoText": "Так", + "mapSelectGetMoreMapsText": "Атрымаць больш мапаў...", + "mapSelectText": "Выбраць...", + "mapSelectTitleText": "${GAME} Мапы", + "mapText": "Мапа", + "maxConnectionsText": "Максімальная колькасць падключэнняў.", + "maxPartySizeText": "Максімальны памер групы.", + "maxPlayersText": "Максімальная колькасць гульцоў.", + "modeArcadeText": "Аркадны рэжым.", + "modeClassicText": "Класічны рэжым.", + "modeDemoText": "Дэмо рэжым", + "mostValuablePlayerText": "Самы Карысны Гулец", + "mostViolatedPlayerText": "Самы Збіты Гулец", + "mostViolentPlayerText": "Самы Жорсткі Гулец", + "moveText": "Рухацца", + "multiKillText": "${COUNT}-ЗАБІТА!!!", + "multiPlayerCountText": "${COUNT} гульцоў", + "mustInviteFriendsText": "Вы можаце запрасіць сяброў у\nраздзеле \"${GATHER}\" ці прыкласці\nкантролеры, каб гуляць у мультыплэеры.", + "nameBetrayedText": "${NAME} здрадзіў ${VICTIM}.", + "nameDiedText": "${NAME} загінуў.", + "nameKilledText": "${NAME} забіў ${VICTIM}.", + "nameNotEmptyText": "Імя не можа быць пустым!", + "nameScoresText": "${NAME} вядзе!", + "nameSuicideKidFriendlyText": "${NAME} выпадкова загінуў.", + "nameSuicideText": "${NAME} скончыў жыццё самагубствам.", + "nameText": "Імя", + "nativeText": "Родны", + "newPersonalBestText": "Новы асабісты рэкорд!", + "newTestBuildAvailableText": "Новая тэставая зборка даступна! (${VERSION} build ${BUILD}).\nАтрымайце яе на ${ADDRESS}", + "newText": "Новы", + "newVersionAvailableText": "Новая версія ${APP_NAME} даступна! (${VERSION})", + "nextAchievementsText": "Наступныя дасягненні:", + "nextLevelText": "Наступны Ўзровень", + "noAchievementsRemainingText": "- не", + "noContinuesText": "(без працягу)", + "noExternalStorageErrorText": "Знешняя памяць не знойдзена", + "noGameCircleText": "Памылка: вы не ўвайшлі ў GameCircle", + "noProfilesErrorText": "У вас няма ніводнага профіля, таму вас будуць называць '${NAME}'.\nЗайдзіце ў \"Налады -> Профілі\", каб стварыць уласны профіль.", + "noScoresYetText": "Вынікаў пакуль няма.", + "noThanksText": "Не, дзякуй", + "noTournamentsInTestBuildText": "УВАГА: Ацэнкі турніраў з гэтай тэставай зборкі будуць ігнаравацца.", + "noValidMapsErrorText": "Не знойдзена мап для гэтага тыпу гульні.", + "notEnoughPlayersRemainingText": "Засталося вельмі мала гульцоў; пачніце новую гульню.", + "notEnoughPlayersText": "Вам патрэбна не менш за ${COUNT} гульцоў, каб пачаць!", + "notNowText": "Не Зараз", + "notSignedInErrorText": "Вы павінны ўвайсці, каб выканаць гэта.", + "notSignedInGooglePlayErrorText": "Вы павінны ўвайсці з Google Play, каб выканаць гэта.", + "notSignedInText": "не ўвайшлі", + "nothingIsSelectedErrorText": "Нічога не выбрана!", + "numberText": "№${NUMBER}", + "offText": "Выключана", + "okText": "Так", + "onText": "Уключана", + "oneMomentText": "Адну мінуту...", + "onslaughtRespawnText": "${PLAYER} з'явіцца ў ${WAVE} хвалі", + "orText": "${A} ці ${B}", + "otherText": "Іншае...", + "outOfText": "(#${RANK} з ${ALL})", + "ownFlagAtYourBaseWarning": "Каб зарабіць ачкі, ваш сцяг\nпавінен быць на вашай базе!", + "packageModsEnabledErrorText": "Гульня па сетцы не дазваляе выкарыстоўваць моды (глядзі \"Налады -> Дадатковыя\")", + "partyWindow": { + "chatMessageText": "Паведамленне ў Чат", + "emptyText": "Вашае лоббі пустое", + "hostText": "(хост)", + "sendText": "Адправіць", + "titleText": "Вашае Лоббі" + }, + "pausedByHostText": "(спынена хостам)", + "perfectWaveText": "Бездакорная Хваля!", + "pickUpText": "Падняць", + "playModes": { + "coopText": "Кааператыўны", + "freeForAllText": "Адзіночны", + "multiTeamText": "Мультыкамандны", + "singlePlayerCoopText": "Адзін Гулец / Група", + "teamsText": "Камандны" + }, + "playText": "Гуляць", + "playWindow": { + "oneToFourPlayersText": "1-4 гульца", + "titleText": "Гуляць", + "twoToEightPlayersText": "2-8 гульцоў" + }, + "playerCountAbbreviatedText": "${COUNT} гулец", + "playerDelayedJoinText": "${PLAYER} увойдзе ў пачатаку наступнага раўнда.", + "playerInfoText": "Інфармацыя аб Гульцы", + "playerLeftText": "${PLAYER} пакінуў гульню.", + "playerLimitReachedText": "Ліміт гульцоў (${COUNT}) дасягнуты; далучэнне немагчыма.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Вы не можаце выдаліць профіль вашага акаўнта.", + "deleteButtonText": "Выдаліць\nПрофіль", + "deleteConfirmText": "Выдаліць '${PROFILE}'?", + "editButtonText": "Рэдагаваць\nПрофіль", + "explanationText": "(стварэнне розных імёнаў і выглядаў для гэтага акаўнта)", + "newButtonText": "Новы\nПрофіль", + "titleText": "Профілі Гульцоў" + }, + "playerText": "Гулец", + "playlistNoValidGamesErrorText": "У гэтым плэйлісце няма адкрытых гульняў.", + "playlistNotFoundText": "плэйліст не знойдзены", + "playlistText": "Плэйліст", + "playlistsText": "Плэйлісты", + "pleaseRateText": "Калі вам падабаецца ${APP_NAME}, калі ласка, знайдзіце\nчас, каб ацаніць яго ці напісаць водгук. Гэта забя-\nспечвае сувязь і дапамагае развіццю гульні.\n\nДзякуй!\n-Эрык", + "pleaseWaitText": "Калі ласка пачакай...", + "pluginsDetectedText": "Выяўлены новыя ўбудовы. Уключыце / наладзьце іх у наладах.", + "pluginsText": "Убудовы", + "practiceText": "Практыка", + "pressAnyButtonPlayAgainText": "Націсніце любую кнопку, каб перазапусціць...", + "pressAnyButtonText": "Націсніце любую кнопку, каб працягнуць...", + "pressAnyButtonToJoinText": "націсніце любую кнопку, каб далучыцца...", + "pressAnyKeyButtonPlayAgainText": "Націсніце любую кнопку, каб перазапусціць...", + "pressAnyKeyButtonText": "Націсніце любую кнопку, каб працягнуць...", + "pressAnyKeyText": "Націсніце любую кнопку...", + "pressJumpToFlyText": "** Націскайце прыгаць некалькі разоў, каб лятаць **", + "pressPunchToJoinText": "націсніце УДАРЫЦЬ, каб далучыцца", + "pressToOverrideCharacterText": "націсніце ${BUTTONS}, каб пераназначыць свайго персанажа", + "pressToSelectProfileText": "націсніце ${BUTTONS}, каб выбраць гульца", + "pressToSelectTeamText": "націсніце ${BUTTONS}, каб выбраць каманду", + "promoCodeWindow": { + "codeText": "Код", + "codeTextDescription": "Прома-Код", + "enterText": "Адправіць" + }, + "promoSubmitErrorText": "Памылка пры адпраўцы кода; праверце падключэнне да Інтэрнэту", + "ps3ControllersWindow": { + "macInstructionsText": "Адключыце харчаванне на задняй панэлі PS3, пераканайцеся, што Bluetooth\nуключаны на вашым кампутары, а затым падключыце кантролер да Mac\nз дапамогаю кабеля USB для сінхранізацыі. Зараз можна выкарыстоўваць\nкнопку кантролера 'Home' каб падключыць яго да Mac у правадным (USB)\nабо бесправадным (Bluetooth) рэжыме.\n\nНа некаторых Mac пры сінхранізацыі можа спатрэбіцца код доступу.\nУ гэтым выпадку звярніцеся да наступнай інструкцыі або да Google.\n\n\n\n\nКантралёры PS3, звязаныя па бесправадной сетцы, павінны з'явіцца\nу спісе прылад у \"Налады сістэмы -> Bluetooth\". Магчыма, вам прыйдзецца\nвыдаліць іх з гэтага спісу, калі вы хочаце зноў выкарыстоўваць іх з PS3.\n\nТаксама заўсёды адключайце іх ад Bluetooth, калі ён не выкарыстоўваецца,\nінакш будуць садзіцца батарэйкі.\n\nBluetooth павінен апрацоўваць да 7 падлучаных прылад,\nале у вас можа атрымацца па-іншаму.", + "ouyaInstructionsText": "Каб выкарыстоўваць кантролер PS3 з OUYA, проста падключыце яго адзін раз\nз дапамогай кабеля USB для сінхранізацыі. Гэта можа адключыць іншыя\nкантролеры, тады трэба перазагрузіць OUYA і адлучыць кабель USB.\n\nПасля гэтага можна выкарыстоўваць кнопку 'Home' для бесправаднога\nпадключэння. Пасля гульні націсніце і ўтрымлівайце кнопку 'Home' на працягу\n10 секунд каб выключыць кантролер, у адваротным выпадку ён можа\nзастацца уключаным і разрадзіць батарэйкі.", + "pairingTutorialText": "спарванне туторыяла", + "titleText": "Выкарыстоўванне кантролераў PS3 з ${APP_NAME}:" + }, + "punchBoldText": "УДАРЫЦЬ", + "punchText": "Ударыць", + "purchaseForText": "Набыць за ${PRICE}", + "purchaseGameText": "Набыць Гульню", + "purchasingText": "Набыццё...", + "quitGameText": "Зачыніць ${APP_NAME}?", + "quittingIn5SecondsText": "Выхад праз 5 секунд...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Выпадкова", + "rankText": "Узровень", + "ratingText": "Рэйтынг", + "reachWave2Text": "Дасягніце 2-ой хвалі, каб атрымаць узровень.", + "readyText": "гатовы", + "recentText": "Нядаўнія", + "remoteAppInfoShortText": "Гуляць ў ${APP_NAME} значна цікавей з сям'ёй ці сябрамі.\nПадлучыце некалькі кантролераў ці ўсталюйце прыкладанне\n${REMOTE_APP_NAME} на тэлефон ці планшэт, каб выкарыстоўваць\nіх у якасці кантролераў.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Месцазнаходжанне Кнопак", + "button_size": "Памер Кнопак", + "cant_resolve_host": "Хост не знойдзены.", + "capturing": "Чаканне...", + "connected": "Злучана.", + "description": "Выкарыстоўвайце ваш тэлефон ці планшэт у якасці кантролераў.\nАдначасова можна падлучыць да 8 прылад.", + "disconnected": "Адключаны серверам.", + "dpad_fixed": "фіксаваны", + "dpad_floating": "незафіксаваны", + "dpad_position": "Месцазнаходжанне D-Pad", + "dpad_size": "Памер D-Pad", + "dpad_type": "Тып D-Pad", + "enter_an_address": "Увесці Адрас", + "game_full": "Гульня не адказвае.", + "game_shut_down": "Гульня адключана.", + "hardware_buttons": "Сістэмныя Кнопкі", + "join_by_address": "Падлучыцца па Адрасе...", + "lag": "Лаг: ${SECONDS} сек", + "reset": "Аднавіць Налады", + "run1": "Бег 1", + "run2": "Бег 2", + "searching": "Пошук гульняў BombSquad...", + "searching_caption": "Націсніце на імя гульні, каб падлучыцца.\nПераканайцеся, што вы падлучаны да адной WiFi сеткі.", + "start": "Пачаць", + "version_mismatch": "Старая версія.\nПераканайцеся, што вы маеце апошнія версіі\nBombSquad і BombSquad Remote." + }, + "removeInGameAdsText": "Купіце \"${PRO}\" у магазіне, каб выдаліць рэкламу.", + "renameText": "Перайменаваць", + "replayEndText": "Закончыць Запіс", + "replayNameDefaultText": "Запіс Апошняй Гульні", + "replayReadErrorText": "Памылка пры чытанні запіса.", + "replayRenameWarningText": "Пераймянуйце \"${REPLAY}\" пасля гульні, калі вы жадаеце захаваць яго; інакш ён выдаліцца.", + "replayVersionErrorText": "Прабачце, запіс быў зроблены ў старай версіі\nгульні і не можа адлюстравацца.", + "replayWatchText": "Глядзець Запіс", + "replayWriteErrorText": "Памылка пры запісе відэазапіса.", + "replaysText": "Запісы", + "reportPlayerExplanationText": "Напішыце на гэты email, каб паскардзіцца на махлярства ці іншыя дрэнныя паводзіны.\nКалі ласка, апішыце ніжэй:", + "reportThisPlayerCheatingText": "Махлярства", + "reportThisPlayerLanguageText": "Нецэнзурныя Выказванні", + "reportThisPlayerReasonText": "На што вы жадаеце паскардзіцца?", + "reportThisPlayerText": "Паскардзіцца", + "requestingText": "Запыт...", + "restartText": "Перазапусціць", + "retryText": "Яшчэ Раз", + "revertText": "Аднавіць", + "runText": "Бяжаць", + "saveText": "Захаваць", + "scanScriptsErrorText": "Памылкі пры сканаванні сцэнарыяў; падрабязнасці глядзіце ў логах.", + "scoreChallengesText": "Іншыя Вынікі", + "scoreListUnavailableText": "Вынікі недаступны.", + "scoreText": "Ачкі", + "scoreUnits": { + "millisecondsText": "Мілісекунды", + "pointsText": "Ачкі", + "secondsText": "Секунды" + }, + "scoreWasText": "(быў ${COUNT})", + "selectText": "Выбраць", + "seriesWinLine1PlayerText": "ПЕРАМАГАЕ Ў", + "seriesWinLine1TeamText": "ПЕРАМАГАЮЦЬ У", + "seriesWinLine1Text": "ПЕРАМАГАЕ Ў", + "seriesWinLine2Text": "СЕРЫІ!", + "settingsWindow": { + "accountText": "Акаўнт", + "advancedText": "Дадатковыя", + "audioText": "Аўдыя", + "controllersText": "Кантролеры", + "graphicsText": "Графіка", + "playerProfilesMovedText": "Заўвага: Профілі гульцоў былі перамешчаны ў \"Акаўнт\" у галоўным меню.", + "playerProfilesText": "Профілі Гульцоў", + "titleText": "Налады" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(простая, зручная для кантролера клавіятура для рэдагавання тэксту)", + "alwaysUseInternalKeyboardText": "Заўсёды карыстацца ўбудаванай клавіятурай", + "benchmarksText": "Тэст Прадукцыйнасці і Тэст-Нагрузка", + "disableCameraGyroscopeMotionText": "Адключыць рух гіраскопа камеры", + "disableCameraShakeText": "Адключыць устрэсванне камеры", + "disableThisNotice": "(вы можаце адключыць гэта апавяшчэнне ў дадатковых наладах)", + "enablePackageModsDescriptionText": "(уключае моды, але адключае гульню па сетцы)", + "enablePackageModsText": "Уключыць Лакальныя Пакеты Модаў", + "enterPromoCodeText": "Увесці код", + "forTestingText": "Гэтыя значэнні выкарыстоўваюцца толькі для тэстаў і будуць згублены пры закрыцці гульні.", + "helpTranslateText": "Пераклад ${APP_NAME} з англійскай мовы - намаганне супольнасці\nпадтрымкі. Калі вы жадаеце выправіць пераклад,\nпрайдзіце па спасылцы ніжэй. Дзякуй!", + "kickIdlePlayersText": "Выкідваць гульцоў, якія не дзейнічаюць", + "kidFriendlyModeText": "Дзіцячы Рэжым (менш гвалту і г.д.)", + "languageText": "Мова", + "moddingGuideText": "Кіраўніцтва па Модынгу", + "mustRestartText": "Вы павінны перазагрузіць гульню, каб прымяніць новыя налады.", + "netTestingText": "Тэсціраванне Сеткі", + "resetText": "Скінуць", + "showBombTrajectoriesText": "Паказваць Траекторыi Бомб", + "showPlayerNamesText": "Паказваць Імёны Гульцоў", + "showUserModsText": "Паказаць Тэчку З Модамі", + "titleText": "Дадаткова", + "translationEditorButtonText": "Рэдактар Перакладаў ${APP_NAME}", + "translationFetchErrorText": "статус перакладу недаступны", + "translationFetchingStatusText": "праверка статуса перакладу...", + "translationInformMe": "Паведаміце мне, калі мая мова мае патрэбу ў абнаўленнях", + "translationNoUpdateNeededText": "гэтая мова абноўлена; ура!", + "translationUpdateNeededText": "** гэтая мова патрабуе абнаўлення!! **", + "vrTestingText": "VR Тэстіраванне" + }, + "shareText": "Падзяліцца", + "sharingText": "Абагульванне...", + "showText": "Паказаць", + "signInForPromoCodeText": "Вы павінны ўвайсці, каб карыстацца кодамі.", + "signInWithGameCenterText": "Каб карыстацца акаўнтам Game Centerб\nувайдзіце з дапамогаю прыкладання Game Center.", + "singleGamePlaylistNameText": "Толькі ${GAME}", + "singlePlayerCountText": "1 гулец", + "soloNameFilterText": "Сола ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Выбар Героя", + "Chosen One": "Абраны", + "Epic": "Эпічны Рэжым", + "Epic Race": "Эпічная Гонка", + "FlagCatcher": "Захоп Сцяга", + "Flying": "Шчаслівыя Думкі", + "Football": "Футбол", + "ForwardMarch": "Напад", + "GrandRomp": "Заваяванне", + "Hockey": "Хакей", + "Keep Away": "Утрыманне", + "Marching": "Манёўр", + "Menu": "Галоўнае Меню", + "Onslaught": "Атака", + "Race": "Гонка", + "Scary": "Кароль Гары", + "Scores": "Табліца Вынікаў", + "Survival": "Ліквідацыя", + "ToTheDeath": "Смяротная Бойка", + "Victory": "Табліца Канчатковых Вынікаў" + }, + "spaceKeyText": "прабел", + "statsText": "Статыстыка", + "storagePermissionAccessText": "Для гэтага неабходны доступ да сховішча", + "store": { + "alreadyOwnText": "У вас ужо ёсць ${NAME}!", + "bombSquadProDescriptionText": "• Дублюе ўсе білеты, якія вы атрымліваеце\n• Выдаляе ўсю рэкламу з гульні\n• Утрымлівае ${COUNT} бонусных білетаў\n• +${PERCENT}% да вашага бонуса Лігі\n• Адкрывае кааператыўныя гульні\n '${INF_ONSLAUGHT}' і '${INF_RUNAROUND}' ", + "bombSquadProFeaturesText": "Асаблівасці:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Выдаляе гульнявую рэкламу і экраны\n• Адкрывае дадатковыя налады гульні\n• Таксама ўключае:", + "buyText": "Набыць", + "charactersText": "Персанажы", + "comingSoonText": "Хутка...", + "extrasText": "Дадаткова", + "freeBombSquadProText": "BombSquad зараз бясплатны, але калі вы набылі яго раней, зараз вы атрымліваеце\nBombSquad Pro і ${COUNT} білетаў у якасці падзякі.\nАтрымлівайце асалоду ад новых магчымасцей і вялікі дзякуй за вашу падтрымку!\n-Эрык", + "gameUpgradesText": "Паляпшэнне Гульні", + "holidaySpecialText": "Святочная Акцыя", + "howToSwitchCharactersText": "(зайдзіце ў \"${SETTINGS} -> ${PLAYER_PROFILES}\", каб наладзіць профілі)", + "howToUseIconsText": "(стварыце глабальны профіль (у раздзеле \"Акаўнт\"), каб скарыстацца гэтым)", + "howToUseMapsText": "(карыстайцеся гэтымі мапамі ў вашых гульнях)", + "iconsText": "Аватары", + "loadErrorText": "Немагчыма загрузіць старонку.\nПраверце інтэрнэт-злучэнне.", + "loadingText": "ладаванне", + "mapsText": "Мапы", + "miniGamesText": "Міні-Гульні", + "oneTimeOnlyText": "(толькі адзін раз)", + "purchaseAlreadyInProgressText": "Набыццё гэтага аб'екта ўжо выконваецца.", + "purchaseConfirmText": "Набыць ${ITEM}?", + "purchaseNotValidError": "Набыццё не адбылося.\nКалі гэта памылка, напішыце на ${EMAIL}.", + "purchaseText": "Набыць", + "saleBundleText": "Распродаж Камплектаў!", + "saleExclaimText": "Акцыя!", + "salePercentText": "(${PERCENT}% зніжка)", + "saleText": "АКЦЫЯ", + "searchText": "Шукаць", + "teamsFreeForAllGamesText": "Камандныя Гульні / Кожны Сам За Сябе", + "totalWorthText": "*** будет стоить вам ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Абнавіць?", + "winterSpecialText": "Зімняя Акцыя", + "youOwnThisText": "- вы маеце гэта -" + }, + "storeDescriptionText": "Гульнявое Вар'яцтва з 8 Гульцамі!\n\nПадрывайце вашых сяброў (ці камп'ютар) у турніры выбуховых міні-гульняў, такіх як Захоп Сцяга ці Эпічная Бойка Запаволенага Дзеяння!\n\nЗ простым кіраваннем і пашыранай падтрымкай кантролераў 8 чалавек могуць далучыцца да гульні, можна нават выкарыстоўваць мабільныя прылады як кантралёры праз бясплатнае прыкладанне 'BombSquad Remote'!\n\nУ атаку!\n\nГл. www.froemling.net/BombSquad для дадатковай інфармацыі.", + "storeDescriptions": { + "blowUpYourFriendsText": "Падарвіце вашых сяброў.", + "competeInMiniGamesText": "Спаборнічайце ў міні-гульнях ад гонак да палётаў.", + "customize2Text": "Наладжвайце персанажаў, міні-гульні і нават саўндтрэкі.", + "customizeText": "Наладзіць персанажаў і стварыць сваі плэйлісты з міні-гульнямі.", + "sportsMoreFunText": "Спорт у шмат разоў весялей з выбухамі!", + "teamUpAgainstComputerText": "Каманды супраць камп'ютара." + }, + "storeText": "Крама", + "submitText": "Адправіць", + "submittingPromoCodeText": "Адпраўка кода...", + "teamNamesColorText": "Назвы / колеры каманд ...", + "telnetAccessGrantedText": "Доступ Telnet уключаны.", + "telnetAccessText": "Знойдзены доступ Telnet, дазволіць?", + "testBuildErrorText": "Гэтая версія састарэла; калі ласка, праверце абнаўленні.", + "testBuildText": "Тэставая Зборка", + "testBuildValidateErrorText": "Не атрымліваецца праверыць тэставую зборку (няма інтэрнэту?)", + "testBuildValidatedText": "Тэставая Зборка Праверана; Поспехаў!", + "thankYouText": "Дзякуй за вашу падтрымку! Прыемнай гульні!!", + "threeKillText": "ТРЫ ЗАБОЙСТВЫ!!", + "timeBonusText": "Бонус Часу", + "timeElapsedText": "Прайшло Часу", + "timeExpiredText": "Час Скончыўся", + "timeSuffixDaysText": "${COUNT} дзён", + "timeSuffixHoursText": "${COUNT} гадзін", + "timeSuffixMinutesText": "${COUNT} мінут", + "timeSuffixSecondsText": "${COUNT} секунд", + "tipText": "Парада", + "titleText": "BombSquad", + "titleVRText": "${ARG1}", + "topFriendsText": "Топ Сяброў", + "tournamentCheckingStateText": "Праверка статусу турніра; калі ласка, пачакайце...", + "tournamentEndedText": "Гэты турнір скончыўся. Хутка пачнецца новы.", + "tournamentEntryText": "Уваход у Турнір", + "tournamentResultsRecentText": "Вынікі Нядаўніх Турніраў", + "tournamentStandingsText": "Месцы ў Турніры", + "tournamentText": "Турнір", + "tournamentTimeExpiredText": "Час Турніра Скончыўся", + "tournamentsText": "Турніры", + "translations": { + "characterNames": { + "Agent Johnson": "Агент 007", + "B-9000": "Ка-9000", + "Bernard": "Бернард", + "Bones": "Боўнс", + "Butch": "Буч", + "Easter Bunny": "Вялікдзеньскі Трусік", + "Flopsy": "Флопсі", + "Frosty": "Фросці", + "Gretel": "Грытэль", + "Grumbledorf": "Гэндальф", + "Jack Morgan": "Джэк Морган", + "Kronk": "Кронк", + "Lee": "Лі", + "Lucky": "Шчасліўчык", + "Mel": "Мэл", + "Middle-Man": "Сярэдні", + "Minimus": "Мінімус", + "Pascal": "Паскаль", + "Pixel": "Піксел", + "Sammy Slam": "Сэммі Слэм", + "Santa Claus": "Святы Мікалай", + "Snake Shadow": "Цень Змяі", + "Spaz": "Спаз", + "Taobao Mascot": "Таабаа Маскат", + "Todd": "Кевін", + "Todd McBurton": "Тод МакБартан", + "Xara": "Ксара", + "Zoe": "Зоя", + "Zola": "Зола" + }, + "coopLevelNames": { + "${GAME} Training": "Падрыхтоўка да гульні ${GAME}", + "Infinite ${GAME}": "Бясконцая ${GAME}", + "Infinite Onslaught": "Бясконцая Атака", + "Infinite Runaround": "Бясконцы Манеўр", + "Onslaught Training": "Атака: Трэніроўка", + "Pro ${GAME}": "${GAME} Профі", + "Pro Football": "Футбол Профі", + "Pro Onslaught": "Атака Профі", + "Pro Runaround": "Манёўр Профі", + "Rookie ${GAME}": "${GAME} Лёгкі", + "Rookie Football": "Футбол Лёгкі", + "Rookie Onslaught": "Атака Лёгкая", + "The Last Stand": "Апошняя Мяжа", + "Uber ${GAME}": "Убер ${GAME}", + "Uber Football": "Убер Футбол", + "Uber Onslaught": "Убер Атака", + "Uber Runaround": "Убер Манёўр" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Каб перамагчы, стань абраным на некаторы час.\nКаб стаць абраным, забей мінулага абранага.", + "Bomb as many targets as you can.": "Падарвіце як мага больш мішэняў.", + "Carry the flag for ${ARG1} seconds.": "Трымайце флаг у руках ${ARG1} секундаў.", + "Carry the flag for a set length of time.": "Трымайце флаг у руках на працягу некаторага часу.", + "Crush ${ARG1} of your enemies.": "Разбейце ${ARG1} ворага(ў).", + "Defeat all enemies.": "Перамажыце ўсех ворагаў.", + "Dodge the falling bombs.": "Ухіліцеся ад падаючых бомб.", + "Final glorious epic slow motion battle to the death.": "Апошняя эпічная смяротная бойка запаволенага дзеяння.", + "Gather eggs!": "Збярыце яйкі!", + "Get the flag to the enemy end zone.": "Перанясіце сцяг у зону абароны ворага.", + "How fast can you defeat the ninjas?": "Як хутка вы можаце перамагчы ніндзя?", + "Kill a set number of enemies to win.": "Забейце некаторую колькасць ворагаў, каб перамагчы.", + "Last one standing wins.": "Апошні жывы перамагае.", + "Last remaining alive wins.": "Перамагае апошні жывы.", + "Last team standing wins.": "Апошняя жывая каманда перамагае.", + "Prevent enemies from reaching the exit.": "Не дайце ворагам прайсці да выхада.", + "Reach the enemy flag to score.": "Дасягніце варожага сцяга, каб зарабіць ачкі.", + "Return the enemy flag to score.": "Перанясіце варожы сцяг на базу, каб зарабіць ачкі.", + "Run ${ARG1} laps.": "Прабяжыце ${ARG1} кругоў.", + "Run ${ARG1} laps. Your entire team has to finish.": "Прабяжыце ${ARG1} кругоў. Прыйсці на фініш павінна ўся каманда.", + "Run 1 lap.": "Прабяжыце 1 круг.", + "Run 1 lap. Your entire team has to finish.": "Прабяжыце 1 круг. Прыйсці на фініш павінна ўся каманда.", + "Run real fast!": "Бяжыце вельмі хутка!", + "Score ${ARG1} goals.": "Забейце ${ARG1} галоў.", + "Score ${ARG1} touchdowns.": "Зрабіце ${ARG1} тачдаўнаў.", + "Score a goal.": "Забейце гол.", + "Score a touchdown.": "Зрабіце тачдаўн.", + "Score some goals.": "Забейце некалькі галоў.", + "Secure all ${ARG1} flags.": "Захапіце ўсе ${ARG1} сцягоў.", + "Secure all flags on the map to win.": "Захапіце ўсе сцягі на мапе, каб перамагчы.", + "Secure the flag for ${ARG1} seconds.": "Захапіце сцяг на ${ARG1} секунд.", + "Secure the flag for a set length of time.": "Захапіце сцяг на пэўны час.", + "Steal the enemy flag ${ARG1} times.": "Скрадзіце варожы сцяг ${ARG1} разоў.", + "Steal the enemy flag.": "Скрадзіце варожы сцяг.", + "There can be only one.": "Можа быць толькі адзін.", + "Touch the enemy flag ${ARG1} times.": "Дакраніцеся да варожага сцяга ${ARG1} разоў.", + "Touch the enemy flag.": "Дакраніцеся да варожага сцяга.", + "carry the flag for ${ARG1} seconds": "трымайце флаг у руках ${ARG1} секундаў", + "kill ${ARG1} enemies": "забейце ${ARG1} ворагаў", + "last one standing wins": "апошні жывы перамагае", + "last team standing wins": "апошняя жывая каманда перамагае", + "return ${ARG1} flags": "перанясіце ${ARG1} сцягаў на базу", + "return 1 flag": "перанясіце сцяг на базу", + "run ${ARG1} laps": "прабяжыце ${ARG1} кругоў", + "run 1 lap": "прабяжыце 1 круг", + "score ${ARG1} goals": "забейце ${ARG1} галоў", + "score ${ARG1} touchdowns": "зрабіце ${ARG1} тачдаўнаў", + "score a goal": "забейце гол", + "score a touchdown": "зрабіце тачдаўн", + "secure all ${ARG1} flags": "захапіце ўсе ${ARG1} сцягоў", + "secure the flag for ${ARG1} seconds": "захапіце сцяг на ${ARG1} секунд", + "touch ${ARG1} flags": "дакраніцеся да ${ARG1} сцягаў", + "touch 1 flag": "дакраніцеся да сцяга" + }, + "gameNames": { + "Assault": "Напад", + "Capture the Flag": "Захоп Сцяга", + "Chosen One": "Абраны", + "Conquest": "Заваёва", + "Death Match": "Смяротная Бойка", + "Easter Egg Hunt": "Вялікдзеньскае Паляванне па Яйкі", + "Elimination": "Ліквідацыя", + "Football": "Футбол", + "Hockey": "Хакей", + "Keep Away": "Не падыходзіць!", + "King of the Hill": "Кароль Гары", + "Meteor Shower": "Метыярытны Дождж", + "Ninja Fight": "Бойка З Ніндзя", + "Onslaught": "Атака", + "Race": "Гонка", + "Runaround": "Абыход", + "Target Practice": "Стральба Па Мішэнях", + "The Last Stand": "Апошняя Мяжа" + }, + "inputDeviceNames": { + "Keyboard": "Клавіятура", + "Keyboard P2": "Клавіятура - Гулец 2" + }, + "languages": { + "Arabic": "Арабскi", + "Belarussian": "Беларуская", + "Chinese": "Кітайская спрошчаная", + "ChineseTraditional": "Кітайская традыцыйная", + "Croatian": "Харвацкая", + "Czech": "Чэшская", + "Danish": "Дацкая", + "Dutch": "Нямецкая", + "English": "Англійская", + "Esperanto": "Эсперанта", + "Filipino": "філіпінскі", + "Finnish": "Фінская", + "French": "Французская", + "German": "Нямецкая", + "Gibberish": "Gibberish", + "Greek": "Грэчаскі", + "Hindi": "Хіндзі", + "Hungarian": "Венгерская", + "Indonesian": "Інданезійская", + "Italian": "Італьянская", + "Japanese": "Японская", + "Korean": "Карэйская", + "Persian": "Фарсі", + "Polish": "Польская", + "Portuguese": "Партугальская", + "Romanian": "Румынская", + "Russian": "Руская", + "Serbian": "Сербская", + "Slovak": "Славацкая", + "Spanish": "Гішпанская", + "Swedish": "Шведская", + "Tamil": "тамільская", + "Thai": "Тайская мова", + "Turkish": "Турэцкі", + "Ukrainian": "Украінскі", + "Venetian": "Венецыянскі", + "Vietnamese": "В'етнамскі" + }, + "leagueNames": { + "Bronze": "Бронзавая", + "Diamond": "Алмазная", + "Gold": "Залатая", + "Silver": "Сярэбраная" + }, + "mapsNames": { + "Big G": "Вялікая G", + "Bridgit": "Брыджыт", + "Courtyard": "Двор", + "Crag Castle": "Замак на Скале", + "Doom Shroom": "Смяротны Грыб", + "Football Stadium": "Футбольны Стадыён", + "Happy Thoughts": "Воблачныя Думкі", + "Hockey Stadium": "Хакейны Стадыён", + "Lake Frigid": "Ледзяная Роўнядзь", + "Monkey Face": "Твар Малпы", + "Rampage": "Буянства", + "Roundabout": "Карусель", + "Step Right Up": "Лесвіца", + "The Pad": "Кілімок", + "Tip Top": "Ціп-Топ", + "Tower D": "Вежа D", + "Zigzag": "Зігзаг" + }, + "playlistNames": { + "Just Epic": "Толькі Эпічна", + "Just Sports": "Толькі Спорт" + }, + "scoreNames": { + "Flags": "Сцягі", + "Goals": "Галы", + "Score": "Ачкі", + "Survived": "Выжыванні", + "Time": "Час", + "Time Held": "Час Гульні" + }, + "serverResponses": { + "A code has already been used on this account.": "Прома-код ужо выкарыстоўваўся на гэтым акаўнце.", + "A reward has already been given for that address.": "За гэты адрас ужо ўручана ўзнагарода.", + "Account linking successful!": "Злучэнне акаўнтаў выканана!", + "Account unlinking successful!": "Ўліковы запіс паспяхова адключаны!", + "Accounts are already linked.": "Акаўнты ўжо злучаны.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Немагчыма праверыць прагляд рэкламы.\nПераканайцеся, што вы выкарыстоўваеце афіцыйную і свежую версію гульні.", + "An error has occurred; (${ERROR})": "Адбылася памылка; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Адбылася памылка; калі ласка, звяжыцеся са службай падтрымкі. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Узнікла памылка; звяжыцеся з support@froemling.net.", + "An error has occurred; please try again later.": "Адбылася памылка; калі ласка паспрабуйце зноў пазней.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Вы ўпэўнены, што жадаеце звязаць гэтыя акаўнты?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nГэта нельга будзе адмяніць!", + "BombSquad Pro unlocked!": "BombSquad Pro адкрыты!", + "Can't link 2 accounts of this type.": "Немагчыма звязаць 2 акаўнты гэтага тыпа.", + "Can't link 2 diamond league accounts.": "Нельга звязаць 2 акаўнты алмазнай лігі.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Злучэнне немагчыма; дасягнута максімальная колькасць злучэнняў (${COUNT}).", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Заўважана махлярства; ачкі і прызы забаронены на ${COUNT} дзён.", + "Could not establish a secure connection.": "Немагчыма стварыць бяспечнае злучэнне.", + "Daily maximum reached.": "Штодзённы максімум дасягнуты.", + "Entering tournament...": "Уваход у турнір...", + "Invalid code.": "Няправільны код.", + "Invalid payment; purchase canceled.": "Несапраўдная аплата; купля адменена.", + "Invalid promo code.": "Няправільны прома-код.", + "Invalid purchase.": "Памылка пры набыцці.", + "Invalid tournament entry; score will be ignored.": "Няправільны турнір; вынік не будзе залічаны.", + "Item unlocked!": "Элемент разблакаваны!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ЗВЯЗАННЕ АДМЕНАВАНА. ${ACCOUNT} змяшчае\nважныя дадзеныя, якія ЎСЕ БУДУЦЬ СТРАЧЭНЫ.\nВы можаце зрабіць спасылку ў адваротным парадку, калі хочаце\n(і замест гэтага страціць дадзеныя ГЭТАГА ўліковага запісу)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Прывязаць уліковы запіс ${ACCOUNT} к гэтаму улiковаму запiсу?\nУсе існуючыя дадзеныя на ${ACCOUNT} будуць страчаны.\nГэта не можа быць адменена. Вы ўпэўнены?", + "Max number of playlists reached.": "Максімальная колькасць плэйлістаў дасягнута.", + "Max number of profiles reached.": "Максімальная колькасць профіляў дасягнута.", + "Maximum friend code rewards reached.": "Дасягнута максімальная ўзнагарода за код сябра.", + "Message is too long.": "Паведамленне занадта доўгае.", + "No servers are available. Please try again soon.": "Няма даступных сервераў. Калі ласка, паспрабуйце яшчэ раз пазней.", + "Profile \"${NAME}\" upgraded successfully.": "Профіль \"${NAME}\" палепшаны паспяхова.", + "Profile could not be upgraded.": "Профіль нельга палепшыць.", + "Purchase successful!": "Аб'ект набыты паспяхова!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Атрымана ${COUNT} квіткоў за ўваход.\nПрыходзьце заўтра, каб атрымаць яшчэ ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Функцыянальнасць сервера больш не падтрымліваецца ў гэтай версіі гульні;\nАбнавіце да новай версіі.", + "Sorry, there are no uses remaining on this code.": "Прабачце, код ужо выкарыстаны максімальную колькасць разоў.", + "Sorry, this code has already been used.": "Прабачце, гэты код ужо выкарыстоўваўся.", + "Sorry, this code has expired.": "На жаль, срок дзеяння гэтага кода ўжо скончыўся.", + "Sorry, this code only works for new accounts.": "Прабачце, гэты код працуе толькі на новых акаўнтах.", + "Still searching for nearby servers; please try again soon.": "Працягваецца пошук бліжэйшых сервераў; калі ласка, паспрабуйце яшчэ раз пазней.", + "Temporarily unavailable; please try again later.": "Часова недаступны; калі ласка паспрабуйце зноў пазней.", + "The tournament ended before you finished.": "Турнір скончыўся перад тым, як вы закончылі.", + "This account cannot be unlinked for ${NUM} days.": "Немагчыма адлучыць гэты ўліковы запіс на працягу ${NUM} дзён.", + "This code cannot be used on the account that created it.": "Кодам нельга скарыстацца на акаўнце, які стварыў яго.", + "This is currently unavailable; please try again later.": "У цяперашні час гэта недаступна; калі ласка, паспрабуйце зноў пазней.", + "This requires version ${VERSION} or newer.": "Неабходна версія ${VERSION} гульні ці навей.", + "Tournaments disabled due to rooted device.": "Турніры адключаны з-за рутiраванай прылады.", + "Tournaments require ${VERSION} or newer": "Для турніраў патрабуецца ${VERSION} або больш позняя версія", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Адключыць ${ACCOUNT} ад гэтага ўліковага запісу?\nУсе дадзеныя на ${ACCOUNT} будуць скіданы.\n(за выключэннем дасягненняў у некаторых выпадках)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "УВАГА: на ваш уліковы запіс паступілі скаргі на ўзлом.\nБудуць забаронены ўліковыя запісы, якія будуць прызнаныя хакерскімі. Калі ласка, гуляйце сумленна.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Ці жадаеце вы аб'яднаць ваш акаўнт на прыладзе з гэтым?\n\nВаш акаўнт на прыладзе - ${ACCOUNT1}\nГэты акаўнт - ${ACCOUNT2}\n\nГэта дазволіць вам сінхранізіраваць прагрэс.\nАсцярожна - гэта нельга адмяніць!", + "You already own this!": "Вы ўжо маеце гэта!", + "You can join in ${COUNT} seconds.": "Вы можаце далучыцца праз ${COUNT} секунд.", + "You don't have enough tickets for this!": "У вас не хапае квіткоў!", + "You don't own that.": "Вы не валодаеце гэтым.", + "You got ${COUNT} tickets!": "Вы атрымалі ${COUNT} квіткоў!", + "You got a ${ITEM}!": "Вы атрымалі ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Вас павысілі і перавялі ў іншую лігу; віншуем!", + "You must update to a newer version of the app to do this.": "Вы павінны абнавіць гульню, каб зрабіць гэта.", + "You must update to the newest version of the game to do this.": "Для гэтага неабходна абнавіць да новай версіі гульні.", + "You must wait a few seconds before entering a new code.": "Пачакайце некалькі секунд, перад тым, як уводзіць новы код.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ваш узровень у апошнім турніры: #${RANK}. Дзякуй за гульню!", + "Your account was rejected. Are you signed in?": "Ваш уліковы запіс быў адхілены. Вы ўвайшлі ў сістэму?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ваша версія гульні была мадыфікавана.\nКалі ласка, адмяніце ўсе змены і паспрабуйце яшчэ раз.", + "Your friend code was used by ${ACCOUNT}": "${ACCOUNT} выкарыстаў ваш сяброўскі код" + }, + "settingNames": { + "1 Minute": "1 Мінута", + "1 Second": "1 Секунда", + "10 Minutes": "10 Мінут", + "2 Minutes": "2 мінуты", + "2 Seconds": "2 Секунды", + "20 Minutes": "20 Мінут", + "4 Seconds": "4 Секунды", + "5 Minutes": "5 Мінут", + "8 Seconds": "8 секунд", + "Allow Negative Scores": "Дазволiць Адмоўныя Вынікі", + "Balance Total Lives": "Размяркоўваць Здароўе, Якое Засталося", + "Bomb Spawning": "Стварэнне бомб", + "Chosen One Gets Gloves": "Абраны Атрымлівае Пальчаткі", + "Chosen One Gets Shield": "Абраны Атрымлівае Шчыт", + "Chosen One Time": "Час Абранага", + "Enable Impact Bombs": "Уключыць Ударныя Бомбы", + "Enable Triple Bombs": "Уключыць Патрайняльнік Бомб", + "Entire Team Must Finish": "Уся каманда павінна дайсці да фінішу", + "Epic Mode": "Эпічны Рэжым", + "Flag Idle Return Time": "Час Вяртання Кінутага Сцяга", + "Flag Touch Return Time": "Час Захопу Сцяга", + "Hold Time": "Час Утрымлівання", + "Kills to Win Per Player": "Забойствы - Перамагаючаму Гульцу", + "Laps": "Кругі", + "Lives Per Player": "Здароўя На Гульца", + "Long": "Доўга", + "Longer": "Даўжэй", + "Mine Spawning": "Мінаванне", + "No Mines": "Без Мін", + "None": "Не", + "Normal": "Нармальна", + "Pro Mode": "Складаны рэжым", + "Respawn Times": "Час да Ўваскрашэння", + "Score to Win": "Ачкоў для Перамогі", + "Short": "Коратка", + "Shorter": "Карачэй", + "Solo Mode": "Сола-Рэжым", + "Target Count": "Мішэняў Адначасова", + "Time Limit": "Ліміт Часу" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} дыскваліфікаваны, таму што ${PLAYER} выйшаў", + "Killing ${NAME} for skipping part of the track!": "Ліквідацыя ${NAME} за скарачэнне трасы!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Папярэджанне для ${NAME}: турба / спам-кнопкі выб'е вас з ладу." + }, + "teamNames": { + "Bad Guys": "Злодзеі", + "Blue": "Блакітныя", + "Good Guys": "Героі", + "Red": "Чырвоныя" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Своечасовая паслядоўнасць \"Бег-Скачок-Кручэнне-Удар\" можа забіць\nадным ударам і даць вам пажыццёвую павагу вашых сяброў.", + "Always remember to floss.": "Не забывайце карыстацца зубной ніткай.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Стварайце профілі для сябе і вашых сяброў з асабістымі імёнамі і\nзнешнім выглядам замест таго, каб карыстацца выпадковымі.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Скрыні Смерці хутка ператвараюць вас у бомбу.\nАдзіны спосаб пазбавіцца ад гэтага - схапіць аптэчку.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Незалежна ад знешняга выгляду, здольнасці ўсіх персанажаў \nаднолькавыя, таму выбіраеце тых, на каго вы больш падобныя.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Не будзьце занадта дзёрзкім с гэтым энэргетычным шчытом; вас усё яшчэ можна скінуць з абрыва.", + "Don't run all the time. Really. You will fall off cliffs.": "Не бегай увесь час. Сур'ёзна. Звалішся з абрыва.", + "Don't spin for too long; you'll become dizzy and fall.": "Не круціцеся занадта доўга; у вас закружыцца галава і вы ўпадзе.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Націсніце любую кнопку, каб бяжаць. (трыгеры вельмі зручныя для гэтага)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Націсніце любую кнопку, каб бяжаць. Канечне, вы будзеце \nрухацца хутчэй. Але не забывайце пра абрывы!", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ледзяныя бомбы не вельмі моцныя, але яны спыняюць усіх\nнавокал, робячы іх безабароненымі і далікатнымі.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Калі хтосьці вас схапіў, бейце яго, і ён адпусціць.\nГэта таксама працуе ў рэальным жыцці.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Калі ў вас няма кантролераў, усталюйце прыкладанне ${REMOTE_APP_NAME} на \nвашу мабільную прыладу, каб карыстацца ёю ў якасці кантролера.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Калі вам не хапае кантролераў, усталюйце прыкладанне 'BombSquad Remote'\nна iOS або Android прылады, каб карыстацца імі, як кантролерамі.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Калі вы злавілі бомбу-ліпучку, прыгайце і бегайце. Магчыма, вам пашанцуе, і вы \nскінеце яе. У адваротным выпадку вы хоць павесяліце сяброў.", + "If you kill an enemy in one hit you get double points for it.": "Калі вы заб'еце ворага адным ударам, вам дадуць у два разы больш ачкоў.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Калі вы падхапілі смяротны бонус, адзіная надзея - знайсці\nаптэчку ў бліжэйшыя некалькі секундаў.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Не стой на месцы - падсмажышся! Бягі і старайся выжыць.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Калі ў вашым лоббі гуляе многа людзей, уключыце \"Аўтаматычнае выкідванне пры\nпрастоі\" у наладах. Магчыма, нехта з гульцоў забыў выйсці.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Калi ваша прылада награваецца цi вы жадаеце захаваць запад батарэi,\nпаменьшыце \"Вiзуальныя эфекты\" цi \"Разрашэнне\" ý Налады->Графiка.", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Калi карцiнка перарывiстая, паспрабуйце паменьшыць разрэшэнне\nцi графiку ý наладах графiкi ý гульне.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "У Захопе Сцяга ваш сцяг павiнен быць на вашай базе, каб захапiць чужы, калi чужая \nкаманда амаль-што захапiла ваш сцяг, добрым вырашэннем iх спынення будзе схапiць iх сцяг.", + "In hockey, you'll maintain more speed if you turn gradually.": "У хакее магчыма падтрымлiваць большую хуткасць, калi паварачваць паступова.", + "It's easier to win with a friend or two helping.": "Лягчэй перамагчы з адным цi дзвума сябрамi.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Скокнi адразу парад кiдком бомбы,каб закiнуць яе як мага вышэй.", + "Land-mines are a good way to stop speedy enemies.": "Мiны - добры спосаб спынiць хуткiх ворагаý.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Многа рэчаý магчыма ýзняць i кiнуць, уключна другiх гулбцоý. Шпурлянне \nвашых ворагаý з абрыва можа зрабiцца эфектыýнай i падбадзёрлiвай стратэгiяй.", + "No, you can't get up on the ledge. You have to throw bombs.": "Не, у вас не атрымаецца ýзлезцi на выступ. Вам патрэбна кiдаць бомбы.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Гульцы могуць далучацца i зыходзiць ý сярэдзiне многiх гульняý, \nтаксама вы можаце падключаць i адключаць кантролеры прам на ляту.", + "Practice using your momentum to throw bombs more accurately.": "Папрактыкуйцеся карыстацца патрэбным момантам для кiдання бомб больш акуратна.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Удары робяць тым больш урону, чым хутчэй вы бяжыце перад iмi,\nТак што паспрабуйце бегчы, скакаць i круцiцца як вар'ят.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Прабяжыце назад i павернiцеся перад кiдком \nбомбы для таго, каб махнуць ёй i кiнуць далей.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Забейце некалькi злодзеяý, кiнуýшы \nбомбу недалёка ад TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Галава - самае ўразлівае месца, так што ліпучая бомба\nпа галаве, як правіла, значыць капут.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Гэты ўзровень бясконцы, але высокія ачкі тут\nзаробяць вам адвечную павагу ва ўсім свеце.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Моц кідку залежыць ад накірунку, які націснут. Каб акуратна \nкінуць што-небудзь прама перад сабой, не націскакйце ні ў якім накірунку.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Надакучыў саундтрэк? Змяніце яго на свой!\nГлядзіце Налады->Аўдыя->Саундтрэкі", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Паспрабуйце \"Падцяпліць\" бомбы секунду ці дзве перад тым, як кінуць іх.", + "Try tricking enemies into killing eachother or running off cliffs.": "Паспрабуйце падмануць ворагаў, каб яны забілі адзін аднаго ці саскочылі з абрыва.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Карыстайцеся кнопкай выбару (трохвугольнік), каб схапіць сцяг < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Узмахніце туды-сюды, каб закінуць далей", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Вы можаце накіроўваць удары, круцячыся ў правы ці ў левы бок.\nГэта карысна для спіхвання злодзеяў з краю або для галоў у хакее", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Час выбуху бомбы магчыма адгадаць па колеры іскраў ад кнота:\nжоўты..аранжавы..чырвоны..БАБАХ.", + "You can throw bombs higher if you jump just before throwing.": "Бомбу магчыма кінуць вышэй, калі падскочыць адразу перад кідком", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Вы атрымліваеце страты, калі б'ецеся галавой,\nтак што беражыце галаву", + "Your punches do much more damage if you are running or spinning.": "Вашы ўдары робяцца мацней, калі вы бяжыце ці кружыцеся" + } + }, + "trophiesRequiredText": "Для гэтага патрэбны мінімум ${NUMBER} трафеяў.", + "trophiesText": "Трафеі", + "trophiesThisSeasonText": "Трафеі за Гэты Сезон", + "tutorial": { + "cpuBenchmarkText": "Прагон туторыяла з немагчымай хуткасцю (нагружае працэсар)", + "phrase01Text": "Прывітанне!", + "phrase02Text": "Прывітанне ў ${APP_NAME}!", + "phrase03Text": "Вось некалькі парад для кантролю вашага героя:", + "phrase04Text": "Мноства рэчаў у ${APP_NAME} заснавана на фізіцы.", + "phrase05Text": "Напрыклад, калі вы ўдарыце,..", + "phrase06Text": "..страты будуць залежыць ад вашай хуткасці.", + "phrase07Text": "Бачылі? Мы не рухаліся, таму ледзь ударылі ${NAME}.", + "phrase08Text": "Цяпер давайце прыгаць, каб рухацца яшчэ хутчэй.", + "phrase09Text": "О, так лепш.", + "phrase10Text": "Бег таксама дапамагае.", + "phrase11Text": "Націсніце ЛЮБУЮ кнопку, каб бяжаць.", + "phrase12Text": "Каб нанесці вельмі вялікія страты, спрабуйце бяжаць І прыгаць.", + "phrase13Text": "Упс; ${NAME}, прабач за гэта.", + "phrase14Text": "Вы можаце падымаць і кідаць рэчы, напрыклад сцягі.. ці ${NAME}.", + "phrase15Text": "Нарэшце, гэта бомбы.", + "phrase16Text": "Кіданне бомб патрабуе практыкі.", + "phrase17Text": "Оў! Не вельмі добры кідок.", + "phrase18Text": "Рух дапамагае вам кідаць далей.", + "phrase19Text": "Скачкі дапамагаюць вам кідаць вышэй.", + "phrase20Text": "\"Закручаныя\" бомбы ляцяць яшчэ далей.", + "phrase21Text": "\"Падцяпліць\" бомбу даволі складана.", + "phrase22Text": "Міма.", + "phrase23Text": "Паспрабуйце \"падцяпліць\" бомбу секунду ці дзве.", + "phrase24Text": "Ура! Добра падцяплілі!", + "phrase25Text": "Гэта, мабыць, усё.", + "phrase26Text": "Наперад, на міны!", + "phrase27Text": "Памятайце сваю трэніроўку, і вы вернецеся жывым!", + "phrase28Text": "...магчыма...", + "phrase29Text": "Поспехаў!", + "randomName1Text": "Фрэд", + "randomName2Text": "Гары", + "randomName3Text": "Біл", + "randomName4Text": "Чак", + "randomName5Text": "Філ", + "skipConfirmText": "Сапраўды прапусціць туторыял? Націсніце, каб пацвердзіць.", + "skipVoteCountText": "${COUNT}/${TOTAL} галасоў за пропуск", + "skippingText": "пропуск туторыяла...", + "toSkipPressAnythingText": "(націсніце, каб прапусціць туторыял)" + }, + "twoKillText": "ДВА ЗАБОЙСТВЫ!", + "unavailableText": "недаступна", + "unconfiguredControllerDetectedText": "Невядомы кантролер знойдзены:", + "unlockThisInTheStoreText": "Гэта павінна быць адкрыта ў магазіне.", + "unlockThisProfilesText": "Каб стварыць больш за ${NUM} профіляў, вам трэба:", + "unlockThisText": "Каб адкрыць гэта, вам патрэбна:", + "unsupportedHardwareText": "Прабачце, ваша прылада не падтрымлівае гэтую версію гульні.", + "upFirstText": "Спачатку:", + "upNextText": "Далей у гульні ${COUNT}:", + "updatingAccountText": "Абнаўленне вашага акаўнта...", + "upgradeText": "Палепшыць", + "upgradeToPlayText": "Адкрыйце \"${PRO}\" у магазіне, каб гуляць у гэта.", + "useDefaultText": "Вярнуць Стандартныя", + "usesExternalControllerText": "Гэта гульня можа выкарыстоўваць знешні кантролер для кіравання.", + "usingItunesText": "Выкарыстанне музычнага прыкладання для саўндтрэка ...", + "usingItunesTurnRepeatAndShuffleOnText": "Калі ласка, праверце, што ператасаванне і паўтор усяго ў iTunes ўключаны. ", + "validatingTestBuildText": "Праверка Тэставай Зборкі...", + "victoryText": "Перамога!", + "voteDelayText": "Вы не можаце пачаць яшчэ адно галасаванне на працягу ${NUMBER} секунд", + "voteInProgressText": "Галасаванне ўжо ідзе.", + "votedAlreadyText": "Вы ўжо прагаласавалі", + "votesNeededText": "Патрэбна ${NUMBER} галасоў", + "vsText": "супраць", + "waitingForHostText": "(чакаем ${HOST}, каб працягнуць)", + "waitingForPlayersText": "чакаем гульцоў...", + "waitingInLineText": "Чакаем у чарзе (вечарынка поўная)...", + "watchAVideoText": "Глядзіце відэа", + "watchAnAdText": "Глядзець Рэкламу", + "watchWindow": { + "deleteConfirmText": "Выдаліць \"${REPLAY}\"?", + "deleteReplayButtonText": "Выдаліць\nЗапіс", + "myReplaysText": "Мае Відэазапісы", + "noReplaySelectedErrorText": "Запіс Не Выбраны", + "playbackSpeedText": "Хуткасць прайгравання: ${SPEED}", + "renameReplayButtonText": "Перайменаваць\nЗапіс", + "renameReplayText": "Перайменаваць \"${REPLAY}\" на:", + "renameText": "Перайменаваць", + "replayDeleteErrorText": "Памылка пры выдаленні.", + "replayNameText": "Імя Запіса", + "replayRenameErrorAlreadyExistsText": "Запіс с такім імем ужо існуе.", + "replayRenameErrorInvalidName": "Нельга перайменаваць запіс; немагчымае імя.", + "replayRenameErrorText": "Памылка пры перайменаванні запіса.", + "sharedReplaysText": "Агульныя Запісы", + "titleText": "Глядзець", + "watchReplayButtonText": "Глядзець\nЗапіс" + }, + "waveText": "Хваля", + "wellSureText": "Выдатна!", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Слуханне Wiimotes...", + "pressText": "Адначасова націсніце кнопкі 1 і 2.", + "pressText2": "На новых Wiimotes з убудаваным Motion Plus, націсніце чырвоную кнопку 'sync'." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "listenText": "Слухаць", + "macInstructionsText": "Пераканайцеся, што ваш Wii выключаны, а на вашым камп'ютары\nўключаны Bluetooth, а затым націсніце «Слухаць». Падтрымка \nWiimote можа быць трохі няправільная, так што вам, магчыма, прыйдзецца \nпаспрабаваць некалькі разоў, перш чым вы атрымаеце злучэнне.\n\nBluetooth павінны апрацоўваць да 7 падлучаных прылад,\nале нэта можа вар'іравацца.\n\nBombSquad падтрымлівае арыгінальныя Wiimotes, Nunchuks,\nі класічны кантролер.\nНовая Wii Remote Plus ў цяперашні час працуе добра,\nале не з ўкладаннямі.", + "thanksText": "Дзякуй камандзе DarwiinRemote\nза то, што зрабілі гэта магчымым.", + "titleText": "Налады Wiimote" + }, + "winsPlayerText": "${NAME} Перамагае!", + "winsTeamText": "${NAME} Перамагаюць!", + "winsText": "${NAME} Перамагае!", + "worldScoresUnavailableText": "Сусветныя вынікі недаступны.", + "worldsBestScoresText": "Лепшыя Сусветныя Вынікі", + "worldsBestTimesText": "Лепшы Сусветны Час", + "xbox360ControllersWindow": { + "getDriverText": "Атрымаць Драйвер", + "macInstructions2Text": "Каб выкарыстоўваць бесправадныя кантролеры, вам таксама патрэбен \nпрыёмнік, які пастаўляецца з «Xbox 360 Wireless Controller для Windows\".\nАдзін прыёмнік дазваляе падключыць да 4 кантролераў.\n\nВажна: 3-ія прыёмнікі не будуць працаваць з гэтым драйверам;\nпераканайцеся, што на вашым прыёмніке напісана \"Microsoft\", а не \n«XBOX 360». Microsoft больш не прадае іх асобна, так што вам\nтрэба набыць камплект, альбо шукаць кантролеры на Ebay.\n\nКалі вы знойдзеце гэта карысным, калі ласка, разгледзіце ахвяраванне\nраспрацоўшчыку драйвераў на ягоным сайце.", + "macInstructionsText": "Для выкарыстання кантролераў Xbox 360, вы павінны будзеце ўсталяваць\nдрайвер для Mac, даступны па спасылцы ніжэй.\nГэта працуе як з праваднымі, так і з бесправаднымі кантролерамі.", + "ouyaInstructionsText": "Для выкарыстання правадных кантролераў Xbox 360 з BombSquad, проста\nпадключыце іх да USB-порту вашай прылады. Вы можаце выкарыстоўваць канцэнтратар\nUSB для падлучэння некалькіх кантролераў.\n\nДля выкарыстання бесправадных кантролераў вам патрэбен бесправадной прыёмнік,\nякі даступны як частка пакета \"Бесправадной кантролер Xbox 360 для Windows\"\nабо прадаецца асобна. Кожны прыёмнік падключаецца да порта USB і\nдазваляе падключыць да 4 бесправадных кантролераў.", + "titleText": "Выкарыстоўванне кантролераў Xbox 360 з ${APP_NAME}:" + }, + "yesAllowText": "Так, Дазволіць!", + "yourBestScoresText": "Вашыя Лепшыя Вынікі", + "yourBestTimesText": "Ваш Лепшы Час" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/chinese.json b/dist/ba_data/data/languages/chinese.json new file mode 100644 index 0000000..fba406b --- /dev/null +++ b/dist/ba_data/data/languages/chinese.json @@ -0,0 +1,1908 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "账户名称不能包含Emoji表情符号或其他特殊符号!", + "accountProfileText": "(账户资料)", + "accountsText": "账户", + "achievementProgressText": "完成了${TOTAL}个成就中的${COUNT}个", + "campaignProgressText": "战役进程 [困难] :${PROGRESS}", + "changeOncePerSeason": "在每个赛季中你只能更改它一次。", + "changeOncePerSeasonError": "你需要等到下个赛季才能对它再次更改 (还有${NUM}天)", + "customName": "玩家姓名", + "googlePlayGamesAccountSwitchText": "如果你想登录两个不同的谷歌账户,\n请使用Play游戏APP来操作~", + "linkAccountsEnterCodeText": "输入代码", + "linkAccountsGenerateCodeText": "生成代码", + "linkAccountsInfoText": "(在不同的平台上同步游戏进程)", + "linkAccountsInstructionsNewText": "要关联两个帐户,首先点“生成代码”\n,在第二设备点“输入代码”输入。\n两个帐户数据将被两者共享。\n\n您最多可以关联${COUNT}个帐户。\n(包括自己的账户)\n\n重要提示:最好只关联自己的账户;\n如果你与朋友的账户关联了,那么\n你们将不能同时游玩线上模式。", + "linkAccountsInstructionsText": "若要关联两个账户,在其中一个账户内\n生成一个代码,用以在另一个账户内输入。\n游戏进程和物品将会被合并。\n您最多可以关联${COUNT}个账户\n\n重要:只能关联您自己的帐户!\n如果您跟您的朋友关联帐户\n您将无法在同一时间玩\n\n另外:此操作目前不能撤销,所以要小心!", + "linkAccountsText": "关联账户", + "linkedAccountsText": "已关联的账户:", + "manageAccountText": "管理账户", + "nameChangeConfirm": "更改账户名称为${NAME}?", + "notLoggedInText": "未登录", + "resetProgressConfirmNoAchievementsText": "这样会重置单机模式的进程和\n本地的高分记录(并不包括你的点券),\n而且不能恢复,确定要这样做吗?", + "resetProgressConfirmText": "这样会重置单机模式的进程,\n成就和本地的高分记录\n(并不包括你的点券),而且不能\n恢复,确定要这样做吗?", + "resetProgressText": "重置游戏进程", + "setAccountName": "设置账户名称", + "setAccountNameDesc": "选择要为您的帐户显示的名称。\n您可以从链接的帐户选择\n或创建唯一的自定义名称。", + "signInInfoText": "登陆以获取点券, 在线竞赛,\n并在不同设备上同步游戏进程。", + "signInText": "登陆", + "signInWithDeviceInfoText": "(仅适用于此设备的一个自动账户)", + "signInWithDeviceText": "用设备账户来登陆", + "signInWithGameCircleText": "使用 Game Circle 登入", + "signInWithGooglePlayText": "用 Google Play 来登陆", + "signInWithTestAccountInfoText": "使用设备上的其他网络帐号登录;不建议选择该项", + "signInWithTestAccountText": "用测试账户来登陆", + "signInWithV2InfoText": "(账户在所有平台都通用)", + "signInWithV2Text": "使用炸弹小分队账号登录", + "signOutText": "登出", + "signingInText": "登录中...", + "signingOutText": "登出中...", + "testAccountWarningOculusText": "警告:你正在使用“测试”账户登录。\n此账户会在今年晚些时候被Oculus账户代替,\n并将会提供票券购买功能和其他的功能。\n\n现在你只能在游戏中赢取票券。\n(然而,你可以免费升级到BombSquad的专业版本)", + "testAccountWarningText": "警告:你正在使用“测试”账户登录。\n这个账户是与现在这一台设备绑定的,\n并且可能会被周期性地重置数据。(所以\n请不要花太长的时间来解锁或收集物品)\n\n运行本游戏的正式版来使用一个\"真正的\"账户\n(Game-Center或Google Plus账户等等)。\n这样做能将你的数据存储在云端并且在不同的\n设备间共享。\n", + "ticketsText": "点券:${COUNT}", + "titleText": "账号", + "unlinkAccountsInstructionsText": "选择要取消关联的帐户", + "unlinkAccountsText": "取消连结帐户", + "unlinkLegacyV1AccountsText": "取消连接旧版(V1)账户", + "v2LinkInstructionsText": "扫码或使用链接来登录或注册新账户", + "viaAccount": "(不可用名称 ${NAME})", + "youAreLoggedInAsText": "您已登录为", + "youAreSignedInAsText": "你已登录为:" + }, + "achievementChallengesText": "成就挑战", + "achievementText": "成就", + "achievements": { + "Boom Goes the Dynamite": { + "description": "用 TNT 炸死三个坏蛋", + "descriptionComplete": "用 TNT 炸死了三个坏蛋", + "descriptionFull": "在${LEVEL}中用TNT炸死三个坏蛋", + "descriptionFullComplete": "在${LEVEL}中用 TNT 炸死了三个坏蛋", + "name": "发威吧!TNT!" + }, + "Boxer": { + "description": "不使用任何炸弹获得胜利", + "descriptionComplete": "没有使用任何炸弹就获胜了", + "descriptionFull": "在${LEVEL}中不用炸弹获胜", + "descriptionFullComplete": "在${LEVEL}中没用炸弹就获胜了", + "name": "拳王" + }, + "Dual Wielding": { + "descriptionFull": "连接两个控制手柄(硬件或应用)", + "descriptionFullComplete": "已经连接两个控制手柄(硬件或应用)", + "name": "成双成对" + }, + "Flawless Victory": { + "description": "毫发无损地获胜", + "descriptionComplete": "毫发无损地获胜了", + "descriptionFull": "在${LEVEL}中毫发无损地获胜", + "descriptionFullComplete": "在${LEVEL}中毫发无损地获胜了", + "name": "完美获胜" + }, + "Free Loader": { + "descriptionFull": "开始一个“混战模式”游戏(2+玩家)", + "descriptionFullComplete": "已经开始一个“混战模式”游戏(2+玩家)", + "name": "揩油的人" + }, + "Gold Miner": { + "description": "用地雷杀死6个坏蛋", + "descriptionComplete": "用地雷杀死了6个坏蛋", + "descriptionFull": "在${LEVEL}中用地雷杀死6个坏蛋", + "descriptionFullComplete": "在${LEVEL}中用地雷杀死了6个坏蛋", + "name": "地雷专家" + }, + "Got the Moves": { + "description": "不用炸弹或拳头攻击就获胜", + "descriptionComplete": "没有用炸弹或拳头攻击就获胜了", + "descriptionFull": "在${LEVEL}中不用炸弹或拳头攻击就获胜", + "descriptionFullComplete": "在${LEVEL}中没有用炸弹或拳头攻击就获胜了", + "name": "跑位是关键" + }, + "In Control": { + "descriptionFull": "连接一个控制手柄(硬件或应用)", + "descriptionFullComplete": "已经连接一个控制手柄(硬件或应用)", + "name": "掌控之中" + }, + "Last Stand God": { + "description": "得1000分", + "descriptionComplete": "得了1000分", + "descriptionFull": "在${LEVEL}中获得1000分", + "descriptionFullComplete": "在${LEVEL}中获得了1000分", + "name": "${LEVEL}之神" + }, + "Last Stand Master": { + "description": "得250分", + "descriptionComplete": "得了250分", + "descriptionFull": "在${LEVEL}中获得250分", + "descriptionFullComplete": "在${LEVEL}中获得了250分", + "name": "${LEVEL}的大师" + }, + "Last Stand Wizard": { + "description": "得了500分", + "descriptionComplete": "得了500分", + "descriptionFull": "在${LEVEL}中获得500分", + "descriptionFullComplete": "在${LEVEL}中获得了500分", + "name": "${LEVEL}的行家" + }, + "Mine Games": { + "description": "用地雷炸死3个坏蛋", + "descriptionComplete": "用地雷炸死了3个坏蛋", + "descriptionFull": "在${LEVEL}中用地雷炸死3个坏蛋", + "descriptionFullComplete": "在${LEVEL}中用地雷炸死了3个坏蛋", + "name": "地雷战" + }, + "Off You Go Then": { + "description": "把3个坏蛋扔出地图", + "descriptionComplete": "把3个坏蛋扔出地图", + "descriptionFull": "在${LEVEL}中把3个坏蛋扔出地图", + "descriptionFullComplete": "在${LEVEL}中把3个坏蛋扔出地图", + "name": "现在到你了" + }, + "Onslaught God": { + "description": "得5000分", + "descriptionComplete": "得了5000分", + "descriptionFull": "在${LEVEL}中获得5000分", + "descriptionFullComplete": "在${LEVEL}中获得了5000分", + "name": "${LEVEL}之神" + }, + "Onslaught Master": { + "description": "得500分", + "descriptionComplete": "得了500分", + "descriptionFull": "在${LEVEL}中得500分", + "descriptionFullComplete": "在${LEVEL} 中得到500分", + "name": "${LEVEL} 专家" + }, + "Onslaught Training Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在${LEVEL} 上打败所有敌人", + "descriptionFullComplete": "在${LEVEL} 上打败了所有敌人", + "name": "${LEVEL} 胜利" + }, + "Onslaught Wizard": { + "description": "得1000分", + "descriptionComplete": "得了1000分", + "descriptionFull": "在${LEVEL} 中得1000分", + "descriptionFullComplete": "在${LEVEL} 中得到了1000分", + "name": "${LEVEL} 之圣" + }, + "Precision Bombing": { + "description": "一个工具箱都不捡就取得胜利", + "descriptionComplete": "一个工具箱都不捡就取得了胜利", + "descriptionFull": "在${LEVEL} 中一个工具箱都不捡就取得胜利", + "descriptionFullComplete": "在${LEVEL} 中一个工具箱都不捡就取得了胜利", + "name": "精确爆炸" + }, + "Pro Boxer": { + "description": "不用任何炸弹就取胜", + "descriptionComplete": "不用任何炸弹就取胜了", + "descriptionFull": "在${LEVEL} 中不用炸弹就取胜", + "descriptionFullComplete": "在${LEVEL} 中不用炸弹就取胜了", + "name": "专业拳击手" + }, + "Pro Football Shutout": { + "description": "完爆坏人队(不让坏人队得分)", + "descriptionComplete": "完爆了坏人队(不让坏人队得分)", + "descriptionFull": "在${LEVEL} 中完爆坏人队(不让坏人队得分)", + "descriptionFullComplete": "在${LEVEL} 中完爆了坏人队(不让坏人队得分)", + "name": "无懈可击的${LEVEL}" + }, + "Pro Football Victory": { + "description": "赢得比赛", + "descriptionComplete": "赢得了比赛", + "descriptionFull": "赢得${LEVEL}", + "descriptionFullComplete": "赢得了${LEVEL}", + "name": "${LEVEL} 获胜" + }, + "Pro Onslaught Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在${LEVEL} 中打败所有坏蛋", + "descriptionFullComplete": "在${LEVEL} 中打败了所有坏蛋", + "name": "${LEVEL} 获胜" + }, + "Pro Runaround Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在${LEVEL} 中打败所有坏蛋", + "descriptionFullComplete": "在${LEVEL} 中打败了所有坏蛋", + "name": "${LEVEL} 取胜" + }, + "Rookie Football Shutout": { + "description": "完爆坏人队(不让坏人队得分)", + "descriptionComplete": "完爆了坏人队", + "descriptionFull": "在${LEVEL} 中完爆坏人队", + "descriptionFullComplete": "在${LEVEL} 中完爆了坏人队", + "name": "${LEVEL} 完胜" + }, + "Rookie Football Victory": { + "description": "赢得比赛", + "descriptionComplete": "赢得了比赛", + "descriptionFull": "赢得${LEVEL}", + "descriptionFullComplete": "赢得了${LEVEL}", + "name": "${LEVEL} 获胜" + }, + "Rookie Onslaught Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在${LEVEL} 中打败所有坏蛋", + "descriptionFullComplete": "在${LEVEL} 中打败了所有坏蛋", + "name": "${LEVEL} 获胜" + }, + "Runaround God": { + "description": "得2000分", + "descriptionComplete": "得了2000分", + "descriptionFull": "在${LEVEL} 中得到2000分", + "descriptionFullComplete": "在${LEVEL} 中得到了2000分", + "name": "${LEVEL} 之神" + }, + "Runaround Master": { + "description": "得500分", + "descriptionComplete": "得了500分", + "descriptionFull": "在${LEVEL} 中得到500分", + "descriptionFullComplete": "在${LEVEL} 中得到了500分", + "name": "${LEVEL} 大师" + }, + "Runaround Wizard": { + "description": "得1000分", + "descriptionComplete": "得了1000分", + "descriptionFull": "在${LEVEL} 得到1000分", + "descriptionFullComplete": "在${LEVEL} 中得到了1000分", + "name": "${LEVEL} 之圣" + }, + "Sharing is Caring": { + "descriptionFull": "成功和一个朋友分享游戏", + "descriptionFullComplete": "已经成功和一个朋友分享游戏", + "name": "独享不如分享" + }, + "Stayin' Alive": { + "description": "一直活着赢得比赛", + "descriptionComplete": "一直活着赢得了比赛", + "descriptionFull": "在${LEVEL} 中不死赢得比赛", + "descriptionFullComplete": "在${LEVEL} 中不死赢得了比赛", + "name": "不死之身" + }, + "Super Mega Punch": { + "description": "一拳造成100%的伤害", + "descriptionComplete": "一拳造成了100%的伤害", + "descriptionFull": "一拳造成了100%的伤害", + "descriptionFullComplete": "在${LEVEL}中一拳造成了100%的伤害", + "name": "无敌大拳头" + }, + "Super Punch": { + "description": "一拳造成50%的伤害", + "descriptionComplete": "一拳造成了50%的伤害", + "descriptionFull": "在${LEVEL}中一拳造成了50%的伤害", + "descriptionFullComplete": "在${LEVEL}中一拳造成50%的伤害", + "name": "大拳头" + }, + "TNT Terror": { + "description": "用TNT炸死6个坏蛋", + "descriptionComplete": "用TNT炸死了6个坏蛋", + "descriptionFull": "在${LEVEL}中用TNT炸死6个坏蛋", + "descriptionFullComplete": "在${LEVEL}中用TNT炸死了6个坏蛋", + "name": "恐怖TNT" + }, + "Team Player": { + "descriptionFull": "开始一个“团队”游戏(4+玩家)", + "descriptionFullComplete": "已经开始一个“团队”游戏(4+玩家)", + "name": "团队玩家" + }, + "The Great Wall": { + "description": "阻止所有坏蛋通过", + "descriptionComplete": "阻止了所有坏蛋", + "descriptionFull": "在${LEVEL}中阻止所有坏蛋通过", + "descriptionFullComplete": "在${LEVEL}中阻止了所有坏蛋", + "name": "铜墙铁壁" + }, + "The Wall": { + "description": "阻止所有坏蛋通过", + "descriptionComplete": "阻止了所有的坏蛋", + "descriptionFull": "在${LEVEL}中阻止所有坏蛋通过", + "descriptionFullComplete": "在${LEVEL}中阻止了所有的坏蛋", + "name": "铜墙铁壁" + }, + "Uber Football Shutout": { + "description": "不失分赢得比赛", + "descriptionComplete": "不失分赢得了比赛", + "descriptionFull": "在${LEVEL} 中不失分赢得比赛", + "descriptionFullComplete": "在${LEVEL} 中不失分赢得了比赛", + "name": "${LEVEL} 完胜" + }, + "Uber Football Victory": { + "description": "赢得比赛", + "descriptionComplete": "赢得比赛", + "descriptionFull": "在${LEVEL}中获胜", + "descriptionFullComplete": "在${LEVEL}中获胜", + "name": "${LEVEL} 获胜" + }, + "Uber Onslaught Victory": { + "description": "防御所有坏蛋", + "descriptionComplete": "防御了所有坏蛋", + "descriptionFull": "在 ${LEVEL} 中防御所有坏蛋", + "descriptionFullComplete": "在 ${LEVEL} 中防御了所有坏蛋", + "name": "${LEVEL} 获胜" + }, + "Uber Runaround Victory": { + "description": "打败所有敌人", + "descriptionComplete": "打败了所有敌人", + "descriptionFull": "在 ${LEVEL} 中打败所有敌人", + "descriptionFullComplete": "在 ${LEVEL} 中打败了所有敌人", + "name": "${LEVEL} 获胜" + } + }, + "achievementsRemainingText": "未完成成就:", + "achievementsText": "成就", + "achievementsUnavailableForOldSeasonsText": "抱歉,往届的成就细节不可用。", + "activatedText": "${THING} 已激活", + "addGameWindow": { + "getMoreGamesText": "获取更多游戏模式…", + "titleText": "添加比赛" + }, + "allowText": "允许", + "alreadySignedInText": "您的账号已在其他设备登录;\n请切换账号或者退出已登录的设备,\n然后再试一次", + "apiVersionErrorText": "无法加载模组${NAME};它的API版本为 ${VERSION_USED},我们需要 ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(“自动”仅在插入耳机时有效)", + "headRelativeVRAudioText": "头部相对VR音频", + "musicVolumeText": "音乐音量", + "soundVolumeText": "音效音量", + "soundtrackButtonText": "自定义背景音乐", + "soundtrackDescriptionText": "导入自定义背景音乐", + "titleText": "声音" + }, + "autoText": "自动", + "backText": "返回", + "banThisPlayerText": "禁掉该玩家", + "bestOfFinalText": "${COUNT}局决胜制最后得分", + "bestOfSeriesText": "${COUNT}决胜制:", + "bestRankText": "您的最佳是 #${RANK}", + "bestRatingText": "您的最高评价是 ${RATING}", + "bombBoldText": "炸弹", + "bombText": "炸弹", + "boostText": "加速", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME}在该应用程序自身中设置。", + "buttonText": "按钮", + "canWeDebugText": "您是否希望炸弹小分队向开发人员自动报告\n错误、崩溃和基本使用信息?\n\n数据中不包含任何个人信息,可有助于\n保持游戏零错误平稳运行。", + "cancelText": "取消", + "cantConfigureDeviceText": "抱歉,${DEVICE}不可配置。", + "challengeEndedText": "此挑战已经结束。", + "chatMuteText": "屏蔽消息", + "chatMutedText": "聊天静音", + "chatUnMuteText": "取消屏蔽消息", + "choosingPlayerText": "<选择玩家>", + "completeThisLevelToProceedText": "你需要先完成这一关", + "completionBonusText": "完成奖励", + "configControllersWindow": { + "configureControllersText": "手柄配置", + "configureKeyboard2Text": "键盘设置 P2", + "configureKeyboardText": "键盘配置", + "configureMobileText": "用移动设备作为控制器", + "configureTouchText": "触摸屏配置", + "ps3Text": "PS3手柄", + "titleText": "手柄", + "wiimotesText": "Wiimote", + "xbox360Text": "Xbox360手柄" + }, + "configGamepadSelectWindow": { + "androidNoteText": "注意:是否支持手柄取决于设备和安卓版本。", + "pressAnyButtonText": "按手柄上的任意按钮\n 您想要配置...", + "titleText": "手柄配置" + }, + "configGamepadWindow": { + "advancedText": "高级", + "advancedTitleText": "高级控制器设置", + "analogStickDeadZoneDescriptionText": "(释放摇杆角色出现“漂移”情况时调高)", + "analogStickDeadZoneText": "模拟摇杆盲区", + "appliesToAllText": "(适用于所有该类型手柄)", + "autoRecalibrateDescriptionText": "(角色未全速移动时有效)", + "autoRecalibrateText": "自动校准模拟摇杆", + "axisText": "轴", + "clearText": "清除", + "dpadText": "方向键", + "extraStartButtonText": "额外启动按钮", + "ifNothingHappensTryAnalogText": "如无反应,请尝试分配至模拟摇杆。", + "ifNothingHappensTryDpadText": "如无反应,请尝试分配至方向键。", + "ignoreCompletelyDescriptionText": "(避免这个控制器影响游戏或菜单)", + "ignoreCompletelyText": "已完全忽略", + "ignoredButton1Text": "已忽略 按键1", + "ignoredButton2Text": "已忽略 按键2", + "ignoredButton3Text": "已忽略 按键3", + "ignoredButton4Text": "已忽略 按键4", + "ignoredButtonDescriptionText": "(用于防止“主页”或“同步”按钮影响用户界面)", + "pressAnyAnalogTriggerText": "按任意模拟扳机...", + "pressAnyButtonOrDpadText": "按任意键或方向键...", + "pressAnyButtonText": "按任意键", + "pressLeftRightText": "按左或右", + "pressUpDownText": "按上或下", + "runButton1Text": "跑 按键1", + "runButton2Text": "跑 按键2", + "runTrigger1Text": "跑 扳机1", + "runTrigger2Text": "跑 扳机2", + "runTriggerDescriptionText": "(模拟扳机可实现变速奔跑)", + "secondHalfText": "用于设置显示为单一手柄的\n二合一手柄设备的\n第二部分。", + "secondaryEnableText": "启用", + "secondaryText": "从属手柄", + "startButtonActivatesDefaultDescriptionText": "(如果启动按钮更倾向为“菜单”按钮,则关闭此功能)", + "startButtonActivatesDefaultText": "启动按钮激活默认部件", + "titleText": "手柄设置", + "twoInOneSetupText": "二合一手柄设置", + "uiOnlyDescriptionText": "阻止这个控制器加入游戏", + "uiOnlyText": "限制菜单应用", + "unassignedButtonsRunText": "全部未分配按钮 跑", + "unsetText": "<未设置>", + "vrReorientButtonText": "虚拟按钮调整" + }, + "configKeyboardWindow": { + "configuringText": "配置${DEVICE}", + "keyboard2NoteText": "注:大多数键盘一次只能同时按几个按键,\n所以如果玩家另接一个单独的键盘,\n则两个键盘可帮助他们更好地玩游戏。\n请注意,即使在这种情况下,您也仍需\n为两个玩家分配独特的按键。" + }, + "configTouchscreenWindow": { + "actionControlScaleText": "动作控制量表", + "actionsText": "动作", + "buttonsText": "按钮", + "dragControlsText": "<拖动手柄重新定位他们>", + "joystickText": "游戏摇杆", + "movementControlScaleText": "移动控制量表", + "movementText": "移动", + "resetText": "重置", + "swipeControlsHiddenText": "隐藏滑动图标", + "swipeInfoText": "“滑动”式手柄是需要花点时间来适应的,但\n能不看手柄上的控制键玩游戏会更轻松。", + "swipeText": "滑动", + "titleText": "触摸屏配置" + }, + "configureItNowText": "立即配置?", + "configureText": "配置", + "connectMobileDevicesWindow": { + "amazonText": "亚马逊Appstore", + "appStoreText": "App Store", + "bestResultsText": "零延迟无线网可助你取得最佳成绩。要想降低无线网延迟,\n你可以关闭其他无线设备,\n或者在无线路由器附近玩,\n再或者将游戏主机连接以太网。", + "explanationText": "如果想把智能手机或平板设备作为控制器,请安装\n“${REMOTE_APP_NAME}”。通过无线网络,最多可\n以支持8个设备同时连接。最酷的是,这完全免费!", + "forAndroidText": "安卓", + "forIOSText": "苹果iOS", + "getItForText": "iOS 用户可从 ${REMOTE_APP_NAME} 取得炸弹小分队遥控器\nAndroid 使用者可以通过 Google Play 商店或者亚马逊应用商店下载", + "googlePlayText": "Google Play", + "titleText": "把移动设备用作为游戏手柄" + }, + "continuePurchaseText": "花 ${PRICE}继续?", + "continueText": "继续", + "controlsText": "控制键", + "coopSelectWindow": { + "activenessAllTimeInfoText": "不提供所有时间的排名。", + "activenessInfoText": "倍数随玩游戏天数增加,\n随未玩游戏天数减少。", + "activityText": "活动", + "campaignText": "比赛", + "challengesInfoText": "获取完成迷你游戏的奖励。\n\n每完成一项挑战\n奖励和难度都会增加,\n每挑战失败或放弃挑战一次,奖励和难度都会降低。", + "challengesText": "挑战", + "currentBestText": "当前最高分", + "customText": "自定义", + "entryFeeText": "参赛", + "forfeitConfirmText": "要放弃挑战吗?", + "forfeitNotAllowedYetText": "尚不能放弃此挑战。", + "forfeitText": "放弃", + "multipliersText": "倍数", + "nextChallengeText": "下一挑战", + "nextPlayText": "下一次游戏", + "ofTotalTimeText": "${TOTAL}", + "playNowText": "立即开玩", + "pointsText": "分", + "powerRankingFinishedSeasonUnrankedText": "(已结束赛季,未排名)", + "powerRankingNotInTopText": "(${NUMBER}名以外)", + "powerRankingPointsEqualsText": "${NUMBER}分", + "powerRankingPointsMultText": "(x ${NUMBER} 分)", + "powerRankingPointsText": "${NUMBER} 分", + "powerRankingPointsToRankedText": "(${CURRENT}分 已获得 共${REMAINING}分)", + "powerRankingText": "能力排位", + "prizesText": "奖励", + "proMultInfoText": "${PRO}升级的玩家\n获得${PERCENT}%的得分提速。", + "seeMoreText": "更多……", + "skipWaitText": "跳过等待", + "timeRemainingText": "剩余时间", + "toRankedText": "排名", + "totalText": "总计", + "tournamentInfoText": "与联赛中的其他玩家\n争夺高分。\n\n锦标赛时间结束时\n高分玩家将赢得奖励。", + "welcome1Text": "欢迎来到${LEAGUE}。你可以通过\n在锦标赛中赚取星级、达成成就及\n赢得冠军来提升你的联赛排名。", + "welcome2Text": "你还可参加很多相同活动来赢取点券。\n点券可用于解锁新的角色、地图和\n迷你游戏,或进入锦标赛,或更多用途", + "yourPowerRankingText": "你的能力排位:" + }, + "copyConfirmText": "复制到剪贴板", + "copyOfText": "${NAME} 复制", + "copyText": "copy", + "createEditPlayerText": "<创建/编辑玩家>", + "createText": "创建", + "creditsWindow": { + "additionalAudioArtIdeasText": "添补音频、初期原图和创意:${NAME}", + "additionalMusicFromText": "添补背景音乐:${NAME}", + "allMyFamilyText": "帮助进行游戏测试的我的所有好友和家人", + "codingGraphicsAudioText": "编码、图像和音频:${NAME}", + "languageTranslationsText": "语言翻译:", + "legalText": "法律:", + "publicDomainMusicViaText": "版权公有音乐:${NAME}", + "softwareBasedOnText": "该软件部分基于${NAME}的工作", + "songCreditText": "${TITLE}演唱:${PERFORMER}\n作曲:${COMPOSER},改编:${ARRANGER},发行:${PUBLISHER},\n由${SOURCE}提供", + "soundAndMusicText": "音乐和音效", + "soundsText": "音乐(${SOURCE}):", + "specialThanksText": "特别感谢", + "thanksEspeciallyToText": "尤其感谢 ${NAME}", + "titleText": "${APP_NAME}制作团队", + "whoeverInventedCoffeeText": "发明咖啡的人" + }, + "currentStandingText": "您目前的排名是#${RANK}", + "customizeText": "自定义...", + "deathsTallyText": "${COUNT}次死亡", + "deathsText": "死亡", + "debugText": "调试", + "debugWindow": { + "reloadBenchmarkBestResultsText": "注意:建议您在调试阶段将设置->画面->纹理设置为“高”。", + "runCPUBenchmarkText": "运行CPU基准程序", + "runGPUBenchmarkText": "运行GPU基准程序", + "runMediaReloadBenchmarkText": "运行媒体重载基准程序", + "runStressTestText": "运行压力测试", + "stressTestPlayerCountText": "玩家计数", + "stressTestPlaylistDescriptionText": "压力测试列表", + "stressTestPlaylistNameText": "列表名称", + "stressTestPlaylistTypeText": "列表类型", + "stressTestRoundDurationText": "回合时长", + "stressTestTitleText": "压力测试", + "titleText": "基准程序和压力测试", + "totalReloadTimeText": "总计重载时间:${TIME}(详见日志)" + }, + "defaultGameListNameText": "默认${PLAYMODE}列表", + "defaultNewGameListNameText": "我的${PLAYMODE}列表", + "deleteText": "删除", + "demoText": "演示", + "denyText": "拒绝", + "deprecatedText": "已弃用", + "desktopResText": "桌面分辨率", + "deviceAccountUpgradeText": "紧急警告:\n你正在使用本地账户登录! (${NAME})\n此账户会在未来升级中被删除!!\n~如果想保持账号,请升级到v2账户~", + "difficultyEasyText": "简单", + "difficultyHardOnlyText": "仅限困难模式", + "difficultyHardText": "困难", + "difficultyHardUnlockOnlyText": "该关卡只可解锁在困难模式下解锁。\n你认为自己拥有夺冠的实力吗!?!?", + "directBrowserToURLText": "请打开网页浏览器访问以下URL:", + "disableRemoteAppConnectionsText": "解除手柄应用链接", + "disableXInputDescriptionText": "允许使用4个以上的控制器但可能不会正常工作", + "disableXInputText": "禁用XInput", + "doneText": "完成", + "drawText": "平局", + "duplicateText": "复制", + "editGameListWindow": { + "addGameText": "添加\n比赛", + "cantOverwriteDefaultText": "不可以覆盖默认的比赛列表!", + "cantSaveAlreadyExistsText": "已存在与此名字相同的比赛列表!", + "cantSaveEmptyListText": "不可以保存空白的比赛列表!", + "editGameText": "编辑\n比赛", + "gameListText": "比赛列表", + "listNameText": "比赛列表名称", + "nameText": "名称", + "removeGameText": "删除\n比赛", + "saveText": "保存", + "titleText": "列表编辑器" + }, + "editProfileWindow": { + "accountProfileInfoText": "此特殊玩家档案,\n可能含有其中一个图标:\n\n${ICONS}\n\n基于您的登录平台以显示\n相关图标。", + "accountProfileText": "(账户资料)", + "availableText": "\"${NAME}\"可用。", + "changesNotAffectText": "注意:更改不会影响已经存在的比赛角色", + "characterText": "角色", + "checkingAvailabilityText": "正在检查\"${NAME}\"是否可用…", + "colorText": "颜色", + "getMoreCharactersText": "获取更多角色...", + "getMoreIconsText": "获取更多图标...", + "globalProfileInfoText": "全球玩家档案可使玩家拥有全世界唯一\n的名称。档案也包括自定义图标。", + "globalProfileText": "(全球档案)", + "highlightText": "副颜色", + "iconText": "图标", + "localProfileInfoText": "本地玩家档案不含图标,且玩家名称不具唯一性。\n升级至全球档案,以拥有唯一的游戏名称,并添加自定义图标。\n#警告:切勿使用随机到的名称,被使用的可能性极大。", + "localProfileText": "(本地档案)", + "nameDescriptionText": "角色名称", + "nameText": "名称", + "randomText": "随机", + "titleEditText": "编辑档案", + "titleNewText": "新建档案", + "unavailableText": "\"${NAME}\"不可用;请尝试另一名称。", + "upgradeProfileInfoText": "这可在全球范围内保存您的玩家名称,\n并可让您为自己的名称分配一个自定义图标。", + "upgradeToGlobalProfileText": "升级至全球档案" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "不能删除默认的背景音乐。", + "cantEditDefaultText": "不能编辑默认的背景音乐。请备份或是新建一个背景音乐列表。", + "cantOverwriteDefaultText": "不可以覆盖默认的背景音乐", + "cantSaveAlreadyExistsText": "这个名字的背景音乐已经存在!", + "defaultGameMusicText": "<默认游戏音乐>", + "defaultSoundtrackNameText": "默认自定义背景音乐", + "deleteConfirmText": "删除自定义背景音乐:\n\n'${NAME}'?", + "deleteText": "删除自定义\n背景音乐", + "duplicateText": "备份自定义\n背景音乐", + "editSoundtrackText": "自定义背景音乐编辑器", + "editText": "编辑自定义\n背景音乐", + "fetchingITunesText": "正在获得音乐应用播放列表", + "musicVolumeZeroWarning": "注意:现在音量为0", + "nameText": "名称", + "newSoundtrackNameText": "我的背景音乐${COUNT}", + "newSoundtrackText": "新的背景音乐:", + "newText": "创建背\n景音乐", + "selectAPlaylistText": "选择一个列表", + "selectASourceText": "音乐来源", + "testText": "测试", + "titleText": "自定义背景音乐", + "useDefaultGameMusicText": "默认游戏音乐", + "useITunesPlaylistText": "音乐应用播放列表", + "useMusicFileText": "音乐文件(mp3等)", + "useMusicFolderText": "音乐文件夹" + }, + "editText": "修改", + "endText": "结束", + "enjoyText": "尽情享用吧!", + "epicDescriptionFilterText": "史诗级慢动作 ${DESCRIPTION}。", + "epicNameFilterText": "史诗级${NAME}", + "errorAccessDeniedText": "访问被拒绝", + "errorDeviceTimeIncorrectText": "您设备的时间有 ${HOURS} 小时的误差。\n这会导致游戏出现问题。\n请检查您设备的时间和时区设置。", + "errorOutOfDiskSpaceText": "磁盘空间不足", + "errorSecureConnectionFailText": "无法建立安全的云链接,网络可能会连接失败", + "errorText": "错误", + "errorUnknownText": "未知错误", + "exitGameText": "退出${APP_NAME}?", + "exportSuccessText": "退出'${NAME}'", + "externalStorageText": "外部存储器", + "failText": "失败", + "fatalErrorText": "哎呀,有些档案遗失或损坏了。\n请尝试重新安装游戏,或者\n联系 ${EMAIL} 寻求帮助", + "fileSelectorWindow": { + "titleFileFolderText": "选择一个文件或文件夹", + "titleFileText": "选择一个文件", + "titleFolderText": "选择一个文件夹", + "useThisFolderButtonText": "使用此文件夹" + }, + "filterText": "过滤器", + "finalScoreText": "最后得分", + "finalScoresText": "最后得分", + "finalTimeText": "最终时间", + "finishingInstallText": "安装即将完成...", + "fireTVRemoteWarningText": "* 为获得更好的游戏体验,请使用\n游戏手柄或在您的手机和\n平板电脑上安装\n'${REMOTE_APP_NAME}'。", + "firstToFinalText": "${COUNT}局自由混战赛最后得分", + "firstToSeriesText": "${COUNT}局自由混战赛", + "fiveKillText": "五连杀!!!", + "flawlessWaveText": "完美的一波!", + "fourKillText": "四连杀!!!", + "friendScoresUnavailableText": "无法查看好友的得分。", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "最高得分玩家数:${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "您不能删除默认的比赛列表!", + "cantEditDefaultText": "不能编辑默认的比赛列表!复制或者新建一个。", + "cantShareDefaultText": "你不能分享默认列表", + "deleteConfirmText": "是否删除“${LIST}”?", + "deleteText": "删除比\n赛列表", + "duplicateText": "复制比\n赛列表", + "editText": "编辑比\n赛列表", + "gameListText": "比赛列表", + "newText": "新建比\n赛列表", + "showTutorialText": "显示教程", + "shuffleGameOrderText": "随机比赛模式", + "titleText": "自定义${TYPE}列表" + }, + "gameSettingsWindow": { + "addGameText": "添加比赛" + }, + "gamesToText": "${WINCOUNT}比${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "请记住:如果你有足够多的游戏手柄,\n派对中的任意设备可允许多个玩家同时游戏。", + "aboutDescriptionText": "使用这些选项卡来组织一场派对。\n\n通过派对,你可以和好友在不同的设备上\n一起玩游戏和比赛。\n\n使用手柄右上角的${PARTY}按钮\n来发起派对聊天和互动。\n(在菜单中时按${BUTTON})", + "aboutText": "关于", + "addressFetchErrorText": "<获取地址出错>", + "appInviteInfoText": "邀请好友一起玩BombSquad,新玩家可获得 ${COUNT}免费点券。\n每成功邀请到一位好友,您可获得${YOU_COUNT}点券。", + "appInviteMessageText": "${NAME} 在${APP_NAME}中送给了您${COUNT} 点券", + "appInviteSendACodeText": "向他们发送一个代码", + "appInviteTitleText": "${APP_NAME} App 邀请码", + "bluetoothAndroidSupportText": "(适用于任何支持蓝牙功能的安卓设备)", + "bluetoothDescriptionText": "通过蓝牙来创建或加入比赛", + "bluetoothHostText": "通过蓝牙来创建游戏", + "bluetoothJoinText": "通过蓝牙来加入游戏", + "bluetoothText": "蓝牙", + "checkingText": "检查中...", + "copyCodeConfirmText": "代码已复制到粘贴板。", + "copyCodeText": "复制代码", + "dedicatedServerInfoText": "建立一个专用服务器来获得最佳效果,详情见 bombsquadgame.com/server 哦!", + "disconnectClientsText": "这将使派对中的${COUNT}位玩家\n断开连接。是否确定?", + "earnTicketsForRecommendingAmountText": "如果您的朋友们玩了这款游戏,他们将会收到 ${COUNT} 点券\n(每个畅游的朋友将让你收到 ${YOU_COUNT}点券)", + "earnTicketsForRecommendingText": "分享游戏来\n获取免费点券...", + "emailItText": "通过电子邮件发送", + "favoritesSaveText": "另存为收藏", + "favoritesText": "收藏", + "freeCloudServerAvailableMinutesText": "下一次免费云服务器将在 ${MINUTES} 分钟后可用。", + "freeCloudServerAvailableNowText": "当前免费云服务器可用!", + "freeCloudServerNotAvailableText": "无免费云服务器可用。", + "friendHasSentPromoCodeText": "从 ${NAME} 中获取 ${COUNT} 张 ${APP_NAME} 点券", + "friendPromoCodeAwardText": "每使用一次,你可收到${COUNT}张点券。", + "friendPromoCodeExpireText": "代码将在 ${EXPIRE_HOURS} 小时后失效,代码仅适用于新玩家。", + "friendPromoCodeInstructionsText": "要使用代码,可打开 ${APP_NAME},按\"设置->高级->输入促销代码\"操作。\n所有支持平台的下载链接见 bombsquadgame.com。", + "friendPromoCodeRedeemLongText": "达到${MAX_USES}人后,就不可获得${COUNT}免费点券。(防止玩家用来作弊)", + "friendPromoCodeRedeemShortText": "可在游戏中兑换${COUNT}免费点券。", + "friendPromoCodeWhereToEnterText": "(在\"设置->高级->输入促销代码\"中)", + "getFriendInviteCodeText": "获取好友邀请码", + "googlePlayDescriptionText": "邀请Google Play玩家来加入你的派对", + "googlePlayInviteText": "邀请", + "googlePlayReInviteText": "如果你发出一个新邀请,\n则你的派对中的${COUNT}位Google Play玩家将断开连接。\n在发出的新邀请中再次邀请他们,让他们重回派对。", + "googlePlaySeeInvitesText": "查看邀请", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(仅针对 Google Play 设备)", + "hostPublicPartyDescriptionText": "创建一个公开派对", + "hostingUnavailableText": "主机不可用", + "inDevelopmentWarningText": "注意:\n\n联网模式是一项新的并且还在开发特性,\n目前强烈建议所有玩家在同一个\n无线局域网下游戏。", + "internetText": "在线游戏", + "inviteAFriendText": "好友还未加入该游戏?邀请他们\n一起玩,新玩家可获得${COUNT}张免费点券。", + "inviteFriendsText": "邀请朋友", + "joinPublicPartyDescriptionText": "加入一个公开派对", + "localNetworkDescriptionText": "加入一个局域网派对(通过wifi,蓝牙,etc等)", + "localNetworkText": "本地网络", + "makePartyPrivateText": "将我的派对变成私人派对", + "makePartyPublicText": "将我的派对变成公开派对", + "manualAddressText": "地址", + "manualConnectText": "连接", + "manualDescriptionText": "加入派对,地址:", + "manualJoinSectionText": "使用地址加入", + "manualJoinableFromInternetText": "是否可从互联网连接?:", + "manualJoinableNoWithAsteriskText": "否*", + "manualJoinableYesText": "是", + "manualRouterForwardingText": "* 若要解决此问题,请尝试将您的路由器设置为将UDP端口${PORT}转发到你的本地地址(地址一般是192.168.*.1)", + "manualText": "手动", + "manualYourAddressFromInternetText": "互联网地址:", + "manualYourLocalAddressText": "本地地址:", + "nearbyText": "附近", + "noConnectionText": "<无连接>", + "otherVersionsText": "(其他版本)", + "partyCodeText": "派对代码", + "partyInviteAcceptText": "接受", + "partyInviteDeclineText": "拒绝", + "partyInviteGooglePlayExtraText": "(查看'Gather'窗口中的'Google Play'选项卡)", + "partyInviteIgnoreText": "忽略", + "partyInviteText": "${NAME}已邀请\n你加入他们的派对!", + "partyNameText": "派对名称", + "partyServerRunningText": "您的派对服务器正在运行。", + "partySizeText": "派对规模大小", + "partyStatusCheckingText": "检查中", + "partyStatusJoinableText": "你的派对现在可以从互联网上加入了", + "partyStatusNoConnectionText": "无法连接到服务器", + "partyStatusNotJoinableText": "你的派对不能从互联网上加入", + "partyStatusNotPublicText": "你的派对是私人的", + "pingText": "延迟", + "portText": "端口", + "privatePartyCloudDescriptionText": "私有方在专用的云服务器上运行;无需路由器配置", + "privatePartyHostText": "创建一个私人派对", + "privatePartyJoinText": "加入一个公开派对", + "privateText": "私人", + "publicHostRouterConfigText": "这可能需要配置路由器进行端口转发,为了更简单的选择,请使用私人派对", + "publicText": "公共", + "requestingAPromoCodeText": "正在请求代码…", + "sendDirectInvitesText": "直接邀请", + "shareThisCodeWithFriendsText": "与好友分享此代码:", + "showMyAddressText": "显示我的地址", + "startHostingPaidText": "创建需花费 ${COST}", + "startHostingText": "创建", + "startStopHostingMinutesText": "你还可以使用${MINUTES}分钟的免费服务器", + "stopHostingText": "停止主机", + "titleText": "多人游戏", + "wifiDirectDescriptionBottomText": "如果所有设备都设有 Wi-Fi Direct 面板,那他们应该可以使用通过它来找到彼此,\n然后相互连接。一旦所有设备都相互连接上了,你就可以通过“本地网络”选项卡\n在此组织派对,常规的无线局域网也是一样。\n\n如要取得最佳效果,Wi-Fi Direct 创建者也应是${APP_NAME} 派对的创建者", + "wifiDirectDescriptionTopText": "无需无线网络即可直接\n通过Wi-Fi Direct连接安卓设备。对于安装了Android 4.2或更高版本操作系统的设备效果更好。\n\n要使用该功能,可打开无线网络连接设置,然后在菜单中寻找'Wi-Fi Direct'。", + "wifiDirectOpenWiFiSettingsText": "打开无线网络连接设置", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(所有平台之间运作)", + "worksWithGooglePlayDevicesText": "(适用于运行Google Play(安卓)版游戏的设备)", + "youHaveBeenSentAPromoCodeText": "您已送出一个 ${APP_NAME} 促销代码:" + }, + "getTicketsWindow": { + "freeText": "免费!", + "freeTicketsText": "免费点券", + "inProgressText": "一个交易正在进行;请稍后再试。", + "purchasesRestoredText": "购买恢复。", + "receivedTicketsText": "获得${COUNT}点券!", + "restorePurchasesText": "恢复购买", + "ticketDoublerText": "点券倍增器", + "ticketPack1Text": "小型点券包", + "ticketPack2Text": "中等点券包", + "ticketPack3Text": "大型点券包", + "ticketPack4Text": "巨型点券包", + "ticketPack5Text": "猛犸象点券包", + "ticketPack6Text": "终极点券包", + "ticketsFromASponsorText": "观看广告\n白嫖${COUNT}个点券", + "ticketsText": "${COUNT}点券", + "titleText": "获得点券", + "unavailableLinkAccountText": "对不起,该平台上不可进行购买。\n您可将此帐户链接到另一个\n平台,以进行购买。", + "unavailableTemporarilyText": "该选项当前不可用;请稍后再试。", + "unavailableText": "对不起,该选项不可用。", + "versionTooOldText": "对不起,这个版本的游戏太旧了;请更新到新版本。", + "youHaveShortText": "您拥有${COUNT}", + "youHaveText": "你拥有${COUNT}点券" + }, + "googleMultiplayerDiscontinuedText": "抱歉,Google的多人游戏服务已不可用。\n我将尽快更换新的替代服务。\n在此之前,请尝试其他连接方法。\n-Eric", + "googlePlayPurchasesNotAvailableText": "Google商店购买不可用!\n请安装谷歌框架或更新Google服务。", + "googlePlayServicesNotAvailableText": "Google Play服务不可用\n某些功能可能会被禁用", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "总是", + "fullScreenCmdText": "全屏显示(Cmd+F)", + "fullScreenCtrlText": "全屏(Ctrl-F)", + "gammaText": "Gamma", + "highText": "高", + "higherText": "极高", + "lowText": "低", + "mediumText": "中", + "neverText": "关", + "resolutionText": "分辨率", + "showFPSText": "显示FPS", + "texturesText": "材质质量", + "titleText": "图像质量", + "tvBorderText": "电视边缘", + "verticalSyncText": "垂直同步", + "visualsText": "视觉" + }, + "helpWindow": { + "bombInfoText": "炸弹\n比拳头伤害高,但也能把自己送上西天。\n给你个建议:等引线快烧完的时候\n再把炸弹扔向敌人。", + "canHelpText": "${APP_NAME}可以帮助。", + "controllersInfoText": "你可以和好友在同一网络下玩${APP_NAME},或者\n如果你有足够多的手柄,那也可以在同一个设备上游戏。\n${APP_NAME}支持各种选择;你甚至可以通过免费的'${REMOTE_APP_NAME}'\n用手机作为游戏手柄。\n更多信息,请参见设置->手柄。", + "controllersInfoTextRemoteOnly": "你可以通过网络与你的朋友们一起游玩${APP_NAME}\n或者你可以使用${REMOTE_APP_NAME}\n它会将你的手机作为手柄在同一个设备上与你的朋友一起游玩", + "controllersText": "手柄", + "controlsSubtitleText": "你的友好的${APP_NAME}角色具有几个基本动作:", + "controlsText": "控制键", + "devicesInfoText": "VR版${APP_NAME}可与\n普通版本联网游戏,所以掏出你所有的手机、平板电脑\n和电脑,大玩一场吧。你甚至还可以将\n普通版本的游戏连接至VR版,\n让游戏外的人也能看你玩。", + "devicesText": "设备", + "friendsGoodText": "这对你而言都是好事。和三五好友一起玩${APP_NAME}最有趣了,\n最多可以支持8个玩家一起玩,进入", + "friendsText": "好友", + "jumpInfoText": "跳跃\n跳跃可以跳过较窄的缝隙,\n或是把炸弹扔的更远,\n或是表达你难以掩盖的喜悦之情。", + "orPunchingSomethingText": "或用拳猛击敌人,将它砸下悬崖,然后在它下落的途中用粘性炸弹炸掉它。", + "pickUpInfoText": "拾起\n你可以拾起旗子,敌人,\n还有所有没固定在地上的东西,\n然后,再扔出去吧。", + "powerupBombDescriptionText": "将炸弹最大投掷数量\n由一个提升为三个", + "powerupBombNameText": "三连炸弹", + "powerupCurseDescriptionText": "你可能想要避开这些。\n…或者你想试试看?", + "powerupCurseNameText": "诅咒", + "powerupHealthDescriptionText": "完全回血!\n想不到吧!", + "powerupHealthNameText": "医疗包", + "powerupIceBombsDescriptionText": "威力比普通炸弹小,\n但能将你的敌人冻住,\n让它们变得特别脆弱。", + "powerupIceBombsNameText": "冰冻弹", + "powerupImpactBombsDescriptionText": "威力比普通炸弹稍弱,\n但碰到外物后就会爆炸。", + "powerupImpactBombsNameText": "触感弹", + "powerupLandMinesDescriptionText": "大特价,一包3个。\n居家旅行,防守阵地的不二选择,\n还可以阻止那些跑的飞快的敌人。", + "powerupLandMinesNameText": "地雷", + "powerupPunchDescriptionText": "让您变成专业拳击手\n更高!更快!更强!", + "powerupPunchNameText": "拳击手套", + "powerupShieldDescriptionText": "能吸收一些伤害,\n关键时刻可能会有用。", + "powerupShieldNameText": "能量护盾", + "powerupStickyBombsDescriptionText": "黏在任何碰到的东西上,\n然后就等着看烟花吧。", + "powerupStickyBombsNameText": "黏黏炸弹", + "powerupsSubtitleText": "当然,没有道具的游戏很难通关:", + "powerupsText": "道具", + "punchInfoText": "拳击\n跑得越快,拳击的伤害\n越高。所以像疯子一样\n旋转跳跃吧!", + "runInfoText": "冲刺\n按任意键冲刺,如果你用手柄操作将会容易许多。\n冲刺跑的虽快,但会造成转向困难。且冲且珍惜。", + "someDaysText": "有些时候你只是想挥拳猛击某些东西,或把什么东西给炸飞。", + "titleText": "${APP_NAME}帮助", + "toGetTheMostText": "要想最痛快地玩这个游戏,你需要:", + "welcomeText": "欢迎来到${APP_NAME}!" + }, + "holdAnyButtonText": "<按住任意按钮>", + "holdAnyKeyText": "<按住任何键>", + "hostIsNavigatingMenusText": "- ${HOST}像皇帝一样控制主菜单 -", + "importPlaylistCodeInstructionsText": "用代码来导入列表", + "importPlaylistSuccessText": "成功导入${TYPE}列表 '${NAME}'", + "importText": "导入", + "importingText": "导入中", + "inGameClippedNameText": "名字会是\n\"${NAME}\"", + "installDiskSpaceErrorText": "错误:无法完成安装。\n您的设备可能是空间不足。\n腾出一些空间,然后重试。", + "internal": { + "arrowsToExitListText": "按${LEFT}或${RIGHT}退出列表", + "buttonText": "按钮", + "cantKickHostError": "你不能踢房主啊喂!", + "chatBlockedText": "玩家 ${NAME} 被禁言 ${TIME} 秒.", + "connectedToGameText": "加入 '${NAME}'", + "connectedToPartyText": "加入${NAME}的房间!", + "connectingToPartyText": "正在连接...", + "connectionFailedHostAlreadyInPartyText": "连接失败;创建者正在另一派对中。", + "connectionFailedPartyFullText": "连接出错:房间满员了…", + "connectionFailedText": "连接失败。", + "connectionFailedVersionMismatchText": "连接失败;创建者正在运行不同版本的游戏。\n请确保你们都安装了最新版本,然后再试一次。", + "connectionRejectedText": "连接被拒绝。", + "controllerConnectedText": "${CONTROLLER}已连接。", + "controllerDetectedText": "检测到1个手柄。", + "controllerDisconnectedText": "${CONTROLLER}断开连接。", + "controllerDisconnectedTryAgainText": "${CONTROLLER}断开连接。请尝试重新连接。", + "controllerForMenusOnlyText": "此控制器无法在游戏中使用", + "controllerReconnectedText": "${CONTROLLER}重新连接。", + "controllersConnectedText": "已连接${COUNT}个手柄。", + "controllersDetectedText": "检测到${COUNT}个手柄。", + "controllersDisconnectedText": "${COUNT}个手柄断开连接。", + "corruptFileText": "检测到已损坏的文件。请尝试重新安装,或发送电子邮件至${EMAIL}", + "errorPlayingMusicText": "播放音乐错误:${MUSIC}", + "errorResettingAchievementsText": "无法重置在线成就;请稍后再试。", + "hasMenuControlText": "${NAME}目前拥有菜单的控制权限。", + "incompatibleNewerVersionHostText": "房主运行着最新版本游戏。\n请更新您的游戏版本然后重试。", + "incompatibleVersionHostText": "创建者正在运行不同版本的游戏。\n请确保你们都安装了最新版本,然后再试一次。", + "incompatibleVersionPlayerText": "${NAME}正在运行不同版本的游戏。\n请确保你们都安装了最新版本,然后再试一次。", + "invalidAddressErrorText": "错误:无效的地址。", + "invalidNameErrorText": "错误:无效的名字", + "invalidPortErrorText": "错误:无效端口", + "invitationSentText": "已发出邀请。", + "invitationsSentText": "已发出${COUNT}个邀请。", + "joinedPartyInstructionsText": "有人加入了你的派对\n去“开始战斗”中开始一场游戏吧", + "keyboardText": "键盘", + "kickIdlePlayersKickedText": "${NAME}空闲,将其踢出。", + "kickIdlePlayersWarning1Text": "如果${NAME}仍然空闲,则将在${COUNT}秒后被踢出。", + "kickIdlePlayersWarning2Text": "(您可以在设置 ->高级中将其关闭)", + "leftGameText": "离开 '${NAME}'.", + "leftPartyText": "离开${NAME}的游戏", + "noMusicFilesInFolderText": "文件夹内没有音乐文件。", + "playerJoinedPartyText": "${NAME}加入了游戏!", + "playerLeftPartyText": "${NAME}离开了游戏。", + "rejectingInviteAlreadyInPartyText": "拒绝邀请(已经在派对中)。", + "serverRestartingText": "服务器自动重启中,请重新加入..", + "serverShuttingDownText": "服务器正在关机…", + "signInErrorText": "登陆出错啦~", + "signInNoConnectionText": "哎呀,无法登陆。(网络连接有故障?)", + "telnetAccessDeniedText": "错误:用户未得到telnet访问授权。", + "timeOutText": "(将在${TIME}秒内超出时限)", + "touchScreenJoinWarningText": "您已以触摸屏方式加入。\n如果这是一个错误,点击“菜单->离开游戏菜单”。", + "touchScreenText": "触摸屏", + "unableToResolveHostText": "错误:房主有问题", + "unavailableNoConnectionText": "哎呀,这个用不了呢(网络连接故障?)", + "vrOrientationResetCardboardText": "重置VR定位。\n您需使用外部手柄来玩该游戏。", + "vrOrientationResetText": "VR定位重置。", + "willTimeOutText": "(若空闲则会超出时限)" + }, + "jumpBoldText": "跳", + "jumpText": "跳", + "keepText": "举起", + "keepTheseSettingsText": "要保留您的新设置吗?", + "keyboardChangeInstructionsText": "双击空格以更改控制器", + "keyboardNoOthersAvailableText": "无其他可用的控制器", + "keyboardSwitchText": "切换控制器为\"${NAME}\"", + "kickOccurredText": "踢出 ${NAME}", + "kickQuestionText": "你们说要不要踢 ${NAME}? 呢…", + "kickText": "踢出", + "kickVoteCantKickAdminsText": "无法踢出管理员.", + "kickVoteCantKickSelfText": "您不能踢出您自己.", + "kickVoteFailedNotEnoughVotersText": "没有足够玩家投票", + "kickVoteFailedText": "踢出玩家投票未成功", + "kickVoteStartedText": "踢出${NAME}的投票已被发起", + "kickVoteText": "投票踢出玩家", + "kickVotingDisabledText": "投票踢出已被禁用.", + "kickWithChatText": "在聊天框中输入 ${YES} 来同意,输入 ${NO} 来拒绝(输入2来弃权)", + "killsTallyText": "${COUNT}次击杀", + "killsText": "击杀数", + "kioskWindow": { + "easyText": "简单", + "epicModeText": "史诗模式", + "fullMenuText": "完整菜单", + "hardText": "困难", + "mediumText": "中等", + "singlePlayerExamplesText": "单人游戏/合作模式样例", + "versusExamplesText": "对战模式样例" + }, + "languageSetText": "现在的语言是 \"${LANGUAGE}\"。", + "lapNumberText": "圈数:${CURRENT}/${TOTAL}", + "lastGamesText": "(最后${COUNT}局比赛)", + "leaderboardsText": "排行榜", + "league": { + "allTimeText": "所有时间", + "currentSeasonText": "当前赛季(${NUMBER})", + "leagueFullText": "${NAME}联赛", + "leagueRankText": "联赛排名", + "leagueText": "联赛", + "rankInLeagueText": "#${RANK}、${NAME}联赛${SUFFIX}", + "seasonEndedDaysAgoText": "赛季已于${NUMBER}天前结束。", + "seasonEndsDaysText": "赛季将于${NUMBER}天后结束。", + "seasonEndsHoursText": "赛季将于${NUMBER}小时后结束。", + "seasonEndsMinutesText": "赛季将于${NUMBER}分钟后结束。", + "seasonText": "第${NUMBER}赛季", + "tournamentLeagueText": "你一定要到${NAME}联赛参加这项赛事。", + "trophyCountsResetText": "奖杯计数将在下个赛季重置。" + }, + "levelBestScoresText": "在 ${LEVEL}中的最佳成绩", + "levelBestTimesText": "在 ${LEVEL}中的最佳时间", + "levelFastestTimesText": "${LEVEL}最短时间", + "levelHighestScoresText": "${LEVEL}最高得分", + "levelIsLockedText": "${LEVEL}处于锁定状态。", + "levelMustBeCompletedFirstText": "必须先完成${LEVEL}。", + "levelText": "${NUMBER}关卡", + "levelUnlockedText": "关卡解锁!", + "livesBonusText": "生命奖励", + "loadingText": "载入中", + "loadingTryAgainText": "加载中请稍后再试", + "macControllerSubsystemBothText": "均可(不推荐)", + "macControllerSubsystemClassicText": "经典", + "macControllerSubsystemDescriptionText": "(如果你的手柄无法工作,请尝试更改此项)", + "macControllerSubsystemMFiNoteText": "已检测到 Made-for-iOS/Mac 手柄;\n你需要在 设置->手柄 中启用该设备", + "macControllerSubsystemMFiText": "Made-for-iOS/Mac", + "macControllerSubsystemTitleText": "手柄支持", + "mainMenu": { + "creditsText": "制作团队", + "demoMenuText": "演示菜单", + "endGameText": "结束", + "endTestText": "结束测试", + "exitGameText": "退出", + "exitToMenuText": "退出到菜单", + "howToPlayText": "帮助", + "justPlayerText": "(仅${NAME})", + "leaveGameText": "离开游戏", + "leavePartyConfirmText": "确实要离开吗?", + "leavePartyText": "离开派对", + "quitText": "离开游戏", + "resumeText": "回到游戏", + "settingsText": "设置" + }, + "makeItSoText": "应用", + "mapSelectGetMoreMapsText": "获取更多地图…", + "mapSelectText": "选择…", + "mapSelectTitleText": "${GAME}地图", + "mapText": "地图", + "maxConnectionsText": "最大连接数", + "maxPartySizeText": "最大派对规模", + "maxPlayersText": "最多人数", + "merchText": "来买周边吧~", + "modeArcadeText": "街机模式", + "modeClassicText": "经典模式", + "modeDemoText": "演示模式", + "mostValuablePlayerText": "最具价值玩家", + "mostViolatedPlayerText": "最遭暴力玩家", + "mostViolentPlayerText": "最暴力玩家", + "moveText": "移动", + "multiKillText": "${COUNT}连杀!!", + "multiPlayerCountText": "${COUNT}名玩家", + "mustInviteFriendsText": "注意:你必须在“${GATHER}”面板中邀请好友,\n或连接多个\n手柄,和好友一起游戏。", + "nameBetrayedText": "${NAME}背叛了${VICTIM}", + "nameDiedText": "${NAME}挂了。", + "nameKilledText": "${NAME}把${VICTIM}杀了", + "nameNotEmptyText": "名字不能为空", + "nameScoresText": "${NAME}得分咯!", + "nameSuicideKidFriendlyText": "${NAME}意外挂了。", + "nameSuicideText": "${NAME}自杀了。", + "nameText": "名称", + "nativeText": "本机", + "newPersonalBestText": "新个人记录!", + "newTestBuildAvailableText": "更新的测试版可供下载了!(${VERSION}生成${BUILD})。\n到${ADDRESS}获取", + "newText": "新建", + "newVersionAvailableText": "更新版本的 ${APP_NAME} 可供下载了! 版本号(${VERSION})", + "nextAchievementsText": "下一个成就:", + "nextLevelText": "下一关", + "noAchievementsRemainingText": "- '无'", + "noContinuesText": "(无可继续)", + "noExternalStorageErrorText": "该设备上未发现外部存储器", + "noGameCircleText": "错误:未登入GameCircle", + "noProfilesErrorText": "您没有玩家档案,所以还得忍受“${NAME}”这个名字。\n进入设置->玩家档案,为自己创建档案。", + "noScoresYetText": "还未有得分记录。", + "noThanksText": "不,谢谢", + "noTournamentsInTestBuildText": "温馨提示:测试版的锦标赛分数不能计入锦标赛哦!", + "noValidMapsErrorText": "该比赛类型中未发现有效地图。", + "notEnoughPlayersRemainingText": "剩余玩家不足,退出并开始新游戏。", + "notEnoughPlayersText": "你需要至少${COUNT}名玩家来开始这场比赛!", + "notNowText": "不是现在", + "notSignedInErrorText": "您必须登录到您的帐户。", + "notSignedInGooglePlayErrorText": "您必须通过Google Play登录。", + "notSignedInText": "(未登录)", + "notUsingAccountText": "注意:已忽略${SERVICE}账户的自动登录\n如果你想用它登录,前往“账户->使用${SERVICE}登录”~", + "nothingIsSelectedErrorText": "未选择任何内容!", + "numberText": "#${NUMBER}", + "offText": "关", + "okText": "好的", + "onText": "开", + "oneMomentText": "请稍候...", + "onslaughtRespawnText": "${PLAYER}将于第${WAVE}波后复活", + "orText": "${A}或${B}", + "otherText": "其他。。。", + "outOfText": "(在${ALL}名玩家中位列#${RANK})", + "ownFlagAtYourBaseWarning": "你的旗帜必须在\n你自己的基地上才能得分!", + "packageModsEnabledErrorText": "启用本地程序包修改时,联网对战模式不可用(参见设置->高级)", + "partyWindow": { + "chatMessageText": "聊天消息", + "emptyText": "你的派对为空", + "hostText": "(创建者)", + "sendText": "发送", + "titleText": "你的派对" + }, + "pausedByHostText": "(创建者已暂停)", + "perfectWaveText": "完美的一波!", + "pickUpText": "捡起", + "playModes": { + "coopText": "合作", + "freeForAllText": "混战模式", + "multiTeamText": "多团队", + "singlePlayerCoopText": "单人游戏/合作模式", + "teamsText": "团队对抗" + }, + "playText": "开始战斗", + "playWindow": { + "coopText": "合作模式", + "freeForAllText": "大乱斗", + "oneToFourPlayersText": "适合1~4名玩家", + "teamsText": "团队对抗", + "titleText": "开始战斗", + "twoToEightPlayersText": "适合2~8名玩家" + }, + "playerCountAbbreviatedText": "${COUNT}名玩家", + "playerDelayedJoinText": "${PLAYER}将在下一回合开始时进入。", + "playerInfoText": "玩家资料", + "playerLeftText": "${PLAYER}离开了游戏。", + "playerLimitReachedText": "已达到${COUNT}名玩家上限;其他玩家不允许加入。", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "您无法删除您的帐户资料。", + "deleteButtonText": "删除\n档案", + "deleteConfirmText": "删除'${PROFILE}'?", + "editButtonText": "编辑\n档案", + "explanationText": "(为这个账号定制玩家名称和外观)", + "newButtonText": "创建\n档案", + "titleText": "玩家档案" + }, + "playerText": "玩家", + "playlistNoValidGamesErrorText": "此列表未包含有效的已解锁游戏。", + "playlistNotFoundText": "找不到列表", + "playlistText": "列表", + "playlistsText": "列表", + "pleaseRateText": "如果你喜欢 ${APP_NAME},请考虑花一点时间\n来评价一下它或为它写一篇评论。这将为我们提供\n有用的反馈建议,为游戏的未来开发给予支持。\n\n感谢您!\n-eric", + "pleaseWaitText": "请稍等...", + "pluginClassLoadErrorText": "加载'${PLUGIN}'插件时出错了耶: ${ERROR}", + "pluginInitErrorText": "初始化'${PLUGIN}'插件失败了啦: ${ERROR}", + "pluginSettingsText": "插件设置喵", + "pluginsAutoEnableNewText": "自动启用新插件", + "pluginsDetectedText": "新插件安装成功,请重启游戏或在设置中设置它们~", + "pluginsDisableAllText": "禁用所有插件", + "pluginsEnableAllText": "启用所有插件", + "pluginsRemovedText": "有${NUM}个插件被删除了...", + "pluginsText": "插件", + "practiceText": "练习", + "pressAnyButtonPlayAgainText": "按任意按钮再玩一次...", + "pressAnyButtonText": "按任意按钮继续...", + "pressAnyButtonToJoinText": "按任意按钮加入...", + "pressAnyKeyButtonPlayAgainText": "按任意键/按钮再玩一次...", + "pressAnyKeyButtonText": "按任意键/按钮继续......", + "pressAnyKeyText": "按任意键...", + "pressJumpToFlyText": "** 按连续跳跃以腾空 **", + "pressPunchToJoinText": "按下“出拳”来加入", + "pressToOverrideCharacterText": "按${BUTTONS}更换您的角色", + "pressToSelectProfileText": "按${BUTTONS}选择一个玩家", + "pressToSelectTeamText": "按下${BUTTONS}来选择一支队伍", + "promoCodeWindow": { + "codeText": "代码", + "codeTextDescription": "促销代码", + "enterText": "输入" + }, + "promoSubmitErrorText": "提交代码时出错; 检查您的互联网连接", + "ps3ControllersWindow": { + "macInstructionsText": "关闭PS3背面的电源开关,确保\n您的Mac电脑上启用了蓝牙,然后通过USB连接线将您的手柄连接到\n您的Mac电脑上使其配对。之后,您\n就可以使用该手柄上的主页按钮以有线(USB)或无线(蓝牙)模式\n将其连接到您的Mac电脑上。\n\n在一些Mac电脑上配对时可能会提示您输入密码。\n在此情况下,请参阅一下教程或搜索谷歌寻求帮助。\n\n\n\n\n无线连接的PS3手柄应该出现在\n系统偏好设置->蓝牙中的设备列表中。当您想要再次用你的PS3使用它们时,\n您可能需要从该列表中移除它们。\n\n另外,请确保它们在未使用状态下时与蓝牙断开连接,\n以免其电池持续消耗。\n\n蓝牙最多可处理7个连接设备,\n虽然您的里程可能会有所不同。", + "ouyaInstructionsText": "若要通过OUYA使用PS3手柄,仅需使用USB连接线\n将其连接配对。这样做可能会使您的其他手柄断开连接,因此\n您应该重新启动您的OUYA,然后拔下USB连接线。\n\n然后,你应该能够使用手柄的主页按钮\n以无线模式将其连接。结束游戏后,按住主页按钮\n10秒钟,以关闭手柄;否则,手柄将持续处于启动状态\n并消耗电池。", + "pairingTutorialText": "配对教程视频", + "titleText": "使用 PS3 手柄玩 ${APP_NAME}:" + }, + "punchBoldText": "拳击", + "punchText": "拳击", + "purchaseForText": "购买花费${PRICE}", + "purchaseGameText": "购买游戏", + "purchasingText": "正在购买…", + "quitGameText": "退出${APP_NAME}?", + "quittingIn5SecondsText": "在5秒后退出...", + "randomPlayerNamesText": "企鹅王,企鹅骑士团成员,王♂の传人,挨揍使我快乐,ChineseBomber,一拳超人,二营长の意大利炮,野渡无人舟自横,马克斯,雪糕,炸鸡翅,手柄玩家18子,寻找宝藏的海盗,炸弹投手,炸弹不是糖果,我是对面的,万有引力,鸟语花香,狗年大吉,小狗狗,大狗子,二狗子,三狗子,四狗子,五狗子,高质量人类,吴签,菜虚困,劈我瓜是吧,是我dio哒,亚达哟,王雷卖鱼,蕉♂个朋友,小猪配齐,摇摆羊,可莉,胡桃,钟离,七七,刻晴,甘雨,巴巴托斯,温迪,旅行者,绿坝娘,哔哩哔哩,别闹我有药", + "randomText": "随机", + "rankText": "排行", + "ratingText": "排名", + "reachWave2Text": "进入第2波才可排名。", + "readyText": "准备", + "recentText": "最近", + "remoteAppInfoShortText": "与家人或者朋友们一起玩${APP_NAME}是非常有趣的!\n您可以连接一个或多个硬件控制器\n或者在手机、平板上安装${REMOTE_APP_NAME}APP程序\n把他们当做控制器使用。", + "remote_app": { + "app_name": "炸弹小分队手柄", + "app_name_short": "炸弹小分队手柄", + "button_position": "按钮位置", + "button_size": "按钮尺寸", + "cant_resolve_host": "无法解析主机。", + "capturing": "捕捉中…", + "connected": "已连接。", + "description": "使用手机或平板电脑作为炸弹小分队游戏手柄。\n一台电视或平板电脑上可同时连接8台设备,体验史诗级多人模式的疯狂游戏。", + "disconnected": "服务器断开连接", + "dpad_fixed": "固定", + "dpad_floating": "浮动", + "dpad_position": "方向键位置", + "dpad_size": "方向键尺寸", + "dpad_type": "方向键类型", + "enter_an_address": "输入地址", + "game_full": "游戏连接已满或不接受更多连接。", + "game_shut_down": "游戏关闭。", + "hardware_buttons": "硬件按钮", + "join_by_address": "通过地址…加入", + "lag": "延迟:${SECONDS}秒", + "reset": "恢复默认值", + "run1": "运行 1", + "run2": "运行 2", + "searching": "正在搜索炸弹小分队游戏…", + "searching_caption": "点击游戏名,进入游戏。\n确保和游戏处于相同的wifi网络下。", + "start": "开始", + "version_mismatch": "版本不匹配。\n确定 炸弹小分队 和 BombSquad Remote\n 为最新版本后,重新尝试。" + }, + "removeInGameAdsText": "在商店中解锁\"${PRO}\",以删除游戏中的广告。", + "renameText": "重命名", + "replayEndText": "结束回放", + "replayNameDefaultText": "终场游戏回放", + "replayReadErrorText": "读取回放文件时出错。", + "replayRenameWarningText": "如果想保存回放文件,则以游戏来命名\"${REPLAY}\";否则文件将被覆盖。", + "replayVersionErrorText": "抱歉,该回放由不同版本的游戏制成,\n不能使用。", + "replayWatchText": "观看回放", + "replayWriteErrorText": "写入回放文件时出错。", + "replaysText": "回放", + "reportPlayerExplanationText": "利用此电子邮箱举报作弊、 不当言语或其他不良行为。\n请描述如下信息:", + "reportThisPlayerCheatingText": "作弊", + "reportThisPlayerLanguageText": "不当言语", + "reportThisPlayerReasonText": "举报内容是?", + "reportThisPlayerText": "举报该玩家", + "requestingText": "正在请求...", + "restartText": "重新启动", + "retryText": "请重试", + "revertText": "还原", + "runText": "运行", + "saveText": "保存", + "scanScriptsErrorText": "扫描脚本存在一个或多个错误;查看错误日志来了解详情。", + "scoreChallengesText": "得分挑战", + "scoreListUnavailableText": "得分列表不可用。", + "scoreText": "得分", + "scoreUnits": { + "millisecondsText": "毫秒", + "pointsText": "分", + "secondsText": "秒" + }, + "scoreWasText": "(是${COUNT})", + "selectText": "选择", + "seriesWinLine1PlayerText": "赢得", + "seriesWinLine1TeamText": "赢得", + "seriesWinLine1Text": "赢得", + "seriesWinLine2Text": "系列!", + "settingsWindow": { + "accountText": "账户", + "advancedText": "高级", + "audioText": "音效", + "controllersText": "控制器", + "graphicsText": "图像", + "playerProfilesMovedText": "注意:玩家档案已移至主菜单的「账号」窗口下", + "playerProfilesText": "玩家档案", + "titleText": "设置" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(一款简单、控制方便的用于文本编辑的屏幕键盘)", + "alwaysUseInternalKeyboardText": "始终使用内置键盘", + "benchmarksText": "基准与压力测试", + "disableCameraGyroscopeMotionText": "禁用相机陀螺仪运动", + "disableCameraShakeText": "禁用相机抖动", + "disableThisNotice": "(可在高级设置中关闭此通知)", + "enablePackageModsDescriptionText": "(启用额外的模组功能,但是禁用多人模式)", + "enablePackageModsText": "启用本地程序包修改", + "enterPromoCodeText": "输入促销代码", + "forTestingText": "注意:这些数值仅用于测试,并会在应用程序退出时丢失。", + "helpTranslateText": "${APP_NAME}的非英语翻译是社区\n共同努力的成果。如果您希望参与翻译或对其提出更正,\n请点击以下链接。先行感谢!", + "kickIdlePlayersText": "踢掉空闲玩家", + "kidFriendlyModeText": "儿童友好模式(低暴力等)", + "languageText": "语言", + "moddingGuideText": "修改指南", + "mustRestartText": "您必须重启游戏来使之生效", + "netTestingText": "网络测试", + "resetText": "恢复默认值", + "showBombTrajectoriesText": "显示炸弹轨迹", + "showInGamePingText": "显示游戏延迟", + "showPlayerNamesText": "显示玩家名字", + "showUserModsText": "显示修改文件夹", + "titleText": "高级", + "translationEditorButtonText": "${APP_NAME}翻译编辑器", + "translationFetchErrorText": "翻译状态不可用", + "translationFetchingStatusText": "检查翻译进度…", + "translationInformMe": "所选语言可更新时请通知我!", + "translationNoUpdateNeededText": "当前语言是最新的;呜呼!", + "translationUpdateNeededText": "**当前语言需要更新!! **", + "vrTestingText": "VR测试" + }, + "shareText": "分享", + "sharingText": "分享", + "showText": "显示", + "signInForPromoCodeText": "您必须登录到一个帐户, 代码才能生效", + "signInWithGameCenterText": "使用游戏中心\n应用程序登录。", + "singleGamePlaylistNameText": "仅${GAME}", + "singlePlayerCountText": "一个玩家", + "soloNameFilterText": "单挑模式 ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "角色选择", + "Chosen One": "选定模式", + "Epic": "史诗模式游戏", + "Epic Race": "史诗级竞赛", + "FlagCatcher": "夺旗战", + "Flying": "快乐山区", + "Football": "运旗战", + "ForwardMarch": "突袭战", + "GrandRomp": "征服战", + "Hockey": "冰球战", + "Keep Away": "抓旗战", + "Marching": "塔防战", + "Menu": "主菜单", + "Onslaught": "冲锋战", + "Race": "竞赛", + "Scary": "山丘之王", + "Scores": "得分屏幕", + "Survival": "消除战", + "ToTheDeath": "死亡竞赛", + "Victory": "最终得分屏幕" + }, + "spaceKeyText": "空格", + "statsText": "详情", + "storagePermissionAccessText": "需要存储权限", + "store": { + "alreadyOwnText": "您已拥有${NAME}!", + "bombSquadProDescriptionText": "• 在游戏中赚取双倍点券\n• 移除游戏广告\n• 包括${COUNT}奖励点券\n• +${PERCENT}%联赛得分奖励\n• 解锁'${INF_ONSLAUGHT}'和\n '${INF_RUNAROUND}'合作关卡", + "bombSquadProFeaturesText": "功能:", + "bombSquadProNameText": "${APP_NAME}专业版", + "bombSquadProNewDescriptionText": "• 移除游戏内广告和烦人页面\n• 解锁更多的游戏设置\n• 另外还包括:", + "buyText": "购买", + "charactersText": "人物", + "comingSoonText": "敬请期待……", + "extrasText": "额外部分", + "freeBombSquadProText": "BombSquad现在是免费的,由于最初您是通过购买所得,您将获得\nBombSquad专业版升级和${COUNT}点券,以表感谢。\n尽享全新功能,同时感谢您的支持!\n-Eric", + "gameUpgradesText": "游戏升级", + "holidaySpecialText": "假期特献", + "howToSwitchCharactersText": "(进入\"${SETTINGS} -> ${PLAYER_PROFILES}\"指定和自定义人物)", + "howToUseIconsText": "(升级全球档案以使用图标)", + "howToUseMapsText": "(在团队/混战游戏中使用这些地图)", + "iconsText": "图标", + "loadErrorText": "无法加载页面。\n请检查您的网络连接。", + "loadingText": "加载中", + "mapsText": "地图", + "miniGamesText": "迷你游戏", + "oneTimeOnlyText": "(仅一次)", + "purchaseAlreadyInProgressText": "该物品的购买已在进行中。", + "purchaseConfirmText": "购买${ITEM}?", + "purchaseNotValidError": "购买无效。\n如果这是一个错误,请联系${EMAIL}。", + "purchaseText": "购买", + "saleBundleText": "捆绑销售!", + "saleExclaimText": "出售!", + "salePercentText": "(${PERCENT}%折扣)", + "saleText": "特卖", + "searchText": "搜索", + "teamsFreeForAllGamesText": "团队/混战游戏", + "totalWorthText": "*** 价值${TOTAL_WORTH}! ***", + "upgradeQuestionText": "更新吗?", + "winterSpecialText": "冬季特献", + "youOwnThisText": "- 您已拥有 -" + }, + "storeDescriptionText": "8人派对游戏尽显疯狂!\n\n在爆炸类迷你游戏中炸飞您的好友(或电脑),如夺旗战、冰球战及史诗级慢动作死亡竞赛!\n\n简单的控制和广泛的手柄支持可轻松允许多达8人参与游戏;您甚至可以通过免费的“BombSquad Remote”应用将您的移动设备作为手柄使用!\n\n投射炸弹!\n\n更多信息,请登录www.froemling.net/bombsquad。", + "storeDescriptions": { + "blowUpYourFriendsText": "炸飞你的好友。", + "competeInMiniGamesText": "在从竞速到飞行的迷你游戏中一较高下。", + "customize2Text": "自定义角色、迷你游戏,甚至是背景音乐。", + "customizeText": "自定义角色并创建自己的迷你游戏播放列表。", + "sportsMoreFunText": "加入炸药后运动变得更加有趣。", + "teamUpAgainstComputerText": "组队对抗电脑程序。" + }, + "storeText": "商店", + "submitText": "提交", + "submittingPromoCodeText": "正在提交代码...", + "teamNamesColorText": "团队名称/颜色。。。", + "telnetAccessGrantedText": "Telnet访问已启用。", + "telnetAccessText": "检测到Telnet访问;是否允许?", + "testBuildErrorText": "该测试版已失效;请检查是否存在新版本。", + "testBuildText": "测试版", + "testBuildValidateErrorText": "无法验证测试版。(无网络连接?)", + "testBuildValidatedText": "测试版已通过验证;尽请享用!", + "thankYouText": "感谢您的支持!尽情享受游戏!!", + "threeKillText": "三杀!!", + "timeBonusText": "时间奖励", + "timeElapsedText": "时间耗尽", + "timeExpiredText": "时间结束", + "timeSuffixDaysText": "${COUNT}天", + "timeSuffixHoursText": "${COUNT}时", + "timeSuffixMinutesText": "${COUNT}分", + "timeSuffixSecondsText": "${COUNT}秒", + "tipText": "提示", + "titleText": "炸弹小分队", + "titleVRText": "炸弹小分队 VR", + "topFriendsText": "最佳好友", + "tournamentCheckingStateText": "检查锦标赛状态;请稍候……", + "tournamentEndedText": "本次锦标赛已经结束。一场新的锦标赛即将开始。", + "tournamentEntryText": "锦标赛入口", + "tournamentResultsRecentText": "最近锦标赛结果", + "tournamentStandingsText": "锦标赛积分榜", + "tournamentText": "锦标赛", + "tournamentTimeExpiredText": "锦标赛时间结束", + "tournamentsDisabledWorkspaceText": "工作区启用时无法参加锦标赛!\n关闭工作区,才能进入锦标赛。", + "tournamentsText": "锦标赛", + "translations": { + "characterNames": { + "Agent Johnson": "约翰逊特工", + "B-9000": "B-9000", + "Bernard": "伯纳德", + "Bones": "骷髅", + "Butch": "牛仔邦奇", + "Easter Bunny": "复活兔", + "Flopsy": "萌兔耷拉", + "Frosty": "冰冰", + "Gretel": "格蕾特", + "Grumbledorf": "男巫", + "Jack Morgan": "杰克摩根", + "Kronk": "克罗克", + "Lee": "李", + "Lucky": "幸运儿", + "Mel": "梅尔", + "Middle-Man": "平衡之尊", + "Minimus": "迷你姆斯", + "Pascal": "巴斯卡", + "Pixel": "精灵", + "Sammy Slam": "萨米斯拉姆", + "Santa Claus": "圣诞老人", + "Snake Shadow": "蛇影", + "Spaz": "斯巴子", + "Taobao Mascot": "淘公仔", + "Todd McBurton": "托德马克波顿", + "Zoe": "佐伊", + "Zola": "佐拉" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME}训练", + "Infinite ${GAME}": "无限${GAME}", + "Infinite Onslaught": "无限冲锋战", + "Infinite Runaround": "无限塔防战", + "Onslaught Training": "冲锋训练", + "Pro ${GAME}": "专业版${GAME}", + "Pro Football": "专业橄榄球赛", + "Pro Onslaught": "专业冲锋战", + "Pro Runaround": "专业塔防战", + "Rookie ${GAME}": "新手版${GAME}", + "Rookie Football": "新手橄榄球赛", + "Rookie Onslaught": "新手冲锋战", + "The Last Stand": "最终杀敌战", + "Uber ${GAME}": "高级${GAME}", + "Uber Football": "高级橄榄球赛", + "Uber Onslaught": "高级冲锋战", + "Uber Runaround": "高级塔防战" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "在一定时间内取代选定目标进而获得胜利。\n杀死选定目标并取而代之。", + "Bomb as many targets as you can.": "尽可能多地炸毁目标。", + "Carry the flag for ${ARG1} seconds.": "扛旗${ARG1}秒。", + "Carry the flag for a set length of time.": "在设定时长内扛旗。", + "Crush ${ARG1} of your enemies.": "粉碎${ARG1}敌人。", + "Defeat all enemies.": "打败所有的敌人。", + "Dodge the falling bombs.": "躲避下落的炸弹。", + "Final glorious epic slow motion battle to the death.": "在最后的荣耀史诗级慢动作大战中战斗至死。", + "Gather eggs!": "收集蛋吧!", + "Get the flag to the enemy end zone.": "扛旗进入敌人达阵区。", + "How fast can you defeat the ninjas?": "你能多快地打败忍者?", + "Kill a set number of enemies to win.": "杀死一定数量的敌人来获得胜利。", + "Last one standing wins.": "最终杀敌者获胜。", + "Last remaining alive wins.": "最终幸存者获胜。", + "Last team standing wins.": "最终杀敌团队获胜。", + "Prevent enemies from reaching the exit.": "阻止敌人到达出口。", + "Reach the enemy flag to score.": "触碰敌人的旗帜来得分。", + "Return the enemy flag to score.": "交回敌人的旗帜来得分。", + "Run ${ARG1} laps.": "跑${ARG1}圈。", + "Run ${ARG1} laps. Your entire team has to finish.": "跑${ARG1}圈。你的整个团队都得完成。", + "Run 1 lap.": "跑1圈。", + "Run 1 lap. Your entire team has to finish.": "跑1圈。你的整个团队都得完成。", + "Run real fast!": "快速奔跑!", + "Score ${ARG1} goals.": "${ARG1}进球得分。", + "Score ${ARG1} touchdowns.": "${ARG1}触地得分。", + "Score a goal.": "一次进球得分。", + "Score a touchdown.": "一次触地得分。", + "Score some goals.": "多次进球得分。", + "Secure all ${ARG1} flags.": "固定所有的${ARG1}旗帜。", + "Secure all flags on the map to win.": "固定地图上的所有旗帜来获得胜利。", + "Secure the flag for ${ARG1} seconds.": "固定旗帜${ARG1}秒。", + "Secure the flag for a set length of time.": "在设定时长内固定旗帜。", + "Steal the enemy flag ${ARG1} times.": "窃取敌人的旗帜${ARG1}次。", + "Steal the enemy flag.": "窃取敌人的旗帜。", + "There can be only one.": "无敌模式", + "Touch the enemy flag ${ARG1} times.": "触碰敌人的旗帜${ARG1}次。", + "Touch the enemy flag.": "触碰敌人的旗帜。", + "carry the flag for ${ARG1} seconds": "扛旗${ARG1}秒", + "kill ${ARG1} enemies": "杀死${ARG1}敌人", + "last one standing wins": "最终杀敌者获胜", + "last team standing wins": "最终杀敌团队获胜", + "return ${ARG1} flags": "交回${ARG1}旗帜", + "return 1 flag": "交回1面旗帜", + "run ${ARG1} laps": "跑${ARG1}圈", + "run 1 lap": "跑1圈", + "score ${ARG1} goals": "${ARG1}进球得分", + "score ${ARG1} touchdowns": "${ARG1}触地得分", + "score a goal": "一次进球得分", + "score a touchdown": "一次触地得分", + "secure all ${ARG1} flags": "固定所有的${ARG1}旗帜", + "secure the flag for ${ARG1} seconds": "固定旗帜${ARG1}秒", + "touch ${ARG1} flags": "触碰${ARG1}旗帜", + "touch 1 flag": "触碰1面旗帜" + }, + "gameNames": { + "Assault": "突袭战", + "Capture the Flag": "夺旗战", + "Chosen One": "选定模式", + "Conquest": "征服战", + "Death Match": "死亡竞赛", + "Easter Egg Hunt": "彩蛋猎人", + "Elimination": "消除战", + "Football": "运旗战", + "Hockey": "冰球战", + "Keep Away": "抓旗战", + "King of the Hill": "山丘之王", + "Meteor Shower": "流星战", + "Ninja Fight": "忍者大战", + "Onslaught": "冲锋战", + "Race": "竞速赛", + "Runaround": "塔防战", + "Target Practice": "目标训练", + "The Last Stand": "最终杀敌战" + }, + "inputDeviceNames": { + "Keyboard": "键盘", + "Keyboard P2": "键盘P2" + }, + "languages": { + "Arabic": "阿拉伯语", + "Belarussian": "白俄罗斯语", + "Chinese": "简体中文", + "ChineseTraditional": "繁体中文", + "Croatian": "克罗地亚语", + "Czech": "捷克语", + "Danish": "丹麦语", + "Dutch": "荷兰语", + "English": "英语", + "Esperanto": "世界语", + "Filipino": "菲律宾语", + "Finnish": "芬兰语", + "French": "法语", + "German": "德语", + "Gibberish": "用于测试", + "Greek": "希腊语", + "Hindi": "印度语", + "Hungarian": "匈牙利语", + "Indonesian": "印尼语", + "Italian": "意大利语", + "Japanese": "日本语", + "Korean": "朝鲜语", + "Malay": "马来语", + "Persian": "波斯文", + "Polish": "波兰语", + "Portuguese": "葡萄牙语", + "Romanian": "罗马尼亚语", + "Russian": "俄语", + "Serbian": "塞尔维亚语", + "Slovak": "斯洛伐克语", + "Spanish": "西班牙语", + "Swedish": "瑞典语", + "Tamil": "泰米尔语", + "Thai": "泰语", + "Turkish": "土耳其语", + "Ukrainian": "乌克兰语", + "Venetian": "威尼斯语", + "Vietnamese": "越南语" + }, + "leagueNames": { + "Bronze": "铜牌联赛", + "Diamond": "钻石联赛", + "Gold": "金牌联赛", + "Silver": "银牌联赛" + }, + "mapsNames": { + "Big G": "大G地图", + "Bridgit": "小桥地图", + "Courtyard": "庭院地图", + "Crag Castle": "岩城地图", + "Doom Shroom": "末日蘑菇地图", + "Football Stadium": "橄榄球场", + "Happy Thoughts": "快乐想法", + "Hockey Stadium": "曲棍球场地图", + "Lake Frigid": "寒湖地图", + "Monkey Face": "猴面地图", + "Rampage": "狂暴地图", + "Roundabout": "塔防地图", + "Step Right Up": "攻击地图", + "The Pad": "平板地图", + "Tip Top": "顶点地图", + "Tower D": "塔防地图", + "Zigzag": "蜿蜒地图" + }, + "playlistNames": { + "Just Epic": "仅限史诗级", + "Just Sports": "仅限运动类" + }, + "scoreNames": { + "Flags": "旗帜", + "Goals": "进球", + "Score": "得分", + "Survived": "幸存", + "Time": "时间", + "Time Held": "保持时间" + }, + "serverResponses": { + "A code has already been used on this account.": "该账户已使用代码。", + "A reward has already been given for that address.": "您已经领取过该奖励了", + "Account linking successful!": "账号连接成功!", + "Account unlinking successful!": "取消关联账户成功!", + "Accounts are already linked.": "账号已经连接。", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "广告加载失败。\n请验证你的游戏版本为官方最新版。", + "An error has occurred; (${ERROR})": "出现了一个错误; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "出现了一个错误,请联系客服获取支持.(${ERROR})", + "An error has occurred; please contact support@froemling.net.": "发生了一个错误,请联系 support@froemling.net。", + "An error has occurred; please try again later.": "发生了一个错误, 请稍候再试", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "确定要链接这些账户?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n此操作不可撤销!", + "BombSquad Pro unlocked!": "炸弹小分队专业版已解锁!", + "Can't link 2 accounts of this type.": "无法连接2个这种账号。", + "Can't link 2 diamond league accounts.": "无法连接两个钻石联赛账号。", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "无法连接,会超过上限 ${COUNT} 个账号。", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "发现作弊行为;得分及奖励在${COUNT}天内暂停。", + "Could not establish a secure connection.": "无法建立安全连接。", + "Daily maximum reached.": "已达今日上限。", + "Entering tournament...": "进入锦标赛……", + "Invalid code.": "代码无效。", + "Invalid payment; purchase canceled.": "不可用的付款方式:交易取消", + "Invalid promo code.": "促销代码无效。", + "Invalid purchase.": "购买无效。", + "Invalid tournament entry; score will be ignored.": "错误的联赛资料,分数会被忽略。", + "Item unlocked!": "项目已解除锁定!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "连接账号行为取消。${ACCOUNT} 含有\n重要数据可能会丢失。\n如果你想要的话,你可以反向链接账号。\n(那样就会丢失这个账号的数据)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "将帐户${ACCOUNT}关联到此帐户吗?\n${ACCOUNT}将共享数据。\n此操作不能撤销。", + "Max number of playlists reached.": "已达到最大列表数目。", + "Max number of profiles reached.": "已达到最大档案数目。", + "Maximum friend code rewards reached.": "邀请码奖励达到上限", + "Message is too long.": "消息太长.", + "No servers are available. Please try again soon.": "当前没有空余的服务器,请稍后再试", + "Profile \"${NAME}\" upgraded successfully.": "${NAME}档案升级成功。", + "Profile could not be upgraded.": "档案不可升级。", + "Purchase successful!": "购买成功!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "登录领取${COUNT}点券。\n明日再来领取${TOMORROW_COUNT}。", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "此版本的游戏不再支持服务器功能;\n请更新到较新版本。", + "Sorry, there are no uses remaining on this code.": "对不起,此代码已经无法继续使用了。", + "Sorry, this code has already been used.": "对不起,此代码已被使用。", + "Sorry, this code has expired.": "对不起,此代码已失效。", + "Sorry, this code only works for new accounts.": "对不起,此代码仅适用于新账户。", + "Still searching for nearby servers; please try again soon.": "正在搜索附近的服务器,请稍后再试", + "Temporarily unavailable; please try again later.": "目前暂不可用;请稍候再试!", + "The tournament ended before you finished.": "本次锦标赛在你完成之前结束。", + "This account cannot be unlinked for ${NUM} days.": "此帐户无法在${NUM}天内取消关联。", + "This code cannot be used on the account that created it.": "此代码不可在创建其的账户上使用。", + "This is currently unavailable; please try again later.": "当前不可用:请稍后再试", + "This requires version ${VERSION} or newer.": "这需要版本${VERSION}或更高版本。", + "Tournaments disabled due to rooted device.": "该设备已禁用比赛。", + "Tournaments require ${VERSION} or newer": "比赛需要${VERSION}或更高版本", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "从此帐户取消 ${ACCOUNT} 的连结?\n${ACCOUNT}上的所有数据将被重置。\n(在某些情况下除成就外)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "警告:针对您的帐户发出黑客投诉。\n被盗用的帐户将被禁止。请公平竞技。", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "是否将您的设备帐户链接到此?\n\n您的设备账户为${ACCOUNT1}\n此帐户为${ACCOUNT2}\n\n您可保存现有进度。\n警告: 此操作不可撤消!", + "You already own this!": "你已拥有了!", + "You can join in ${COUNT} seconds.": "你在${COUNT} 秒后可以加入", + "You don't have enough tickets for this!": "你的点券不足!", + "You don't own that.": "你尚未拥有", + "You got ${COUNT} tickets!": "你获得了${COUNT}点券!", + "You got a ${ITEM}!": "你获得了一个${ITEM}!", + "You have been promoted to a new league; congratulations!": "你已被升级至一个全新联赛;恭喜!", + "You must update to a newer version of the app to do this.": "你必须升级到最新版本才可以", + "You must update to the newest version of the game to do this.": "你必须更新到最新版来做到这一点。", + "You must wait a few seconds before entering a new code.": "你必须在输入新代码前稍等几秒。", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "你在上一场锦标赛中排名#${RANK}。多谢玩赏本游戏!", + "Your account was rejected. Are you signed in?": "您的账号被拒绝。您是否已登录?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "你的游戏副本已被更改。\n请恢复任何更改并重试。", + "Your friend code was used by ${ACCOUNT}": "${ACCOUNT}已使用您的好友代码" + }, + "settingNames": { + "1 Minute": "1分钟", + "1 Second": "1秒钟", + "10 Minutes": "10分钟", + "2 Minutes": "2分钟", + "2 Seconds": "2秒钟", + "20 Minutes": "20分钟", + "4 Seconds": "4秒钟", + "5 Minutes": "5分钟", + "8 Seconds": "8秒钟", + "Allow Negative Scores": "允许负分", + "Balance Total Lives": "平衡总生命", + "Bomb Spawning": "生成炸弹", + "Chosen One Gets Gloves": "选定目标获取手套", + "Chosen One Gets Shield": "选定目标获取盾牌", + "Chosen One Time": "选定模式时间", + "Enable Impact Bombs": "启用冲击炸弹", + "Enable Triple Bombs": "启用三连炸弹", + "Entire Team Must Finish": "整个队伍必须一起通过", + "Epic Mode": "史诗模式", + "Flag Idle Return Time": "旗帜闲置返回时间", + "Flag Touch Return Time": "旗帜触碰返回时间", + "Hold Time": "保持时间", + "Kills to Win Per Player": "每一玩家取胜击杀数", + "Laps": "圈数", + "Lives Per Player": "每一玩家生命", + "Long": "长", + "Longer": "更长", + "Mine Spawning": "地雷增生", + "No Mines": "无地雷", + "None": "无", + "Normal": "正常", + "Pro Mode": "专业模式", + "Respawn Times": "重生時長", + "Score to Win": "得分取胜", + "Short": "短", + "Shorter": "更短", + "Solo Mode": "单人模式", + "Target Count": "目标计数", + "Time Limit": "时限" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM}被踢,因为 ${PLAYER}离开了", + "Killing ${NAME} for skipping part of the track!": "杀死跳过部分赛道的${NAME}!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "警告 ${NAME}: 超幅 / 散播按钮 将使你被踢出。" + }, + "teamNames": { + "Bad Guys": "坏人队", + "Blue": "蓝队", + "Good Guys": "好人队", + "Red": "红队" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "一记完美、及时的“跑跳旋转拳”可一次性击杀敌人,并\n助你一生享有好友的尊重。", + "Always remember to floss.": "地面上的辅助线可能会有用。", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "使用首选名称和外观,而非采用随机形式\n来为自己和好友创建玩家档案。", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "诅咒之盒把你变成了一个定时炸弹。\n唯一的解决方法是迅速抢占一个生命值包。", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "尽管长相不同,所有人物的技能是相同的,\n所以只需随意挑选一个与你最相似的。", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "不要因为拥有能量盾牌而狂妄自大;你仍然可能使自己坠入悬崖。", + "Don't run all the time. Really. You will fall off cliffs.": "不要总是奔跑。真的。你可能会坠入悬崖。", + "Don't spin for too long; you'll become dizzy and fall.": "不要旋转得太久,不然你会眩晕并摔倒。", + "Hold any button to run. (Trigger buttons work well if you have them)": "按住任意按钮来奔跑。(如果你有的话,扳机按钮将会很有用)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "按住任意按钮来奔跑。你将会更快地抵达一些地方,\n但是转弯效果并不好,所以当心悬崖。", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "寒冰炸弹并非很厉害,但它们能够冻结\n任何被击中者,使他们极易粉碎。", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "如果有人将你提起,出拳攻击他们,他们便会放手。\n这在现实生活中同样有效。", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "如果您缺控制器,可以在手机安装「${REMOTE_APP_NAME}」\n然后手机就可以当作控制器啦~", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "如果你没有手柄,请在你的iOS或Android设备上安装\n“BombSquad Remote”应用程序,并将它们作为手柄使用。", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "如果一个黏黏弹将你困住,你应该四处跳动并转圈。你可能\n将炸弹抖落,或如果没有其他办法,你最后的时刻将是有趣的。", + "If you kill an enemy in one hit you get double points for it.": "如果你一击杀死一个敌人,你将获得双倍积分。", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "如果你捡到一个诅咒之盒,你唯一的生存希望是\n在接下来的几秒内找到一个加血包。", + "If you stay in one place, you're toast. Run and dodge to survive..": "如果你停留在一个地方,你就完了。为了生存而奔跑和躲避……", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "如果众多玩家进进出出,在设置下打开“自动踢出闲置玩家”,以防\n任何玩家忘记离开游戏。", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "如果你的设备过热,或者你想要节省电池电量,\n则在设置->图形中调低“视觉效果”或“分辨率”", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "如果你的帧速率不稳定,请尝试在游戏的\n图形设置中调低分辨率或视觉效果。", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "在夺旗战中,你的旗帜必须位于你的基地才能得分,如果对方\n团队即将得分,窃取他们的旗帜是一个不错的阻止方法。", + "In hockey, you'll maintain more speed if you turn gradually.": "在冰球战中,逐渐转向将使你保持更快的速度。", + "It's easier to win with a friend or two helping.": "在拥有一名好友或两个帮扶的情况下更易获胜。", + "Jump just as you're throwing to get bombs up to the highest levels.": "就像你试图将炸弹扔到最高点那样跳起来。", + "Land-mines are a good way to stop speedy enemies.": "地雷是阻止高速敌人的一个很好的方式。", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "很多东西都可以捡起来并投掷,包括其他玩家。将你的\n敌人抛下悬崖可能是一个有效的且情感上可获得满足的策略。", + "No, you can't get up on the ledge. You have to throw bombs.": "不,你不能在岩脊上起身。你必须要投掷炸弹。", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "玩家可在大多数游戏中途加入或离开,\n同时,你也可以在百忙中插上或拔出手柄。", + "Practice using your momentum to throw bombs more accurately.": "练习借助你的力量更准确地投掷炸弹。", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "拳头跑得越快,拳击的伤害越高,\n所以请成为飞奔的拳击手吧。", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "在投掷炸弹之前来回跑动,\n以“鞭打”炸弹,并将其投掷更远。", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "在TNT炸药箱附近引爆\n一个炸弹来消灭一群敌人。", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "头部是最脆弱的区域,所以一个黏黏弹\n接触头部通常便意味着游戏结束。", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "这一关卡永远不会结束,但是更高的得分将\n助你赢得全世界永恒的尊重。", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "投掷力量取决于你所保持的方向。\n如要向前方轻轻投掷某物,不要保持在任何方向。", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "更换背景音乐?更换成你自己音乐吧!\n参见设置->音频->背景音乐", + "Try 'Cooking off' bombs for a second or two before throwing them.": "尝试在投掷之前将炸弹“爆燃”一秒或两秒。", + "Try tricking enemies into killing eachother or running off cliffs.": "试图诱使敌人互相厮杀或坠入悬崖。", + "Use the pick-up button to grab the flag < ${PICKUP} >": "使用拾取按钮来抢夺旗帜< ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "来回鞭打以投掷更远距离……", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "你可以通过左转或右转“瞄准”出拳。\n这有利于将坏人击倒出边界或在冰球战中得分。", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "你可以根据导火线火花的颜色判断炸弹什么时候爆炸:\n黄色……橙色……红色……嘭。", + "You can throw bombs higher if you jump just before throwing.": "如果投弹前跳起,你将投掷更远。", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "当你用头部重击物体时将受到伤害,\n所以尽量不要用头部重击物体。", + "Your punches do much more damage if you are running or spinning.": "如果你奔跑或旋转,拳击的伤害将更高。" + } + }, + "trophiesRequiredText": "你必须要有至少 ${NUMBER} 个奖杯", + "trophiesText": "奖杯", + "trophiesThisSeasonText": "本赛季奖杯", + "tutorial": { + "cpuBenchmarkText": "以惊人的速度运行教程(主要用于测试CPU速度)", + "phrase01Text": "嗨,您好!", + "phrase02Text": "欢迎来到${APP_NAME}!", + "phrase03Text": "以下是用于控制你的角色的一些技巧:", + "phrase04Text": "${APP_NAME}的很多方面是以物理为基础的。", + "phrase05Text": "例如,当你出拳时,", + "phrase06Text": "伤害程度取决于你拳头的速度。", + "phrase07Text": "看到没?如果我们不动,这样几乎不会伤害${NAME}。", + "phrase08Text": "现在,让我们跳跃并旋转起来,以获得更快的速度。", + "phrase09Text": "啊,这样好多了。", + "phrase10Text": "奔跑也会发挥作用。", + "phrase11Text": "按住任意按钮来奔跑。", + "phrase12Text": "想成为一拳超人,可以尝试边跑边旋转。", + "phrase13Text": "啊;真抱歉啊,${NAME}。(狗头)", + "phrase14Text": "你可以捡起并投掷物体,如旗帜或${NAME}。", + "phrase15Text": "最后,还有炸弹。", + "phrase16Text": "投掷炸弹需要练习。", + "phrase17Text": "大家不要学我这样丢...", + "phrase18Text": "跑起来有助你投掷得更远。", + "phrase19Text": "跳跃有助你投掷得更高。", + "phrase20Text": "“鞭打”你的炸弹以抛出更远的距离。", + "phrase21Text": "你还要卡准时机丢出炸弹。", + "phrase22Text": "我靠。", + "phrase23Text": "可以让火线先燃烧一秒或两秒。", + "phrase24Text": "好耶!差点秒杀~", + "phrase25Text": "好了,教程先到这里吧。", + "phrase26Text": "先尝试一波吧,老铁!", + "phrase27Text": "记住刚刚的教程,你会活着回来的!", + "phrase28Text": "......好吧,也许...", + "phrase29Text": "祝好运!", + "randomName1Text": "弗雷德", + "randomName2Text": "哈里", + "randomName3Text": "比尔", + "randomName4Text": "查克", + "randomName5Text": "菲尔", + "skipConfirmText": "确定跳过教程?点击或按下按钮以确认。", + "skipVoteCountText": "${COUNT}/${TOTAL}跳过投票", + "skippingText": "跳过教程……", + "toSkipPressAnythingText": "(点击或按下任何按钮以跳过教程)" + }, + "twoKillText": "双杀!", + "unavailableText": "不可用", + "unconfiguredControllerDetectedText": "检测到未配置的手柄:", + "unlockThisInTheStoreText": "这必须在商店中解锁。", + "unlockThisProfilesText": "如需创建超过 ${NUM} 个玩家档案,你需要", + "unlockThisText": "你需要这些来解锁", + "unsupportedHardwareText": "抱歉,此版本的游戏不支持该硬件。", + "upFirstText": "进入第一局:", + "upNextText": "进入比赛${COUNT}第二局:", + "updatingAccountText": "更新您的帐户……", + "upgradeText": "升级", + "upgradeToPlayText": "在游戏商店中解锁\"${PRO}\",以体验该游戏。", + "useDefaultText": "使用默认值", + "usesExternalControllerText": "该游戏使用外部手柄进行输入。", + "usingItunesText": "使用音乐应用设置背景音乐……", + "usingItunesTurnRepeatAndShuffleOnText": "请确认iTunes中随机播放已开启且重复全部歌曲。", + "v2AccountLinkingInfoText": "要连接V2账户,请点击“管理账户”~", + "validatingTestBuildText": "测试版验证中……", + "victoryText": "胜利!", + "voteDelayText": "${NUMBER} 秒内你不能发起另一个投票", + "voteInProgressText": "已经有一个投票在进行中了", + "votedAlreadyText": "你已经投过票啦!", + "votesNeededText": "通过需要 ${NUMBER} 个投票", + "vsText": "vs.", + "waitingForHostText": "(请等待${HOST}继续游戏)", + "waitingForPlayersText": "等待玩家的加入……", + "waitingInLineText": "正在排队等候(人满为患)...", + "watchAVideoText": "看一个小广告视频", + "watchAnAdText": "观看广告", + "watchWindow": { + "deleteConfirmText": "删除\"${REPLAY}\"?", + "deleteReplayButtonText": "删除\n回放", + "myReplaysText": "我的回放", + "noReplaySelectedErrorText": "未选择回放", + "playbackSpeedText": "回放速度: ${SPEED}", + "renameReplayButtonText": "重命名\n录像", + "renameReplayText": "重命名\"${REPLAY}\"至:", + "renameText": "重命名", + "replayDeleteErrorText": "删除回放错误。", + "replayNameText": "回放名称", + "replayRenameErrorAlreadyExistsText": "该名称的回放已经存在。", + "replayRenameErrorInvalidName": "无法重命名回放;名称无效。", + "replayRenameErrorText": "重命名回放错误。", + "sharedReplaysText": "共享回放", + "titleText": "观看回放", + "watchReplayButtonText": "观看\n回放" + }, + "waveText": "波", + "wellSureText": "确定!", + "whatIsThisText": "这啥玩意??", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote版权所有" + }, + "wiimoteListenWindow": { + "listeningText": "监听Wiimotes……", + "pressText": "同时按下Wiimote按钮1和2。", + "pressText2": "在较新的安装有Motion Plus的Wiimotes上,可按下背部的红色“同步”按钮作为替代。" + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote版权所有", + "listenText": "监听", + "macInstructionsText": "确保您Mac上的Wii已关闭且蓝牙已启用\n,然后按下“监听”。Wiimote支持可能出现稍许不稳定,\n所以在完成连接之前\n您可能需要尝试多次。\n\n蓝牙需能够处理多达7台连接设备,\n但您的里程可能会有所不同。\n\nBombSquad支持原装Wiimotes、Nunchuks\n及经典手柄。\n较新版本的Wii Remote Plus现也已可使用,\n但与附件不兼容", + "thanksText": "感谢DarwiinRemote团队的努力,\n这一切已成为可能。", + "titleText": "Wiimote设置" + }, + "winsPlayerText": "${NAME}获胜!", + "winsTeamText": "${NAME}获胜!", + "winsText": "${NAME}获胜!", + "workspaceSyncErrorText": "同步${WORKSPACE}出错了啦,详情见日志文件", + "workspaceSyncReuseText": "同步${WORKSPACE}时出错,正在使用以前同步的数据....", + "worldScoresUnavailableText": "全球得分不可用。", + "worldsBestScoresText": "全球最高得分", + "worldsBestTimesText": "全球最佳时间", + "xbox360ControllersWindow": { + "getDriverText": "获取驱动程序", + "macInstructions2Text": "如要使用无线手柄,您还需要\n“用于Windows的无线Xbox360手柄”自带的接收器。\n一个接收器可让您连接多达4个手柄。\n\n重要提示:第三方接收器与此驱动程序不兼容;\n请确保您的接收器标示有'Microsoft',而非'XBOX 360'。\nMicrosoft不再单独出售该设备,所以您需要获得\n手柄附带的接收器或在eBay搜索其他设备。\n\n如果这对您有帮助,请考虑在驱动程序开发人员\n网站进行捐赠。", + "macInstructionsText": "如要使用Xbox 360手柄,您需要安装\n通过以下链接所获得的Mac驱动程序。\n该驱动程序与有线和无线手柄二者兼容。", + "ouyaInstructionsText": "如要在BombSquad中使用有线Xbox 360手柄,只需\n将其插入您设备的USB端口。您可以使用USB集线器\n以连接多个手柄。\n\n如要使用无线手柄,您需要一台无线接收器,\n其可作为“用于Windows的无线Xbox360手柄”\n安装包的一部分或单独出售。每一接收器插入一个USB端口,\n允许您连接多达4台无线手柄。", + "ouyaInstructionsTextScale": 0.8, + "titleText": "在${APP_NAME}中使用Xbox 360手柄:" + }, + "yesAllowText": "是的,允许!", + "yourBestScoresText": "你的最高得分", + "yourBestTimesText": "你的最佳时刻" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/chinesetraditional.json b/dist/ba_data/data/languages/chinesetraditional.json new file mode 100644 index 0000000..5c26f30 --- /dev/null +++ b/dist/ba_data/data/languages/chinesetraditional.json @@ -0,0 +1,1878 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "帳號名不可包含表情符號或其他特殊字符", + "accountsText": "帳號", + "achievementProgressText": "已完成${TOTAL}個成就中的${COUNT}個", + "campaignProgressText": "戰役進度[困難]: ${PROGRESS}", + "changeOncePerSeason": "每一賽季只有一次更改機會", + "changeOncePerSeasonError": "您必須等${NUM}天到下個賽季改變此選項", + "customName": "自定義名稱", + "googlePlayGamesAccountSwitchText": "如果您想使用其他 Google 帳戶,\n使用 Google Play 遊戲應用程序進行切換。", + "linkAccountsEnterCodeText": "輸入代碼", + "linkAccountsGenerateCodeText": "生成代碼", + "linkAccountsInfoText": "(在不同的平台上共享遊戲進度)", + "linkAccountsInstructionsNewText": "要連結兩個帳號,在第一個帳號里點擊“生成代碼”按鈕。\n在第二個帳號裡輸入那個代碼。\n兩個帳號數據將被共享。\n(第一個帳號的數據將會消失)\n\n您總共可連結${COUNT}個帳號。\n\n重要訊息:你只能連結你自己的帳號;\n如果你連結了朋友的帳號, \n你將無法同時線上遊玩。", + "linkAccountsText": "連結帳號", + "linkedAccountsText": "已連結的帳號:", + "manageAccountText": "管理賬戶", + "nameChangeConfirm": "更改帳號名為${NAME}?", + "resetProgressConfirmNoAchievementsText": "這會重設你的合作模式進度和\n本地高分紀錄 (但不包含你的票卷)。\n這是不可回復的操作,你確定嗎?", + "resetProgressConfirmText": "這會重設你的合作模式進度,\n成就和本地高分\n(但不包括你的票卷)。這是不可\n回復的操作。你確定嗎?", + "resetProgressText": "重置遊戲進程", + "setAccountName": "設置帳號名", + "setAccountNameDesc": "選擇你要為你帳號使用的遊戲內名稱。\n你直接使用你其中一個已連結的賬戶的名稱或\n創造一個獨特的自定義名稱。", + "signInInfoText": "登入得以收集票卷,完成線上\n和與其他裝置共享進度", + "signInText": "登入", + "signInWithDeviceInfoText": "一個這裝置現有的自動帳號", + "signInWithDeviceText": "使用設備賬戶登入", + "signInWithGameCircleText": "使用Game Circle登入", + "signInWithGooglePlayText": "用play商店登入", + "signInWithTestAccountInfoText": "(舊有的帳號登入方式;使用後來的創設的帳號)", + "signInWithTestAccountText": "用測試帳號登入", + "signInWithV2InfoText": "(可用於所有平臺的賬戶)", + "signInWithV2Text": "使用Bombsquad賬戶登入", + "signOutText": "登出", + "signingInText": "登入中…", + "signingOutText": "登出中…", + "ticketsText": "擁有票券: ${COUNT}", + "titleText": "帳號", + "unlinkAccountsInstructionsText": "選擇一個要解除連結的帳號", + "unlinkAccountsText": "解除連結帳號", + "unlinkLegacyV1AccountsText": "取消鏈接舊版(V1)賬戶", + "v2LinkInstructionsText": "使用此鏈接新建或登錄賬戶", + "viaAccount": "(透過帳號 ${NAME})", + "youAreSignedInAsText": "您以這帳號登入:" + }, + "achievementChallengesText": "成就挑戰", + "achievementText": "成就", + "achievements": { + "Boom Goes the Dynamite": { + "description": "用TNT殺死了三個壞蛋", + "descriptionComplete": "用TNT殺死了三個壞蛋", + "descriptionFull": "在${LEVEL}中用TNT殺3個壞蛋", + "descriptionFullComplete": "在 ${LEVEL}中殺死了三個壞蛋", + "name": "炸彈爆炸了" + }, + "Boxer": { + "description": "沒用任何炸彈的情況下獲勝", + "descriptionComplete": "在沒用任何炸彈的情況下獲勝了", + "descriptionFull": "在沒用任何炸彈的情況下完成 ${LEVEL}", + "descriptionFullComplete": "在沒用任何炸彈的情況下完成了 ${LEVEL}", + "name": "拳擊手" + }, + "Dual Wielding": { + "descriptionFull": "鏈接兩個控制器(硬體或手機應用程式)", + "descriptionFullComplete": "兩個控制器已連接(硬體或應用程式)", + "name": "成雙成對" + }, + "Flawless Victory": { + "description": "毫髮無傷", + "descriptionComplete": "毫髮無傷地贏了", + "descriptionFull": "毫髮無傷地在 ${LEVEL}獲勝", + "descriptionFullComplete": "毫髮無傷地在 ${LEVEL}獲勝了", + "name": "完美獲勝" + }, + "Free Loader": { + "descriptionFull": "與兩位以上的玩家開始一場自由死鬥遊戲", + "descriptionFullComplete": "已與兩位以上的玩家開始了一場自由死鬥遊戲", + "name": "自由的戰鬥民族" + }, + "Gold Miner": { + "description": "用地雷殺死六個壞蛋", + "descriptionComplete": "已用地雷殺死了六個壞蛋", + "descriptionFull": "在 ${LEVEL}用地雷殺死六個壞蛋", + "descriptionFullComplete": "在 ${LEVEL}用地雷殺死了六個壞蛋", + "name": "淘金礦工" + }, + "Got the Moves": { + "description": "在不揮拳或使用炸彈的情況下獲勝", + "descriptionComplete": "在不揮拳或使用炸彈的情況下獲勝了", + "descriptionFull": "不揮拳或使用炸彈的情況下在 ${LEVEL}獲勝", + "descriptionFullComplete": "不揮拳或使用炸彈的情況下在 ${LEVEL}獲勝了", + "name": "蛇皮走位" + }, + "In Control": { + "descriptionFull": "連結一個控制器 (硬體或應用程式)", + "descriptionFullComplete": "已連結一個控制器 (硬體或應用程式)", + "name": "一切都在掌控之中" + }, + "Last Stand God": { + "description": "得到1000分", + "descriptionComplete": "已得到1000分", + "descriptionFull": "在 ${LEVEL}得到1000分", + "descriptionFullComplete": "已在 ${LEVEL}得到了1000分", + "name": "${LEVEL} 之神" + }, + "Last Stand Master": { + "description": "贏得250分", + "descriptionComplete": "已贏得了250分", + "descriptionFull": "在 ${LEVEL}贏得250分", + "descriptionFullComplete": "在 ${LEVEL}贏得了250分", + "name": "${LEVEL}大師" + }, + "Last Stand Wizard": { + "description": "贏得500分", + "descriptionComplete": "已贏得了500分", + "descriptionFull": "在 ${LEVEL}贏得500分", + "descriptionFullComplete": "在 ${LEVEL}贏得了500分", + "name": "${LEVEL}巫師" + }, + "Mine Games": { + "description": "用地雷殺死三個壞蛋", + "descriptionComplete": "已用地雷殺死了三個壞蛋", + "descriptionFull": "在 ${LEVEL}用地雷殺死三個壞蛋", + "descriptionFullComplete": "在 ${LEVEL}用地雷殺死了三個壞蛋", + "name": "地雷遊戲" + }, + "Off You Go Then": { + "description": "把三個壞蛋丟出地圖外", + "descriptionComplete": "把三個壞蛋丟出地圖外了", + "descriptionFull": "在 ${LEVEL}把三個壞蛋丟出地圖外", + "descriptionFullComplete": "在 ${LEVEL}把三個壞蛋丟出地圖外了", + "name": "滾出去!!!" + }, + "Onslaught God": { + "description": "贏得5000分", + "descriptionComplete": "贏得了5000分", + "descriptionFull": "在 ${LEVEL}贏得5000分", + "descriptionFullComplete": "在 ${LEVEL}贏得了5000分", + "name": "${LEVEL}衝鋒神" + }, + "Onslaught Master": { + "description": "得分500分", + "descriptionComplete": "獲得500分", + "descriptionFull": "在${LEVEL}裡獲得500分", + "descriptionFullComplete": "在${LEVEL}裡獲得500分", + "name": "${LEVEL}專家" + }, + "Onslaught Training Victory": { + "description": "擊敗所有敵人", + "descriptionComplete": "擊敗所有敵人", + "descriptionFull": "擊敗${LEVEL}中的所有敵人", + "descriptionFullComplete": "擊敗了${LEVEL}中的所有敵人", + "name": "${LEVEL}獲勝" + }, + "Onslaught Wizard": { + "description": "獲得1000分", + "descriptionComplete": "獲得1000分", + "descriptionFull": "在${LEVEL}裡獲得1000分", + "descriptionFullComplete": "在${LEVEL}裡獲得了1000分", + "name": "${LEVEL}精英" + }, + "Precision Bombing": { + "description": "不使用任何道具獲勝", + "descriptionComplete": "不使用任何道具就獲勝了", + "descriptionFull": "在${LEVEL}裡不使用任何道具獲勝", + "descriptionFullComplete": "在${LEVEL}裡不使用任何道具就", + "name": "精準爆破" + }, + "Pro Boxer": { + "description": "不使用任何炸彈獲勝", + "descriptionComplete": "不使用任何炸彈就獲勝了", + "descriptionFull": "在${LEVEL}裡不使用任何炸彈獲勝", + "descriptionFullComplete": "在${LEVEL}裡不使用任何炸彈就獲勝了", + "name": "職業拳擊手" + }, + "Pro Football Shutout": { + "description": "在敵人不得分的情況下獲勝", + "descriptionComplete": "在敵人不得分的情況下就獲勝了", + "descriptionFull": "在${LEVEL}裡不然敵人得分就獲勝了", + "descriptionFullComplete": "在${LEVEL}裡不然敵人得分就獲勝了", + "name": "無懈可擊的${LEVEL}" + }, + "Pro Football Victory": { + "description": "贏得比賽", + "descriptionComplete": "贏得了比賽", + "descriptionFull": "在${LEVEL}裡獲勝", + "descriptionFullComplete": "在${LEVEL}裡獲勝了", + "name": "${LEVEL}獲勝" + }, + "Pro Onslaught Victory": { + "description": "擊敗所有敵人", + "descriptionComplete": "擊敗了所有敵人", + "descriptionFull": "擊敗${LEVEL}裡的所有敵人", + "descriptionFullComplete": "擊敗了${LEVEL}裡的所有敵人", + "name": "${LEVEL}獲勝" + }, + "Pro Runaround Victory": { + "description": "擊敗所有敵人", + "descriptionComplete": "擊敗了所有敵人", + "descriptionFull": "擊敗${LEVEL}裡的所有敵人", + "descriptionFullComplete": "擊敗了${LEVEL}裡的所有敵人", + "name": "${LEVEL}h獲勝" + }, + "Rookie Football Shutout": { + "description": "不讓敵人得分的情況下獲勝", + "descriptionComplete": "不讓敵人得分的情況下就獲勝了", + "descriptionFull": "不讓敵人得分的情況下獲得${LEVEL}的勝利", + "descriptionFullComplete": "不讓敵人得分的情況下就在${LEVEL}獲勝", + "name": "無懈可擊的${LEVEL}" + }, + "Rookie Football Victory": { + "description": "獲得比賽的勝利", + "descriptionComplete": "獲得了比賽的勝利", + "descriptionFull": "在${LEVEL}裡獲勝", + "descriptionFullComplete": "在${LEVEL}裡獲勝了", + "name": "${LEVEL}獲勝" + }, + "Rookie Onslaught Victory": { + "description": "擊敗所有敵人", + "descriptionComplete": "擊敗了所有敵人", + "descriptionFull": "擊敗${LEVEL}裡的所有敵人", + "descriptionFullComplete": "擊敗了${LEVEL}裡的所有敵人", + "name": "${LEVEL}獲勝" + }, + "Runaround God": { + "description": "獲得2000分", + "descriptionComplete": "獲得了2000分", + "descriptionFull": "在${LEVEL}裡獲得2000分", + "descriptionFullComplete": "在${LEVEL}裡獲得了2000分", + "name": "${LEVEL}大師" + }, + "Runaround Master": { + "description": "獲得500分", + "descriptionComplete": "獲得了500分", + "descriptionFull": "在${LEVEL}裡獲得500分", + "descriptionFullComplete": "在${LEVEL}裡獲得了500分", + "name": "${LEVEL}專家" + }, + "Runaround Wizard": { + "description": "獲得1000分", + "descriptionComplete": "獲得了1000分", + "descriptionFull": "在${LEVEL}裡獲得1000分", + "descriptionFullComplete": "在${LEVEL}裡獲得了1000分", + "name": "${LEVEL}精英" + }, + "Sharing is Caring": { + "descriptionFull": "成功給朋友推薦遊戲", + "descriptionFullComplete": "成功給朋友推薦了遊戲", + "name": "分享的快樂" + }, + "Stayin' Alive": { + "description": "不死亡獲勝", + "descriptionComplete": "不死亡就獲勝了", + "descriptionFull": "在${LEVEL}裡不死亡獲勝", + "descriptionFullComplete": "在${LEVEL}裡不死亡就獲勝了", + "name": "我……還活著" + }, + "Super Mega Punch": { + "description": "一拳造成100%的傷害", + "descriptionComplete": "一拳造成了100%的傷害", + "descriptionFull": "在${LEVEL}裡一拳造成100%的傷害", + "descriptionFullComplete": "在${LEVEL}裡一拳造成了100%的傷害", + "name": "鑽石之拳" + }, + "Super Punch": { + "description": "一拳造成50%的傷害", + "descriptionComplete": "一拳造成了50%的傷害", + "descriptionFull": "在${LEVEL}裡一拳造成了50%的傷害", + "descriptionFullComplete": "在${LEVEL}裡一拳造成了50%的傷害", + "name": "黃金之拳" + }, + "TNT Terror": { + "description": "用TNT殺死六個敵人", + "descriptionComplete": "用TNT殺死了六個敵人", + "descriptionFull": "在${LEVEL}裡用TNT殺死六個敵人", + "descriptionFullComplete": "在${LEVEL}裡用TNT殺死了六個敵人", + "name": "爆破鬼才" + }, + "Team Player": { + "descriptionFull": "開始一個四人以上的比賽", + "descriptionFullComplete": "開始了一個四人以上的比賽", + "name": "團隊遊戲" + }, + "The Great Wall": { + "description": "阻止所有敵人", + "descriptionComplete": "阻止了所有敵人", + "descriptionFull": "在${LEVEL}裡阻止了所有敵人", + "descriptionFullComplete": "在${LEVEL}裡阻止了所有敵人", + "name": "城牆" + }, + "The Wall": { + "description": "阻止所有敵人", + "descriptionComplete": "阻止了所有敵人", + "descriptionFull": "在${LEVEL}裡阻止了所有敵人", + "descriptionFullComplete": "在${LEVEL}裡阻止了所有敵人", + "name": "高牆" + }, + "Uber Football Shutout": { + "description": "不讓敵人得分並獲勝", + "descriptionComplete": "不讓敵人得分就獲勝了", + "descriptionFull": "在${LEVEL}裡不讓敵人得分就是獲勝了", + "descriptionFullComplete": "在${LEVEL}裡不讓敵人得分就獲勝了", + "name": "無懈可擊的${LEVEL}" + }, + "Uber Football Victory": { + "description": "贏得比賽", + "descriptionComplete": "贏得比賽", + "descriptionFull": "在${LEVEL}裡獲勝", + "descriptionFullComplete": "在${LEVEL}裡獲得勝利", + "name": "${LEVEL}獲勝" + }, + "Uber Onslaught Victory": { + "description": "擊敗所有敵人", + "descriptionComplete": "擊敗了所有敵人", + "descriptionFull": "擊敗了${LEVEL}裡的所有敵人", + "descriptionFullComplete": "擊敗了${LEVEL}裡的所有敵人", + "name": "${LEVEL}勝利" + }, + "Uber Runaround Victory": { + "description": "擊敗所有敵人", + "descriptionComplete": "擊敗了所有敵人", + "descriptionFull": "擊敗了${LEVEL}裡的所有敵人", + "descriptionFullComplete": "擊敗了${LEVEL}裡的所有敵人", + "name": "${LEVEL}勝利" + } + }, + "achievementsRemainingText": "未完成的成就", + "achievementsText": "成就", + "achievementsUnavailableForOldSeasonsText": "抱歉,往屆成就細節不可用", + "activatedText": "${THING}已激活", + "addGameWindow": { + "getMoreGamesText": "獲取更多比賽模式", + "titleText": "新增比賽" + }, + "allowText": "允許", + "alreadySignedInText": "你的賬號已在其他設備上登錄\n請退出其他設備的登錄\n然後重試", + "apiVersionErrorText": "無法加載模塊${NAME},它的API版本為${VERSION_USED},我們需要${VERSION_REQUIRED}。", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(“自動”僅在插入耳機時有效)", + "headRelativeVRAudioText": "頭戴式VR音頻", + "musicVolumeText": "音樂音量", + "soundVolumeText": "音效音量", + "soundtrackButtonText": "自定義音軌", + "soundtrackDescriptionText": "(導入自定義的音樂)", + "titleText": "音樂音量" + }, + "autoText": "自動", + "backText": "返回", + "banThisPlayerText": "禁止這個玩家", + "bestOfFinalText": "${COUNT}的最後一局", + "bestOfSeriesText": "${COUNT}決勝制", + "bestRankText": "你的最佳是#${RANK}", + "bestRatingText": "你的最高評價是${RATING}", + "bombBoldText": "炸彈", + "bombText": "炸彈", + "boostText": "加速", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME}是在应用本身中配置的。", + "buttonText": "按鈕", + "canWeDebugText": "你想要炸彈小分隊自動報告\n錯誤信息給開發人員嗎?\n\n信息中不包含個人信息\n可用於遊戲更加穩定", + "cancelText": "取消", + "cantConfigureDeviceText": "抱歉,${DEVICE}不可配置", + "challengeEndedText": "此比賽挑戰已結束", + "chatMuteText": "屏蔽消息", + "chatMutedText": "屏蔽聊天信息", + "chatUnMuteText": "取消屏蔽消息", + "choosingPlayerText": "<選擇玩家>", + "completeThisLevelToProceedText": "你需要先完成\n這一關", + "completionBonusText": "完成獎勵", + "configControllersWindow": { + "configureControllersText": "設置遊戲手柄", + "configureKeyboard2Text": "設置本地第二鍵盤", + "configureKeyboardText": "設置鍵盤", + "configureMobileText": "用移動電話作控制器", + "configureTouchText": "設置觸屏", + "ps3Text": "PS3 控制器設置", + "titleText": "手柄", + "wiimotesText": "Wiimotes", + "xbox360Text": "Xbox 360 手柄" + }, + "configGamepadSelectWindow": { + "androidNoteText": "注意:手柄支持取決於你的Android版本", + "pressAnyButtonText": "點擊手柄任意按鈕\n以繼續設置...", + "titleText": "手柄測試" + }, + "configGamepadWindow": { + "advancedText": "高級設置", + "advancedTitleText": "高級控制器設置", + "analogStickDeadZoneDescriptionText": "(釋放搖桿時角色出現“漂移”時調高)", + "analogStickDeadZoneText": "模擬搖桿盲區", + "appliesToAllText": "(適用於所有該類型手柄)", + "autoRecalibrateDescriptionText": "(角色未全速移動時有效)", + "autoRecalibrateText": "自動校準模擬搖桿", + "axisText": "搖桿軸", + "clearText": "清除", + "dpadText": "方向鍵", + "extraStartButtonText": "額外啟動按鈕", + "ifNothingHappensTryAnalogText": "如果無法使用,請手動設置模擬搖桿", + "ifNothingHappensTryDpadText": "如果無法使用,請手動設置方向鍵", + "ignoreCompletelyDescriptionText": "(避免這個控制器影響遊戲或菜單)", + "ignoreCompletelyText": "已完全忽略", + "ignoredButton1Text": "已忽略 按鍵1", + "ignoredButton2Text": "已忽略 按鍵2", + "ignoredButton3Text": "已忽略 按鍵3", + "ignoredButton4Text": "已屏蔽 按鍵4", + "ignoredButtonDescriptionText": "(用於防止“主頁”或“同步”按鈕影響用戶界面)", + "pressAnyAnalogTriggerText": "按任意模擬板機", + "pressAnyButtonOrDpadText": "按任意鍵或方向鍵...", + "pressAnyButtonText": "按任意鍵...", + "pressLeftRightText": "按左或右...", + "pressUpDownText": "按上或下...", + "runButton1Text": "跑 按鍵1", + "runButton2Text": "跑 按鍵2", + "runTrigger1Text": "跑 扳機1", + "runTrigger2Text": "跑 扳機2", + "runTriggerDescriptionText": "(模擬板機可實現變速運行)", + "secondHalfText": "用於設置顯示為單一手柄的\n二合一手柄設備的\n第二部分", + "secondaryEnableText": "啟用", + "secondaryText": "從屬手柄", + "startButtonActivatesDefaultDescriptionText": "(如果啟動按鈕更傾向為“菜單按鈕”,則關閉此功能)", + "startButtonActivatesDefaultText": "啟動按鈕激活默認部件", + "titleText": "手柄設置", + "twoInOneSetupText": "二合一手柄設置", + "uiOnlyDescriptionText": "(組織這個控制器加入遊戲)", + "uiOnlyText": "限制菜單應用", + "unassignedButtonsRunText": "未給任何按鈕分配“跑”", + "unsetText": "<未設置>", + "vrReorientButtonText": "虛擬按鈕調整" + }, + "configKeyboardWindow": { + "configuringText": "配置 ${DEVICE}", + "keyboard2NoteText": "注意:很多鍵盤只能一次同時按下幾個按鍵\n所以如果玩家連接另一個鍵盤\n則兩個鍵盤可以獲得更好的遊戲體驗\n請注意:即使在這種情況下,您也仍需\n為兩個玩家分配獨特的按鍵" + }, + "configTouchscreenWindow": { + "actionControlScaleText": "動作搖桿大小", + "actionsText": "動作", + "buttonsText": "按鈕", + "dragControlsText": "<拖動按鍵以改變它們的位置>", + "joystickText": "遊戲搖桿", + "movementControlScaleText": "移動遙感大小", + "movementText": "移動", + "resetText": "重置", + "swipeControlsHiddenText": "隱藏滑動圖標", + "swipeInfoText": "“滑動”式控制是需要花時間來適應的\n但更嫻熟的使用可能會讓你在遊戲內表現的更好", + "swipeText": "滑動", + "titleText": "觸屏操作設置" + }, + "configureItNowText": "立即配置?", + "configureText": "配置", + "connectMobileDevicesWindow": { + "amazonText": "亞馬遜應用商店", + "appStoreText": "應用商店", + "bestResultsText": "更好的網絡環境可幫助你在遊戲內表現更好,你可以關閉\n其他無線設備來降低網絡延遲\n或者盡量在路由器附近\n再或者將遊戲主機使用有線網絡", + "explanationText": "如果想用智能手機或平板電腦作為控制器,請在手機或平板電腦上安裝\n\"${REMOTE_APP_NAME}\"軟件。${APP_NAME}可以在局域網環境下\n同時支持八個設備的鏈接,這些完全免費", + "forAndroidText": "對於Android:", + "forIOSText": "對於iOS:", + "getItForText": "iOS用戶可從${REMOTE_APP_NAME}獲取Bombsquad控制器\nAndroid用戶可從Google Play商店或Amazon應用商店下載", + "googlePlayText": "Google Play商店", + "titleText": "使用移動裝置作為控制器:" + }, + "continuePurchaseText": "花費${PRICE}繼續?", + "continueText": "繼續", + "controlsText": "控制按鍵", + "coopSelectWindow": { + "activenessAllTimeInfoText": "不提供所有時間的排名", + "activenessInfoText": "倍數隨著遊戲天數增加\n隨著離線天數減少", + "activityText": "活動", + "campaignText": "比賽", + "challengesInfoText": "獲得完成迷你遊戲的獎勵\n\n每完成一項挑戰\n獎勵和難度就會隨之增加\n每挑戰失敗或放棄一次,獎勵和難度就會隨之下降", + "challengesText": "挑戰", + "currentBestText": "當前最高分", + "customText": "自定義", + "entryFeeText": "參賽", + "forfeitConfirmText": "要放棄此挑戰嗎?", + "forfeitNotAllowedYetText": "目前不能放棄此挑戰", + "forfeitText": "放棄", + "multipliersText": "倍數", + "nextChallengeText": "下一次挑戰", + "nextPlayText": "下一次遊戲", + "ofTotalTimeText": "在 ${TOTAL}", + "playNowText": "現在開始", + "pointsText": "分數", + "powerRankingFinishedSeasonUnrankedText": "(以結束賽季,無排名)", + "powerRankingNotInTopText": "(在 ${NUMBER}名次以外)", + "powerRankingPointsEqualsText": "= ${NUMBER} 分", + "powerRankingPointsMultText": "(x ${NUMBER} 分)", + "powerRankingPointsText": "${NUMBER} 分", + "powerRankingPointsToRankedText": "(共${CURRENT}分 已獲得${REMAINING}分)", + "powerRankingText": "能力排位", + "prizesText": "獎勵", + "proMultInfoText": "擁有 ${PRO} 的玩家\n可獲得 ${PERCENT}% 的得分加成", + "seeMoreText": "更多", + "skipWaitText": "跳過等待", + "timeRemainingText": "剩餘時間", + "toRankedText": "排名", + "totalText": "總計", + "tournamentInfoText": "與聯賽中的玩家\n爭奪分數\n\n錦標賽時間結束時\n最高分玩家將會獲得獎勵", + "welcome1Text": "歡迎來到${LEAGUE}。你可以通過\n在錦標賽中獲得獎杯、完成成就及\n獲得冠軍來提升你的聯賽排名", + "welcome2Text": "你還可以參加很多相同活動來贏取點券\n點券可以用於解鎖新角色、地圖、圖標\n和迷你遊戲,或購買錦標賽門票", + "yourPowerRankingText": "你的能力排名:" + }, + "copyConfirmText": "複製到剪切板", + "copyOfText": "${NAME} 拷貝", + "copyText": "複製", + "createEditPlayerText": "<創建/編輯玩家>", + "createText": "創建", + "creditsWindow": { + "additionalAudioArtIdeasText": "音頻補充、初期原稿和創意: ${NAME}", + "additionalMusicFromText": "補充背景音樂: ${NAME}", + "allMyFamilyText": "幫助進行遊戲測試的朋友和家人", + "codingGraphicsAudioText": "代碼,貼圖和音頻: ${NAME}", + "languageTranslationsText": "翻譯:", + "legalText": "法律", + "publicDomainMusicViaText": "版權共有音樂: ${NAME}", + "softwareBasedOnText": "該軟件基於 ${NAME}的工作", + "songCreditText": "${TITLE} 演唱: ${PERFORMER}\n作曲: ${COMPOSER},改編: ${ARRANGER},發行: ${PUBLISHER}\n由 ${SOURCE}提供", + "soundAndMusicText": "音樂&音效:", + "soundsText": "音樂 (${SOURCE}):", + "specialThanksText": "特別鳴謝:", + "thanksEspeciallyToText": "尤其感謝 ${NAME}", + "titleText": "${APP_NAME} 製作團隊", + "whoeverInventedCoffeeText": "製作咖啡的人" + }, + "currentStandingText": "您目前的排名是 #${RANK}", + "customizeText": "自定義…", + "deathsTallyText": "${COUNT}次死亡", + "deathsText": "死亡", + "debugText": "測試", + "debugWindow": { + "reloadBenchmarkBestResultsText": "注意:建議您在調試階段將設置—>畫面—>紋理設置為“高”", + "runCPUBenchmarkText": "CPU壓力測試", + "runGPUBenchmarkText": "CPU壓力測試", + "runMediaReloadBenchmarkText": "運行媒體重載基準程序", + "runStressTestText": "運行壓力測試", + "stressTestPlayerCountText": "模擬玩家數量", + "stressTestPlaylistDescriptionText": "壓力測試列表", + "stressTestPlaylistNameText": "列表名稱", + "stressTestPlaylistTypeText": "列表類型", + "stressTestRoundDurationText": "回合時長", + "stressTestTitleText": "壓力測試", + "titleText": "基準程序和壓力測試", + "totalReloadTimeText": "總計裝載時間: ${TIME} (詳見日誌)" + }, + "defaultGameListNameText": "默認${PLAYMODE}列表", + "defaultNewGameListNameText": "我的${PLAYMODE}列表", + "deleteText": "刪除", + "demoText": "演示", + "denyText": "拒絕", + "deprecatedText": "棄用", + "desktopResText": "桌面分辨率", + "deviceAccountUpgradeText": "警告:\n您已使用設備帳戶(${NAME})登錄。\n設備帳戶將在未來的更新中刪除。\n如果您想保留賬戶,請升級到 V2 帳戶。", + "difficultyEasyText": "簡單", + "difficultyHardOnlyText": "僅困難模式", + "difficultyHardText": "困難", + "difficultyHardUnlockOnlyText": "該關卡僅在困難模式解鎖.\n你相信你有奪冠的能力嗎!?!?!", + "directBrowserToURLText": "請打開瀏覽器訪問以下URL:", + "disableRemoteAppConnectionsText": "取消Remote應用連接", + "disableXInputDescriptionText": "允許使用四個以上的控制器,但可能不會正常工作", + "disableXInputText": "禁用XInput", + "doneText": "完成", + "drawText": "平局", + "duplicateText": "複製", + "editGameListWindow": { + "addGameText": "添加\n比賽", + "cantOverwriteDefaultText": "不可以覆蓋默認的遊戲列表", + "cantSaveAlreadyExistsText": "已存在一個同名稱的遊戲列表", + "cantSaveEmptyListText": "不可以保存空白的遊戲列表", + "editGameText": "編輯\n比賽", + "listNameText": "遊戲列表名稱", + "nameText": "名稱", + "removeGameText": "刪除\n比賽", + "saveText": "保存列表", + "titleText": "遊戲列表編輯器" + }, + "editProfileWindow": { + "accountProfileInfoText": "此特殊玩家檔案\n可能含有其中一個圖標\n\n${ICONS}\n\n基於你的登錄平台以顯示\n相關圖標", + "accountProfileText": "(賬戶資料)", + "availableText": "\"${NAME}\" 可用", + "characterText": "腳色", + "checkingAvailabilityText": "正在檢查\"${NAME}\"是否可用", + "colorText": "顏色", + "getMoreCharactersText": "獲得更多角色...", + "getMoreIconsText": "獲得更多圖標...", + "globalProfileInfoText": "全球玩家檔案名稱不會重複\n並且可以自定義圖標", + "globalProfileText": "(全球檔案)", + "highlightText": "副顏色", + "iconText": "圖標", + "localProfileInfoText": "本地玩家檔案不含圖標,且玩家名稱不具備唯一性\n升級至全球檔案,以擁有唯一的遊戲名稱,並且自定義圖標\n#警告:切勿使用隨機名稱,被使用的可能性很大", + "localProfileText": "(本地檔案)", + "nameDescriptionText": "玩家名稱", + "nameText": "名稱", + "randomText": "隨機", + "titleEditText": "編輯檔案", + "titleNewText": "新建檔案", + "unavailableText": "\"${NAME}\" 不可用,請使用其他名稱", + "upgradeProfileInfoText": "這可以在全球範圍內保存您的萬家名稱\n並且你可以自定義一個圖標", + "upgradeToGlobalProfileText": "升級至全球檔案" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "不能刪除默認的背景音與", + "cantEditDefaultText": "不能編輯默認的背景音樂。請備份或創建一個新的背景音樂列表", + "cantOverwriteDefaultText": "不可以覆蓋默認的背景音樂", + "cantSaveAlreadyExistsText": "這個名字的背景音樂已經存在", + "defaultGameMusicText": "<默認背景音樂>", + "defaultSoundtrackNameText": "默認自定義背景音樂", + "deleteConfirmText": "刪除自定義背景音樂\n\n“${NAME}”?", + "deleteText": "刪除\n自定義背景音樂", + "duplicateText": "備份\n自定義背景音樂", + "editSoundtrackText": "自定義背景音樂編輯器", + "editText": "編輯\n自定義背景音樂", + "fetchingITunesText": "正在獲取音樂軟件播放列表...", + "musicVolumeZeroWarning": "注意:目前音量為0", + "nameText": "名稱", + "newSoundtrackNameText": "我的背景音樂${COUNT}", + "newSoundtrackText": "新的背景音樂", + "newText": "創建\n背景音樂", + "selectAPlaylistText": "選擇一個音樂列表", + "selectASourceText": "音樂來源", + "testText": "測試", + "titleText": "自定義背景音樂", + "useDefaultGameMusicText": "默認遊戲音樂", + "useITunesPlaylistText": "音樂軟件播放列表", + "useMusicFileText": "音樂文件(MP3等...)", + "useMusicFolderText": "音樂文件夾" + }, + "editText": "修改", + "endText": "結束", + "enjoyText": "盡情享用吧", + "epicDescriptionFilterText": "史詩級慢動作${DESCRIPTION}", + "epicNameFilterText": "史詩級${NAME}", + "errorAccessDeniedText": "訪問被拒絕", + "errorDeviceTimeIncorrectText": "您的系統時間與BS伺服器相差了${HOURS}小時\n這可能會出現一些問題\n請檢查你的系統時間或時區", + "errorOutOfDiskSpaceText": "磁盤空間不足", + "errorSecureConnectionFailText": "無法安全的連接到伺服器,網絡功能可能會失效", + "errorText": "錯誤", + "errorUnknownText": "未知錯誤", + "exitGameText": "退出${APP_NAME}?", + "exportSuccessText": "退出'${NAME}'", + "externalStorageText": "外部存儲器", + "failText": "失敗", + "fatalErrorText": "有一些遊戲檔案遺失或被損壞\n請嘗試重新安裝退遊戲\n或者聯繫${EMAIL}尋求幫助", + "fileSelectorWindow": { + "titleFileFolderText": "選擇一個文件或文件夾", + "titleFileText": "選擇一個文件", + "titleFolderText": "選擇一個文件夾", + "useThisFolderButtonText": "使用此文件夾" + }, + "filterText": "过滤器", + "finalScoreText": "最後得分", + "finalScoresText": "最後得分", + "finalTimeText": "最終時間", + "finishingInstallText": "安裝即將完成...", + "fireTVRemoteWarningText": "*為獲得更好的遊戲體驗\n請使用遊戲手柄\n或者在你的手機或平板電腦安裝\n'${REMOTE_APP_NAME}'", + "firstToFinalText": "${COUNT} 局自由混戰賽最後得分", + "firstToSeriesText": "${COUNT}局的自由混戰賽", + "fiveKillText": "五連殺!!!!", + "flawlessWaveText": "無傷通過!", + "fourKillText": "四連殺!!!", + "friendScoresUnavailableText": "無法獲取好友的得分", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "最高得分玩家數${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "你不能刪除默認的遊戲列表", + "cantEditDefaultText": "不能編輯默認的遊戲列表!請複製或新建一個", + "cantShareDefaultText": "你不能分享默認列表", + "deleteConfirmText": "是否刪除\"${LIST}\"?", + "deleteText": "刪除\n遊戲列表", + "duplicateText": "複製\n比賽列表", + "editText": "編輯\n比賽列表", + "newText": "新建\n比賽列表", + "showTutorialText": "顯示新手教程", + "shuffleGameOrderText": "隨機比賽模式", + "titleText": "自定義${TYPE}列表" + }, + "gameSettingsWindow": { + "addGameText": "添加比賽" + }, + "gamesToText": "${WINCOUNT}比${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "請注意:如果你有足夠多的遊戲手柄\n派對中的任意設備可以允許多個玩家同時遊戲", + "aboutDescriptionText": "使用這些選項卡來組織一場派對\n\n通過派對,你可以和好友在不同的設備上\n一起玩遊戲和比賽\n\n使用手柄右上角的${PARTY}按鈕\n來發起派對聊天和互動\n(在菜單時按${BUTTON})", + "aboutText": "關於", + "addressFetchErrorText": "<獲取地址錯誤>", + "appInviteMessageText": "${NAME} 在 ${APP_NAME} 送給了您 ${COUNT} 點券", + "appInviteSendACodeText": "向他們發送一個代碼", + "appInviteTitleText": "${APP_NAME} 邀請碼", + "bluetoothAndroidSupportText": "(適用於任何支持藍牙功能的Android設備)", + "bluetoothDescriptionText": "使用藍牙創建遊戲或加入遊戲", + "bluetoothHostText": "使用藍牙創建遊戲", + "bluetoothJoinText": "通過藍牙加入遊戲", + "bluetoothText": "藍牙", + "checkingText": "檢查中...", + "copyCodeConfirmText": "代碼已複製進剪切板", + "copyCodeText": "複製此代碼", + "dedicatedServerInfoText": "建立一個伺服器來獲取最佳效果,詳情見bombsquadgame.com/server", + "disconnectClientsText": "這將使派對中的${COUNT}位玩家斷開連接\n確定這麼做嗎?", + "earnTicketsForRecommendingAmountText": "如果您的朋友們玩了這款遊戲,它們將會受到${COUNT}點券\n(每個遊玩的朋友會使你獲取${YOU_COUNT}點券)", + "earnTicketsForRecommendingText": "分享遊戲來\n獲取免費點券...", + "emailItText": "通過電子郵件發送", + "favoritesSaveText": "另存為收藏", + "favoritesText": "收藏", + "freeCloudServerAvailableMinutesText": "你需要${MINUTES}分鐘後才可獲取一個免費的伺服器", + "freeCloudServerAvailableNowText": "免費伺服器可用", + "freeCloudServerNotAvailableText": "非免費伺服器可用", + "friendHasSentPromoCodeText": "從${NAME}中獲取到${COUNT}個${APP_NAME}點券", + "friendPromoCodeAwardText": "每使用一次,你就會收到${COUNT}張點券", + "friendPromoCodeExpireText": "此代碼將在${EXPIRE_HOURS}小時後失效,該代碼只對新玩家有效", + "friendPromoCodeInstructionsText": "要使用此代碼,可打開${APP_NAME}。通過“設置->高級設置->輸入促銷代碼”操作\n所有支持平台的下載鏈接可見bombsquadgame.com", + "friendPromoCodeRedeemLongText": "達到${MAX_USES}人後就不能獲得${COUNT}免費點券(防止玩家作弊)", + "friendPromoCodeRedeemShortText": "可在遊戲中兌換${COUNT}免費點券", + "friendPromoCodeWhereToEnterText": "(在“設置->高級設置->輸入促銷代碼”中)", + "getFriendInviteCodeText": "獲取好友邀請碼", + "googlePlayDescriptionText": "通過Google Play邀請玩家進入你的派對", + "googlePlayInviteText": "邀請", + "googlePlayReInviteText": "如果你發送一個邀請\n則你的派對中的${COUNT}位Google Play玩家將斷開連接\n在發出新邀請中再次邀請他們,讓他們回到派對", + "googlePlaySeeInvitesText": "查看邀請", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android/Google Play 設備)", + "hostPublicPartyDescriptionText": "創建一個公開派對", + "hostingUnavailableText": "主機不可用", + "inDevelopmentWarningText": "注意:\n\n聯網模式是一項新的並且還在開發階段\n目前強烈建議所有玩家在\n局域網環境下進行遊戲", + "internetText": "在線遊戲", + "inviteAFriendText": "好友還未加入遊戲?邀請他們加入遊戲\n新玩家還可以獲得${COUNT}免費點券", + "inviteFriendsText": "邀請朋友", + "joinPublicPartyDescriptionText": "加入一個公開派對", + "localNetworkDescriptionText": "加入一個附近的派對(局域網,藍牙,etc等)", + "localNetworkText": "本地局域網", + "makePartyPrivateText": "將我的派對變成私人派對", + "makePartyPublicText": "將我的派對變成公開排隊", + "manualAddressText": "地址", + "manualConnectText": "連接", + "manualDescriptionText": "加入派對,地址:", + "manualJoinSectionText": "使用地址加入", + "manualJoinableFromInternetText": "能否從互聯網連接:", + "manualJoinableNoWithAsteriskText": "否*", + "manualJoinableYesText": "能", + "manualRouterForwardingText": "*若要解決此問題,請嘗試將你的路由器設置為將UDP端口 ${PORT}轉發到你的本地地址", + "manualText": "手動", + "manualYourAddressFromInternetText": "互聯網地址:", + "manualYourLocalAddressText": "本地地址:", + "nearbyText": "附近", + "noConnectionText": "<無連接>", + "otherVersionsText": "(其他版本)", + "partyCodeText": "派對代碼", + "partyInviteAcceptText": "接受", + "partyInviteDeclineText": "拒絕", + "partyInviteGooglePlayExtraText": "(查看“多人遊戲”窗口的“Google Play”選項卡)", + "partyInviteIgnoreText": "忽略", + "partyInviteText": "${NAME} 已邀請\n你可以加入他們的派對", + "partyNameText": "排隊名稱", + "partyServerRunningText": "你的派對伺服器正在運行", + "partySizeText": "派對人數", + "partyStatusCheckingText": "檢查中...", + "partyStatusJoinableText": "你的派對現在可以從公開派對列表中加入了", + "partyStatusNoConnectionText": "無法連接到伺服器", + "partyStatusNotJoinableText": "你的派對無法從公開派對列表加入", + "partyStatusNotPublicText": "你的派對是私人派對", + "pingText": "網絡延遲", + "portText": "端口", + "privatePartyCloudDescriptionText": "私有方在專用的伺服器上運行,無需進行路由器配置", + "privatePartyHostText": "舉辦私人派對", + "privatePartyJoinText": "加入一個私人派對", + "privateText": "私人", + "publicHostRouterConfigText": "這可能需要配置路由器進行端口轉發,為了更簡單的選擇,請舉辦一個私人派對", + "publicText": "公開", + "requestingAPromoCodeText": "正在請求代碼...", + "sendDirectInvitesText": "直接邀請", + "shareThisCodeWithFriendsText": "給好友分享此代碼", + "showMyAddressText": "顯示我的地址", + "startHostingPaidText": "使用${COST}去創建一個派對", + "startHostingText": "開始", + "startStopHostingMinutesText": "你的下一個免費服務器將在${MINUTES}後可被開始或停止", + "stopHostingText": "停止", + "titleText": "多人遊戲", + "wifiDirectDescriptionBottomText": "如果所有設備都沒有'Wi-Fi Direct'界面,那他們應該可以通過它找到彼此\n然後互相連接。一旦所有的設備都互相連接上了,你就可以通過“本地網絡”選項卡\n在此組織派對,常規的局域網也是一樣\n\n如果要獲取最佳的效果,Wi-Fi Direct創建者也應是${APP_NAME}派對的創建者", + "wifiDirectDescriptionTopText": "無需打開網絡連接即可直接\n通過Wi-Fi Direct連接安卓設備。對Android4.2及以上的系統版本效果更好\n\n要使用該功能。可打開網絡設置,然後在菜單中尋找'Wi-Fi Direct'", + "wifiDirectOpenWiFiSettingsText": "打開無線網絡設置", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(所有平台之間運作)", + "worksWithGooglePlayDevicesText": "(適用於運行Google Play(Android)版遊戲的設備)", + "youHaveBeenSentAPromoCodeText": "您已送出一個${APP_NAME}促銷代碼:" + }, + "getTicketsWindow": { + "freeText": "免費!", + "freeTicketsText": "免費點券", + "inProgressText": "一個交易正在進行:請稍後再試", + "purchasesRestoredText": "購買恢復", + "receivedTicketsText": "獲得${COUNT}點券", + "restorePurchasesText": "恢復購買", + "ticketPack1Text": "小型點券包", + "ticketPack2Text": "中型點券包", + "ticketPack3Text": "大型點券包", + "ticketPack4Text": "局型點券包", + "ticketPack5Text": "巨巨巨巨巨巨巨巨巨巨型點券包", + "ticketPack6Text": "終極點券包", + "ticketsFromASponsorText": "看推廣影片\n獲取${COUNT}點券", + "ticketsText": "${COUNT} 點券", + "titleText": "獲得點券", + "unavailableLinkAccountText": "對不起,該平台不可進行購買\n您可以將賬戶鏈接到另一個\n平台,以進行購買", + "unavailableTemporarilyText": "該選項當前不可用;請稍後再試", + "unavailableText": "對不起,該選項目前不可用", + "versionTooOldText": "對不起,你的遊戲版本太舊了;請更新到最新版本", + "youHaveShortText": "你擁有 ${COUNT}", + "youHaveText": "你擁有 ${COUNT}點券" + }, + "googleMultiplayerDiscontinuedText": "抱歉,Google的多人遊戲服務不再可用。\n我將盡快更換新的替代服務。\n在此之前,請嘗試其他連接方法。\n-Eric", + "googlePlayPurchasesNotAvailableText": "Google Play購買不可用\n你可能需要更新你的Google Play商店組件", + "googlePlayServicesNotAvailableText": "Google play當前不可用\n一些功能將會被禁用", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "總是", + "fullScreenCmdText": "全屏顯示Cmd-F", + "fullScreenCtrlText": "全屏顯示(Ctrl-F)", + "gammaText": "Gamma", + "highText": "高", + "higherText": "最高", + "lowText": "低", + "mediumText": "中", + "neverText": "關", + "resolutionText": "分辨率", + "showFPSText": "顯示幀數", + "texturesText": "材質質量", + "titleText": "貼圖質量", + "tvBorderText": "UI微縮進", + "verticalSyncText": "垂直同步", + "visualsText": "視覺" + }, + "helpWindow": { + "bombInfoText": "—炸彈—\n比拳頭傷害高,但也能對自己造成傷害\n給你個建議:\n在引線快要燒完時\n把炸彈扔向敵人", + "canHelpText": "${APP_NAME}可以給你幫助", + "controllersInfoText": "你可以正在局域網環境下與其他玩家遊玩${APP_NAME} ,或者\n你有足夠多的遊戲手柄,那樣也可以在同一個設備下游戲\n${APP_NAME}支持各種選擇;你甚至可以通過免費的 '${REMOTE_APP_NAME}' \n用手機或平板電腦作為遊戲手柄\n更多信息,請參考\"設置—>控制器\"", + "controllersInfoTextRemoteOnly": "你可以和好友在同一網路下玩${APP_NAME},或者你們\n可以通過使用免費的應用'${REMOTE_APP_NAME}'\n來將手機作爲遊戲控制手柄在同一個設備上遊戲", + "controllersText": "手柄", + "controlsSubtitleText": "你的好友的${APP_NAME}角色具有幾個基本動作", + "controlsText": "控制鍵", + "devicesInfoText": "VR版${APP_NAME}可與\n普通版本進行聯網遊戲,所以掏出你的所有手機、平板電腦\n和電腦,盡情暢玩吧。你甚至可以將\n普通版本的遊戲連機至VR版\n讓遊戲外的人也能看到遊戲畫面", + "devicesText": "設備", + "friendsGoodText": "這對於你而言是個好事,與三五好友一起玩${APP_NAME}最有趣了\n最對支持8個玩家一起玩", + "friendsText": "好友", + "jumpInfoText": "-跳躍-\n跳躍可以讓你跳過比較高的障礙物\n或者是讓你把炸彈扔的更遠\n又或者用來表達你的喜悅", + "orPunchingSomethingText": "或用券猛擊敵人,將他們打下懸崖,然後在下落的途中用粘性炸彈炸掉它", + "pickUpInfoText": "-撿起-\n你可以撿起旗子,敵人\n還有所有沒固定在地上的東西\n然後再扔出去吧", + "powerupBombDescriptionText": "連續扔出\n三連炸彈", + "powerupBombNameText": "三連炸彈", + "powerupCurseDescriptionText": "你可能想要避開那些\n...或者你想試試看?", + "powerupCurseNameText": "詛咒", + "powerupHealthDescriptionText": "讓你恢復所有生命值\n你永遠都想不到", + "powerupHealthNameText": "生命恢復", + "powerupIceBombsDescriptionText": "威力比普通炸彈小\n但能把你的敵人凍住\n並且變得十分脆弱", + "powerupIceBombsNameText": "冰凍炸彈", + "powerupImpactBombsDescriptionText": "威力比普通炸彈低\n但是碰到其他物品之後直接爆炸", + "powerupImpactBombsNameText": "觸感炸彈", + "powerupLandMinesDescriptionText": "大特價,買一贈二\n居家旅行,防守陣地的不二選擇\n還可以阻止那些跑的飛快的人", + "powerupLandMinesNameText": "地雷", + "powerupPunchDescriptionText": "沒有拳套的我唯唯諾諾\n擁有拳套的我重拳出擊", + "powerupPunchNameText": "拳擊手套", + "powerupShieldDescriptionText": "無可阻擋!\n堅不可摧!", + "powerupShieldNameText": "能量護盾", + "powerupStickyBombsDescriptionText": "可以黏在任何物體上\n(聽說它和TNT是死對頭)", + "powerupStickyBombsNameText": "粘性炸彈", + "powerupsSubtitleText": "當然,沒有道具的遊戲會變得很難通關", + "powerupsText": "道具", + "punchInfoText": "-拳擊-\n跑得越快,造成的傷害越高\n你可以嘗試一下“衝刺旋轉跳拳”\n當然,要注意防守", + "runInfoText": "-衝刺-\n按住任意鍵+移動=衝刺\n衝刺雖然跑得快,但會對轉彎造成困難", + "someDaysText": "有些時候你只是想揮拳猛擊默寫東西,或把什麼東西炸飛", + "titleText": "${APP_NAME}幫助", + "toGetTheMostText": "想要獲得更好的遊戲體驗,你需要:", + "welcomeText": "歡迎來到 ${APP_NAME}!" + }, + "holdAnyButtonText": "<按住任意按鈕>", + "holdAnyKeyText": "<按住任意鍵>", + "hostIsNavigatingMenusText": "-${HOST} 正在觀察主頁面-", + "importPlaylistCodeInstructionsText": "用代碼來導入列表", + "importPlaylistSuccessText": "成功導入${TYPE} 遊戲列表'${NAME}'", + "importText": "導入", + "importingText": "導入中...", + "inGameClippedNameText": "名字會是\n\"${NAME}\"", + "installDiskSpaceErrorText": "錯誤:無法完成安裝\n你的設備磁盤空間不足\n請釋放一些空間後重試", + "internal": { + "arrowsToExitListText": "按${LEFT} 或 ${RIGHT} 退出列表", + "buttonText": "按鈕", + "cantKickHostError": "你無法踢出創建者", + "chatBlockedText": "玩家${NAME} 被禁言 ${TIME} 秒", + "connectedToGameText": "加入 '${NAME}'", + "connectedToPartyText": "加入${NAME}的派對", + "connectingToPartyText": "正在連接...", + "connectionFailedHostAlreadyInPartyText": "連接失敗:創建者正在另一派對中", + "connectionFailedPartyFullText": "連接錯誤:房間滿員了", + "connectionFailedText": "連接失敗", + "connectionFailedVersionMismatchText": "連接失敗:創建者使用了更高的遊戲版本\n請確保你的遊戲版本與創建者一致再繼續", + "connectionRejectedText": "連接被拒絕", + "controllerConnectedText": "${CONTROLLER} 已連接", + "controllerDetectedText": "檢測到1個手柄", + "controllerDisconnectedText": "${CONTROLLER} 斷開連接", + "controllerDisconnectedTryAgainText": "${CONTROLLER} 斷開連接。請嘗試重新連接", + "controllerForMenusOnlyText": "此控制器無法在遊戲中使用", + "controllerReconnectedText": "${CONTROLLER} 重新連接", + "controllersConnectedText": "已連接${COUNT} 個手柄", + "controllersDetectedText": "檢測到${COUNT} 個手柄", + "controllersDisconnectedText": "${COUNT} 個手柄斷開連接", + "corruptFileText": "檢測到已損壞文件。請嘗試重新安裝,或發送電子郵件到${EMAIL}尋求幫助", + "errorPlayingMusicText": "無法播放音樂: ${MUSIC}", + "errorResettingAchievementsText": "無法重置在線成就;請稍後再試", + "hasMenuControlText": "${NAME} 目前擁有控制菜單的權限", + "incompatibleNewerVersionHostText": "創建者的遊戲版本更高\n請更新您的遊戲版本後重試", + "incompatibleVersionHostText": "創建者的遊戲版本與你的不一致\n請確保你們的遊戲版本相同後重試", + "incompatibleVersionPlayerText": "${NAME} 正在運行不同的遊戲版本\n請確保你們的遊戲版本一致後重試", + "invalidAddressErrorText": "錯誤:無效的地址", + "invalidNameErrorText": "錯誤:無效的名字", + "invalidPortErrorText": "錯誤:無效的端口", + "invitationSentText": "已發出邀請", + "invitationsSentText": "已發出${COUNT} 個邀請", + "joinedPartyInstructionsText": "有人加入了你的派對\n去“開始戰鬥”中開始一場對戰吧", + "keyboardText": "鍵盤", + "kickIdlePlayersKickedText": "${NAME}掛機時間過長,將其踢出", + "kickIdlePlayersWarning1Text": "如果${NAME} 繼續掛機,則將會在${COUNT} 後將其踢出", + "kickIdlePlayersWarning2Text": "(你可以在設置->高級設置中將其關閉)", + "leftGameText": "離開'${NAME}'.", + "leftPartyText": "離開${NAME}的派對", + "noMusicFilesInFolderText": "文件夾內沒有音頻文件", + "playerJoinedPartyText": "${NAME} 加入了派對", + "playerLeftPartyText": "${NAME} 離開了派對", + "rejectingInviteAlreadyInPartyText": "拒絕邀請(已經在派對中)", + "serverRestartingText": "伺服器正在重啟,請稍後加入", + "serverShuttingDownText": "伺服器正在關閉...", + "signInErrorText": "登錄出錯.", + "signInNoConnectionText": "網絡連接失敗,無法登錄", + "telnetAccessDeniedText": "錯誤:用戶未得到遠程登錄連接授權", + "timeOutText": "(將在${TIME} 秒後超出時限)", + "touchScreenJoinWarningText": "你已以觸摸屏的方式加入\n如果這是一個錯誤,請手動退出遊戲", + "touchScreenText": "觸摸屏", + "unableToResolveHostText": "錯誤:創建者網絡環境有問題", + "unavailableNoConnectionText": "網絡連接故障", + "vrOrientationResetCardboardText": "重置VR定位\n您需要用外部手柄來進行遊戲", + "vrOrientationResetText": "VR定位重置", + "willTimeOutText": "(若掛機則會超出時限)" + }, + "jumpBoldText": "跳", + "jumpText": "跳", + "keepText": "舉起", + "keepTheseSettingsText": "保存這些設置嗎", + "keyboardChangeInstructionsText": "雙擊空格以更改控制器", + "keyboardNoOthersAvailableText": "無其他可用的控制器", + "keyboardSwitchText": "切換控制器為\"${NAME}\"", + "kickOccurredText": "${NAME} 被踢出", + "kickQuestionText": "是否要踢出玩家${NAME}?", + "kickText": "踢出", + "kickVoteCantKickAdminsText": "服務器管理員無法被踢出派對", + "kickVoteCantKickSelfText": "你不可以踢出你自己", + "kickVoteFailedNotEnoughVotersText": "沒有足夠的玩家參與投票", + "kickVoteFailedText": "投票踢出玩家未成功", + "kickVoteStartedText": "踢出玩家${NAME}的投票已發起", + "kickVoteText": "投票踢出玩家", + "kickVotingDisabledText": "投票踢人已被禁用", + "kickWithChatText": "在聊天框內輸入${YES} 以同意,輸入${NO} 以否定", + "killsTallyText": "${COUNT} 次擊殺", + "killsText": "擊殺數", + "kioskWindow": { + "easyText": "簡單", + "epicModeText": "史詩模式", + "fullMenuText": "完整菜單", + "hardText": "困難", + "mediumText": "中級", + "singlePlayerExamplesText": "單人模式/合作模式樣例", + "versusExamplesText": "對戰模式樣例" + }, + "languageSetText": "現在的語言是\"${LANGUAGE}\".", + "lapNumberText": "圈數:${CURRENT}/${TOTAL}", + "lastGamesText": "(最後${COUNT}局比賽)", + "leaderboardsText": "排行榜", + "league": { + "allTimeText": "所有時間", + "currentSeasonText": "當前賽季(${NUMBER})", + "leagueFullText": "${NAME}聯賽", + "leagueRankText": "聯賽排名", + "leagueText": "聯賽", + "rankInLeagueText": "#${RANK}, ${NAME} 聯賽${SUFFIX}", + "seasonEndedDaysAgoText": "賽季已於${NUMBER}天前結束", + "seasonEndsDaysText": "賽季將在${NUMBER}天後結束", + "seasonEndsHoursText": "賽季將於${NUMBER}小時後結束", + "seasonEndsMinutesText": "賽季將於${NUMBER}分鐘後結束", + "seasonText": "第${NUMBER}賽季", + "tournamentLeagueText": "你一定要到${NAME}聯賽後才能參加此賽事", + "trophyCountsResetText": "獎杯計數將於下個賽季重置" + }, + "levelBestScoresText": "在${LEVEL}中的最高成績", + "levelBestTimesText": "在${LEVEL}中的最佳時間", + "levelIsLockedText": "${LEVEL}正在鎖定狀態", + "levelMustBeCompletedFirstText": "你必須先完成${LEVEL}", + "levelText": "${NUMBER}關卡", + "levelUnlockedText": "關卡解鎖", + "livesBonusText": "生命獎勵", + "loadingText": "正在加載中", + "loadingTryAgainText": "加載中...請稍後再試", + "macControllerSubsystemBothText": "均可(不推薦)", + "macControllerSubsystemClassicText": "經典", + "macControllerSubsystemDescriptionText": "(在你手柄無法使用時請嘗試更改此選項)", + "macControllerSubsystemMFiNoteText": "已檢測到Made-for-iOS/Mac手柄\n你需要在設置->控制器中啟用此設備", + "macControllerSubsystemMFiText": "Made-for-iOS/Mac", + "macControllerSubsystemTitleText": "手柄支持", + "mainMenu": { + "creditsText": "製作團隊", + "demoMenuText": "演示菜單", + "endGameText": "結束遊戲", + "endTestText": "結束測試", + "exitGameText": "退出遊戲", + "exitToMenuText": "退出到菜單?", + "howToPlayText": "幫助", + "justPlayerText": "(勁${NAME})", + "leaveGameText": "離開遊戲", + "leavePartyConfirmText": "確定要離開派對嗎?", + "leavePartyText": "離開派對", + "quitText": "離開遊戲", + "resumeText": "回到遊戲", + "settingsText": "設置" + }, + "makeItSoText": "應用", + "mapSelectGetMoreMapsText": "獲取更多地圖...", + "mapSelectText": "選擇...", + "mapSelectTitleText": "${GAME}地圖", + "mapText": "地圖", + "maxConnectionsText": "最大連接數", + "maxPartySizeText": "最大派對規模", + "maxPlayersText": "最多人數", + "merchText": "周邊", + "modeArcadeText": "街機模式", + "modeClassicText": "經典模式", + "modeDemoText": "演示模式", + "mostValuablePlayerText": "最有價值的玩家", + "mostViolatedPlayerText": "最遭受暴力的玩家", + "mostViolentPlayerText": "最暴力的玩家", + "moveText": "移動", + "multiKillText": "${COUNT}連殺!!!", + "multiPlayerCountText": "${COUNT}名玩家", + "mustInviteFriendsText": "注意:你必須在“${GATHER}”面板中邀請好友\n或連接多個手柄\n和好友一起遊戲", + "nameBetrayedText": "${NAME} 擊殺了隊友${VICTIM}.", + "nameDiedText": "${NAME}死了", + "nameKilledText": "${NAME}擊殺${VICTIM}.", + "nameNotEmptyText": "名字不能為空", + "nameScoresText": "${NAME} 得分", + "nameSuicideKidFriendlyText": "${NAME}意外逝世.", + "nameSuicideText": "${NAME}自殺了.", + "nameText": "名稱", + "nativeText": "本機", + "newPersonalBestText": "新個人最佳!", + "newTestBuildAvailableText": "更新的測試版可供下載了! (${VERSION} 升級至 ${BUILD}).\n到${ADDRESS}獲取測試版", + "newText": "新建", + "newVersionAvailableText": "更新版本的${APP_NAME} 可供下載了 版本號:${VERSION}", + "nextAchievementsText": "未完成的成就:", + "nextLevelText": "下一關", + "noAchievementsRemainingText": "- 無", + "noContinuesText": "(無可繼續)", + "noExternalStorageErrorText": "該設備未發現外部存儲器", + "noGameCircleText": "錯誤:未登錄GameCircle", + "noScoresYetText": "沒有得分記錄", + "noThanksText": "不,謝謝", + "noTournamentsInTestBuildText": "注意:此測試版本的比賽分數將會被作廢", + "noValidMapsErrorText": "沒有發現該比賽類型的有效地圖", + "notEnoughPlayersRemainingText": "剩餘玩家不足,退出並開始新遊戲", + "notEnoughPlayersText": "至少需要${COUNT}名玩家來開始遊戲", + "notNowText": "不是現在", + "notSignedInErrorText": "你必須登入來進行該操作.", + "notSignedInGooglePlayErrorText": "您必須通過Google Play登錄", + "notSignedInText": "(未登錄)", + "notUsingAccountText": "注意:忽略 ${SERVICE} 帳戶。\n如果您想使用它,請轉到“帳戶 -> 使用 ${SERVICE} 登錄”。", + "nothingIsSelectedErrorText": "未選擇任何內容", + "numberText": "#${NUMBER}", + "offText": "關", + "okText": "好的", + "onText": "開", + "oneMomentText": "請等待", + "onslaughtRespawnText": "${PLAYER}將於${WAVE}波復活", + "orText": "${A} 或 ${B}", + "otherText": "其他", + "outOfText": "(在${ALL}名玩家中位列#${RANK})", + "ownFlagAtYourBaseWarning": "你的旗幟必須在自己\n的基地上才能得分", + "packageModsEnabledErrorText": "啟用本地程序包修改時,聯網對戰不可用(參見設置->高級設置)", + "partyWindow": { + "chatMessageText": "聊天消息", + "emptyText": "你的派對為空", + "hostText": "(創建者)", + "sendText": "發送", + "titleText": "你的派對" + }, + "pausedByHostText": "(創建者已暫停)", + "perfectWaveText": "完美的一波", + "pickUpText": "撿起1", + "playModes": { + "coopText": "合作模式", + "freeForAllText": "混戰模式", + "multiTeamText": "多團隊", + "singlePlayerCoopText": "單人遊戲/合作模式", + "teamsText": "團隊模式" + }, + "playText": "開始戰鬥", + "playWindow": { + "oneToFourPlayersText": "一到四個玩家", + "titleText": "開始戰鬥", + "twoToEightPlayersText": "適合2-8名玩家" + }, + "playerCountAbbreviatedText": "${COUNT}名玩家", + "playerDelayedJoinText": "${PLAYER}將在下一回合進入遊戲", + "playerInfoText": "玩家資料", + "playerLeftText": "${PLAYER}離開了遊戲", + "playerLimitReachedText": "已達到${COUNT}名玩家上線;其他玩家不可加入", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "您無法刪除您的玩家資料", + "deleteButtonText": "刪除\n檔案", + "deleteConfirmText": "刪除'${PROFILE}'?", + "editButtonText": "編輯\n檔案", + "explanationText": "(為這個賬號定義玩家名稱和外觀)", + "newButtonText": "新建\n檔案", + "titleText": "玩家檔案" + }, + "playerText": "玩家", + "playlistNoValidGamesErrorText": "此列表未包含有效的已解鎖遊戲", + "playlistNotFoundText": "找不到遊戲列表", + "playlistText": "遊玩列表", + "playlistsText": "遊戲列表", + "pleaseRateText": "如果你喜歡${APP_NAME},請考慮花一些時間\n為Bombsquad寫一篇評論。這將為我們\n提供一些有用的反饋建議,為遊戲的未來開發給予支持\n\nThanks!\n-Eric", + "pleaseWaitText": "請稍等....", + "pluginClassLoadErrorText": "加載插件類'${PLUGIN}'時出錯:${ERROR}", + "pluginInitErrorText": "初始化插件'${PLUGIN}'時出錯:${ERROR}", + "pluginsDetectedText": "檢測到新插件。重新啓動以激活,或在設置中配置這些插件", + "pluginsRemovedText": "${NUM}個插件已丟失", + "pluginsText": "外掛程式", + "practiceText": "練習", + "pressAnyButtonPlayAgainText": "按任意鍵再玩一次...", + "pressAnyButtonText": "按任意鍵以繼續...", + "pressAnyButtonToJoinText": "按任意鍵加入...", + "pressAnyKeyButtonPlayAgainText": "按任意鍵再玩一次...", + "pressAnyKeyButtonText": "按任意鍵繼續...", + "pressAnyKeyText": "按任意鍵...", + "pressJumpToFlyText": "**按跳躍鍵以飛行**", + "pressPunchToJoinText": "按出拳加入", + "pressToOverrideCharacterText": "按 ${BUTTONS} 更換你的角色", + "pressToSelectProfileText": "按 ${BUTTONS} 選擇一個玩家", + "pressToSelectTeamText": "按${BUTTONS} 選擇一個隊伍", + "promoCodeWindow": { + "codeText": "代碼", + "enterText": "輸入" + }, + "promoSubmitErrorText": "提交代碼時錯誤:檢查你的網絡連接", + "ps3ControllersWindow": { + "macInstructionsText": "關閉PS3背面的電源開關,確保\n您的MAC電腦上啟用了藍牙,然後通過USB連接將您的手柄連接到\n您的MAC電腦上時期配對。之後,您\n就可以使用該手柄上的主頁按鈕以有線(USB)或無線(藍牙)模式\n將其連接到你的電腦上\n\n在一些MAC電腦上配對時可能會提示你輸入密碼\n在此情況下,請參閱一下教程或搜索Google尋求幫助\n\n\n\n\n無線連接的PS3手柄應該出現在\n系統偏好設置->藍牙中的設備列表中。當你想再次使用你的PS3時\n您可以從該列表中移除它們\n\n另外,請確保它們在未使用狀態下時與藍牙斷開連接\n以免其電池持續消耗\n\n藍牙最多可以處理七個連接設備\n雖然您的里程可能會有所不同", + "ouyaInstructionsText": "若要通過OUYA使用PS3手柄,僅需使用USB連接線\n將其連接配對。這樣做可能會使您的其他手柄斷開連接,因此\n您應該重新啟動您的OUYA,然後拔下USB連接線\n\n然後,你應該能夠使用手柄的主頁按鈕\n以無線模式將其連接。結束遊戲後,按住主頁按鈕\n10秒鐘,以關閉手柄,否則,手柄將持續處於啟動狀態\n並消耗電池", + "pairingTutorialText": "配對教學視頻", + "titleText": "用PS3手柄玩 ${APP_NAME}:" + }, + "punchBoldText": "拳擊", + "punchText": "拳擊", + "purchaseForText": "購買花費 ${PRICE}", + "purchaseGameText": "購買遊戲", + "purchasingText": "正在購買...", + "quitGameText": "退出 ${APP_NAME}?", + "quittingIn5SecondsText": "將於5秒後退出...", + "randomPlayerNamesText": "Reol,爆破鬼才,ZACK,炸蛋小分隊,隊友摧毀者,炸彈吞噬者,TNT的朋友,冰凍使者,田所浩二,拳擊高手,創世神,炸彈人,機械狂人,大發明家,吹噓海盜,末日預言者", + "randomText": "隨機", + "rankText": "排行", + "ratingText": "排名", + "reachWave2Text": "進入第二波才可參與排名", + "readyText": "準備", + "recentText": "最近", + "remoteAppInfoShortText": "與家人或者朋友們一起玩${APP_NAME}是非常有趣的!\n您可以連接一個或多個控制器\n或者在手機、平板上安裝${REMOTE_APP_NAME}APP程序\n把他們當作控制器使用", + "remote_app": { + "app_name": "BombSquad手柄", + "app_name_short": "BS手柄", + "button_position": "按鈕位置", + "button_size": "按鈕尺寸", + "cant_resolve_host": "無法解析主機...", + "capturing": "捕捉中...", + "connected": "已連接", + "description": "使用手機或平板電腦作為Bombsquad的遊戲手柄\n一台電視或平板電腦上可以同時連接8台設備,體驗史詩級多人模式的瘋狂遊戲", + "disconnected": "伺服器斷開鏈接", + "dpad_fixed": "固定", + "dpad_floating": "浮動", + "dpad_position": "方向鍵位置", + "dpad_size": "方向盤大小", + "dpad_type": "方向鍵類型", + "enter_an_address": "輸入地址", + "game_full": "遊戲連接已滿或不接收更多的連接", + "game_shut_down": "遊戲關閉", + "hardware_buttons": "硬件按鈕", + "join_by_address": "通過地址加入...", + "lag": "延遲:${SECONDS}秒", + "reset": "恢復默認值", + "run1": "運行1", + "run2": "運行2", + "searching": "正在搜索Bombsquad遊戲", + "searching_caption": "點擊遊戲名,進入遊戲\n確保和遊戲處於同一個局域網環境下", + "start": "開始", + "version_mismatch": "版本不匹配\n確保Bombsquad與Bombsquad手柄都是\n最新版本後重試" + }, + "removeInGameAdsText": "在商店中解鎖\"${PRO}\",以刪除遊戲中的廣告", + "renameText": "重命名", + "replayEndText": "結束回放", + "replayNameDefaultText": "終場遊戲回放", + "replayReadErrorText": "讀取回放文件時出錯", + "replayRenameWarningText": "如果想保存回放文件,則以遊戲來命名\"${REPLAY}\",否則溫江將會被覆蓋", + "replayVersionErrorText": "抱歉,該回放由於遊戲版本不同\n無法播放", + "replayWatchText": "播放回放", + "replayWriteErrorText": "寫入遊戲回放時出錯", + "replaysText": "回放", + "reportPlayerExplanationText": "利用此電子郵件來舉報作弊、不當言論等其他遊戲不良行為\n請描述如下信息:", + "reportThisPlayerCheatingText": "作弊", + "reportThisPlayerLanguageText": "不當言行", + "reportThisPlayerReasonText": "舉報該玩家的原因是?", + "reportThisPlayerText": "舉報此玩家", + "requestingText": "正在請求", + "restartText": "重新啟動", + "retryText": "請重試", + "revertText": "還原", + "runText": "運行", + "saveText": "保存", + "scanScriptsErrorText": "掃描腳本時存在錯誤,查看錯誤日誌來了解詳情", + "scoreChallengesText": "得分挑戰", + "scoreListUnavailableText": "得分列表不可用", + "scoreText": "得分", + "scoreUnits": { + "millisecondsText": "毫秒", + "pointsText": "分", + "secondsText": "秒" + }, + "scoreWasText": "(是 ${COUNT})", + "selectText": "選擇", + "seriesWinLine1PlayerText": "贏得", + "seriesWinLine1TeamText": "贏得", + "seriesWinLine1Text": "贏得", + "seriesWinLine2Text": "本局!", + "settingsWindow": { + "accountText": "賬戶", + "advancedText": "高級設置", + "audioText": "音效", + "controllersText": "控制器", + "graphicsText": "圖像", + "playerProfilesMovedText": "注意:玩家檔案已移至主菜單的“賬戶”窗口下", + "titleText": "設置" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(注意:遊戲內置輸入法只能讓輸入英文字符和部分符號)", + "alwaysUseInternalKeyboardText": "使用遊戲內置輸入法", + "benchmarksText": "基準/壓力測試", + "disableCameraGyroscopeMotionText": "禁用陀螺儀畫面抖動", + "disableCameraShakeText": "禁止畫面抖動", + "disableThisNotice": "(可在高級設置中關閉此通知)", + "enablePackageModsDescriptionText": "(啟用額外的修改性能,但是禁止網絡遊戲)", + "enablePackageModsText": "啟用本地程序包修改", + "enterPromoCodeText": "輸入促銷代碼", + "forTestingText": "注意:這些數值僅用於測試,並會在退出遊戲後重置", + "helpTranslateText": "${APP_NAME}的非英語翻譯是其他玩家\n共同努力的成果,如果你希望參與遊戲文本翻譯或修正\n請點擊以下連接。感謝大家對遊戲翻譯提出的貢獻", + "kickIdlePlayersText": "自動踢出掛機玩家", + "kidFriendlyModeText": "兒童模式(低暴力等)", + "languageText": "語言", + "moddingGuideText": "修改指南", + "mustRestartText": "你必須重啟遊戲才能生效", + "netTestingText": "網絡連接測試", + "resetText": "恢復默認", + "showBombTrajectoriesText": "顯示炸彈軌跡", + "showPlayerNamesText": "顯示玩家名稱", + "showUserModsText": "顯示MOD安裝文件夾", + "titleText": "高級設置", + "translationEditorButtonText": "${APP_NAME}翻譯編輯", + "translationFetchErrorText": "翻譯狀態不可用", + "translationFetchingStatusText": "檢查翻譯進度...", + "translationInformMe": "我的語言翻譯可更新時通知我", + "translationNoUpdateNeededText": "當前語言翻譯文本是最新的", + "translationUpdateNeededText": "**當前語言翻譯文本需要更新**", + "vrTestingText": "VR 調試" + }, + "shareText": "分享", + "sharingText": "分享中...", + "showText": "顯示", + "signInForPromoCodeText": "你必須登錄才能使用促銷代碼", + "signInWithGameCenterText": "使用Game Center\n來登錄", + "singleGamePlaylistNameText": "僅 ${GAME}", + "singlePlayerCountText": "1 玩家", + "soloNameFilterText": "單挑模式 ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "角色選擇", + "Chosen One": "選定模式", + "Epic": "史詩模式遊戲", + "Epic Race": "史詩級競賽", + "FlagCatcher": "奪旗戰", + "Flying": "飛行之地", + "Football": "運旗站", + "ForwardMarch": "突襲戰", + "GrandRomp": "佔領戰", + "Hockey": "冰球戰", + "Keep Away": "舉旗戰", + "Marching": "塔防戰", + "Menu": "主菜單", + "Onslaught": "衝鋒戰", + "Race": "競賽", + "Scary": "據點佔領", + "Scores": "得分結算屏幕", + "Survival": "消除戰", + "ToTheDeath": "死亡競賽", + "Victory": "最終結算屏幕" + }, + "spaceKeyText": "空格", + "statsText": "統計", + "storagePermissionAccessText": "需要存儲權限", + "store": { + "alreadyOwnText": "您已擁有${NAME}!", + "bombSquadProNameText": "${APP_NAME} PRO", + "bombSquadProNewDescriptionText": "•移除遊戲中廣告和煩人的界面\n•解鎖更多遊戲設置\n•以及:", + "buyText": "購買", + "charactersText": "人物", + "comingSoonText": "即將來臨...", + "extrasText": "額外部分", + "freeBombSquadProText": "BombSquad現在是免費的,由於最初您是通過購買獲得,您將獲得\nBombSquad Pro和${COUNT}點券,以表感謝\n盡享全新功能,感謝您對Bombsquad的支持\n-Eric", + "holidaySpecialText": "假日特售", + "howToSwitchCharactersText": "(進入${SETTINGS} -> ${PLAYER_PROFILES}自定義人物)", + "howToUseIconsText": "(升級全球檔案以使用圖標)", + "howToUseMapsText": "(在團隊/混戰遊戲中使用這些地圖)", + "iconsText": "圖標", + "loadErrorText": "無法加載頁面\n請檢查網絡連接", + "loadingText": "加載中", + "mapsText": "地圖", + "miniGamesText": "迷你遊戲", + "oneTimeOnlyText": "(僅一次)", + "purchaseAlreadyInProgressText": "該物品的購買正在進行中", + "purchaseConfirmText": "購買${ITEM}?", + "purchaseNotValidError": "購買失敗\n如果這是一個錯誤,請聯繫${EMAIL}", + "purchaseText": "購買", + "saleBundleText": "捆綁售賣", + "saleExclaimText": "出售", + "salePercentText": "(-${PERCENT}%)", + "saleText": "特惠", + "searchText": "搜索", + "teamsFreeForAllGamesText": "團隊/混戰遊戲", + "totalWorthText": "*** ${TOTAL_WORTH} 值 ***", + "upgradeQuestionText": "更新?", + "winterSpecialText": "冬季特售", + "youOwnThisText": "-您已擁有-" + }, + "storeDescriptionText": "8人派对游戏尽显疯狂!\n\n在爆炸类迷你游戏中炸飞您的好友(或电脑),如夺旗战、冰球战及史诗级慢动作死亡竞赛!\n\n简单的控制和广泛的手柄支持可轻松允许多达8人参与游戏;您甚至可以通过免费的“BombSquad Remote”应用将您的移动设备作为手柄使用!\n\n投射炸弹!\n\n更多信息,请登录www.froemling.net/bombsquad。", + "storeDescriptions": { + "blowUpYourFriendsText": "炸飛你的朋友", + "competeInMiniGamesText": "在從競速到飛行的迷你遊戲中一決高下", + "customize2Text": "自定義角色、迷你遊戲甚至是背景音樂", + "customizeText": "自定義角色並創建自己的迷你遊戲列表", + "sportsMoreFunText": "加入炸藥後遊戲變得更加有趣", + "teamUpAgainstComputerText": "組隊對抗人機" + }, + "storeText": "商店", + "submitText": "提交", + "submittingPromoCodeText": "正在提交代碼...", + "teamNamesColorText": "團隊名稱/顏色...", + "telnetAccessGrantedText": "Telnet訪問以啟用", + "telnetAccessText": "檢測到Telnet訪問,是否允許?", + "testBuildErrorText": "該測試版已失效;請檢查是否存在新版本", + "testBuildText": "測試版", + "testBuildValidateErrorText": "無法驗證測試版(網絡連接出錯)", + "testBuildValidatedText": "測試版已通過驗證,盡情享用", + "thankYouText": "感謝你的支持!盡情享受遊戲!", + "threeKillText": "三殺!!", + "timeBonusText": "時間獎勵", + "timeElapsedText": "時間耗盡", + "timeExpiredText": "時間結束", + "timeSuffixDaysText": "${COUNT}天", + "timeSuffixHoursText": "${COUNT}時", + "timeSuffixMinutesText": "${COUNT}分", + "timeSuffixSecondsText": "${COUNT}秒", + "tipText": "提示", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "最佳好友", + "tournamentCheckingStateText": "檢查錦標賽狀態中,請稍後...", + "tournamentEndedText": "此錦標賽已結束。新的錦標賽已開始", + "tournamentEntryText": "錦標賽入口", + "tournamentResultsRecentText": "最近錦標賽結果", + "tournamentStandingsText": "錦標賽積分榜", + "tournamentText": "錦標賽", + "tournamentTimeExpiredText": "錦標賽時間結束", + "tournamentsDisabledWorkspaceText": "儅工作區處於開啓狀態時講標賽將被禁用\n如果想解禁錦標賽,請關閉您的工作區並重啓游戲", + "tournamentsText": "錦標賽", + "translations": { + "characterNames": { + "Agent Johnson": "約翰遜特工", + "B-9000": "B-9000", + "Bernard": "伯納德", + "Bones": "骷髏", + "Butch": "牛仔邦奇", + "Easter Bunny": "復活節兔子", + "Flopsy": "Flopsy", + "Frosty": "冬日雪人", + "Gretel": "歌者格雷特", + "Grumbledorf": "男巫道博", + "Jack Morgan": "海盜傑克", + "Kronk": "肌肉男克羅克", + "Lee": "李", + "Lucky": "幸運兒", + "Mel": "大廚梅爾", + "Middle-Man": "平衡者", + "Minimus": "小姆斯", + "Pascal": "企鵝巴斯卡", + "Pixel": "精靈莉莉絲", + "Sammy Slam": "薩米斯拉姆", + "Santa Claus": "聖誕老人", + "Snake Shadow": "忍者蛇影", + "Spaz": "鋼盔斯巴子", + "Taobao Mascot": "淘公仔", + "Todd McBurton": "托德馬克波頓", + "Zoe": "遊俠佐伊", + "Zola": "刺殺者佐拉" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME}訓練", + "Infinite ${GAME}": "無限${GAME}", + "Infinite Onslaught": "無限衝鋒戰", + "Infinite Runaround": "無限塔防戰", + "Onslaught Training": "衝鋒訓練", + "Pro ${GAME}": "${GAME}Pro", + "Pro Football": "橄欖球戰Pro", + "Pro Onslaught": "衝鋒戰Pro", + "Pro Runaround": "塔防戰Pro", + "Rookie ${GAME}": "新手${GAME}", + "Rookie Football": "新手橄欖球戰", + "Rookie Onslaught": "新手衝鋒戰", + "The Last Stand": "最終殺敵戰", + "Uber ${GAME}": "高級${GAME}", + "Uber Football": "高級橄欖球戰", + "Uber Onslaught": "高級衝鋒戰", + "Uber Runaround": "高級塔防戰" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "在一定時間內取代選定目標進而取得勝利\n殺死選定目標並取而代之", + "Bomb as many targets as you can.": "盡可能多的摧毀炸毀", + "Carry the flag for ${ARG1} seconds.": "扛旗 ${ARG1} 秒", + "Carry the flag for a set length of time.": "在設定時長內扛旗", + "Crush ${ARG1} of your enemies.": "殺死 ${ARG1} 敵人", + "Defeat all enemies.": "打敗所有敵人", + "Dodge the falling bombs.": "躲避所有炸彈", + "Final glorious epic slow motion battle to the death.": "在最終殺敵中盡量得分吧", + "Gather eggs!": "收集蛋", + "Get the flag to the enemy end zone.": "舉旗進入敵方陣地", + "How fast can you defeat the ninjas?": "你能多快的打敗所有忍者", + "Kill a set number of enemies to win.": "殺死一定數量的敵人來獲勝", + "Last one standing wins.": "最終殺敵者獲勝", + "Last remaining alive wins.": "最終倖存者獲勝", + "Last team standing wins.": "最終殺敵團隊獲勝", + "Prevent enemies from reaching the exit.": "阻止敵人到達出口", + "Reach the enemy flag to score.": "抵達敵方旗幟來得分", + "Return the enemy flag to score.": "交回敵人旗幟來得分", + "Run ${ARG1} laps.": "跑${ARG1}圈", + "Run ${ARG1} laps. Your entire team has to finish.": "跑${ARG1} 圈。你的整個團隊必須來完成", + "Run 1 lap.": "跑1圈", + "Run 1 lap. Your entire team has to finish.": "跑1圈。你的整個團隊都需完成", + "Run real fast!": "快速奔跑", + "Score ${ARG1} goals.": "${ARG1}進球得分", + "Score ${ARG1} touchdowns.": "${ARG1}觸地得分", + "Score a goal.": "一次進球得分", + "Score a touchdown.": "一次觸地得分", + "Score some goals.": "多次觸地得分", + "Secure all ${ARG1} flags.": "固定所有的${ARG1}旗幟", + "Secure all flags on the map to win.": "固定地圖上的所有旗幟來得分", + "Secure the flag for ${ARG1} seconds.": "固定旗幟${ARG1}秒", + "Secure the flag for a set length of time.": "在設定時長內固定旗幟", + "Steal the enemy flag ${ARG1} times.": "竊取的敵人旗幟${ARG1}次", + "Steal the enemy flag.": "竊取敵人旗幟", + "There can be only one.": "誰會是唯一呢?", + "Touch the enemy flag ${ARG1} times.": "觸碰敵人旗幟${ARG1}次", + "Touch the enemy flag.": "觸碰敵人旗幟", + "carry the flag for ${ARG1} seconds": "舉旗${ARG1} 秒", + "kill ${ARG1} enemies": "殺死${ARG1}敵人", + "last one standing wins": "最終殺敵者獲勝", + "last team standing wins": "最終殺敵團隊獲勝", + "return ${ARG1} flags": "交回${ARG1}旗幟", + "return 1 flag": "交回1面旗幟", + "run ${ARG1} laps": "跑${ARG1}圈", + "run 1 lap": "跑1圈", + "score ${ARG1} goals": "${ARG1}進球得分", + "score ${ARG1} touchdowns": "${ARG1}觸地得分", + "score a goal": "一次進球得分", + "score a touchdown": "一次觸地得分", + "secure all ${ARG1} flags": "固定所有的${ARG1}旗幟", + "secure the flag for ${ARG1} seconds": "固定旗幟${ARG1}秒", + "touch ${ARG1} flags": "觸碰${ARG1}旗幟", + "touch 1 flag": "觸碰一次旗幟" + }, + "gameNames": { + "Assault": "突襲戰", + "Capture the Flag": "奪旗戰", + "Chosen One": "選定模式", + "Conquest": "佔領戰", + "Death Match": "死亡競賽", + "Easter Egg Hunt": "復活蛋獵人", + "Elimination": "消除戰", + "Football": "橄欖球戰", + "Hockey": "冰球戰", + "Keep Away": "舉起戰", + "King of the Hill": "據點佔領", + "Meteor Shower": "炸彈流星戰", + "Ninja Fight": "忍者大戰", + "Onslaught": "衝鋒戰", + "Race": "競速賽", + "Runaround": "塔防戰", + "Target Practice": "精準度訓練", + "The Last Stand": "最終殺敵戰" + }, + "inputDeviceNames": { + "Keyboard": "鍵盤", + "Keyboard P2": "鍵盤P2" + }, + "languages": { + "Arabic": "阿拉伯語", + "Belarussian": "白俄羅斯語", + "Chinese": "簡體中文", + "ChineseTraditional": "繁體中文", + "Croatian": "克羅地亞語", + "Czech": "捷克語", + "Danish": "丹麥語", + "Dutch": "荷蘭語", + "English": "英語", + "Esperanto": "世界語", + "Filipino": "菲律賓語", + "Finnish": "芬蘭語", + "French": "法語", + "German": "德語", + "Gibberish": "用於測試", + "Greek": "希臘語", + "Hindi": "印度語", + "Hungarian": "匈牙利語", + "Indonesian": "印尼語", + "Italian": "意大利語", + "Japanese": "日語", + "Korean": "朝鮮語", + "Malay": "馬來語", + "Persian": "波斯文", + "Polish": "波蘭語", + "Portuguese": "葡萄牙語", + "Romanian": "羅馬尼亞語", + "Russian": "俄羅斯語", + "Serbian": "塞爾維亞語", + "Slovak": "斯洛伐克語", + "Spanish": "西班牙語", + "Swedish": "瑞典語", + "Tamil": "泰米爾語", + "Thai": "泰語", + "Turkish": "土耳其語", + "Ukrainian": "烏克蘭語", + "Venetian": "威尼斯語", + "Vietnamese": "越南語" + }, + "leagueNames": { + "Bronze": "銅牌", + "Diamond": "鑽石", + "Gold": "金牌", + "Silver": "銀牌" + }, + "mapsNames": { + "Big G": "大G", + "Bridgit": "小橋", + "Courtyard": "庭院", + "Crag Castle": "岩城", + "Doom Shroom": "蘑菇雲", + "Football Stadium": "橄欖球場", + "Happy Thoughts": "飛行地帶", + "Hockey Stadium": "冰球場", + "Lake Frigid": "寒湖", + "Monkey Face": "猴面", + "Rampage": "狂暴", + "Roundabout": "塔防", + "Step Right Up": "攻擊", + "The Pad": "平板", + "Tip Top": "頂點", + "Tower D": "塔防", + "Zigzag": "蜿蜒" + }, + "playlistNames": { + "Just Epic": "僅限史詩級", + "Just Sports": "僅限運動類" + }, + "scoreNames": { + "Flags": "旗幟", + "Goals": "進球", + "Score": "得分", + "Survived": "倖存", + "Time": "時間", + "Time Held": "保持時間" + }, + "serverResponses": { + "A code has already been used on this account.": "該賬戶已使用過促銷代碼", + "A reward has already been given for that address.": "您已經領取過該獎勵了", + "Account linking successful!": "賬號關聯成功", + "Account unlinking successful!": "取消關聯成功", + "Accounts are already linked.": "賬號已經連接", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "廣告加載失敗。\n請驗證遊戲版本為官方最新版", + "An error has occurred; (${ERROR})": "出現了一個錯誤(${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "出現了一個錯誤,請聯繫客服解決(${ERROR})", + "An error has occurred; please contact support@froemling.net.": "發生了一個錯誤,請聯繫support@froemling.net", + "An error has occurred; please try again later.": "發生了一個錯誤,請稍後再試", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "確定要連接這些賬戶?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n此操作可在30天后取消", + "BombSquad Pro unlocked!": "BombSquad Pro已解鎖", + "Can't link 2 accounts of this type.": "無法連接這兩個賬號", + "Can't link 2 diamond league accounts.": "無法連接兩個鑽石聯賽的賬號", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "無法連接,已超過關聯上線${COUNT}個賬號", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "發現賬號作弊行為;得分及獎勵在${COUNT}天內暫停", + "Could not establish a secure connection.": "無法建立安全連接", + "Daily maximum reached.": "已達今日上限", + "Entering tournament...": "進入錦標賽...", + "Invalid code.": "代碼無效", + "Invalid payment; purchase canceled.": "不可用的付款方式:交易取消", + "Invalid promo code.": "促銷代碼無效", + "Invalid purchase.": "購買無效", + "Invalid tournament entry; score will be ignored.": "錯誤的聯賽資料,分數會被忽略", + "Item unlocked!": "項目已解除綁定", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "連接賬號行為取消,${ACCOUNT}含有\n的重要數據可能會丟失\n如果想要關聯的話,你可以反向鏈接賬號\n(最好用自己的賬號進行關聯)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "確定將${ACCOUNT}關聯到此賬戶嗎\n${ACCOUNT}將共享數據\n可在30天后取消", + "Max number of playlists reached.": "已達到最大列表數", + "Max number of profiles reached.": "已達到最大檔案數", + "Maximum friend code rewards reached.": "邀請碼獎勵達到上限", + "Message is too long.": "消息過長", + "No servers are available. Please try again soon.": "當前沒有空餘的伺服器,請稍後再試", + "Profile \"${NAME}\" upgraded successfully.": "\"${NAME}\"檔案升級成功", + "Profile could not be upgraded.": "檔案不可升級", + "Purchase successful!": "購買成功", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "登錄簽到獎勵${COUNT} 點券\n明天簽到可獲得${TOMORROW_COUNT}點券", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "此版本不在支持伺服器功能\n請升級到最新版本", + "Sorry, there are no uses remaining on this code.": "對不起,此代碼已經無法繼續使用了", + "Sorry, this code has already been used.": "對不起,此代碼已被使用", + "Sorry, this code has expired.": "對不起,此代碼已失效", + "Sorry, this code only works for new accounts.": "對不起,此代碼僅適用於新用戶", + "Still searching for nearby servers; please try again soon.": "正在查詢附近的伺服器,請稍後再試", + "Temporarily unavailable; please try again later.": "目前暫不可用,請稍後再試", + "The tournament ended before you finished.": "本次錦標賽將於在你完成之前結束了", + "This account cannot be unlinked for ${NUM} days.": "此賬戶在${NUM}天內無法取消關聯", + "This code cannot be used on the account that created it.": "此代碼無法在創建的其他賬戶上使用", + "This is currently unavailable; please try again later.": "當前不可用,請稍後再試", + "This requires version ${VERSION} or newer.": "這需要${VERSION}或更高的版本", + "Tournaments disabled due to rooted device.": "此設備已禁賽", + "Tournaments require ${VERSION} or newer": "比賽需要${VERSION}或更高的版本", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "從此賬戶上取消${ACCOUNT}的關聯?\n${ACCOUNT}上的數據將會被重置\n(在某些情況下成就除外)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "警告:針對你的賬戶發出黑客控訴\n被盜用的賬戶將被禁止。請公平競技", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "是否經你的賬戶連接到此?\n\n你的賬戶為${ACCOUNT1}\n此賬戶為${ACCOUNT2}\n\n你可以保存現有進度\n警告:此操作可在30天后取消", + "You already own this!": "你已擁有這個", + "You can join in ${COUNT} seconds.": "你可以在${COUNT}秒後加入", + "You don't have enough tickets for this!": "你的點券不足", + "You don't own that.": "你尚未擁有", + "You got ${COUNT} tickets!": "你獲得了${COUNT}點券", + "You got a ${ITEM}!": "你獲得了一個${ITEM}!", + "You have been promoted to a new league; congratulations!": "你已經被升級至一個全新的聯賽:恭喜", + "You must update to a newer version of the app to do this.": "你必須先更新遊戲才能這麼做", + "You must update to the newest version of the game to do this.": "你必須更新到最新版本才可以執行此操作", + "You must wait a few seconds before entering a new code.": "你必須要在輸入新代碼前等待一會", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "你在上一場錦標賽中排名#${RANK},繼續加油", + "Your account was rejected. Are you signed in?": "你的髒號被拒絕,您是否已登陸?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "您的遊戲副本已更改\n請恢復任何更改並重試", + "Your friend code was used by ${ACCOUNT}": "${ACCOUNT}已使用您的促銷代碼" + }, + "settingNames": { + "1 Minute": "1分鐘", + "1 Second": "1秒", + "10 Minutes": "10分鐘", + "2 Minutes": "2分鐘", + "2 Seconds": "2秒", + "20 Minutes": "20分鐘", + "4 Seconds": "4秒", + "5 Minutes": "5分鐘", + "8 Seconds": "8秒", + "Allow Negative Scores": "允許負分", + "Balance Total Lives": "平衡總生命", + "Bomb Spawning": "生成炸彈", + "Chosen One Gets Gloves": "選定目標獲得拳擊手套", + "Chosen One Gets Shield": "選定目標獲得能量護盾", + "Chosen One Time": "選定模式時間", + "Enable Impact Bombs": "啟用觸感炸彈", + "Enable Triple Bombs": "啟用三連炸彈", + "Entire Team Must Finish": "需要所有隊伍成員一起通過", + "Epic Mode": "史詩模式", + "Flag Idle Return Time": "旗幟閒置重置時間", + "Flag Touch Return Time": "旗幟觸碰重置時間", + "Hold Time": "保持時間", + "Kills to Win Per Player": "玩家獲勝擊殺數", + "Laps": "圈數", + "Lives Per Player": "每位玩家的初始生命數量", + "Long": "長", + "Longer": "更長", + "Mine Spawning": "地雷生成", + "No Mines": "無地雷", + "None": "無", + "Normal": "正常", + "Pro Mode": "Pro模式", + "Respawn Times": "復活時長", + "Score to Win": "獲勝分數", + "Short": "短", + "Shorter": "更短", + "Solo Mode": "單人模式", + "Target Count": "目標計數", + "Time Limit": "時限" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} 被踢,因為${PLAYER}離開遊戲", + "Killing ${NAME} for skipping part of the track!": "殺死跳過部分賽道的${NAME}", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "警告:檢測到${NAME}操作異常 將使其被踢出" + }, + "teamNames": { + "Bad Guys": "敵方", + "Blue": "藍隊", + "Good Guys": "我方", + "Red": "紅隊" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "一记完美、及时的“跑跳旋转拳”可一次性击杀敌人,并\n助你一生享有好友的尊重。", + "Always remember to floss.": "地面上的辅助线可能会有用。", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "使用首选名称和外观,而非采用随机形式\n来为自己和好友创建玩家档案。", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "诅咒之盒把你变成了一个定时炸弹。\n唯一的解决方法是迅速抢占一个生命值包。", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "尽管长相不同,所有人物的技能是相同的,\n所以只需随意挑选一个与你最相似的。", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "不要因为拥有能量盾牌而狂妄自大;你仍然可能使自己坠入悬崖。", + "Don't run all the time. Really. You will fall off cliffs.": "不要总是奔跑。真的。你可能会坠入悬崖。", + "Don't spin for too long; you'll become dizzy and fall.": "不要旋转得太久,不然你会眩晕并摔倒。", + "Hold any button to run. (Trigger buttons work well if you have them)": "按住任意按钮来奔跑。(如果你有的话,扳机按钮将会很有用)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "按住任意按钮来奔跑。你将会更快地抵达一些地方,\n但是转弯效果并不好,所以当心悬崖。", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "寒冰炸弹并非很厉害,但它们能够冻结\n任何被击中者,使他们极易粉碎。", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "如果有人将你提起,出拳攻击他们,他们便会放手。\n这在现实生活中同样有效。", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "如果您缺控制器,在手機上安裝「${REMOTE_APP_NAME}」\n並用手機當控制器。", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "如果一个黏黏弹将你困住,你应该四处跳动并转圈。你可能\n将炸弹抖落,或如果没有其他办法,你最后的时刻将是有趣的。", + "If you kill an enemy in one hit you get double points for it.": "如果你一击杀死一个敌人,你将获得双倍积分。", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "如果你捡到一个诅咒之盒,你唯一的生存希望是\n在接下来的几秒内找到一个生命值提升器。", + "If you stay in one place, you're toast. Run and dodge to survive..": "如果你停留在一个地方,你就完了。为了生存而奔跑和躲避……", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "如果众多玩家进进出出,在设置下打开“自动踢出闲置玩家”,以防\n任何玩家忘记离开游戏。", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "如果你的设备过热,或者你想要节省电池电量,\n则在设置->图形中调低“视觉效果”或“分辨率”", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "如果你的帧速率不稳定,请尝试在游戏的\n图形设置中调低分辨率或视觉效果。", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "在夺旗战中,你的旗帜必须位于你的基地才能得分,如果对方\n团队即将得分,窃取他们的旗帜是一个不错的阻止方法。", + "In hockey, you'll maintain more speed if you turn gradually.": "在冰球战中,逐渐转向将使你保持更快的速度。", + "It's easier to win with a friend or two helping.": "在拥有一名好友或两个帮扶的情况下更易获胜", + "Jump just as you're throwing to get bombs up to the highest levels.": "就像你试图将炸弹扔到最高点那样跳起来。", + "Land-mines are a good way to stop speedy enemies.": "地雷是阻止高速敌人的一个很好的方式。", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "很多东西都可以捡起来并投掷,包括其他玩家。将你的\n敌人抛下悬崖可能是一个有效的且情感上可获得满足的策略。", + "No, you can't get up on the ledge. You have to throw bombs.": "不,你不能在岩脊上起身。你必须要投掷炸弹", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "玩家可在大多数游戏中途加入或离开,\n同时,你也可以在百忙中插上或拔出手柄。", + "Practice using your momentum to throw bombs more accurately.": "练习借助你的力量更准确地投掷炸弹。", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "拳头跑得越快,拳击的伤害越高,\n所以请成为飞奔的拳击手吧。", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "在投掷炸弹之前来回跑动,\n以“鞭打”炸弹,并将其投掷更远。", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "在TNT炸药箱附近引爆\n一个炸弹来消灭一群敌人。", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "头部是最脆弱的区域,所以一个黏黏弹\n接触头部通常便意味着游戏结束。", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "这一关卡永远不会结束,但是更高的得分将\n助你赢得全世界永恒的尊重。", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "投掷力量取决于你所保持的方向。\n如要向前方轻轻投掷某物,不要保持在任何方向。", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "更换背景音乐?更换成你自己音乐吧!\n参见设置->音频->背景音乐", + "Try 'Cooking off' bombs for a second or two before throwing them.": "尝试在投掷之前将炸弹“爆燃”一秒或两秒。", + "Try tricking enemies into killing eachother or running off cliffs.": "试图诱使敌人互相厮杀或坠入悬崖。", + "Use the pick-up button to grab the flag < ${PICKUP} >": "使用拾取按钮来抢夺旗帜< ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "来回鞭打以投掷更远距离……", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "你可以通过左转或右转“瞄准”出拳。\n这有利于将坏人击倒出边界或在冰球战中得分。", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "你可以根据导火线火花的颜色判断炸弹什么时候爆炸:\n黄色……橙色……红色……嘭。", + "You can throw bombs higher if you jump just before throwing.": "如果投弹前跳起,你将投掷更远。", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "当你用头部重击物体时将受到伤害,\n所以尽量不要用头部重击物体。", + "Your punches do much more damage if you are running or spinning.": "如果你奔跑或旋转,拳击的伤害将更高。" + } + }, + "trophiesRequiredText": "你至少要擁有${NUMBER}個獎杯", + "trophiesText": "獎杯", + "trophiesThisSeasonText": "本賽季獎杯", + "tutorial": { + "cpuBenchmarkText": "以驚人的速度來運行遊戲教程(用於測試CPU上限)", + "phrase01Text": "嘿,夥計", + "phrase02Text": "歡迎來到${APP_NAME}!", + "phrase03Text": "以下適用於此遊戲的一些技巧", + "phrase04Text": "${APP_NAME}在很多情況下還是很物理的", + "phrase05Text": "比如,當你出拳時", + "phrase06Text": "拳頭的傷害取決於你它的速度", + "phrase07Text": "看到了嗎,如果我們不動,這樣幾乎不會造成傷害${NAME}", + "phrase08Text": "現在,讓我們跳躍並旋轉起來,以獲得更快的速度", + "phrase09Text": "啊,這樣就好多了", + "phrase10Text": "奔跑也會發揮作用", + "phrase11Text": "按住任意按鈕來奔跑", + "phrase12Text": "如果要完成一個很棒的出拳,請持續奔跑和旋轉", + "phrase13Text": "humm 關於${NAME}我很抱歉", + "phrase14Text": "你可以撿起投擲物品,如炸彈、旗幟或${NAME}", + "phrase15Text": "最後還有炸彈", + "phrase16Text": "投擲炸彈需要練習", + "phrase17Text": "ahh這一次貌似並不漂亮", + "phrase18Text": "移動有助於你投擲的更遠", + "phrase19Text": "跳躍有助於你投擲的更高", + "phrase20Text": "甩炸彈會讓你把炸彈投擲到更遠的位置", + "phrase21Text": "把握好時間可能會十分困難", + "phrase22Text": "¿", + "phrase23Text": "嘗試將導火線控制的更加精準", + "phrase24Text": "OHHHHH爆炸就是藝術", + "phrase25Text": "OK已經很不錯了", + "phrase26Text": "現在去完成你的任務吧,兄弟", + "phrase27Text": "記住你的訓練,你會活著回來的", + "phrase28Text": "也許...是吧", + "phrase29Text": "祝你好運", + "randomName1Text": "Fred", + "randomName2Text": "Harry", + "randomName3Text": "Bill", + "randomName4Text": "Chuck", + "randomName5Text": "Phil", + "skipConfirmText": "確定要跳過教程?再次按下按鈕來確定", + "skipVoteCountText": "${COUNT}/${TOTAL} 跳過投票", + "skippingText": "跳過教程...", + "toSkipPressAnythingText": "(按下任意鍵來跳過教程)" + }, + "twoKillText": "雙殺!", + "unavailableText": "不可用", + "unconfiguredControllerDetectedText": "檢測到未配置的手柄", + "unlockThisInTheStoreText": "這必須從商店解鎖", + "unlockThisProfilesText": "如需創建超過${NUM}個檔案,你需要", + "unlockThisText": "你需要這些來解鎖", + "unsupportedHardwareText": "抱歉,此版本的遊戲不支持該硬件", + "upFirstText": "進入第一局", + "upNextText": "進入比賽${COUNT}第二局", + "updatingAccountText": "更新你的賬戶", + "upgradeText": "升級", + "upgradeToPlayText": "你必須在商店裡解鎖${PRO}以體驗此內容", + "useDefaultText": "使用默認值", + "usesExternalControllerText": "該遊戲使用外部手柄進行接入", + "usingItunesText": "使用音樂軟件設置背景音樂...", + "v2AccountLinkingInfoText": "要鏈接 V2 帳戶,請使用“管理帳戶”按鈕。", + "validatingTestBuildText": "測試版驗證中", + "victoryText": "勝利!", + "voteDelayText": "你不能在${NUMBER}內發起一個新的投票", + "voteInProgressText": "已經有一個投票正在進行中了", + "votedAlreadyText": "你已經參與過投票了", + "votesNeededText": "通過需要${NUMBER}個投票", + "vsText": "vs.", + "waitingForHostText": "(等待${HOST}繼續)", + "waitingForPlayersText": "等待玩家加入", + "waitingInLineText": "正在派對等候(派對爆滿)", + "watchAVideoText": "觀看一個廣告視頻", + "watchAnAdText": "觀看廣告", + "watchWindow": { + "deleteConfirmText": "刪除\"${REPLAY}\"?", + "deleteReplayButtonText": "刪除\n回放", + "myReplaysText": "我的回放", + "noReplaySelectedErrorText": "未選擇回放", + "playbackSpeedText": "回放速度: ${SPEED}", + "renameReplayButtonText": "重命名\n回放", + "renameReplayText": "重命名\"${REPLAY}\"至:", + "renameText": "重命名", + "replayDeleteErrorText": "刪除回放錯誤", + "replayNameText": "錄像名稱", + "replayRenameErrorAlreadyExistsText": "該名稱的回放已經存在", + "replayRenameErrorInvalidName": "無法重命名回放:名稱無效", + "replayRenameErrorText": "重命名回放錄像時出現錯誤。", + "sharedReplaysText": "已分享錄像", + "titleText": "回放錄像", + "watchReplayButtonText": "觀看\n重放" + }, + "waveText": "波", + "wellSureText": "確定!", + "whatIsThisText": "這是什麼?", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote版權擁有©" + }, + "wiimoteListenWindow": { + "listeningText": "監聽Wiimotes...", + "pressText": "同時按下Wiimote的按鈕1和按鈕2", + "pressText2": "再較新的安裝有Motion Plus的Wiimotes上,可按下背部紅色的'sync'按鈕作為替代" + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote 版權所有", + "listenText": "監聽", + "macInstructionsText": "確保您Mac上的Wil已關閉且藍牙功能已啟用\n然後按下監聽,Wiimote支持可能出現不穩定\n所以在完成連接之前\n您肯呢個需要嘗試多次\n\n藍牙需能夠處理多達7台連接設備\n但您的里程可能會有所不同\n\nBombsquad支持原裝Wiimotes, Nunchuks\n及經典手柄\n較新版本的Wii Remote Plus現也可以使用\n但與附件不兼容", + "thanksText": "感謝DarwiinRemote團隊的努力\n這一切已成為可能", + "titleText": "Wiimote設置" + }, + "winsPlayerText": "${NAME}贏了!", + "winsTeamText": "${NAME}贏了!", + "winsText": "${NAME}贏了!", + "workspaceSyncErrorText": "同步${WORKSPACE}時出錯,詳情日志已輸出", + "workspaceSyncReuseText": "無法同步${WORKSPACE},重複使用以前的同步版本", + "worldScoresUnavailableText": "無法讀入全球分數", + "worldsBestScoresText": "全球最佳分數", + "worldsBestTimesText": "全球最佳時間", + "xbox360ControllersWindow": { + "getDriverText": "獲取驅動程式", + "macInstructions2Text": "如果想使用無線手柄,您還需要\n“用於Windows的無線Xbox360手柄的無線接收器”\n一個接收器可讓你連接多達4個手柄\n\n重要提示:第三方接收器與此驅動程序不兼容\n確保您的接收器標示有“Microsoft”而非“Xbox360”\nMicrosoft不再單獨出售該產品,所以您需要獲得\n手柄附帶的接收器或在eBoy搜索其他設備\n\n如果這對你有幫助,請考慮在驅動程序開發人員\n網站進行捐贈", + "macInstructionsText": "若需使用Xbox360控制器,你需要安裝\n下方超鏈接中的Mac 專用驅動。\n這個驅動同時支持無線與有限連接方式。", + "ouyaInstructionsText": "如果要在Bombsquad中使用有線Xbox360手柄,只需\n將其插入USB接口。您可以使用USB集線器\n以連接多個手柄\n\n如果要使用無線手柄,您需要一台無線接收器\n其可以作為“用於Windows的無線Xbox360手柄”\n安裝包的一部分或單獨出售。每一個接收器插入一個USB接口\n允許你連接多達4個手柄", + "titleText": "通過${APP_NAME}使用Xbox 360 控制器:" + }, + "yesAllowText": "是的,允許!", + "yourBestScoresText": "最佳分數", + "yourBestTimesText": "最佳時間" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/croatian.json b/dist/ba_data/data/languages/croatian.json new file mode 100644 index 0000000..e88c2e1 --- /dev/null +++ b/dist/ba_data/data/languages/croatian.json @@ -0,0 +1,1880 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Korisničko ime ne može sadržavati emotikone ili druge posebne znakove", + "accountProfileText": "(korisnički račun)", + "accountsText": "Korisnički računi", + "achievementProgressText": "Postignuća: ${COUNT} od ${TOTAL}", + "campaignProgressText": "Napredak kampanje[Teško]: ${PROGRESS}", + "changeOncePerSeason": "Ovo možeš promjeniti samo jednom po sezoni.", + "changeOncePerSeasonError": "Moraš pričekati sljedeču sezonu da promjeniš ovo(${NUM} days)", + "customName": "Prilagođeno ime", + "linkAccountsEnterCodeText": "Unesi kod", + "linkAccountsGenerateCodeText": "Stvori kod", + "linkAccountsInfoText": "(podijeli napredak na svim platformama)", + "linkAccountsInstructionsNewText": "Za povezivanje dva računa, generiraj kod sa prvog\ni unesi taj kod na drugi. Podaci s drugog računa\nće biti podjeljeni između oba.\n(Podaci s prvog računa će biti izgubljeni)\n\nMožeš povezati do ${COUNT} računa.\n\nVAŽNO: povezuj samo vlastite račune;\nAko povežeš prijateljev račun onda nećete moći\nzajedno igrati u isto vrijeme.", + "linkAccountsInstructionsText": "Da povežeš dva profila, stvori kod na \njednomod njih i unesi ga na drugom.\nNapredak i sve kupljeno bit će kombinirano.\nMožeš povezati najviše ${COUNT} profila.", + "linkAccountsText": "Poveži profile", + "linkedAccountsText": "Povezani računi:", + "nameChangeConfirm": "Promjeni svoje ime u ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Ovo će poništiti tvoj napredak u timskom modu i\ntvoje najbolje rezultate (ali ne i tvoje kupone).\nNemaš mogućnost povratka. Jesi li siguran?", + "resetProgressConfirmText": "Ovo će poništiti tvoj napredak u timskom modu,\npostignuća, i vaše najbolje rezultate\n(ali ne i tvoje kupone). Nemaš mogućnost\npovratka. Jesi li siguran?", + "resetProgressText": "Počni ponovno", + "setAccountName": "Postavi ime računa", + "setAccountNameDesc": "Odaberi koje ime da se prikaže za tvoj račun.\nMožeš koristiti ime jednog od tvojih povezanih računa\nili kreirati vlastito prilagođeno ime.", + "signInInfoText": "Prijavi se da možeš dobivati kupone, natjecati\nse online, i dijeliti napredak između uređaja.", + "signInText": "Prijavi se", + "signInWithDeviceInfoText": "(automatski profil dostupan samo na ovom uređaju)", + "signInWithDeviceText": "Prijavi se sa profilom uređaja", + "signInWithGameCircleText": "Prijavi se sa Game Circle", + "signInWithGooglePlayText": "Prijavi sa sa Google Play", + "signInWithTestAccountInfoText": "(stari tip profila; ubuduće koristi profile uređaja)", + "signInWithTestAccountText": "Prijavi se s testnim profilom", + "signInWithV2InfoText": "(račun koji radi na svim platformama)", + "signInWithV2Text": "Prijavite se s BombSquad računom", + "signOutText": "Odjavi se", + "signingInText": "Prijava...", + "signingOutText": "Odjava...", + "testAccountWarningCardboardText": "Upozorenje: prijavljuješ se s \"testnim\" računom.\nOn će biti zamijenjen Google računom kada\nGoogle računi postanu podržani u Cardboard aplikacijama.\n\nZasad ćeš morati sakupiti sve kupone u igri.\n(u svakom slučaju ćeš dobiti BombSquad Pro nadogradnju besplatno)", + "testAccountWarningOculusText": "Upozorenje: prijavljuješ se s \"testnim\" računom. \nOn će biti zamijenjen s Oculus računom kasnije ove\ngodine koji će omogućiti kupovanje kuponima i ostale značajke. \n\nZasad ćeš morati sakupiti sve kupone u igri. \n(u svakom slučaju ćeš dobiti BombSquad Pro nadogradnju besplatno)", + "testAccountWarningText": "Upozorenje: prijavljuješ se \"testnim\" računom. \nOvaj račun je vezan za ovaj uređaj i\nmože se povremeno izbrisati. (zato te molim da \nne trošiš previše vremena skupljajući/otključavajući stvari za njega)\n\nPokreni verziju igre iz trgovine da možeš koristiti \"pravi\" \nračun (Game-Center, Google Plus, itd.) Ovo ti također \nomogućuje da sačuvaš svoj napredak u oblaku i dijeliš\nga s drugim uređajima. ", + "ticketsText": "Kuponi: ${COUNT}", + "titleText": "Račun", + "unlinkAccountsInstructionsText": "Odaberi račun za prekid veze.", + "unlinkAccountsText": "Prekini vezu računa", + "v2LinkInstructionsText": "Koristite ovu vezu za kreiranje računa ili prijavu.", + "viaAccount": "(Preko ${NAME} računa)", + "youAreSignedInAsText": "Prijavljeni ste kao:" + }, + "achievementChallengesText": "Izazovi za postignuća", + "achievementText": "Postignuće", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Ubij 3 neprijatelja TNT-om", + "descriptionComplete": "Ubio si 3 neprijatelja TNT-om", + "descriptionFull": "Ubij 3 neprijatelja TNT-om na ${LEVEL}", + "descriptionFullComplete": "Ubio si 3 neprijatelja TNT-om na ${LEVEL}", + "name": "3, 2, 1, BUM!!!" + }, + "Boxer": { + "description": "Pobijedi bez korištenja bombi", + "descriptionComplete": "Pobijedio si bez korištenja bombi", + "descriptionFull": "Dovrši ${LEVEL} bez korištenja bombi", + "descriptionFullComplete": "Dovršio si ${LEVEL} bez korištenja bombi", + "name": "Boksač" + }, + "Dual Wielding": { + "descriptionFull": "Konektuj 2 kontrolera (hardver ili aplikacija)", + "descriptionFullComplete": "Konektovana 2 kontrolera (hardver ili aplikacija)", + "name": "Dupla Kontrola" + }, + "Flawless Victory": { + "description": "Pobijedi bez primljenog udarca", + "descriptionComplete": "Pobijedio si bez primljenog udarca", + "descriptionFull": "Pobijedi na ${LEVEL} bez primljenog udarca", + "descriptionFullComplete": "Pobijedio si na ${LEVEL} bez primljenog udarca", + "name": "Pobjeda bez greške" + }, + "Free Loader": { + "descriptionFull": "Pokreni Svako-Za-Svakog igru sa 2+ igrača", + "descriptionFullComplete": "Pokrenuta Svako-Za-Svakog igra sa 2+ igrača", + "name": "Vuk Samotnjak" + }, + "Gold Miner": { + "description": "Ubij 6 neprijatelja minama", + "descriptionComplete": "Ubio si 6 neprijatelja minama", + "descriptionFull": "Ubij 6 neprijatelja minama na ${LEVEL}", + "descriptionFullComplete": "Ubio si 6 neprijatelja minama na ${LEVEL}", + "name": "Eli-mina-tor" + }, + "Got the Moves": { + "description": "Pobijedi bez korištenja bombi i udaraca", + "descriptionComplete": "Pobijedio si bez korištenja bombi i udaraca", + "descriptionFull": "Pobijedi na ${LEVEL} bez korištenja bombi i udaraca", + "descriptionFullComplete": "Pobijedio si na ${LEVEL} bez korištenja bombi i udaraca", + "name": "Imaš ritma" + }, + "In Control": { + "descriptionFull": "Konektuj kontroler. (hardver ili aplikacija)", + "descriptionFullComplete": "Konektovan kontroler. (hardver ili aplikacija)", + "name": "U Kontroli" + }, + "Last Stand God": { + "description": "Osvoji 1000 bodova", + "descriptionComplete": "Osvojio si 1000 bodova", + "descriptionFull": "Osvoji 1000 bodova na ${LEVEL}", + "descriptionFullComplete": "Osvojio si 1000 bodova na ${LEVEL}", + "name": "Bog (${LEVEL})" + }, + "Last Stand Master": { + "description": "Osvoji 250 bodova", + "descriptionComplete": "Osvojio si 250 bodova", + "descriptionFull": "Osvoji 250 bodova na ${LEVEL}", + "descriptionFullComplete": "Osvojio si 250 bodova na ${LEVEL}", + "name": "Majstor (${LEVEL})" + }, + "Last Stand Wizard": { + "description": "Osvoji 500 bodova", + "descriptionComplete": "Osvojio si 500 bodova", + "descriptionFull": "Osvoji 500 bodova na ${LEVEL}", + "descriptionFullComplete": "Osvojio si 500 bodova na ${LEVEL}", + "name": "Čarobnjak (${LEVEL})" + }, + "Mine Games": { + "description": "Ubij 3 neprijatelja minama", + "descriptionComplete": "Ubio si 3 neprijatelja minama", + "descriptionFull": "Ubij 3 neprijatelja minama na ${LEVEL}", + "descriptionFullComplete": "Ubio si 3 neprijatelja minama na ${LEVEL}", + "name": "Igra s minama" + }, + "Off You Go Then": { + "description": "Baci 3 neprijatelja preko ruba mape", + "descriptionComplete": "Bacio si 3 neprijatelja preko ruba mape", + "descriptionFull": "Baci 3 neprijatelja preko ruba mape na ${LEVEL}", + "descriptionFullComplete": "Bacio si 3 neprijatelja preko ruba mape na ${LEVEL}", + "name": "Do (ne)viđenja" + }, + "Onslaught God": { + "description": "Osvoji 5000 bodova", + "descriptionComplete": "Osvojio si 5000 bodova", + "descriptionFull": "Osvoji 5000 bodova na ${LEVEL}", + "descriptionFullComplete": "Osvojio si 5000 bodova na ${LEVEL}", + "name": "Bog (${LEVEL})" + }, + "Onslaught Master": { + "description": "Osvoji 500 bodova", + "descriptionComplete": "Osvojio si 500 bodova", + "descriptionFull": "Osvoji 500 bodova na ${LEVEL}", + "descriptionFullComplete": "Osvojio si 500 bodova na ${LEVEL}", + "name": "Majstor (${LEVEL})" + }, + "Onslaught Training Victory": { + "description": "Pobijedi sve nalete", + "descriptionComplete": "Pobijedio si sve nalete", + "descriptionFull": "Pobijedi sve nalete na ${LEVEL}", + "descriptionFullComplete": "Pobijedio si sve nalete na ${LEVEL}", + "name": "Pobjeda na ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Osvoji 1000 bodova", + "descriptionComplete": "Osvojio si 1000 bodova", + "descriptionFull": "Osvoji 1000 bodova na ${LEVEL}", + "descriptionFullComplete": "Osvojio si 1000 bodova na ${LEVEL}", + "name": "Čarobnjak (${LEVEL})" + }, + "Precision Bombing": { + "description": "Pobijedi bez ikakvih bonusa", + "descriptionComplete": "Pobijedio si bez ikakvih bonusa", + "descriptionFull": "Pobijedi na ${LEVEL} bez ikakvih bonusa", + "descriptionFullComplete": "Pobijedio si na ${LEVEL} bez ikakvih bonusa", + "name": "Precizno bombardiranje" + }, + "Pro Boxer": { + "description": "Pobijedi bez korištenja bombi", + "descriptionComplete": "Pobijedio si bez korištenja bombi", + "descriptionFull": "Pobijedi na ${LEVEL} bez korištenja bombi", + "descriptionFullComplete": "Pobijedio si na ${LEVEL} bez korištenja bombi", + "name": "Profesionalni boksač" + }, + "Pro Football Shutout": { + "description": "Pobijedi ne dopuštajući lošim dečkima da zabiju gol", + "descriptionComplete": "Pobijedio si ne dopuštajući lošim dečkima da zabiju gol", + "descriptionFull": "Pobijedi na ${LEVEL} ne dopuštajući lošim dečkima da zabiju gol", + "descriptionFullComplete": "Pobijedio si na ${LEVEL} ne dopuštajući lošim dečkima da zabiju gol", + "name": "Prazna mreža (${LEVEL})" + }, + "Pro Football Victory": { + "description": "Pobijedi", + "descriptionComplete": "Pobijedio si", + "descriptionFull": "Pobijedi na ${LEVEL}", + "descriptionFullComplete": "Pobijedio si na ${LEVEL}", + "name": "Pobjeda na ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Pobijedi sve nalete", + "descriptionComplete": "Pobijedio si sve nalete", + "descriptionFull": "Pobijedi sve nalete na ${LEVEL}", + "descriptionFullComplete": "Pobijedio si sve nalete na ${LEVEL}", + "name": "Pobjeda na ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Pobijedi sve nalete", + "descriptionComplete": "Pobijedio si sve nalete", + "descriptionFull": "Pobijedi sve nalete na ${LEVEL}", + "descriptionFullComplete": "Pobijedio si sve nalete na ${LEVEL}", + "name": "Pobjeda na ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Pobijedi ne dopuštajući lošim dečkima da zabiju gol", + "descriptionComplete": "Pobijedio si ne dopuštajući lošim dečkima da zabiju gol", + "descriptionFull": "Pobijedi na ${LEVEL} ne dopuštajući lošim dečkima da zabiju gol", + "descriptionFullComplete": "Pobijedio si na ${LEVEL} ne dopuštajući lošim dečkima da zabiju gol", + "name": "Prazna mreža (${LEVEL})" + }, + "Rookie Football Victory": { + "description": "Pobijedi", + "descriptionComplete": "Pobijedio si", + "descriptionFull": "Pobijedi na ${LEVEL}", + "descriptionFullComplete": "Pobijedio si na ${LEVEL}", + "name": "Pobjeda na ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Pobijedi sve nalete", + "descriptionComplete": "Pobijedio si sve nalete", + "descriptionFull": "Pobijedi sve nalete na ${LEVEL}", + "descriptionFullComplete": "Pobijedio si sve nalete na ${LEVEL}", + "name": "Pobjeda na ${LEVEL}" + }, + "Runaround God": { + "description": "Osvoji 2000 bodova", + "descriptionComplete": "Osvojio si 2000 bodova", + "descriptionFull": "Osvoji 2000 bodova na ${LEVEL}", + "descriptionFullComplete": "Osvojio si 2000 bodova na ${LEVEL}", + "name": "Bog (${LEVEL})" + }, + "Runaround Master": { + "description": "Osvoji 500 bodova", + "descriptionComplete": "Osvojio si 500 bodova", + "descriptionFull": "Osvoji 500 bodova na ${LEVEL}", + "descriptionFullComplete": "Osvojio si 500 bodova na ${LEVEL}", + "name": "Majstor (${LEVEL})" + }, + "Runaround Wizard": { + "description": "Osvoji 1000 bodova", + "descriptionComplete": "Osvojio si 1000 bodova", + "descriptionFull": "Osvoji 1000 bodova na ${LEVEL}", + "descriptionFullComplete": "Osvojio si 1000 bodova na ${LEVEL}", + "name": "Čarobnjak (${LEVEL})" + }, + "Sharing is Caring": { + "descriptionFull": "Uspešno podeli igru sa drugom", + "descriptionFullComplete": "Uspešno podeljena igra sa drugom", + "name": "Deljenje na Čekanju" + }, + "Stayin' Alive": { + "description": "Pobijedi bez da ijednom umreš", + "descriptionComplete": "Pobijedio si bez da si ijednom umro", + "descriptionFull": "Pobijedi na ${LEVEL} bez da ijednom umreš", + "descriptionFullComplete": "Pobijedio si na ${LEVEL} bez da si ijednom umro", + "name": "Preživljavam" + }, + "Super Mega Punch": { + "description": "Nanesi 100% štete jednim udarcem", + "descriptionComplete": "Nanio si 100% štete jednim udarcem", + "descriptionFull": "Nanesi 100% štete jednim udarcem na ${LEVEL}", + "descriptionFullComplete": "Nanio si 100% štete jednim udarcem na ${LEVEL}", + "name": "Super mega udarac" + }, + "Super Punch": { + "description": "Nanesi 50% štete jednim udarcem", + "descriptionComplete": "Nanio si 50% štete jednim udarcem", + "descriptionFull": "Nanesi 50% štete jednim udarcem na ${LEVEL}", + "descriptionFullComplete": "Nanio si 50% štete jednim udarcem na ${LEVEL}", + "name": "Super Udarac" + }, + "TNT Terror": { + "description": "Ubij 6 neprijatelja TNT-om", + "descriptionComplete": "Ubio si 6 neprijatelja TNT-om", + "descriptionFull": "Ubij 6 neprijatelja TNT-om na ${LEVEL}", + "descriptionFullComplete": "Ubio si 6 neprijatelja TNT-om na ${LEVEL}", + "name": "TNT ubojica" + }, + "Team Player": { + "descriptionFull": "Pokreni igru Timova sa 4+ igrača", + "descriptionFullComplete": "Pokrenuta igra Timova sa 4+ igrača", + "name": "Timski Igrač" + }, + "The Great Wall": { + "description": "Zaustavi baš svakog neprijatelja", + "descriptionComplete": "Zaustavio si baš svakog neprijatelja", + "descriptionFull": "Zaustavi baš svakog neprijatelja na ${LEVEL}", + "descriptionFullComplete": "Zaustavio si baš svakog neprijatelja na ${LEVEL}", + "name": "Veliki zid" + }, + "The Wall": { + "description": "Zaustavi baš svakog neprijatelja", + "descriptionComplete": "Zaustavio si baš svakog neprijatelja", + "descriptionFull": "Zaustavi baš svakog neprijatelja na ${LEVEL}", + "descriptionFullComplete": "Zaustavio si baš svakog neprijatelja na ${LEVEL}", + "name": "Zid" + }, + "Uber Football Shutout": { + "description": "Pobijedi ne dopuštajući lošim dečkima da zabiju gol", + "descriptionComplete": "Pobijedio si ne dopuštajući lošim dečkima da zabiju gol", + "descriptionFull": "Pobijedi ${LEVEL} ne dopuštajući lošim dečkima da zabiju gol", + "descriptionFullComplete": "Pobijedio si na ${LEVEL} ne dopuštajući lošim dečkima da zabiju gol", + "name": "Prazna mreža (${LEVEL})" + }, + "Uber Football Victory": { + "description": "Pobijedi", + "descriptionComplete": "Pobijedio si", + "descriptionFull": "Pobijedi na ${LEVEL}", + "descriptionFullComplete": "Pobijedio si na ${LEVEL}", + "name": "Pobjeda na ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Pobijedi sve nalete", + "descriptionComplete": "Pobijedio si sve nalete", + "descriptionFull": "Pobijedi sve nalete na ${LEVEL}", + "descriptionFullComplete": "Pobijedio si sve nalete na ${LEVEL}", + "name": "Pobijedi na ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Pobijedi sve nalete", + "descriptionComplete": "Pobijedio si sve nalete", + "descriptionFull": "Pobijedi sve nalete na ${LEVEL}", + "descriptionFullComplete": "Pobijedio si sve nalete na ${LEVEL}", + "name": "Pobjeda na ${LEVEL}" + } + }, + "achievementsRemainingText": "Preostala Postignuća:", + "achievementsText": "Postignuća", + "achievementsUnavailableForOldSeasonsText": "Žao nam je,postignuća pojedinosti nisu dostupni za stare sezone.", + "activatedText": "${THING} uključeno.", + "addGameWindow": { + "getMoreGamesText": "Još igara...", + "titleText": "Dodaj igru" + }, + "allowText": "Dopusti", + "alreadySignedInText": "Tvoj akaunt je prijavljen sa drugog uredjaja;\nmolimo promenite akaunt ili zatvori igru na\ntvom drugom uredjaju i probaj opet.", + "apiVersionErrorText": "Nemoguće je učitati modul ${NAME}; napravljen je za ${VERSION_USED} verziju aplikacije; potrebna je verzija ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Automatski\" omogućuje ovo samo kad su slušalice priključene)", + "headRelativeVRAudioText": "VR relativni zvuk", + "musicVolumeText": "Glasnoća glazbe", + "soundVolumeText": "Glasnoća zvukova", + "soundtrackButtonText": "Glazbena lista", + "soundtrackDescriptionText": "(postavi svoju vlasitu glazbu da svira tijekom igara)", + "titleText": "Zvuk" + }, + "autoText": "Automatski", + "backText": "Nazad", + "banThisPlayerText": "Zabrani ovog igrača", + "bestOfFinalText": "Najbolji od ${COUNT} - konačni rezultat:", + "bestOfSeriesText": "Najbolji od ${COUNT} - rezultati:", + "bestOfUseFirstToInstead": 1, + "bestRankText": "Najbolji je bio: #${RANK}", + "bestRatingText": "Tvoja najbolja ocjena je ${RATING}", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Ubrzaj", + "bsRemoteConfigureInAppText": "${REMOTE_APLIKACIJA_IME} je podešeno u samoj aplikaciji.", + "buttonText": "tipka", + "canWeDebugText": "Bi li htio da BombSquad automatski prijavi\ngreške, rušenja, i osnovne informacije o korištenju programeru? \n\nOvi podaci ne sadrže osobne informacije i pomažu\nda igra teče glatko i bez grešaka.", + "cancelText": "Odustani", + "cantConfigureDeviceText": "Žao mi je, ${DEVICE} nije moguće podesiti.", + "challengeEndedText": "Ovaj izazov je završio.", + "chatMuteText": "Stišaj Chat", + "chatMutedText": "Chat Stišan", + "chatUnMuteText": "Upali Chat", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Moraš završiti ovu\nrazinu da nastaviš!", + "completionBonusText": "Završni bonus", + "configControllersWindow": { + "configureControllersText": "Podesi kontrolere", + "configureKeyboard2Text": "Podesi P2 tipkovnicu", + "configureKeyboardText": "Podesi tipkovnica", + "configureMobileText": "Mobilni uređaji kao kontroleri", + "configureTouchText": "Podesi Touchscreen", + "ps3Text": "PS3 kontroleri", + "titleText": "Kontroleri", + "wiimotesText": "Wiimote-ovi", + "xbox360Text": "Xbox 360 kontroleri" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Pažnja: podrška za kontrole ovisi o uređaju i verziji Androida.", + "pressAnyButtonText": "Na kontroleru pritisni bilo koju tipku\nkoju želiš podesiti...", + "titleText": "Podesi kontrolere" + }, + "configGamepadWindow": { + "advancedText": "Napredno", + "advancedTitleText": "Napredno podešavanje kontrolera", + "analogStickDeadZoneDescriptionText": "(povećaj ovo ako tvoj lik otklizi kad otpustiš palicu)", + "analogStickDeadZoneText": "Mrtva zona analogne palice", + "appliesToAllText": "(primjenjuje se na sve kontrolere ove vrste)", + "autoRecalibrateDescriptionText": "(uključi ovo ako se tvoj lik ne kreće punom brzinom)", + "autoRecalibrateText": "Automatski rekalibriraj anlognu palicu", + "axisText": "os", + "clearText": "ukloni", + "dpadText": "dpad", + "extraStartButtonText": "Dodatna Start tipka", + "ifNothingHappensTryAnalogText": "Ako se ništa ne događa, pokušaj tu kontrolu dodijeliti analognoj palici.", + "ifNothingHappensTryDpadText": "Ako se ništa ne događa, pokušaj tu kontrolu dodijeliti d-padu.", + "ignoreCompletelyDescriptionText": "(Spreči ovaj kontroler od uticanja igri i menijima)", + "ignoreCompletelyText": "Ignoriši kompletno", + "ignoredButton1Text": "Zanemarena tipka 1", + "ignoredButton2Text": "Zanemarena tipka 2", + "ignoredButton3Text": "Zanemarena tipka 3", + "ignoredButton4Text": "Ignorisan tipka 4", + "ignoredButtonDescriptionText": "(koristi ovo da spriječiš 'home' i 'sync' tipke da utječu na sučelje)", + "pressAnyAnalogTriggerText": "Pritisni bilo koji analogni okidač...", + "pressAnyButtonOrDpadText": "Pritisni bilo koju tipku ili dpad...", + "pressAnyButtonText": "Pririsni bilo koju tipku...", + "pressLeftRightText": "Pritisni lijevo ili desno...", + "pressUpDownText": "Pritisni gore ili dolje...", + "runButton1Text": "Tipka za trčanje 1", + "runButton2Text": "Tipka za trčanje 2", + "runTrigger1Text": "Okidač za trčanje 1", + "runTrigger2Text": "Okidač za trčanje 2", + "runTriggerDescriptionText": "(analogni okidači omogućuju ti da trčiš pri promjenjivim brzinama)", + "secondHalfText": "Koristi ovo da podesiš drugu polovicu\n2 kontrolera u 1 uređaja koji se\npokazuje kao jedan kontroler.", + "secondaryEnableText": "Omogući", + "secondaryText": "Sekundarni kontroler", + "startButtonActivatesDefaultDescriptionText": "(isključi ovo ako je tvoja start tipka sličnija 'menu' tipki)", + "startButtonActivatesDefaultText": "Start tipka aktvira zadani widget", + "titleText": "Podešavanja kontrolera", + "twoInOneSetupText": "Podešavanje 2 u 1 kontrolera", + "uiOnlyDescriptionText": "(Spreči ovaj kontroler od ulaska u igru)", + "uiOnlyText": "Limit korišćenja menija", + "unassignedButtonsRunText": "Sve nedodijeljene tipke su za trk", + "unsetText": "", + "vrReorientButtonText": "Orijentacija za VS" + }, + "configKeyboardWindow": { + "configuringText": "Podešavanje uređaja ${DEVICE}", + "keyboard2NoteText": "Pažnja: većina tipkovnica može registrirati samo nekoliko pritisaka tipki\nodjednom, pa bi igranje s drugim igračem na tipkovnici\nmoglo raditi bolje ako postoji odvojena tipkovnica da je koristi. \nNo, ipak ćeš morati dodijeliti jedinstvene kontrole za\noba igrača u tom slučaju." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Veličina akcijskih kontrola", + "actionsText": "Akcijske kontrole", + "buttonsText": "tipke", + "dragControlsText": "", + "joystickText": "igraća palica", + "movementControlScaleText": "Veličina kontrola kretanja", + "movementText": "Kretanje", + "resetText": "Poništi promjene", + "swipeControlsHiddenText": "Sakrij ikone povlačenja", + "swipeInfoText": "Treba malo vremena da se naviknete na kontrole 'Povlačenje' \nali je lakše igrati bez da gledaš u kontrole.", + "swipeText": "povlačenje", + "titleText": "Podesi ekran na dodir" + }, + "configureItNowText": "Podesi sada?", + "configureText": "Podesi", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Za najbolje rezultate trebat ćeš wifi mrežu bez laga(zastoja). Možeš \nsmanjiti wifi lag tako da isključiš ostale bežične uređaje, igraš\nBlizu tvog wifi modema, i priključujući\ndomaćina igre direktno na mrežu putem entherneta.", + "explanationText": "Da možeš koristiti pametni telefon ili tablet kao bežični kontroler, \ninstaliraj \"${REMOTE_APP_NAME}\" aplikaciju na njega. Bilo koji broj uređaja\nse može povezati sa ${APP_NAME} igrom preko Wi-Fi-a", + "forAndroidText": "za Android:", + "forIOSText": "za iOS:", + "getItForText": "Get ${REMOTE_APP_NAME} za IOS na Apple APP storu\nili za Android na Google Plej storu ili Amazon App storu", + "googlePlayText": "Google Play", + "titleText": "Korištenje mobilnih uređaja kao kontrolera:" + }, + "continuePurchaseText": "Nastavi za ${PRICE}?", + "continueText": "Nastavi", + "controlsText": "Kontrole", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Ovo se ne primjenjuje na ukupni poredak.", + "activenessInfoText": "Ovaj se multiplikator povećava na dane kada\nigraš, a smanjuje na dane kada ne igraš.", + "activityText": "Aktivnost", + "campaignText": "Kampanja", + "challengesInfoText": "Zaradi nagrade završavanjem mini-igara.\n\nNagrade i težina levela se uvećava\nsvakog puta kada je izazov završen i \nsmanjuje se kada istekne ili je zabranjen.", + "challengesText": "Izazovi", + "currentBestText": "Trenutno Najbolji", + "customText": "Razno", + "entryFeeText": "Kotizacija", + "forfeitConfirmText": "Zaboravio si ovaj izazov?", + "forfeitNotAllowedYetText": "Ovaj izazov nemože još biti zaboravljen.", + "forfeitText": "Zaboraviti", + "multipliersText": "Multiplikatori", + "nextChallengeText": "Sledeći izazov", + "nextPlayText": "Sledeća igra", + "ofTotalTimeText": "od ${TOTAL}", + "playNowText": "Igraj sad", + "pointsText": "Bodovi", + "powerRankingFinishedSeasonUnrankedText": "(Završena sezona neobjavljena)", + "powerRankingNotInTopText": "(nisi u najboljih ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} bodova", + "powerRankingPointsMultText": "(x ${NUMBER} bodova)", + "powerRankingPointsText": "${NUMBER} bodova", + "powerRankingPointsToRankedText": "(${CURRENT} od ${REMAINING} bodova)", + "powerRankingText": "Rang igrača", + "prizesText": "Nagrade", + "proMultInfoText": "Igrači s ${PRO} nadogradnjom\novdje dobivaju još ${PERCENT}% bodova.", + "seeMoreText": "Više...", + "skipWaitText": "Prekočite Čekanje", + "timeRemainingText": "Preostalo Vrijeme", + "toRankedText": "Do pozicije na ljestvici", + "totalText": "ukupno", + "tournamentInfoText": "Završite za visoke rezultate sa\nostalim igračima u tvojoj ligi\n\nNagrade su dodeljene igračima sa \nnajvećim rezultatom kada se turnir završi.", + "welcome1Text": "Dobrodošao u ${LEAGUE}. Možeš napredovati u\nligi osvajajući dobre ocjene(zvjezdice), dovršavajući\npostignuća, i osvajajući trofeje u turnirima.", + "welcome2Text": "Možeš zarađivati kupone raznim aktivnostima.\nKupone možeš koristiti za otključavanje novih likova, mapa, i\nigara, ulaženje u turnire, i puno više.", + "yourPowerRankingText": "Tvoja pozicija" + }, + "copyOfText": "Kopija ${NAME}", + "copyText": "Kopirati", + "createEditPlayerText": "", + "createText": "Stvori", + "creditsWindow": { + "additionalAudioArtIdeasText": "Dodatni Zvukovi, Rane Ilustracije, i Ideje by ${NAME}", + "additionalMusicFromText": "Dodatna glazba od ${NAME}", + "allMyFamilyText": "Svi moji prijatelji i obitelj koji su mi pomogli testirati", + "codingGraphicsAudioText": "Kodiranje, grafika i zvukovi by ${NAME}", + "languageTranslationsText": "Prijevodi:", + "legalText": "Legalno:", + "publicDomainMusicViaText": "Glazba u javnom vlasništvu preko ${NAME}", + "softwareBasedOnText": "Ovaj softver je dijelom baziran radu ${NAME} grupe", + "songCreditText": "${TITLE} izvodi ${PERFORMER}\nSkladao ${COMPOSER}, uredio ${ARRANGER} , objavio ${PUBLISHER},\nusluga ${SOURCE}", + "soundAndMusicText": "Zvuk i glazba:", + "soundsText": "Zvukovi (${SOURCE}):", + "specialThanksText": "Posebne Zahvale:", + "thanksEspeciallyToText": "Posebno hvala ${NAME}", + "titleText": "${APP_NAME} Krediti", + "whoeverInventedCoffeeText": "Tkogod je izumio kavu" + }, + "currentStandingText": "Tvoj trenutačni plasman je #${RANK}", + "customizeText": "Prilagodi...", + "deathsTallyText": "Umro si ${COUNT} puta", + "deathsText": "Smrti", + "debugText": "ukloni greške", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Preporučeno je da Postavke->Grafika->Teksture postavite na 'Visoko' dok testirate ovo.", + "runCPUBenchmarkText": "Pokreni test učinka CPU-a (procesora)", + "runGPUBenchmarkText": "Pokreni test učinka GPU-a (grafike)", + "runMediaReloadBenchmarkText": "Pokreni Media-Reload test učinka", + "runStressTestText": "Pokreni test opterećenja", + "stressTestPlayerCountText": "Broj igrača", + "stressTestPlaylistDescriptionText": "Lista igara testa opterećenja", + "stressTestPlaylistNameText": "Ime liste igara", + "stressTestPlaylistTypeText": "Vrsta liste igara", + "stressTestRoundDurationText": "Trajanje runde", + "stressTestTitleText": "Test opterećenja", + "titleText": "Testovi učinka i opterećenja", + "totalReloadTimeText": "Ukupno vrijeme ponovnog učitavanja: ${TIME} (pogledaj log za detalje)" + }, + "defaultGameListNameText": "Zadana ${PLAYMODE} lista igara", + "defaultNewGameListNameText": "Moja ${PLAYMODE} lista igara", + "deleteText": "Izbriši", + "demoText": "Demo", + "denyText": "Odbij", + "desktopResText": "Desktop rezolucija", + "difficultyEasyText": "Lagano", + "difficultyHardOnlyText": "Samo u teškom modu", + "difficultyHardText": "Teško", + "difficultyHardUnlockOnlyText": "Ovu razinu možeš otključati samo u teškom modu. \nMisliš li da možeš to!?!?!", + "directBrowserToURLText": "Molim posjetite sljedeći URL s web-preglednikom:", + "disableRemoteAppConnectionsText": "Isključi konekciju Remote-aplikacije", + "disableXInputDescriptionText": "Dozvoljava više od 4 kontrolera ali možda neće raditi dobro.", + "disableXInputText": "Isključi XInput", + "doneText": "Gotovo", + "drawText": "Neriješeno", + "duplicateText": "Dupliciraj", + "editGameListWindow": { + "addGameText": "Dodaj\nIgru", + "cantOverwriteDefaultText": "Nemoguće je mijenjati zadanu listu igara!", + "cantSaveAlreadyExistsText": "Lista igara s tim imenom već postoji!", + "cantSaveEmptyListText": "Nemoguće je spremiti praznu listu igara!", + "editGameText": "Uredi\nIgru", + "listNameText": "Ime liste igara", + "nameText": "Ime", + "removeGameText": "Ukloni\nIgru", + "saveText": "Spremi Listu", + "titleText": "Uređivaj liste igara" + }, + "editProfileWindow": { + "accountProfileInfoText": "Ovaj specijalni \nprofil ima ime i \nikonicu zasnovanu \nna tvom \nakauntu.\n\n${ICONS}", + "accountProfileText": "(profil akaunta)", + "availableText": "Ime \"${NAME}\" je dostupno.", + "changesNotAffectText": "Promjene neće utjecati na likove koji su već u igri. ", + "characterText": "lik", + "checkingAvailabilityText": "Proveravanje dostupnosti za \"${NAME}\"...", + "colorText": "boja", + "getMoreCharactersText": "Još likova...", + "getMoreIconsText": "Uzmi više ikonica...", + "globalProfileInfoText": "Profil svakog igraca na svijetu ima svoje ime. \nTakođer postoje i osobne ikone.", + "globalProfileText": "(globalni profil)", + "highlightText": "pozadina", + "iconText": "Ikonica", + "localProfileInfoText": "Lokalni profili igrača nemaju ikone i njihova imena možda\nnisu jedinstvena. Nadogradi na\nglobalni profil\nda rezerviraš jedinstveno ime i prilagođenu ikonu.", + "localProfileText": "(Lokalni profil)", + "nameDescriptionText": "Ime Igrača", + "nameText": "Ime", + "randomText": "nasumično", + "titleEditText": "Uredi Profil", + "titleNewText": "Novi Profil", + "unavailableText": "\"${NAME}\" nije dosgupan; probaj drugo ime", + "upgradeProfileInfoText": "Ovo ce zauzeti tvoje korisnicko ime\nI dozvoliti ti da koristis osobnu ikonu", + "upgradeToGlobalProfileText": "Nadogradi na Globalni Profil" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Ne možeš izbrisati zadanu glazbenu listu.", + "cantEditDefaultText": "Ne možeš uređivati zadanu glazbenu listu. Dupliciraj je ili napravi novu.", + "cantOverwriteDefaultText": "Nemoguće je presnimiti zadanu glazbenu listu", + "cantSaveAlreadyExistsText": "Glazbena lista s tim imenom već postoji!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Zadana glazbena lista", + "deleteConfirmText": "Izbriši glazbenu listu: \n\n'${NAME}'?", + "deleteText": "Izbriši\nglazbenu listu", + "duplicateText": "Dupliciraj\nglazbenu listu", + "editSoundtrackText": "Uređuj glazbene liste", + "editText": "Uredi\nglazbenu listu", + "fetchingITunesText": "dohvaćam glazbene liste...", + "musicVolumeZeroWarning": "Upozorenje: glasnoća glazbe je postavljena na 0", + "nameText": "Ime", + "newSoundtrackNameText": "Moja glazbena lista ${COUNT}", + "newSoundtrackText": "Nova glazbena lista:", + "newText": "Nova\nglazbena lista", + "selectAPlaylistText": "Izaberi listu igara", + "selectASourceText": "Izvor glazbe", + "testText": "test", + "titleText": "Glazbene liste", + "useDefaultGameMusicText": "Zadana Glazba", + "useITunesPlaylistText": "Glazbena lista", + "useMusicFileText": "Glazbena Datoteka (mp3, itd.)", + "useMusicFolderText": "Mapa s Glazbenim Datotekama" + }, + "editText": "Izmjeni", + "endText": "Kraj", + "enjoyText": "Uživaj", + "epicDescriptionFilterText": "${DESCRIPTION} U epskom usporenom filmu.", + "epicNameFilterText": "${NAME} (epski mod)", + "errorAccessDeniedText": "pristup zabranjen", + "errorOutOfDiskSpaceText": "nema prostora na disku", + "errorText": "Greška", + "errorUnknownText": "nepoznata greška", + "exitGameText": "Izlaz iz ${APP_NAME}?", + "exportSuccessText": "'${NAME}' je izvezen.", + "externalStorageText": "Vanjska Pohrana", + "failText": "Neuspjeh", + "fatalErrorText": "Uh oh; nešto nedostaje ili je pokvareno. \nMolim pokušaj ponovno instalirati aplikaciju ili\nkontaktiraj ${EMAIL} za pomoć.", + "fileSelectorWindow": { + "titleFileFolderText": "Izaberi Datoteku ili Mapu", + "titleFileText": "Izaberi Datoteku", + "titleFolderText": "Izaberi Mapu", + "useThisFolderButtonText": "Koristi Ovu Mapu" + }, + "filterText": "Pretraži", + "finalScoreText": "Konačni Rezultat", + "finalScoresText": "Konačni Rezultati", + "finalTimeText": "Konačno Vrijeme", + "finishingInstallText": "Dovršavam instalaciju; samo trenutak...", + "fireTVRemoteWarningText": "* Za bolje iskustvo, koristi\nGame Controller ili instaliraj\n'${REMOTE_APP_NAME}' aplikaciju na tvoje\ntelefone i tablete.", + "firstToFinalText": "Prvi do ${COUNT} - konačni rezultat", + "firstToSeriesText": "Prvi do ${COUNT} - rezultati", + "fiveKillText": "PETEROSTRUKO UBOJSTVO!!!", + "flawlessWaveText": "Nalet bez greške!", + "fourKillText": "ČETVEROSTRUKO UBOJSTVO!!!", + "friendScoresUnavailableText": "Rezultati prijatelja nedostupni.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Najbolji u igri ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "Ne možeš izbrisati zadanu listu igara.", + "cantEditDefaultText": "Ne možeš uređivati zadanu listu igara! Dupliciraj je ili napravi novu.", + "cantShareDefaultText": "Ne možeš dijeliti zadan popis pjesama.", + "deleteConfirmText": "Izbriši \"${LIST}\"?", + "deleteText": "Izbriši \nListu", + "duplicateText": "Dupliciraj\nListu", + "editText": "Uredi \nListu", + "newText": "Nova\nLista", + "showTutorialText": "Pokaži upute", + "shuffleGameOrderText": "Promiješaj red igara", + "titleText": "Prilagodi ${TYPE} liste igara" + }, + "gameSettingsWindow": { + "addGameText": "Dodaj Igru" + }, + "gamesToText": "${WINCOUNT} igre naprema ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Zapamti: bilo koji uređaj u partiji može imati više\nod jednog igrača ako imaš dovoljno kontrolera.", + "aboutDescriptionText": "Koristi ove kartice da sastaviš partiju. \n\nPartije ti omogućuju da igraš igre i turnire\ns tvojim prijateljima na različitim uređajima. \n\nKoristi ${PARTY} tipku u gornjem desnom kutu za\nrazgovor i komunikaciju s ostalima.\n(na kontroleru, pritsni ${BUTTON} dok si u izborniku)", + "aboutText": "O", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} poslao ti je ${COUNT} ulaznica za ${APP_NAME}", + "appInviteSendACodeText": "Pošalji im kod", + "appInviteTitleText": "${APP_NAME} Pozovi u igru", + "bluetoothAndroidSupportText": "(radi s bilo kojim Android uređajem koji podržava Bluetooth)", + "bluetoothDescriptionText": "Ugosti/uključi se u partiju preko Bluetooth-a:", + "bluetoothHostText": "Ugosti preko Bluetooth-a", + "bluetoothJoinText": "Uključi se preko Bluetooth-a", + "bluetoothText": "Bluetooth", + "checkingText": "provjeravam...", + "copyCodeConfirmText": "Kôd je kopiran u međuspremnik.", + "copyCodeText": "Kopiraj kod", + "dedicatedServerInfoText": "Za najbolje rezultate, postavi posvećen server. Vidi bombsquadgame.com/server da saznas kako.", + "disconnectClientsText": "Ovo će isključiti ${COUNT} igrača\niz partije. Jesi li siguran?", + "earnTicketsForRecommendingAmountText": "Prijatelji će dobiti ${COUNT} ulaznica ako probaju igru\n(ti ćeš dobiti ${YOU_COUNT} ulaznica za svakog koji proba)", + "earnTicketsForRecommendingText": "Podeli igri za besplatne karte\n...", + "emailItText": "Emajlaj", + "favoritesSaveText": "Spremi kao favorit", + "favoritesText": "Omiljeni", + "freeCloudServerAvailableMinutesText": "Sljedeći besplatni poslužitelj u oblaku dostupan za ${MINUTES} minuta.", + "freeCloudServerAvailableNowText": "Besplatno dostupan poslužitelj u oblaku!", + "freeCloudServerNotAvailableText": "Nema dostupnih besplatnih poslužitelja u oblaku.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} ulaznica od ${NAME}", + "friendPromoCodeAwardText": "Primit ćeš ${COUNT} ulaznica svaki put kada je kod iskorišten.", + "friendPromoCodeExpireText": "Ovaj kod će isteći za ${EXPIRE_HOURS} sati i radi samo za nove igrače.", + "friendPromoCodeInstructionsText": "Da ga iskoristiš, otvori ${APP_NAME} idi u \"Postavke->Napredno->Unesi kod\".\nVidi bombsquadgame.com za sve platforme na kojima možeš igrati.", + "friendPromoCodeRedeemLongText": "Može biti otkupljeno za ${COUNT} besplatnih ulaznica do ${MAX_USES} ljudi.", + "friendPromoCodeRedeemShortText": "Može biti otkupljeno za ${COUNT} ulaznica u igri.", + "friendPromoCodeWhereToEnterText": "(u \"Postavke->Napredno>Unesi Kod\")", + "getFriendInviteCodeText": "Dohvati kod za poziv prijatelja", + "googlePlayDescriptionText": "Pozovi Google Play igrače u tvoju partiju:", + "googlePlayInviteText": "Pozovi", + "googlePlayReInviteText": "${COUNT} Google Play igrača iz tvoje partije\nće biti isključeno iz nje ako započneš novi poziv. \nUključi ih u njega ako želiš da se vrate.", + "googlePlaySeeInvitesText": "Pogledaj pozive", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play verzija)", + "hostPublicPartyDescriptionText": "Izradi javnu partiju", + "hostingUnavailableText": "Hosting nedostupan", + "inDevelopmentWarningText": "Pažnja: \n\nMrežna igra je nova značajka koja je još u razvoju. \nZasad, preporučuje se da su svi\nigrači spojeni na istu Wi-Fi mrežu.", + "internetText": "Internet", + "inviteAFriendText": "Prijatelji nemaju igru? Pozovi ih da je\nprobaju i oni će dobiti ${COUNT} besplatnih ulaznica.", + "inviteFriendsText": "Pozovi Prijatelje", + "joinPublicPartyDescriptionText": "Pridruži se javnoj partiji", + "localNetworkDescriptionText": "Uđi u blisku partiju (Lan, Bluetooth, itd.)", + "localNetworkText": "Lokalna mreža", + "makePartyPrivateText": "Postavi moju partiju privatnom", + "makePartyPublicText": "Postavi moju partiju javnom", + "manualAddressText": "Adresa", + "manualConnectText": "Spoji se", + "manualDescriptionText": "Uljuči se u partiju po adresi:", + "manualJoinSectionText": "Uđi s Adresom", + "manualJoinableFromInternetText": "Mogu li se drugi priključiti tebi s Interneta?:", + "manualJoinableNoWithAsteriskText": "NE*", + "manualJoinableYesText": "DA", + "manualRouterForwardingText": "*da popraviš ovo, pokušaj podesiti tvoj modem da prosljeđuje UDP port ${PORT} za tvoju lokalnu adresu", + "manualText": "Ručno", + "manualYourAddressFromInternetText": "Tvoja adresa s Interneta:", + "manualYourLocalAddressText": "Tvoja lokalna adresa:", + "nearbyText": "Blizu", + "noConnectionText": "", + "otherVersionsText": "(druge verzije)", + "partyCodeText": "Grupna šifra", + "partyInviteAcceptText": "Prihvati", + "partyInviteDeclineText": "Odbij", + "partyInviteGooglePlayExtraText": "(pogledaj 'Google Play' karticu u prozoru 'Sakupi')", + "partyInviteIgnoreText": "Odbaci", + "partyInviteText": "${NAME} te pozvao\nda se priključiš njegovoj partiji!", + "partyNameText": "Naziv igre", + "partyServerRunningText": "Tvoj grupni server radi.", + "partySizeText": "Veličina žurke", + "partyStatusCheckingText": "provjeravam status...", + "partyStatusJoinableText": "tvoja igra je spremna za povezivanje s interneta", + "partyStatusNoConnectionText": "ne mogu se spojiti na server", + "partyStatusNotJoinableText": "tvoja igra nije dostupna preko interneta", + "partyStatusNotPublicText": "tvoja igra nije javna", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Privatne grupe radu na posvećenim cloud serverima; Nikakvih ruter konfiguracija potrebno", + "privatePartyHostText": "Napravi privatnu grupu", + "privatePartyJoinText": "Uđi u privatnu grupu", + "privateText": "Privatno", + "publicHostRouterConfigText": "Za ovo možda bude trebalo konfiguriranje \"port-forwarding\"-a na vašem ruteru. Za lakšu opciju napravite privatnu grupu", + "publicText": "Javno", + "requestingAPromoCodeText": "Dohvaćam kod...", + "sendDirectInvitesText": "Pošalji izravni poziv", + "sendThisToAFriendText": "Posalji ovaj kod prijatelju:", + "shareThisCodeWithFriendsText": "Podijeli ovaj kod s prijateljima:", + "showMyAddressText": "Prikaži moju IP adresu", + "startHostingPaidText": "Napravi sada za ${COST}", + "startHostingText": "Napravi", + "startStopHostingMinutesText": "Možeš početi i zaustaviti server besplatno za slijedećih ${MINUTES} minuta.", + "stopHostingText": "Prestani server", + "titleText": "Okupljanje", + "wifiDirectDescriptionBottomText": "Ako svi uređaji imaju 'Wi-Fi Direct' opciju, trebali bi ga moći iskoristiti da pronađu jedan\ndrugoga i povežu se. Kad su svi uređaji povezani, možeš kreiratu igru\nkoristeći karticu 'Lokalna mreža', isto kao i kod obične Wi-Fi mreže. \n\nZa najbolje rezultate, domaćin Wi-Fi Directa također bi trebao biti domaćin ${APP_NAME} igre.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct možete koristiti da povežete Android uređaje direktno bez \npotrebe za Wi-Fi mrežom. Ovo najbolje radi na Android verziji 4.2 ili novijoj. \n\nZa korištenje, otvori Wi-Fi postavke i potraži 'Wi-Fi Direct' u izborniku.", + "wifiDirectOpenWiFiSettingsText": "Otvori Wi-Fi postavke", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(radi na svim platformama)", + "worksWithGooglePlayDevicesText": "(radi na uređajima s Google Play (Android) verzijom igre)", + "youHaveBeenSentAPromoCodeText": "Netko ti je poslao ${APP_NAME} promo kod:" + }, + "getTicketsWindow": { + "freeText": "BESPLATNO!", + "freeTicketsText": "Besplatni kuponi", + "inProgressText": "Transakcija je u tijeku; pokušaj ponovno za trenutak.", + "purchasesRestoredText": "Kupovine poništene.", + "receivedTicketsText": "Dobio si ${COUNT} kupona!", + "restorePurchasesText": "Poništi kupovine", + "ticketDoublerText": "Dupli kuponi", + "ticketPack1Text": "Mali paket kupona", + "ticketPack2Text": "Srednji paket kupona", + "ticketPack3Text": "Veliki paket kupona", + "ticketPack4Text": "Jumbo paket kupona", + "ticketPack5Text": "Mamutski paket kupona", + "ticketPack6Text": "Ultimativni paket kupona", + "ticketsFromASponsorText": "Dobij ${COUNT} kupona\nod sponzora", + "ticketsText": "${COUNT} kupona", + "titleText": "Zaradi kupone", + "unavailableLinkAccountText": "Nažalost, kupovina nije dostupna na ovoj platformi.\nKao zaobilazno rješenje, možete povezati račun s računom na \ndrugoj platformi i tamo nastaviti kupovinu.", + "unavailableTemporarilyText": "Ovo je trenutačno nedostupno; molim pokušajte kasnije.", + "unavailableText": "Žao mi je, ovo nije dostupno.", + "versionTooOldText": "Žao mi je, ova verzija igre je prestara; molim ažurirajte je na noviju verziju.", + "youHaveShortText": "imaš ${COUNT}", + "youHaveText": "imaš ${COUNT} kupona" + }, + "googleMultiplayerDiscontinuedText": "Oprostite, Google Play Games servis za partije u igrama više ne postoji.\nTrenutno radim na zamjeni što je brže moguće.\nTo tada, priključujte se u partije na druge načine.\n-Eric", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Uvijek", + "fullScreenCmdText": "Cijeli ekran (Cmd-F)", + "fullScreenCtrlText": "Cijeli ekran (Ctrl-F)", + "gammaText": "Svjetlina(Gamma)", + "highText": "Visoko", + "higherText": "Više", + "lowText": "Nisko", + "mediumText": "Srednje", + "neverText": "Nikad", + "resolutionText": "Rezolucija", + "showFPSText": "Pokaži FPS", + "texturesText": "Teksture", + "titleText": "Grafika", + "tvBorderText": "TV okvir", + "verticalSyncText": "Vertical Sync (Vertikalna sinkronizacija)", + "visualsText": "Vizualno" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nJača od udaraca, ali može rezultirati \nsamoubojstvom. Za najbolje \nrezultate, baci je prema neprijatelju \nprije nego što fitilj potpuno izgori.", + "canHelpText": "${APP_NAME} može pomoći.", + "controllersInfoText": "Možeš igrati ${APP_NAME} s prijeteljima preko mreže, ili svi\nmožete igrati na istom uređaju ako imate dovoljno kontrolera. \n${APP_NAME} podržava razne kontrolere; čak možete koristiti telefone\nkao kontrolere pomoću besplatne '${REMOTE_APP_NAME}' aplikacije. \nZa više informacija pogledaj pod Postavke->Kontroleri.", + "controllersInfoTextRemoteOnly": "Možete igrati ${APP_NAME} sa prijateljima \nPreko wifi-a ili\npreko istog uređaju koristeći mobitele kao kontrolere pomoću besplatnom aplikacijom '${REMOTE_APP_NAME}'", + "controllersText": "Kontroleri", + "controlsSubtitleText": "Tvoj prijateljski ${APP_NAME} lik ima par osnovnih kretnji:", + "controlsText": "Kontrole", + "devicesInfoText": "VR verziju ${APP_NAME} možeš igrati preko mreže s\nobičnom verzijom, pa izvadi svoje dodatne telefone, tablete, \ni računala i igraj. Čak može biti korisno da\npovežeš običnu verziju igre s VR verzijom samo da\nomogućiš ostalima da gledaju akciju.", + "devicesText": "Uređaji", + "friendsGoodText": "Dobro ih je imati. ${APP_NAME} je najzabavniji s\nprijateljima i podržava do 8 odjednom, što nas dovodi do:", + "friendsText": "Prijatelji", + "jumpInfoText": "- Skok - \nSkači da preskočiš manje rupe, \nbacaš stvari više, i\nizraziš sreću.", + "orPunchingSomethingText": "Ili udariti nešto, baciti ga s litice i raznijeti ga na putu dolje ljepljivom bombom.", + "pickUpInfoText": "- Podigni -\nUhvati zastave, neprijatelje, ili bilo što\ndrugo što nije pričvršćeno za tlo. \nPritsni ponovno da baciš.", + "powerupBombDescriptionText": "Omogućuje ti da baciš tri bombe\nzaredom umjesto samo jedne.", + "powerupBombNameText": "Trostruke bombe", + "powerupCurseDescriptionText": "Vjerojatno želiš izbjegavati ovo. \n.... ili možda ne?", + "powerupCurseNameText": "Kletva", + "powerupHealthDescriptionText": "Potpuno te izliječi. \nNikad ne bi pogodio.", + "powerupHealthNameText": "Prva pomoć", + "powerupIceBombsDescriptionText": "Slabije od normalnih bombi\nali smrzavaju tvoje neprijatelje, \nostavljajući ih lomljivima.", + "powerupIceBombsNameText": "Ledene bombe", + "powerupImpactBombsDescriptionText": "Lagano slabije od običnih \nbombi, ali eksplodiraju pri udarcu.", + "powerupImpactBombsNameText": "Kontakt bombe", + "powerupLandMinesDescriptionText": "Dolaze u pakovanjima po 3;\nKorisne za obranu baze ili\nza zaustavljanje brzih neprijatelja.", + "powerupLandMinesNameText": "Mine", + "powerupPunchDescriptionText": "Čini tvoje udarce čvršćima, \nbržima, boljima, jačima.", + "powerupPunchNameText": "Boksačke rukavice", + "powerupShieldDescriptionText": "Prima udarce tako \nda ti ne moraš.", + "powerupShieldNameText": "Energetski štit", + "powerupStickyBombsDescriptionText": "Lijepe se za sve što udare. \nNastaje veselje.", + "powerupStickyBombsNameText": "Ljepljive bombe", + "powerupsSubtitleText": "Naravno, nijedna igra nije dovršena bez bonusa:", + "powerupsText": "Bonusi", + "punchInfoText": "- Udarac -\nUdarci nanose više štete\nšto se brže kreću tvoje šake, \npa trči i vrti se kao luđak.", + "runInfoText": "- Trk -\nDrži BILO KOJU tipku da potrčiš. Okidačke ili ramene (PS L,R 1,2) tipke također rade. \nDok trčiš, puno si brži ali je teže okretati se, pa pazi na zavoje i litice.", + "someDaysText": "Nekad samo želiš udariti nešto. Ili dignuti nešto u zrak.", + "titleText": "${APP_NAME} Pomoć", + "toGetTheMostText": "Da izvučeš najbolje iz ove igre, trebat ćeš:", + "welcomeText": "Dobrodošli u ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} prolazi kroz labirint izbornika -", + "importPlaylistCodeInstructionsText": "Iskoristi ovaj kod za uvoz ove playliste negdje drugdje:", + "importPlaylistSuccessText": "${TYPE} playlista '${NAME}' je uvezena.", + "importText": "Ubaci", + "importingText": "Ubacivanje...", + "inGameClippedNameText": "U igri bi će \n\"${NAME}\"", + "installDiskSpaceErrorText": "GREŠKA: Nemoguće je dovršiti instalaciju. \nMožda nema više prostora na tvom uređaju. \nOslobodi malo prostora i pokušaj ponovno.", + "internal": { + "arrowsToExitListText": "pritisni ${LEFT} ili ${RIGHT} da iziđeš s liste", + "buttonText": "tipka", + "cantKickHostError": "Nemožeš izbaciti domaćina.", + "chatBlockedText": "${NAME} je čet blokiran za ${TIME} sekundi.", + "connectedToGameText": "Ušao '${NAME}'", + "connectedToPartyText": "Priključio si se ${NAME}(o)voj partiji!", + "connectingToPartyText": "Povezujem se...", + "connectionFailedHostAlreadyInPartyText": "Greška u povezivanju; domaćin je u drugoj partiji.", + "connectionFailedPartyFullText": "Veza nije uspostavljena; žurka je puna.", + "connectionFailedText": "Greška u povezivanju.", + "connectionFailedVersionMismatchText": "Greška u povezivanju; domaćin ima drugu verziju igre. \nProvjeri da obojica imate aktualnu verziju i pokušaj ponovno.", + "connectionRejectedText": "Pokušaj povezivanja odbačen.", + "controllerConnectedText": "${CONTROLLER} priključen.", + "controllerDetectedText": "1 kontroler otkriven.", + "controllerDisconnectedText": "${CONTROLLER} isključen.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} isključen. Pokušaj ga ponovno priključiti.", + "controllerForMenusOnlyText": "S ovim kontrolerom se ne može igrati; može se samo kretati kroz menije.", + "controllerReconnectedText": "${CONTROLLER} se ponovno priključio.", + "controllersConnectedText": "${COUNT} kontrolera priključeno.", + "controllersDetectedText": "${COUNT} kontrolera otkriveno.", + "controllersDisconnectedText": "${COUNT} kontrolera isključeno.", + "corruptFileText": "Otkrivene neispravne datoteke. Pokušaj ponovno instalirati, ili pošalji email na adresu: ${EMAIL}", + "errorPlayingMusicText": "Greška u reprodukciji glazbe: ${MUSIC}", + "errorResettingAchievementsText": "Nije moguće poništiti mrežna postignuća; pokušaj ponovno kasnije.", + "hasMenuControlText": "${NAME} ima kontrolu menija.", + "incompatibleNewerVersionHostText": "Domaćin ima noviju verziju igre.\nAžuriraj igru na zadnju verziju i pokušaj ponovo.", + "incompatibleVersionHostText": "Domaćin ima drugu verziju igre. \nProvjeri da obojica imate aktualnu verziju igre i pokušaj ponovno.", + "incompatibleVersionPlayerText": "${NAME} ima drugu verziju igre. \nProvjeri da obojica imate aktualnu verziju igre i pokušaj ponovno.", + "invalidAddressErrorText": "Greška: neispravna adresa.", + "invalidNameErrorText": "Greška: krivo ime.", + "invalidPortErrorText": "Greška: krivi port.", + "invitationSentText": "Pozivnica poslana.", + "invitationsSentText": "${COUNT} pozivnica poslano.", + "joinedPartyInstructionsText": "Netko se priključio u tvoj tim. \nPritisni 'Igraj' da pokreneš igru.", + "keyboardText": "Tipkovnica", + "kickIdlePlayersKickedText": "Izbacujem ${NAME} zbog neaktivnosti.", + "kickIdlePlayersWarning1Text": "${NAME} će biti izbačen za ${COUNT} sekudi ako još bude neaktivan.", + "kickIdlePlayersWarning2Text": "(ovo možeš isključiti pod Postavke -> Napredno)", + "leftGameText": "Izašao '${NAME}'.", + "leftPartyText": "Napustio si ${NAME}(o)vu partiju.", + "noMusicFilesInFolderText": "Mapa ne sadrži glazbene datoteke.", + "playerJoinedPartyText": "${NAME} se uključio u partiju!", + "playerLeftPartyText": "${NAME} je napustio partiju.", + "rejectingInviteAlreadyInPartyText": "Odbijam poziv (već si u partiji).", + "serverRestartingText": "Server se ponovno pokreće. Pridružite se ponovno za trenutak...", + "serverShuttingDownText": "Server se isključuje...", + "signInErrorText": "Greška u prijavi.", + "signInNoConnectionText": "Nije moguće prijaviti se. (nema internetske veze?)", + "telnetAccessDeniedText": "GREŠKA: korisniku nije dopušten telnet pristup.", + "timeOutText": "(završava za ${TIME} sekundi)", + "touchScreenJoinWarningText": "Uključio si se s ekranom na dodir. \nAko si pogriješio, odaberi 'Izbornik->Napusti igru' na njemu.", + "touchScreenText": "Ekran na dodir", + "unableToResolveHostText": "Greška: ne mogu pronaći domaćina.", + "unavailableNoConnectionText": "Ovo je trenutno nedostupno (nema internetske veze?)", + "vrOrientationResetCardboardText": "Koristi ovo da bi vratio na početak orijenaciju VR-a.\nDa bi mogao igrati igru, trebat ćeš vanjski kontroler.", + "vrOrientationResetText": "VR orijentacija poništena.", + "willTimeOutText": "(završit će ako je neaktivan)" + }, + "jumpBoldText": "SKOK", + "jumpText": "Skok", + "keepText": "Zadrži", + "keepTheseSettingsText": "Zadrži ove postavke?", + "keyboardChangeInstructionsText": "Stisni te space tipku dva puta da zamijenite tipkovnice.", + "keyboardNoOthersAvailableText": "Nijedna tipkovnica dostupna.", + "keyboardSwitchText": "Minjanje tipkovnice do \"${NAME}\".", + "kickOccurredText": "${NAME} je izbačen.", + "kickQuestionText": "Izbaci ${NAME}?", + "kickText": "Izbaci", + "kickVoteCantKickAdminsText": "Administratori ne mogu biti izbačeni.", + "kickVoteCantKickSelfText": "Nemozeš izbaciti sebe.", + "kickVoteFailedNotEnoughVotersText": "Nema dovoljno igrača za glasanje.", + "kickVoteFailedText": "Glasanje za izbačaj nije uspelo.", + "kickVoteStartedText": "Glasanje za izbačaj ${NAME} je počelo.", + "kickVoteText": "Glasajte da izbacite", + "kickVotingDisabledText": "Glasanje za izbacivanje je isključeno.", + "kickWithChatText": "Napiši ${YES} u četu za da i ${NO} za ne.", + "killsTallyText": "${COUNT} ubojstava", + "killsText": "Ubojstva", + "kioskWindow": { + "easyText": "Lagano", + "epicModeText": "Epski mod", + "fullMenuText": "Cijeli izbornik", + "hardText": "Teško", + "mediumText": "Srednje", + "singlePlayerExamplesText": "Primjeri razina za jednog igrača / tim", + "versusExamplesText": "Primjeri igara u kojima se igrači bore jedni protiv drugih" + }, + "languageSetText": "Jezik je sad \"${LANGUAGE}\".", + "lapNumberText": "Krug ${CURRENT}/${TOTAL}", + "lastGamesText": "(zadnjih ${COUNT} igara)", + "leaderboardsText": "Najbolji rezultati", + "league": { + "allTimeText": "Ukupan poredak", + "currentSeasonText": "Trenutna sezona (${NUMBER})", + "leagueFullText": "${NAME} liga", + "leagueRankText": "Pozicija u ligi", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "Sezona je završila prije ${NUMBER} dana.", + "seasonEndsDaysText": "Sezona završava za ${NUMBER} dana.", + "seasonEndsHoursText": "Sezona završava za ${NUMBER} sati.", + "seasonEndsMinutesText": "Sezona završava za ${NUMBER} minuta.", + "seasonText": "Sezona ${NUMBER}", + "tournamentLeagueText": "Moraš se plasirati u ${NAME} ligu da možeš sudjelovati u ovom turniru.", + "trophyCountsResetText": "Broj trofeja će se poništiti iduće sezone." + }, + "levelBestScoresText": "Najbolji skor na ${LEVEL}", + "levelBestTimesText": "Najbolje vrijeme na ${LEVEL}", + "levelFastestTimesText": "Najbrže vrijeme na ${LEVEL}", + "levelHighestScoresText": "Najbolji rezultati na ${LEVEL}", + "levelIsLockedText": "Razina ${LEVEL} je zaključana.", + "levelMustBeCompletedFirstText": "Prvo moraš završiti razinu ${LEVEL}.", + "levelText": "Nivo ${NUMBER}", + "levelUnlockedText": "Razina otključana!", + "livesBonusText": "Preostali život", + "loadingText": "učitavam", + "loadingTryAgainText": "Učitavanje; probajte kasnije...", + "macControllerSubsystemBothText": "Oba (nije preporučeno)", + "macControllerSubsystemClassicText": "klasika", + "macControllerSubsystemDescriptionText": "(probaj to promijeniti ako tvoji kontroleri ne rade)", + "macControllerSubsystemMFiNoteText": "Made-for-iOS/Mac kontroler detektiran;\nMožda bi ih htio aktivirati u Postavke -> Kontroleri", + "macControllerSubsystemMFiText": "Made-for-iOS/Mac", + "macControllerSubsystemTitleText": "Podržavanje kontrolera", + "mainMenu": { + "creditsText": "Zasluge", + "demoMenuText": "Demo izbornik", + "endGameText": "Kraj igre", + "exitGameText": "Izlaz iz igre", + "exitToMenuText": "Povratak u izbornik?", + "howToPlayText": "Kako igrati", + "justPlayerText": "(Samo ${NAME})", + "leaveGameText": "Napusti igru", + "leavePartyConfirmText": "Stvarno napuštaš partiju?", + "leavePartyText": "Napusti partiju", + "quitText": "Izlaz", + "resumeText": "Nastavi", + "settingsText": "Postavke" + }, + "makeItSoText": "Neka bude tako", + "mapSelectGetMoreMapsText": "Još mapa...", + "mapSelectText": "Odaberi...", + "mapSelectTitleText": "Mape za ${GAME}", + "mapText": "Mapa", + "maxConnectionsText": "Maksimalna konekcija", + "maxPartySizeText": "Maksimum veličine žurke", + "maxPlayersText": "Maksimum igrača", + "modeArcadeText": "Arkadni Mod", + "modeClassicText": "Klasični Mod", + "modeDemoText": "Demo Mod", + "mostValuablePlayerText": "Najbolji igrač", + "mostViolatedPlayerText": "Najveća žrtva", + "mostViolentPlayerText": "Najnasilniji igrač", + "moveText": "Pomicanje", + "multiKillText": "${COUNT}-STRUKO UBOJSTVO!!!", + "multiPlayerCountText": "${COUNT} igrača", + "mustInviteFriendsText": "Pažnja: moraš pozvati prijatelje u\n\"${GATHER}\" panelu ili priključiti\nkontrolere da možeš igrati s drugima.", + "nameBetrayedText": "${NAME} je izdao ${VICTIM}.", + "nameDiedText": "${NAME} je umro.", + "nameKilledText": "${NAME} je ubio ${VICTIM}.", + "nameNotEmptyText": "Ime ne može biti prazno!", + "nameScoresText": "${NAME} osvaja bod!", + "nameSuicideKidFriendlyText": "${NAME} je slučajno umro.", + "nameSuicideText": "${NAME} je počinio samoubojstvo.", + "nameText": "Ime", + "nativeText": "Standardno", + "newPersonalBestText": "Novi osobni najbolji rezultat!", + "newTestBuildAvailableText": "", + "newText": "Novo", + "newVersionAvailableText": "Novija verzija ${APP_NAME} je dostupna! (${VERSION})", + "nextAchievementsText": "Sledeće dostignuće:", + "nextLevelText": "Iduća razina", + "noAchievementsRemainingText": "- nijedno", + "noContinuesText": "(bez nastavaka)", + "noExternalStorageErrorText": "Vanjska pohrana nije pronađena", + "noGameCircleText": "Greška: nisi prijavljen u GameCircle", + "noProfilesErrorText": "Nemaš profila igrača, pa ti je samo ime '${NAME}' na raspolaganju. \nPođi pod Postavke->Profili igrača da sebi napraviš profil. ", + "noScoresYetText": "Još nema rezultata.", + "noThanksText": "Ne hvala", + "noTournamentsInTestBuildText": "UPOZORENJE: Turnirski bodovi od ove test gradnje će biti ignorirani.", + "noValidMapsErrorText": "Nijedna ispravna mapa nije pronađena za ovu igru.", + "notEnoughPlayersRemainingText": "Nije ostalo dovoljno igrača; iziđi i započni novu igru.", + "notEnoughPlayersText": "Trebaš najmanje ${COUNT} igrača da započneš ovu igru!", + "notNowText": "Ne sad", + "notSignedInErrorText": "Moraš se prijaviti da uradiš ovo.", + "notSignedInGooglePlayErrorText": "Moraš se ulogovati preko Google pleja da uradiš ovo.", + "notSignedInText": "nisi prijavljen", + "nothingIsSelectedErrorText": "Ništa nije odabrano!", + "numberText": "#${NUMBER}", + "offText": "Isključeno", + "okText": "U redu", + "onText": "Uključeno", + "oneMomentText": "Jedan trenutak...", + "onslaughtRespawnText": "${PLAYER} će se ponovno pojaviti u naletu ${WAVE}", + "orText": "${A} ili ${B}", + "otherText": "Drugo...", + "outOfText": "(#${RANK} od ${ALL})", + "ownFlagAtYourBaseWarning": "Tvoja zastava mora biti\nu tvojoj bazi da bi mogao osvojiti bod!", + "packageModsEnabledErrorText": "Mrežna igra nije dozvoljena dok su modovi iz lokalne pohrane uključeni(pogledaj pod Postavke->Napredno)", + "partyWindow": { + "chatMessageText": "Poruka", + "emptyText": "Nitko se nije priključio tvojoj partiji", + "hostText": "(domaćin)", + "sendText": "Pošalji", + "titleText": "Tvoja partija" + }, + "pausedByHostText": "(pauzirao domaćin)", + "perfectWaveText": "Savršen nalet!", + "pickUpText": "Podigni", + "playModes": { + "coopText": "Timski mod", + "freeForAllText": "Svatko protiv svakoga", + "multiTeamText": "Više ekipa", + "singlePlayerCoopText": "Solo/timski mod", + "teamsText": "Ekipe" + }, + "playText": "Igraj", + "playWindow": { + "oneToFourPlayersText": "1-4 igrača", + "titleText": "Igraj", + "twoToEightPlayersText": "2-8 igrača" + }, + "playerCountAbbreviatedText": "${COUNT} igrač(a)", + "playerDelayedJoinText": "${PLAYER} će se pojaviti na početku sledeće igre.", + "playerInfoText": "Igracova informacija", + "playerLeftText": "${PLAYER} je napustio igru.", + "playerLimitReachedText": "Maksimalan broj igrača je ${COUNT}; nitko se više ne može uključiti.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Ne možeš izbrisati tvoj korisnički račun.", + "deleteButtonText": "Izbriši\nProfil", + "deleteConfirmText": "Izbriši '${PROFILE}'?", + "editButtonText": "Uredi\nProfil", + "explanationText": "(stvori vaša imena i izglede za igrače na ovom uređaju)", + "newButtonText": "Novi\nProfil", + "titleText": "Profili igrača" + }, + "playerText": "Igrač", + "playlistNoValidGamesErrorText": "Ova lista igara ne sadrži nijednu valjanu otključanu igru.", + "playlistNotFoundText": "lista igara nije pronađena", + "playlistText": "Playlista", + "playlistsText": "Liste igara", + "pleaseRateText": "Ako ti se sviđa ${APP_NAME}, molim te razmisli o tome\nda ga ocijeniš ili napišeš recenziju.\nOvako šalješ korisnu povratnu informaciju koja pomaže u daljnjem razvoju.\n\nHvala!\n-eric", + "pleaseWaitText": "Molimo sačekajte...", + "pluginClassLoadErrorText": "Pogreška učitavanja dodatka klase '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Pogreška iniciranja dodatka '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Novi dodatak(ci) detektiran(i) Resetiraj da ih ukljućiš ili ih konfiguriraj u postavkima", + "pluginsRemovedText": "${NUM} dodatak/ci više nisu pronađeni.", + "pluginsText": "Dodatci", + "practiceText": "Vježba", + "pressAnyButtonPlayAgainText": "Pritisni bilo koju tipku za ponovnu igru...", + "pressAnyButtonText": "Pritisni bilo koju tipku za nastavak...", + "pressAnyButtonToJoinText": "pritisni bilo koju tipku da se uključiš...", + "pressAnyKeyButtonPlayAgainText": "Pritisni bilo koju kontrolu/tipku za ponovnu igru...", + "pressAnyKeyButtonText": "Pritisni bilo koju kontrolu/tipku za nastavak...", + "pressAnyKeyText": "Pritisni bilo koju kontrolu...", + "pressJumpToFlyText": "**Pritišći skok konstantno za let**", + "pressPunchToJoinText": "pritisni UDARAC da se uključiš...", + "pressToOverrideCharacterText": "pritisni ${BUTTONS} da promijeniš svog lika", + "pressToSelectProfileText": "pritisni ${BUTTONS} da izabereš svog igrača", + "pressToSelectTeamText": "pritisni ${BUTTONS} da izabereš svoju ekipu", + "promoCodeWindow": { + "codeText": "Kod", + "codeTextDescription": "Promotivni kod", + "enterText": "Unesi" + }, + "promoSubmitErrorText": "Greška u korištenju koda; provjerite internetsku vezu", + "ps3ControllersWindow": { + "macInstructionsText": "Isključi tvoj PS3 na njegovoj stražnjoj strani, provjeri da je\nBluetooth uključen na tvom Macu, pa onda priključi kontroler\nna tvom Macu USB kabelom da ih upariš. Nakon toga, možeš\nkoristiti home tipku kontrolera da ga priključiš sa svojim Macom\nu žičnom (USB) ili bežičnom (Bluetooth) modu.\n\nNa nekim Macovima mogli bi te zatražiti loziku prilikom uparivanja.\nAko se ovo dogodi, pogledaj sljedeće upute ili guglaj za pomoć.\n\n\n\n\nPS3 kontroleri koje priključiš bežično trebali bi se pokazati u\nuređaja pod System Preferences->Bluetooth. Možda ćeš ih trebati\nukloniti s te liste kad ih želiš ponovno koristiti s tvojim PS3.\n\nIsto tako provjeri da ih isključiš s Bluetooth kad ih\nne koristiš ili će se njihove baterije nastaviti prazniti.\n\nBluetooth bi trebao podržavati do 7 povezanih uređaja,\nmada bi tvoja daljina mogla varirati.", + "ouyaInstructionsText": "Za korištenje PS3 kontrolera s OUYA-om, jednostavno ga priključi USB kabelom\njednom da ga upariš. Ovo bi moglo isključiti ostale kontrolere, pa\nbi trebao ponovno pokrenuti OUYA-u i isključiti USB kabel.\n\nNakon toga bi trebao moći koristiti HOME tipku na kontroleru da\nga priključiš bežično. Kad si završio s igrom, drži HOME tipku na kontroleru\n10 sekundi da isključiš kontroler; u protivnom bi mogao ostati uključen\ni baterija bi mu se mogla istrošiti.", + "pairingTutorialText": "video s uputama za uparivanje", + "titleText": "Korištenje PS3 kontrolera s ${APP_NAME}:" + }, + "punchBoldText": "UDARAC", + "punchText": "Udarac", + "purchaseForText": "Kupi za ${PRICE}", + "purchaseGameText": "Kupi igru", + "purchasingText": "Kupujem...", + "quitGameText": "izađi iz ${APP_NAME}?", + "quittingIn5SecondsText": "Izlazim za 5 sekundi...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Nasumično", + "rankText": "Pozicija", + "ratingText": "Ocjena", + "reachWave2Text": "Đođi do drugog naleta da se nađeš na ljestvici.", + "readyText": "spreman", + "recentText": "Nedavno", + "remoteAppInfoShortText": "${APP_NAME} najviše je zabavan kada se igra s obitelji i prijateljima.\nPovežite jedan ili više hardverskih kontrolera ili instalirajte\n${REMOTE_APP_NAME} aplikaciju na mobitele i tablete da ih koristite \nkao kontrolere.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Pozicija gumba", + "button_size": "Veličina gumba", + "cant_resolve_host": "Ne mogu pronaći hosta.", + "capturing": "Snimanje", + "connected": "Povezano.", + "description": "Koristi svoj mobitel ili tablet kao kontroler sa BombSquadom.\nDo 8 uređaja se može povezati od jednom za epsko ludilo za lokalno više igrača na TV-u ili tabletu.", + "disconnected": "Veza prekinuta od servera.", + "dpad_fixed": "zaljepljeno", + "dpad_floating": "lebdeće", + "dpad_position": "Pozicija D-Pada", + "dpad_size": "Veličina D-Pada", + "dpad_type": "Tip D-Pada", + "enter_an_address": "Ubaci Andresu", + "game_full": "Igra ima najviše mogućih igraća ili ne prihvaća veze.", + "game_shut_down": "Igra se ugasila.", + "hardware_buttons": "Gumbi hardvera", + "join_by_address": "Uključi se adresom...", + "lag": "Zaostaje: ${SECONDS} sekundi", + "reset": "Resetirano na standardno", + "run1": "Trči 1", + "run2": "Trči 2", + "searching": "Traženje BombSquad igri...", + "searching_caption": "Klikni na ime igre da joj se pridružiš.\nPobrinite se da ste na istoj wifi mreži kao i igra.", + "start": "Počni", + "version_mismatch": "Nejednake verzije.\nProvjerite da BombSquad i BombSquad Remote\nbudu ažurirani i pokušajte ponovo." + }, + "removeInGameAdsText": "Otključaj \"${PRO}\" u dućanu da ukloniš oglase.", + "renameText": "Preimenuj", + "replayEndText": "Kraj snimke", + "replayNameDefaultText": "Snimka zadnje igre", + "replayReadErrorText": "Greška u čitanju datoteke snimke.", + "replayRenameWarningText": "Preimenuj \"${REPLAY}\" poslije igre ako je želiš sačuvati; u protivnom će biti presnimljena.", + "replayVersionErrorText": "Žao mi je, ova snimka je napravljena u drugoj \nverziji igre i ne može se koristiti.", + "replayWatchText": "Gledaj snimku", + "replayWriteErrorText": "Greška u brisanju snimke.", + "replaysText": "Snimke", + "reportPlayerExplanationText": "Preko ovog emaila mi javite varanje, neprikladan jezik ili drugo loše ponašanje.\nMolim vas opišite ispod:", + "reportThisPlayerCheatingText": "Varanje", + "reportThisPlayerLanguageText": "Neprikladan jezik", + "reportThisPlayerReasonText": "Šta bi želeo da prijaviš?", + "reportThisPlayerText": "Reportaj ovog igraca", + "requestingText": "Zatražujem...", + "restartText": "Počni ponovno", + "retryText": "Pokušaj ponovno", + "revertText": "Poništi", + "runText": "Trk", + "saveText": "Spremi", + "scanScriptsErrorText": "Greška(e) skeniranja skripra; provjerite dnevnik za detalje.", + "scoreChallengesText": "Izazovi za rezultat", + "scoreListUnavailableText": "Lista s rezultatima nedostupna.", + "scoreText": "Rezultat", + "scoreUnits": { + "millisecondsText": "Milisekundi", + "pointsText": "Bodova", + "secondsText": "Sekundi" + }, + "scoreWasText": "(bio je ${COUNT})", + "selectText": "Odaberi", + "seriesWinLine1PlayerText": "POBJEĐUJE", + "seriesWinLine1TeamText": "POBJEĐUJU", + "seriesWinLine1Text": "POBJEĐUJE", + "seriesWinLine2Text": "U SERIJI!", + "settingsWindow": { + "accountText": "Račun", + "advancedText": "Napredno", + "audioText": "Zvuk", + "controllersText": "Kontroleri", + "graphicsText": "Grafika", + "playerProfilesMovedText": "Napomena: Profili igrača su pomaknuti na sekciju Račun u meniju.", + "playerProfilesText": "Profili Igrača", + "titleText": "Postavke" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(jednostavna tipkovnica za uređivanje teksta laka za upravljanje kontrolerom)", + "alwaysUseInternalKeyboardText": "Uvijek koristi ugrađenu tipkovnicu", + "benchmarksText": "Testovi učinka i testovi opterećenja", + "disableCameraGyroscopeMotionText": "Onesposobi Žiroskopski Pokret Kamere", + "disableCameraShakeText": "Onesposobi Potres Kamere", + "disableThisNotice": "(možeš isključiti ovu obavijest u naprednim postavkama)", + "enablePackageModsDescriptionText": "(omogućava dodatne modding mogućnosti ali onemogućava mrežnu igru)", + "enablePackageModsText": "Omogući modove iz lokalne pohrane", + "enterPromoCodeText": "Unesi kod", + "forTestingText": "Pažnja: ove vrijednosti su samo za testiranje i bit će izgubljene kad iziđete iz aplikacije.", + "helpTranslateText": "Prijevodi ${APP_NAME} na druge jezike su trud\nzajednice. Ako bi želio doprinijeti ili ispraviti\nprijevod, slijedi poveznicu ispod. Hvala unaprijed!", + "kickIdlePlayersText": "Izbaci neaktivne igrače", + "kidFriendlyModeText": "Mod za djecu (smanjeno nasilje, itd.)", + "languageText": "Jezik", + "moddingGuideText": "Vodič za modding", + "mustRestartText": "Moraš ponovno pokrenuti igru da ovo stupi na snagu.", + "netTestingText": "Testiranje mreže", + "resetText": "Poništi", + "showBombTrajectoriesText": "Pokaži putanju bombe", + "showPlayerNamesText": "Pokaži imena igrača", + "showUserModsText": "Pokaži mapu za modove", + "titleText": "Napredno", + "translationEditorButtonText": "Uredi prijevode ${APP_NAME}", + "translationFetchErrorText": "status prijevoda nedostupan", + "translationFetchingStatusText": "provjeravam status prijevoda...", + "translationInformMe": "Obavijesti me kad moj jezik treba ažurirat", + "translationNoUpdateNeededText": "trenutni jezik je ažuran; juuhuu!", + "translationUpdateNeededText": "** trenutni jezik treba ažurirati!! **", + "vrTestingText": "VR testiranje" + }, + "shareText": "Podeli", + "sharingText": "Deljenje...", + "showText": "Pokaži", + "signInForPromoCodeText": "Moraš se prijaviti na račun da bi kodovi utjecali.", + "signInWithGameCenterText": "Da upotrijebiš Game Center račun,\nprijavi se u Game Center aplikaciji.", + "singleGamePlaylistNameText": "Samo ${GAME}", + "singlePlayerCountText": "1 igrač", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Odabir lika", + "Chosen One": "Odabrani", + "Epic": "Igre u epskom modu", + "Epic Race": "Epska utrka", + "FlagCatcher": "Otmi zastavu", + "Flying": "Sretne misli", + "Football": "Američki nogomet", + "ForwardMarch": "Juriš", + "GrandRomp": "Osvajači", + "Hockey": "Hokej", + "Keep Away": "Drži se podalje", + "Marching": "Obrana", + "Menu": "Glavni izbornik", + "Onslaught": "Invazija", + "Race": "Utrka", + "Scary": "Čuvar zastave", + "Scores": "Ekran s rezultatima", + "Survival": "Eliminacija", + "ToTheDeath": "Bitka do smrti", + "Victory": "Ekran sa završnim rezultatima" + }, + "spaceKeyText": "razmaknica", + "statsText": "Statistika", + "storagePermissionAccessText": "Ovo treba pristup datotekama", + "store": { + "alreadyOwnText": "Već imaš ${NAME}!", + "bombSquadProDescriptionText": "Udvostručuje kupone zarađene u igri\n\nUklanja oglase\n\nUključuje ${COUNT} dodatnih kupona\n\n+${PERCENT}% više bodova za poziciju u ligi\n\nOtključava ${INF_ONSLAUGHT}\ni ${INF_RUNAROUND} razine u timskom modu", + "bombSquadProFeaturesText": "Značajke: ", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Uklanja reklame u igri i nag zaslona\n• Otključava više postavki u igri\n• Također uključuje:", + "buyText": "Kupi", + "charactersText": "Likovi", + "comingSoonText": "Ubrzo...", + "extrasText": "Extra", + "freeBombSquadProText": "BombSquad je sada besplatan, ali budući da si ga kupio prije toga\nprimaš BombSquad Pro nadogradnju i ${COUNT} kupona kao zahvalu. \nUživaj u novim značajkama, i hvala ti na podršci! \n-Eric", + "gameUpgradesText": "Nadogradnje igre", + "holidaySpecialText": "Blagdanski specijal", + "howToSwitchCharactersText": "(idi pod \" ${SETTINGS} -> ${PLAYER_PROFILES}\" da dodijeliš i prilagodiš likove)", + "howToUseIconsText": "(napravi globalni profil igrača (u sekciji račun) da ih koristiš)", + "howToUseMapsText": "(koristi te mape u tvojim ekipnim/svatko protiv svakoga listama igara)", + "iconsText": "Ikoni", + "loadErrorText": "Nemoguće je učitati stranicu. \nProvjeri svoju internetsku vezu.", + "loadingText": "učitavam", + "mapsText": "Mape", + "miniGamesText": "Igre", + "oneTimeOnlyText": "(samo jednom)", + "purchaseAlreadyInProgressText": "Kupovina ovog artikla je već u tijeku.", + "purchaseConfirmText": "Kupi ${ITEM}?", + "purchaseNotValidError": "Kupovina nije valjana. \nKontaktiraj ${EMAIL} ako je ovo greška.", + "purchaseText": "Kupi", + "saleBundleText": "Rasprodaja paketa!", + "saleExclaimText": "Popust!", + "salePercentText": "(${PERCENT}% popusta)", + "saleText": "POPUST", + "searchText": "Traži", + "teamsFreeForAllGamesText": "Ekipe / Svatko protiv svakoga igre", + "totalWorthText": "*** Vrijednost ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Ažuriraj?", + "winterSpecialText": "Zimski specijal", + "youOwnThisText": "- ovo već imaš -" + }, + "storeDescriptionText": "Ludilo za 8 igrača!\n\nRaznesi svoje prijatelje (ili računalo) u turniru eksplozivnih igara kao Otmi zastavu, Hokej i Epska bitka do smrti u usporenom filmu!\n\nSvima je lako uskočiti u akciju uz jednostavne kontrole i podršku za vanjske kontrolere; čak možeš koristiti tvoje mobilne uređaje kao kontrolere putem besplatne 'BombSquad Remote' aplikacije!\n\nPazi, bomba!\n\nZa više informacija, posjeti www.froemling.net/bombsquad.", + "storeDescriptions": { + "blowUpYourFriendsText": "Digni u zrak tvoje prijatelje.", + "competeInMiniGamesText": "Natječi se u igrama od utrkivanja do letenja.", + "customize2Text": "Prilagodi likove, igre, pa čak i glazbu.", + "customizeText": "Prilagodi likove i stvori tvoje vlastite liste igara.", + "sportsMoreFunText": "Sportovi su zabavniji s eksplozivima.", + "teamUpAgainstComputerText": "Udružite se protiv kompjutera." + }, + "storeText": "Trgovina", + "submitText": "Podnesi", + "submittingPromoCodeText": "Podnošenje koda...", + "teamNamesColorText": "Imena/Boja ekipa...", + "telnetAccessGrantedText": "Telnet pristup dozvoljen.", + "telnetAccessText": "Telnet pristup otkriven; dozvoli?", + "testBuildErrorText": "Ova testna vezija više nije aktivna; molim instaliraj novu.", + "testBuildText": "Testna verzija", + "testBuildValidateErrorText": "Nemoguće je potvrditi testnu verziju. (nema internetske veze?)", + "testBuildValidatedText": "Testna verzija potvrđena; uživaj!", + "thankYouText": "Hvala ti na podršci! Uživaj u igri!!", + "threeKillText": "TROSTRUKO UBOJSTVO!!!", + "timeBonusText": "Vremenski bonus", + "timeElapsedText": "Vremena prošlo.", + "timeExpiredText": "Vrijeme isteklo", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Savjet", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Prijatelji s najboljim rezultatima", + "tournamentCheckingStateText": "Provjeravam stanje turnira; molim pričekaj...", + "tournamentEndedText": "Ovaj turnir je završio. Novi će započeti ubrzo.", + "tournamentEntryText": "Kotizacija", + "tournamentResultsRecentText": "Nedavni Rezultati turnira", + "tournamentStandingsText": "Poredak", + "tournamentText": "Turnir", + "tournamentTimeExpiredText": "Vrijeme turnira je isteklo", + "tournamentsText": "Turniri", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "B-9000", + "Bernard": "Medo Brundo", + "Bones": "Bones", + "Butch": "Butch", + "Easter Bunny": "Uskršnji Zeko", + "Flopsy": "Flopsy", + "Frosty": "Mrzli", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Srećko", + "Mel": "Mel", + "Middle-Man": "Sredina-Man", + "Minimus": "Minimus", + "Pascal": "Paskal", + "Pixel": "Piksel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Djed Mraz", + "Snake Shadow": "Snake Shadow", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao Maskota", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} (Trening)", + "Infinite ${GAME}": "${GAME} (Beskonačno)", + "Infinite Onslaught": "Beskonačna invazija", + "Infinite Runaround": "Beskonačna obrana", + "Onslaught Training": "Invazija (Trening)", + "Pro ${GAME}": "${GAME} (Pro)", + "Pro Football": "Američki nogomet (Pro)", + "Pro Onslaught": "Invazija (Pro)", + "Pro Runaround": "Obrana (Pro)", + "Rookie ${GAME}": "${GAME} (Početnik)", + "Rookie Football": "Američki nogomet (Početnik)", + "Rookie Onslaught": "Invazija (Početnik)", + "The Last Stand": "Posljednja bitka", + "Uber ${GAME}": "${GAME} (Uber)", + "Uber Football": "Američki nogomet (Uber)", + "Uber Onslaught": "Invazija (Uber)", + "Uber Runaround": "Obrana (Uber)" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Budi odabrani u određenom vremenskom periodu da pobijediš. \nUbij odabranog da postaneš odabran.", + "Bomb as many targets as you can.": "Pogodi što više meta.", + "Carry the flag for ${ARG1} seconds.": "Nosi zastavu ${ARG1} sekundi.", + "Carry the flag for a set length of time.": "Nosi zastavu u određenom vremenskom periodu.", + "Crush ${ARG1} of your enemies.": "Ubij ${ARG1} neprijatelja.", + "Defeat all enemies.": "Pobijedi sve neprijatelje.", + "Dodge the falling bombs.": "Izbjegavaj bombe koje padaju.", + "Final glorious epic slow motion battle to the death.": "Završna slavna epska bitka do smrti u usporenom filmu.", + "Gather eggs!": "Skupi jaja!", + "Get the flag to the enemy end zone.": "Odnesi zastavu do krajnje neprijateljske zone.", + "How fast can you defeat the ninjas?": "Koliko brzo možeš pobijediti nindže?", + "Kill a set number of enemies to win.": "Ubij određeni broj neprijatelja da pobijediš.", + "Last one standing wins.": "Posljednji preživjeli pobjeđuje.", + "Last remaining alive wins.": "Posljednji preživjeli pobjeđuje.", + "Last team standing wins.": "Posljednji preživjeli tim pobjeđuje.", + "Prevent enemies from reaching the exit.": "Spriječi neprijatelje da dođu do izlaza.", + "Reach the enemy flag to score.": "Dođi do neprijateljske zastave da osvojiš bod.", + "Return the enemy flag to score.": "Otmi neprijateljsku zastavu i donesi je u svoju bazu da osvojiš bod.", + "Run ${ARG1} laps.": "Pretrči zadani broj krugova. (${ARG1})", + "Run ${ARG1} laps. Your entire team has to finish.": "Pretrči zadani broj krugova (${ARG1}). Cijela tvoja ekipa mora završiti.", + "Run 1 lap.": "Pretrči 1 krug.", + "Run 1 lap. Your entire team has to finish.": "Pretrči 1 krug. Cijela tvoja ekipa mora završiti.", + "Run real fast!": "Trči stvarno brzo!", + "Score ${ARG1} goals.": "Zabij zadani broj golova. (${ARG1})", + "Score ${ARG1} touchdowns.": "Zabij zadani broj golova. (${ARG1})", + "Score a goal.": "Zabij gol.", + "Score a touchdown.": "Zabij gol.", + "Score some goals.": "Zabij nekoliko golova.", + "Secure all ${ARG1} flags.": "Osiguraj sve ${ARG1} zastave.", + "Secure all flags on the map to win.": "Osiguraj sve zastave na mapi da podijediš.", + "Secure the flag for ${ARG1} seconds.": "Osiguraj zastavu ${ARG1} sekundi.", + "Secure the flag for a set length of time.": "Osiguraj zastavu u određenom vremenskom periodu.", + "Steal the enemy flag ${ARG1} times.": "Otmi neprijateljsku zastavu ${ARG1} puta.", + "Steal the enemy flag.": "Otmi neprijateljsku zastavu.", + "There can be only one.": "Na tronu može biti samo jedan.", + "Touch the enemy flag ${ARG1} times.": "Dotakni neprijateljsku zastavu zadani broj puta. (${ARG1})", + "Touch the enemy flag.": "Dotakni neprijateljsku zastavu.", + "carry the flag for ${ARG1} seconds": "nosi zastavu ${ARG1} sekundi", + "kill ${ARG1} enemies": "ubij ${ARG1} neprijatelja", + "last one standing wins": "posljednji preživjeli pobjeđuje", + "last team standing wins": "posljednji preživjeli tim pobjeđuje", + "return ${ARG1} flags": "otmi zadani broj zastava (${ARG1})", + "return 1 flag": "otmi 1 zastavu", + "run ${ARG1} laps": "pretrči zadani broj krugova (${ARG1})", + "run 1 lap": "pretrči 1 krug", + "score ${ARG1} goals": "zabij zadani broj golova (${ARG1})", + "score ${ARG1} touchdowns": "zabij zadani broj golova (${ARG1})", + "score a goal": "zabij gol", + "score a touchdown": "zabij gol", + "secure all ${ARG1} flags": "osiguraj sve ${ARG1} zastave", + "secure the flag for ${ARG1} seconds": "osiguraj zastavu ${ARG1} sekundi", + "touch ${ARG1} flags": "dotakni zadani broj zastava (${ARG1})", + "touch 1 flag": "dotakni 1 zastavu" + }, + "gameNames": { + "Assault": "Juriš", + "Capture the Flag": "Otmi zastavu", + "Chosen One": "Odabrani", + "Conquest": "Osvajači", + "Death Match": "Bitka do smrti", + "Easter Egg Hunt": "Lov na Uskršnja Jaja", + "Elimination": "Eliminacija", + "Football": "Američki nogomet", + "Hockey": "Hokej", + "Keep Away": "Drži se podalje", + "King of the Hill": "Čuvar zastave", + "Meteor Shower": "Kiša meteora", + "Ninja Fight": "Borba s nindžama", + "Onslaught": "Invazija", + "Race": "Utrka", + "Runaround": "Obrana", + "Target Practice": "Vježba gađanja", + "The Last Stand": "Posljednja bitka" + }, + "inputDeviceNames": { + "Keyboard": "Tipkovnica", + "Keyboard P2": "Tipkovnica P2" + }, + "languages": { + "Arabic": "Arapski", + "Belarussian": "Bjeloruski", + "Chinese": "Pojednostavljeni Kineski", + "ChineseTraditional": "Tradicionalni Kineski", + "Croatian": "Hrvatski", + "Czech": "Češki", + "Danish": "Danski", + "Dutch": "Nizozemski", + "English": "Engleski", + "Esperanto": "Esperanto", + "Filipino": "Filipinski", + "Finnish": "Finski", + "French": "Francuski", + "German": "Njemački", + "Gibberish": "Frfljanje", + "Greek": "Grčki", + "Hindi": "Hindski", + "Hungarian": "Mađarski", + "Indonesian": "Indonezijski", + "Italian": "Talijanski", + "Japanese": "Japanski", + "Korean": "Korejski", + "Persian": "Perzijski", + "Polish": "Poljski", + "Portuguese": "Portugalski", + "Romanian": "Rumunjski", + "Russian": "Ruski", + "Serbian": "Srpski", + "Slovak": "Slovački", + "Spanish": "Španjolski", + "Swedish": "Švedski", + "Tamil": "Tamil", + "Thai": "tajlandski", + "Turkish": "Turski", + "Ukrainian": "Ukrajinski", + "Venetian": "Venecijanski", + "Vietnamese": "Vijetnamski" + }, + "leagueNames": { + "Bronze": "Brončana", + "Diamond": "Dijamantna", + "Gold": "Zlatna", + "Silver": "Srebrna" + }, + "mapsNames": { + "Big G": "Veliki G", + "Bridgit": "Bridgit", + "Courtyard": "Dvorište", + "Crag Castle": "Crag Castle", + "Doom Shroom": "Gljiva smrti", + "Football Stadium": "Nogometni stadion", + "Happy Thoughts": "Vesele misli", + "Hockey Stadium": "Stadion za hokej", + "Lake Frigid": "Jezero Frigid", + "Monkey Face": "Majmunovo lice", + "Rampage": "Rampage", + "Roundabout": "Roundabout", + "Step Right Up": "Step Right Up", + "The Pad": "The Pad", + "Tip Top": "Tip Top", + "Tower D": "Toranj D", + "Zigzag": "Cik-cak" + }, + "playlistNames": { + "Just Epic": "Samo epske", + "Just Sports": "Samo sportovi" + }, + "scoreNames": { + "Flags": "Zastave", + "Goals": "Golovi", + "Score": "Rezultat", + "Survived": "Preživio", + "Time": "Vrijeme", + "Time Held": "Vrijeme držanja" + }, + "serverResponses": { + "A code has already been used on this account.": "Ovaj kod je vec koriscen na ovom akauntu", + "A reward has already been given for that address.": "Nagrada je već dobivena na ovoj adresi.", + "Account linking successful!": "Povezivanje računa uspješno!", + "Account unlinking successful!": "Odspajanje računa uspješno!", + "Accounts are already linked.": "Računi su već povezani.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Prikaz oglasa se nije mogao provjeriti.\nMolim vas budite sigurni da koristite službenu i suvremenu verziju ove igre", + "An error has occurred; (${ERROR})": "Greška se pojavila; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Greška se pojavila; molimo vas pozovite pomoć. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Greška se pojavila; molim vas pozovite support@froemling.net.", + "An error has occurred; please try again later.": "Greška se pojavila, molim vas pokušajte kasnije.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Jeste li sigurni da želite spojiti ove račune?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nTo se ne može zaustaviti!", + "BombSquad Pro unlocked!": "BombSquad Pro otključan!", + "Can't link 2 accounts of this type.": "Nije moguće spojiti 2 računa tog tipa.", + "Can't link 2 diamond league accounts.": "Nije moguće spojiti 2 računa dijamantne lige.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Nije moguće spojiti; prešlo bi maksimum od ${COUNT} spojenih računa.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Varanje detektirano; rekordi i nagrade suspendirani na ${COUNT} dana.", + "Could not establish a secure connection.": "Ne moguće uspostaviti sigurnu vezu.", + "Daily maximum reached.": "Dnevni maksimu predzen", + "Entering tournament...": "Ulazim u turnir...", + "Invalid code.": "Nevažeći kod.", + "Invalid payment; purchase canceled.": "Neispravno plaćanje; kupovina prekinuta.", + "Invalid promo code.": "Neispravan promotivni kod.", + "Invalid purchase.": "Greška u kupnji.", + "Invalid tournament entry; score will be ignored.": "Nevaljan ulazak u turnir; rekord će se ignorirati.", + "Item unlocked!": "Otključao si stvar!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "SPAJANJE ZAUSTAVLJENO. ${ACCOUNT} sadržava\nznačajne podatke koje bi ste SVE NJIH IZGUBILI.\nMožete se povezati drugim redosljedom ako hoćete\n(i izgubiti sve informacije OVOG računa)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Spoji račun ${ACCOUNT} na ovaj račun?\nSve postojeće informacije o ${ACCOUNT} će biti izgubljene.\nTo se ne može zaustaviti. Jesi li siguran?", + "Max number of playlists reached.": "Max broj dosegao popise pjesama.", + "Max number of profiles reached.": "Max broj dosegao profila.", + "Maximum friend code rewards reached.": "Maksimalne nagrade od prijateljskih kodova dostignute.", + "Message is too long.": "Poruka je prevelika.", + "No servers are available. Please try again soon.": "Nema dostupnih servera. Pokušajte opet kasnije.", + "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" uspjesno upgrajdovan", + "Profile could not be upgraded.": "Profil se ne može ažurirati.", + "Purchase successful!": "Kupovina uspješna!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Primio si ${COUNT} kupona za prijavu. \nPonovno se prijavi sutra da dobiješ ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Funkcija poslužitelja više nije podržana u ovoj verziji igre;\nAžurirajte na noviju verziju.", + "Sorry, there are no uses remaining on this code.": "Izvini, ovaj kod se vise nemoze koristit.", + "Sorry, this code has already been used.": "Izvini, ovaj kod je već iskorišćen.", + "Sorry, this code has expired.": "Izvini, ovaj kod je istekao.", + "Sorry, this code only works for new accounts.": "Izvini, ovaj kod radi samo za nove igrače.", + "Still searching for nearby servers; please try again soon.": "Još pretražuješ za bliske servere; pokušajte opet kasnije", + "Temporarily unavailable; please try again later.": "Privremeno nedostupno; molimo vas pokušajte kasnije.", + "The tournament ended before you finished.": "Turnir je šio prije nego što si ti završio.", + "This account cannot be unlinked for ${NUM} days.": "Ovaj se račun ne može odvezati ${NUM} dana.", + "This code cannot be used on the account that created it.": "Ovaj kod se nemoze koristiti na akauntu koji je stvorio.", + "This is currently unavailable; please try again later.": "Ovo je trenutačno nedostupno; pokušajte opet kasnije.", + "This requires version ${VERSION} or newer.": "Ovo zahtijeva verziju ${VERSION} ili noviju.", + "Tournaments disabled due to rooted device.": "Turniri nedostupni zbog rootanog uređaja.", + "Tournaments require ${VERSION} or newer": "Turniri koriste ${VERSION} ili noviju", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Odveži ${ACCOUNT} s ovog računa?\nSve informacije sa ${ACCOUNT} će se resetirati.\n(osim postignuća u nekim slučajima)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "UPOZORENJE: pritužbe hakiranja izdane su na vaš račun.\nRačuni koji su pronađeni hakirajući će biti zabranjeni za korištenje. Igrajte pošteno.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Da li bi ste htjeli spojiti račun uređaja na ovaj?\n\nRačun uređaja je ${ACCOUNT1}\nOvaj račun je ${ACCOUNT2}\n\nOvo će dozvoliti da nastaviš gdje si stao.\nUpozorenje: ovo se ne može poništiti!", + "You already own this!": "Ovo već imaš!", + "You can join in ${COUNT} seconds.": "Možeš se pridružiti za ${COUNT} sekundi.", + "You don't have enough tickets for this!": "Nemaš dovoljno kupona za ovo!", + "You don't own that.": "Ne poseduješ to.", + "You got ${COUNT} tickets!": "Dobio si ${COUNT} kupona!", + "You got a ${ITEM}!": "Dobio si ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Prešao si u novu ligu; čestitke!", + "You must update to a newer version of the app to do this.": "Moraš ažurirati ovu aplikaciju na noviju verziju da uradiš ovo.", + "You must update to the newest version of the game to do this.": "Morate ažurirati igru na najnoviju verziju da biste ovo mogli.", + "You must wait a few seconds before entering a new code.": "Moraš pričekati nekoliko sekundi prije unošenja novog koda.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Zauzeo si #${RANK} mjesto u zadnjem turniru. Hvala na sudjelovanju!", + "Your account was rejected. Are you signed in?": "Vaš je račun odbijen. Jeste li prijavljeni?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Tvoja kopija igre je izmijenjena. \nMolim poništi sve promjene i pokušaj ponovno.", + "Your friend code was used by ${ACCOUNT}": "Tvoj kod druga je iskorišćen od strane ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minuta", + "1 Second": "1 Sekunda", + "10 Minutes": "10 Minuta", + "2 Minutes": "2 Minute", + "2 Seconds": "2 Sekunde", + "20 Minutes": "20 Minuta", + "4 Seconds": "4 Sekunde", + "5 Minutes": "5 Minuta", + "8 Seconds": "8 Sekundi", + "Allow Negative Scores": "Dozvoli Negativne Rezultate", + "Balance Total Lives": "Balansiraj ukupne živote", + "Bomb Spawning": "Bomba Nastaje", + "Chosen One Gets Gloves": "Odabrani dobija rukavice", + "Chosen One Gets Shield": "Odabrani dobija štit", + "Chosen One Time": "Vrijeme koje moraš biti Odabrani", + "Enable Impact Bombs": "Uključi kontakt-bombe", + "Enable Triple Bombs": "Uključi trostruke bombe", + "Entire Team Must Finish": "Ceo Tim Mora Završiti", + "Epic Mode": "Epski mod", + "Flag Idle Return Time": "Vrijeme povratka zastave dok je u mirovanju", + "Flag Touch Return Time": "Vrijeme povratka zastave nakon dodira", + "Hold Time": "Vrijeme držanja", + "Kills to Win Per Player": "Ubojstava za pobjedu po igraču", + "Laps": "Krugovi", + "Lives Per Player": "Života po igraču", + "Long": "Dugo", + "Longer": "Duže", + "Mine Spawning": "Stvaranje mina", + "No Mines": "Nema mina", + "None": "Ništa", + "Normal": "Normalno", + "Pro Mode": "Pro mod", + "Respawn Times": "Vrijeme oživljavanja", + "Score to Win": "Bodova za pobjedu", + "Short": "Kratko", + "Shorter": "Kraće", + "Solo Mode": "Solo mod", + "Target Count": "Broj meta", + "Time Limit": "Vremensko ograničenje" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} je diskvalifikovan zbog ${PLAYER} izasao", + "Killing ${NAME} for skipping part of the track!": "Ubijam ${NAME} zbog preskakanja dijela trake!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Upozorenje za ${NAME}: turbo / neprekidno pritiskanje tipki vas izbaci." + }, + "teamNames": { + "Bad Guys": "Loši dečki", + "Blue": "Plavi", + "Good Guys": "Dobri dečki", + "Red": "Crveni" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Pravovremeni trčeći-skačući-vrteći udarac može ubiti odjednom\ni zaraditi ti doživotno poštovanje tvojih prijatelja.", + "Always remember to floss.": "Uvijek očisti zube koncem.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Stvori profile igrača za sebe i svoje prijatelje s\ntebi dražim imenima i izgledima umjesto nasumičnih.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Kletva te pretvori u otkucavajuću tempiranu bombu. \nJedini lijek je da brzo zgrabiš prvu pomoć.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Unatoč njihovim izgledima, mogućnosti svih likova su iste, \npa samo izaberi onoga kojemu si najsličniji.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Nemoj se previše uobraziti s energetskim štitom; još te uvijek mogu baciti s litice.", + "Don't run all the time. Really. You will fall off cliffs.": "Nemoj trčati cijelo vrijeme. Stvarno. Past ćeš s litice.", + "Don't spin for too long; you'll become dizzy and fall.": "Nemoj se vrteti mnogo dugo; dobićeš vrtoglavicu i pasti.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Drži bilo koju tipku za trk. (Okidačke tipke isto rade ako ih imaš)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Drži bilo koju tipku za trk. Bit ćeš brži, \nali ne možeš dobro skretati, pa pazi na zavoje i litice.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ledene bombe nisu jako moćne, ali zamrzavaju\nsvakoga koga udare, ostavljajući ih lomljivima.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Ako te netko uhvati, udari ga i pustit će te. \nOvo radi i u stvarnom životu.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Ako nemate kontrolere, intalirajte\n'${REMOTE_APP_NAME}` app na vašem telefonu da bi ste ih koristili kao kontrolere.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Ako ti nedostaje kontrolera, instaliraj 'BombSquad Remote' aplikaciju\nna tvoje iOS i Android uređaje da ih možeš koristiti kao kontrolere. ", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Ako se ljepljiva bomba zalijepi na tebe, skači okolo i vrti se u krugovima. Mogao bi\notresti bombu sa sebe, a ako ne uspiješ bar će tvoji zadnji trenutci biti zabavni.", + "If you kill an enemy in one hit you get double points for it.": "Ako ubiješ neprijatelja u jednom udarcu, za to dobiješ duple bodove.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Ako pokupiš kletvu, jedina nada da da preživiš je da\npronađeš prvu pomoć u idućih par sekundi.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Ako stojiš na jednom mjestu, gotov si. Trči i izbjegavaj neprijatelje da preživiš..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Ako imaš puno igrača koji dolaze i odlaze, uključi 'automatski izbaci neaktivne igrače' \nu postavkama u slučaju da netko zaboravi napustiti igru.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Ako se tvoj uređaj previše ugrije ili bi htio sačuvati bateriju, \nsmanji \"Vizualno\" ili \"Rezolucija\" u Postavke->Grafika", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Ako je tvoj FPS nizak, pokušaj smanjiti rezoluciju\nili vizualna u grafičkim postavkama igre.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "U igri Otmi zastavu, tvoja vlastita zastava mora biti u tvojoj bazi da bi mogao osvojiti bod, \npa ako je druga ekipa blizu osvajanja boda, ukradi njihovu zastavu da ih zaustaviš.", + "In hockey, you'll maintain more speed if you turn gradually.": "U hokeju, dobit ćeš više brzine ako se okrećeš postepeno.", + "It's easier to win with a friend or two helping.": "Lakše je pobijediti ako ti pomaže jedan ili dva prijatelja.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Skači dok bacaš bombe da ih baciš na najviše razine.", + "Land-mines are a good way to stop speedy enemies.": "Mine su dobar način da zaustaviš brze neprijatelje.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Puno stvari možeš podignuti i baciti, uključujući ostale igrače. Bacanje \ntvojih neprijatelja s litice može biti učinkovita i emocionalno zadovoljavajuća strategija.", + "No, you can't get up on the ledge. You have to throw bombs.": "Ne, ne možeš se popeti gore. Moraš bacati bombe.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Igrači mogu ući u i napustiti većinu igara dok su u tijeku, \na isto tako možeš uključiti i isključiti kontrolere.", + "Practice using your momentum to throw bombs more accurately.": "Vježbaj koristeći zalet da bacaš bombe preciznije.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Udarci nanose više štete što se brže kreću tvoje šake, \npa pokušaj trčati, skakati i vrtjeti se kao lud.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Trči naprijed-nazad prije nego što\nbaciš bombu da je baciš dalje.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Ubij grupu neprijatelja\nbacajući bombu blizu TNT-a.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Glava je najosjetljivije područje, pa ljepljiva bomba\nu glavu obično znači kraj igre.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Ova razina nikad ne završava, ali najbolji rezultat ovdje\nzaradit će ti vječno poštovanje kroz cijeli svijet.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Jačina izbačaja temelji se na pravcu kojeg držiš. \nDa baciš nešto nježno ispred sebe, nemoj držati niti jedan pravac.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Dosadila ti je glazbena lista? Zamijeni je s vlastitom! \nPogledaj pod Postavke->Zvuk->Glazbena lista", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Pokušaj pričekati sekundu ili dvije prije bacanja bombe da fitilj malo izgori.", + "Try tricking enemies into killing eachother or running off cliffs.": "Pokuša prevariti neprijatelje tako da ubiju jedan drugoga ili padnu s litice.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Koristi 'podigni' tipku da uhvatiš zastavu < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Trči naprijed-nazad da bacaš dalje..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Možeš 'naciljati' tvoje udarce vrteći se lijevo ili desno. \nOvo je korisno za odbacivanje neprijatelja s ruba ili zabijanje golova u hokeju.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Možeš prosuditi kad će bomba eksplodirati na temelju boje \niskri s fitilja: žuta.. narančasta.. crvena.. BUM.", + "You can throw bombs higher if you jump just before throwing.": "Možeš bacati bombe više ako skočiš malo prije nego što baciš.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Trpiš štetu kad udariš glavom o nešto, \npa pokušaj ne udarati glavom o nešto.", + "Your punches do much more damage if you are running or spinning.": "Tvoji udarci nanose više štete ako trčiš ili se vrtiš." + } + }, + "trophiesRequiredText": "Za ovo je potrebno minimum ${NUMBER} trofeja.", + "trophiesText": "Trofeja", + "trophiesThisSeasonText": "Trofeji ove sezone", + "tutorial": { + "cpuBenchmarkText": "Vrtim upute na ludo-smiješnoj brzini (prvenstveno testira brzinu procesora)", + "phrase01Text": "Pozdrav!", + "phrase02Text": "Dobrodošao u ${APP_NAME}!", + "phrase03Text": "Evo nekoliko savjeta za kontroliranje tvog lika:", + "phrase04Text": "Puno stvari u ${APP_NAME}-u je temeljeno na FIZICI.", + "phrase05Text": "Na primjer, kad udaraš,..", + "phrase06Text": "..šteta koju ćeš nanijeti temelji se na brzini tvojih šaka.", + "phrase07Text": "Vidiš? Nismo se micali, pa je to jedva ozlijedilo ${NAME}a.", + "phrase08Text": "Sad ćemo skočiti i vrtjeti se da postignemo veću brzinu.", + "phrase09Text": "Ah, to je bolje.", + "phrase10Text": "Trčanje također pomaže.", + "phrase11Text": "Pritisni i drži pritisnutom BILO KOJU tipku da potrčiš.", + "phrase12Text": "Trči i okreći se za ekstra-fenomenalne udarce.", + "phrase13Text": "Uuups, oprosti zbog toga ${NAME}.", + "phrase14Text": "Možeš podići i baciti stvari kao što su zastave... ili ${NAME}.", + "phrase15Text": "Naposljetku, bombe.", + "phrase16Text": "Za precizno bacanje bombi treba vježbe.", + "phrase17Text": "Au! Ovo nije bilo baš dobro bacanje.", + "phrase18Text": "Kretanje ti pomaže da bacaš dalje.", + "phrase19Text": "Skakanje ti pomaže da bacaš više.", + "phrase20Text": "Zavrti se dok bacaš bombe da bacaš još više.", + "phrase21Text": "Tempiranje tvojih bombi može biti teško.", + "phrase22Text": "K vrapcu.", + "phrase23Text": "Pokušaj pričekati sekundu ili dvije da fitilj malo izgori.", + "phrase24Text": "Hura! Lijepo izgoreno.", + "phrase25Text": "Pa, to je više-manje sve.", + "phrase26Text": "Sad ih uhvati, tigre!", + "phrase27Text": "Sjeti se treninga, i VRATIT ćeš se živ!", + "phrase28Text": "... pa, valjda...", + "phrase29Text": "Sretno!", + "randomName1Text": "Fred", + "randomName2Text": "Harry", + "randomName3Text": "Bill", + "randomName4Text": "Chuck", + "randomName5Text": "Phil", + "skipConfirmText": "Stvarno ćeš preskočiti upute? Pritisni da potvrdiš.", + "skipVoteCountText": "${COUNT}/${TOTAL} glasova za preskakanje", + "skippingText": "preskačem upute...", + "toSkipPressAnythingText": "(pritisni bilo što da preskočiš upute)" + }, + "twoKillText": "DVOSTRUKO UBOJSTVO!", + "unavailableText": "nedostupno", + "unconfiguredControllerDetectedText": "Nepodešen kontroler otkriven:", + "unlockThisInTheStoreText": "Ovo moraš otključati u dućanu.", + "unlockThisProfilesText": "Da napraviš više od ${NUM} profila, treba ti:", + "unlockThisText": "Da oslobodite ovo, trebate", + "unsupportedHardwareText": "Žao mi je, ova verzija igre ne podržava ovaj hardver.", + "upFirstText": "Prva igra:", + "upNextText": "Igra ${COUNT}:", + "updatingAccountText": "Ažuriram tvoj račun...", + "upgradeText": "Upgrajd", + "upgradeToPlayText": "Otključaj \"${PRO}\" u dućanu da možeš igrati ovo.", + "useDefaultText": "Koristi zadano", + "usesExternalControllerText": "Ova igra koristi vanjski kontroler za kretanje.", + "usingItunesText": "Koristim glazbenu aplikaciju za glazbenu listu...", + "usingItunesTurnRepeatAndShuffleOnText": "Molim provjeri da je opcija shuffle uključena, a opcija repeat postavljena na SVE na iTunes. ", + "validatingTestBuildText": "Potvrđujem testnu verziju...", + "victoryText": "Pobjeda!", + "voteDelayText": "Nemožeš započeti još jedno glasanje ${NUMBER} sekundi", + "voteInProgressText": "Glasanje je već u toku", + "votedAlreadyText": "Već si glasao", + "votesNeededText": "${NUMBER} glasova potrebno", + "vsText": "protiv", + "waitingForHostText": "(čekam na ${HOST} za nastavak)", + "waitingForPlayersText": "čekam na igrače da se priključe...", + "waitingInLineText": "Čekanje u redu (žurka je puna)...", + "watchAVideoText": "Pogledaj video", + "watchAnAdText": "Pogledaj oglas", + "watchWindow": { + "deleteConfirmText": "Izbriši \"${REPLAY}\"?", + "deleteReplayButtonText": "Izbriši\nsnimku", + "myReplaysText": "Moje snimke", + "noReplaySelectedErrorText": "Niti jedna snimka nije odabrana", + "playbackSpeedText": "Brzina reprodukcije: ${SPEED}", + "renameReplayButtonText": "Preimenuj \nsnimku", + "renameReplayText": "Novo ime snimke \"${REPLAY}\":", + "renameText": "Preimenuj", + "replayDeleteErrorText": "Greška u brisanju snimke.", + "replayNameText": "Ime snimke", + "replayRenameErrorAlreadyExistsText": "Snimka s tim imenom već postoji.", + "replayRenameErrorInvalidName": "Nemoguće preimenovati snimku; nevažeće ime.", + "replayRenameErrorText": "Greška u preimenovanju snimke.", + "sharedReplaysText": "Podijeljene snimke", + "titleText": "Gledaj", + "watchReplayButtonText": "Pogledaj\nsnimku" + }, + "waveText": "Nalet", + "wellSureText": "Sigurno!", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Tražim Wiimote-ove...", + "pressText": "Pritisni Wiimote tipke 1 i 2 istovremeno.", + "pressText2": "Na novijim Wiimote-ovima s ugrađenim Motion Plus-om, umjesto njih pritisni crvenu 'sync' tipku na poleđini." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "listenText": "Traži", + "macInstructionsText": "Provjeri da je tvoj Wii isključen, a Bluetooth uključen\nna tvome Macu, pa pritisni 'Traži'. Podrška za Wiimote-ove\nmože biti malo nestabilna, pa ćeš možda morati pokušati nekoliko puta\nprije nego što uspostaviš vezu.\n\nBluetooth bi trebao podržati do 7 povezanih uređaja,\nmada bi tvoja udaljenost mogla varirati.\n\nBombSquad podržava originalne Wiimote-ove, Nunchuk-ove,\ni Classic Controller.\nNoviji Wii Remote Plus sada radi,\nali ne s dodacima.", + "thanksText": "Hvala DarwiinRemote timu\nšto je ovo omogućio.", + "titleText": "Podešavanje Wiimote-ova" + }, + "winsPlayerText": "${NAME} pobjeđuje!", + "winsTeamText": "${NAME} pobjeđuju!", + "winsText": "${NAME} pobjeđuje!", + "workspaceSyncErrorText": "Pogreška sinkroniziranja ${WORKSPACE}. Pogledaj log za više detalja.", + "workspaceSyncReuseText": "Nemoguće sinkronizirati ${WORKSPACE}. Ponovno korištenje stare verzije", + "worldScoresUnavailableText": "Svjetski rezultati nedostupni.", + "worldsBestScoresText": "Najbolji svjetski rezultati", + "worldsBestTimesText": "Najbolja svjetska prolazna vremena", + "xbox360ControllersWindow": { + "getDriverText": "Nabavi driver", + "macInstructions2Text": "Da možeš koristiti kontrolere bežično, trebat ćeš i reciever koji\ndolazi u 'Xbox 360 Wireless Controller for Windows' paketu.\nJedan reciever omogućuje ti da povežeš do 4 kontrolera.\n\nVažno: recieveri trećih strana neće raditi s ovim driverom; \nprovjeri da na tvom recieveru piše 'Microsoft', a ne 'XBOX 360'.\nMicrosoft ih više ne prodaje odvojeno, pa ćeš morati nabaviti\njednoga u paketu s kontrolerom ili potraži na ebayu.\n\nAko ti je ovo bilo korisno, molim te razmisli o donaciji\nprogrameru drivera na njegovoj stranici.", + "macInstructionsText": "Da možeš koristiti Xbox 360 kontrolere, morat ćeš instalirati\nMac driver dostupan na poveznici ispod. \nRadi i sa žičnim i s bežičnim kontrolerima.", + "ouyaInstructionsText": "Za korištenje žičnih Xbox 360 kontrolera s BombSquadom, jednostavno\nih uključi u USB ulaz tvog uređaja. Možeš koristiti USB hub\nda priključiš više kontrolera.\n\nZa korištenje bežičnih kontrolera trebat ćeš bežični reciever, \nkoji je dostupan kao dio \"Xbox 360 wireless Controller for Windows\" \npaketa ili u slobodnoj prodaji. Svaki se reciever priključuje u USB ulaz i\nomogućuje ti da povežeš do 4 bežična kontrolera.", + "titleText": "Korišćenje Xbox 360 kontrolera sa $(APP_NAME)" + }, + "yesAllowText": "Da, dopusti!", + "yourBestScoresText": "Tvoji najbolji rezultati", + "yourBestTimesText": "Tvoja najbolja prolazna vremena" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/czech.json b/dist/ba_data/data/languages/czech.json new file mode 100644 index 0000000..f7cdb15 --- /dev/null +++ b/dist/ba_data/data/languages/czech.json @@ -0,0 +1,1903 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Jména účtů nemůžou obsahovat smajlíky ani jiné speciální znaky", + "accountProfileText": "(Aktuální profil)", + "accountsText": "Účty", + "achievementProgressText": "Achievementy: ${COUNT}/${TOTAL}", + "campaignProgressText": "Postup Kampaně [Těžká]: ${PROGRESS}", + "changeOncePerSeason": "Lze změnit pouze jednou za sezónu.", + "changeOncePerSeasonError": "Chcete-li toto změnit znovu, musíte počkat na další sezónu (${NUM} days)", + "customName": "Vlastní Jméno", + "googlePlayGamesAccountSwitchText": "Pokud chcete použít jiný Google účet,\npoužijte pro změnu aplikaci Google Play Hry.", + "linkAccountsEnterCodeText": "Vložit kód", + "linkAccountsGenerateCodeText": "Generovat kód", + "linkAccountsInfoText": "(sdílení postupu mezi různými zařízeními)", + "linkAccountsInstructionsNewText": "Pro spojení dvou účtů na jednom z nich\ngenerujte kód a na druhém tento kód zadejte. Data z \ndruhého účtu se pak budou s prvním sdílet\n(Data z prvního účtu budou smazána.)\n\nMůžete spojit až ${COUNT} účtů.\n\nDŮLEŽITÉ: Spojujte jen účty které vlastníte, \nnikoliv s přáteli. Pokud tak učiníte, nebudete\nmoci hrát ve stejný čas!", + "linkAccountsInstructionsText": "Pokud chcete propojit účty, na jednom z nich generujte kód\na na druhém tento kód zadejte.\nPostup a inventář bude zkombinován.\nMůžete propojit až ${COUNT} účtů.\n\nDŮLEŽITÉ: PROPOJUJTE POUZE ÚČTY KTERÉ JSOU VAŠE!\nPOKUD PROPOJÍTE ÚČTY S KAMARÁDEM, NEBUDETE MOCI\nHRÁT OBA VE STEJNÝ ČAS!\n\nDobře si to rozmyslete; Tuto akci nelze vrátit zpět!", + "linkAccountsText": "Propojit účty", + "linkedAccountsText": "Propojené účty:", + "manageAccountText": "Spravovat Účet", + "nameChangeConfirm": "Přejete si změnit jméno účtu na ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Jste si jistí, že to chcete udělat?\nTímto NENÁVRATNĚ resetujete veškerý postup Co-op\na lokální nejlepší výsledky (ale kupóny vám zůstanou).", + "resetProgressConfirmText": "Jste si jistí, že to chcete udělat?\nTímto NENÁVRATNĚ resetujete veškerý postup Co-Op,\nachievementy a lokální nejlepší výsledky.\n(ale kupóny vám zůstanou)", + "resetProgressText": "Resetovat Postup", + "setAccountName": "Nastavit jméno účtu", + "setAccountNameDesc": "Vyberte si jméno pro váš účet.\nMůžete použít jedno ze svých již\npoužitých nebo si vytvořit nové.", + "signInInfoText": "Přihlašte se, abyste mohli sbírat kupóny, soupeřit online,\na sdílet postup mezi zařízeními.", + "signInText": "Přihlásit", + "signInWithDeviceInfoText": "(automaticky vytvořený účet dostupný pouze na tomto zařízení)", + "signInWithDeviceText": "Přihlásit se s účtem zařízení", + "signInWithGameCircleText": "Přihlásit se s ,,Game circle\"", + "signInWithGooglePlayText": "Přihlásit se přes Google Play", + "signInWithTestAccountInfoText": "(zastaralý typ účtu; použije raději účet zařízení)", + "signInWithTestAccountText": "Přihlásit se s testovacím účtem", + "signInWithV2InfoText": "(účet který funguje na všech platformách)", + "signInWithV2Text": "Přihlášení s BombSquad účtem", + "signOutText": "Odhlásit se", + "signingInText": "Přihlašuji se...", + "signingOutText": "Odhlašuji se...", + "testAccountWarningCardboardText": "Varování: Přihlašujete se s \"testovacím\" účtem.\nTyto účty budou nahrazeny Google účty hned,\njakmile budou podporovány cardboard aplikacemi.\n\nProzatím si všechny kupony budete muset získat ve hře\n(avšak získáte Pro účet zdarma na vyzkoušení).", + "testAccountWarningOculusText": "Varování: Přihlašujete se pod \"testovacím\" účtem.\nTyto účty budou později v tomto roce nahrazeny Oculus účty,\nkteré nabídnou nákupy kupónů a ostatní vylepšení.\n\nProzatím musíte všechny kupóny získat ve hře\n(avšak získáte BombSquad Pro upgrade zdarma na vyzkoušení).", + "testAccountWarningText": "Upozornění: jste přihlášení k \"test\" účtu. \nTento účet je vázán na toto konkrétní zařízení a \nmůže dojít k pravidelnému resetování. (takže není důvod utrácet \nspoustu času k získávání a odemykání věci) \n\nPoužíváním klasické verze této hry je možné používat \"skutečný\" \núčet (Game-Center, Google Plus, atd.), \nkterý umožňuje ukládat svůj postup v cloudu \na sdílet tento postup mezi různými zařízeními.", + "ticketsText": "Kupóny: ${COUNT}", + "titleText": "Profil", + "unlinkAccountsInstructionsText": "Zvolte účet k odpojení", + "unlinkAccountsText": "Odpojit účty", + "unlinkLegacyV1AccountsText": "na rozdíl od starších účtů (V1).", + "v2LinkInstructionsText": "Použijte tento odkaz pro vytvoření účtu nebo přihlášení.", + "viaAccount": "(přes účet ${NAME})", + "youAreLoggedInAsText": "Jste přihlášen jako:", + "youAreSignedInAsText": "Jste přihlášen jako:" + }, + "achievementChallengesText": "Ocenění Výzev", + "achievementText": "Úspěch", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Zabijte 3 padouchy pomocí TNT", + "descriptionComplete": "Zabili jste 3 padouchy pomocí TNT", + "descriptionFull": "Zabijte 3 padouchy pomocí TNT v ${LEVEL}", + "descriptionFullComplete": "Zabili jste 3 padouchy pomocí TNT v ${LEVEL}", + "name": "Dynamit dělá Bum" + }, + "Boxer": { + "description": "Vyhrajte bez použití bomb", + "descriptionComplete": "Vyhráli jste bez použití bomb", + "descriptionFull": "Dokončete ${LEVEL} bez použití bomb.", + "descriptionFullComplete": "Dokončili jste ${LEVEL} bez použití bomb.", + "name": "Boxer" + }, + "Dual Wielding": { + "descriptionFull": "Připojte alespoň 2 ovladače (Hardware nebo aplikaci)", + "descriptionFullComplete": "Připojeno alespoň 2 ovladače (hardware/aplikaci)", + "name": "Ovladačový maniak" + }, + "Flawless Victory": { + "description": "Vyhrajte aniž byste byly zasaženi", + "descriptionComplete": "Vyhráli jste aniž byste byly zasaženi", + "descriptionFull": "Vyhrajte ${LEVEL} aniž byste byli zasaženi", + "descriptionFullComplete": "Vyhráli jste ${LEVEL} aniž byste byli zasaženi", + "name": "Bezvadná Výhra" + }, + "Free Loader": { + "descriptionFull": "Začněte hru ,,všichni proti všem\" s alespoň 2 hráči", + "descriptionFullComplete": "Začali jste ,,všichni proti všem\" hru s více jak 2 hráči", + "name": "Všichni proti všem!!!" + }, + "Gold Miner": { + "description": "Zabijte 6 padouchů pomocí min", + "descriptionComplete": "Zabili jste 6 padouchů pomocí min", + "descriptionFull": "Zabijte 6 padouchů pomocí min v ${LEVEL}", + "descriptionFullComplete": "Zabili jste 6 padouchů pomocí min v ${LEVEL}", + "name": "Zlatokop" + }, + "Got the Moves": { + "description": "Vyhrajte bez použití pěstí a bomb", + "descriptionComplete": "Vyhráli jste bez použití pěstí a bomb", + "descriptionFull": "Vyhrajte ${LEVEL} bez mlácení nebo bomb", + "descriptionFullComplete": "Vyhráli jste ${LEVEL} bez mlácení nebo bomb", + "name": "Naučit se kroky" + }, + "In Control": { + "descriptionFull": "Připojte ovladač (hardware/aplikaci)", + "descriptionFullComplete": "Připojen ovladač (hardware/aplikaci)", + "name": "Ve spojení" + }, + "Last Stand God": { + "description": "Získejte 1000 bodů", + "descriptionComplete": "Získáno 1000 bodů", + "descriptionFull": "Získejte 1000 bodů v ${LEVEL}", + "descriptionFullComplete": "Získáno 1000 bodů v ${LEVEL}", + "name": "${LEVEL} Bůh" + }, + "Last Stand Master": { + "description": "Získejte 250 bodů", + "descriptionComplete": "Získáno 250 bodů", + "descriptionFull": "Získejte 250 bodů v ${LEVEL}", + "descriptionFullComplete": "Získáno 250 bodů v ${LEVEL}", + "name": "${LEVEL} Profík" + }, + "Last Stand Wizard": { + "description": "Získajte 500 bodů", + "descriptionComplete": "Získáno 500 bodů", + "descriptionFull": "Získejte 500 bodů v ${LEVEL}", + "descriptionFullComplete": "Získáno 500 bodů v ${LEVEL}", + "name": "${LEVEL} Kouzelník" + }, + "Mine Games": { + "description": "Zabij 3 padouchy pomocí min", + "descriptionComplete": "Zabili jste 3 padouchy pomocí min", + "descriptionFull": "Zabij 3 padouchy pomocí min v ${LEVEL}", + "descriptionFullComplete": "Zabili jste 3 padouchy pomocí min v ${LEVEL}", + "name": "Minové hry" + }, + "Off You Go Then": { + "description": "Vyhoď 3 padouchy pryč z mapy", + "descriptionComplete": "Vyhodili jste 3 padouchy pryč z mapy", + "descriptionFull": "Vyhoďte 3 padouchy pryč z mapy v ${LEVEL}", + "descriptionFullComplete": "Vyhodili jste 3 padouchy pryč z mapy v ${LEVEL}", + "name": "Je čas, aby jsi odešel" + }, + "Onslaught God": { + "description": "Získejte 5000 bodů", + "descriptionComplete": "Získáno 5000 bodů", + "descriptionFull": "Získejte 5000 bodů v ${LEVEL}", + "descriptionFullComplete": "Získáno 5000 bodů v ${LEVEL}", + "name": "${LEVEL} Bůh" + }, + "Onslaught Master": { + "description": "Získejte 500 bodů", + "descriptionComplete": "Získáno 500 bodů", + "descriptionFull": "Získejte 500 bodů v ${LEVEL}", + "descriptionFullComplete": "Získáno 500 bodů v ${LEVEL}", + "name": "${LEVEL} Profík" + }, + "Onslaught Training Victory": { + "description": "Dokončete všechny vlny", + "descriptionComplete": "Dokončeny všechny vlny", + "descriptionFull": "Dokončete všechny vlny v ${LEVEL}", + "descriptionFullComplete": "Dokončeny všechny vlny v ${LEVEL}", + "name": "${LEVEL} Vítězství" + }, + "Onslaught Wizard": { + "description": "Získejte 1000 bodů", + "descriptionComplete": "Získáno 5000 bodů", + "descriptionFull": "Získejte 1000 bodů v ${LEVEL}", + "descriptionFullComplete": "Získáno 1000 bodů v ${LEVEL}", + "name": "${LEVEL} Kouzelník" + }, + "Precision Bombing": { + "description": "Vyhrajte bez bonusů", + "descriptionComplete": "Vyhráli jste bez bonusů", + "descriptionFull": "Vyhrajte ${LEVEL} bez bonusů", + "descriptionFullComplete": "Vyhráli jste ${LEVEL} bez bonusů", + "name": "Přesné odpálení" + }, + "Pro Boxer": { + "description": "Vyhrajte bez bomb", + "descriptionComplete": "Vyhráli jste bez bomb", + "descriptionFull": "Dokončete ${LEVEL} bez bomb", + "descriptionFullComplete": "Dokončen ${LEVEL} bez bomb", + "name": "Profi Boxer" + }, + "Pro Football Shutout": { + "description": "Vyhrajte aniž by padouši skórovali", + "descriptionComplete": "Vyhráli jste aniž by padouši skórovali", + "descriptionFull": "Vyhrajte ${LEVEL} aniž by padouši skórovali", + "descriptionFullComplete": "Vyhráli jste ${LEVEL} aniž by padouši skórovali", + "name": "${LEVEL} Bezchybná výhra" + }, + "Pro Football Victory": { + "description": "Vyhrajte hru", + "descriptionComplete": "Vyhráli jste hru", + "descriptionFull": "Vyhrajte hru v ${LEVEL}", + "descriptionFullComplete": "Vyhráli jste hru v ${LEVEL}", + "name": "${LEVEL} Vítězství" + }, + "Pro Onslaught Victory": { + "description": "Porazte všechny vlny", + "descriptionComplete": "Všechny vlny poraženy", + "descriptionFull": "Porazte všechny vlny v ${LEVEL}", + "descriptionFullComplete": "Porazili jste všechny vlny v ${LEVEL}", + "name": "${LEVEL} Vítězství" + }, + "Pro Runaround Victory": { + "description": "Dokončete všechny vlny", + "descriptionComplete": "Dokončili jste všechny vlny", + "descriptionFull": "Dokončete všechny vlny v ${LEVEL}", + "descriptionFullComplete": "Dokončili jste všechny vlny v ${LEVEL}", + "name": "${LEVEL} Výhra" + }, + "Rookie Football Shutout": { + "description": "Vyhrajte aniž by padouši skórovali", + "descriptionComplete": "Vyhráli jste aniž by padouši skórovali", + "descriptionFull": "Vyhrajte ${LEVEL} aniž by padouši skórovali", + "descriptionFullComplete": "Vyhráli jste ${LEVEL} aniž by padouši skórovali", + "name": "${LEVEL} Bezchybná výhra" + }, + "Rookie Football Victory": { + "description": "Vyhrajte hru", + "descriptionComplete": "Vyhráli jste hru", + "descriptionFull": "Vyhrajte hru v ${LEVEL}", + "descriptionFullComplete": "Vyhráli jste hru v ${LEVEL}", + "name": "${LEVEL} Vítězství" + }, + "Rookie Onslaught Victory": { + "description": "Dokončete všechny vlny", + "descriptionComplete": "Dokončili jste všechny vlny", + "descriptionFull": "Dokončete všechny vlny v ${LEVEL}", + "descriptionFullComplete": "Dokončili jste všechny vlny v ${LEVEL}", + "name": "${LEVEL} Vítězství" + }, + "Runaround God": { + "description": "Získejte 2000 bodů", + "descriptionComplete": "Získáno 2000 bodů", + "descriptionFull": "Získejte 2000 bodů v ${LEVEL}", + "descriptionFullComplete": "Získáno 2000 bodů v ${LEVEL}", + "name": "${LEVEL} Bůh" + }, + "Runaround Master": { + "description": "Získejte 500 bodů", + "descriptionComplete": "Získáno 500 bodů", + "descriptionFull": "Získejte 500 bodů v ${LEVEL}", + "descriptionFullComplete": "Získáno 500 bodů v ${LEVEL}", + "name": "${LEVEL} Profík" + }, + "Runaround Wizard": { + "description": "Získejte 1000 bodů", + "descriptionComplete": "Získáno 1000 bodů", + "descriptionFull": "Získejte 1000 bodů v ${LEVEL}", + "descriptionFullComplete": "Získáno 1000 bodů v ${LEVEL}", + "name": "${LEVEL} Kouzelník" + }, + "Sharing is Caring": { + "descriptionFull": "Úspěšně sdílet hru s přítelem", + "descriptionFullComplete": "Úspěšně sdílena hra s přítelem", + "name": "Sdílení je laskavé" + }, + "Stayin' Alive": { + "description": "Vyhrajte bez smrti", + "descriptionComplete": "Vyhráli jste bez smrti", + "descriptionFull": "Vyhrajte ${LEVEL} bez smrti", + "descriptionFullComplete": "Vyhráli jste ${LEVEL} bez smrti", + "name": "Zůstaňte naživu" + }, + "Super Mega Punch": { + "description": "Způsobte 100% zranění jedním úderem", + "descriptionComplete": "Způsobili jste 100% zranění jedním úderem", + "descriptionFull": "Způsobte 100% zranění jedním úderem v ${LEVEL}", + "descriptionFullComplete": "Způsobili jste 100% zranění jedním úderem v ${LEVEL}", + "name": "Super Mega Úder" + }, + "Super Punch": { + "description": "Způsobte 50% zranění jedním úderem", + "descriptionComplete": "Způsobili jste 50% zranění jedním úderem", + "descriptionFull": "Způsobte 50% zranění jedním úderem v ${LEVEL}", + "descriptionFullComplete": "Způsobili jste 50% zranění jedním úderem v ${LEVEL}", + "name": "Super Úder" + }, + "TNT Terror": { + "description": "Zabijte 6 padouchů pomocí TNT", + "descriptionComplete": "Zabili jste 6 padouchů pomocí TNT", + "descriptionFull": "Zabijte 6 padouchů pomocí TNT v ${LEVEL}", + "descriptionFullComplete": "Zabili jste 6 padouchů pomocí TNT v ${LEVEL}", + "name": "TNT Terror" + }, + "Team Player": { + "descriptionFull": "Začněte týmovou hru s 4+ hráči", + "descriptionFullComplete": "Začali jste Týmovou hru s 4+ hráči", + "name": "Týmový hráč" + }, + "The Great Wall": { + "description": "Zastavte všechny padouchy", + "descriptionComplete": "Zastavili jste všechny padouchy", + "descriptionFull": "Zastavte všechny padouchy v ${LEVEL}", + "descriptionFullComplete": "Zastavili jste všechny padouchy v ${LEVEL}", + "name": "Velká zeď" + }, + "The Wall": { + "description": "Zastavte všechny padouchy", + "descriptionComplete": "Zastavili jste všechny padouchy", + "descriptionFull": "Zastavte všechny padouchy v ${LEVEL}", + "descriptionFullComplete": "Zastavili jste všechny padouchy v ${LEVEL}", + "name": "Zeď" + }, + "Uber Football Shutout": { + "description": "Vyhrajte bez toho, aby padouši skórovali", + "descriptionComplete": "Vyhráli jste bez toho, aby padouši skórovali", + "descriptionFull": "Vyhrajte ${LEVEL} bez toho, aby padouši skórovali", + "descriptionFullComplete": "Vyhráli jste ${LEVEL} bez toho, aby padouchové skórovali", + "name": "${LEVEL} Bezchybná výhra" + }, + "Uber Football Victory": { + "description": "Vyhrajte hru", + "descriptionComplete": "Vyhráli jste hru", + "descriptionFull": "Vyhrajte hru v ${LEVEL}", + "descriptionFullComplete": "Vyhráli jste hru v ${LEVEL}", + "name": "${LEVEL} Vítězství" + }, + "Uber Onslaught Victory": { + "description": "Poražte všechny vlny", + "descriptionComplete": "Porazili jste všechny vlny", + "descriptionFull": "Poražte všechny vlny v ${LEVEL}", + "descriptionFullComplete": "Porazili jste všechny vlny v ${LEVEL}", + "name": "${LEVEL} Vítězství" + }, + "Uber Runaround Victory": { + "description": "Dokončete všechny vlny", + "descriptionComplete": "Dokončili jste všechny vlny", + "descriptionFull": "Dokončete všechny vlny v ${LEVEL}", + "descriptionFullComplete": "Dokončili jste všechny vlny v ${LEVEL}", + "name": "${LEVEL} Vítězství" + } + }, + "achievementsRemainingText": "Achievementů Zbývá:", + "achievementsText": "Achievementy", + "achievementsUnavailableForOldSeasonsText": "Promiňte, ale detaily úspěchu nejsou pro starší sezóny zpřístupněny.", + "activatedText": "${THING} aktivováno.", + "addGameWindow": { + "getMoreGamesText": "Získat Více Her...", + "titleText": "Přidat Hru" + }, + "allowText": "Povolit", + "alreadySignedInText": "Tento účet je používán v jiném zařízení;\npřepněte účet nebo v druhém zařízení hru zavřete, \npoté to zkuste znova.", + "apiVersionErrorText": "Nelze načíst modul ${NAME}; je vytvořen pro verzi api ${VERSION_USED}; je potřeba ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" zapněte pouze když jsou připojeny sluchátka)", + "headRelativeVRAudioText": "Head-Relative VR Audio", + "musicVolumeText": "Hlasitost Hudby", + "soundVolumeText": "Hlasitost Zvuků", + "soundtrackButtonText": "Soundtracky", + "soundtrackDescriptionText": "(přiřaďte vaši vlastní hudbu, která bude hrát při hraní)", + "titleText": "Zvuky" + }, + "autoText": "Automaticky", + "backText": "Zpět", + "banThisPlayerText": "Znemožnit hráči přístup do hry", + "bestOfFinalText": "Nejlepší z ${COUNT} Finální", + "bestOfSeriesText": "Nejlepší z ${COUNT} sérií", + "bestRankText": "Váš nejlepší je #${RANK}", + "bestRatingText": "Vaše nejlepší hodnocení je ${RATING}", + "betaErrorText": "Tato beta-verze již není aktivní; prosím podívejte se na novější verze", + "betaValidateErrorText": "Nelze schválit data. (není připojení k internetu?)", + "betaValidatedText": "Beta Schválená; Bavte se!", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Zrychlit", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} je nastaven v aplikaci sám.", + "buttonText": "tlačitko", + "canWeDebugText": "Chtěli byste, aby BombSquad automaticky hlásil \nchyby a základní info o používání, vývojáři?\n\nTato data neobsahují žádné osobní informace a napomáhají,\naby hra běžela hladce a bez chyb.", + "cancelText": "Zrušit", + "cantConfigureDeviceText": "Omlouváme se, ale ${DEVICE} není nastavitelné", + "challengeEndedText": "Tato výzva již byla ukončena.", + "chatMuteText": "Ztlumit Chat", + "chatMutedText": "Chat ztlumen", + "chatUnMuteText": "Obnovit chat", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Musíte dokončit\ntento level abyste mohli pokračovat!", + "completionBonusText": "Bonus za dokončení", + "configControllersWindow": { + "configureControllersText": "Nastavit Ovladače", + "configureKeyboard2Text": "Nastavit Klávesnici P2", + "configureKeyboardText": "Nastavit Klávesnici", + "configureMobileText": "Mobilní Zařízení jako Ovladače", + "configureTouchText": "Nastavit Dotykovou obrazovku", + "ps3Text": "PS3 Ovladače", + "titleText": "Ovladače", + "wiimotesText": "Wiimote ovladače", + "xbox360Text": "Xbox 360 Ovladače" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Poznámka: podpora ovladače závisí na zařízení a verzi Androidu", + "pressAnyButtonText": "Stiskněte libovolné tlačítko na ovladači,\n který chcete nastavovat...", + "titleText": "Nastavit Ovladače" + }, + "configGamepadWindow": { + "advancedText": "Pokročilé", + "advancedTitleText": "Pokročilé Nastavení Ovladače", + "analogStickDeadZoneDescriptionText": "(zapněte tohle, jestliže Vaše postava 'klouže' po uvolnění páčky)", + "analogStickDeadZoneText": "Mrtvá Zóna Analogové Páčky", + "appliesToAllText": "(nastaví na všechny ovladače tohoto typu)", + "autoRecalibrateDescriptionText": "(zapněte to, jestliže se Vaše postava nepohybuje plnou rychlostí)", + "autoRecalibrateText": "Automaticky Rekalibrovat Analogovou Páčku", + "axisText": "osa", + "clearText": "smazat", + "dpadText": "dpad", + "extraStartButtonText": "Startovací tlačítko (navíc)", + "ifNothingHappensTryAnalogText": "Jestliže se nic neděje, zkuste místo toho přiřadit analogovou páčku.", + "ifNothingHappensTryDpadText": "Jestliže se nic neděje, zkuste místo toho přiřadit d-pad.", + "ignoreCompletelyDescriptionText": "(zabránit tomuto ovladači ovlivnit buď hru nebo nabídku)", + "ignoreCompletelyText": "Ignorovat úplně", + "ignoredButton1Text": "Ignorované Tlačítko 1", + "ignoredButton2Text": "Ignorované Tlačítko 2", + "ignoredButton3Text": "Ignorované Tlačítko 3", + "ignoredButton4Text": "Ignorováno tlačítko 4", + "ignoredButtonDescriptionText": "(použijte tohle pro zabránění tlačítkům 'home' nebo 'synchronizace' ovlivnění UI)", + "pressAnyAnalogTriggerText": "Stiskněte libovolný analogový spínač...", + "pressAnyButtonOrDpadText": "Stistkněte libovolné tlačítko nebo dpad...", + "pressAnyButtonText": "Stiskněte libovolné tlačítko...", + "pressLeftRightText": "Stistkněte doleva nebo doprava...", + "pressUpDownText": "Stiskněte nahoru nebo dolů...", + "runButton1Text": "Tlačítko Běh 1", + "runButton2Text": "Tlačítko Běh 2", + "runTrigger1Text": "Přepnutí Běhu 1", + "runTrigger2Text": "Přepnutí Běhu 2", + "runTriggerDescriptionText": "(analogové spínače Vám dovolí běhat v různých rychlostech)", + "secondHalfText": "Použijte tohle k nastavení druhé poloviny\n2 ovladačů v 1 zařízení, které se zobrazuje\njako jedno zařízení", + "secondaryEnableText": "Zapnout", + "secondaryText": "Druhý Ovladač", + "startButtonActivatesDefaultDescriptionText": "(vypněte, jestliže Vaše start tlačítko je spíše 'menu' tlačítko)", + "startButtonActivatesDefaultText": "Start Tlačítko Aktivuje Základní Widget", + "titleText": "Nastavení Ovladače", + "twoInOneSetupText": "2-v-1 Ovladač Nastavení", + "uiOnlyDescriptionText": "(zabránit ovladači k připojení do hry)", + "uiOnlyText": "Omezeno k použití menu", + "unassignedButtonsRunText": "Všechna Nenastavená Tlačítka Běh", + "unsetText": "", + "vrReorientButtonText": "Reorientovat VR tlačítko" + }, + "configKeyboardWindow": { + "configuringText": "Nastavuji ${DEVICE}", + "keyboard2NoteText": "Poznámka: většina klávesnic může registrovat jen pár stisklých\nkláves najednou, takže pro druhého hráče na klávesnici může být\nvýhodnější, když má druhou, vlastní klávesnici, kterou bude používat.\nOvšem,i v tomto případě, je stejně potřeba nastavit \nkaždému jiné klávesy." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Velikost Ovládacího Prvku", + "actionsText": "Ovládací Prvky", + "buttonsText": "tlačítka", + "dragControlsText": "< posouvejte ovládacími prvky pro změnu jejich pozice >", + "joystickText": "joystick", + "movementControlScaleText": "Velikost Ovládacího Prvku pro Pohyb", + "movementText": "Pohyb", + "resetText": "Resetovat", + "swipeControlsHiddenText": "Skrýt Přejížděcí Ikony", + "swipeInfoText": "Na 'Přejížděcí' styl ovládání se trochu déle zvyká, ale\nje s ním jednodužší hrát bez koukání se na tlačítka.", + "swipeText": "přejíždění", + "titleText": "Nastavit Dotykovou Obrazovku" + }, + "configureItNowText": "Nastavit teď?", + "configureText": "Nastavit", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Pro nejlepší výsledky budete potřebovat wifi síť bez lagů.\nLagy na wifi můžete snížit vypnutím některých bezdrátových zařízení,\nhraním blízko Vašeho routeru, a připojením hostitele hry přímo\ndo sítě přes ethernet.", + "explanationText": "Pro použití chytrého telefonu nebo tabletu jako bezdrátový ovladač,nainstalujte si aplikaci ${REMOTE_APP_NAME}.\nLibovolný počet zařízení může by připojeno do hry ${APP_NAME}\npřipojeno přes síť Wi-Fi , a je to zdarma !!", + "forAndroidText": "pro Android:", + "forIOSText": "pro iOS:", + "getItForText": "Získejte ${REMOTE_APP_NAME} pro I OS v App Store,\nnebo pro Android v Google play nebo v Amazon appstore", + "googlePlayText": "Google Play", + "titleText": "Použití Mobilních Zařízení jako Ovladačů" + }, + "continuePurchaseText": "Pokračovat za ${PRICE}?", + "continueText": "Pokračovat", + "controlsText": "Ovládání", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Nepočítá se do celkového žebříčku.", + "activenessInfoText": "Tento násobič se zvyšuje ve dnech kdy hrajete,\na snižuje ve dnech, kdy ne.", + "activityText": "Aktivita", + "campaignText": "Kampaň", + "challengesInfoText": "Vyhrajte ceny za dokončování mini-her.\n\nCeny a obtížnost úrovní se zvyšují vždy,\njakmile je výzva dokončena a snižují se vždy\njakmile výzva vyprší nebo je zahozena.", + "challengesText": "Výzvy", + "currentBestText": "Aktuální Nejepší", + "customText": "Speciální mapy", + "entryFeeText": "Vstupné", + "forfeitConfirmText": "Chcete zahodit tuto výzvu?", + "forfeitNotAllowedYetText": "Tato výzva ještě nemůže být zahozena.", + "forfeitText": "Zahodit", + "multipliersText": "Násobiče", + "nextChallengeText": "Další výzva", + "nextPlayText": "Další hra", + "ofTotalTimeText": "z ${TOTAL}", + "playNowText": "Hrát teď", + "pointsText": "Body", + "powerRankingFinishedSeasonUnrankedText": "(sezóna ukončena bez hodnocení)", + "powerRankingNotInTopText": "(nejste v top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER}bodů", + "powerRankingPointsMultText": "(x ${NUMBER})", + "powerRankingPointsText": "${NUMBER} bodů", + "powerRankingPointsToRankedText": "(${CURRENT} z ${REMAINING} bodů)", + "powerRankingText": "Hodnocení", + "prizesText": "Ceny", + "proMultInfoText": "Hráči s upgradem ${PRO}\nobdrží ${PERCENT}% bonus k bodům.", + "seeMoreText": "Zobrazit více...", + "skipWaitText": "Přeskočit čekání", + "timeRemainingText": "Zbývající Čas", + "toRankedText": "Pro hodnocení", + "totalText": "Celkem", + "tournamentInfoText": "Soutěžte s vysokým skóre\ns ostatními hráči ve Vaší lize.\n\nCeny jsou uělovány hráčům, kteří mají\nnejvíce bodů po ukončení turnaje.", + "welcome1Text": "Vítejte v ${LEAGUE}. Pozici v lize\nmůžete vylepšit pomocí hvězdných hodnocení,\nplněním achievementů a vyhráváním trofejí v turnajích.", + "welcome2Text": "Také můžete získávat kupóny z mnoha aktivit.\nMohou být použity pro odemykání nových postav, map,\nmini-her, pro vstup do turnajů, a dalších.", + "yourPowerRankingText": "Vaše pozice:" + }, + "copyConfirmText": "Zkopírováno do schránky.", + "copyOfText": "${NAME} Kopie", + "copyText": "Kopírovat", + "createEditPlayerText": "", + "createText": "Vytvořit", + "creditsWindow": { + "additionalAudioArtIdeasText": "Dodatečné Audio, První Artworky, a nápady od ${NAME}", + "additionalMusicFromText": "Dodatečná hudba od ${NAME}", + "allMyFamilyText": "Všem mým přátelům a rodině, kteří pomohli testovat hratelnost", + "codingGraphicsAudioText": "Kódování, Grafika, a Audio od ${NAME}", + "languageTranslationsText": "Překladatelé:", + "legalText": "Práva:", + "publicDomainMusicViaText": "Public-domain hudba přes ${NAME}", + "softwareBasedOnText": "Tento software je založen na části práce ${NAME}", + "songCreditText": "${TITLE} od ${PERFORMER}\nSložil ${COMPOSER}, Aranžér ${ARRANGER}, Publikoval ${PUBLISHER},\nS laskavým svolením ${SOURCE}", + "soundAndMusicText": "Zvuky & Hudba", + "soundsText": "Zvuky (${SOURCE}):", + "specialThanksText": "Zvláštní Poděkování:", + "thanksEspeciallyToText": "Děkuji zejména ${NAME}", + "titleText": "Tvůrci ${APP_NAME}", + "whoeverInventedCoffeeText": "Tomu, kdo vynalezl kávu" + }, + "currentStandingText": "Vaše momentální umístění je #${RANK}", + "customizeText": "Přizpůsobit...", + "deathsTallyText": "${COUNT} - počet smrtí", + "deathsText": "Smrti", + "debugText": "ladění", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Poznámka: je doporučené nastavit Nastavení->Grafika>Textury na \"Vysoká\" při tomto testování.", + "runCPUBenchmarkText": "Spustit CPU Benchmark", + "runGPUBenchmarkText": "Spustit GPU Benchmark", + "runMediaReloadBenchmarkText": "Spustit Media-Reload Benchmark", + "runStressTestText": "Spustit test výdrže", + "stressTestPlayerCountText": "Počet Hráčů", + "stressTestPlaylistDescriptionText": "Playlist Testu Výdrže", + "stressTestPlaylistNameText": "Název Playlistu", + "stressTestPlaylistTypeText": "Typ Playlistu", + "stressTestRoundDurationText": "Délka Trvání Kola", + "stressTestTitleText": "Test Výdrže", + "titleText": "Benchmarky & Testy Výdrže", + "totalReloadTimeText": "Celkový čas znovunačtení: ${TIME} (koukněte do logu pro detaily)" + }, + "defaultGameListNameText": "Výchozí ${PLAYMODE} Playlist", + "defaultNewGameListNameText": "Můj ${PLAYMODE} Playlist", + "deleteText": "Vymaž", + "demoText": "Demo", + "denyText": "Zakázat", + "deprecatedText": "Zastaralé", + "desktopResText": "Rozlišení Plochy", + "deviceAccountUpgradeText": "Varování:\nJste přihlášeni na účet dostupný pouze na tomto zařízení\n(${NAME}).\nTyto účty budou v příští aktualizaci odstraněny.", + "difficultyEasyText": "Lehká", + "difficultyHardOnlyText": "Pouze Těžký Mód", + "difficultyHardText": "Těžká", + "difficultyHardUnlockOnlyText": "Tento level může být odemčen pouze v těžkém módu.\nMyslíte si snad, že na to máte?", + "directBrowserToURLText": "Naveďte prosím svůj webový prohlížeč na následující adresu:", + "disableRemoteAppConnectionsText": "Zablokovat přístup Ovladačům-z-aplikace", + "disableXInputDescriptionText": "Povolí více než 4 ovladače ale nemusí fungovat dobře.", + "disableXInputText": "Vypnout XInput", + "doneText": "Hotovo", + "drawText": "Remíza", + "duplicateText": "Duplikovat", + "editGameListWindow": { + "addGameText": "Přidat\nHru", + "cantOverwriteDefaultText": "Nemohu přepsat výchozí playlist!", + "cantSaveAlreadyExistsText": "Playlist s tímto jménem už existuje!", + "cantSaveEmptyListText": "Nemohu uložit prázdný playlist!", + "editGameText": "Upravit\nHru", + "listNameText": "Název Playlistu", + "nameText": "Jméno", + "removeGameText": "Odstranit\nHru", + "saveText": "Uložit seznam", + "titleText": "Editor Playlistů" + }, + "editProfileWindow": { + "accountProfileInfoText": "Toto je speciální profil se jménem\na ikonou založenou na Vašem účtě.\n\n${ICONS}\n\nVytvořte si vlastní profily pro použití\nrůzných jmen či vlastních ikon.", + "accountProfileText": "(profil účtu)", + "availableText": "Jméno \"${NAME}\" je dostupné.", + "changesNotAffectText": "Poznámka: změny neovlivní postavy, které jsou již ve hře", + "characterText": "postava", + "checkingAvailabilityText": "Kontrola dostupnosti jména \"${NAME}\"...", + "colorText": "barva", + "getMoreCharactersText": "Získat Více Postav...", + "getMoreIconsText": "Získat Více Ikon...", + "globalProfileInfoText": "U globálních herních profilů je garantováno, že Vaše\njméno bude na celém světě unikátní. Včetně vlastních ikon.", + "globalProfileText": "(globální profil)", + "highlightText": "zvýraznění", + "iconText": "ikona", + "localProfileInfoText": "Lokální herní profily nemají žádné ikony a u jejich jmen \nnelze garantovat jejich unikátnost. Přeměnou na globální profil\nsi zajistíte unikátní uživatelské jméno a možnost přidat vlatní ikonu.", + "localProfileText": "(local profile)", + "nameDescriptionText": "Přezdívka", + "nameText": "Jméno", + "randomText": "náhodně", + "titleEditText": "Upravit Profil", + "titleNewText": "Nový Profil", + "unavailableText": "jméno \"${NAME}\" není dostupné; zkuste jiné.", + "upgradeProfileInfoText": "Toto rezervuje Vaše uživatelské jméno celosvětově,\na povolí Vám k němu přiřadit vlastní ikonu.", + "upgradeToGlobalProfileText": "Přeměnit na Globální profil" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Nemůžete odstranit výchozí soundtrack.", + "cantEditDefaultText": "Nelze upravit výchozí soundtrack. Zduplikujte jej nebo vytvořte nový.", + "cantEditWhileConnectedOrInReplayText": "Nelze upravovat soundtracky, když jste připojení k partě nebo při záznamu.", + "cantOverwriteDefaultText": "Nelze přepsat výchozí soundtrack", + "cantSaveAlreadyExistsText": "Soundtrack s tímto jménem už existuje!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Výchozí Soundtrack", + "deleteConfirmText": "Odstranit Soundtrack:\n\n'${NAME}'?", + "deleteText": "Odstranit\nSoundtrack", + "duplicateText": "Duplikovat\nSoundtrack", + "editSoundtrackText": "Editor Soundtracků", + "editText": "Upravit\nSoundtrack", + "fetchingITunesText": "získávám Music App playlisty...", + "musicVolumeZeroWarning": "Varování: hlasitost hudby je nastavena na 0", + "nameText": "Název", + "newSoundtrackNameText": "Můj Soundtrack ${COUNT}", + "newSoundtrackText": "Nový Soundtrack:", + "newText": "Nový\nSoundtrack", + "selectAPlaylistText": "Vybrat Playlist", + "selectASourceText": "Zdroj Hudby", + "testText": "test", + "titleText": "Soundtracky", + "useDefaultGameMusicText": "Výchozí Herní Hudba", + "useITunesPlaylistText": "Music App Playlist", + "useMusicFileText": "Hudební Soubor (mp3, atd.)", + "useMusicFolderText": "Složka s Hudebními Soubory" + }, + "editText": "Upravit", + "endText": "Konec", + "enjoyText": "Užij si to!", + "epicDescriptionFilterText": "${DESCRIPTION} V epickém slow motionu", + "epicNameFilterText": "Epické ${NAME}", + "errorAccessDeniedText": "přístup zamítnut", + "errorDeviceTimeIncorrectText": "Čas vašeho zařízení je špatně o ${HOURS} h.\nTo pravděpodobně způsobí problémy.\nProsím zkontrolujte nastavení času a časového pásma.", + "errorOutOfDiskSpaceText": "není místo na disku", + "errorSecureConnectionFailText": "Unable to establish secure cloud connection; network functionality may fail.", + "errorText": "Chyba", + "errorUnknownText": "neznámá chyba", + "exitGameText": "Ukončit ${APP_NAME} ???", + "exportSuccessText": "'${NAME}' úspěšně exportován.", + "externalStorageText": "Externí Úložiště", + "failText": "Fail", + "fatalErrorText": "Ajaj, něco chybí nebo se něco rozbilo.\nZkuste reinstalovat BombSquad\nnebo kontaktujte ${EMAIL} pro pomoc.", + "fileSelectorWindow": { + "titleFileFolderText": "Vyberte Soubor nebo Složku", + "titleFileText": "Vybrat Soubor", + "titleFolderText": "Vybrat Složku", + "useThisFolderButtonText": "Použít Tuto Složku" + }, + "filterText": "Filtr", + "finalScoreText": "Konečné Skóre", + "finalScoresText": "Konečné Výsledky", + "finalTimeText": "Konečný Čas", + "finishingInstallText": "Dokončuji instalaci; chvilí strpení...", + "fireTVRemoteWarningText": "* Pro lepší zkušenosti použijte \novladač nebo nainstalujte aplikaci \n${REMOTE_APP_NAME} na Váš\ntelefon nebo tablet.", + "firstToFinalText": "První-do-${COUNT} Finále", + "firstToSeriesText": "První-do-${COUNT} Série", + "fiveKillText": "PĚT ZABITÍ!!!", + "flawlessWaveText": "Dokonalá vlna!", + "fourKillText": "ČTYŘI ZABITÍ!!!", + "friendScoresUnavailableText": "Skóre přátel není dostupné.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Nejlepší hráči - ${COUNT}. hra", + "gameListWindow": { + "cantDeleteDefaultText": "Nemůžete odstranit výchozí playlist.", + "cantEditDefaultText": "Nelze upravit výchozí playlist! Duplikujte ho nebo vytvořte nový.", + "cantShareDefaultText": "Nemůžete sdílet výchozí playlist.", + "deleteConfirmText": "Odstranit \"${LIST}\" ?", + "deleteText": "Odstranit\nPlaylist", + "duplicateText": "Duplikovat\nPlaylist", + "editText": "Upravit\nPlaylist", + "newText": "Nový\nPlaylist", + "showTutorialText": "Zobrazit Tutorial", + "shuffleGameOrderText": "Náhodné seřazení her", + "titleText": "Přizpůsobit ${TYPE} Playlisty" + }, + "gameSettingsWindow": { + "addGameText": "Přidat Hru" + }, + "gamesToText": "${WINCOUNT} Her k ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Pamatujte: jakékoli zařízení v partě může mít více\nnež jednoho hráče, když máte dostatek ovladačů.", + "aboutDescriptionText": "Použijte tyto záložky pro vytvoření party.\n\nHra s partou vám umožní hrát turnaje\ns Vašimi přáteli mezi různými zařízeními.\n\nPoužijte ${PARTY} Tlačítko v pravo nahoře\npro chat a interakci s Vaší partou.\n(na ovladači stiskněte tlačítko ${BUTTON}, když jste v menu)", + "aboutText": "Použití", + "addressFetchErrorText": "", + "appInviteInfoText": "Pozvěte přátele ke hraní BombSquad a získají\n${COUNT} kupónů zdarma. Vy získáte ${YOU_COUNT} kupónů\nza každého kdo hru vyzkouší.", + "appInviteMessageText": "${NAME} Vám poslal ${COUNT} kupónů v ${APP_NAME}", + "appInviteSendACodeText": "Odeslat jim kód", + "appInviteTitleText": "Pozvat ke hraní ${APP_NAME}", + "bluetoothAndroidSupportText": "(funguje s jakýmkoli Android zařízením podporujícím Bluetooth)", + "bluetoothDescriptionText": "Hostovat/Připojit se k partě přes Bluetooth:", + "bluetoothHostText": "Hostovat přes Bluetooth", + "bluetoothJoinText": "Připojit přes Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "zjišťuji...", + "copyCodeConfirmText": "Kód zkopírován do schránky", + "copyCodeText": "Zkopírovat kód", + "dedicatedServerInfoText": "Pro dosažení nejlepších výsledků nastavte dedikovaný server. Viz bombsquadgame.com/server přečti si to.", + "disconnectClientsText": "Tímto se odpojí ${COUNT} hráč/ů\nve Vaší partě. Jste si jistí?", + "earnTicketsForRecommendingAmountText": "Přátelé získají ${COUNT} tiketů když zkusí tuto hru\n(a ty získáš ${YOU_COUNT} za každého, kdo to udělá)", + "earnTicketsForRecommendingText": "Sdílet hru\nza kupóny zdarma...", + "emailItText": "Odeslat emailem", + "favoritesSaveText": "Uložit jako oblíbený", + "favoritesText": "Oblíbené", + "freeCloudServerAvailableMinutesText": "Další bezplatný server bude dostupný za ${MINUTES} minut.", + "freeCloudServerAvailableNowText": "Bezplatný server je dostupný!", + "freeCloudServerNotAvailableText": "Žádný bezplatný server není dostupný.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} kupónů od ${NAME}", + "friendPromoCodeAwardText": "Získáte ${COUNT} kupónů pokaždé, jakmile je použit.", + "friendPromoCodeExpireText": "Kód vyprší za ${EXPIRE_HOURS} hodin a je funkční pouze pro nové hráče.", + "friendPromoCodeInstructionsText": "Pro použití otevřete ${APP_NAME} a jděte do ,,Nastavení->Pokročilé->Vložit kód\"\nPodívejte se na bombsquadgame.com na odkazy k stažení na všechny podporované platformy.", + "friendPromoCodeRedeemLongText": "Může z něj být získáno ${COUNT} kupónů zdarma, až pro ${MAX_USES} lidí.", + "friendPromoCodeRedeemShortText": "Může být použit pro získání ${COUNT} kupónů do hry.", + "friendPromoCodeWhereToEnterText": "(v \"Nastavení->Pokročilé->Vložit Kód\")", + "getFriendInviteCodeText": "Získat kód pro pozvání přátel", + "googlePlayDescriptionText": "Pozvěte Google Play hráče do vaší Party:", + "googlePlayInviteText": "Pozvat", + "googlePlayReInviteText": "Máte v partě ${COUNT} Google Play hráčů.\nTi budou odpojeni, pokud odešlete novou pozvánku.\nPozvěte je také, aby se připojili zpět.", + "googlePlaySeeInvitesText": "Zobrazit Pozvánky", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google play verze)", + "hostPublicPartyDescriptionText": "Hostovat veřejnou party", + "hostingUnavailableText": "Hostování není dostupné", + "inDevelopmentWarningText": "Poznámka:\n\nSíťová hra je nová a stále se rozvíjející funkce.\nAktualně je vysoce doporučeno, aby všichni hráči\nbyli na stejné Wi-Fi síti.", + "internetText": "Internet", + "inviteAFriendText": "Že vaši přátelé ještě tuto hru nehrají? Pozvěte je,\naby ji vyzkoušeli, a získají ${COUNT} kupónů zdarma.", + "inviteFriendsText": "Pozvat přátele", + "joinPublicPartyDescriptionText": "Připojit se k veřejné skupině", + "localNetworkDescriptionText": "Připojit se k partě (LAN, Bluetooth, atd.)", + "localNetworkText": "Lokální síť", + "makePartyPrivateText": "Publikovat mojí Party", + "makePartyPublicText": "Publikovat mojí Party", + "manualAddressText": "Adresa", + "manualConnectText": "Připojit", + "manualDescriptionText": "Připojit se k partě pomocí adresy:", + "manualJoinSectionText": "Připojit k adrese", + "manualJoinableFromInternetText": "Jste připojitelní přes internet?:", + "manualJoinableNoWithAsteriskText": "NE*", + "manualJoinableYesText": "ANO", + "manualRouterForwardingText": "*aby to mohlo fungovat, zkuste nastavit forward UDP portu ${PORT} ve vašem routeru, na vaší lokální adresu", + "manualText": "Ručně", + "manualYourAddressFromInternetText": "Vaše adresa z internetu:", + "manualYourLocalAddressText": "Vaše lokální adresa:", + "nearbyText": "Blízké", + "noConnectionText": "<žádné připojení>", + "otherVersionsText": "(ostatní verze)", + "partyCodeText": "Kód party", + "partyInviteAcceptText": "Potvrdit", + "partyInviteDeclineText": "Zamítnout", + "partyInviteGooglePlayExtraText": "(koukněte se do 'Google Play' záložky v okně 'Klubovna')", + "partyInviteIgnoreText": "Ignorovat", + "partyInviteText": "${NAME} Vás pozval\nk připojení se k jeho partě!", + "partyNameText": "Název Party", + "partyServerRunningText": "Server vaší party běží", + "partySizeText": "velikost party", + "partyStatusCheckingText": "Zjištiji stav...", + "partyStatusJoinableText": "Nyní se k vaší Party může kdokoli přidat", + "partyStatusNoConnectionText": "Připojení k serveru selhalo", + "partyStatusNotJoinableText": "K vaší Party se nikdo nemůže přidat z internetu", + "partyStatusNotPublicText": "Vaše párty není veřejná", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Privátní parta běží na dedikovaných serverech; není potřeba nastavovat router.", + "privatePartyHostText": "Hostovat privátní partu", + "privatePartyJoinText": "Připojit se k privátní partě", + "privateText": "Privátní", + "publicHostRouterConfigText": "Může vyžadovat konfiguraci přesměrování portů na vašem routeru. Pro snadnější volbu, hostujte privátní partu.", + "publicText": "Veřejné", + "requestingAPromoCodeText": "Získávám kód...", + "sendDirectInvitesText": "Odeslat přímou pozvánku", + "shareThisCodeWithFriendsText": "Sdílejte tento kód s přáteli:", + "showMyAddressText": "Ukaž moji adresu", + "startHostingPaidText": "Hostovat ihned za ${COST}", + "startHostingText": "Hostovaní", + "startStopHostingMinutesText": "Můžete začít a ukončit bezplatné hostování na dalších ${MINUTES} minut.", + "stopHostingText": "Ukončit hostování", + "titleText": "Klubovna", + "wifiDirectDescriptionBottomText": "Jestližem mají všechna zařízení funkci 'Wi-Fi Direct', je možné ji použít k nalezení\na připojení k sobě navzájem. Jakmile jsou všichni jednou propojeni, můžou tvořit party\npomocí záložky 'Lokální síť', prostě tak, jako kdyby byli v normální Wi-Fi síti.\n\nPro nejlepší výsledky by měl být hostitel Wi-Fi Direct zároveň hostitel ${APP_NAME} party.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct může být použit pro propojení zařízení Android přímo,\nbez potřeby Wi-Fi sítě. Nejlépe to funguje na Android 4.2 a novějších.\n\nPro použítí, otevřete Wi-Fi nastavení, a podívejte se v menu po 'Wi-Fi Direct'.", + "wifiDirectOpenWiFiSettingsText": "Otevřít nastavení Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(funguje mezi všemi platformami)", + "worksWithGooglePlayDevicesText": "(funguje se zařízeními které mají Google Play (android) verzi hry)", + "youHaveBeenSentAPromoCodeText": "Byl vám odeslán ${APP_NAME} promo kód:" + }, + "getTicketsWindow": { + "freeText": "ZDARMA!", + "freeTicketsText": "Kupóny Zdarma!", + "inProgressText": "Probíhá transakce; Prosím zkuste to za chvíli.", + "purchasesRestoredText": "Transakce obnoveny", + "receivedTicketsText": "Obdrženo ${COUNT} kupónů!", + "restorePurchasesText": "Obnovit nákupy", + "ticketDoublerText": "Zdvojnásobovač Kupónů", + "ticketPack1Text": "Malý Balíček Kupónů", + "ticketPack2Text": "Střední Balíček Kupónů", + "ticketPack3Text": "Velký Balíček Kupónů", + "ticketPack4Text": "Sloní Balíček Kupónů", + "ticketPack5Text": "Mamutí Balíček Kupónů!", + "ticketPack6Text": "Ultimátní Balíček Kupónů", + "ticketsFromASponsorText": "Zhlédni reklamu \nza ${COUNT} tiketů", + "ticketsText": "${COUNT} Kupónů", + "titleText": "Získat Kupóny", + "unavailableLinkAccountText": "Omlouváme se, ale nákupy nejsou na této platformě možné.\nJako řešení je, že můžete si tento účet propojit s jiným\nna jiné platformě a uskutečnit nákup tam.", + "unavailableTemporarilyText": "Momentálně nedostupné; Zkuste to prosím později", + "unavailableText": "Omlouváme se, ale není dostupné", + "versionTooOldText": "Omlouváme se, ale tato verze hry je moc stará; aktualizujte prosím na novější", + "youHaveShortText": "Máš ${COUNT}", + "youHaveText": "Máte ${COUNT} kupónů" + }, + "googleMultiplayerDiscontinuedText": "Litujeme, služba pro více hráčů Google již není k dispozici.\n Pracuji na výměně co nejrychleji.\n Do té doby zkuste jiný způsob připojení.\n -Eric", + "googlePlayPurchasesNotAvailableText": "Nákupy na Google Play nejsou k dispozici.\nMožná budete muset aktualizovat obchod play.", + "googlePlayServicesNotAvailableText": "Služby Google play nejsou dostupné.\nNěkteré funkce mohou být zakázány.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Vždy", + "fullScreenCmdText": "Celá obrazovka (Cmd-F)", + "fullScreenCtrlText": "Celá obrazovka (Ctrl-F)", + "gammaText": "Gamma", + "highText": "Velká", + "higherText": "Větší", + "lowText": "Malá", + "mediumText": "Střední", + "neverText": "Nikdy", + "resolutionText": "Rozlišení", + "showFPSText": "Zobrazit FPS", + "texturesText": "Textury", + "titleText": "Grafika", + "tvBorderText": "TV Rámeček", + "verticalSyncText": "Vertikální Synchronizace", + "visualsText": "Kvalita zobrazení" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nSilnější než pěsti, ale\nmůže dojít k sebe-zraněním.\nNejlepší bude, když hodíte bombu\nna nepřítele dříve, než vyprší její čas.", + "canHelpText": "${APP_NAME} může pomoci.", + "controllersInfoText": "Můžete hrát ${APP_NAME} s přáteli přes síť nebo můžete, pokud máte\ndostatek ovladačů, hrát všichni na stejném zařízení. ${APP_NAME}\njich podporuje nepřeberné množství. Navíc můžete použít svoje telefony\njako ovladače pomocí aplikace '${REMOTE_APP_NAME}', která\nje zdarma. Podívejte se do Nastavení->Ovladače pro více informací.", + "controllersInfoTextRemoteOnly": "Hrajte ${APP_NAME} s přáteli přes internet \nnebo všichni na jednom zařízení za pomoci \nGamepadů nebo mobilní aplikace '${REMOTE_APP_NAME}'", + "controllersText": "Ovladače", + "controlsSubtitleText": "Vaše přátelská ${APP_NAME} postava má pár základních schopností:", + "controlsText": "Ovládání", + "devicesInfoText": "VR verze ${APP_NAME} může být hrána přes síť s normální\nverzí. Tak vyndejte telefony, tablety a počítače co máte\nnavíc a zapněte svou hru. Propojení normální verze k VR\nverzi může být užitečné kvůli povolení pozorování akce\nlidem zvenčí.", + "devicesText": "Zařízení", + "friendsGoodText": "Je dobré je mít. ${APP_NAME} je největší zábava s více hráči\na podporuje jich až 8 najednou, což nás přivádí k:", + "friendsText": "Přátelé", + "jumpInfoText": "- Skok -\nSkákejte přes malé mezery,\nházejte věci výše nebo si skočte\njen tak z radosti.", + "orPunchingSomethingText": "Nebo do něčeho udeřit, hodit to z útesu nebo to odpálit lepivou bombou", + "pickUpInfoText": "- Zvedání -\nBrát vlajky, nepřátele, nebo cokoli\njiného nepřibitého k zemi.\nStiskněte znovu pro házení.", + "powerupBombDescriptionText": "Dovolí vám vyhodit tři bomby\nza sebou místo pouhé jedné.", + "powerupBombNameText": "Trojité-Bomby", + "powerupCurseDescriptionText": "Pravděpodobně se jim chcete vyhnout.\n ...nebo nechcete?", + "powerupCurseNameText": "Prokletí", + "powerupHealthDescriptionText": "Obnoví veškeré zdraví\nO tom se Vám ani nesnilo.", + "powerupHealthNameText": "Lékárnička", + "powerupIceBombsDescriptionText": "Slabší než normální bomby,\ntvé nepřátele však zmrazí\na učiní je křehkými.", + "powerupIceBombsNameText": "Ledové-Bomby", + "powerupImpactBombsDescriptionText": "Trochu slabší než normální bomby,\nale explodují při nárazu.", + "powerupImpactBombsNameText": "Nárazové-Bomby", + "powerupLandMinesDescriptionText": "Jsou v balíčku po 3;\nUžitečné pro základní obranu\nnebo zastavování rychlých nepřátel", + "powerupLandMinesNameText": "Pozemní-Miny", + "powerupPunchDescriptionText": "Udělá tvé pěsti tvrdšími,\nrychlejšími, lepšími, silnějšími.", + "powerupPunchNameText": "Boxovací-Rukavice", + "powerupShieldDescriptionText": "Absorbuje trochu zranění,\ntakže Vám se nic moc nestane.", + "powerupShieldNameText": "Energetický-Štít", + "powerupStickyBombsDescriptionText": "Přilepí se k čemukoli co trefí.\nZábava zaručena.", + "powerupStickyBombsNameText": "Lepící-Bomby", + "powerupsSubtitleText": "Samozřejmě, žádná hra není hotová bez bonusů:", + "powerupsText": "Bonusy", + "punchInfoText": "- Pěsti -\nPěsti zraní více,\nkdyž se rychle pohybují.\nTakže běhejte a točte se jako šílenci.", + "runInfoText": "- Sprint -\nDržením libovolného tlačítka sprintujte. Pokud máte ovladač tak fungují i ostatní tlačítka.\nSprintování Vás značně zrychlí ale ztíží vám pohyb, takže si dávejte pozor na okraje mapy.", + "someDaysText": "Některé dny prostě cítíte, že potřebujete něco praštit. Nebo něco vyhodit do vzduchu.", + "titleText": "${APP_NAME} Nápověda", + "toGetTheMostText": "Abyste si hru nejvíce užili, budete potřebovat:", + "welcomeText": "Vítejte v ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} obsluhuje menu like a boss -", + "importPlaylistCodeInstructionsText": "Použijte následující kó pro importování kdekoliv jinde:", + "importPlaylistSuccessText": "Úspěšně importován ${TYPE} playlist „'${NAME}'“", + "importText": "Importovat", + "importingText": "Probíhá importování...", + "inGameClippedNameText": "Ve hře bude vidět jako\n\"${NAME}\"", + "installDiskSpaceErrorText": "CHYBA: Není možné dokončit instalaci.\nMožná nemáte dostatek volného místa na Vašem zařízení.\nUvolněte nějaké místo, a zkuste to znovu.", + "internal": { + "arrowsToExitListText": "stiskněte ${LEFT} nebo ${RIGHT} pro opuštění seznamu", + "buttonText": "tlačítko", + "cantKickHostError": "Nemůžete kopat hostitele.", + "chatBlockedText": "${NAME} chat je blokován na ${TIME} sekund.", + "connectedToGameText": "Připojen '${NAME}'", + "connectedToPartyText": "Připojen k ${NAME} partě!", + "connectingToPartyText": "Připojuji...", + "connectionFailedHostAlreadyInPartyText": "Připojení selhalo; Hostitel je v jiné partě.", + "connectionFailedPartyFullText": "Připojení se nezdařilo; parta je plná.", + "connectionFailedText": "Připojení selhalo.", + "connectionFailedVersionMismatchText": "Připojení selhalo; Hostitel používá jinou verzi hry.\nUjistěte se, že máte oba aktualizovanou verzi, a zkuste to znovu.", + "connectionRejectedText": "Připojení odmítnuto.", + "controllerConnectedText": "${CONTROLLER} připojen.", + "controllerDetectedText": "1 nalezený ovladač.", + "controllerDisconnectedText": "${CONTROLLER} odpojen.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} odpojen. Prosím, zkuste ho připojit znovu.", + "controllerForMenusOnlyText": "Tento ovladač nemůže být použit pro hraní; pouze k ovládání v nabídce", + "controllerReconnectedText": "${CONTROLLER} znovu připojen.", + "controllersConnectedText": "${COUNT} - ovladačů připojeno.", + "controllersDetectedText": "${COUNT} - ovladačů nalezeno.", + "controllersDisconnectedText": "${COUNT} - ovladačů odpojeno.", + "corruptFileText": "Nalezen jeden nebo více poškozených souborů. Zkuste prosím reinstalaci, nebo napište email na ${EMAIL}", + "errorPlayingMusicText": "Chyba při přehrávání hudby: ${MUSIC}", + "errorResettingAchievementsText": "Nebylo možné resetovat online achievementy; zkuste to prosím znovu později", + "hasMenuControlText": "${NAME} ovládá menu.", + "incompatibleNewerVersionHostText": "Hostitel serveru má novější verzi než vy, \npro připojení hru aktualizujte.", + "incompatibleVersionHostText": "Hostitel používá jinou verzi hry.\nUjistěte se, že oba používáte aktualizovanou verzi, a zkuste to znovu", + "incompatibleVersionPlayerText": "${NAME} používá jinou verzi hry.\nUjistěte se, že oba použváte aktualizovanou verzi, a zkuste to znovu.", + "invalidAddressErrorText": "Chyba: Neplatná adresa.", + "invalidNameErrorText": "Chyba: Neplatné jméno.", + "invalidPortErrorText": "Chyba: neplatný port.", + "invitationSentText": "Pozvánka odeslána.", + "invitationsSentText": "${COUNT} - pozvánek odesláno.", + "joinedPartyInstructionsText": "Někdo se připojil do tvojí party. \nStiskni 'Hrát' pro start hry", + "keyboardText": "Klávesnice", + "kickIdlePlayersKickedText": "${NAME} vyhozen kvůli neaktivitě.", + "kickIdlePlayersWarning1Text": "${NAME} bude vyhozen do ${COUNT} sekund, pokud bude stále neaktivní.", + "kickIdlePlayersWarning2Text": "(můžete to vypnout v Nastavení -> Pokročilé)", + "leftGameText": "Odpojen '${NAME}'.", + "leftPartyText": "Opustili jste ${NAME} partu.", + "noMusicFilesInFolderText": "Složka neobsahuje žádnou hudbu.", + "playerJoinedPartyText": "${NAME} se připojil do party!", + "playerLeftPartyText": "${NAME} opustil partu.", + "rejectingInviteAlreadyInPartyText": "Odmítnutí pozvánky (už jste v partě).", + "serverRestartingText": "Server se restartuje. Vraťte se za chvíli...", + "serverShuttingDownText": "Server se vypíná...", + "signInErrorText": "Chyba přihlašování.", + "signInNoConnectionText": "Přihlášení selhalo. (žádné internetové připojení)", + "telnetAccessDeniedText": "CHYBA: uživatel nemá povolený přístup k telnetu.", + "timeOutText": "(vyprší za ${TIME} sekund)", + "touchScreenJoinWarningText": "Připojili jste se s dotykovou obrazovkou.\nJestli je to chyba, klepněte na 'Menu->Opustit hru'.", + "touchScreenText": "Dotyková Obrazovka", + "unableToResolveHostText": "Chyba: Nezdařilo se spojit s hostitelem (IP adresa možná neexistuje)", + "unavailableNoConnectionText": "Toto je momentálně nedostupné (bez internetového připojení?)", + "vrOrientationResetCardboardText": "Použitjte toto pro reset orientace VR.\nPro hraní hry budete potřebovat externí ovladač.", + "vrOrientationResetText": "VR resetování orientace.", + "willTimeOutText": "(vyprší čas, když je neaktivní)" + }, + "jumpBoldText": "SKOK", + "jumpText": "Skok", + "keepText": "Zachovat", + "keepTheseSettingsText": "Zachovat tato nastavení?", + "keyboardChangeInstructionsText": "Dvakrát stiskni mezerník pro změnu klávesnice.", + "keyboardNoOthersAvailableText": "Žádné další klávesnice nejsou dostupné.", + "keyboardSwitchText": "Změna klávesnice na \"${NAME}\".", + "kickOccurredText": "${NAME} byl vykopnut.", + "kickQuestionText": "Kopnout ${NAME}?", + "kickText": "kop", + "kickVoteCantKickAdminsText": "Admin nemůže být vyhozen.", + "kickVoteCantKickSelfText": "Nemůžeš vyhodit sám sebe.", + "kickVoteFailedNotEnoughVotersText": "Není dostatek hráčů pro hlasování.", + "kickVoteFailedText": "Kopací-hlasování se nezdařilo.", + "kickVoteStartedText": "Kopací hlasování bylo zahájeno pro ${NAME}.", + "kickVoteText": "Hlasovat pro Kopnutí", + "kickVotingDisabledText": "Hlasování pro vyhození je vypnuto.", + "kickWithChatText": "Typ ${YES} v chatu pro ano a ${NO} pro ne.", + "killsTallyText": "${COUNT} zabití", + "killsText": "Zabití", + "kioskWindow": { + "easyText": "Lehké", + "epicModeText": "Epický Mód", + "fullMenuText": "Celé Menu", + "hardText": "Těžké", + "mediumText": "Střední", + "singlePlayerExamplesText": "Sólo Hra / Co-op Ukázky", + "versusExamplesText": "Versus Ukázky" + }, + "languageSetText": "Jazyk je nastaven na \"${LANGUAGE}\".", + "lapNumberText": "Kolo ${CURRENT}/${TOTAL}", + "lastGamesText": "(posledních ${COUNT} her)", + "leaderboardsText": "Žebříčky", + "league": { + "allTimeText": "Celkově", + "currentSeasonText": "Tato Sezóna (${NUMBER})", + "leagueFullText": "${NAME} Liga", + "leagueRankText": "Liga - Umístění", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "Sezóna ukončena před ${NUMBER} dny.", + "seasonEndsDaysText": "Sezóna končí za ${NUMBER} dní.", + "seasonEndsHoursText": "Sezóna končí za ${NUMBER} hodin.", + "seasonEndsMinutesText": "Sezóna končí za ${NUMBER} minut.", + "seasonText": "Sezóna ${NUMBER}", + "tournamentLeagueText": "Musíte být v lize ${NAME}, abyste se mohli zúčastnit tohoto turnaje.", + "trophyCountsResetText": "Počet trofejí se vymaže příští sezónu." + }, + "levelBestScoresText": "Nejlepší skóre na ${LEVEL}", + "levelBestTimesText": "Nejlepší čas na ${LEVEL}", + "levelFastestTimesText": "Nejrychleji v ${LEVEL}", + "levelHighestScoresText": "Nejvyšší skóre v ${LEVEL}", + "levelIsLockedText": "${LEVEL} je uzamčen.", + "levelMustBeCompletedFirstText": "${LEVEL} musí být nejdříve dokončen.", + "levelText": "Úroveň ${NUMBER}", + "levelUnlockedText": "Level odemčen!", + "livesBonusText": "Bonus života", + "loadingText": "načítám", + "loadingTryAgainText": "Načítání; zkuste to znovu za chvíli...", + "macControllerSubsystemBothText": "Obojí (může způsobovat chyby)", + "macControllerSubsystemClassicText": "Klasický", + "macControllerSubsystemDescriptionText": "(zkus toto změnit pokud vám blbnou ovladače)", + "macControllerSubsystemMFiNoteText": "Ddetekován IOS/Mac ovladač;\nPokud jej chcete použít, povolte je v Nastvení > Ovladače", + "macControllerSubsystemMFiText": "iOS/Mac ovladače", + "macControllerSubsystemTitleText": "Podporované ovladače", + "mainMenu": { + "creditsText": "Tvůrci", + "demoMenuText": "Demo menu", + "endGameText": "Konec Hry", + "endTestText": "Konec Testu", + "exitGameText": "Ukončit Hru", + "exitToMenuText": "Vrátit se do menu?", + "howToPlayText": "Jak hrát", + "justPlayerText": "(Jen ${NAME})", + "leaveGameText": "Opustit Hru", + "leavePartyConfirmText": "Opravdu opustit partu?", + "leavePartyText": "Opustit partu", + "quitText": "Konec", + "resumeText": "Pokračovat", + "settingsText": "Nastavení" + }, + "makeItSoText": "Potvrdit", + "mapSelectGetMoreMapsText": "Získat více map...", + "mapSelectText": "Vybrat...", + "mapSelectTitleText": "${GAME} Mapy", + "mapText": "Mapa", + "maxConnectionsText": "Max připojitelných hráčů", + "maxPartySizeText": "Maximální velikost party", + "maxPlayersText": "Max hráčů", + "merchText": "Pro fanoušky!", + "modeArcadeText": "Arkádový mód", + "modeClassicText": "Klasický mód", + "modeDemoText": "Ukázkový mód", + "mostValuablePlayerText": "Nejcennější hráč", + "mostViolatedPlayerText": "Nejvíce obětovaný hráč", + "mostViolentPlayerText": "Nejvíce násilný hráč", + "moveText": "Pohyb", + "multiKillText": "${COUNT}-ZABITÍ!!!", + "multiPlayerCountText": "${COUNT} - počet hráčů", + "mustInviteFriendsText": "Poznámka: Musíte pozvat přátele\npomocí tlačítka \"${GATHER}\", nebo\npžipojit ovladače pro hraní s více hráči.", + "nameBetrayedText": "${NAME} zradil ${VICTIM}", + "nameDiedText": "${NAME} zemřel.", + "nameKilledText": "${NAME} zabil ${VICTIM}.", + "nameNotEmptyText": "Jméno nemůže být prázdné!", + "nameScoresText": "${NAME} Skóruje!", + "nameSuicideKidFriendlyText": "${NAME} zemřel nešťastnou náhodou.", + "nameSuicideText": "${NAME} spáchal sebevraždu.", + "nameText": "Jméno", + "nativeText": "Nativní", + "newPersonalBestText": "Nový osobní rekord!", + "newTestBuildAvailableText": "Novější testovací build je dostupný! (${VERSION} build ${BUILD}).\nZískejte ho na ${ADDRESS}", + "newText": "Nový", + "newVersionAvailableText": "Je dostupná novější verze ${APP_NAME}! (${VERSION})", + "nextAchievementsText": "Další ocenění:", + "nextLevelText": "Další Level", + "noAchievementsRemainingText": "- žádný", + "noContinuesText": "(bez pokračování)", + "noExternalStorageErrorText": "Žádné externí úložiště nebylo na tomto zařízení nalezeno", + "noGameCircleText": "Chyba: nejste přihlášeni do Game Circle", + "noProfilesErrorText": "Nemáte žádné herní profily, takže Vám bylo podstrčeno jméno '${NAME}'.\nJděte do Nastavení->Herní Profily pro vytvoření svého profilu.", + "noScoresYetText": "Zatím žádné výsledky.", + "noThanksText": "Ne, Děkuji", + "noTournamentsInTestBuildText": "VAROVÁNÍ: Skore z turnajů z tohoto účtu budou ignorována.", + "noValidMapsErrorText": "Nebyly nalezeny žádné platné mapy pro tento typ hry.", + "notEnoughPlayersRemainingText": "Nezbývá dostatek hráčů; ukončete a zapněte novou hru", + "notEnoughPlayersText": "Potřebujete nejméně ${COUNT} hráčů pro spuštění této hry!", + "notNowText": "Teď Ne", + "notSignedInErrorText": "Pro tuto akci se musíte přihlásit", + "notSignedInGooglePlayErrorText": "Pro tuto akci se musíte přihlásit přes Google Play", + "notSignedInText": "nepřihlášen", + "notUsingAccountText": "Poznámka: nevyužívaný ${SERVICE} account.\nJděte do 'Účet -> Přihlásit se službou ${SERVICE}' pokud chcete účet používat.", + "nothingIsSelectedErrorText": "Nic není vybráno!", + "numberText": "#${NUMBER}", + "offText": "Vyp", + "okText": "Ok", + "onText": "Zap", + "oneMomentText": "Chvilku strpení...", + "onslaughtRespawnText": "${PLAYER} se oživí ve vlně ${WAVE}", + "orText": "${A} nebo ${B}", + "otherText": "Ostatní...", + "outOfText": "(#${RANK} z ${ALL})", + "ownFlagAtYourBaseWarning": "Vaše vlajka musí být\nna vaší základně, abyste mohli skórovat!", + "packageModsEnabledErrorText": "Hra po síti není povolena pokud jsou zapnuty lokální-balíčky-modů (Koukněte se do Nastavení->Pokročilé)", + "partyWindow": { + "chatMessageText": "Zpráva do chatu", + "emptyText": "Vaše parta nemá žádného člena", + "hostText": "(hostitel)", + "sendText": "Odeslat", + "titleText": "Vaše Parta" + }, + "pausedByHostText": "(pozastaveno hostitelem)", + "perfectWaveText": "Perfektní Vlna!", + "pickUpText": "Zvednout", + "playModes": { + "coopText": "Co-op", + "freeForAllText": "Všichni-proti-Všem", + "multiTeamText": "Multi-Team", + "singlePlayerCoopText": "Pro jednoho hráče / Co-op", + "teamsText": "Týmy" + }, + "playText": "Hrát", + "playWindow": { + "oneToFourPlayersText": "1-4 hráči", + "titleText": "Hrát", + "twoToEightPlayersText": "2-8 hráčů" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} vstoupí na začátku dalšího kola.", + "playerInfoText": "Info o hráči", + "playerLeftText": "${PLAYER} opustil hru.", + "playerLimitReachedText": "Limit hráčů (${COUNT}) byl dosažen; žádní ostatní připojovaní nejsou povoleni.", + "playerLimitReachedUnlockProText": "Upgradujte v obchodě na \"${PRO}\", abyste mohli hrát s více než ${COUNT} hráči.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Nemůžete odstranit Váš profil s účtem.", + "deleteButtonText": "Odstranit\nProfil", + "deleteConfirmText": "Odstranit '${PROFILE}'?", + "editButtonText": "Upravit\nProfil", + "explanationText": "(různé přezdívky a vzhledy pro hráče na tomto účtu)", + "newButtonText": "Nový\nProfil", + "titleText": "Herní Profily" + }, + "playerText": "Hráč", + "playlistNoValidGamesErrorText": "Tento playlist neobsahuje žádné platné odemčené hry.", + "playlistNotFoundText": "playlist nenalezen", + "playlistText": "Playlist", + "playlistsText": "Playlisty", + "pleaseRateText": "Jestliže Vás ${APP_NAME} baví, zvažte prosím, jestli si nechcete udělat\nchvilku na ohodnocení nebo napsání recenze. Poskytuje to užitečnou\nzpětnou vazbu a pomáhá podporovat budoucí vývoj.\n\nDíky!\n-eric", + "pleaseWaitText": "Prosím čekejte...", + "pluginClassLoadErrorText": "Chyba při načítání třídy pluginu '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Chyba při inicializaci pluginu '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Nové plugin(y) nalezeny. Pro aktivaci restartujte, nebo konfigurujte v nastavení.", + "pluginsRemovedText": "${NUM} plugin(y) nenalezeny.", + "pluginsText": "Pluginy", + "practiceText": "Cvičení", + "pressAnyButtonPlayAgainText": "Stiskněte libovolné tlačítko pro opakování hry...", + "pressAnyButtonText": "Stisktněte libovolné tlačítko pro pokračování...", + "pressAnyButtonToJoinText": "stiskněte libovolné tlačítko pro připojení...", + "pressAnyKeyButtonPlayAgainText": "Stiskněte libovolnou klávesu/tlačítko pro opakování hry...", + "pressAnyKeyButtonText": "Stiskněte libovolnou klávesu/tlačítko pro pokračování...", + "pressAnyKeyText": "Stiskněte libovolnou klávesu...", + "pressJumpToFlyText": "** Stiskněte opakovaně skok pro létání **", + "pressPunchToJoinText": "stiskněte PRAŠTIT pro připojení...", + "pressToOverrideCharacterText": "stiskněte ${BUTTONS} pro nahrazení vaší postavy", + "pressToSelectProfileText": "Stiskněte ${BUTTONS} pro zvolení hráče", + "pressToSelectTeamText": "stiskněte ${BUTTONS} pro vybrání týmu", + "promoCodeWindow": { + "codeText": "Kód", + "codeTextDescription": "Promo Kód", + "enterText": "Vložit" + }, + "promoSubmitErrorText": "Chyba při odesílání kódu; zkontrolujte internetové připojení", + "ps3ControllersWindow": { + "macInstructionsText": "Vypněte na zadní straně své PS3, ujistěte se, že\nje na Vašem Mac zaplý Bluetooth, a poté připojte Váš ovladač\nk vašemu Mac přes USB kabel, abyste je mohli spárovat. Odteď\nmůžete použít na ovladači tlačítko home (domů) pro připojení k Vašemu\nMacu ať už v kabelovém (USB) nebo bezdrátovém (Bluetooth) módu.\n\nNa některých Mac zařízeních můžete být při párování vyzváni k zadání passcode.\nJestliže se tohle stane, podívejte se na následující tutorial, nebo zkuste hledat na google.\n\n\n\n\nOvladače PS3, připojené bezdrátově, by se měly zobrazit v seznamu v\nSystémová nastavení->Bluetooth. Možná je budete potřebovat odstranit, pokud \nje budete chtít znovu použít s Vaším PS3.\n\nTaké se ujistěte, že je odpojíte od Bluetooth když nejsou používané,\nprotože jinak se jejich baterie budou stále vybíjet.\n\nBluetooth by měl zvládnout až 7 připojených zařízení,\nale to se může lišit.", + "ouyaInstructionsText": "Pro použití ovladače s Vaším OUYA, ho prostě jednou připojte přes USB kabel\nkvůli spárování. Ovšem při tomto kroku se mohou odpojit ostatní ovladače,\ntakže byste měli restartovat Vaši OUYA a odpojit USB kabel.\n\nOdteď budete schopni použít tlačítko HOME na ovladači k jeho připojení\nbezdrátově. Poté co dohrajete, držte tlačítko HOME 10 sekund, aby se\novladač vypl; jinak může zůstat zaplý\na vybíjet baterie.", + "pairingTutorialText": "video tutorial o párování", + "titleText": "Používání PS3 Ovladače s ${APP_NAME}:" + }, + "punchBoldText": "PRAŠTIT", + "punchText": "Praštit", + "purchaseForText": "Koupit za ${PRICE}", + "purchaseGameText": "Koupit Hru", + "purchasingText": "Probíhá transakce...", + "quitGameText": "Ukončit ${APP_NAME}?", + "quittingIn5SecondsText": "Ukončuji za 5 sekund...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Náhodně", + "rankText": "Rank", + "ratingText": "Hodnocení", + "reachWave2Text": "Pro hodnocení se dostaňte do vlny 2.", + "readyText": "připraven", + "recentText": "Poslední", + "remoteAppInfoShortText": "${APP_NAME} je zábavnější hrát s rodinou & přáteli.\nPřipoj jedno nebo více hardwerových ovladačů nebo \nnainstaluj ${REMOTE_APP_NAME} na telefon nebo tablet \nk jejich použití jako ovladač.", + "remote_app": { + "app_name": "BombSquad Ovladač", + "app_name_short": "BSOvladač", + "button_position": "Pozice tlačítek", + "button_size": "Velikost tlačítek", + "cant_resolve_host": "Hostitel nebyl nalezen.", + "capturing": "Zachytávám...", + "connected": "Připojen.", + "description": "Použijte Váš telefon či tablet jako ovladač pro BombSquad.\nNajednou lze připojit až 8 zařízení k lokálnímu multiplayerovému šílenství na televizi či tabletu.", + "disconnected": "Odpojen serverem.", + "dpad_fixed": "statický", + "dpad_floating": "plovoucí", + "dpad_position": "Pozice D-Pad", + "dpad_size": "Velikost D-Pad", + "dpad_type": "Typ D-Pad", + "enter_an_address": "Zadejte adresu", + "game_full": "Hra je již zaplněna hráči nebo nepřijímá připojení.", + "game_shut_down": "Hra byla vypnuta.", + "hardware_buttons": "Hardwarová tlačítka", + "join_by_address": "Připojit se k adrese...", + "lag": "Prodleva: ${SECONDS} sekund", + "reset": "Navrátit základní", + "run1": "Běh 1", + "run2": "Běh 2", + "searching": "Probíhá hledání aktivních her BombSquad...", + "searching_caption": "Pro připojení se dotkněte jména hry.\nUjistěte se, že jste na stejné síti wifi.", + "start": "Start", + "version_mismatch": "Neshoda verzí.\nUjistěte se, že BombSquad a BombSquad Ovladač\njsou aktualizované na poslední verzi, a zkuste to znovu." + }, + "removeInGameAdsText": "Odemkněte \"${PRO}\" v obchodě pro odstranění reklam ve hře.", + "renameText": "Přejmenovat", + "replayEndText": "Ukončit Záznam", + "replayNameDefaultText": "Záznam Poslední Hry", + "replayReadErrorText": "Chyba při čtení souboru záznamu.", + "replayRenameWarningText": "Přejmenujte \"${REPLAY}\" po odehrané hře, pokud ho chcete zachovat; jinak bude přepsán", + "replayVersionErrorText": "Omlouváme se, ale tento záznam byl vytvořen\nv jiné verzi hry a nemůže být přehrán.", + "replayWatchText": "Podívat se na Záznam", + "replayWriteErrorText": "Chyba při zápisu souboru záznamu.", + "replaysText": "Záznamy", + "reportPlayerExplanationText": "Použijte tento email pro nahlášení podvádění, nevhodného vyjadřování či jiného špatného chování.\nProsím popište níže:", + "reportThisPlayerCheatingText": "Podvádění", + "reportThisPlayerLanguageText": "Nevhodné vyjadřování", + "reportThisPlayerReasonText": "Proč chcete tohoto hráče nahlásit?", + "reportThisPlayerText": "Nahlásit tohoto hráče", + "requestingText": "Vyžaduje se...", + "restartText": "Restartovat", + "retryText": "Zkusit znovu", + "revertText": "Navrátit", + "runText": "Běh", + "saveText": "Uložit", + "scanScriptsErrorText": "Chyba při skenování skriptů; shlédni záznam pro více informací.", + "scoreChallengesText": "Skóre Výzev", + "scoreListUnavailableText": "Seznam skóre nedostupný", + "scoreText": "Skóre", + "scoreUnits": { + "millisecondsText": "Milisekund", + "pointsText": "Bodů", + "secondsText": "Sekund" + }, + "scoreWasText": "(předchozí ${COUNT})", + "selectText": "Zvolit", + "seriesWinLine1PlayerText": "VYHRÁVÁ", + "seriesWinLine1TeamText": "VYHRÁVÁ", + "seriesWinLine1Text": "VYHRÁVÁ", + "seriesWinLine2Text": "SÉRII!", + "settingsWindow": { + "accountText": "Účet", + "advancedText": "Pokročilé", + "audioText": "Zvuk", + "controllersText": "Ovladače", + "graphicsText": "Grafika", + "playerProfilesMovedText": "Poznámka: profily hráče byly přesunuty do okna účtů v hlavním menu.", + "playerProfilesText": "Herní Profily", + "titleText": "Nastavení" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(jednoduchá, ovládáním přátelská, klávesnice na obrazovce pro úpravu textu)", + "alwaysUseInternalKeyboardText": "Vždy Použít Interní klávesnici", + "benchmarksText": "Benchmarky a Testy výdrže", + "disableCameraGyroscopeMotionText": "Vypnout gyroskopický pohyb kamery", + "disableCameraShakeText": "Vypnout otřes kamery", + "disableThisNotice": "(můžete si toto oznámení vypnout v pokročilých nastaveních)", + "enablePackageModsDescriptionText": "(zapíná extra modovací možnosti, ale vypíná hru po síti)", + "enablePackageModsText": "Zapnout Lokální Balíčky Módů", + "enterPromoCodeText": "Zadat kód", + "forTestingText": "Poznámka: Tyto hodnoty sou pouze pro test. Obnoví se po restartu.", + "helpTranslateText": "Jiné než anglické verze ${APP_NAME} jsou komunitně\npodporovanou záležitostí. Pokud byste chtěli přidat\nnebo opravit překlad, následujte odkaz níže. Předem děkujeme!", + "kickIdlePlayersText": "Vyhazovat Neaktivní Hráče", + "kidFriendlyModeText": "Dětský Mód (sníženo násilí, atd.)", + "languageText": "Jazyk", + "moddingGuideText": "Příručka módů", + "mustRestartText": "Musíte restartovat hru, aby se změny projevily.", + "netTestingText": "Testování Sítě", + "resetText": "Obnovit", + "showBombTrajectoriesText": "Ukázat trajektorii bomb", + "showPlayerNamesText": "Jména hráčů", + "showUserModsText": "Zobrazit Složku s Módy", + "titleText": "Pokročilé", + "translationEditorButtonText": "${APP_NAME} Editor Překladu", + "translationFetchErrorText": "stav překladu nedostupný", + "translationFetchingStatusText": "zjišťuji stav překladu...", + "translationInformMe": "Oznamte mi když bude můj jazyk potřebovat aktualizaci", + "translationNoUpdateNeededText": "tento jazyk je aktuální; woohoo!", + "translationUpdateNeededText": "** jazyk potřebuje aktualizovat!! **", + "vrTestingText": "VR Test" + }, + "shareText": "Sdílet", + "sharingText": "Sdílení...", + "showText": "Zobrazit", + "signInForPromoCodeText": "Musíte se přihlásit k účtu, aby mohly kódy fungovat.", + "signInWithGameCenterText": "Pro použití účtu Game Center se přihlaste\ns pomocí aplikace Game Center.", + "singleGamePlaylistNameText": "Jen ${GAME}", + "singlePlayerCountText": "1 Hráč", + "soloNameFilterText": "Sólo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Vybírání Postavy", + "Chosen One": "Vyvolený", + "Epic": "Hry v Epickém Módu", + "Epic Race": "Epický závod", + "FlagCatcher": "Seberte vlajku", + "Flying": "Veselé Myšlenky", + "Football": "Ragby", + "ForwardMarch": "Přepadení", + "GrandRomp": "Dobývání", + "Hockey": "Hokej", + "Keep Away": "Držte se Dál", + "Marching": "Obrana", + "Menu": "Hlavní menu", + "Onslaught": "Útok", + "Race": "Závod", + "Scary": "Král Kopce", + "Scores": "Obrazovka Skóre", + "Survival": "Zneškodnění", + "ToTheDeath": "Zápas Smrti", + "Victory": "Obrazovka Konečného Skóre" + }, + "spaceKeyText": "mezera", + "statsText": "Statistiky", + "storagePermissionAccessText": "Tohle vyžaduje přístup k úložišti", + "store": { + "alreadyOwnText": "Už vlastníš ${NAME}!", + "bombSquadProDescriptionText": "• Zdvojnásobuje kupóny získané za achievementy\n• Odstraňuje reklamy ve hře\n• Obsahuje ${COUNT} bonusových kupónů\n• +${PERCENT}% bonus ke skóre ligy\n• Odemyká '${INF_ONSLAUGHT}' a \n '${INF_RUNAROUND}' co-op mapy", + "bombSquadProFeaturesText": "Vylepšení:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Odstraní reklamy ve hře\n• Odemkne další herní nastavení\n• A k tomu:", + "buyText": "Koupit", + "charactersText": "Postavy", + "comingSoonText": "Již brzy...", + "extrasText": "Bonusy", + "freeBombSquadProText": "BombSquad je nyní zdarma, ale pokud jste si ho dříve zakoupili,\ndostáváte BombSquad Pro upgrade a ${COUNT} kupónů jako poděkování.\nUžijte si nové možnosti a děkujeme za vaši podporu!\n-Eric", + "gameUpgradesText": "Vylepšení hry", + "holidaySpecialText": "Vánoční speciál", + "howToSwitchCharactersText": "(jděte do \"${SETTINGS} -> ${PLAYER_PROFILES}\" k použití nebo úpravě postav)", + "howToUseIconsText": "(vytvořte si globální herní účet (v okně účtů) abyste je mohli použít)", + "howToUseMapsText": "(použijte tyto mapy ve vlastních týmových/všichni-proti-všem seznamech)", + "iconsText": "Ikony", + "loadErrorText": "Nelze načíst.\nZkontrolujte připojení.", + "loadingText": "Načítání...", + "mapsText": "Mapy", + "miniGamesText": "MiniHry", + "oneTimeOnlyText": "(pouze jednou)", + "purchaseAlreadyInProgressText": "Koupě této položky již probíhá.", + "purchaseConfirmText": "Zakoupit ${ITEM}?", + "purchaseNotValidError": "Nákup je neplatný.\nKontaktuje ${EMAIL} pokuď je to chyba.", + "purchaseText": "Zakoupit", + "saleBundleText": "Balíček ve slevě!", + "saleExclaimText": "Sleva!", + "salePercentText": "(o ${PERCENT}% levnější)", + "saleText": "VÝPRODEJ", + "searchText": "Hledat", + "teamsFreeForAllGamesText": "Týmy / Všichni-proti-Všem Hry", + "totalWorthText": "***JEDNOTLIVĚ STOJÍ ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Aktivovat?", + "winterSpecialText": "Zimní Speciál", + "youOwnThisText": "- již vlastníte -" + }, + "storeDescriptionText": "Šílená Hra s Osmi Hráči v Partě!\n\nVyhoďte do vzduchu své přátele (nebo počítač) v turnaji explozivních miniher jako je třeba Seber Vlajku, Bomber-Hokej, a Epický-Slow-Motion-Zápas-Smrti!\n\nJednoduché ovládání a široká podpora ovladačů tvoří jednoduchou vlastnost připojit až 8 lidí do akce; a také můžete použít své mobilní zařízení jako ovladače přes aplikaci 'BombSquad Remote', která je zdarma!\n\nOdhoďte Bomby\n\nPro více informací navštivte stránku www.froemling.net/bombsquad", + "storeDescriptions": { + "blowUpYourFriendsText": "Vyhoďte přátele do vzduchu.", + "competeInMiniGamesText": "Utkejte se v minihrách od závodění po létání.", + "customize2Text": "Přuzpůsobte si postavy, minihry, a dokonce i soundtrack.", + "customizeText": "Přizpůsobte si postavy a vytvořte si vlastní playlist miniher.", + "sportsMoreFunText": "Sporty jsou s bombami větší zábava.", + "teamUpAgainstComputerText": "Sjednoťte se proti počítači." + }, + "storeText": "Obchod", + "submitText": "Odeslat", + "submittingPromoCodeText": "Odesílám kód...", + "teamNamesColorText": "Týmové Jména/Barvy...", + "telnetAccessGrantedText": "Přístup k telnetu zapnut.", + "telnetAccessText": "Detekován přístup k telnetu; povolit?", + "testBuildErrorText": "Tento testovací build již není dlouho aktivní; podívejte se prosím po nové verzi.", + "testBuildText": "Testovací Build", + "testBuildValidateErrorText": "Nebylo možné ověřit testovací build. (žádné internetové připojení?)", + "testBuildValidatedText": "Testovací Build Ověřen; Užívejte!", + "thankYouText": "Děkujeme Vám za podporu! Užijte si hru!!", + "threeKillText": "TŘI ZABITÍ!!!", + "timeBonusText": "Časový Bonus", + "timeElapsedText": "Uplynulý Čas", + "timeExpiredText": "Čas Vypršel", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Tip", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Nejlepší Přátelé", + "tournamentCheckingStateText": "Zjišťuji stav turnaje; Počkejte prosím...", + "tournamentEndedText": "Tento turnaj již skončil. Brzy ale začne další.", + "tournamentEntryText": "Vstup do turnaje", + "tournamentResultsRecentText": "Vysledky predchozich turnaju", + "tournamentStandingsText": "Pořadí v turnaji", + "tournamentText": "Turnaj", + "tournamentTimeExpiredText": "Čas turnaje vypršel", + "tournamentsDisabledWorkspaceText": "Turnaje jsou zakázány, když jsou aktivní pracovní prostory.\nChcete-li znovu povolit turnaje, deaktivujte svůj pracovní prostor a restartujte.", + "tournamentsText": "Turnaje", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Kosťík", + "Butch": "Butch", + "Easter Bunny": "Velikonoční králíček", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Štístko", + "Mel": "Mel", + "Middle-Man": "Střední-Muž", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Santa Claus", + "Snake Shadow": "Hadí stín", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao maskot", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} - Trénink", + "Infinite ${GAME}": "${GAME} - Nekonečné", + "Infinite Onslaught": "Nekonečné Útočení", + "Infinite Runaround": "Nekonečná Obrana", + "Onslaught Training": "Útok - Trénink", + "Pro ${GAME}": "${GAME} - Profík", + "Pro Football": "Ragby - Profík", + "Pro Onslaught": "Útok - Profík", + "Pro Runaround": "Obrana - Profík", + "Rookie ${GAME}": "${GAME} - Nováček", + "Rookie Football": "Ragby - Nováček", + "Rookie Onslaught": "Útok - Nováček", + "The Last Stand": "Poslední vzdor", + "Uber ${GAME}": "${GAME} - Mega", + "Uber Football": "Ragby - Megatěžké", + "Uber Onslaught": "Útok - Megatěžké", + "Uber Runaround": "Obrana - Megatěžká" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Staňte se vyvoleným po dlouhý čas, abyste vyhráli.\nZabijte vyvoleného, abyste se jím stali.", + "Bomb as many targets as you can.": "Vybombardujte tolik cílů, kolik dokážete.", + "Carry the flag for ${ARG1} seconds.": "Držte vlajku po dobu ${ARG1} sekund.", + "Carry the flag for a set length of time.": "Držte vlajku po nastavený čas.", + "Crush ${ARG1} of your enemies.": "Rozdrťte ${ARG1} Vašich nepřátel.", + "Defeat all enemies.": "Porazte všechny nepřátele", + "Dodge the falling bombs.": "Vyhněte se padajícím bombám.", + "Final glorious epic slow motion battle to the death.": "Finální úžasný epický slow motion souboj na smrt.", + "Gather eggs!": "Sbírání vajec!", + "Get the flag to the enemy end zone.": "Dostaňte vlajku na nepřátelskou koncovou zónu.", + "How fast can you defeat the ninjas?": "Jak rychle dokážete porazit ninja bojovníky?", + "Kill a set number of enemies to win.": "Zabijte určený počet nepřátel, abyste vyhráli.", + "Last one standing wins.": "Poslední vzdorující vyhrává.", + "Last remaining alive wins.": "Poslední zbývající živý vyhrává.", + "Last team standing wins.": "Poslední vzdorující tým vyhrává.", + "Prevent enemies from reaching the exit.": "Zabraňte nepřátelům dostat se na konec.", + "Reach the enemy flag to score.": "Dostaňte nepřátelskou vlajku, abyste skórovali.", + "Return the enemy flag to score.": "Vraťe nepřátelskou vlajku pro skórování.", + "Run ${ARG1} laps.": "Uběhněte ${ARG1} kol/a.", + "Run ${ARG1} laps. Your entire team has to finish.": "Uběhněte ${ARG1} kol. Celý Váš tým musí dokončit.", + "Run 1 lap.": "Uběhněte 1 kolo.", + "Run 1 lap. Your entire team has to finish.": "Uběhněte 1 kolo. Celý váš tým musí dokončit.", + "Run real fast!": "Běžte opravdu rychle!", + "Score ${ARG1} goals.": "Dejte góly - ${ARG1}.", + "Score ${ARG1} touchdowns.": "Dejte touchdowny - ${ARG1}.", + "Score a goal.": "Dejte gól.", + "Score a touchdown.": "Dejte touchdown.", + "Score some goals.": "Dejte pár gólů.", + "Secure all ${ARG1} flags.": "Zajistěte všechny vlajky - ${ARG1}", + "Secure all flags on the map to win.": "Zajistěte všechny vlajky na mapě, abyste vyhráli.", + "Secure the flag for ${ARG1} seconds.": "Zajistěte vlajku na ${ARG1} sekund.", + "Secure the flag for a set length of time.": "Zajistěte vlajku po určený čas.", + "Steal the enemy flag ${ARG1} times.": "Ukradněte ${ARG1}x nepřátelskou vlajku.", + "Steal the enemy flag.": "Ukradněte nepřátelskou vlajku.", + "There can be only one.": "Tady může být jen jedna.", + "Touch the enemy flag ${ARG1} times.": "Dotkněte se ${ARG1}x nepřátelské vlajky.", + "Touch the enemy flag.": "Dotkněte se nepřátelské vlajky.", + "carry the flag for ${ARG1} seconds": "Držte vlajku po dobu ${ARG1} sekund", + "kill ${ARG1} enemies": "zabijte ${ARG1} nepřátel", + "last one standing wins": "poslední vzdorující vyhrává", + "last team standing wins": "poslední vzdorující tým vyhrává", + "return ${ARG1} flags": "vraťte ${ARG1} vlajek", + "return 1 flag": "vraťte 1 vlajku", + "run ${ARG1} laps": "uběhněte ${ARG1} kol/a", + "run 1 lap": "uběhněte 1 kolo", + "score ${ARG1} goals": "dejte góly - ${ARG1}", + "score ${ARG1} touchdowns": "dejte touchdowny - ${ARG1}", + "score a goal": "dejte gól", + "score a touchdown": "dejte touchdown", + "secure all ${ARG1} flags": "zajistěte všechny vlajky - ${ARG1}", + "secure the flag for ${ARG1} seconds": "zajistěte vlajku na ${ARG1} sekund", + "touch ${ARG1} flags": "dotkněte se ${ARG1} vlajek", + "touch 1 flag": "dotkněte se 1 vlajky" + }, + "gameNames": { + "Assault": "Přepadení", + "Capture the Flag": "Seberte Vlajku", + "Chosen One": "Vyvolený", + "Conquest": "Dobývání", + "Death Match": "Zápas Smrti", + "Easter Egg Hunt": "Lovení velikonočních vajíček", + "Elimination": "Zneškodnění", + "Football": "Ragby", + "Hockey": "Hokej", + "Keep Away": "Držte se Dál", + "King of the Hill": "Král Kopce", + "Meteor Shower": "Smršť Meteoritů", + "Ninja Fight": "Souboj Ninja bojovníků", + "Onslaught": "Útok", + "Race": "Závod", + "Runaround": "Obrana", + "Target Practice": "Trénování Cílů", + "The Last Stand": "Poslední vzdor" + }, + "inputDeviceNames": { + "Keyboard": "Klávesnice", + "Keyboard P2": "Klávesnice P2" + }, + "languages": { + "Arabic": "Arabsky", + "Belarussian": "Běloruština", + "Chinese": "Zjednodušená Čínština", + "ChineseTraditional": "Tradiční Čínština", + "Croatian": "Chorvatština", + "Czech": "Čeština", + "Danish": "Dánština", + "Dutch": "Holandština", + "English": "Angličtina", + "Esperanto": "Esperanto", + "Filipino": "Filipínština", + "Finnish": "Finština", + "French": "Francouzština", + "German": "Němčina", + "Gibberish": "Hatmatilka", + "Greek": "Řečtina", + "Hindi": "Hindština", + "Hungarian": "Maďarština", + "Indonesian": "Indonéština", + "Italian": "Italština", + "Japanese": "Japonština", + "Korean": "Korejština", + "Malay": "Malajština", + "Persian": "Perština", + "Polish": "Polština", + "Portuguese": "Portugalština", + "Romanian": "Rumunština", + "Russian": "Ruština", + "Serbian": "Srbština", + "Slovak": "Slovenština", + "Spanish": "Španělština", + "Swedish": "Švédština", + "Tamil": "Tamiština", + "Thai": "Thaiština", + "Turkish": "Turečtina", + "Ukrainian": "Ukrajinština", + "Venetian": "Benátština", + "Vietnamese": "Vietnamština" + }, + "leagueNames": { + "Bronze": "Bronz", + "Diamond": "Diamant", + "Gold": "Zlato", + "Silver": "Stříbro" + }, + "mapsNames": { + "Big G": "Velké G", + "Bridgit": "Mostík", + "Courtyard": "Nádvoří", + "Crag Castle": "Skalní Hrad", + "Doom Shroom": "Houba Zkázy", + "Football Stadium": "Ragby Stadion", + "Happy Thoughts": "Veselé Myšlenky", + "Hockey Stadium": "Hokejový Stadion", + "Lake Frigid": "Jezero Zmrzlík", + "Monkey Face": "Opičí Tvář", + "Rampage": "Zuřivost", + "Roundabout": "Kruhový Objezd", + "Step Right Up": "Zmatené schody", + "The Pad": "Podložka", + "Tip Top": "Tip Ťop", + "Tower D": "Věž D", + "Zigzag": "Cikcak" + }, + "playlistNames": { + "Just Epic": "Jen Epické", + "Just Sports": "Jen Sporty" + }, + "scoreNames": { + "Flags": "Vlajky", + "Goals": "Góly", + "Score": "Skóre", + "Survived": "Přežil", + "Time": "Čas", + "Time Held": "Čas Držen" + }, + "serverResponses": { + "A code has already been used on this account.": "Kód již byl pro tento účet použit.", + "A reward has already been given for that address.": "Chyba: Tato adresa již odměnu dostala.", + "Account linking successful!": "Spojení účtu úspěšné!", + "Account unlinking successful!": "Účet úspěšně odpojen!", + "Accounts are already linked.": "Účty jsou již spojeny.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Zhlédnutí reklamy nebylo ověřeno.\nProsím ujistěte se, že máte oficiální a updatovanou hru.", + "An error has occurred; (${ERROR})": "Nastala chyba; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Nastala chyba; kontaktujete prosím podporu. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Stala se chyba; prosím kontaktujte support@froemling.net.", + "An error has occurred; please try again later.": "Vyskytla se chyba; prosím zkuste to znova za chvilku", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Jste si jisti, že chcete propojit tyto účty?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nTuto akci nelze vrátit zpět!", + "BombSquad Pro unlocked!": "BombSquad Pro odemčen!", + "Can't link 2 accounts of this type.": "Nelze spojit 2 účty tohodle typu.", + "Can't link 2 diamond league accounts.": "Nelze spojit 2 účty diamantové ligy.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Nelze propojit; převýšily maximum ${COUNT} propojených účtů.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Detekováno podvádění; skóre a ceny pozastaveny na ${COUNT} dní", + "Could not establish a secure connection.": "Nelze navázat bezpečné připojení.", + "Daily maximum reached.": "Dosaženo denní maximum.", + "Entering tournament...": "Vstupujete do turnaje...", + "Invalid code.": "Neplatný kód.", + "Invalid payment; purchase canceled.": "Neplatná platební maetoda; platba zrušena.", + "Invalid promo code.": "Neplatný Promo kód.", + "Invalid purchase.": "Neplatná koupě.", + "Invalid tournament entry; score will be ignored.": "Neplatný turnaj; skóre bude ignorováno.", + "Item unlocked!": "Položka odemčena!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "Propojení zamítnuto. ${ACCOUNT} obsahuje\nznačné data, které by byly ZCELA ZTRACENY.\nPokud chcete, můžete připojit účet v opačném\npořadí (a ztratit tak data TOHOTO účtu)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Chcete spojit účet ${ACCOUNT} s tímto účtem?\nVšechna data na účtě ${ACCOUNT} budou smazána.\nTuto akci nelze navrátit zpět. Jste si jisti?", + "Max number of playlists reached.": "Dosazano maximalniho počtu výpisů", + "Max number of profiles reached.": "Dosaženo maximalního počtu profilů", + "Maximum friend code rewards reached.": "Kamarádova maximální výhra na kódu.", + "Message is too long.": "Zpráva je příliš dlouhá.", + "No servers are available. Please try again soon.": "Žádné servery nejsou nyní dostupné. Zkuste to prosím později.", + "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" byl úspěšně přeměněn.", + "Profile could not be upgraded.": "Profil nelze přeměnit.", + "Purchase successful!": "Koupě se zdařila!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Získali jste ${COUNT} kupónů za přihlášení.\nVraťte se zítra, abyste jich obdrželi ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Server běží na novější verzi a tu vaši nepodporuje,\naktualizujte hru pro připojení.", + "Sorry, there are no uses remaining on this code.": "Omlouváme se, ale již zde nejsou žádné zbývající použití pro tento kód.", + "Sorry, this code has already been used.": "Omlouváme se, ale tento kód již byl použit.", + "Sorry, this code has expired.": "Omlouváme se, ale platnost tohoto kódu vypršela.", + "Sorry, this code only works for new accounts.": "Omlouváme se, ale tento kód je platný pouze pro nové účty.", + "Still searching for nearby servers; please try again soon.": "Stále se vyhledávají lokální servery; Prosím zkuste to později.", + "Temporarily unavailable; please try again later.": "Dočasně nedostupné; zkuste to později.", + "The tournament ended before you finished.": "Turnaj skončil než jste ho dokončili.", + "This account cannot be unlinked for ${NUM} days.": "Tento účet nelze odpojit po dobu ${NUM} dnů.", + "This code cannot be used on the account that created it.": "Tento kód nemůže být použit na účtu, na kterém byl vytvořen.", + "This is currently unavailable; please try again later.": "Tato možnost je momentálně nedostupná; prosím zkuste to později.", + "This requires version ${VERSION} or newer.": "Toto vyžaduje verzi ${VERSION} nebo vyšší.", + "Tournaments disabled due to rooted device.": "Turnaje nedostupné na zařízeních s rootem.", + "Tournaments require ${VERSION} or newer": "Turnaje vyžadují ${VERSION} nebo novější", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Odpojit ${ACCOUNT} od tohoto účtu?\nVeškerá data na účtě ${ACCOUNT} se resetují.\n(výjimka jsou v některých případech úspěchy)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "VAROVÁNÍ: Byla proti vám vznešena obvinění z podvádění ve hře.\nÚčty o kterých se prokáže že používají ulehčující módy budou smazány, hrajte prosím férově.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Přejete si propojit Váš účet zařízení k tomuto?\n\nÚčet vašeho zařízení je ${ACCOUNT1}\nTento účet je ${ACCOUNT2}\n\nTato akce Vám umožní zachovat si stávající postup.\nVarování: Nelze vrátit zpět!", + "You already own this!": "Toto již vlastníte!", + "You can join in ${COUNT} seconds.": "Připojit se můžete až za ${COUNT} sek.", + "You don't have enough tickets for this!": "Na toto bohužel nemáte dostatek kupónů!", + "You don't own that.": "Nevlastníte tuto věc.", + "You got ${COUNT} tickets!": "Získal jste ${COUNT} kupónů!", + "You got a ${ITEM}!": "Získaly jste ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Byli jste povýšeni do další ligy; gratulujeme!", + "You must update to a newer version of the app to do this.": "Musíš updatovat na novější verzi aplikace k udělání tohodle.", + "You must update to the newest version of the game to do this.": "Vaše verze hry tuto akci nepodporuje, aktualizujte hru na nejnovější verzi.", + "You must wait a few seconds before entering a new code.": "Před zadáním nového kódu počkejte pár sekund.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "V posledním turnaji jste se umístil na #${RANK} pozici. Děkujeme!", + "Your account was rejected. Are you signed in?": "Váš účet byl odmítnut. Jste přihlášen?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Vaše kopie hry byla pozměněna.\nVraťte prosím všechny změny a zkuste to znovu.", + "Your friend code was used by ${ACCOUNT}": "Váš kód pro přátele byl použit hráčem ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minuta", + "1 Second": "1 Sekunda", + "10 Minutes": "10 Minut", + "2 Minutes": "2 Minuty", + "2 Seconds": "2 Sekundy", + "20 Minutes": "20 Minut", + "4 Seconds": "4 Sekundy", + "5 Minutes": "5 Minut", + "8 Seconds": "8 Sekund", + "Allow Negative Scores": "Povolit negativní skóre", + "Balance Total Lives": "Rovnovážný Počet Životů", + "Bomb Spawning": "Objevení bomby", + "Chosen One Gets Gloves": "Vyvolený získal rukavice", + "Chosen One Gets Shield": "Vyvolený získal štít", + "Chosen One Time": "Čas Vyvoleného", + "Enable Impact Bombs": "Zapnout Nárazové Bomby", + "Enable Triple Bombs": "Zapnout Trojité Bomby", + "Entire Team Must Finish": "Celý tým musí skončit", + "Epic Mode": "Epický Mód", + "Flag Idle Return Time": "Čas Návratu Neaktivní Vlajky", + "Flag Touch Return Time": "Čas Návratu Dotknuté Vlajky", + "Hold Time": "Čas Držení", + "Kills to Win Per Player": "Počet Zabití pro vítězství", + "Laps": "Kola", + "Lives Per Player": "Životy na Hráče", + "Long": "Dlouhý", + "Longer": "Delší", + "Mine Spawning": "Přidávání Min", + "No Mines": "Bez Min", + "None": "Žádný", + "Normal": "Normální", + "Pro Mode": "Pro(fi) mód", + "Respawn Times": "Časy Znovuzrození", + "Score to Win": "Skóre pro Výhru", + "Short": "Krátký", + "Shorter": "Kratší", + "Solo Mode": "Sólo Mód", + "Target Count": "Počet cílů", + "Time Limit": "Časový Limit" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "Diskvalifikuji ${TEAM} tým protože ${PLAYER} opustil hru.", + "Killing ${NAME} for skipping part of the track!": "Zabíjím ${NAME} kvůli přeskočení části tratě!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Varování pro ${NAME}: Turbo / spamování tlačítek tě vyhodí" + }, + "teamNames": { + "Bad Guys": "Padouši", + "Blue": "Modrý", + "Good Guys": "Dobráci", + "Red": "Červený" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Perfektně načasovaný Běh-výskok-otočka-úder může zabít na jednu ránu\na zajistit vám doživotní respekt od vašich přátel.", + "Always remember to floss.": "Nikdy nezapomeňte na zubní nit.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Vytvořte herní profily pro Vás i Vaše přátele s Vašimi\npreferovanými jmény a vzhledy místo používání náhodně generovaných.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Prokletí vás změní v časovanou bombu.\nJediná protilátka je rychle sebrat lékárničku.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Kromě vzhledu mají všechny postavy stejné vlastnosti\ntakže si prostě vyberte toho, který se Vám nejvíc podobá.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Radši s tím štítem nebuďte moc namyšlení; pořád můžete vypadnout pryč z mapy.", + "Don't run all the time. Really. You will fall off cliffs.": "Nepobíhejte pořád. Vážně. Vypadnete z mapy.", + "Don't spin for too long; you'll become dizzy and fall.": "Netoč se moc dlouho, bude ti špatně.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Pro sprint držte jakékoliv tlačítko.(Pokuď máte ovladač, fungují i ostatní tlačítka)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Držte jakékoliv tlačítko pro sprint. Budete rychlejší.¨\nAle dávejte si pozor na okraje mapy.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ledové Bomby nejsou moc silné, ale zmrazí vše, \nčeho se dotknou, a zanechají je náchylné k rozbití.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Pokuď vás někdo chytne, udeřte ho a on vás pustí.\nTak to funguje i v reálném životě.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Pokud jste krátký na řadičích, nainstalujte '${REMOTE_APP_NAME}' app \nna svých mobilních zařízení k jejich použití jako regulátorů.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Pokuď nemáte ovladač, nainstalujte si aplikaci 'BombSquad Remote'\nna vaše druhé zařízení a používejte ho jako ovladač.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Když se k Vám přilepí Lepivá Bomba, skákejte jako diví a točte se v kruzích.\nMožná setřesete bombu, nebo, když už nic jiného, budou Vaše poslední chvilky zajímavé.", + "If you kill an enemy in one hit you get double points for it.": "Pokuď někoho zabijete na jednu ránu, dostanete dvojnásobek bodů.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Pokud seberete prokletí, vaší jedinou nadějí na přežití\nje, v následujících pár sekundách, najít lékárničku.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Pokuď budete stát na místě, bude z vás toust. Běhejte a uhýbejte abyste přežili..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jestliže máte hodně hráčů, kteří přichází a odchází, zapněte 'automatické vyhazování neaktivních hráčů'\nv nastavení, pro případ, že někdo zapomene opustit hru.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Pokud se vaše zařízení zahřívá nebo byste chtěli šetřit baterii,\nsnižte kvalitu \"Detailů\" nebo \"Rozlišení\" v Nastavení->Grafika", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Pokud se vám začne sekat obraz, zkuste si snížit\n\"Rozlišení\" nebo \"Detaily\" v Nastavení->Grafika", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "V Seberte Vlajku, Vaše vlajka musí být na vaší základně, abyste mohli skórovat.\nJestliže chce druhý tým skórovat, krádež jejich vlajky může být dobrý způsob jejich zastavení.", + "In hockey, you'll maintain more speed if you turn gradually.": "V Hokeji získáte větší rychlost, když se budete točit pomalu.", + "It's easier to win with a friend or two helping.": "Je jednodušší vyhrát když vám pomáhají přátelé.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Když během házení bomby vyskočité, bomby doletí výš a dál.", + "Land-mines are a good way to stop speedy enemies.": "Miny jsou dobré na zastavení rychlých padouchů.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Spousty věcí může být sebráno a hozeno, včetně ostatních hráčů.\nVrhání Vašich nepřátel z útesu může být efektivní a emočně naplňující strategií.", + "No, you can't get up on the ledge. You have to throw bombs.": "Ne, nemůžete lézt po římsách. Musíte házet bomby.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Hráči se mohou připojit a odpojit i v průběhu hry\na také lze během hry připojovat a odpojovat ovladače.", + "Practice using your momentum to throw bombs more accurately.": "Vyzkoušejte si přesnější házení bomb za použití Vaší kinetické energie.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Čím rychleji se pohybujete, tím větší zranění Vaše pěsti vytvoří,\ntakže zkoušejte běhat, skákat, a točit se jako šílenec.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Běhejte tam a zpět před odhozením bomby,\nabyste se rozmáchli a odhodili ji dále.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Zabijte víc padouchů tím že\ndáte bombu hned vedle TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Hlava je nezranitelnější část, takže Lepivá Bomba\nna hlavě většinou končí koncem hry.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Tento level nikdy nezkončí, ale zdejší vysoké skóre\nnaučí hráče respektovat Vás po celém světě.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Síla hodu je založena na směru který držíte.\nPro jemné odhození něčeho přímo před Vás, nedržte žádný směr.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Unavuje vás SoundTrack? Nastavte si svůj vlastní!\nNastavení->Zvuk->Soundtrack", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Zkuste bomby chvilku držet před tím než je hodíte.", + "Try tricking enemies into killing eachother or running off cliffs.": "Obelstěte padouchy, aby se zabili navzájem nebo vypadli pryč z mapy.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Na sebrání vlajky použijte < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Švihněte sebou dozadu a dopředu abyste bombu dohodily dál..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Můžete 'mířit' svoje údery točením se doleva nebo doprava.\nJe to užitečné pro shazování padouchů z hran nebo skórování v hokeji.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Můžete usoudit kdy se bomba chystá vybouchnout podle\nbarvy jisker z její rozbušky: žlutá..oranžová..červená..BUM.", + "You can throw bombs higher if you jump just before throwing.": "Můžete bomby házet výš když vyskočíte těsně před hodem.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Když se o něco bouchnete hlavou.. můžete se zranit\ntak bych to být Vámi nezkoušel.", + "Your punches do much more damage if you are running or spinning.": "Pokuď se točíte nebo běžíte tak vaše údery budou silnější." + } + }, + "trophiesRequiredText": "To vyžaduje minimálně ${NUMBER} trofeje.", + "trophiesText": "- Trofeje", + "trophiesThisSeasonText": "Trofeje tuto sezónu", + "tutorial": { + "cpuBenchmarkText": "Spuštění tutorialu ve směšné rychlosti (testuje hlavně rychlost CPU)", + "phrase01Text": "Ahoj, ty tam!", + "phrase02Text": "Vítejte v ${APP_NAME}u!", + "phrase03Text": "Tady máte pár tipů jak ovládat postavu:", + "phrase04Text": "Většina věcí v ${APP_NAME}u je založena na fyzice.", + "phrase05Text": "Například, když někoho udeříte,...", + "phrase06Text": "..záleží na tom jak rychlá je vaše pěst.", + "phrase07Text": "Vidíte? Nehýbal jsem se, takže to ${NAME}e sotva bolelo.", + "phrase08Text": "Teď výskok a otočka pro větší rychlost.", + "phrase09Text": "Ha, to je lepší.", + "phrase10Text": "Běh taky pomáhá.", + "phrase11Text": "Pro běh držte JAKÉKOLIV tlačítko.", + "phrase12Text": "Pro super údery, zkuste běh a otočku.", + "phrase13Text": "Ježiš, to jsem nechtěl ${NAME}i.", + "phrase14Text": "Některé věci můžete chytit a hodit. Třeba vlajky.. nebo ${NAME}e.", + "phrase15Text": "A to nejlepší, jsou tu bomby.", + "phrase16Text": "Naučit se házet bomby zabere čas.", + "phrase17Text": "Jau! To nebyl moc dobrý hod.", + "phrase18Text": "Pohyb vám pomůže dohodit dál.", + "phrase19Text": "Skákání vám pomůže házet výš.", + "phrase20Text": "Pro ještě větší vzdálenost zkuste malou otočku.", + "phrase21Text": "Správné načasovaní je dost užitečné.", + "phrase22Text": "Krucipísek.", + "phrase23Text": "Zkuste si s hodem počkat vteřinku nebo dvě.", + "phrase24Text": "Hurá! Dokonale načasováno.", + "phrase25Text": "Nu, to bude asi všechno.", + "phrase26Text": "Teď běž, tygře!!!", + "phrase27Text": "Pamatuj na trénink, a určitě se vrátíš živý!", + "phrase28Text": "...teda, možná...", + "phrase29Text": "Přeji hodně štěstí!", + "randomName1Text": "Lukáš", + "randomName2Text": "Marek", + "randomName3Text": "Daniel", + "randomName4Text": "Matěj", + "randomName5Text": "Pepa", + "skipConfirmText": "Opravdu chcete přeskočit Tutorial? Klikněte pro potvrzení.", + "skipVoteCountText": "${COUNT}/${TOTAL} přeskočení", + "skippingText": "Přeskakuji Tutorial...", + "toSkipPressAnythingText": "(Stistkni cokoli pro přeskočení Tutorialu)" + }, + "twoKillText": "DVĚ ZABITÍ!!!", + "unavailableText": "Nedostupné", + "unconfiguredControllerDetectedText": "Zaznamenán nenakonfigurovaný ovladač:", + "unlockThisInTheStoreText": "Toto musí být nejdříve odemknuto v obchodě.", + "unlockThisProfilesText": "Pro vytvoření více než ${NUM} profilů, potřebuješ:", + "unlockThisText": "Pro odemknutí tohoto je zapotřebí:", + "unsupportedHardwareText": "Omlouváme se, ale tento hardware není porporován tímto buildem hry.", + "upFirstText": "První:", + "upNextText": "Další, ${COUNT}. hra bude:", + "updatingAccountText": "Aktualizuji Váš účet...", + "upgradeText": "Přeměnit", + "upgradeToPlayText": "Upgradujte na \"${PRO}\" v herním obchodě, abyste toto mohli hrát.", + "useDefaultText": "Použít Výchozí", + "usesExternalControllerText": "Tato hra používá jako vstup externí ovladač.", + "usingItunesText": "Používám Music App pro soundtrack", + "usingItunesTurnRepeatAndShuffleOnText": "Ujistěte se prosím, že je zaplý shuffle, a opakovat VŠE v iTunes,", + "v2AccountLinkingInfoText": "Pro propojení V2 účtů, stiskněte tlačítko 'Spravovat Účet'", + "validatingTestBuildText": "Ověřuji Testovací Build...", + "victoryText": "Vítězství!!!", + "voteDelayText": "Nelze spustit další hlas za ${NUMBER} sekund", + "voteInProgressText": "Hlasování již probíhá.", + "votedAlreadyText": "Již jste hlasoval", + "votesNeededText": "${NUMBER} hlasů potřebných", + "vsText": "vs.", + "waitingForHostText": "(čeká se na ${HOST})", + "waitingForPlayersText": "Čeká se na jiného hráče...", + "waitingInLineText": "Čekání ve frontě (parta plná)", + "watchAVideoText": "Zkoukni reklamu", + "watchAnAdText": "Zkouknout Reklamu", + "watchWindow": { + "deleteConfirmText": "Vymazat \"${REPLAY}\"?", + "deleteReplayButtonText": "Vymazat\nZáznam", + "myReplaysText": "Moje záznamy", + "noReplaySelectedErrorText": "Nevybrán žádný záznam", + "playbackSpeedText": "Rychlost přehrávání: ${SPEED}", + "renameReplayButtonText": "Přejmenovat\nZáznam", + "renameReplayText": "Přejmenovat \"${REPLAY}\" na:", + "renameText": "Přejmenovat", + "replayDeleteErrorText": "Chyba při mazání záznamu.", + "replayNameText": "Jméno Záznamu", + "replayRenameErrorAlreadyExistsText": "Záznam s tímto jménem již existuje.", + "replayRenameErrorInvalidName": "Nelze přejmenovat; chybné jméno.", + "replayRenameErrorText": "Chyba při přejmenování záznamu.", + "sharedReplaysText": "Sdílené Záznamy", + "titleText": "Záznamy", + "watchReplayButtonText": "Shlédnout\nZáznam" + }, + "waveText": "Vlna", + "wellSureText": "Nuže dobrá!", + "whatIsThisText": "Co je tohle?", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Hledám Wiimotes...", + "pressText": "Stiskněte současně Tlačítka Wiimote 1 a 2.", + "pressText2": "Na novějších Wiimote ovladačích s vestavěným Motion Plus stiskněte červené 'synchroznizační' tlačítko v zadní části." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "listenText": "Poslouchat", + "macInstructionsText": "Ujistěte se, že je Vaše Wii vyplé a Bluetooth je na vašem\nMac zařízení zaplý, a poté stistkněte 'Poslouchat'. Podpora\nWiimote může být trochu horší, a možná bude potřeba to párkrát\nzkusit, než se Vám podaří ho připojit.\n\nZařízení Bluetooth dokáže mít připojených až 7 zařízení,\nale to se může lišit\n\nBombSquad podporuje originální Wiimote, Nunchuk,\na klasický ovladač\nNovější Wii Remote Plus nyní funguje také,\nale bez přídavků.", + "thanksText": "Děkujeme týmu DarwiinRemote,\nže tohle uskutečnili.", + "titleText": "Nastavení Wiimote" + }, + "winsPlayerText": "${NAME} Vyhrál!", + "winsTeamText": "${NAME} Vyhrál!", + "winsText": "${NAME} Vyhrál!", + "workspaceSyncErrorText": "Chyba synchronizace ${WORKSPACE}. Podrobnosti v logu.", + "workspaceSyncReuseText": "Nelze synchronizovat ${WORKSPACE}. Opětovné použití předchozí synchronizované verze.", + "worldScoresUnavailableText": "Světové skóre nepřístupné.", + "worldsBestScoresText": "Světové nejlepší skóre", + "worldsBestTimesText": "Světové nejlepší časy", + "xbox360ControllersWindow": { + "getDriverText": "Získat Driver", + "macInstructions2Text": "Pro bezdrátové použití ovladače také potřebujete příjmač, který\nje součástí 'Xbox 360 Wireless Controller for Windows'.\nJeden příjmač dovoluje připojit až 4 zařízení.\n\nDůležité: příjmače třetích stran s tímto driverem nebudou fungovat;\nujistěte se, že je na Vašem příjmači 'Microsoft' a ne 'XBOX 360'.\nMicrosoft už tyto příjmače neprodává samostatně, takže budete muset\njeden koupit s ovladačem dohromady, nebo hledat na ebay.\n\nJestliže je pro Vás toto užitečné, zvažte prosím přispění \ntvůrci driveru na jeho stránce.", + "macInstructionsText": "Pro použití ovladače Xbox 360, potřebujete nainstalovat\nMac Driver který naleznete na odkazu napsaném níže.\nFunguje s drátovou i s bezdrátovou verzí ovladače.", + "ouyaInstructionsText": "Pro použití kabelových Xbox 360 ovladačů pro BombSquad, je jednoduše\npřipojte do USB portu vašeho zařízení. Můžete použít USB hub\npro připojení více ovladačů.\n\nPro použití bezdrátových ovladačů budete potřebovat bezdrátový příjmač,\ndostupný jako součást \"Xbox 360 wirelles Controller for Windows\"\nbalíčku nebo prodávaného samostatně. Každý příjmač zapojíte do USB portu\na každý z nich Vám dovolí připojit až 4 bezdrátové ovladače.", + "titleText": "Hrát ${APP_NAME} s ovladačem Xbox 360:" + }, + "yesAllowText": "Ano, Povolit!", + "yourBestScoresText": "Vaše nejlepší skóre", + "yourBestTimesText": "Váš nejlepší čas" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/danish.json b/dist/ba_data/data/languages/danish.json new file mode 100644 index 0000000..0a31603 --- /dev/null +++ b/dist/ba_data/data/languages/danish.json @@ -0,0 +1,1626 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Konto navne kan ikke indeholde emojis eller andre specielle bogstaver", + "accountProfileText": "(bruger profil)", + "accountsText": "Konti", + "achievementProgressText": "Achievements: ${COUNT} ud af ${TOTAL}", + "campaignProgressText": "Kampagneforløb ${PROGRESS}", + "changeOncePerSeason": "Du kan kun ændre dette en gang pr. sæson", + "changeOncePerSeasonError": "Du må vente indtil næste sæson for at ændre dette igen (${NUM} days)", + "customName": "Brugerdefineret Navn", + "linkAccountsEnterCodeText": "Indtast kode", + "linkAccountsGenerateCodeText": "Generér kode", + "linkAccountsInfoText": "(del forløb på tværs af platforme)", + "linkAccountsInstructionsNewText": "For at forbinde to kontoer, generer en kode på den første\nog skriv den kode på den anden. Dataen fra den anden konto\nvil så blive delt mellem dem begge.\n(Dataen fra den første konto vil blive tabt)\n\nDu kan forbinde op til ${COUNT} kontoer.\n\nVIGTIGT: forbind kun kontoer som du ejer;\nHvis du forbinder med din vens konto vil du ikke\nkunne spille online på samme tid som ham.", + "linkAccountsInstructionsText": "For at forbinde to konti, opret en kode på en\naf dem og indtast den kode på den anden.\nFremskridt og inventar vil blive kombineret.\nDu kan forbinde op til ${COUNT} konti.\n\nVIGTIGT: Kun forbinde konti som du ejer!\nHvis du forbinder konti med dine venner\nvil i ikke kunne spille samtidigt!\n\nPlus: dette kan ikke endu fortrydes, så vær forsigtig!", + "linkAccountsText": "Forbind konti", + "linkedAccountsText": "Forbundne konti:", + "nameChangeConfirm": "Ændre dit konto navn til ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Dette vil nulstille dit co-op forløb og dine\nlokale high-scores (men ikke dine tickets).\nDette kan ikke fortrydes. Er du sikker?", + "resetProgressConfirmText": "Dette vil nulstille dine co-op fremskridt,\nachievements og lokale highschores. \n(men ikke dine tickets). Dette kan ikke \ngøres om. Er du sikker?", + "resetProgressText": "Nulstil Process", + "setAccountName": "Indstil kontonavn", + "setAccountNameDesc": "Vælg navnet du vil vise til din konto.\nDu kan bruge navnet fra en af dine forbundne\nkontoer eller lave et unikt brugerdefineret navn.", + "signInInfoText": "Log in for at optjene tickets, konkurrere online \nog dele dit forløb på tværs af enheder.", + "signInText": "Log Ind", + "signInWithDeviceInfoText": "(en automatisk oprettet konto kun tilgængelig fra denne enhed)", + "signInWithDeviceText": "Log in med en enheds-konto.", + "signInWithGameCircleText": "Log in med Game Circle", + "signInWithGooglePlayText": "Log in med Google Play", + "signInWithTestAccountInfoText": "(ældre kontotype; brug enheds-konti fremover)", + "signInWithTestAccountText": "Log in med test konto", + "signOutText": "Log ud", + "signingInText": "Logger ind...", + "signingOutText": "Logger ud...", + "testAccountWarningOculusText": "Advarsel: Du logger ind med en \"test\" bruger. \nDette ville blive erstattet med \"rigtige\" brugere senere i dette \når, hvilket vil tilbyde ticket (billet) købsmuligheder og andre funktioner.\n\nindtilvidere skal du tjene alle dine tickets in-game.\n(Du får dog BombSquad Pro upgrade helt gratis!)", + "testAccountWarningText": "Advarsel: Du logger nu ind med en \"test\" bruger.\nDenne bruger er bunden med en bestemt enhed og\nkan risikere at blive nulstillet periodisk. (så lad vær\nmed at brug lang tid på at samle/oplåse ting til den)\n\nKør en detailversion af spillet for at bruge en \"rigtig\"\nbruger (Game-Center, Google Plus, osv.) Dette giver\ndig også mulighed for at gemme dine fremskridt i\nskyen og dele det mellem forskellige enheder.", + "ticketsText": "Tickets (biletter): ${COUNT}", + "titleText": "Din bruger", + "unlinkAccountsInstructionsText": "Vælg en konto at adskille", + "unlinkAccountsText": "Adskil kontoer", + "viaAccount": "(via konto ${NAME})", + "youAreLoggedInAsText": "Du er logget ind som: ", + "youAreSignedInAsText": "Du er logget ind som:" + }, + "achievementChallengesText": "Achievementudfordringer", + "achievementText": "Achievement", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Dræb 3 fjender med dynamit", + "descriptionComplete": "Du dræbte 3 fjender med dynamit", + "descriptionFull": "Dræb 3 fjender med dynamit i ${LEVEL}", + "descriptionFullComplete": "Du dræbte 3 fjender med dynamit i ${LEVEL}", + "name": "”Boom”, sagde dynamitten" + }, + "Boxer": { + "description": "Vind uden at bruge nogen bomber", + "descriptionComplete": "Du vandt uden at bruge nogen bomber", + "descriptionFull": "Gennemfør ${LEVEL} uden at bruge nogen bomber", + "descriptionFullComplete": "Du gennemførte ${LEVEL} uden at bruge nogen bomber", + "name": "Bokser" + }, + "Dual Wielding": { + "descriptionFull": "Forbind 2 kontrollere (hardware eller app)", + "descriptionFullComplete": "2 kontrollere forbundet (hardware eller app)", + "name": "Dobbelt-båren" + }, + "Flawless Victory": { + "description": "Vind uden at blive ramt", + "descriptionComplete": "Du vandt uden at blive ramt", + "descriptionFull": "Vind ${LEVEL} uden at blive ramt", + "descriptionFullComplete": "Du vandt ${LEVEL} uden at blive ramt", + "name": "Fejlfri sejr" + }, + "Free Loader": { + "descriptionFull": "Start et Free-For-All spil med 2+ spillere.", + "descriptionFullComplete": "Startede et Free-For-All spil med 2+ spillere", + "name": "Gratist" + }, + "Gold Miner": { + "description": "Dræb 6 fjender med miner", + "descriptionComplete": "Du dræbte 6 fjender med miner", + "descriptionFull": "Dræb 6 fjender med miner i ${LEVEL}", + "descriptionFullComplete": "Du dræbte 6 fjender med miner i ${LEVEL}", + "name": "Guldgraver" + }, + "Got the Moves": { + "description": "Vind uden at slå eller bruge bomber", + "descriptionComplete": "Du vandt uden at slå eller bruge bomber", + "descriptionFull": "Vind ${LEVEL} uden at slå eller bruge bomber", + "descriptionFullComplete": "Du vandt ${LEVEL} uden at slå eller bruge bomber", + "name": "Styr på trinene" + }, + "In Control": { + "descriptionFull": "Forbind en controller (hardware eller app)", + "descriptionFullComplete": "Forbind en controller. (hardware eller app)", + "name": "Under Kontrol" + }, + "Last Stand God": { + "description": "Scor 1000 point", + "descriptionComplete": "Du scorede 1000 point", + "descriptionFull": "Score 1000 point i ${LEVEL}", + "descriptionFullComplete": "Du scorede 1000 point i ${LEVEL}", + "name": "Gud i ${LEVEL}" + }, + "Last Stand Master": { + "description": "Scor 250 point", + "descriptionComplete": "Du scorede 250 point", + "descriptionFull": "Scor 250 point i ${LEVEL}", + "descriptionFullComplete": "Du scorede 250 point i ${LEVEL}", + "name": "Mester i ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Scor 500 point", + "descriptionComplete": "Du scorede 500 point", + "descriptionFull": "Scor 500 point i ${LEVEL}", + "descriptionFullComplete": "Du scorede 500 point i ${LEVEL}", + "name": "Troldmand i ${LEVEL}" + }, + "Mine Games": { + "description": "Dræb 3 fjender med miner", + "descriptionComplete": "Du dræbte 3 fjender med miner", + "descriptionFull": "Dræb 3 fjender med miner i ${LEVEL}", + "descriptionFullComplete": "Du dræbte 3 fjender med miner i ${LEVEL}", + "name": "Minespil" + }, + "Off You Go Then": { + "description": "Kast 3 fjender ud af banen", + "descriptionComplete": "Kastede 3 fjender ud af banen", + "descriptionFull": "Kast 3 fjender af banen i ${LEVEL}", + "descriptionFullComplete": "Du kastede 3 fjender af banen i ${LEVEL}", + "name": "Afsted med dig" + }, + "Onslaught God": { + "description": "Scor 5000 point", + "descriptionComplete": "Du scorede 5000 point", + "descriptionFull": "Scor 5000 point i ${LEVEL}", + "descriptionFullComplete": "Du scorede 5000 point i ${LEVEL}", + "name": "Gud i ${LEVEL}" + }, + "Onslaught Master": { + "description": "Scor 5000 point", + "descriptionComplete": "Du scorede 500 point", + "descriptionFull": "Scor 500 point i ${LEVEL}", + "descriptionFullComplete": "Du scorede 500 point i ${LEVEL}", + "name": "Mester i ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Besejr alle bølgerne", + "descriptionComplete": "Du besejrede alle bølgerne", + "descriptionFull": "Besejr alle bølgerne i ${LEVEL}", + "descriptionFullComplete": "Du besejrede alle bølgerne i ${LEVEL}", + "name": "Sejr i ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Scor 1000 point", + "descriptionComplete": "Du scorede 1000 point", + "descriptionFull": "Scor 1000 point i ${LEVEL}", + "descriptionFullComplete": "Du scorede 1000 point i ${LEVEL}", + "name": "Troldmand i ${LEVEL}" + }, + "Precision Bombing": { + "description": "Vind uden at bruge nogen powerups", + "descriptionComplete": "Du vandt uden at bruge nogen powerups", + "descriptionFull": "Vind ${LEVEL} uden at bruge nogen powerups", + "descriptionFullComplete": "Du vandt ${LEVEL} uden at bruge nogen powerups", + "name": "Præcisionsbombning" + }, + "Pro Boxer": { + "description": "Vind uden at bruge nogen bomber", + "descriptionComplete": "Du vandt uden at bruge nogen bomber", + "descriptionFull": "Gennemfør ${LEVEL} uden at bruge nogen bomber", + "descriptionFullComplete": "Du gennemførte ${LEVEL} uden at bruge nogen bomber", + "name": "Professionel bokser" + }, + "Pro Football Shutout": { + "description": "Vind uden at lade fjenderne score", + "descriptionComplete": "Du vandt uden at lade fjenderne score", + "descriptionFull": "Vind ${LEVEL} uden at lade fjenderne score", + "descriptionFullComplete": "Du vandt ${LEVEL} uden at lade fjenderne score", + "name": "Straffespark i ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Vind kampen", + "descriptionComplete": "Du vandt kampen", + "descriptionFull": "Vind kampen i ${LEVEL}", + "descriptionFullComplete": "Du vandt kampen i ${LEVEL}", + "name": "Sejr i ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Besejr alle bølger", + "descriptionComplete": "Du besejrede alle bølger", + "descriptionFull": "Besejr alle bølger i ${LEVEL}", + "descriptionFullComplete": "Du besejrede alle bølger af ${LEVEL}", + "name": "Sejr i ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Gennemfør alle bølger", + "descriptionComplete": "Du gennemførte alle bølger", + "descriptionFull": "Gennemfør alle bølger i ${LEVEL}", + "descriptionFullComplete": "Du gennemførte alle bølger i ${LEVEL}", + "name": "Sejr i ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Vind uden at fjenderne scorer", + "descriptionComplete": "Du vandt uden at fjenderne scorede", + "descriptionFull": "Vind ${LEVEL} uden at fjenderne scorer", + "descriptionFullComplete": "Du vandt ${LEVEL} uden at fjenderne scorede", + "name": "Straffespark i ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Vind kampen", + "descriptionComplete": "Du vandt kampen", + "descriptionFull": "Vind kampen i ${LEVEL}", + "descriptionFullComplete": "Du vandt kampen i ${LEVEL}", + "name": "Sejr i ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Besejr alle bølger", + "descriptionComplete": "Du besejrede alle bølger", + "descriptionFull": "Besejr alle bølger i ${LEVEL}", + "descriptionFullComplete": "Du besejrede alle bølger i ${LEVEL}", + "name": "Sejr i ${LEVEL}" + }, + "Runaround God": { + "description": "Scor 2000 point", + "descriptionComplete": "Du scorede 2000 point", + "descriptionFull": "Scor 2000 point i ${LEVEL}", + "descriptionFullComplete": "Du scorede 2000 point i ${LEVEL}", + "name": "Gud i ${LEVEL}" + }, + "Runaround Master": { + "description": "Scor 500 point", + "descriptionComplete": "Du scorede 500 point", + "descriptionFull": "Scor 500 point i ${LEVEL}", + "descriptionFullComplete": "Du scorede 500 point i ${LEVEL}", + "name": "Mester i ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Scor 1000 point", + "descriptionComplete": "Du scorede 1000 point", + "descriptionFull": "Scor 1000 point i ${LEVEL}", + "descriptionFullComplete": "Du scorede 1000 point i ${LEVEL}", + "name": "Troldmand i ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Del spillet med en ven", + "descriptionFullComplete": "Har delt spillet med en ven", + "name": "Sharing is Caring" + }, + "Stayin' Alive": { + "description": "Vind uden at dø", + "descriptionComplete": "Du vandt uden at dø", + "descriptionFull": "Vind ${LEVEL} uden at dø", + "descriptionFullComplete": "Du vandt ${LEVEL} uden at dø", + "name": "Forbliv i live" + }, + "Super Mega Punch": { + "description": "Giv 100% skade med ét slag", + "descriptionComplete": "Du gav 100% skade med ét slag", + "descriptionFull": "Giv 100% skade med ét slag i ${LEVEL}", + "descriptionFullComplete": "Du gav 100% skade med ét slag i ${LEVEL}", + "name": "Super Mega Slag" + }, + "Super Punch": { + "description": "Giv 50% skade med ét slag", + "descriptionComplete": "Du gav 50% skade med ét slag", + "descriptionFull": "Giv 50% skade med ét slag i ${LEVEL}", + "descriptionFullComplete": "Du gav 50% skade med ét slag i ${LEVEL}", + "name": "Super slag" + }, + "TNT Terror": { + "description": "Dræb 6 fjender med TNT", + "descriptionComplete": "Du dræbte 6 fjender med TNT", + "descriptionFull": "Dræb 6 fjender med TNT i ${LEVEL}", + "descriptionFullComplete": "Du dræbte 6 fjender med TNT i ${LEVEL}", + "name": "TNT-terror" + }, + "Team Player": { + "descriptionFull": "Start et Hold spil med mere end 4 spillere", + "descriptionFullComplete": "Startede et Hold spil med mere end 4 spillere", + "name": "Hold Spiller" + }, + "The Great Wall": { + "description": "Stop hver eneste fjende", + "descriptionComplete": "Du stoppede hver eneste fjende", + "descriptionFull": "Stop hver eneste fjende i ${LEVEL}", + "descriptionFullComplete": "Du stoppede hver eneste fjende i ${LEVEL}", + "name": "Den Store Mur" + }, + "The Wall": { + "description": "Stop hver eneste fjende", + "descriptionComplete": "Du stoppede hver eneste fjende", + "descriptionFull": "Stop hver eneste fjende i ${LEVEL}", + "descriptionFullComplete": "Du stoppede hver eneste fjende i ${LEVEL}", + "name": "Muren" + }, + "Uber Football Shutout": { + "description": "Vind uden at fjenderne scorer", + "descriptionComplete": "Du vandt uden at fjenden scorede", + "descriptionFull": "Vind ${LEVEL} uden at fjenden scorer", + "descriptionFullComplete": "Du vandt ${LEVEL} uden at fjenden scorede", + "name": "Straffespark i ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Vind kampen", + "descriptionComplete": "Du vandt kampen", + "descriptionFull": "Vind kampen i ${LEVEL}", + "descriptionFullComplete": "Du vandt kampen i ${LEVEL}", + "name": "Sejr i ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Besejr alle bølger", + "descriptionComplete": "Du besejrede alle bølger", + "descriptionFull": "Besejr alle bølger i ${LEVEL}", + "descriptionFullComplete": "Du gennemførte alle bølger i ${LEVEL}", + "name": "Sejr i ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Gennemfør alle bølger", + "descriptionComplete": "Du gennemførte alle bølger", + "descriptionFull": "Gennemfør alle bølger i ${LEVEL}", + "descriptionFullComplete": "Du gennemførte alle bølger i ${LEVEL}", + "name": "Sejr i ${LEVEL}" + } + }, + "achievementsRemainingText": "Achievements tilbage:", + "achievementsText": "Achievements", + "achievementsUnavailableForOldSeasonsText": "Beklager, det er ikke muligt at se detaljer for tidligere sæsoner.", + "addGameWindow": { + "getMoreGamesText": "Få Flere Spil...", + "titleText": "Tilføj spil" + }, + "allowText": "Tillad", + "alreadySignedInText": "Din konto er logget ind fra en anden enhed;\nvær sød at skifte konto eller luk spillet ned på\ndine andre enheder og prøv igen", + "apiVersionErrorText": "Kan ikke indlæse ${NAME}; det er målrettet api-version ${VERSION_USED}; vi behøver ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(Sætter kun dette til automatisk når høretelefoner er sat i)", + "headRelativeVRAudioText": "Head-Relative VR Audio", + "musicVolumeText": "Musiklydstyrke", + "soundVolumeText": "Lydstyrke", + "soundtrackButtonText": "Lydspor", + "soundtrackDescriptionText": "(Afspil din egen musik, mens du spiller)", + "titleText": "Lyd" + }, + "autoText": "Auto", + "backText": "Tilbage", + "banThisPlayerText": "Ban denne spiller", + "bestOfFinalText": "Bedst ud af ${COUNT} finale", + "bestOfSeriesText": "Bedst ud af ${COUNT}:", + "bestRankText": "Dine bedste er #${RANK}", + "bestRatingText": "Din bedste vurdering er ${RATING}", + "betaErrorText": "Denne beta er ikke længere aktiv; tjek venligst om der er en ny version tilgængelig", + "betaValidateErrorText": "Ude af stand til til at validere beta. Har du tjekket din internetforbindelse?", + "betaValidatedText": "Beta valideret; Nyd den!", + "bombBoldText": "BOMB", + "bombText": "Bomb", + "boostText": "Boost", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} konfigureres i selve app'en.", + "buttonText": "Knap", + "canWeDebugText": "Er det okay at BombSquad automatisk rapporterer fejl, \ncrashes og generelt brug til udvikleren?\n\nDenne data indeholder ingen personlige informationer og hjælper med \nat få spillet til at kører flydende og uden fejl.", + "cancelText": "Annuller", + "cantConfigureDeviceText": "Undskyld, ${DEVICE} kan ikke konfigureres.", + "challengeEndedText": "Udfordringen er afsluttet.", + "chatMuteText": "Slå chat fra", + "chatMutedText": "Chat fra", + "chatUnMuteText": "Slå chat til", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Du bliver nødt til at gennemføre\ndette level for at fortsætte!", + "completionBonusText": "Gennemføringsbonus", + "configControllersWindow": { + "configureControllersText": "Konfigurer Controllers", + "configureGamepadsText": "Konfigurér Gamepads", + "configureKeyboard2Text": "Konfigurér Tastatur P2", + "configureKeyboardText": "Konfigurér Tastatur", + "configureMobileText": "Mobilenheder som Controllers", + "configureTouchText": "Konfigurér touchskærm", + "ps3Text": "PS3-controllere", + "titleText": "Controllere", + "wiimotesText": "Wiimotes", + "xbox360Text": "Xbox 360-controllere" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Bemærk: Controllersupport varierer fra enhed til enhed og Android-version.", + "pressAnyButtonText": "Tryk på en hvilkårlig knap på controller\nsom du gerne vil konfigurere.", + "titleText": "Konfigurér Controllers" + }, + "configGamepadWindow": { + "advancedText": "Avanceret", + "advancedTitleText": "Avanceret Controllersetup", + "analogStickDeadZoneDescriptionText": "(Skru dette op, hvis din spiller 'drifter' efter du har sluppet pinden)", + "analogStickDeadZoneText": "Den analoge pinds dødszone", + "appliesToAllText": "(gælder alle controllers af denne type)", + "autoRecalibrateDescriptionText": "(Aktivér dette, hvis din spiller ikke bevæger sig med fuld hastighed)", + "autoRecalibrateText": "Re-kalibrer automatisk den analoge pind", + "axisText": "akse", + "clearText": "Ryd", + "dpadText": "dpad", + "extraStartButtonText": "Ekstra startknap", + "ifNothingHappensTryAnalogText": "Hvis intet sker, så prøv det analoge stik i stedet.", + "ifNothingHappensTryDpadText": "Hvis intet sker, så prøv d-pad'en i stedet.", + "ignoreCompletelyDescriptionText": "(forhindrer denne kontroller i at påvirke spillet eller menuerne)", + "ignoreCompletelyText": "Ignorer Fuldstændigt", + "ignoredButton1Text": "Ignoreret knap 1", + "ignoredButton2Text": "Ignoreret knap 2", + "ignoredButton3Text": "Ignoreret knap 3", + "ignoredButton4Text": "Ignoreret Knap 4", + "ignoredButtonDescriptionText": "(Brug denne for at undgå 'hjem'- eller 'sync'-knapperne påvirker UI'en)", + "ignoredButtonText": "Ignorerede knapper", + "pressAnyAnalogTriggerText": "Tryk på hvilken som helst analog udløser...", + "pressAnyButtonOrDpadText": "Tryk på hvilken som helst knap eller dpad...", + "pressAnyButtonText": "Tryk på hvilken som helst knap...", + "pressLeftRightText": "Tryk venstre eller højre...", + "pressUpDownText": "Tryk op eller ned...", + "runButton1Text": "Løbeknap 1", + "runButton2Text": "Løbeknap 2", + "runTrigger1Text": "Løbeudløser 1", + "runTrigger2Text": "Løbeudløser 2", + "runTriggerDescriptionText": "(analoge udløserere lader dig løbe i forskellige hastigheder)", + "secondHalfText": "Brug denne til at konfigurere den anden\ndel af en 2-i-1-enhed, som\nviser sig som en enkelt gamepad.", + "secondaryEnableText": "Aktivér", + "secondaryText": "Sekundær Controller", + "startButtonActivatesDefaultDescriptionText": "(sluk denne, hvis din 'start'-knap fungerer mere som en 'menu'-knap)", + "startButtonActivatesDefaultText": "Startknap aktiverer standard widget", + "titleText": "Controllersetup", + "twoInOneSetupText": "2-i-1 controllersetup", + "uiOnlyDescriptionText": "(forhindre, at denne controller deltager i et spil)", + "uiOnlyText": "Begræns til Menu Brug", + "unassignedButtonsRunText": "Alle knapper, der ikke er i brug, bruges som løbeknap", + "unsetText": "", + "vrReorientButtonText": "VR Positionsnulstillings Knap" + }, + "configKeyboardWindow": { + "configuringText": "Konfigurerer ${DEVICE}", + "keyboard2NoteScale": 0.7, + "keyboard2NoteText": "Bemærk: De fleste tastaturer kan kun registrere nogle få tryk\nad gangen, så det er en god idé at have et ekstra\ntastatur. Bemærk, at du stadig skal registrere unikke\nknapfunktioner til de to spillere." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Action kontrol vægt", + "actionsText": "Handlinger", + "buttonsText": "knapper", + "dragControlsText": "< træk styringerne for at replacere dem >", + "joystickText": "joystick", + "movementControlScaleText": "Bevægelseskontrol vægt", + "movementText": "Bevægelse", + "resetText": "Nulstil", + "swipeControlsHiddenText": "Gem 'swipe' ikoner.", + "swipeInfoText": "'Swipe'-kontrol tager lidt tid at vænne sig til, men\ndet gør det lettere at spille uden at kigge på knapperne.", + "swipeText": "swipe", + "titleText": "Konfigurér touchskærm", + "touchControlsScaleText": "Skala ift. berøringsstyring" + }, + "configureItNowText": "Konfigurér den nu?", + "configureText": "Konfigurér", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsScale": 0.65, + "bestResultsText": "For at få de bedste resultater skal du bruge et lag-frit wifi-netværk.\nDu kan reducere wifi-lag ved at slukke for andre trådløse enheder,\nved at spille tæt ved din wifi-router og ved at forbinde spilværten\ndirekte til netværket via internet.", + "explanationScale": 0.8, + "explanationText": "For at bruge en smartphone eller tablet som en trådløs controller,\nskal du installere app'en \"${REMOTE_APP_NAME}\". Et utal af enheder\nkan forbinde til et ${APP_NAME} spil via WiFi, og det er helt gratis!", + "forAndroidText": "til Android:", + "forIOSText": "til iOS:", + "getItForText": "Få ${REMOTE_APP_NAME} til iOS i Apple App Store eller til\nAndroid på Google Play Store eller Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Mobile enheder som controllers:" + }, + "continuePurchaseText": "Fortsæt for ${PRICE}?", + "continueText": "Fortsæt", + "controlsText": "Styring", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Nem mindenki Joshua", + "activenessInfoText": "Denne multiplikator siger på dage hvor du\nspiller og falder på dage hvor du ikke spiller.", + "activityText": "Aktivitet", + "campaignText": "Kampagne", + "challengesInfoText": "Tjen præmier ved at gennemføre mini-games.\n\nPræmier og vanskelighedniveauer stiger \nhver gang en udfordring er gennemført og\nfalder når én udløber eller er annuleret.", + "challengesText": "Udfordringer", + "currentBestText": "Nuværende bedste", + "customText": "Brugerdefineret", + "entryFeeText": "Entré", + "forfeitConfirmText": "Opgiv denne udfordring?", + "forfeitNotAllowedYetText": "Denne udfordring kan ikke opgives endnu.", + "forfeitText": "Opgiv", + "multipliersText": "Multiplikatorer", + "nextChallengeText": "Næste udfordring", + "nextPlayText": "Næste spil", + "ofTotalTimeText": "ud af ${TOTAL}", + "playNowText": "Spil nu", + "pointsText": "Point", + "powerRankingFinishedSeasonUnrankedText": "(færdiggjorde sæson urangeret)", + "powerRankingNotInTopText": "(ikke i top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} point", + "powerRankingPointsMultText": "(x ${NUMBER} point)", + "powerRankingPointsText": "${NUMBER} point", + "powerRankingPointsToRankedText": "(${CURRENT} ud af ${REMAINING} point)", + "powerRankingText": "Power Rangering", + "prizesText": "Priser", + "proMultInfoText": "Spillere med en ${PRO} opgradering\nfår ${PERCENT}% point boost her", + "seeMoreText": "Flere...", + "skipWaitText": "Skip at vente", + "timeRemainingText": "Tid tilbage", + "titleText": "Co-op", + "toRankedText": "Til rangeret", + "totalText": "i alt", + "tournamentInfoText": "Konkurrer efter high scores med\nandre spillere i din liga.\n\nPræmier er tildelt til de top scorende\nspillere når turneringens tid er udløbet.", + "welcome1Text": "Velkommen til ${LEAGUE}. Du kan forbedre din\nliga rang ved at indtjene stjerne bedømmelser, klare\npræstationer og vinde trofæer i turneringer.", + "welcome2Text": "Du kan også vinde billetter fra mange af de samme aktiviteter.\nBilletter kan blive brugt til oplåsning af nye spilkarakterer, baner, og\nmini-games, at komme ind i turneringer, og meget mere.", + "yourPowerRankingText": "Din Power Rangering" + }, + "copyOfText": "${NAME} kopi", + "copyText": "Kopier", + "copyrightText": "© 2013 Eric Froemling", + "createAPlayerProfileText": "Opret en spillerprofil?", + "createEditPlayerText": "", + "createText": "Opret", + "creditsWindow": { + "additionalAudioArtIdeasText": "Ekstra lyd, tidlige illustrationer og idéer af ${NAME}", + "additionalMusicFromText": "Ekstra musik fra ${NAME}", + "allMyFamilyText": "Alle mine venner og familie, der hjalp med at spilteste", + "codingGraphicsAudioText": "Kodning, grafik og lyd af ${NAME}", + "languageTranslationsText": "Sprogoversættelse:", + "legalText": "Juridisk:", + "publicDomainMusicViaText": "Offentlig ejendomsmusik via ${NAME}", + "softwareBasedOnText": "Denne software er delvist baseret på arbejde udført af ${NAME}", + "songCreditText": "${TITLE} Sunget af ${PERFORMER}\nKomponeret af ${COMPOSER}, Arrangeret af ${ARRANGER}, udgivet af ${PUBLISHER},\nVenligst stillet til rådighed af ${SOURCE}", + "soundAndMusicText": "Lyd & Musik:", + "soundsText": "Lyde (${SOURCE}):", + "specialThanksText": "Specielt tak til:", + "thanksEspeciallyToText": "Specielt tak til ${NAME}", + "titleText": "${APP_NAME} Credits", + "whoeverInventedCoffeeText": "Den person, der opfandt kaffe" + }, + "currentStandingText": "Din nuværende placering er #${RANK}", + "customizeText": "Tilpas...", + "deathsTallyText": "Antal gange død: ${COUNT}", + "deathsText": "Antal gange død", + "debugText": "debug", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Obs: Det anbefales at du sætter Indstillinger->Grafik-> Teksturer til 'høj' når du tester dette.", + "runCPUBenchmarkText": "Kør CPU Benchmark", + "runGPUBenchmarkText": "Kør GPU Benchmark", + "runMediaReloadBenchmarkText": "Kør Media-Reload Benchmark", + "runStressTestText": "Kør stresstest", + "stressTestPlayerCountText": "Antal spillere", + "stressTestPlaylistDescriptionText": "Stresstest playliste", + "stressTestPlaylistNameText": "Navn på playliste", + "stressTestPlaylistTypeText": "Playlistens type", + "stressTestRoundDurationText": "Varighed af runde", + "stressTestTitleText": "Stresstest", + "titleText": "Benchmark- og stresstests", + "totalReloadTimeText": "Totale genindlæsningstid: ${TIME} (se log for detaljer)", + "unlockCoopText": "Åbn co-op levels" + }, + "defaultFreeForAllGameListNameText": "Standard alle mod alle-spil", + "defaultGameListNameText": "Standard ${PLAYMODE} spilleliste", + "defaultNewFreeForAllGameListNameText": "Mine alle mod alle-spil", + "defaultNewGameListNameText": "Min ${PLAYMODE} playliste", + "defaultNewTeamGameListNameText": "Mine holdspil", + "defaultTeamGameListNameText": "Standard holdspil", + "deleteText": "Slet", + "demoText": "Demo", + "denyText": "Afvis", + "desktopResText": "Computeropløsning", + "difficultyEasyText": "Nemt", + "difficultyHardOnlyText": "Svær niveautilstand udelukkende", + "difficultyHardText": "Svær", + "difficultyHardUnlockOnlyText": "Dette niveau kan kun blive oplåst på svært niveautilstand.\nTror du at du har hvad der skal til!?!?!?", + "directBrowserToURLText": "Henvis venligst en web-browser til den følgende URL:", + "disableRemoteAppConnectionsText": "Deaktiver Remote-App forbindelser", + "disableXInputDescriptionText": "Tillader mere end 4 kontrollere men måske virker det ikke", + "disableXInputText": "Deaktiver XInput", + "doneText": "Færdig", + "drawText": "Uafgjort", + "duplicateText": "Dupliker", + "editGameListWindow": { + "addGameText": "Tilføj spil", + "cantOverwriteDefaultText": "Kan ikke overskrive standard spilliste!", + "cantSaveAlreadyExistsText": "En spilleliste med det navn eksisterer allerede!", + "cantSaveEmptyListText": "En tom spilleliste kan ikke gemmes!", + "editGameText": "Rediger\nspil", + "gameListText": "Spilliste", + "listNameText": "Spillelistens navn", + "nameText": "Navn", + "removeGameText": "Fjern\nspil", + "saveText": "Gem liste", + "titleText": "Spilleliste editor" + }, + "editProfileWindow": { + "accountProfileInfoText": "Denne specielle profil har et navn\nog et ikon baseret på din konto\n\n${ICONS}\n\nLav brugdefinerede profiler for at bruge\nforskellige navne og brugerdefinerede ikoner.", + "accountProfileText": "(konto profil)", + "availableText": "Dette navn \"${NAME}\" er ledigt.", + "changesNotAffectText": "Bemærk: ændringer vil ikke have nogen indvirkning på spillere, som allerede er i spil.", + "characterText": "karakter", + "checkingAvailabilityText": "Checker muligheden for \"${NAME}\"...", + "colorText": "farve", + "getMoreCharactersText": "Få flere karakterer...", + "getMoreIconsText": "Få flere ikoner...", + "globalProfileInfoText": "Globale spillerprofiler er garanteret til at have unikke\nnavne verden over. Det samme gælder brugerdefinerede ikoner.", + "globalProfileText": "(global profil)", + "highlightText": "fremhæv", + "iconText": "ikon", + "localProfileInfoText": "Lokale spillerprofiler har ikke ikoner og deres navne er\nikke garanteret til at være unikke. Opgrader til en global profil\nfor at reservere dit unikke navn og tilføje et brugerdefineret ikon.", + "localProfileText": "(lokal profil)", + "nameDescriptionText": "Spillernavn", + "nameText": "Navn", + "randomText": "tilfældig", + "titleEditText": "Rediger profil", + "titleNewText": "Ny profil", + "unavailableText": "\"${NAME}\" er ikke ledigt; prøv et andet navn.", + "upgradeProfileInfoText": "Dette vil reservere dit spillernavn i hele verden\nog tillade dig at tildele et brugerdefineret ikon til det.", + "upgradeToGlobalProfileText": "Opgrader til Global Profil" + }, + "editProfilesAnyTimeText": "(du kan redigere profiler på hvilket som helst tidspunkt under 'indstillinger')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Du kan ikke slette standard lydspor.", + "cantEditDefaultText": "Kan ikke redigere standard lydspor. Kopier den eller lav en ny.", + "cantOverwriteDefaultText": "Kan ikke overskrive standard lydspor", + "cantSaveAlreadyExistsText": "Et lydspor med det navn eksisterer allerede!", + "copyText": "Kopier", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Standard lydspor", + "deleteConfirmText": "Slet Lydspor:\n\n'${NAME}'?", + "deleteText": "Slet\nLydspor", + "duplicateText": "Dupliker\nLydspor", + "editSoundtrackText": "Lydspor Editor", + "editText": "Rediger\nLydspor", + "fetchingITunesText": "Henter iTunes spilleliste...", + "musicVolumeZeroWarning": "Advarsel: Din lydstyrke i spillet er sat til 0", + "nameText": "Navn", + "newSoundtrackNameText": "Mit lydspor ${COUNT}", + "newSoundtrackText": "Nyt lydspor:", + "newText": "Nyt\nLydspor", + "selectAPlaylistText": "Vælg en spilleliste", + "selectASourceText": "Musikkilde", + "soundtrackText": "Lydspor", + "testText": "Hør", + "titleText": "Lydspor", + "useDefaultGameMusicText": "Standard spilmusik", + "useITunesPlaylistText": "iTunesplayliste", + "useMusicFileText": "Musikfil (mp3 osv)", + "useMusicFolderText": "Mappe med musikfiler" + }, + "editText": "Rediger", + "endText": "Afslut", + "enjoyText": "God fornøjelse!", + "epicDescriptionFilterText": "${DESCRIPTION} i imponerende slowmotion.", + "epicNameFilterText": "Imponerende ${NAME}", + "errorAccessDeniedText": "Adgang nægtet", + "errorOutOfDiskSpaceText": "ikke nok disk plads", + "errorText": "Fejl", + "errorUnknownText": "ukendt fejl", + "exitGameText": "Afslut ${APP_NAME}?", + "exportSuccessText": "'${NAME}' eksporteret.", + "externalStorageText": "Ekstern lagring", + "failText": "Du tabte", + "fatalErrorText": "Uh åh; noget mangler eller er i stykker.\nVær venlig og geninstaller appen eller\nkontakt ${EMAIL} for hjælp.", + "fileSelectorWindow": { + "titleFileFolderText": "Vælg en fil eller mappe", + "titleFileText": "Vælg en fil", + "titleFolderText": "Vælg en mappe", + "useThisFolderButtonText": "Brug denne mappe" + }, + "finalScoreText": "Endelig score", + "finalScoresText": "Endelige scorer", + "finalTimeText": "Endelig tid", + "finishingInstallText": "Afslutter installationen; et øjeblik...", + "fireTVRemoteWarningText": "* For at få den bedste oplevelse, brug \nspilkontrollere eller installer\n'${REMOTE_APP_NAME}' appen på din \ntelefon eller tablet.", + "firstToFinalText": "Først til ${COUNT} – Finale", + "firstToSeriesText": "Første til ${COUNT}", + "fiveKillText": "FEM DRAB!!!!", + "flawlessWaveText": "Fejlfri bølge!", + "fourKillText": "FIREDOBBELT DRAB!!!!", + "freeForAllText": "Alle mod alle", + "friendScoresUnavailableText": "Dine venners scorer er utilgængelige.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Stilling efter ${COUNT}. spil:", + "gameListWindow": { + "cantDeleteDefaultText": "Du kan ikke slette standard spilliste!", + "cantEditDefaultText": "Kan ikke redigere i standardspillisten! Dupliker den eller lav en ny.", + "cantShareDefaultText": "Du kan ikke dele den standard spilliste.", + "deleteConfirmText": "Slet \"${LIST}\"?", + "deleteText": "Slet\nSpilliste", + "duplicateText": "Dupliker\nSpilliste", + "editText": "Rediger\nSpilliste", + "gameListText": "Spilliste", + "newText": "Ny\nSpilliste", + "showTutorialText": "Vis tutorial", + "shuffleGameOrderText": "Bland rækkefølgen", + "titleText": "Tilpas ${TYPE} Spillister" + }, + "gameSettingsWindow": { + "addGameText": "Tilføj spil" + }, + "gamepadDetectedText": "1 gamepad registreret", + "gamepadsDetectedText": "${COUNT} gamepads registreret.", + "gamesToText": "${WINCOUNT} til ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Husk: alle enheder i en gruppe kan have mere\nend en spiller hvis du har nok kontrollere.", + "aboutDescriptionText": "Brug disse faner for at samle en gruppe.\n\nGrupper lader dig spille spil og turneringer\nmed dine venner gennem forskellige enheder.\n\nBrug ${PARTY} knappen øverst til højre for\nat chatte og interagere med din gruppe.\n(på en kontroller, pres ${BUTTON} når du er i menuen)", + "aboutText": "Om", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} sendte dig ${COUNT} billetter i ${APP_NAME}", + "appInviteSendACodeText": "Send dem en kode", + "appInviteTitleText": "${APP_NAME} App Inviter", + "bluetoothAndroidSupportText": "(virker med alle android enheder, som supporter Bluetooth)", + "bluetoothDescriptionText": "Lav/deltag en gruppe over Bluetooth:", + "bluetoothHostText": "Lav en gruppe over Bluetooth", + "bluetoothJoinText": "Deltag over Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "kontrollerer...", + "dedicatedServerInfoText": "For de bedste resultater, lav en dedikeret server. Se bombsquadgame.com/server for at lære hvordan.", + "disconnectClientsText": "Dette vil koble ${COUNT} spiller(e) fra\ndin gruppe. Er du sikker?", + "earnTicketsForRecommendingAmountText": "Venner vil modtage ${COUNT} billetter hvis de prøver spillet\n(og du vil modtage ${YOU_COUNT} for hver, som gør)", + "earnTicketsForRecommendingText": "Del spiller\nfor gratis billetter...", + "emailItText": "Email det", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} billetter fra ${NAME}", + "friendPromoCodeAwardText": "Du vil modtage ${COUNT} billetter hver gang det bliver brugt.", + "friendPromoCodeExpireText": "Denne kode vil udløbe om ${EXPIRE_HOURS} timer og vil kun virke for nye spillere.", + "friendPromoCodeInstructionsText": "For at bruge det, åben ${APP_NAME} og gå ind i \"Indstillinger->Avanceret->Indtast Kode\".\nSe bombsquadgame.com for downloadlinks til alle understøttede platforme.", + "friendPromoCodeRedeemLongText": "Det kan blive indløst for ${COUNT} gratis billetter for op til ${MAX_USES} personer.", + "friendPromoCodeRedeemShortText": "Det kan blive indløst for ${COUNT} billetter i spillet.", + "friendPromoCodeWhereToEnterText": "(i \"Indstillinger->Avanceret->Indtast Kode\")", + "getFriendInviteCodeText": "Få invitationskode til venner", + "googlePlayDescriptionText": "Inviter Google Play spillere til din gruppe:", + "googlePlayInviteText": "Inviter", + "googlePlayReInviteText": "Der er ${COUNT} Google Play spiller(e) i din gruppe\nsom vil blive koblet fra hvis du starter en ny invitation.\nInkluder dem i den nye invitation for at få dem tilbage.", + "googlePlaySeeInvitesText": "Se inviterede", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play version)", + "hostPublicPartyDescriptionText": "Lav en offentlig gruppe:", + "inDevelopmentWarningText": "Note:\n\nNetværksspil er en ny og stadig udviklende funktion.\nFor nu, anbefales det stærkt, at alle\nspillere er på det samme WiFi-netværk.", + "internetText": "Internet", + "inviteAFriendText": "Venner har ikke spillet? Inviter de til at\nprøve det og så modtager de ${COUNT} gratis billetter.", + "inviteFriendsText": "Inviter venner", + "joinPublicPartyDescriptionText": "Deltag i en offentlig gruppe:", + "localNetworkDescriptionText": "Deltag i en gruppe på dit netværk:", + "localNetworkText": "Lokalt netværk", + "makePartyPrivateText": "Gør min gruppe privat", + "makePartyPublicText": "Gør min gruppe offentlig", + "manualAddressText": "Adresse", + "manualConnectText": "Opret forbindelse", + "manualDescriptionText": "Deltag i en gruppe på en adresse:", + "manualJoinableFromInternetText": "Kan du deltage via internettet?:", + "manualJoinableNoWithAsteriskText": "NEJ*", + "manualJoinableYesText": "JA", + "manualRouterForwardingText": "*For at løse dette, prøv at konfigurere din router til at videresende UDP-port ${PORT} til din lokale adresse", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Din adresse fra internettet:", + "manualYourLocalAddressText": "Din lokale adresse:", + "noConnectionText": "", + "otherVersionsText": "(andre versioner)", + "partyInviteAcceptText": "Accepter", + "partyInviteDeclineText": "Afvis", + "partyInviteGooglePlayExtraText": "(Se 'Google Play' fanen i 'Saml' vinduet)", + "partyInviteIgnoreText": "Ignorer", + "partyInviteText": "${NAME} har inviteret\ndig til at deltage i deres gruppe!", + "partyNameText": "Gruppe navn", + "partySizeText": "gruppe størrelse", + "partyStatusCheckingText": "kontrollerer status...", + "partyStatusJoinableText": "din gruppe kan nu tilsluttes fra internettet", + "partyStatusNoConnectionText": "kunne ikke forbinde til serveren", + "partyStatusNotJoinableText": "din gruppe kan ikke tilsluttes fra internettet", + "partyStatusNotPublicText": "din gruppe er ikke offentlig", + "pingText": "ping", + "portText": "Port", + "requestingAPromoCodeText": "Anmoder om kode...", + "sendDirectInvitesText": "Send direkte invitationer", + "shareThisCodeWithFriendsText": "Del denne kode med dine venner:", + "showMyAddressText": "Vis min adresse", + "titleText": "Saml", + "wifiDirectDescriptionBottomText": "Hvis alle enheder har et 'WiFi Direkte' panel, skulle de være i stand til at bruge det til at finde\nog forbinde til hinanden. Når alle enheder er tilsluttet, kan du danne grupper\nher ved hjælp af fanen 'Lokalt netværk', præcis på samme måde som med et almindeligt WiFi-netværk.\n\nFor de bedste resultater skal WiFi Direct værten også være ${APP_NAME} gruppeværten.", + "wifiDirectDescriptionTopText": "WiFi Direkte kan bruges til at forbinde Android-enheder direkte uden\nbrug for et WiFi-netværk. Dette fungerer bedst på Android 4.2 eller nyere.\n\nFor at bruge det skal du åbne WiFi-indstillingerne og kigge efter 'WiFi Direkte' i menuen.", + "wifiDirectOpenWiFiSettingsText": "Åben WiFi indstillinger", + "wifiDirectText": "WiFi Direkte", + "worksBetweenAllPlatformsText": "(virker imellem alle platforme)", + "worksWithGooglePlayDevicesText": "(fungerer med enheder, der kører Google Play (Android) versionen af ​​spillet)", + "youHaveBeenSentAPromoCodeText": "Du har modtaget en ${APP_NAME} promoveringskode:" + }, + "getCoinsWindow": { + "coinDoublerText": "Coinfordobler", + "coinsText": "${COUNT} coins", + "freeCoinsText": "Gratis coins", + "restorePurchasesText": "Genskab køb", + "titleText": "Få coins" + }, + "getTicketsWindow": { + "freeText": "GRATIS!", + "freeTicketsText": "Gratis billetter", + "inProgressText": "En transaktion er igang; vær venlig at prøve igen om lidt.", + "purchasesRestoredText": "Køb gendannet.", + "receivedTicketsText": "Modtog ${COUNT} billetter!", + "restorePurchasesText": "Gendan køb", + "ticketPack1Text": "Lille billetpakke", + "ticketPack2Text": "Mellem billetpakke", + "ticketPack3Text": "Stor billetpakke", + "ticketPack4Text": "Jumbo billetpakke", + "ticketPack5Text": "Mammut billetpakke", + "ticketPack6Text": "Ultimativ billetpakke", + "ticketsFromASponsorText": "Få ${COUNT} billetter\nfra en sponsor", + "ticketsText": "${COUNT} billetter", + "titleText": "Få billetter", + "unavailableLinkAccountText": "Beklager, køb er ikke tilgængeligt på denne platform.\nSom en løsning kan du forbinde denne konto til en anden konto på\nen anden platform og foretage købene der.", + "unavailableTemporarilyText": "Dette er i øjeblikket ikke tilgængeligt; prøv igen senere.", + "unavailableText": "Beklager, dette er ikke muligt.", + "versionTooOldText": "Beklager, denne version af spillet er for gammelt; vær venlig at opdatere til en nyere.", + "youHaveShortText": "Du har ${COUNT}", + "youHaveText": "du har ${COUNT} billetter" + }, + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Altid", + "fullScreenCmdText": "Fuld skærm (Cmd-F)", + "fullScreenCtrlText": "Fuld skærm (Ctrl-F)", + "gammaText": "Gamma", + "highText": "Høj", + "higherText": "Højere", + "lowText": "Lav", + "mediumText": "Mellem", + "neverText": "Aldrig", + "resolutionText": "Opløsning", + "showFPSText": "Vis FPS", + "texturesText": "Teksturer", + "titleText": "Grafik", + "tvBorderText": "TV-grænse", + "verticalSyncText": "Vertikal synkronisering", + "visualsText": "Visuals" + }, + "helpWindow": { + "bombInfoText": "- Bombe -\nStærkere end slag men den kan\nresultere i stor skade på dig selv.\nFor at få det bedste resultat kast bomben\nmod fjenden, før lunten løber ud.", + "bombInfoTextScale": 0.6, + "canHelpText": "${APP_NAME} kan hjælpe.", + "controllersInfoText": "Du kan spille ${APP_NAME} med venner over et netværk eller I\nkan alle spille på den samme enhed, hvis du har nok kontrollere.\n${APP_NAME} understøtter en række af dem; du kan endda bruge telefoner\nsom kontrollere via den gratis '${REMOTE_APP_NAME}' app.\nSe Indstillinger->Kontrollere for mere information.", + "controllersInfoTextFantasia": "BombSquad understøtter de fleste USB- og Bluetooth-gamepads ligesom xBox 360-controllere\nDu kan også bruge iOS/Android-enheder som controllere via den gratis \"BombSquad Remote\" app.\nSe \"Controllere\" under \"Indstillinger\" for mere info.", + "controllersInfoTextMac": "En eller to spillere kan bruge tastaturet, men Bombsquad er bedst med gamepads. \nBombSquad kan bruge USB-gamepads, PS3-controllere, xBox 360-controllere,\nWiimotes og iOS/Android-enheder til at spille med. Forhåbentlig har du en af disse.\nSe 'Controllere' under 'Indstillinger' for mere info.", + "controllersInfoTextOuya": "Du kan bruge OUYA-controllere, PS3-controllere, xBox 360-controllere,\nog mange andre USB- og Bluetooth-gamepads med BombSquad.\nDu kan også bruge iOS/Android-enheder som controllere via den gratis\n\"BombSquad Remote\" app. Se 'Controllere' under 'Indstillinger' for mere info.", + "controllersText": "Controllere", + "controllersTextScale": 0.67, + "controlsSubtitleText": "Din venlige ${APP_NAME} karakter har nogle få grundlæggende handlinger:", + "controlsSubtitleTextScale": 0.7, + "controlsText": "Styring", + "controlsTextScale": 1.4, + "devicesInfoText": "VR-versionen af ${APP_NAME} kan spilles over netværket med\nden almindelige version, så pisk dine ekstra telefoner, tablets,\nog computere frem og få dit spil igang. Det kan endda være nyttigt at\ntilslutte en almindelig version af spillet til VR-versionen bare for at\ntillade folk udefra at se handlingen.", + "devicesText": "Enheder", + "friendsGoodText": "Disse er gode at have. ${APP_NAME} er sjovest at spille med flere spillere,\nog det understøtter op til 8 spillere ad gangen, hvilket leder os til:", + "friendsGoodTextScale": 0.62, + "friendsText": "Venner", + "friendsTextScale": 0.67, + "jumpInfoText": "- Hop -\nHop over små huller,\nfor at kaste ting højere, og \nfor at vise, når du er glad.", + "jumpInfoTextScale": 0.6, + "orPunchingSomethingExtraSpace": 0, + "orPunchingSomethingText": "Eller slå noget, kaste det ud over en kløft, og sprænge det i luften med en klister bombe.", + "pickUpInfoText": "- Saml op -\nLøft flag, fjender og alt andet,\nder ikke er fæstnet til jorden.\nTryk igen for at kaste.", + "pickUpInfoTextScale": 0.6, + "powerupBombDescriptionText": "Lader dig kaste tre bomber\ni streg i stedet for kun en", + "powerupBombNameText": "Tredobbeltbombe", + "powerupCurseDescriptionText": "Du vil nok gerne undgå dem her.\n … eller vil du?", + "powerupCurseNameText": "Forbandelse", + "powerupHealthDescriptionText": "Giver dig fuldt liv.\nDet havde du aldrig gættet.", + "powerupHealthNameText": "Medicin", + "powerupIceBombsDescriptionText": "Svagere end normale bomber\nmen efterlader dine fjender frosne\nog skøre.", + "powerupIceBombsNameText": "Isbomber", + "powerupImpactBombsDescriptionText": "En smule svagere end normale bomber\nmen eksploderer, når de rør noget.", + "powerupImpactBombsNameText": "Berøringsbomber", + "powerupLandMinesDescriptionText": "De kommer i pakker af 3; \nNyttige til forsvar eller \nfor at stoppe hurtige fjender.", + "powerupLandMinesNameText": "Miner", + "powerupPunchDescriptionText": "Får dig til at flå hårdere, hurtigere, bedre og stærkere.", + "powerupPunchNameText": "Boksehandsker", + "powerupShieldDescriptionText": "Tager noget af skaden så du ikke tager den.", + "powerupShieldNameText": "Energiskjold", + "powerupStickyBombsDescriptionText": "Klistrer til alt de rammer.\nMunterhed følger.", + "powerupStickyBombsNameText": "Klisterbombe", + "powerupsSubtitleText": "Selvfølgelig er der intet spil uden powerups:", + "powerupsSubtitleTextScale": 0.8, + "powerupsText": "Powerups", + "powerupsTextScale": 1.4, + "punchInfoText": "- Slag -\nSlag gør mere skade, jo\nhurtigere du løber, Så løb\nog slå som en gal.", + "punchInfoTextScale": 0.6, + "runInfoText": "- Spurt -\nHold hvilken som helst knap nede. Udløselsesknapper virker godt, hvis du har dem. Spurt gør så \ndu bevæger dig hurtigere, men det gør det også sværere at dreje, så hold øje med skrænter.", + "runInfoTextScale": 0.6, + "someDaysExtraSpace": 0, + "someDaysText": "Nogle dage har du bare lyst til at slå noget. Eller at sprænge noget i luften.", + "titleText": "${APP_NAME} hjælp", + "toGetTheMostText": "For at få mest ud af spillet skal du bruge:", + "toGetTheMostTextScale": 1.0, + "welcomeText": "Velkommen til ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} navigerer i menuer som en boss -", + "importPlaylistCodeInstructionsText": "Brug den følgende kode for at importere denne spilliste til andre steder:", + "importPlaylistSuccessText": "Importerede ${TYPE} spilliste '${NAME}'", + "importText": "Importer", + "importingText": "Importerer...", + "inGameClippedNameText": "i spillet bliver det\n\"${NAME}\"", + "installDiskSpaceErrorText": "FEJL: Kan ikke gennemføre installationen.\nDu er måske tom for plads på din enhed.\nRyd noget plads og prøv igen.", + "internal": { + "arrowsToExitListText": "Tryk på ${LEFT} eller ${RIGHT} for afslutte liste", + "buttonText": "knap", + "cantKickHostError": "Du kan ikke smide værten ud.", + "chatBlockedText": "${NAME} er chatblokeret i ${TIME} sekunder.", + "connectedToGameText": "'${NAME}' deltog", + "connectedToPartyText": "Deltog ${NAME}'s gruppe!", + "connectingToPartyText": "Tilslutter...", + "connectionFailedHostAlreadyInPartyText": "Tilslutning fejlede; værten er i en anden gruppe.", + "connectionFailedPartyFullText": "Tilslutningen fejlede; gruppen er fuld.", + "connectionFailedText": "Tilslutningen fejlede.", + "connectionFailedVersionMismatchText": "Tilslutningen fejlede; værten kører på en anden version af spillet.\nVære sikker på, at I begge er opdaterede og prøv igen.", + "connectionRejectedText": "Forbindelsen er afvist.", + "controllerConnectedText": "${CONTROLLER} forbundet.", + "controllerDetectedText": "1 kontroller opdaget.", + "controllerDisconnectedText": "${CONTROLLER} afbrudt.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} afbrudt. Prøv venligst igen.", + "controllerForMenusOnlyText": "Denne kontroller kan ikke bruges til at spille; kun til at navigere i menuer.", + "controllerReconnectedText": "${CONTROLLER} blev forbundet igen.", + "controllersConnectedText": "${COUNT} kontrollere tilsluttet.", + "controllersDetectedText": "${COUNT} kontrollere opdaget.", + "controllersDisconnectedText": "${COUNT} kontrollere koblet fra.", + "corruptFileText": "Korrupt(e) fil(er) opdaget. Prøv at geninstallere eller email ${EMAIL}", + "errorPlayingMusicText": "Fejl ved afspilningen af ${MUSIC}", + "errorResettingAchievementsText": "Ude af stand til at nulstille online achievements; prøv venligst igen senere.", + "hasMenuControlText": "${NAME} har menu kontrollen.", + "incompatibleNewerVersionHostText": "Værten kører en nyere version af spillet.\nOpdater til den seneste version og prøv igen.", + "incompatibleVersionHostText": "Værten kører en anden version af spillet.\nVær sikker på, at I begge er opdateret og prøv igen.", + "incompatibleVersionPlayerText": "${NAME} kører på en anden version af spillet.\nVære sikker på, at I begge er opdateret og prøv igen.", + "invalidAddressErrorText": "Fejl: ugyldig adresse.", + "invalidNameErrorText": "Fejl: ugyldigt navn", + "invalidPortErrorText": "Fejl ugyldig port.", + "invitationSentText": "Invitation sendt.", + "invitationsSentText": "${COUNT} invitationer sendt.", + "joinedPartyInstructionsText": "Nogen har tilsluttet sig din gruppe.\nGå til 'Spil' for at starte spillet.", + "keyboardText": "Tastatur", + "kickIdlePlayersKickedText": "${NAME} blev smidt ud på grund af inaktivitet.", + "kickIdlePlayersWarning1Text": "${NAME} vil blive smidt ud om ${COUNT} sekunder, hvis inaktiviteten fortsætter.", + "kickIdlePlayersWarning2Text": "(du kan slå dette fra under 'Indstillinger' -> 'Avanceret')", + "leftGameText": "'${NAME}' forlod.", + "leftPartyText": "Forlod ${NAME}'s gruppe.", + "noMusicFilesInFolderText": "Mappen indeholder ingen musikfiler.", + "playerJoinedPartyText": "${NAME} tilsluttede sig gruppen!", + "playerLeftPartyText": "${NAME} forlod gruppen.", + "rejectingInviteAlreadyInPartyText": "Afviser invitation (allerede i en gruppe).", + "serverRestartingText": "GENSTARTER. Vær venlig at tilslutte dig igen om lidt.", + "signInErrorText": "Fejl ved login.", + "signInNoConnectionText": "Kan ikke logge ind. (ingen internetforbindelse?)", + "teamNameText": "Hold ${NAME}", + "telnetAccessDeniedText": "FEJL: bruger har ikke givet telnetadgang.", + "timeOutText": "(timeouter om ${TIME} sekunder)", + "touchScreenJoinWarningText": "Du er forbundet med touchskærm.\nHvis det var en fejl, tryk 'Menu->Forlad spil' med det.", + "touchScreenText": "Touchskærm", + "trialText": "prøveversion", + "unableToResolveHostText": "Fejl: kunne ikke finde vært.", + "willTimeOutText": "(timeouter hvis inaktiv)" + }, + "jumpBoldText": "HOP", + "jumpText": "Hop", + "keepText": "Behold", + "keepTheseSettingsText": "Behold disse indstillinger?", + "killsTallyText": "${COUNT} drab", + "killsText": "Drab", + "languageSetText": "Sproget et nu sat til ${LANGUAGE}.\nBemærk: eksisterende UI-elementer bliver måske ikke påvirket.", + "lapNumberText": "Omgang ${CURRENT}/${TOTAL}", + "lastGamesText": "(sidste ${COUNT} spil)", + "leaderboardsText": "Ranglister", + "levelFastestTimesText": "Hurtigste tider på ${LEVEL}", + "levelHighestScoresText": "Højeste scorer på ${LEVEL}", + "levelIsLockedText": "${LEVEL} er låst.", + "levelMustBeCompletedFirstText": "${LEVEL} skal gennemføres først.", + "levelUnlockedText": "Level låst op!", + "livesBonusText": "Livbonus", + "loadingText": "Indlæser", + "mainMenu": { + "creditsText": "Credits", + "endGameText": "Afslut spil", + "exitGameText": "Afslut spil", + "exitToMenuText": "Afslut, og gå til menuen?", + "howToPlayText": "Hvordan spiller man?", + "leaveText": "Forlad", + "quitText": "Afslut", + "resumeText": "Genoptag", + "settingsText": "Indstillinger" + }, + "makeItSoText": "Lav det sådan", + "mapSelectText": "Vælg...", + "mapSelectTitleText": "${GAME}-baner", + "mapText": "Bane", + "mostValuablePlayerText": "Mest værdifulde Spiller", + "mostViolatedPlayerText": "Mest forvoldte Spiller", + "mostViolentPlayerText": "Mest voldelige Spiller", + "moveText": "Bevæg", + "multiKillText": "${COUNT}-DRAB!!!", + "multiPlayerCountText": "${COUNT} spillere", + "nameBetrayedText": "${NAME} forrådte ${VICTIM}.", + "nameDiedText": "${NAME} døde.", + "nameKilledText": "${NAME} dræbte ${VICTIM}.", + "nameNotEmptyText": "Navn kan ikke være tomt!", + "nameScoresText": "${NAME} scorede!", + "nameSuicideKidFriendlyText": "${NAME} døde ved et uheld.", + "nameSuicideText": "${NAME} begik selvmord.", + "newPersonalBestText": "Ny personlig rekord!", + "newTestBuildAvailableText": "En ny testversion er tilgængelig! (${VERSION} build ${BUILD}).\nFå den på ${ADDRESS}", + "newVersionAvailableText": "En nyere version af BombSquad er tilgængelig (${VERSION})", + "nextLevelText": "Næste level", + "noAchievementsRemainingText": "- ingen", + "noExternalStorageErrorText": "Ingen ekstern lagringsenhed fundet på denne enhed.", + "noGameCircleText": "Fejl: ikke logget ind i GameCircle", + "noJoinCoopMidwayText": "Man kan ikke tilslutte co-op spil midtvejs.", + "noProfilesErrorText": "Du har ingen spillerprofiler, så du kan kun bruge '${NAME}'.\nGå til 'Indstillinger' -> 'Spillerprofiler' for at lave dig selv en profil.", + "noThanksText": "Nej tak", + "noValidMapsErrorText": "Ingen gyldige baner fundet for denne spiltype.", + "notNowText": "Ikke nu", + "nothingIsSelectedErrorText": "Ingen valgt", + "offText": "Slukket", + "okText": "Ok", + "onText": "Tændt", + "onslaughtRespawnText": "${PLAYER} vil blive rejst fra de døde i bølge ${WAVE}", + "orText": "${A} eller ${B}", + "outOfText": "(#${RANK} ud af ${ALL})", + "ownFlagAtYourBaseWarning": "Dit eget flag skal være\ni din base for at score!", + "perfectWaveText": "Perfekt bølge!", + "pickUpBoldText": "SAML OP", + "pickUpText": "Saml op", + "playText": "Spil", + "playWindow": { + "coopText": "Co-op", + "freeForAllText": "Alle mod alle", + "oneToFourPlayersText": "1-4 spillere", + "teamsText": "Hold", + "titleText": "Spil", + "twoToEightPlayersText": "2-8 spillere" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerLeftText": "${PLAYER} forlod spillet.", + "playerLimitReachedText": "Spillergrænsen på ${COUNT} er nået; der må ikke tilslutte flere.", + "playerProfilesWindow": { + "deleteButtonText": "Slet", + "deleteConfirmText": "Slet '${PROFILE}'?", + "editButtonText": "Rediger", + "newButtonText": "Ny", + "titleText": "Spillerprofiler" + }, + "playerText": "Spiller", + "playlistNotFoundText": "Playliste ikke fundet", + "pleaseRateText": "Hvis du synes, BombSquad er sjovt, så vær venlig at vurder det eller skriv en anmeldelse.\nDette giver mig nyttig feedback og hjælper med at støtte\nfremtidig udvikling.\n\nTak!\n-Eric (Udvikler)", + "pressAnyButtonPlayAgainText": "Tryk på hvilken som helst knap for at spille igen...", + "pressAnyButtonText": "Tryk hvilken som helst knap for at fortsætte...", + "pressAnyButtonToJoinText": "Tryk på hvilken som helst knap for at deltage...", + "pressAnyKeyButtonPlayAgainText": "Tryk på hvilken som helst tast/knap for at spille igen...", + "pressAnyKeyButtonText": "Tryk på hvilken som helst tast/knap for at fortsætte..", + "pressAnyKeyText": "Tryk på hvilken som helst knap...", + "pressJumpToFlyText": "** Tryk gentagne gange på hop for at flyve **", + "pressPunchToJoinText": "SLÅ for at deltage...", + "pressToOverrideCharacterText": "tryk ${BUTTONS} for at overskrive bruger", + "pressToSelectProfileText": "tryk ${BUTTONS} for at vælge profil", + "pressToSelectTeamText": "tryk ${BUTTONS} for at vælge hold", + "profileInfoText": "Opret profiler for dig selv og dine venner for at\nredigere dine navne, brugere og farver.", + "promoCodeWindow": { + "codeText": "Kode", + "codeTextDescription": "Kampagnekode", + "enterText": "Enter" + }, + "promoSubmitErrorText": "Fejl ved indsendelse af kampagnekode; tjek din internetforbindelse", + "ps3ControllersWindow": { + "macInstructionsText": "Sluk for strømmen bag på din PS3, og sørg for at Bluetooth er\nslået til på din Mac. Forbind herefter din controller til din Mac\nvia et USB-kabel for at parre dem. De efterfølgende gange kan\ndu bruge controllerens home-knap til at forbinde din Mac med\nenten USB-kabel eller en trådløs Bluetooth-forbindelse.\n\nPå nogle Macs skal du muligvis bruge en kode for at parre dem.\nHvis dette sker, så følg denne guide eller Google efter hjælp.\n\n\n\n\nPS3-controllers, der er forbundet trådløst, burde kunne ses på enhedslisten i\n'Indstillinger' -> 'Bluetooth'. Du skal muligvis fjerne dem fra den liste,\nnår du vil bruge dem med din PS3 igen.\n\nSørg også for at frakoble dem fra Bluetooth, når du ikke bruger dem.\nHvis du ikke gør dette, vil dine batterier fortsat blive drænet.\n\nBluetooth burde kunne håndtere op til 7 forbundne enheder, men\nderes ydeevne kan variere.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "For at bruge din PS3-controller med din OUYA skal du bare forbinde den med\net USB-kabel en enkelt gang for at parre dem. At gøre dette kan resultere i\nfrakobling af dine controllere, så du bør genstarte din OUYA og frakoble USB-kablet.\n\nFra nu af bør det at være muligt at bruge controllerens HOME-knap til at forbinde\ndem trådløst. Når du er færdig med at spille, hold HOME-knappen nede i 10 sekunder\nfor at slå controlleren fra. Hvis du ikke gør dette, kan den muligvis forblive tændt\nog spilde batteri.", + "ouyaInstructionsTextScale": 0.74, + "pairingTutorialText": "sammensætter vejledningsvideo", + "titleText": "PS3-controllere og BombSquad:" + }, + "publicBetaText": "OFFENTLIG BETA", + "punchBoldText": "SLÅ", + "punchText": "Slå", + "purchaseForText": "Køb for ${PRICE}", + "purchaseGameText": "Køb spil", + "purchasingText": "Køber...", + "quitGameText": "Afslut BombSquad?", + "quittingIn5SecondsText": "Afslutter om 5 sekunder...", + "randomText": "Tilfældig", + "ratingText": "Vurdering", + "reachWave2Text": "Nå bølge 2 for at få en vurdering.", + "readyText": "Klar!", + "remainingInTrialText": "tilbage af prøverversionen", + "restartText": "Genstart", + "revertText": "Gendan", + "runText": "Løb", + "saveText": "Gem", + "scoreChallengesText": "Score udfordringer", + "scoreListUnavailableText": "Scoreliste utilgængelig.", + "scoreText": "Score", + "scoreUnits": { + "millisecondsText": "Millisekunder", + "pointsText": "Point", + "secondsText": "Sekunder" + }, + "scoreWasText": "(var ${COUNT})", + "selectText": "Vælg", + "seriesWinLine1PlayerText": "VANDT", + "seriesWinLine1TeamText": "VANDT", + "seriesWinLine1Text": "VINDER", + "seriesWinLine2Text": "SERIEN!", + "settingsWindow": { + "accountText": "Bruger", + "advancedText": "Avanceret", + "audioText": "Lyd", + "controllersText": "Controllere", + "graphicsText": "Grafik", + "playerProfilesText": "Spillerprofiler", + "titleText": "Indstillinger" + }, + "settingsWindowAdvanced": { + "enterPromoCodeText": "Indtast kampagnekode", + "helpTranslateText": "BombSquads sprogoversættelser er lavet af BombSquads\ncommunity. Hvis du vil hjælpe eller rette en oversættelse,\nså følg linket nedenunder. På forhånd tak!", + "helpTranslateTextScale": 1.0, + "kickIdlePlayersText": "Smid inaktive spillere ud.", + "kidFriendlyModeText": "Børnevenlig tilstand (Mindre vold osv)", + "languageText": "Sprog", + "languageTextScale": 1.0, + "moddingGuideText": "Moddingguide", + "showPlayerNamesText": "Vis spillernavne", + "showUserModsText": "Vis mappen til mods", + "titleText": "Avanceret", + "translationEditorButtonText": "BombSquad oversættelsesside", + "translationNoUpdateNeededText": "Det nuværende sprog er ajour; woohoo!", + "translationUpdateNeededText": "** Det nuværende sprog mangler opdateringer!! **" + }, + "singlePlayerCountText": "1 spiller", + "soloNameFilterText": "Solo-${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Brugerudvælgelse", + "Chosen One": "Den udvalgte", + "Epic": "Slowmotionspil", + "Epic Race": "Slowmotionrace", + "FlagCatcher": "Find fanen", + "Flying": "Glade drømme", + "Football": "Fodbold", + "ForwardMarch": "Angreb", + "GrandRomp": "Erobring", + "Hockey": "Hockey", + "Keep Away": "Hold dig væk", + "Marching": "Løb", + "Menu": "Hovedmenu", + "Onslaught": "Stormangreb", + "Race": "Race", + "Scary": "Kongen af bakken", + "Scores": "Scoreskærm", + "Survival": "Udslettelse", + "ToTheDeath": "Kamp til døden", + "Victory": "Endelig scoreskærm" + }, + "spaceKeyText": "mellemrum", + "store": { + "alreadyOwnText": "Du har allerede ${NAME}!", + "bombSquadProDescriptionText": "Double billetter optjent in-game\n\nFjerner In-game reklamer\n\nInkluderer ${COUNT} bonus billetter\n\n+${PERCENT}% liga score bonus\n\nOplåser'${INF_ONSLAUGHT}' og\n '${INF_RUNAROUND}' co-op baner", + "bombSquadProFeaturesText": "indkludere:", + "bombSquadProNameText": "BombSquad Pro", + "buyText": "Køb", + "charactersText": "Spillere", + "comingSoonText": "Kommer snart...", + "extrasText": "Extra", + "freeBombSquadProText": "Bombsquad er nu gratis, men da du oprindeligt købte det, du er\nmodtagelse af Bombsquad Pro opgradering og ${COUNT} billetter som en tak.\nNyd de nye funktioner, og tak for din støtte!\n-Eric", + "gameUpgradesText": "spil opgradering", + "getCoinsText": "Få coins", + "holidaySpecialText": "Feriespecials", + "howToSwitchCharactersText": "(gå til \"${SETTINGS} -> ${PLAYER_PROFILES}\" for at tildele og tilpasse karatere)", + "loadErrorText": "Kan ikke indlæse side.\nTjek din internetforbindelse.", + "loadingText": "Indlæser", + "mapsText": "Baner", + "miniGamesText": "Minispil", + "purchaseAlreadyInProgressText": "et køb af denne ting er allerede i gang.", + "purchaseNotValidError": "kan ikke foretage køb\nKontakt ${EMAIL}, hvis dette er en fejl.", + "saleText": "SALE", + "searchText": "Søg", + "teamsFreeForAllGamesText": "Teams / Free-for-All Games", + "winterSpecialText": "Vinterspecials", + "youOwnThisText": "- Du ejer dette -" + }, + "storeDescriptionText": "Vanvittigt spil med op plads til op til 8 spillere!\n\nSpræng dine venner eller computeren i luften i en turnering af eksplosive mini-spil som f.eks. find fanen, bombe-hockey og kamp til døden i slowmotion.\n\nNem styring og omfattende controllersupport gør det nemt at få op til 8 spillere med i kampen! Du kan endda bruge din mobil som controller via den gratis 'BombSquad Remote'-app.\n\n\n\nTjek bombsquadgame.com ud for mere information.", + "storeDescriptions": { + "blowUpYourFriendsText": "Spræng dine venner i luften", + "competeInMiniGamesText": "Konkurrer i mini-spil lige fra racing til at flyve.", + "customize2Text": "Tilpas figurere, minispil og lydspor.", + "customizeText": "Tilpas figurere og lav din egen minispilliste.", + "sportsMoreFunText": "Sport er sjovere med sprængstof.", + "teamUpAgainstComputerText": "Kæmp imod computeren med dine venner." + }, + "storeText": "Butik", + "teamsText": "Hold", + "telnetAccessGrantedText": "Telnet-adgang aktiveret.", + "telnetAccessText": "Telnet-adgang registreret; tillad?", + "testBuildErrorText": "Denne test build er ikke længere aktiv; være venlig og se efter en ny version.", + "testBuildText": "Test Build", + "testBuildValidateErrorText": "Kan ikke validere dette test build. (ingen netforbindelse?)", + "testBuildValidatedText": "Test Build Validated; Nyd det!", + "thankYouText": "Tak for din støtte! Nyd spillet!!", + "threeKillText": "TREDOBBELT DRAB!!", + "timeBonusText": "Tidsbonus", + "timeElapsedText": "Tid brugt", + "timeExpiredText": "Tiden er udløbet", + "tipText": "Tip", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Top venner", + "tournamentCheckingStateText": "Checker turnerings status; vent venligst...", + "tournamentEndedText": "Denne turnerings er slut. En ny vil snart starte.", + "tournamentEntryText": "turnerings indgang", + "tournamentStandingsText": "Turnerings Stillinger", + "tournamentText": "Turnering", + "tournamentTimeExpiredText": "Turnerings tiden er udvidet", + "tournamentsText": "Turneringer", + "translations": { + "characterNames": { + "Bernard": "Bernard", + "Bones": "Bones", + "Santa Claus": "Julemand" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Uendelig\nOnslaught", + "Infinite\nRunaround": "Uendelig\nRunaround", + "Onslaught\nTraining": "Onslaught\nTræning", + "Pro\nFootball": "Pro\nFootballl", + "Pro\nOnslaught": "Pro\nOnslaught", + "Pro\nRunaround": "Pro\nRunaround", + "Rookie\nFootball": "Rookie\nFootball", + "Rookie\nOnslaught": "Rookie\nOnslaught", + "The\nLast Stand": "Sidste\nStående", + "Uber\nFootball": "Uber\nFootball", + "Uber\nOnslaught": "Uber\nOnslaught", + "Uber\nRunaround": "Uber\nRunaround" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Træning", + "Infinite ${GAME}": "uendelig ${GAME}", + "Infinite Onslaught": "Uendeligt stormangreb", + "Infinite Runaround": "Uendeligt løb", + "Onslaught": "Uendelig Onslaught", + "Onslaught Training": "Stormangrebstræning", + "Pro ${GAME}": "Pro ${GAME}", + "Pro Football": "Pro fodbold", + "Pro Onslaught": "Pro stormangreb", + "Pro Runaround": "Pro løb", + "Rookie ${GAME}": "Begynder ${GAME}", + "Rookie Football": "Nybegynderfodbold", + "Rookie Onslaught": "Nybegynderstormangreb", + "Runaround": "Uendelig Runaround", + "The Last Stand": "Sidst overlevende", + "Uber ${GAME}": "Supersvær ${GAME}", + "Uber Football": "Uber fodbold", + "Uber Onslaught": "Uber stormangreb", + "Uber Runaround": "Uber løb" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Vær den udvalgte i et forudbestemt stykke tid for at vinde.\nDræb den udvalgte for selv at blive den udvalgte.", + "Bomb as many targets as you can.": "Ram så mange mål som du kan!", + "Carry the flag for ${ARG1} seconds.": "Bær flaget i ${ARG1} sekunder.", + "Carry the flag for a set length of time.": "Bær flaget i et stykke tid.", + "Crush ${ARG1} of your enemies.": "Knus ${ARG1} af dine fjender.", + "Defeat all enemies.": "Besejr alle dine modstandere", + "Dodge the falling bombs.": "Undgå de faldne bomber", + "Final glorious epic slow motion battle to the death.": "Sidste gloriøse episke slowmotionkamp til døden.", + "Get the flag to the enemy end zone.": "Få flaget til modstanderenes målzone.", + "How fast can you defeat the ninjas?": "Hvor hurtigt kan du besejre ninjaerne?", + "Kill a set number of enemies to win.": "Dræb et forudbestemt antal af fjender for at vinde.", + "Last one standing wins.": "Sidste overlevende vinder.", + "Last remaining alive wins.": "Sidste overlevende vinder", + "Last team standing wins.": "Sidste overlevende hold vinder.", + "Prevent enemies from reaching the exit.": "Forhindr fjenderne i at nå udgangen.", + "Reach the enemy flag to score.": "Nå til modstanderenes flag for at score", + "Return the enemy flag to score.": "Returner modstanderens flag for at score", + "Run ${ARG1} laps.": "Løb ${ARG1} runder.", + "Run ${ARG1} laps. Your entire team has to finish.": "Løb ${ARG1} runder. Hele dit hold skal gennemføre.", + "Run 1 lap.": "Løb 1 runde.", + "Run 1 lap. Your entire team has to finish.": "Løb 1 runde. Hele dit hold skal gennemfører.", + "Run real fast!": "Løb rigtig hurtigt!", + "Score ${ARG1} goals.": "Scor ${ARG1} mål.", + "Score ${ARG1} touchdowns.": "Lav ${ARG1} touchdowns.", + "Score a goal": "Scor et mål", + "Score a goal.": "Scor et mål.", + "Score a touchdown.": "Lav en touchdown.", + "Score some goals.": "Scor nogle mål.", + "Secure all ${ARG1} flags.": "Få fat i alle ${ARG1} flag.", + "Secure all flags on the map to win.": "Få fat i alle flag på banen for at vinde.", + "Secure the flag for ${ARG1} seconds.": "Hold flaget i ${ARG1} sekunder.", + "Secure the flag for a set length of time.": "Hold alle flag i et bestemt stykke tid.", + "Steal the enemy flag ${ARG1} times.": "Stjæl fjendens flag ${ARG1} gange.", + "Steal the enemy flag.": "Stjæl fjendens flag.", + "There can be only one.": "Der kan kun være én.", + "Touch the enemy flag ${ARG1} times.": "Rør fjendens flag ${ARG1} gange.", + "Touch the enemy flag.": "Rør fjendens flag.", + "carry the flag for ${ARG1} seconds": "Bær flaget i ${ARG1} sekunder", + "kill ${ARG1} enemies": "Dræb ${ARG1} fjender", + "last one standing wins": "Sidste overlevende vinder", + "last team standing wins": "Sidste overlevende hold vinder", + "return ${ARG1} flags": "Returner ${ARG1} flag", + "return 1 flag": "Returner 1 flag", + "run ${ARG1} laps": "Løb ${ARG1} runder", + "run 1 lap": "Løb 1 runde", + "score ${ARG1} goals": "Scor ${ARG1} mål", + "score ${ARG1} touchdowns": "Lav ${ARG1} touchdowns", + "score a goal": "Scor et mål", + "score a touchdown": "Lav en touchdown", + "secure all ${ARG1} flags": "Få fat i alle ${ARG1} flag", + "secure the flag for ${ARG1} seconds": "Hold flaget i ${ARG1} sekunder", + "touch ${ARG1} flags": "Rør ${ARG1} flag", + "touch 1 flag": "Rør 1 flag" + }, + "gameNames": { + "Assault": "Angreb", + "Capture the Flag": "Find fanen", + "Chosen One": "Den udvalgte", + "Conquest": "Erobring", + "Death Match": "Kamp til døden", + "Elimination": "Udslettelse", + "Football": "Fodbold", + "Hockey": "Hockey", + "Keep Away": "Hold dig væk", + "King of the Hill": "Kongen af bakken", + "Meteor Shower": "Meteorregn", + "Ninja Fight": "Ninja Kamp", + "Onslaught": "Stormangreb", + "Race": "Race", + "Runaround": "Løb", + "Target Practice": "mål øvelse", + "The Last Stand": "Den sidste overlevende" + }, + "inputDeviceNames": { + "Keyboard": "Tastatur", + "Keyboard P2": "Tastatur P2" + }, + "languages": { + "Chinese": "Kinesisk", + "Croatian": "Kroatisk", + "Czech": "tjekkisk", + "Danish": "Dansk", + "Dutch": "Hollandsk", + "English": "Engelsk", + "Esperanto": "Esperanto", + "Finnish": "Finsk", + "French": "Fransk", + "German": "Tysk", + "Gibberish": "Volapykengelsk", + "Italian": "Italiensk", + "Japanese": "Japansk", + "Korean": "Koreansk", + "Polish": "Polsk", + "Portuguese": "Portugisisk", + "Russian": "Russisk", + "Spanish": "Spansk", + "Swedish": "Svensk" + }, + "leagueNames": { + "Bronze": "Bronze", + "Diamond": "Diamandt", + "Gold": "Guld", + "Silver": "sløv" + }, + "mapsNames": { + "Big G": "Store G", + "Bridgit": "Bridgit", + "Courtyard": "Gårdhaven", + "Crag Castle": "Slottet på klippeskrænten", + "Doom Shroom": "Dommedagssvampen", + "Football Stadium": "Fodboldstadionet", + "Happy Thoughts": "Glade drømme", + "Hockey Stadium": "Hockeystadionet", + "Lake Frigid": "søen Frigid", + "Monkey Face": "Abefjæs", + "Rampage": "Rampage", + "Roundabout": "Rundkørslen", + "Step Right Up": "Trappeslottet", + "The Pad": "Kassen", + "Tip Top": "Keglen", + "Tower D": "D-tårnet", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Bare Epicisk", + "Just Sports": "Bare Sport" + }, + "promoCodeResponses": { + "invalid promo code": "Ugyldig kampagnekode" + }, + "scoreNames": { + "Flags": "Flag", + "Goals": "Mål", + "Score": "Score", + "Survived": "Overlevet", + "Time": "Tid", + "Time Held": "Tid holdt" + }, + "serverResponses": { + "BombSquad Pro unlocked!": "BombSquad Pro oplukket!", + "Entering tournament...": "Går ind i Turnering...", + "Invalid promo code.": "ugylid promo kode.", + "Invalid purchase.": "Fejl i købt.", + "Purchase successful!": "Købt gennemført!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Modtog ${COUNT} tickets fordi du logger ind.\nKom tilbage i morgen for at modtage ${TOMORROW_COUNT}.", + "The tournament ended before you finished.": "Turneringen sluttede, før du blev færdig.", + "This requires version ${VERSION} or newer.": "Dette kræver version ${VERSION} eller nyere.", + "You already own this!": "Du ejer allerede dette!", + "You don't have enough tickets for this!": "Du har ikke tickets nok til dette!", + "You got ${COUNT} tickets!": "Du har ${COUNT} tickets!", + "You got a ${ITEM}!": "Du fik en ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Du er blevet forfremmet til en ny liga; Tillykke!", + "You must wait a few seconds before entering a new code.": "Du skal vente et par sekunder, før du indtaster en ny kode.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Du rangeret #${RANK} i den sidste turnering. Tak fordi du spillede med!", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Din kopi af spillet er blevet modifiseret. \nVære venlig og ændre det tilbage til normal version og prøv igen." + }, + "settingNames": { + "1 Minute": "1 minut", + "1 Second": "1 sekund", + "10 Minutes": "10 minutter", + "2 Minutes": "2 minutter", + "2 Seconds": "2 sekunder", + "20 Minutes": "20 minutter", + "4 Seconds": "4 sekunder", + "5 Minutes": "5 minutter", + "8 Seconds": "8 sekunder", + "Balance Total Lives": "Balancér samlet antal liv", + "Chosen One Gets Gloves": "Den udvalgte får boksehandsker", + "Chosen One Gets Shield": "Den udvalgte får skjold", + "Chosen One Time": "Den udvalgte tid", + "Enable Impact Bombs": "Aktiver Impact Bomber", + "Enable Triple Bombs": "Aktiver triple Bomber", + "Epic Mode": "Epic mode", + "Flag Idle Return Time": "Flag – inaktiv tid før returnering", + "Flag Touch Return Time": "Flag – Berøringstid før returnering", + "Hold Time": "Holdetid", + "Kills to Win Per Player": "Drab for at vinde per spiller", + "Laps": "Omgange", + "Lives Per Player": "Liv per spiller", + "Long": "Lang", + "Longer": "Længere", + "Mine Spawning": "Minegenoplivning", + "No Mines": "Ingen miner", + "None": "Ingen", + "Normal": "Normal", + "Respawn Times": "Antal genoplivninger", + "Score to Win": "Score for at vinde", + "Short": "Kort", + "Shorter": "Kortere", + "Solo Mode": "Solotilstand", + "Target Count": "Mål Optælling", + "Time Limit": "Tidsbegrænsning" + }, + "statements": { + "Killing ${NAME} for skipping part of the track!": "dræbt ${NAME} for at springe en del af banen over!" + }, + "teamNames": { + "Bad Guys": "Fjender", + "Blue": "Blå", + "Good Guys": "Venner", + "Red": "Rød" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Et perfekt løbe-hoppe-dreje-slag kan dræbe på et enkelt slag og\ngiver dig livslang respekt fra dine venner.", + "Always remember to floss.": "Husk altid at bruge tandtråd.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Lav spillerprofiler til dig selv og dine venner med jeres foretrukne navne\nog udseender i stedet for at bruge tilfældige navne og udseender.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Forbandelseskasserne laver dig om til en tikkende bombe.\nDen eneste kur er hurtig at tage en livpakke.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Selvom de ser anderledes ud, er alle spillernes evner\nidentiske. Så vælg den, som du mest ligner.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Bliv ikke for overmodig, bare fordi du har et energiskjold; du kan stadig blive kastet ud over kanten.", + "Don't run all the time. Really. You will fall off cliffs.": "Lad vær' med at løbe hele tiden. Helt seriøst. Du ender med at falde ud over kanten.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Hold hvilken som helst knap nede for at løbe. (Udløselsesknapper virker godt, hvis du har sådan nogle)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Hold en vilkårlig knap nede for at løbe. Du bevæger dig hurtigere, men du drejer ikke så godt, så pas på kanter.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Isbomber er ikke særligt kraftfulde, men de fryser, dem de rammer. Hvilket gør den ramte nem at slå i stykker.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Slå til dem, der løfter dig op – så giver de slip med det samme.\nDette virker også i virkeligheden.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Hvis du har få controllere, så installer 'BombSquad Remote' app'en på\ndin iOS- eller Android-enhed. De kan nemlig bruges som controllere.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Hvis du er blevet ramt af en klistrebombe, så hop rundt og drej i cirkler. Du kan muligvis\nryste bomben af – hvis du ikke kan det, var din sidste tid i det mindste underholdende.", + "If you kill an enemy in one hit you get double points for it.": "Hvis du dræber en fjende med ét slag, får du dobbelt så mange point for det.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Hvis du samler en forbandelse op, er dit eneste håb for overlevelse\nen livspakke, som du skal samle op inden tiden udløber.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Hvis du altid står stille, bliver du nakket. Løb og undgå at blive slået for at overleve.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Hvis der kommer og går mange spillere, så slå automatisk udsmidning af inaktive spillere til under\n'Indstillinger' i tilfælde af at nogle glemmer at forlade spillet.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Hvis enheden bliver for varmt eller du gerne vil spare på batteriet,\nskrue ned \"Visuals\" eller \"Løsning\" i Opsætning-> Grafik", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Hvis din FPS er dårlig, så prøv at skru ned for din opløsning\neller de visuelle effekter i spillets grafikindstillinger.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "I Find Fanen skal dit eget flag være i din base, for at du kan score. Hvis det andet\nhold er ved at score, kan du stjæle deres flag. Dette gør så de ikke kan score.", + "In hockey, you'll maintain more speed if you turn gradually.": "På hockeybanen kan du opretholde din fart, hvis du kun drejer en smule ad gangen.", + "It's easier to win with a friend or two helping.": "Det er lettere at vinde hvis en eller flere af dine venner hjælper.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Hop samtidig med at du kaster for at få bomberne længere og højere.", + "Land-mines are a good way to stop speedy enemies.": "Miner er en god måde at stoppe hurtige fjender på.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Mange ting kan samles op og kastes med – også andre spillere. Det, at kaste dine\nfjender ud over en kant, kan være en effektiv og følelsesmæssigt tilfredsstillende strategi.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nej, du kan ikke komme op på afsatsen. Du bliver nødt til at kaste bomber.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Spillere kan deltage og forlade i midten af de fleste spil,\nog du kan også tilslutte og frakoble kontrollere i farten.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Spillere kan tilslutte og forlade midt i de fleste spil\nog du kan også til- og frakoble gamepads imens.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Powerups er tidsbegrænsede i co-op spil.\nI hold og alle mod alle er de dine, indtil du dør.", + "Practice using your momentum to throw bombs more accurately.": "Øv dig i at bruge dit momentum til at kaste bombe mere præcist.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Slag gør mere skade, jo hurtigere dine knytnæver bevæger\nsig, så prøv at løbe, hoppe og dreje som en gal.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Løb frem og tilbage, før du kaster en bombe\nfor at lave en piskebevægelse og dermed kaste den længere.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Dræb en gruppe af fjender ved\nat udløse en bombe nær en TNT-box.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Hovedet er det mest sårbare område, så en klistrebombe\ntil hovedet betyder for det meste game-over for offeret.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Denne bane ender aldrig, men en høj score vil\ngive dig evig respekt over hele verden.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Kastekraft er baseret på den retningsknap, du holder nede. For at kaste\nnoget lige så stille foran dig, skal du ikke holde nogen retningsknap nede.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Træt af soundtracket? Udskift det med dine egne!\nSe indstiller-> lyd-> Soundtrack", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Prøv at lade lunten brænde lidt, før du kaster bomben.", + "Try tricking enemies into killing eachother or running off cliffs.": "Prøv at snyd dine fjender, så de dræber hinanden eller løber ud over klipper.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Brug opsamlingsknappen til at snuppe flaget < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Lav en piskebevægelse frem og tilbage for at kaste længere.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Du kan 'sigte' dine slag ved at dreje til venstre eller højre. Dette er\ngodt til at slå fjender ud over kanterne eller til at score i hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Du kan se hvornår en bombe vil springe, hvis du kigger\npå farven af gnisterne fra lunten: Gul..orange..rød..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Du kan kaste bomber højere, hvis du hopper, lige før du kaster.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Du behøver ikke at redigere din profil for at ændre brugere: Bare tryk på\n'saml-op' knappen når du tilslutter et spil for at slette dit normale.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Du tager skade, hvis du støder dit hoved mod ting,\nså prøv at undgå det.", + "Your punches do much more damage if you are running or spinning.": "Dit slag kan gøre meget mere skade, hvis du løber og/eller drejer." + } + }, + "trialPeriodEndedText": "Din prøveperiode er slut. Vil du købe\nBombSquad og fortsætte med at spille?", + "trophiesText": "Trofæer", + "tutorial": { + "cpuBenchmarkText": "Løb tutorial ved latterlig-hastighed (primært tester CPU-hastighed)", + "phrase01Text": "Hej med dig!", + "phrase02Text": "Velkommen til BombSquad!", + "phrase03Text": "Here er der lige nogle tips til at styre din spiller:", + "phrase04Text": "Mange ting i BombSquad er baseret på fysik.", + "phrase05Text": "For eksempel når du slår...", + "phrase06Text": "..er skaden baseret på dine hænders fart.", + "phrase07Text": "Se? Fordi vi ikke bevægede os, gjorde det næsten ikke engang ondt på ${NAME}.", + "phrase08Text": "Lad os hoppe og dreje for at få mere fart på.", + "phrase09Text": "Ah, det var bedre.", + "phrase10Text": "Det hjælper også at løbe.", + "phrase11Text": "Hold en vilkårlig knap nede for at løbe.", + "phrase12Text": "For ekstra seje slag, prøv at løb OG drej på samme tid.", + "phrase13Text": "Ups, undskyld ${NAME}.", + "phrase14Text": "Du kan samle ting og kaste med dem. Du kan fx løfte flag... eller ${NAME}.", + "phrase15Text": "Og sidst, men ikke mindst, så er der bomber.", + "phrase16Text": "Det kræver øvelse at kaste med bomber.", + "phrase17Text": "Øv! Det var ikke et særlig godt kast.", + "phrase18Text": "Du kaster længere, når du bevæger dig.", + "phrase19Text": "Du kaster højere, når du hopper.", + "phrase20Text": "Lav en piskebevægelse frem og tilbage for at kaste endnu længere.", + "phrase21Text": "Det kan være svært at time dine bomber.", + "phrase22Text": "Øv! Det var ikke et særlig godt kast.", + "phrase23Text": "Prøv at lade lunten brænde et sekund eller to, før du kaster.", + "phrase24Text": "Wow! Godt gået!", + "phrase25Text": "Nå, men det var det, jeg havde.", + "phrase26Text": "Nu er det for alvor din tur!", + "phrase27Text": "Husk på din træning, og så kommer du helt sikkert tilbage i live.", + "phrase28Text": "…. eller måske ikke...", + "phrase29Text": "Held og lykke!", + "randomName1Text": "Freddy", + "randomName2Text": "Malik", + "randomName3Text": "Niels", + "randomName4Text": "Nikolaj", + "randomName5Text": "Emil", + "skipConfirmText": "vil du springe tutorialen over? Tryk på skærmen eller en knap for at bekræfte.", + "skipVoteCountText": "${COUNT}/${TOTAL} vil springe tutorialen over", + "skippingText": "Springer tutorialen over...", + "toSkipPressAnythingText": "(tryk på en vilkårlig knap for at springe tutorialen over)" + }, + "twoKillText": "DOBBEL DRAB!", + "unavailableText": "utilgængelig", + "unconfiguredControllerDetectedText": "Ukonfigureret controller registreret:", + "unlockThisInTheStoreText": "Det skal være låst op i butikken.", + "unsupportedHardwareText": "Beklager, denne hardware er ikke understøttet af dette build af spillet.", + "upFirstText": "Første spil:", + "upNextText": "Næste bane i spil nummer ${COUNT}:", + "updatingAccountText": "Opdatere din account...", + "upgradeToPlayText": "Lås op \"${PRO}\" i butikken for at spille dette.", + "useDefaultText": "Benyt standardindstillinger", + "usesExternalControllerText": "Dette spil bruger en ekstern controller til input.", + "usingItunesText": "Bruger iTunes til musik...", + "usingItunesTurnRepeatAndShuffleOnText": "Sørg venligst for, at shuffle er PÅ, og at gentag er sat til 'Alle' i iTunes.", + "validatingBetaText": "Validerer beta...", + "validatingTestBuildText": "Validere Test Build ...", + "victoryText": "Sejr!", + "vsText": "vs.", + "waitingForHostText": "(venter på ${HOST} for at fortsætte)", + "waitingForLocalPlayersText": "Venter på lokale spillere...", + "waitingForPlayersText": "venter spillerne til at deltage ...", + "watchAnAdText": "Se en reklame", + "watchWindow": { + "deleteConfirmText": "Slet \"${REPLAY}\"?", + "deleteReplayButtonText": "Slet\nGengivelse", + "myReplaysText": "Mine Gengivelse", + "noReplaySelectedErrorText": "Ingen gengivelse valgt", + "renameReplayButtonText": "Omdøb\nGengivelse", + "renameReplayText": "Omdøb \"${REPLAY}\" til:", + "renameText": "Omdøb", + "replayDeleteErrorText": "Fejl sletter gengivelse.", + "replayNameText": "Gengivelse Navn", + "replayRenameErrorAlreadyExistsText": "En gengivelse med det navn eksisterer allerede.", + "replayRenameErrorInvalidName": "Kan ikke omdøbe gengivelse; ugyldigt navn.", + "replayRenameErrorText": "Fejl i omdøbning af gengivelse.", + "sharedReplaysText": "Del Gengivelser", + "titleText": "Se", + "watchReplayButtonText": "Se\nGengivelse" + }, + "waveText": "Bølge", + "wellSureText": "Øh, ja da!", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Lytter efter Wiimotes...", + "pressText": "Tryk på Wiimote knap 1 og 2 på samme tid.", + "pressText2": "På nyere Wiimotes med Motion Plus indbygget, tryk på den røde 'sync' knap på bagsiden i stedet.", + "pressText2Scale": 0.55, + "pressTextScale": 1.0 + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "copyrightTextScale": 0.6, + "listenText": "Lytter", + "macInstructionsText": "Sørg for at din Wii er slået fra og dit Bluetooth er slået\ntil på din Mac. Tryk derefter på 'Lyt' eller 'Listen'. Wiimote-\nsupport kan være lidt ustabilt, så du er muligvis nødt til\nat prøve et par gange, før du får forbindelse.\n\nBluetooth burde at kunne have op til 7 tilsluttede enheder,\nmen forbindelserne kan variere.\n\nBombSquad virker til de originale Wiimotes, Nunchuks\nog den klassiske controller.\nDen nyere Wii Remote Plus virker også,\nmen kun uden ekstraudstyr.", + "macInstructionsTextScale": 0.7, + "thanksText": "Tak til DarwiinRemote holdet for\nat gøre dette muligt.", + "thanksTextScale": 0.8, + "titleText": "Wiimote opsætning" + }, + "winsPlayerText": "${NAME} vandt!", + "winsTeamText": "${NAME} vandt!", + "winsText": "${NAME} vandt!", + "worldScoresUnavailableText": "Verdensscore utilgængelig.", + "worldsBestScoresText": "Verdens bedste scorer", + "worldsBestTimesText": "Verdens bedste tider", + "xbox360ControllersWindow": { + "getDriverText": "Driverhjemmeside", + "macInstructions2Text": "For at bruge controllere trådløst, skal du også bruge modtageren\nsom følger med 'Xbox 360 Wireless Controller for Windows'.\nEn modtager gør det muligt at tilslutte op til 4 controllers.\n\nVigtigt: 3-partsmodtagere virker ikke med denne driver;\nsørg for, at der står 'Microsoft' på den og ikke 'XBOX 360'.\nMicrosoft sælger ikke længere disse seperat, så du bliver nødt til\nat få den i en pakke sammen med en controller - Eller søg på eBay.\n\nHvis du mener dette er brugbart, må du meget gerne donere\ntil driverudvikleren på hans side.", + "macInstructions2TextScale": 0.76, + "macInstructionsText": "For at bruge Xbox 360-controllere skal du installere en\nMacdriver, der er tilgængelig i linket herunder.\nDet virker både med controllere med og uden ledninger.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "For at bruge Xbox 360-controllere til BombSquad, tilslut dem din enheds USB-port.\nDu kan bruge en USB-hub\ntil at forbinde flere controllere. \n\nFor at bruge trådløse controllere skal du bruge en trådløs modtager,\ntilgængelig som en del af \"Xbox 360 wireless Controller for Windows\"-\npakken eller solgt seperat. Hver modtager puttes ind i en USB port\nog tillader dig at forbinde op til 4 trådløse controllers.", + "ouyaInstructionsTextScale": 0.8, + "titleText": "Hvordan man bruger Xbox 360-controllere med BombSquad:" + }, + "yesAllowText": "Ja, tillad!", + "yourBestScoresText": "Dine bedste scorer", + "yourBestTimesText": "Dine bedste tider" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/dutch.json b/dist/ba_data/data/languages/dutch.json new file mode 100644 index 0000000..a706cfc --- /dev/null +++ b/dist/ba_data/data/languages/dutch.json @@ -0,0 +1,1965 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Account namen mogen geen emoji's of andere speciale tekens bevatten.", + "accountProfileText": "(account profiel)", + "accountsText": "Accounts", + "achievementProgressText": "Prestaties: ${COUNT} van de ${TOTAL}", + "campaignProgressText": "Campagne Voortgang [Moeilijk]: ${PROGRESS}", + "changeOncePerSeason": "U kunt dit maar een keer per seizoen wijzigen.", + "changeOncePerSeasonError": "U moet wachten tot het volgende seizoen om dit te veranderen (${NUM} dagen)", + "customName": "Aangepaste naam", + "deviceSpecificAccountText": "U gebruikt nu het apparaat-specifieke account: ${NAME}", + "linkAccountsEnterCodeText": "Voer Code In", + "linkAccountsGenerateCodeText": "Genereer Code", + "linkAccountsInfoText": "(deel voortgang over verschillende platformen)", + "linkAccountsInstructionsNewText": "Om 2 accounts te verbinden, genereer je een code met het \neerste account en vul je die in op de tweede. \nData van het tweede account zal worden gedeeld over beiden accounts. \n\n(Data van het eerste account zal verloren gaan.) \n\nJe kunt in totaal ${COUNT} accounts verbinden.\n\nBELANGRIJK: Verbind alleen accounts die van jou zijn; \nAls je verbind met een account van een vriend zul je niet meer samen online kunnen spelen.", + "linkAccountsInstructionsText": "Om twee accounts te koppelen, genereer je bij een\ndaar van een code die je invult bij de ander.\nVoortgang en inventaris worden dan samengevoegd.\nJe kan maximaal ${COUNT} accounts koppelen.\n\nBELANGRIJK: Koppel alleen accounts die jij bezit!\nAls je accounts van vrienden koppelt kan je niet \nmeer tegelijkertijd spelen!\n\nOok: Dit kan momenteel niet ongedaan gemaakt worden, dus pas op!", + "linkAccountsText": "Koppel Accounts", + "linkedAccountsText": "Verbonden Accounts:", + "nameChangeConfirm": "Verander je account naam naar ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Dit reset uw co-op campagne voortgang en\nlokale high-scores (maar niet uw tickets).\nDit kan niet ongedaan worden gemaakt. Weet u het zeker?", + "resetProgressConfirmText": "Dit reset uw co-op voortgang,\nprestaties en lokale high-scores\n(maar niet uw tickets). Dit kan niet\nongedaan worden gemaakt. Weet u het zeker?", + "resetProgressText": "Reset Voortgang", + "setAccountName": "Stel account naam in", + "setAccountNameDesc": "Selecteer de naam om weer te geven voor uw account.\nU kan de naam gebruiken van een van de verbonden accounts\nof maak een unieke naam aan.", + "signInInfoText": "Log in om tickets te verzamelen, online te concurreren,\nen om je voortgang te delen tussen apparaten.", + "signInText": "Log In", + "signInWithDeviceInfoText": "(een automatisch account is alleen beschikbaar op dit apparaat)", + "signInWithDeviceText": "Log in met apparaat account", + "signInWithGameCircleText": "Log in met Game Circle", + "signInWithGooglePlayText": "Log in met Google Play", + "signInWithTestAccountInfoText": "(oudere account type; gebruik device account gaat door)", + "signInWithTestAccountText": "Log in met test account", + "signInWithV2InfoText": "(een account dat op alle platforms werkt)", + "signInWithV2Text": "Inloggen met een BombSquad rekening", + "signOutText": "Log Uit", + "signingInText": "Inloggen...", + "signingOutText": "Uitloggen...", + "testAccountWarningCardboardText": "Let op: je logt in met een \"test\" account.\nDeze zullen worden vervangen door Google accounts \nzodra dit wordt ondersteund in Google Cardboard apps.\n\nVoorlopig moet je alle tickets in-game verdienen.\n(Je krijgt, echter, de BombSquad Pro opwaardering gratis)", + "testAccountWarningOculusText": "Waarschuwing: U bent ingelogd met een \"test\" account.\nDeze accounts zullen later dit jaar vervangen worden met Oculus accounts later dit\njaar. Met dat account kan je tickets kopen en andere features gebruiken.\n\nVoor nu moet je al je tickets in-game verdienen.\n(Je krijgt, echter, de BombSquad Pro opwaardering gratis)", + "testAccountWarningText": "Waarschuwing: u ben ingelogd met een \"test\" account.\nDit account is gebonden aan dit specifieke apparaat en\nkan periodiek gereset worden. (besteed dus niet te \nveel tijd met het verzamelen/vrijspelen van spullen er voor)\n\nGebruik een gekochte versie van het spel om een \"echt\"\naccount (Game-Center, Google Plus, etc.) te gebruiken. Hierdoor kan u ook\nuw voortgang bewaren in de cloud en het delen tussen verschillende apparaten.", + "ticketsText": "Tickets: ${COUNT}", + "titleText": "Profiel", + "unlinkAccountsInstructionsText": "Selecteer een account om los te koppelen.", + "unlinkAccountsText": "Koppel accounts los.", + "v2LinkInstructionsText": "Gebruik deze link om een ​​account aan te maken of in te loggen.", + "viaAccount": "(via account ${NAME})", + "youAreLoggedInAsText": "Je bent ingelogd als:", + "youAreSignedInAsText": "U bent ingelogd als:" + }, + "achievementChallengesText": "Prestatie Uitdagingen", + "achievementText": "Prestatie", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Dood 3 slechteriken met TNT", + "descriptionComplete": "Doodde 3 slechteriken met TNT", + "descriptionFull": "Dood 3 slechteriken met TNT op ${LEVEL}", + "descriptionFullComplete": "Doodde 3 slechteriken met TNT op ${LEVEL}", + "name": "Dynamite gaat Boom" + }, + "Boxer": { + "description": "win without useing any fucking bombs", + "descriptionComplete": "Gewonnen zonder het gebruiken van bommen", + "descriptionFull": "Haal ${LEVEL} zonder gebruik van bommen", + "descriptionFullComplete": "Voltooide ${LEVEL} zonder gebruik van bommen", + "name": "Bokser" + }, + "Dual Wielding": { + "descriptionFull": "Verbind 2 controllers (hardware of app)", + "descriptionFullComplete": "Verbind 2 controllers (hardware of app)", + "name": "Dubbel gewapend" + }, + "Flawless Victory": { + "description": "Win zonder geraakt te worden", + "descriptionComplete": "Gewonnen zonder geraakt te worden", + "descriptionFull": "Win ${LEVEL} zonder geraakt te worden", + "descriptionFullComplete": "Won ${LEVEL} zonder geraakt te worden", + "name": "Perfecte Overwinning" + }, + "Free Loader": { + "descriptionFull": "Start een Ieder-Voor-Zich spel met minimaal 2+ spelers", + "descriptionFullComplete": "Een Ieder-Voor-Zich spel gestart met minimaal 2+ spelers", + "name": "Gratis lader" + }, + "Gold Miner": { + "description": "Dood 6 slechteriken met landmijnen", + "descriptionComplete": "Doodde 6 slechteriken met landmijnen", + "descriptionFull": "Dood 6 slechteriken met landmijnen op ${LEVEL}", + "descriptionFullComplete": "Doodde 6 slechteriken met landmijnen op ${LEVEL}", + "name": "Goud Mijner" + }, + "Got the Moves": { + "description": "Win zonder te slaan of bommen te gooien", + "descriptionComplete": "Winnen zonder te slaan of bommen te gooien", + "descriptionFull": "Win ${LEVEL} zonder slagen of bommen", + "descriptionFullComplete": "Won ${LEVEL} zonder slagen of bommen", + "name": "Heb de Bewegingen" + }, + "In Control": { + "descriptionFull": "Verbind een controller (hardware of app)", + "descriptionFullComplete": "Een controller verbonden. (hardware of app)", + "name": "Onder controle" + }, + "Last Stand God": { + "description": "Score 1000 punten", + "descriptionComplete": "Scoorde 1000 punten", + "descriptionFull": "Score 1000 punten op ${LEVEL}", + "descriptionFullComplete": "Scoorde 1000 punten op ${LEVEL}", + "name": "${LEVEL} God" + }, + "Last Stand Master": { + "description": "Score 250 punten", + "descriptionComplete": "250 punten gescoord", + "descriptionFull": "Score 250 punten bij ${LEVEL}", + "descriptionFullComplete": "250 punten gescoord bij ${LEVEL}", + "name": "${LEVEL} Meester" + }, + "Last Stand Wizard": { + "description": "Score 500 punten", + "descriptionComplete": "scoorde 500 punten", + "descriptionFull": "Score 500 punten bij ${LEVEL}", + "descriptionFullComplete": "500 punten gescoord bij ${LEVEL}", + "name": "${LEVEL} Tovenaar" + }, + "Mine Games": { + "description": "Dood 3 slechteriken met landmijnen", + "descriptionComplete": "Doodde 3 slechteriken met landmijnen", + "descriptionFull": "Dood 3 slechteriken met landmijnen op ${LEVEL}", + "descriptionFullComplete": "3 slechteriken gedood met landmijnen op ${LEVEL}", + "name": "Landmijn Spellen" + }, + "Off You Go Then": { + "description": "Gooi 3 slechteriken van het speelveld", + "descriptionComplete": "Gooide 3 slechteriken van het speelveld", + "descriptionFull": "Gooi 3 slechteriken van het speelveld in ${LEVEL}", + "descriptionFullComplete": "3 slechteriken van het speelveld gegooid in ${LEVEL}", + "name": "Daar Ga Je Dan" + }, + "Onslaught God": { + "description": "Score 5000 punten", + "descriptionComplete": "Scoorde 5000 punten", + "descriptionFull": "Score 5000 punten in ${LEVEL}", + "descriptionFullComplete": "5000 punten gescoord in ${LEVEL}", + "name": "${LEVEL} God" + }, + "Onslaught Master": { + "description": "Score 500 punten", + "descriptionComplete": "Scoorde 500 punten", + "descriptionFull": "Score 500 punten in ${LEVEL}", + "descriptionFullComplete": "500 punten gescoord in ${LEVEL}", + "name": "${LEVEL} Meester" + }, + "Onslaught Training Victory": { + "description": "Versla alle golven", + "descriptionComplete": "Alle golven verslagen", + "descriptionFull": "versla alle golven in ${LEVEL}", + "descriptionFullComplete": "Alle golven in ${LEVEL} verslagen", + "name": "${LEVEL} Overwinning" + }, + "Onslaught Wizard": { + "description": "Score 1000 punten", + "descriptionComplete": "Scoorde 1000 punten", + "descriptionFull": "Score 1000 punten in ${LEVEL}", + "descriptionFullComplete": "1000 punten gescoord in ${LEVEL}", + "name": "${LEVEL} Tovenaar" + }, + "Precision Bombing": { + "description": "Win zonder powerups", + "descriptionComplete": "Gewonnen zonder powerups", + "descriptionFull": "Win ${LEVEL} zonder enige power-ups", + "descriptionFullComplete": "${LEVEL} gewonnen zonder enige power-ups", + "name": "Precisie Bombardementen" + }, + "Pro Boxer": { + "description": "Winnen zonder het gebruik van bommen", + "descriptionComplete": "Gewonnen zonder het gebruik van bommen", + "descriptionFull": "Voltooi ${LEVEL} zonder het gebruik van bommen", + "descriptionFullComplete": "${LEVEL} voltooid zonder het gebruik van bommen", + "name": "Pro Boxer" + }, + "Pro Football Shutout": { + "description": "Win zonder de slechteriken te laten scoren", + "descriptionComplete": "Gewonnen zonder de slechteriken te laten scoren", + "descriptionFull": "Win ${LEVEL} zonder de slechteriken te laten scoren", + "descriptionFullComplete": "${LEVEL} gewoon zonder de slechteriken te laten scoren", + "name": "${LEVEL} Buitengesloten" + }, + "Pro Football Victory": { + "description": "Win het wedstrijd", + "descriptionComplete": "Won de wedstrijd", + "descriptionFull": "Win de wedstrijd in ${LEVEL}", + "descriptionFullComplete": "Won de wedstrijd in ${LEVEL}", + "name": "${LEVEL} overwinning" + }, + "Pro Onslaught Victory": { + "description": "Versla alle golven", + "descriptionComplete": "Alle golven verlagen", + "descriptionFull": "Verslag alle golven in ${LEVEL}", + "descriptionFullComplete": "Alle golven van ${LEVEL} verslagen", + "name": "${LEVEL} Gewonnen" + }, + "Pro Runaround Victory": { + "description": "Voltooi alle golven", + "descriptionComplete": "Alle golven voltooid", + "descriptionFull": "Voltooi alle golven van ${LEVEL}", + "descriptionFullComplete": "Alle golven van ${LEVEL} voltooid", + "name": "${LEVEL} Overwinning" + }, + "Rookie Football Shutout": { + "description": "Winnen zonder dat de slechteriken scoren", + "descriptionComplete": "Gewonnen zonder dat de slechteriken scoorden", + "descriptionFull": "Win Rookie${LEVEL} zonder dat de slechteriken scoren", + "descriptionFullComplete": "${LEVEL} gewonnen zonder dat de slechteriken scoren", + "name": "${LEVEL} Buitengesloten" + }, + "Rookie Football Victory": { + "description": "Win het spel", + "descriptionComplete": "De wedstrijd gewonnen", + "descriptionFull": "Win de wedstrijd in ${LEVEL}", + "descriptionFullComplete": "De wedstrijd gewonnen in ${LEVEL}", + "name": "${LEVEL} Overwinning" + }, + "Rookie Onslaught Victory": { + "description": "Versla alle golven", + "descriptionComplete": "Alle golven verslagen", + "descriptionFull": "Verslag alle golven in ${LEVEL}", + "descriptionFullComplete": "Alle golven in ${LEVEL} verslagen", + "name": "${LEVEL} Overwinning" + }, + "Runaround God": { + "description": "Score 2000 punten", + "descriptionComplete": "Scoorde 2000 punten", + "descriptionFull": "Score 2000 punten in ${LEVEL}", + "descriptionFullComplete": "2000 punten gescoord in ${LEVEL}", + "name": "${LEVEL} God" + }, + "Runaround Master": { + "description": "Score 500 punten", + "descriptionComplete": "500 punten gescoord", + "descriptionFull": "Score 500 punten in ${LEVEL}", + "descriptionFullComplete": "500 punten gescoord in ${LEVEL}", + "name": "${LEVEL} Meester" + }, + "Runaround Wizard": { + "description": "Score 1000 punten", + "descriptionComplete": "1000 punten gescoord", + "descriptionFull": "Score 1000 punten in ${LEVEL}", + "descriptionFullComplete": "1000 punten gescoord in ${LEVEL}", + "name": "${LEVEL} Tovenaar" + }, + "Sharing is Caring": { + "descriptionFull": "Deel succesvol de game met een vriend", + "descriptionFullComplete": "Succesvol de game met een vriend gedeeld", + "name": "Delen is verzorgen" + }, + "Stayin' Alive": { + "description": "Win zonder dood te gaan", + "descriptionComplete": "Gewonnen zonder dood te gaan", + "descriptionFull": "Win ${LEVEL} zonder dood te gaan", + "descriptionFullComplete": "${LEVEL} gewonnen zonder dood te gaan", + "name": "Blijven Leven" + }, + "Super Mega Punch": { + "description": "Breng 100% schade toe met een slag", + "descriptionComplete": "100% schade toegebracht met een slag", + "descriptionFull": "Breng 100% schade toe met een slag in ${LEVEL}", + "descriptionFullComplete": "100% schade toegebracht met een slag in ${LEVEL}", + "name": "Super Mega Slag" + }, + "Super Punch": { + "description": "Breng 50% schade toe met een slag", + "descriptionComplete": "50% schade toegebracht met een slag", + "descriptionFull": "Breng 50% schade toe met een slag in ${LEVEL}", + "descriptionFullComplete": "50% schade toegebracht met een slag in ${LEVEL}", + "name": "Super Slag" + }, + "TNT Terror": { + "description": "Dood 6 slechteriken met TNT", + "descriptionComplete": "6 Slechteriken gedood met TNT", + "descriptionFull": "Dood 6 slechteriken met TNT in ${LEVEL}", + "descriptionFullComplete": "6 Slechteriken gedood met TNT in ${LEVEL}", + "name": "TNT Terreur" + }, + "Team Player": { + "descriptionFull": "Start een team spel met 4+ spelers", + "descriptionFullComplete": "Een spel gestart met 4+ spelers", + "name": "Team speler" + }, + "The Great Wall": { + "description": "Stop iedere slechterik", + "descriptionComplete": "Iedere slechterik gestopt", + "descriptionFull": "Stop iedere slechterik in ${LEVEL}", + "descriptionFullComplete": "Iedere slechterik gestopt in ${LEVEL}", + "name": "De Grote Muur" + }, + "The Wall": { + "description": "Stop iedere slechterik", + "descriptionComplete": "Iedere slechterik gestopt", + "descriptionFull": "Stop iedere slechterik in ${LEVEL}", + "descriptionFullComplete": "Iedere slechterik gestopt in ${LEVEL}", + "name": "De Muur" + }, + "Uber Football Shutout": { + "description": "Win zonder de slechteriken te laten scoren", + "descriptionComplete": "Gewonnen zonder de slechteriken te laten scoren", + "descriptionFull": "Win ${LEVEL} zonder de slechteriken te laten scoren", + "descriptionFullComplete": "${LEVEL} gewonnen zonder de slechteriken te laten scoren", + "name": "${LEVEL} Buitengesloten" + }, + "Uber Football Victory": { + "description": "Win de wedstrijd", + "descriptionComplete": "De wedstrijd gewonnen", + "descriptionFull": "Win de wedstrijd in ${LEVEL}", + "descriptionFullComplete": "De wedstrijd gewonnen in ${LEVEL}", + "name": "${LEVEL} Overwinning" + }, + "Uber Onslaught Victory": { + "description": "Versla alle golven", + "descriptionComplete": "Alle golven verslagen", + "descriptionFull": "Verslag alle golven in ${LEVEL}", + "descriptionFullComplete": "Alle golven verslagen in ${LEVEL}", + "name": "${LEVEL} Overwinning" + }, + "Uber Runaround Victory": { + "description": "Voltooi alle golven", + "descriptionComplete": "Alle golven voltooid", + "descriptionFull": "Voltooi alle golven in ${LEVEL}", + "descriptionFullComplete": "Alle golven voltooid in ${LEVEL}", + "name": "${LEVEL} Overwinning" + } + }, + "achievementsRemainingText": "Resterende Prestaties:", + "achievementsText": "Prestaties", + "achievementsUnavailableForOldSeasonsText": "Sorry, prestatie gegevens voor oude seizoenen zijn niet beschikbaar.", + "addGameWindow": { + "getMoreGamesText": "Verkrijg Meer Spellen...", + "titleText": "Voeg Game toe" + }, + "allowText": "Toestaan", + "alreadySignedInText": "Uw account is al ingelogd op een ander apparaat;\nVerander van account of sluit het spel op uw andere\napparaten en probeer het opnieuw.", + "apiVersionErrorText": "Kan module ${NAME} niet laden; deze gebruikt api-versie ${VERSION_USED}; benodigd is ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" activeert dit alleen als een koptelefoon is aangesloten)", + "headRelativeVRAudioText": "Hoofd-Relatieve VR Geluid", + "musicVolumeText": "Muziek Volume", + "soundVolumeText": "Geluid Volume", + "soundtrackButtonText": "Muzieklijsten", + "soundtrackDescriptionText": "(wijs uw eigen muziek toe om af te spelen tijdens het spelen)", + "titleText": "Geluid" + }, + "autoText": "Auto", + "backText": "Terug", + "banThisPlayerText": "Verband deze speler", + "bestOfFinalText": "Beste-van-${COUNT} Definitief", + "bestOfSeriesText": "Beste van ${COUNT} reeks:", + "bestRankText": "Uw beste is #${RANK}", + "bestRatingText": "Uw beste rating is ${RATING}", + "betaErrorText": "Deze beta is niet meer actief, controleer daarom voor een nieuwe versie.", + "betaValidateErrorText": "Niet in staat om beta te valideren. (geen net verbinding?)", + "betaValidatedText": "Beta Gevalideerd; Geniet er van!", + "bombBoldText": "BOM", + "bombText": "Bom", + "boostText": "Boost", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} is geconfigureerd in de app zelf.", + "buttonText": "knop", + "canWeDebugText": "Wilt u dat BombSquad automatisch bugs, crashes,\nen basisgebruik info naar de ontwikkelaar rapporteert?\n\nDeze gegevens bevatten geen persoonlijke informatie\nen helpen om het spel soepel en bug-vrij te houden.", + "cancelText": "Annuleer", + "cantConfigureDeviceText": "Sorry, $ {DEVICE} niet configureerbaar.", + "challengeEndedText": "Deze uitdaging is beëindigd.", + "chatMuteText": "Chat negeren", + "chatMutedText": "berichten gedempt", + "chatUnMuteText": "maak de chat ongedaan", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "U moet dit level voltooien\nom door te gaan!", + "completionBonusText": "Voltooiing Bonus", + "configControllersWindow": { + "configureControllersText": "Configureer Controllers", + "configureGamepadsText": "Gamepads configureren", + "configureKeyboard2Text": "Configureer toetsenbord P2", + "configureKeyboardText": "Configureer Toetsenbord", + "configureMobileText": "Mobiele Apparaten als Controllers", + "configureTouchText": "Configureer Touchscreen", + "ps3Text": "PS3 Controllers", + "titleText": "Controllers", + "wiimotesText": "Wiimotes", + "xbox360Text": "Xbox 360 Controllers" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Opmerking: controller ondersteuning varieert per apparaat en de Android-versie.", + "pressAnyButtonText": "Druk op een knop van de controller\n  die u wilt configureren...", + "titleText": "Configureer Controllers" + }, + "configGamepadWindow": { + "advancedText": "Geavanceerd", + "advancedTitleText": "Geavanceerde Cotroller Configuratie", + "analogStickDeadZoneDescriptionText": "(zet deze aan als uw personage 'zweeft' als u de stick loslaat)", + "analogStickDeadZoneText": "Analoge Stick Dead Zone", + "appliesToAllText": "(geldt voor alle controllers van dit type)", + "autoRecalibrateDescriptionText": "(sta dit toe als uw personage niet beweegt op volle snelheid)", + "autoRecalibrateText": "Auto-Herkalibreer Analoge Stick", + "axisText": "as", + "clearText": "wissen", + "dpadText": "dpad", + "extraStartButtonText": "Extra Start Knop", + "ifNothingHappensTryAnalogText": "Als er niets gebeurt, probeer het dan in plaats daar van toe te toewijzen aan de analoge stick.", + "ifNothingHappensTryDpadText": "Als er niets gebeurt, probeer het dan in plaats daar van toe te wijzen aan de d-pad.", + "ignoreCompletelyDescriptionText": "(voorkom dat deze controller effect heeft op het spel of de menu's)", + "ignoreCompletelyText": "Negeer Volledig", + "ignoredButton1Text": "Genegeerde Knop 1", + "ignoredButton2Text": "Genegeerde Knop 2", + "ignoredButton3Text": "Genegeerde Knop 3", + "ignoredButton4Text": "Knop 4 genegeerd", + "ignoredButtonDescriptionText": "(gebruik deze om te voorkomen dat de 'home' of 'sync' invloed hebben op de UI)", + "ignoredButtonText": "Genegeerde Knop", + "pressAnyAnalogTriggerText": "Druk op een analoge trekker...", + "pressAnyButtonOrDpadText": "Druk op een knop of dpad...", + "pressAnyButtonText": "Druk een knop...", + "pressLeftRightText": "Druk links of rechts...", + "pressUpDownText": "Druk omhoog of omlaag...", + "runButton1Text": "Ren Knop 1", + "runButton2Text": "Ren Knop 2", + "runTrigger1Text": "Ren Activering 1", + "runTrigger2Text": "Ren Activering 2", + "runTriggerDescriptionText": "(analoge triggers laten u op variabele snelheid rennen)", + "secondHalfText": "Gebruik dit om de tweede helft te configureren\nvan een 2-controller-in-1 apparaat dat\nzich toont als een enkele controller.", + "secondaryEnableText": "Toestaan", + "secondaryText": "Secundaire Controller", + "startButtonActivatesDefaultDescriptionText": "(zet dit uit als uw start knop eerder een 'menu' knop is)", + "startButtonActivatesDefaultText": "Start Knop Activeert Standaard Widget", + "titleText": "Controller Instellingen", + "twoInOneSetupText": "2-in-1 Controller Instellingen", + "uiOnlyDescriptionText": "(voorkom dat deze controller meedoet in een spel)", + "uiOnlyText": "Limiteer tot menu gebruik", + "unassignedButtonsRunText": "Alle niet-toegewezen knoppen Ren", + "unsetText": "", + "vrReorientButtonText": "VR Heroriënteren Knop" + }, + "configKeyboardWindow": { + "configuringText": "Configuratie ${DEVICE}", + "keyboard2NoteText": "Opmerking: de meeste toetsenborden kunnen maar enkele\ntoetsaanslagen tegelijk registreren, dus het hebben van een\ntweede toetsenbord kan beter werken als er een apart toetsenbord\nis verbonden voor hen te gebruiken. Let op dat u nog steeds\ntoetsen moet toewijzen aan de tweede speler, zelfs in dit geval." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Actie Besturing Schaal", + "actionsText": "Acties", + "buttonsText": "knoppen", + "dragControlsText": "< sleep controls slepen om ze te herpositioneren >", + "joystickText": "stuurknuppel", + "movementControlScaleText": "Bewegings Besturing Schaal", + "movementText": "Beweging", + "resetText": "Herstel", + "swipeControlsHiddenText": "Verberg Swipe Iconen", + "swipeInfoText": "De 'veeg' stijl controls is even een beetje wennen, maar maakt\nhet makkelijker om te spelen zonder te kijken naar de besturing.", + "swipeText": "veeg", + "titleText": "Configureer Touchscreen", + "touchControlsScaleText": "Touch Besturing Schalen" + }, + "configureItNowText": "Nu configureren?", + "configureText": "Configureren", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Voor het beste resultaat heb u een vertraging-vrij wifi netwerk nodig. u\nkunt de wifi lag verminderen door het uitschakelen van andere\ndraadloze apparaten, door dicht bij uw wifi-router te spelen en door\nde spel host rechtstreeks aan te sluiten op het netwerk via ethernet.", + "explanationText": "Om een smartphone of tablet te gebruiken als een draadloze controller,\ninstalleer dan de \"${REMOTE_APP_NAME}\" app er op. Iedere hoeveelheid apparaten\nkan verbinding maken met een ${APP_NAME} spel via WiFi, en het is gratis!", + "forAndroidText": "voor Android:", + "forIOSText": "voor iOS:", + "getItForText": "Krijg de ${REMOTE_APP_NAME} voor iOS in de Apple App Store\nof voor Android in de Google Play Store of de Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Gebruik Mobiele Apparaten als Controllers:" + }, + "continuePurchaseText": "Voortzetten voor ${PRICE}?", + "continueText": "Voortzetten", + "controlsText": "Besturing", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Dit heeft geen invloed op de all-time klassement.", + "activenessInfoText": "Deze verdubbelaar stijgt op dagen dat je\nspeelt en zakt op dagen dat je niet speelt.", + "activityText": "Activiteit", + "campaignText": "Campagne", + "challengesInfoText": "Verdien prijzen door minigames te voltooien.\n\nPrijzen en moeilijkheidsgraden verhogen\nelke keer een uitdaging is gehaald en\nhet verlaagd als er een verloopt of is opgegeven.", + "challengesText": "Uitdagingen", + "currentBestText": "Huidige Beste", + "customText": "Aangepast", + "entryFeeText": "Inschrijving", + "forfeitConfirmText": "Deze uitdaging opgeven?", + "forfeitNotAllowedYetText": "Deze uitdaging kan nog niet opgegeven worden.", + "forfeitText": "Opgeven", + "multipliersText": "Vermenigvuldigers", + "nextChallengeText": "Volgende Uitdaging", + "nextPlayText": "Volgende spel", + "ofTotalTimeText": "van ${TOTAL}", + "playNowText": "Speel Nu", + "pointsText": "Punten", + "powerRankingFinishedSeasonUnrankedText": "(Afgerond seizoen geen rangschikking)", + "powerRankingNotInTopText": "(niet in de top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} ptn", + "powerRankingPointsMultText": "(x ${NUMBER} ptn)", + "powerRankingPointsText": "${NUMBER} ptn", + "powerRankingPointsToRankedText": "(${CURRENT} van de ${REMAINING} ptn)", + "powerRankingText": "Macht Klassement", + "prizesText": "Prijzen", + "proMultInfoText": "Spelers met de ${PRO} opwaardering\nkrijgen een ${PERCENT}% punten boost hier.", + "seeMoreText": "Meer...", + "skipWaitText": "Sla wachten over", + "timeRemainingText": "Resterende Tijd", + "titleText": "Coöperatief", + "toRankedText": "Naar Rankschikking", + "totalText": "totaal", + "tournamentInfoText": "Strijd voor de highscores tegen andere spelers in jou competitie. \n\nPrijzen zijn bekroond aan de hoogst scorende spelers waneer de toernooi tijd voorbij is.", + "welcome1Text": "Welkom bij ${LEAGUE}. U kan uw competitie rang\nverbeteren door sterren te verdienen,\nprestaties te voltooien en met het winnen van trofeeën in toernooien.", + "welcome2Text": "U kunt ook tickets verdienen van veel van dezelfde activiteiten.\nTickets kunnen gebruikt worden om mee te doen aan toernooien,\nvoor het vrijspelen van nieuwe karakters, speelvelden, mini-spellen en meer.", + "yourPowerRankingText": "Uw Macht Klassement:" + }, + "copyOfText": "${NAME} Kopie", + "copyText": "Kopiëren", + "copyrightText": "© 2013 Eric Froemling", + "createAPlayerProfileText": "Speler profiel aanmaken?", + "createEditPlayerText": "", + "createText": "Maak", + "creditsWindow": { + "additionalAudioArtIdeasText": "Additionele Audio, Eerdere Illustraties, en Ideeën door ${NAME}", + "additionalMusicFromText": "Additionele muziek van ${NAME}", + "allMyFamilyText": "All mijn vrienden en familie die hebben geholpen met testen", + "codingGraphicsAudioText": "Programmeren, Illustraties, en Audio door ${NAME}", + "languageTranslationsText": "Vertalingen:", + "legalText": "Legaliteiten:", + "publicDomainMusicViaText": "Rechtenvrije muziek via ${NAME}", + "softwareBasedOnText": "Deze software is deels gebaseerd op het werk van ${NAME}", + "songCreditText": "${TITLE} Uitgevoerd door ${PERFORMER}\nGecomposeerd door ${COMPOSER}, Gearrangeerd door ${ARRANGER},\nGepubliceerd oor ${PUBLISHER}, Met dank aan ${SOURCE}", + "soundAndMusicText": "Geluid & Muziek:", + "soundsText": "Geluiden (${SOURCE}):", + "specialThanksText": "Speciale Dank:", + "thanksEspeciallyToText": "Vooral mijn dank aan ${NAME}", + "titleText": "${APP_NAME} Credits", + "whoeverInventedCoffeeText": "Wie dan ook koffie heeft uitgevonden" + }, + "currentStandingText": "Je huidige rang is #${RANK}", + "customizeText": "Aanpassen...", + "deathsTallyText": "${COUNT} sterfgevallen", + "deathsText": "Sterfgevallen", + "debugText": "foutopsporing", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Opmerking: het wordt aanbevolen dat u Instellingen->Grafisch->Texturen op 'Hoog' zet als u dit test.", + "runCPUBenchmarkText": "Voer CPU Maatstaaf Uit", + "runGPUBenchmarkText": "Voer GPU Maatstaaf Uit", + "runMediaReloadBenchmarkText": "Voer Media-Herlaad Maatstaaf Uit", + "runStressTestText": "Voer stress test uit", + "stressTestPlayerCountText": "Spelers Aantal", + "stressTestPlaylistDescriptionText": "Stress Test Speellijst", + "stressTestPlaylistNameText": "Speellijst Naam", + "stressTestPlaylistTypeText": "Speellijst Type", + "stressTestRoundDurationText": "Ronde Duratie", + "stressTestTitleText": "Stress test", + "titleText": "Maatstaven & Stress Tests", + "totalReloadTimeText": "Totale herlaad tijd: ${TIME} (zie log voor details)", + "unlockCoopText": "Ontgrendel coöperatieve levels" + }, + "defaultFreeForAllGameListNameText": "Standaard Ieder-voor-Zich Spellen", + "defaultGameListNameText": "Standaard ${PLAYMODE} Speellijst", + "defaultNewFreeForAllGameListNameText": "Mijn Ieder-voor-Zich Spellen", + "defaultNewGameListNameText": "Mijn ${PLAYMODE} Speellijsten", + "defaultNewTeamGameListNameText": "Mijn Team Spellen", + "defaultTeamGameListNameText": "Standaard Team Spellen", + "deleteText": "Verwijder", + "demoText": "demonstratie", + "denyText": "Weigeren", + "desktopResText": "Bureaublad Resolutie", + "difficultyEasyText": "Makkelijk", + "difficultyHardOnlyText": "Alleen moeilijk", + "difficultyHardText": "Moeilijk", + "difficultyHardUnlockOnlyText": "Dit level kan alleen in moeilijke modus vrij gespeeld worden.\nDurf je het aan!?!?!", + "directBrowserToURLText": "Gebruik een web browser om het volgende adres te bezoeken:", + "disableRemoteAppConnectionsText": "Schakel Afstandsbediening-App connecties uit", + "disableXInputDescriptionText": "Staat meer dan 4 controllers toe, maar werkt misschien niet helemaal goed.", + "disableXInputText": "Schakel XInput uit", + "doneText": "Klaar", + "drawText": "Gelijk", + "duplicateText": "Kopieer", + "editGameListWindow": { + "addGameText": "Voeg\nSpel\nToe", + "cantOverwriteDefaultText": "Kan de standaard speellijst niet overschrijven!", + "cantSaveAlreadyExistsText": "Er bestaat al een speellijst met die naam!", + "cantSaveEmptyListText": "Kan een lege speellijst niet opslaan!", + "editGameText": "Spel\nBewerken", + "gameListText": "Spellen Lijst", + "listNameText": "Speellijst Naam", + "nameText": "Naam", + "removeGameText": "Verwijder\nSpel", + "saveText": "Lijst Opslaan", + "titleText": "Speellijst Bewerker" + }, + "editProfileWindow": { + "accountProfileInfoText": "Dit speciale profiel heeft een naam en een pictogram gabaseerd op je profiel. \n\n${ICONS}\n\nCreëer aangepaste profielen als je andere namen en pictogrammen wilt gebruiken.", + "accountProfileText": "(gebruiker profiel)", + "availableText": "De naam \"${NAME}\" is beschikbaar.", + "changesNotAffectText": "Let op: aanpassingen hebben geen invloed op karakters die al in het spel zijn", + "characterText": "karakter", + "checkingAvailabilityText": "Controleren van beschikbaarheid voor \"${NAME}\"...", + "colorText": "kleur", + "getMoreCharactersText": "Verkrijg Meer Karakters...", + "getMoreIconsText": "Krijg Meer Pictogrammen...", + "globalProfileInfoText": "Globale speler profielen hebben gegarandeerd een unieke\nnaam wereldwijd. Ze hebben ook aangepaste pictogrammen.", + "globalProfileText": "(globaal profiel)", + "highlightText": "highlight", + "iconText": "pictogram", + "localProfileInfoText": "Lokale speler profielen hebben geen pictogrammen en hun namen zijn\nniet gegarandeerd uniek. Waardeer op naar een globaal profiel om een unieke\nnaam te krijgen en om een aangepast pictogram toe te voegen.", + "localProfileText": "(lokaal profiel)", + "nameDescriptionText": "Speler Naam", + "nameText": "Naam", + "randomText": "willekeurig", + "titleEditText": "Profiel Aanpassen", + "titleNewText": "Nieuw Profiel", + "unavailableText": "\"${NAME}\" is niet beschikbaar; probeer een andere naam.", + "upgradeProfileInfoText": "Hier door krijg je een wereld wijde speler naam\nen u kunt een aangepast pictogram toewijzen.", + "upgradeToGlobalProfileText": "Waardeer op naar Globaal Profiel" + }, + "editProfilesAnyTimeText": "(Je kan profielen altijd aanpassen in 'instellingen')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "U kunt de standaard muzieklijst niet verwijderen.", + "cantEditDefaultText": "Kan standaard muzieklijst niet bewerken. Dupliceer het of maak een nieuwe.", + "cantEditWhileConnectedOrInReplayText": "Kan muzieklijsten niet aanpassen als je verbonden bent met een partij of in een herhaling.", + "cantOverwriteDefaultText": "Kan standaard muzieklijst niet overschrijven", + "cantSaveAlreadyExistsText": "Er bestaat al een muzieklijst met die naam!", + "copyText": "Kopiëren", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Standaard Muzieklijst", + "deleteConfirmText": "Verwijder Muzieklijst:\n\n'${NAME}'?", + "deleteText": "Verwijder\nMuzieklijst", + "duplicateText": "Dupliceer\nMuzieklijst", + "editSoundtrackText": "Muzieklijst Bewerker", + "editText": "Bewerk Muzieklijst", + "fetchingITunesText": "afspeellijsten van Muziek-app ophalen ...", + "musicVolumeZeroWarning": "Waarschuwing: muziek volume is ingesteld op 0", + "nameText": "Naam", + "newSoundtrackNameText": "Mijn Muzieklijst ${COUNT}", + "newSoundtrackText": "Nieuwe Muzieklijst:", + "newText": "Nieuwe\nMuzieklijst", + "selectAPlaylistText": "Selecteer Een Afspeellijst", + "selectASourceText": "Muziek Bron", + "soundtrackText": "SoundTrack", + "testText": "test", + "titleText": "Muzieklijsten", + "useDefaultGameMusicText": "Standaard Spel Muziek", + "useITunesPlaylistText": "Muziek app afspeellijst", + "useMusicFileText": "Muziek Bestand (mp3, etc)", + "useMusicFolderText": "Map met Muziek Bestanden" + }, + "editText": "Bewerk", + "endText": "Einde", + "enjoyText": "Geniet!", + "epicDescriptionFilterText": "${DESCRIPTION} In epische slow motion.", + "epicNameFilterText": "Epische ${NAME}", + "errorAccessDeniedText": "toegang geweigerd", + "errorOutOfDiskSpaceText": "schuifruimte vol", + "errorText": "Fout", + "errorUnknownText": "onbekende fout", + "exitGameText": "${APP_NAME} Verlaten?", + "exportSuccessText": "'${NAME}' geëxporteerd.", + "externalStorageText": "Externe Opslag", + "failText": "Faal", + "fatalErrorText": "Uh oh; er mist iets of is kapot.\nInstalleer de app opnieuw, of\nvraag ${EMAIL} voor hulp.", + "fileSelectorWindow": { + "titleFileFolderText": "Selecteer een Map of Bestand", + "titleFileText": "Selecteer een Bestand", + "titleFolderText": "Selecteer een Map", + "useThisFolderButtonText": "Gebruik Deze Map" + }, + "filterText": "Filteren", + "finalScoreText": "Uiteindelijke Score", + "finalScoresText": "Uiteindelijke Scores", + "finalTimeText": "Uiteindelijke Tijd", + "finishingInstallText": "Installatie afwerken; een moment...", + "fireTVRemoteWarningText": "* Voor een betere ervaring:\ngebruik een Spel Controller of installeer de\n'${REMOTE_APP_NAME}' app op uw telefoon\nof tablet.", + "firstToFinalText": "Eerste-tot-${COUNT} Finale", + "firstToSeriesText": "Eerste-tot-${COUNT} Serie", + "fiveKillText": "VIJF DODEN!", + "flawlessWaveText": "Foutloze Golf!", + "fourKillText": "QUAD DOOD!!!", + "freeForAllText": "Ieder-voor-Zich", + "friendScoresUnavailableText": "Scores van vrienden onbeschikbaar.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Spel ${COUNT} Leiders", + "gameListWindow": { + "cantDeleteDefaultText": "U kunt de standaard speellijst niet verwijderen!", + "cantEditDefaultText": "Kan de standaard speellijst niet bewerken! Dupliceren het of maak een nieuwe.", + "cantShareDefaultText": "Je kan de standaard afspeellijst niet delen.", + "deleteConfirmText": "Verwijder \"${LIST}\"?", + "deleteText": "Verwijder\nSpeellijst", + "duplicateText": "Dupliceer\nSpeellijst", + "editText": "Bewerk\nSpeellijst", + "gameListText": "Spellen Lijst", + "newText": "Nieuwe\nSpeellijst", + "showTutorialText": "Uitleg Weergeven", + "shuffleGameOrderText": "Willekeurige Spel Volgorde", + "titleText": "Pas ${TYPE} Speellijst aan" + }, + "gameSettingsWindow": { + "addGameText": "Voeg Spel Toe" + }, + "gamepadDetectedText": "1 controler gedetecteerd", + "gamepadsDetectedText": "${COUNT} controllers gedetecteerd.", + "gamesToText": "${WINCOUNT} spellen tegen ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Onthoud: elk apparaat in een partij kan meer\ndan een speler hebben als u genoeg controllers hebt.", + "aboutDescriptionText": "Gebruik deze tabbladen om een partij samen te stellen.\n\nMet partijen kan u spellen en toernooien spelen\nmet uw vrienden op een ander apparaat.\n\nGebruik de ${PARTY} knop rechtsbovenaan om\nte chatten met uw partij.\n(bij een controller , druk ${BUTTON} als u in een menu bent)", + "aboutText": "Over", + "addressFetchErrorText": "", + "appInviteInfoText": "Nodig vrienden uit om BombSquad te proberen en ze\nkrijgen ${COUNT} gratis tickets. U verdient\n${YOU_COUNT} voor iedere vriend die dat doet.", + "appInviteMessageText": "${NAME} heeft je ${COUNT} tickets gegeven in ${APP_NAME}", + "appInviteSendACodeText": "Zendt Ze Een Code", + "appInviteTitleText": "${APP_NAME} app uitnodiging", + "bluetoothAndroidSupportText": "(werkt met elk Android apparaat met Bluetooth)", + "bluetoothDescriptionText": "Host/deelnemen aan een partij via Bluetooth:", + "bluetoothHostText": "Host via Bluetooth", + "bluetoothJoinText": "Neem deel via Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "controleren...", + "copyCodeConfirmText": "Code gekopieerd naar klembord", + "copyCodeText": "Kopieer Code", + "dedicatedServerInfoText": "Voor het beste resultaat, zet dan een dedicated server op. Zie bombsquadgame.com/server om te leren hoe.", + "disconnectClientsText": "Hierdoor verbreekt de verbinding met ${COUNT} spelers(s)\nvan uw partij. Weet u het zeker?", + "earnTicketsForRecommendingAmountText": "Vrienden ontvangen ${COUNT} tickets als ze het spel proberen\n(en jij ontvangt ${YOU_COUNT} voor elke vriend die dit doet)", + "earnTicketsForRecommendingText": "Deel de game \nVoor gratis tickets...", + "emailItText": "Mail het", + "favoritesSaveText": "Opslaan Als Favoriet", + "favoritesText": "Favorieten", + "freeCloudServerAvailableMinutesText": "Volgende gratis cloud server beschikbaar in ${MINUTES} minuten.", + "freeCloudServerAvailableNowText": "Volgende gratis cloud server beschikbaar!", + "freeCloudServerNotAvailableText": "Geen gratis cloud server beschikbaar.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} tickets van ${NAME}", + "friendPromoCodeAwardText": "Je krijgt ${COUNT} tickets elke keer het is gebruikt.", + "friendPromoCodeExpireText": "Deze code zal vervallen in ${EXPIRE_HOURS} uren en werkt alleen met nieuwe spelers.", + "friendPromoCodeInstructionsText": "Om het te gebruiken, open je ${APP_NAME} en ga je naar 'Instellingen-> Geavanceerd-> Voer code in'.\nZie bombsquadgame.com voor downloadlinks voor alle ondersteunde platforms.", + "friendPromoCodeRedeemLongText": "Het kan ingewisseld worden voor ${COUNT} gratis tickets met tot en met ${MAX_USES} mensen.", + "friendPromoCodeRedeemShortText": "Het kan ingewisseld worden voor ${COUNT} in het spel", + "friendPromoCodeWhereToEnterText": "(in \"Instellingen-> Geavanceerd-> Voer code in\")", + "getFriendInviteCodeText": "Krijg een uitnodigingscode", + "googlePlayDescriptionText": "Nodig Google Play spelers uit voor uw partij:", + "googlePlayInviteText": "Uitnodigen", + "googlePlayReInviteText": "Er zijn ${COUNT} Google Play speler(s) in uw partij\nwaarbij de verbinding verbreek als je een nieuwe uitnodiging start.\nVoeg ze bij de nieuwe uitnodiging toe om ze er bij te houden.", + "googlePlaySeeInvitesText": "Zie Uitnodigingen", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play versie)", + "hostPublicPartyDescriptionText": "Accommodeer een Publieke Partij", + "hostingUnavailableText": "Gastheer Niet beschikbaar", + "inDevelopmentWarningText": "Let op:\n\nNetwerk spel is een nieuwe functie in ontwikkeling.\nVoor nu wordt het streng aangeraden dat alle\nspelers op het zelfde Wi-Fi netwerk zijn.", + "internetText": "Internet", + "inviteAFriendText": "Hebben je vrienden dit spel niet?\nNodig ze uit om het uit te proberen en ze krijgen ${COUNT} gratis tickets.", + "inviteFriendsText": "Nodig vrienden uit", + "joinPublicPartyDescriptionText": "Meedoen aan een Publieke Partij", + "localNetworkDescriptionText": "Word lid van een feest in de buurt (LAN, Bluetooth, meer)", + "localNetworkText": "Lokaal Netwerk", + "makePartyPrivateText": "Maak mijn Partij Privé", + "makePartyPublicText": "Maak Mijn Partij Publiek", + "manualAddressText": "Adres", + "manualConnectText": "Verbind", + "manualDescriptionText": "Neem deel aan een partij via adres", + "manualJoinSectionText": "Deelnemen op adres", + "manualJoinableFromInternetText": "Kunnen mensen deelnemen via het internet?:", + "manualJoinableNoWithAsteriskText": "NEE*", + "manualJoinableYesText": "JA", + "manualRouterForwardingText": "*om dit op te lossen, probeer uw router te configureren om UDP port ${PORT} door te sturen naar uw lokale adres", + "manualText": "Handmatig", + "manualYourAddressFromInternetText": "Uw adres via het internet:", + "manualYourLocalAddressText": "Uw lokale adres:", + "nearbyText": "Dichtbij", + "noConnectionText": "", + "otherVersionsText": "(andere versies)", + "partyCodeText": "Partijcode", + "partyInviteAcceptText": "Accepteren", + "partyInviteDeclineText": "Weigeren", + "partyInviteGooglePlayExtraText": "(bekijk het 'Google Play' tabblad in het 'Verzamel' venster)", + "partyInviteIgnoreText": "Negeren", + "partyInviteText": "${NAME} heeft je uitgenodigd\nom bij zijn partij te voegen!", + "partyNameText": "Partij Naam", + "partyServerRunningText": "Uw partyserver is actief.", + "partySizeText": "partij grootte", + "partyStatusCheckingText": "status controleren...", + "partyStatusJoinableText": "uw partij is nu toegankelijk via het internet", + "partyStatusNoConnectionText": "kan geen verbinding maken met server", + "partyStatusNotJoinableText": "uw partij is niet toegankelijk via het internet", + "partyStatusNotPublicText": "uw partij is niet publiek", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Privaat partijen draaien op toegewijd cloud servers; geen routerconfiguratie vereist.", + "privatePartyHostText": "Organiseer een Privefeestje", + "privatePartyJoinText": "Lid worden Privefeestje", + "privateText": "Privaat", + "publicHostRouterConfigText": "Hiervoor moet mogelijk port-forwarding op uw router worden geconfigureerd. Voor een gemakkelijkere optie, organiseer een privéfeest.", + "publicText": "Openbaar", + "requestingAPromoCodeText": "Code aanvragen...", + "sendDirectInvitesText": "Verzend directe uitnodigingen", + "shareThisCodeWithFriendsText": "Deel deze code met vrienden:", + "showMyAddressText": "Toon Mijn Adres", + "startAdvertisingText": "Begin Adverteren", + "startHostingPaidText": "Host nu voor ${COST}", + "startHostingText": "Gastheer", + "startStopHostingMinutesText": "Je kunt de komende ${MINUTES} minuten gratis starten en stoppen met hosten.", + "stopAdvertisingText": "Stop Adverteren", + "stopHostingText": "Stoppen Gastheer Partij", + "titleText": "Verzamel", + "wifiDirectDescriptionBottomText": "Als alle apparaten een 'Wi-Fi Direct' paneel hebben, dan zou het mogelijk moeten zijn\nom ze te vinden en verbinden met elkaar. Als alle apparaten verbonden zijn, kan u hier\npartijen vormen via het 'Lokaal Netwerk' tab, net als bij een normaal Wi-Fi netwerk.\n\nVoor het beste resultaat zou de Wi-Fi Direct host ook de host moeten zijn van de ${APP_NAME} partij.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct kan gebruikt worden om directe verbinding te maken tussen Android apparaten zonder\ngebruik te maken van een Wi-Fi netwerk. Dit werkt het best bij Android 4.2 of nieuwer.\n\nOm het te gebruiken, open de Wi-Fi instellingen en zoek voor 'Wi-Fi Direct' in het menu.", + "wifiDirectOpenWiFiSettingsText": "Open Wi-Fi Instellingen", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(Werkt tussen alle platformen)", + "worksWithGooglePlayDevicesText": "(werkt met apparaten de de Google Play (android) versie van het spel gebruiken.", + "youHaveBeenSentAPromoCodeText": "Je hebt een ${APP_NAME} promo code gekregen:" + }, + "getCoinsWindow": { + "coinDoublerText": "Munten Verdubbelaar", + "coinsText": "${COUNT} Munten", + "freeCoinsText": "Gratis Munten", + "restorePurchasesText": "Aanschaf Herstellen", + "titleText": "Munten Aanschaffen" + }, + "getTicketsWindow": { + "freeText": "GRATIS!", + "freeTicketsText": "Gratis Tickets", + "inProgressText": "Er wordt al een transactie verwerkt; probeer het later opnieuw.", + "purchasesRestoredText": "Aankopen hersteld.", + "receivedTicketsText": "${COUNT} tickets ontvangen!", + "restorePurchasesText": "Herstel Aanschafte Items", + "ticketDoublerText": "Ticket Verdubbelaar", + "ticketPack1Text": "Klein Ticket Pakket", + "ticketPack2Text": "Medium Ticket Pakket", + "ticketPack3Text": "Olifanten Ticket Pakket", + "ticketPack4Text": "Jumbo Ticket Pakket", + "ticketPack5Text": "Mammoeten Ticket Pakket", + "ticketPack6Text": "Ultieme Ticket Pakket", + "ticketsFromASponsorText": "Krijg ${COUNT} tickets\nvan een sponsor", + "ticketsText": "${COUNT} Tickets", + "titleText": "Tickets Verkrijgen", + "unavailableLinkAccountText": "Sorry, aankopen zijn niet beschikbaar op dit platform.\nAls een omweg, kan je dit account verbinden met een account\nop een ander platform en daar de aankoop doen.", + "unavailableTemporarilyText": "Dit is niet beschikbaar op dit moment; probeer het laten opnieuw.", + "unavailableText": "Sorry, dit is niet beschikbaar.", + "versionTooOldText": "Sorry, deze versie van het spel is te oud; update naar een nieuwere versie.", + "youHaveShortText": "Je hebt ${COUNT}", + "youHaveText": "U heeft ${COUNT} tickets" + }, + "googleMultiplayerDiscontinuedText": "Sorry, de Google Play multi-player functie is nu even niet beschikbaar. \nIk werk hard aan een vervanger. \nProbeer nu alsjeblieft een andere connectie mogelijkheid.\n-Eric", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Altijd", + "fullScreenCmdText": "Volledig scherm (Cmd-F)", + "fullScreenCtrlText": "Volledig scherm (Cmd-F)", + "gammaText": "Gamma", + "highText": "Hoog", + "higherText": "Hoger", + "lowText": "Laag", + "mediumText": "Gemiddeld", + "neverText": "Nooit", + "resolutionText": "Resolutie", + "showFPSText": "Toon FPS", + "texturesText": "Texturen", + "titleText": "Grafisch", + "tvBorderText": "TV Grens", + "verticalSyncText": "Verticale Sync", + "visualsText": "Visuele" + }, + "helpWindow": { + "bombInfoText": "- Bom -\nSterker dan slagen, maar kan\nresulteren in ernstige zelfverwonding.\nVoor het beste resultaat, gooi richting\nvijand voordat lont op raakt.", + "canHelpText": "${APP_NAME} kan helpen.", + "controllersInfoText": "U kan ${APP_NAME} spelen met vrienden via een netwerk, of u\nkan het allemaal op hetzelfde apparaat spelen als u genoeg controllers hebt.\n${APP_NAME} ondersteunt er een verscheidenheid van; u kunt zelfs uw telefoons\nals controller gebruiken met de gratis '${REMOTE_APP_NAME}' app.\nZie Instellingen->Controllers voor meer info.", + "controllersInfoTextFantasia": "Een speler kan de afstandbediening gebruiken als controller,\nmaar gamepads zijn sterk aanbevolen. Je kunt ook mobiele-apparaten\ngebruiken als controllers via de gratis 'Bombsquad Remote' app.\nZie 'Controllers' onder 'Instellingen' voor meer info.", + "controllersInfoTextMac": "Een of twee spelers kunnen gebruik maken van het toetsenbord, maar Bombsquad is het beste met gamepads.\nBombsquad kan gebruik maken van USB gamepads, PS3 controllers, Xbox 360 controllers, gebruik\nWiimotes en iOS / Android-apparaten om de karakters te besturen. Hopelijk heb je\neen aantal van deze bij de hand. Zie 'Controllers' onder 'Instellingen' voor meer info.", + "controllersInfoTextOuya": "U kunt OUYA controllers, PS3 controllers, Xbox 360 controllers, \nen tal van andere USB-en Bluetooth-gamepads gebruiken met Bombsquad.\nU kunt ook iOS-en Android-apparaten gebruiken als controllers via de gratis\n'Bombsquad Remote' app. Zie 'Controllers' onder 'Instellingen' voor meer info.", + "controllersInfoTextRemoteOnly": "Je kunt ${APP_NAME} spelen met vrienden via een netwerk, of jij\nkunnen allemaal op hetzelfde apparaat spelen door telefoons te gebruiken als\ncontrollers via de gratis app '${REMOTE_APP_NAME}'.", + "controllersText": "Controllers", + "controlsSubtitleText": "Uw vriendelijke ${APP_NAME} personage heeft een aantal basis acties:", + "controlsText": "Besturing", + "devicesInfoText": "De VR versie van ${APP_NAME} kan gespeeld worden via het netwerk met\nde reguliere versie, dus grijp uw extra telefoons, tablets\nen computers en begin met spelen. Het kan ook nuttig zijn om\nmet een reguliere versie van het spel verbinding te maken met de VR versie\nzodat mensen van buitenaf de actie mee kunnen kijken.", + "devicesText": "Apparaten", + "friendsGoodText": "Deze zijn goed om te hebben. ${APP_NAME} is het leukste met\nmeerdere spelers en kan tot en met 8 spelers tegelijk ondersteunen, dit brengt ons naar:", + "friendsText": "Vrienden", + "jumpInfoText": "- Springen -\nSpring over kleine openingen,\nom dingen hoger te gooien, en om\ngevoelens van vreugde uit te drukken.", + "orPunchingSomethingText": "Of iets slaan, van een klif gooien, en op de weg naar beneden opblazen met een kleverige bom.", + "pickUpInfoText": "- Op Pakken -\nPak vlaggen, vijanden, of iets\nanders niet vastgeschroefd aan de\ngrond. Druk opnieuw om te gooien.", + "powerupBombDescriptionText": "Laat u drie bommen opzwepen\nachter elkaar in plaats van maar een.", + "powerupBombNameText": "Drievoudige-Bommen", + "powerupCurseDescriptionText": "Waarschijnlijk wilt u deze te vermijden.\n  ...of toch niet?", + "powerupCurseNameText": "Vloek", + "powerupHealthDescriptionText": "Herstelt u naar volledige gezondheid.\nU zou het nooit geraden hebben.", + "powerupHealthNameText": "Med-Pack", + "powerupIceBombsDescriptionText": "Zwakker dan normale bommen\nmaar bevriest u vijanden en\nmaakt ze zeer breekbaar.", + "powerupIceBombsNameText": "IJs-bommen", + "powerupImpactBombsDescriptionText": "Iets zwakker dan gewone\nbommen, maar ze ontploffen bij inslag.", + "powerupImpactBombsNameText": "Trigger-Bommen", + "powerupLandMinesDescriptionText": "Deze komen in verpakkingen van 3;\nNuttig voor basis defensie of\nbij het stoppen snelle vijanden.", + "powerupLandMinesNameText": "Land-Mijnen", + "powerupPunchDescriptionText": "Maakt u slagen harder,\nsneller, beter en sterker.", + "powerupPunchNameText": "Box-Handschoenen", + "powerupShieldDescriptionText": "Absorbeert een beetje schade\nzodat jij dat niet hoeft te doen.", + "powerupShieldNameText": "Energie-Schild", + "powerupStickyBombsDescriptionText": "Plakt aan alles wat ze raken.\nHilariteit volgt.", + "powerupStickyBombsNameText": "Plak-Bommen", + "powerupsSubtitleText": "Natuurlijk, geen spel is compleet zonder power-ups:", + "powerupsText": "power-ups", + "punchInfoText": "- Slaan -\nSlaan doet meer schade hoe\nsneller uw vuisten bewegen, dus\nrennen en draaien als een dolle.", + "runInfoText": "- Ren -\nHoud een knop om te rennen. Triggers of schouderknoppen werken goed als u ze hebt. Rennen krijgt\nu sneller op andere plaatsen, maar maakt het moeilijk om te draaien, dus kijk uit voor kliffen.", + "someDaysText": "Sommige dagen heeft u gewoon het gevoel dat u iets moet slaan. Of om iets op te blazen.", + "titleText": "${APP_NAME} Help", + "toGetTheMostText": "Om het meeste uit het spel te halen, heeft u dit nodig:", + "welcomeText": "Welkom bij ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} is aan het navigeren als een baas -", + "importPlaylistCodeInstructionsText": "Gebruik de volgende code om deze afspeellijst ergens anders the importeren:", + "importPlaylistSuccessText": "${TYPE} afspeellijst '${NAME}' geïmporteerd", + "importText": "Importeer", + "importingText": "Aan het importeren...", + "inGameClippedNameText": "zal in-game worden\n\"${NAME}\"", + "installDiskSpaceErrorText": "FOUT: Niet in staat om de installatie te voltooien.\nHet kan zijn dat er gaan ruimte meer is op uw apparaat.\nMaak wat vrij en probeer opnieuw.", + "internal": { + "arrowsToExitListText": "druk ${LEFT} of ${RIGHT} om de lijst te verlaten", + "buttonText": "knop", + "cantKickHostError": "Je kan de host niet eruit schoppen.", + "chatBlockedText": "${NAME} is chat-geblokkeerd voor ${TIME} seconden.", + "connectedToGameText": "Verbonden met '${NAME}'", + "connectedToPartyText": "Deelgenomen aan ${NAME}'s partij!", + "connectingToPartyText": "Verbinden...", + "connectionFailedHostAlreadyInPartyText": "Verbinding mislukt; host is in een andere partij.", + "connectionFailedPartyFullText": "Connectie mislukt; de partij is vol.", + "connectionFailedText": "Verbinding mislukt.", + "connectionFailedVersionMismatchText": "Verbinding mislukt; host gebruikt een andere versie van het spel.\nZorg er voor dat u allebei up-to-date bent en probeer het opnieuw.", + "connectionRejectedText": "Verbinding afgekeurd.", + "controllerConnectedText": "${CONTROLLER} verbonden.", + "controllerDetectedText": "1 controller gedetecteerd", + "controllerDisconnectedText": "${CONTROLLER} verbinding verbroken.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} verbinding verbroken. Probeer opnieuw verbinding te maken alstublieft.", + "controllerForMenusOnlyText": "Deze controller kan niet gebruikt worden op te spelen; alleen voor het navigeren van menu's.", + "controllerReconnectedText": "${CONTROLLER} opnieuw aangesloten.", + "controllersConnectedText": "${COUNT} controllers verbonden.", + "controllersDetectedText": "${COUNT} controllers gedetecteerd.", + "controllersDisconnectedText": "Verbinding ${COUNT} controllers verbroken.", + "corruptFileText": "Verknoeide bestand(en) gedetecteerd. Probeer het opnieuw te installeren, of email ${EMAIL}", + "errorPlayingMusicText": "Fout tijdens het afspelen van: ${MUSIC}", + "errorResettingAchievementsText": "Resetten van uw online prestaties is mislukt; probeer het later nog eens.", + "hasMenuControlText": "${NAME} bestuurd nu het menu.", + "incompatibleNewerVersionHostText": "Host gebruikt een nieuwere versie van de game.\nUpdate naar de laatste versie en probeer opnieuw.", + "incompatibleVersionHostText": "Host gebruikt een andere versie van het spel; kan niet verbinden.\nZorg er voor dat u allebei up-to-date bent en probeer het opnieuw.", + "incompatibleVersionPlayerText": "${NAME} gebruikt een andere versie van het spel en kan niet verbinden.\nZorg er voor dat u allebei up-to-date bent en probeer het opnieuw.", + "invalidAddressErrorText": "Fout: Ongeldig adres.", + "invalidNameErrorText": "Fout: ongeldige naam.", + "invalidPortErrorText": "Fout: ongeldige port.", + "invitationSentText": "Uitnodiging verzonden.", + "invitationsSentText": "${COUNT} uitnodigingen verzonden.", + "joinedPartyInstructionsText": "Iemand doet mee in uw partij.\nGa naar 'Spelen' om een spel te starten.", + "keyboardText": "Toetsenbord", + "kickIdlePlayersKickedText": "${NAME} staat te lang stil en is verwijderd.", + "kickIdlePlayersWarning1Text": "${NAME} staat te lang stil en wordt over ${COUNT} seconden verwijderd.", + "kickIdlePlayersWarning2Text": "(u kunt dit uitschakelen in Instellingen > Geavanceerd)", + "leftGameText": "Je hebt '${NAME}' verlaten.", + "leftPartyText": "${NAME}'s partij verlaten.", + "noMusicFilesInFolderText": "De map bevat geen muziek bestanden.", + "playerJoinedPartyText": "${NAME} neemt deel aan de partij!", + "playerLeftPartyText": "${NAME} verliet de partij.", + "rejectingInviteAlreadyInPartyText": "Uitnodiging verworpen (al in een partij).", + "serverRestartingText": "De server start opnieuw op. Probeer het alsjeblieft nog een keer...", + "serverShuttingDownText": "De server is aan het sluiten...", + "signInErrorText": "Inlog fout", + "signInNoConnectionText": "Niet in staat om in te loggen. (geen internet verbinding?)", + "teamNameText": "Team ${NAME}", + "telnetAccessDeniedText": "FOUT: gebruiker heeft geen telnet toegang verleend.", + "timeOutText": "(tijd op in ${TIME} seconden)", + "touchScreenJoinWarningText": "U doet mee met een aanraakscherm.\nAls dit een vergissing was, druk er mee op 'Menu->Verlaat Spel'.", + "touchScreenText": "TouchScreen", + "trialText": "proefperiode", + "unableToResolveHostText": "Error: kan de host niet resolven.", + "unavailableNoConnectionText": "Dit is momenteel niet beschikbaar (geen internet verbinding?)", + "vrOrientationResetCardboardText": "Hiermee reset je de VR oriëntatie.\nOm het spel te spelen heb je een externe controller nodig.", + "vrOrientationResetText": "VR oriëntatie reset.", + "willTimeOutText": "(totdat u inactief bent)" + }, + "jumpBoldText": "SPRING", + "jumpText": "Spring", + "keepText": "houd", + "keepTheseSettingsText": "Deze instellingen behouden?", + "keyboardChangeInstructionsText": "Dubbelklik op de spatiebalk om van toetsenbord te wisselen.", + "keyboardNoOthersAvailableText": "Geen andere toetsenborden beschikbaar.", + "keyboardSwitchText": "Toetsenbord overschakelen naar '${NAME}'.", + "kickOccurredText": "${NAME} is eruit geschopt.", + "kickQuestionText": "${NAME} er uit schoppen?", + "kickText": "Er uit schoppen", + "kickVoteCantKickAdminsText": "Beheerders kunnen niet worden gekickt.", + "kickVoteCantKickSelfText": "Je kan jezelf niet kicken.", + "kickVoteFailedNotEnoughVotersText": "Te weinig spelers om te stemmen.", + "kickVoteFailedText": "Stemming om er uit te schoppen mislukt.", + "kickVoteStartedText": "Een stemming is begonnen om ${NAME} eruit te schoppen.", + "kickVoteText": "Tem op er uit te Schoppen", + "kickVotingDisabledText": "Kick stemmen is uitgeschakeld.", + "kickWithChatText": "Type ${YES} in de chat voor ja en ${NO} voor nee.", + "killsTallyText": "${COUNT} doden", + "killsText": "Doden", + "kioskWindow": { + "easyText": "Makkelijk", + "epicModeText": "Epische Modus", + "fullMenuText": "Volledig Menu", + "hardText": "Moeilijk", + "mediumText": "Medium", + "singlePlayerExamplesText": "Enkele Speler / Co-op Voorbeelden", + "versusExamplesText": "Tegen Elkaar Voorbeelden" + }, + "languageSetText": "De taal is nu \"${LANGUAGE}\".", + "lapNumberText": "Ronde ${CURRENT}/${TOTAL}", + "lastGamesText": "(laatste ${COUNT} spellen)", + "leaderboardsText": "Klassementen", + "league": { + "allTimeText": "Aller Tijde", + "currentSeasonText": "Huidig Seizoen (${NUMBER})", + "leagueFullText": "${NAME} Competitie", + "leagueRankText": "Competitie Rang", + "leagueText": "Competitie", + "rankInLeagueText": "#${RANK}, ${NAME} Tournooi${SUFFIX}", + "seasonEndedDaysAgoText": "Seizoen eindigde ${NUMBER} dagen geleden.", + "seasonEndsDaysText": "Seizoen eindigt in ${NUMBER} dagen.", + "seasonEndsHoursText": "Seizoen eindigt in ${NUMBER} uur.", + "seasonEndsMinutesText": "Seizoen eindigt in ${NUMBER} minuten.", + "seasonText": "Seizoen ${NUMBER}", + "tournamentLeagueText": "Haal de ${NAME} competitie om aan dit toernooi mee te doen.", + "trophyCountsResetText": "Trofee telling reset in het volgende seizoen." + }, + "levelBestScoresText": "Beste scores voor ${LEVEL}", + "levelBestTimesText": "Beste tijden voor ${LEVEL}", + "levelFastestTimesText": "Snelste tijden in ${LEVEL}", + "levelHighestScoresText": "Hoogste score in ${LEVEL}", + "levelIsLockedText": "${LEVEL} is vergrendeld.", + "levelMustBeCompletedFirstText": "${LEVEL} moet eerst voltooid worden.", + "levelText": "Level ${NUMBER}", + "levelUnlockedText": "Level Ontgrendeld!", + "livesBonusText": "Levens Bonus", + "loadingText": "laden", + "loadingTryAgainText": "Aan het laden; probeer later opnieuw...", + "macControllerSubsystemBothText": "Beide (niet aanbevolen)", + "macControllerSubsystemClassicText": "Klassiek", + "macControllerSubsystemDescriptionText": "(probeer dit te veranderen als je controllers niet werken)", + "macControllerSubsystemMFiNoteText": "Gemaakt-voor-iOS/Mac controller gedetecteerd;\nJe wilt misschien deze instellingen activeren in Instellingen -> Controllers", + "macControllerSubsystemMFiText": "Gemaakt-voor-iOS/Mac", + "macControllerSubsystemTitleText": "Controller Support", + "mainMenu": { + "creditsText": "Credits", + "demoMenuText": "Voorbeeld Menu", + "endGameText": "Beëindig Spel", + "exitGameText": "Verlaat Spel", + "exitToMenuText": "Verlaat naar menu?", + "howToPlayText": "Hoe te Spelen", + "justPlayerText": "(Alleen ${NAME})", + "leaveGameText": "Verlaat Spel", + "leavePartyConfirmText": "Echt de partij verlaten?", + "leavePartyText": "Verlaat Partij", + "leaveText": "Verlaten", + "quitText": "Verlaten", + "resumeText": "Hervatten", + "settingsText": "Instellingen" + }, + "makeItSoText": "Pas Toe", + "mapSelectGetMoreMapsText": "Verkrijg Meer Speelvelden...", + "mapSelectText": "Selecteer...", + "mapSelectTitleText": "${GAME} Gebieden", + "mapText": "Gebied", + "maxConnectionsText": "Max Connecties", + "maxPartySizeText": "Max Partij Grootte", + "maxPlayersText": "Max Spelers", + "modeArcadeText": "Speelhal Modus", + "modeClassicText": "Klassieke Modus", + "modeDemoText": "Demo Modus", + "mostValuablePlayerText": "Meest Waardevolle Speler", + "mostViolatedPlayerText": "Meest Geschonden Speler", + "mostViolentPlayerText": "Meest Gewelddadige Speler", + "moveText": "Bewegen", + "multiKillText": "${COUNT}-DOOD!!!", + "multiPlayerCountText": "${COUNT} spelers", + "mustInviteFriendsText": "Let op: U moet vrienden uitnodigen in\nhet \"${GATHER}\" paneel of verbind meer\ncontrollers om multiplayer te spelen.", + "nameBetrayedText": "${NAME} verraadde ${VICTIM}.", + "nameDiedText": "${NAME} ging dood.", + "nameKilledText": "${NAME} doodde ${VICTIM}.", + "nameNotEmptyText": "Naam kan niet leeg zijn!", + "nameScoresText": "${NAME} Scoort!", + "nameSuicideKidFriendlyText": "${NAME} had een ongelukje.", + "nameSuicideText": "${NAME} pleegde zelfmoord.", + "nameText": "Naam", + "nativeText": "van apparaat", + "newPersonalBestText": "Nieuw persoonlijk record!", + "newTestBuildAvailableText": "Er is een nieuwere testversie beschikbaar! (${VERSION} build ${BUILD}).\nDownload hier ${ADDRESS}", + "newText": "Nieuw", + "newVersionAvailableText": "Er is een nieuwere versie van ${APP_NAME} beschikbaar! (${VERSION})", + "nextAchievementsText": "Volgende Prestatie:", + "nextLevelText": "Volgend Level", + "noAchievementsRemainingText": "- geen", + "noContinuesText": "(geen voortzettingen)", + "noExternalStorageErrorText": "Geen externe opslag gevonden op dit apparaat", + "noGameCircleText": "Fout: niet aangemeld bij GameCircle", + "noJoinCoopMidwayText": "Je kan niet halverwegen inspringen bij coöperatieve spellen.", + "noProfilesErrorText": "U heeeft geen speler profielen, dus zit u vast aan '${NAME}'.\nGa naar Instellingen->Speler Profielen om een profiel te maken voor uzelf.", + "noScoresYetText": "Nog geen scores.", + "noThanksText": "Nee Bedankt", + "noTournamentsInTestBuildText": "PAS OP: De punten van deze test tournament worden niet meegerekend.", + "noValidMapsErrorText": "Geen geldige gebieden gevonden voor dit speltype.", + "notEnoughPlayersRemainingText": "Niet genoeg spelers over; stop en start een nieuw spel.", + "notEnoughPlayersText": "U heeft minstens ${COUNT} spelers nodig om dit spel te starten!", + "notNowText": "Niet Nu", + "notSignedInErrorText": "Je moet inloggen om dit te doen.", + "notSignedInGooglePlayErrorText": "Je moet ingelogd zijn met Google Play om dit te doen.", + "notSignedInText": "niet ingelogd", + "nothingIsSelectedErrorText": "Er is niks geselecteerd!", + "numberText": "#${NUMBER}", + "offText": "Uit", + "okText": "Ok", + "onText": "Aan", + "oneMomentText": "Een Moment..", + "onslaughtRespawnText": "${PLAYER} zal respawnen in golf ${WAVE}", + "orText": "${A} of ${B}", + "otherText": "Andere ...", + "outOfText": "(#${RANK} van de ${ALL})", + "ownFlagAtYourBaseWarning": "Uw eigen vlag moet in\nuw basis zijn om te scoren!", + "packageModsEnabledErrorText": "Netwerk-spel is niet toegestaan als lokale-pakket-aanpassingen zijn ingeschakeld (zie Instellingen->Geavanceerd)", + "partyWindow": { + "chatMessageText": "Chat Bericht", + "emptyText": "Uw partij is leeg", + "hostText": "(host)", + "sendText": "Verzenden", + "titleText": "Uw Partij" + }, + "pausedByHostText": "(Gepauzeerd door host)", + "perfectWaveText": "Perfecte Golf!", + "pickUpBoldText": "PAK OP", + "pickUpText": "Pak Op", + "playModes": { + "coopText": "Coöperatief", + "freeForAllText": "Ieder-voor-zich", + "multiTeamText": "Meerdere Teams", + "singlePlayerCoopText": "Single player / Co-op", + "teamsText": "Teams" + }, + "playText": "Speel", + "playWindow": { + "coopText": "Coöperatief", + "freeForAllText": "Ieder-voor-Zich", + "oneToFourPlayersText": "1-4 spelers", + "teamsText": "Teams", + "titleText": "Speel", + "twoToEightPlayersText": "2-8 spelers" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} zal aan het begin van de volgende ronde mee spelen.", + "playerInfoText": "Speler Info", + "playerLeftText": "${PLAYER} heeft het spel verlaten.", + "playerLimitReachedText": "Het speler limiet van ${COUNT} is bereikt; geen toetreders toegestaan​​.", + "playerLimitReachedUnlockProText": "Upgrade naar \"${PRO}\" in de winkel om te spelen met meer dan ${COUNT} spelers.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "U kunt uw account profiel niet verwijderen.", + "deleteButtonText": "Profiel\nVerwijderen", + "deleteConfirmText": "Verwijder '${PROFILE}'?", + "editButtonText": "Profiel\nBewerken", + "explanationText": "(Creëer aangepaste namen & uiterlijken voor dit account)", + "newButtonText": "Nieuw\nProfiel", + "titleText": "Speler Profielen" + }, + "playerText": "Speler", + "playlistNoValidGamesErrorText": "Deze speellijst bevat geen geldige vrijgespeelde spellen.", + "playlistNotFoundText": "speellijst niet gevonden", + "playlistText": "Afspeellijst", + "playlistsText": "Speellijsten", + "pleaseRateText": "Als u geniet van ${APP_NAME}, zou u dan een moment willen\nnemen om een waardering te geven of recensie te schrijven.\nDit geeft ons nuttige feedback voor toekomstige ontwikkelingen.\n\nBedankt!\n-eric", + "pleaseWaitText": "Even geduld...", + "pluginsDetectedText": "Nieuw contact gedecteerd. Schakel in/configureer in de instellingen.", + "pluginsText": "Contacten", + "practiceText": "Oefenen", + "pressAnyButtonPlayAgainText": "Druk een knop om opnieuw te spelen...", + "pressAnyButtonText": "Druk een knop om verder te gaan...", + "pressAnyButtonToJoinText": "druk een knop om mee te doen...", + "pressAnyKeyButtonPlayAgainText": "Druk een toets/knop om opnieuw te spelen...", + "pressAnyKeyButtonText": "Druk een toets/knop om verder te gaan...", + "pressAnyKeyText": "Druk een toets...", + "pressJumpToFlyText": "** Druk spring herhalend om te vliegen **", + "pressPunchToJoinText": "druk SLAAN om mee te doen...", + "pressToOverrideCharacterText": "druk op ${BUTTONS} om uw karakter te overschrijven", + "pressToSelectProfileText": "druk op ${BUTTONS} om een speler te selecteren", + "pressToSelectTeamText": "druk op ${BUTTONS} om een team te selecteren", + "profileInfoText": "Maak profielen voor jezelf en je vrienden\nom uw namen, karakteres en kleuren aan te passen.", + "promoCodeWindow": { + "codeText": "Code", + "codeTextDescription": "Promo Code", + "enterText": "Invoeren" + }, + "promoSubmitErrorText": "Fout bij het verzenden van code; Controleer je internetverbinding", + "ps3ControllersWindow": { + "macInstructionsText": "Schakel de stroom aan de achterkant van uw PS3, zorg ervoor\nBluetooth is ingeschakeld op uw Mac, verbind dan uw controller\naan uw Mac via een USB-kabel om de twee te koppelen. Van nu af aan, kunt\nu de home-knop van de controller gebruiken om het aan te sluiten op uw Mac\nin beide bedraad (USB) of draadloos (Bluetooth).\n\nOp sommige Macs kunt u worden gevraagd om een wachtwoord bij het koppelen.\nAls dit gebeurt, zie de volgende uitleg of google voor hulp.\n\n\n\n\nPS3 controllers die draadloos verbonden zijn worden weergegeven in de apparaten\nlijst in Systeemvoorkeuren-> Bluetooth. Het kan nodig zijn om ze te verwijderen\nuit die lijst wanneer u ze weer wilt gebruiken met uw PS3.\n\nZorg er ook voor om ze los te koppelen van Bluetooth als u deze niet\ngebruik of de accu's zal blijven leeg lopen.\n\nBluetooth zou 7 aangesloten apparaten aan moeten kunnen,\nal kan de snelheid variëren.", + "ouyaInstructionsText": "Om een PS3 controller met uw OUYA gebruiken, sluit u deze simpelweg aan een USB-kabel\nom deze te koppelen. Door dit te doen kunt u andere controllers los te koppelen, dan\nkunt u de OUYA opnieuw opstarten en de USB-kabel ontkoppel.\n\nVan nu af aan zou het mogelijk moeten zijn om de HOME-knop van de controller te gebruiken\nom hem draadloos te verbinden. Wanneer u klaar bent met spelen, houdt u de knop HOME\ngedurende 10 seconden ingedrukt om de controller uit te schakelen, anders kan het aan blijven\nen verspilt het batterijen.", + "pairingTutorialText": "koppeling instructievideo", + "titleText": "PS3-controllers gebruiken met ${APP_NAME}:" + }, + "publicBetaText": "PUBLIEKE BETA", + "punchBoldText": "SLAAN", + "punchText": "Slaan", + "purchaseForText": "Koop voor ${PRICE}", + "purchaseGameText": "Koop Spel", + "purchasingText": "Aanschaffen...", + "quitGameText": "${APP_NAME} Verlaten?", + "quittingIn5SecondsText": "Sluiten in 5 seconden...", + "randomPlayerNamesText": "DEFAULT_NAMES, Lucas, Finn, Thijs, Sam, Lars, Emma, Mila, Lieke, Lotte, Saar", + "randomText": "Willekeurig", + "rankText": "Rang", + "ratingText": "Waardering", + "reachWave2Text": "Bereik golf 2 om te kwalificeren.", + "readyText": "klaar", + "recentText": "Recent", + "remainingInTrialText": "nog in proefperiode", + "remoteAppInfoShortText": "${APP_NAME} is het leuks met familie en vrienden.\nVerbind één of meer controllers of installeer de\n${REMOTE_APP_NAME} app om je telefoon of tablet\nte gebruiken als controllers.", + "remote_app": { + "app_name": "BombSquad Afstandsbediening", + "app_name_short": "BSAfstandsbediening", + "button_position": "Knop Positie", + "button_size": "Knop Grootte", + "cant_resolve_host": "Kan host niet oplossen.", + "capturing": "Vastleggen...", + "connected": "Verbonden.", + "description": "Gebruik uw telefoon of tablet als controller bij BombSquad.\nTot 8 apparaten kunnen tegelijk verbinding maken voor een epische lokale multiplayer gekkenhuis op een enkele TV of tablet.", + "disconnected": "Verbinding verbroken door server.", + "dpad_fixed": "vast", + "dpad_floating": "zwevend", + "dpad_position": "D-Pad Positie", + "dpad_size": "D-Pad Grootte", + "dpad_type": "D-Pad Type", + "enter_an_address": "Voer een Adres in", + "game_full": "Dit spel is vol of accepteert geen nieuwe verbindingen.", + "game_shut_down": "Het spel is afgesloten.", + "hardware_buttons": "Hardware Knoppen", + "join_by_address": "Meedoen met Adres...", + "lag": "Lag: ${SECONDS} seconden", + "reset": "Herstel naar standaard", + "run1": "Rennen 1", + "run2": "Rennen 2", + "searching": "Zoeken naar BombSquad spellen...", + "searching_caption": "Tik op de naam van het spel om mee te doen.\nZorg er voor dat u op het zelfde wifi netwerk bent als het spel.", + "start": "Begin", + "version_mismatch": "Versie ongelijk.\nZorg er voor dat BombSquad en BombSquad Afstandsbediening\nde nieuwste versie zijn en probeer het opnieuw." + }, + "removeInGameAdsText": "Koop \"${PRO}\" in de winkel om de in-game advertenties te verwijderen.", + "renameText": "Hernoemen", + "replayEndText": "Stop Herhaling", + "replayNameDefaultText": "Herhaling Laatste Spel", + "replayReadErrorText": "Fout bij inlezen herhaling bestand.", + "replayRenameWarningText": "Hernoem \"${REPLAY}\" na een spel om deze te behouden; anders wordt het overschreven.", + "replayVersionErrorText": "Sorry, deze herhaling is opgenomen in een vorige\nversie en kan niet worden afgespeeld", + "replayWatchText": "Bekijk Herhaling", + "replayWriteErrorText": "Fout tijdens wegschrijven herhaling.", + "replaysText": "Herhaling", + "reportPlayerExplanationText": "Gebruik deze email voor het rapporteren van valsspelen, ongepast taalgebruik, of ander slecht gedrag.\nBeschrijf hieronder:", + "reportThisPlayerCheatingText": "Valsspelen", + "reportThisPlayerLanguageText": "Ongepast Taalgebruik", + "reportThisPlayerReasonText": "Wat zou u willen melden?", + "reportThisPlayerText": "Geef deze speler aan", + "requestingText": "Verkrijgen...", + "restartText": "Herstarten", + "retryText": "Probeer opnieuw", + "revertText": "Omkeren", + "runBoldText": "REN", + "runText": "Ren", + "saveText": "Opslaan", + "scanScriptsErrorText": "Fout(en) bij inlezen scripts; zie log voor details.", + "scoreChallengesText": "Score Uitdagingen", + "scoreListUnavailableText": "Score lijst niet beschikbaar.", + "scoreText": "Score", + "scoreUnits": { + "millisecondsText": "Milliseconden", + "pointsText": "Punten", + "secondsText": "Seconden" + }, + "scoreWasText": "(was ${COUNT})", + "selectText": "Selecteren", + "seriesWinLine1PlayerText": "WINT DE", + "seriesWinLine1TeamText": "WINT DE", + "seriesWinLine1Text": "WINT DE", + "seriesWinLine2Text": "SERIE!", + "settingsWindow": { + "accountText": "Profiel", + "advancedText": "Geavanceerd", + "audioText": "Geluid", + "controllersText": "Controllers", + "graphicsText": "Grafisch", + "playerProfilesMovedText": "Opgelet: Speler profielen zijn verhuist naar het Account venster in het hoofd menu.", + "playerProfilesText": "Speler Profielen", + "titleText": "Instellingen" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(een simpele, controller-vriendelijke toetsenbord op het scherm voor tekstbewerking)", + "alwaysUseInternalKeyboardText": "Gebruik altijd Interne Toetsenbord", + "benchmarksText": "Maatstaven en Stress-Testen", + "disableCameraGyroscopeMotionText": "Schakel de Camera Gyroscoop beweging uit", + "disableCameraShakeText": "Schakel schuddende camera uit", + "disableThisNotice": "(U kunt deze melding uitschakelen in de geavanceerde instellingen)", + "enablePackageModsDescriptionText": "(Geeft extra aanpassingsmogelijkheden maar deactiveert net-spel)", + "enablePackageModsText": "Schakel Lokale Pakket Aanpassingen in", + "enterPromoCodeText": "Voer code in", + "forTestingText": "Let op: deze waarden zijn alleen voor testen en zullen verloren gaan als de app gesloten wordt.", + "helpTranslateText": "${APP_NAME}'s niet-Engelse vertalingen is een gezamenlijke\ninspanning van de gemeenschap. Als u daar aan wilt bijdragen of een vertaling\nwilt corrigeren, klik dan op de link hieronder. Bij voorbaat dank!", + "helpTranslateTextScale": 1.0, + "kickIdlePlayersText": "Verstoot Afwezige Spelers", + "kidFriendlyModeText": "Kind Vriendelijke Modus (minder geweld, etc.)", + "languageText": "Taal", + "languageTextScale": 1.0, + "moddingGuideText": "Aanpasgids", + "mustRestartText": "U moet het spel herstarten voordat dit effect heeft.", + "netTestingText": "Netwerk Testen", + "resetText": "Reset", + "showBombTrajectoriesText": "Baan van de bom weergeven", + "showPlayerNamesText": "Toon Namen Spelers", + "showUserModsText": "Toon Aanpassingen Map", + "titleText": "Geavanceerd", + "translationEditorButtonText": "${APP_NAME} Vertalings Bewerker", + "translationFetchErrorText": "vertaalstatus niet beschikbaar", + "translationFetchingStatusText": "vertaalstatus controleren...", + "translationInformMe": "Meld het wanneer mijn taal updates nodig heeft.", + "translationNoUpdateNeededText": "De huidige taal is up to date; woohoo!", + "translationUpdateNeededText": "** de huidige taal heeft updates nodig!! **", + "vrTestingText": "VR Testen" + }, + "shareText": "Deel", + "sharingText": "Aan het delen...", + "showText": "Toon", + "signInForPromoCodeText": "U moet inloggen op een account om de codes van kracht te laten worden.", + "signInWithGameCenterText": "Om een Game Center account te gebruiken,\nlogt u in bij de Game Center app.", + "singleGamePlaylistNameText": "Alleen ${GAME}", + "singlePlayerCountText": "1 speler", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Karakter selectie", + "Chosen One": "De Uitverkorene", + "Epic": "Epische Modus Spellen", + "Epic Race": "Epische Race", + "FlagCatcher": "Verover de Flag", + "Flying": "Vrolijke Gedachten", + "Football": "Rugby", + "ForwardMarch": "Bestorming", + "GrandRomp": "Verovering", + "Hockey": "Hockey", + "Keep Away": "Hou Weg", + "Marching": "Omlopen", + "Menu": "Hoofd Menu", + "Onslaught": "Veldslag", + "Race": "Race", + "Scary": "Koning van de Heuvel", + "Scores": "Score Scherm", + "Survival": "Eliminatie", + "ToTheDeath": "Dood Spel", + "Victory": "Uiteindelijke Score Scherm" + }, + "spaceKeyText": "spatie", + "statsText": "stats", + "storagePermissionAccessText": "Dit vereist toegang tot opslag", + "store": { + "alreadyOwnText": "U bent al de eigenaar van ${NAME}!", + "bombSquadProDescriptionText": "• Verdubbelt prestatie ticket beloningen\n• Verwijdert reclame in het spel\n• Bevat ${COUNT} bonus tickets\n• +${PERCENT}% competitie score bonus\n• Speelt '${INF_ONSLAUGHT}' en\n '${INF_RUNAROUND}' co-op levels vrij", + "bombSquadProFeaturesText": "Functies:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Verwijdert reclames en nare schermpjes binnen het spel\n• Ontgrendeld meer game instellingen\n• Ook inclusief:", + "buyText": "Koop", + "charactersText": "Karakters", + "comingSoonText": "Binnenkort...", + "extrasText": "Extras", + "freeBombSquadProText": "BombSquad is nu gratis, maar sinds u het spel origineel gekocht heeft\nkrijgt u de BombSquad Pro opwaardering en ${COUNT} tickets als dank.\nVeel plezier met de nieuwe functies, en bedankt voor uw ondersteuning!\n-Eric", + "gameUpgradesText": "Spel Opwaarderingen", + "getCoinsText": "Munten Aanschaffen", + "holidaySpecialText": "Speciale aanbieding", + "howToSwitchCharactersText": "(ga naar \"${SETTINGS} -> ${PLAYER_PROFILES}\" om karakters toe te wijzen & aan te passen)", + "howToUseIconsText": "(Creëer globale speler profielen (in het account venster) om deze te gebruiken)", + "howToUseMapsText": "(gebruik deze speelvelden in je eigen team/ieder-voor-zich speellijsten)", + "iconsText": "Pictogrammen", + "loadErrorText": "Kon de pagina niet laden.\nControleer uw internet verbinding.", + "loadingText": "laden", + "mapsText": "Speelvelden", + "miniGamesText": "MiniSpellen", + "oneTimeOnlyText": "(eenmalige aanbieding)", + "purchaseAlreadyInProgressText": "Een aankoop dat dit artikel wordt al verwerkt.", + "purchaseConfirmText": "Koop ${ITEM}?", + "purchaseNotValidError": "Aankoop niet geldig.\nContacteer ${EMAIL} als dit een fout is.", + "purchaseText": "Koop", + "saleBundleText": "Bundel Uitverkoop!", + "saleExclaimText": "Aanbieding!", + "salePercentText": "(${PERCENT}% korting)", + "saleText": "KORTING", + "searchText": "Zoeken", + "teamsFreeForAllGamesText": "Teams / Ieder-voor-Zich Spellen", + "totalWorthText": "*** Ter waarde van ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Opwaarderen?", + "winterSpecialText": "Winter Aanbieding", + "youOwnThisText": "- u bezit dit -" + }, + "storeDescriptionText": "8 Speler Feest Spel Krankzinnigheid!\n\nBlaas uw vrienden op (of de computer) in een toernooi van explosieve mini-spellen zoals Verover-de-Vlag, Bommen-Hockey, en Epische-Slow-Motion-Dood-Spel!\n\nSimpele besturing en uitgebreide controller ondersteuning maakt het makkelijk om tot met 8 spelers in actie te zijn; u kunt zelfs uw iPhones gebruiken als controllers met de gratis 'BombSquad Remote' app!\n\nBombardeer er op los!\n\nKijk op www.froemling.net/Bombsquad voor meer info.", + "storeDescriptions": { + "blowUpYourFriendsText": "Blaas uw vrienden op.", + "competeInMiniGamesText": "Concurreer in mini-spellen van racen tot vliegen.", + "customize2Text": "Pas uw karakter aan, mini-spellen, en zelfs uw eigen muziek.", + "customizeText": "Pas karakters aan en maak uw eigen mini-spellen lijst.", + "sportsMoreFunText": "Sporten zijn leuker met explosieven.", + "teamUpAgainstComputerText": "Vorm een team tegen de computer." + }, + "storeText": "Winkel", + "submitText": "Voorleggen", + "submittingPromoCodeText": "Code verzenden ...", + "teamNamesColorText": "Teamnamen / kleuren ...", + "teamsText": "Teams", + "telnetAccessGrantedText": "Telnet toegang ingeschakeld.", + "telnetAccessText": "Telnet toegang gedetecteerd; toestaan?", + "testBuildErrorText": "Deze test versie is niet meer actief; gelieve controleer voor een nieuwe versie.", + "testBuildText": "Test Versie", + "testBuildValidateErrorText": "Niet in staat om de test versie te valideren. (geen net verbinding?)", + "testBuildValidatedText": "Test Versie Gevalideerd; Veel Plezier!", + "thankYouText": "Bedankt voor uw ondersteuning! Veel plezier met het spel!!", + "threeKillText": "DRIEDUBBELE DOOD!!", + "timeBonusText": "Tijd Bonus", + "timeElapsedText": "Tijd Verstreken", + "timeExpiredText": "Tijd Verstreken", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}u", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Tip", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Top Vrienden", + "tournamentCheckingStateText": "Toernooi status nakijken; even geduld aub...", + "tournamentEndedText": "Dit toernooi is beëindigd. Er zal snel een nieuwe beginnen.", + "tournamentEntryText": "Toernooi Inschrijving", + "tournamentResultsRecentText": "Recente Toernooi Uitslagen", + "tournamentStandingsText": "Toernooi Stand", + "tournamentText": "Toernooi", + "tournamentTimeExpiredText": "Toernooi Tijd Verlopen", + "tournamentsText": "Toernooien", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Bones", + "Butch": "Butch", + "Easter Bunny": "Paashaas", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Middle-Man", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Kerstman", + "Snake Shadow": "Snake Shadow", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao Mascot", + "Todd": "Todd", + "Todd McBurton": "Todd McBurton", + "Xara": "Xara", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Oneindige\nAfslachting", + "Infinite\nRunaround": "Oneindig\nOmlopen", + "Onslaught\nTraining": "Afslacht\nTraining", + "Pro\nFootball": "Pro\nRugby", + "Pro\nOnslaught": "Pro\nAfslachting", + "Pro\nRunaround": "Pro\nOmlopen", + "Rookie\nFootball": "Groentjes\nRugby", + "Rookie\nOnslaught": "Groentjes\nAfslachting", + "The\nLast Stand": "De\nLaatste Stand", + "Uber\nFootball": "Uber\nRugby", + "Uber\nOnslaught": "Uber\nAfslachting", + "Uber\nRunaround": "Uber\nOmlopen" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Training", + "Infinite ${GAME}": "Oneindig ${GAME}", + "Infinite Onslaught": "Oneindige Afslachting", + "Infinite Runaround": "Oneindig Omlopen", + "Onslaught": "Oneindige Afslachting", + "Onslaught Training": "Afslacht Training", + "Pro ${GAME}": "Pro ${GAME}", + "Pro Football": "Pro Rugby", + "Pro Onslaught": "Pro Afslachting", + "Pro Runaround": "Pro Omlopen", + "Rookie ${GAME}": "Amateur ${GAME}", + "Rookie Football": "Groentjes Rugby", + "Rookie Onslaught": "Groentjes Afslachting", + "Runaround": "Oneindig Omlopen", + "The Last Stand": "De Laatste Stand", + "Uber ${GAME}": "Extreem ${GAME}", + "Uber Football": "Uber Rugby", + "Uber Onslaught": "Uber Afslachting", + "Uber Runaround": "Uber Omlopen" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Ben de uitverkorene voor een bepaalde tijd om te winnen.\nDood de uitverkorene om het te worden.", + "Bomb as many targets as you can.": "Bombardeer zo veel mogelijk doelwitten als u kan.", + "Carry the flag for ${ARG1} seconds.": "Draag de vlag voor ${ARG1} seconden.", + "Carry the flag for a set length of time.": "Draag de vlag voor een bepaalde tijd.", + "Crush ${ARG1} of your enemies.": "Verpletter ${ARG1} van uw vijanden.", + "Defeat all enemies.": "Versla alle vijanden.", + "Dodge the falling bombs.": "Ontwijk de vallende bommen.", + "Final glorious epic slow motion battle to the death.": "Uiteindelijke glorieuze epische slow motion gevecht tot de dood.", + "Gather eggs!": "Verzamel eieren!", + "Get the flag to the enemy end zone.": "Breng de vlag naar de vijandelijke eind zone.", + "How fast can you defeat the ninjas?": "Hoe snel kan u de ninjas verslaan?", + "Kill a set number of enemies to win.": "Dood een bepaald aantal vijanden om te winnen.", + "Last one standing wins.": "De laatste die overblijft wint.", + "Last remaining alive wins.": "De laatst overgebleven levende wint.", + "Last team standing wins.": "Het laatste team dat over blijft wint.", + "Prevent enemies from reaching the exit.": "Voorkom de vijanden de uitgang bereiken.", + "Reach the enemy flag to score.": "Bereik de vijandelijke vlag om te scoren.", + "Return the enemy flag to score.": "Breng de vijandelijke vlag terug om te scoren.", + "Run ${ARG1} laps.": "Ren ${ARG1} rondes.", + "Run ${ARG1} laps. Your entire team has to finish.": "Ren ${ARG1} rondes. Uw hele team moet finishen.", + "Run 1 lap.": "Ren 1 ronde.", + "Run 1 lap. Your entire team has to finish.": "Ren 1 rond. Uw hele team moet finishen.", + "Run real fast!": "Ren heel snel!", + "Score ${ARG1} goals.": "Score ${ARG1} doelpunten.", + "Score ${ARG1} touchdowns.": "Score ${ARG1} touchdowns.", + "Score a goal": "Score een doelpunt", + "Score a goal.": "Score een doelpunt.", + "Score a touchdown.": "Score een touchdown.", + "Score some goals.": "Score wat doelpunten.", + "Secure all ${ARG1} flags.": "Beveilig alle ${ARG1} de vlaggen.", + "Secure all flags on the map to win.": "Beveilig alle vlaggen op de kaart om te winnen.", + "Secure the flag for ${ARG1} seconds.": "Beveilig de vlag voor ${ARG1} seconden.", + "Secure the flag for a set length of time.": "Beveilig de vlag voor een bepaalde tijd.", + "Steal the enemy flag ${ARG1} times.": "Steel de vijandelijke vlag ${ARG1} keer.", + "Steal the enemy flag.": "Steel de vijandelijke vlag.", + "There can be only one.": "Er kan er maar een zijn.", + "Touch the enemy flag ${ARG1} times.": "Raak de vijandelijke vlag ${ARG1} keer aan.", + "Touch the enemy flag.": "Raak de vijandelijke vlag aan.", + "carry the flag for ${ARG1} seconds": "draag de vlag voor ${ARG1} seconden", + "kill ${ARG1} enemies": "dood ${ARG1} vijanden", + "last one standing wins": "de laatste die overblijft wint", + "last team standing wins": "het team dat als laatste overblijft wint", + "return ${ARG1} flags": "breng ${ARG1} vlaggen terug", + "return 1 flag": "breng 1 vlag terug", + "run ${ARG1} laps": "ren ${ARG1} rondes", + "run 1 lap": "ren 1 ronde", + "score ${ARG1} goals": "score ${ARG1} doelpunten", + "score ${ARG1} touchdowns": "score ${ARG1} touchdowns", + "score a goal": "score een doelpunt", + "score a touchdown": "score een touchdown", + "secure all ${ARG1} flags": "beveilig alle ${ARG1} de vlaggen", + "secure the flag for ${ARG1} seconds": "beveilig de vlag voor ${ARG1} seconden", + "touch ${ARG1} flags": "raak ${ARG1} vlaggen aan", + "touch 1 flag": "raak 1 vlag aan" + }, + "gameNames": { + "Assault": "Bestorming", + "Capture the Flag": "Verover de Vlag", + "Chosen One": "De Uitverkorene", + "Conquest": "Verovering", + "Death Match": "Dood Spel", + "Easter Egg Hunt": "Paaseieren Jacht", + "Elimination": "Eliminatie", + "Football": "Rugby", + "Hockey": "Hockey", + "Keep Away": "Hou Weg", + "King of the Hill": "Koning van de Heuvel", + "Meteor Shower": "Meteoren Regen", + "Ninja Fight": "Ninja Gevecht", + "Onslaught": "Afslachting", + "Race": "Race", + "Runaround": "Omlopen", + "Target Practice": "Bombardeer Oefening", + "The Last Stand": "De Laatste Stand" + }, + "inputDeviceNames": { + "Keyboard": "Keyboard", + "Keyboard P2": "Keyboard P2" + }, + "languages": { + "Arabic": "Arabisch", + "Belarussian": "Belarusian", + "Chinese": "Vereenvoudigd Chinees", + "ChineseTraditional": "Traditioneel Chinees", + "Croatian": "Kroatisch", + "Czech": "Tsjechisch", + "Danish": "Deens", + "Dutch": "Nederlands", + "English": "Engels", + "Esperanto": "Esperanto", + "Filipino": "Filipijns", + "Finnish": "Fins", + "French": "Frans", + "German": "Duits", + "Gibberish": "Brabbeltaal", + "Greek": "Grieks", + "Hindi": "Hindies", + "Hungarian": "Hongaars", + "Indonesian": "Indonesisch", + "Italian": "Italiaans", + "Japanese": "Japans", + "Korean": "Koreaans", + "Persian": "Perzisch", + "Polish": "Pools", + "Portuguese": "Portugees", + "Romanian": "Roemeens", + "Russian": "Russisch", + "Serbian": "Servisch", + "Slovak": "Sloveens", + "Spanish": "Spaans", + "Swedish": "Zweeds", + "Tamil": "Tamil", + "Thai": "Thais", + "Turkish": "Turks", + "Ukrainian": "Oekraïens", + "Venetian": "Venetiaanse", + "Vietnamese": "Vietnamees" + }, + "leagueNames": { + "Bronze": "Bronzen", + "Diamond": "Diamand", + "Gold": "Goud", + "Silver": "Zilver" + }, + "mapsNames": { + "Big G": "Grote G", + "Bridgit": "Brugut", + "Courtyard": "Binnenplaats", + "Crag Castle": "Rots Kasteel", + "Doom Shroom": "Paddenstoel des Onheils", + "Football Stadium": "Rugby Stadion", + "Happy Thoughts": "Vrolijke Gedachten", + "Hockey Stadium": "Hockey Stadion", + "Lake Frigid": "Het Frigid Meer", + "Monkey Face": "Apen Gezicht", + "Rampage": "Rampage", + "Roundabout": "Rotonde", + "Step Right Up": "Step Right Up", + "The Pad": "Het Blok", + "Tip Top": "Tip Top", + "Tower D": "Toren D", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Alleen Episch", + "Just Sports": "Alleen Sporten" + }, + "promoCodeResponses": { + "invalid promo code": "ongeldige promotie code" + }, + "scoreNames": { + "Flags": "Vlaggen", + "Goals": "Doelpunten", + "Score": "Score", + "Survived": "Overleefd", + "Time": "Tijd", + "Time Held": "Tijd Gehouden" + }, + "serverResponses": { + "A code has already been used on this account.": "Een code is al gebruikt op dit account.", + "A reward has already been given for that address.": "Een beloning is al gegeven voor dat adres.", + "Account linking successful!": "Account succesvol gelinkt!", + "Account unlinking successful!": "Account verbinding succesvol verbroken!", + "Accounts are already linked.": "Accounts zijn al gelinkt.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Advertentieweergave kan niet worden geverifieerd.\nZorg ervoor dat je een officiële en up-to-date versie van het spel gebruikt.", + "An error has occurred; (${ERROR})": "er is een fout opgetreden; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "er is een fout opgetreden, neem contact op met de ondersteuning. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Er is een fout opgetreden; neem alstublieft contact op met support@froemling.net.", + "An error has occurred; please try again later.": "Er is een fout opgetreden; Probeer het later opnieuw.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Bent u zeker dat u deze accounts wilt koppelen?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nDit kan niet ongedaan gemaakt worden!", + "BombSquad Pro unlocked!": "BombSquad Pro ontgrendeld!", + "Can't link 2 accounts of this type.": "Kan geen 2 accounts van dit type linken.", + "Can't link 2 diamond league accounts.": "Kan geen 2 diamanten competitie accounts linken.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Kan niet linken; dit zou het maximum van ${COUNT} gelinkte accounts overschrijden.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Valsspelen ontdekt; scores en prijzen geschorst voor ${COUNT} dagen.", + "Could not establish a secure connection.": "Kon geen beveiligde verbinding tot stand brengen.", + "Daily maximum reached.": "Dagelijkse maximum bekijkt.", + "Entering tournament...": "Toernooi betreden...", + "Invalid code.": "Ongeldige code.", + "Invalid payment; purchase canceled.": "Ongeldige betaling; aankoop geannuleerd.", + "Invalid promo code.": "Ongeldige promo code.", + "Invalid purchase.": "Ongeldige aankoop.", + "Invalid tournament entry; score will be ignored.": "Ongeldige toernooi; score wordt genegeerd.", + "Item unlocked!": "item ontgrendeld!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LINKENDE ONTKENNING. ${ACCOUNT} bevat\nsignificante gegevens die ALLES ZIJN VERLOREN.\nJe kunt in omgekeerde volgorde linken als je wilt\n(en verlies de gegevens van DIT account in plaats daarvan)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Verbind account ${ACCOUNT} aan dit account?\nAlle bestaande data op ${ACCOUNT} zal verloren gaan.\nDit kan niet ongedaan worden gemaakt. Weet je het zeker?", + "Max number of playlists reached.": "Maximaal aantal speellijsten bereikt.", + "Max number of profiles reached.": "Maximaal aantal profielen bereikt.", + "Maximum friend code rewards reached.": "Maximum vriend code beloning behaald", + "Message is too long.": "Bericht is te lang.", + "No servers are available. Please try again soon.": "Er zijn geen servers beschikbaar. Probeer het binnenkort opnieuw.", + "Profile \"${NAME}\" upgraded successfully.": "Profiel \"${NAME}\" is succesvol opgewaardeerd.", + "Profile could not be upgraded.": "Profiel kon niet worden opgewaardeerd.", + "Purchase successful!": "Aankoop succesvol!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "${COUNT} tickets ontvangen door in te loggen.\nKom morgen terug om ${TOMORROW_COUNT} te ontvangen.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Serverfunctionaliteit wordt niet langer ondersteund in deze versie van het spel;\nWerk bij naar een nieuwere versie.", + "Sorry, there are no uses remaining on this code.": "Sorry, deze code is al te veel gebruikt.", + "Sorry, this code has already been used.": "Sorry, deze code is al gebruikt.", + "Sorry, this code has expired.": "Sorry, deze code is verlopen.", + "Sorry, this code only works for new accounts.": "Sorry, deze code werkt alleen op nieuwe accounts.", + "Still searching for nearby servers; please try again soon.": "Nog steeds op zoek naar servers in de buurt; probeer het snel opnieuw.", + "Temporarily unavailable; please try again later.": "Tijdelijk niet beschikbaar; probeer het later opnieuw.", + "The tournament ended before you finished.": "Het toernooi eindigde voordat u klaar was.", + "This account cannot be unlinked for ${NUM} days.": "Dit account kan gedurende ${NUM} dagen niet worden ontkoppeld.", + "This code cannot be used on the account that created it.": "Deze code kan niet gebruikt worden op het account die het gemaakt heeft.", + "This is currently unavailable; please try again later.": "Dit is momenteel niet beschikbaar; probeer het later opnieuw.", + "This requires version ${VERSION} or newer.": "Dit vereist versie ${VERSION} of nieuwer.", + "Tournaments disabled due to rooted device.": "Toernooien uitgeschakeld vanwege geworteld apparaat", + "Tournaments require ${VERSION} or newer": "toernooi vereist ${VERSION} of nieuwer", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Koppel ${ACCOUNT} los van dit account?\nAlle gegevens over ${ACCOUNT} worden opnieuw ingesteld.\n(behalve voor prestaties in sommige gevallen)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "WAARSCHUWING: klachten over hacking zijn afgegeven tegen uw account.\nAccounts die hacken blijken te zijn, worden verbannen. Speel alsjeblieft eerlijk.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Wilt u uw apparaat account hieraan koppelen?\n\nUw apparaat account is ${ACCOUNT1}\nDit account is ${ACCOUNT2}\n\nDit zal u toelaten om uw bestaande vooruitgang te houden.\nWaarschuwing: dit kan niet ongedaan gemaakt worden!", + "You already own this!": "U bezit dit al!", + "You can join in ${COUNT} seconds.": "Je kan meedoen in ${COUNT} seconden.", + "You don't have enough tickets for this!": "U heeft hier niet genoeg tickets voor!", + "You don't own that.": "Je bezit dat niet.", + "You got ${COUNT} tickets!": "U krijgt ${COUNT} tickets!", + "You got a ${ITEM}!": "U hebt een ${ITEM}!", + "You have been promoted to a new league; congratulations!": "U bent gepromoveerd naar een nieuwe competitie; gefeliciteerd!", + "You must update to a newer version of the app to do this.": "Om dit te kunnen doen moet u de app updaten naar een nieuwere versie.", + "You must update to the newest version of the game to do this.": "Je moet dit bijwerken naar de nieuwste versie van het spel.", + "You must wait a few seconds before entering a new code.": "U moet een paar seconden wachten voordat een nieuwe code ingevoerd kan worden.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "U eindigde op rang #${RANK} in het laatste toernooi. Bedankt voor het spelen!", + "Your account was rejected. Are you signed in?": "Je account is geweigerd. Ben je ingelogd?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Uw versie van het spel is aangepast.\nMaakt de veranderingen ongedaan en probeer het opnieuw.", + "Your friend code was used by ${ACCOUNT}": "Uw Vriend code is gebruikt door ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minuut", + "1 Second": "1 Seconde", + "10 Minutes": "10 Minuten", + "2 Minutes": "2 Minuten", + "2 Seconds": "2 Seconden", + "20 Minutes": "20 Minuten", + "4 Seconds": "4 Seconden", + "5 Minutes": "5 Minuten", + "8 Seconds": "8 Seconden", + "Allow Negative Scores": "Negatieve Score Toelaten", + "Balance Total Lives": "Balanseer Totaal Aantal Levens", + "Bomb Spawning": "Bom Spawning", + "Chosen One Gets Gloves": "De Uitverkorene Krijgt Handschoenen", + "Chosen One Gets Shield": "De Uitverkorene Krijgt Een Schild", + "Chosen One Time": "Uitverkorene Tijd", + "Enable Impact Bombs": "Activeer Inslag Bommen", + "Enable Triple Bombs": "Activeer Drievoudige Bommen", + "Entire Team Must Finish": "Volledige Team Moet Voltooien", + "Epic Mode": "Epische Modus", + "Flag Idle Return Time": "Stilligende Vlag Terugkeer Tijd", + "Flag Touch Return Time": "Vlag Aanraken Terugkeer Tijd", + "Hold Time": "Vasthou Tijd", + "Kills to Win Per Player": "Doden om te Winnen Per Speler", + "Laps": "Rondes", + "Lives Per Player": "Levens Per Speler", + "Long": "Lang", + "Longer": "Langer", + "Mine Spawning": "Mijn Spawning", + "No Mines": "Geen Mijnen", + "None": "Geen", + "Normal": "Normaal", + "Pro Mode": "Pro Modus", + "Respawn Times": "Respawn Tijd", + "Score to Win": "Score om te Winnen", + "Short": "Kort", + "Shorter": "Korter", + "Solo Mode": "Individuele Modus", + "Target Count": "Doelwit Aantal", + "Time Limit": "Tijd Limiet" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} is gediskwalificeerd omdat ${PLAYER} heeft verlaten", + "Killing ${NAME} for skipping part of the track!": "${NAME} gedood door overslaan van de baan!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "waarschuwing voor ${NAME}: turbo / button spammen maakt je knock-out" + }, + "teamNames": { + "Bad Guys": "Slechteriken", + "Blue": "Blauw", + "Good Guys": "Goede Kerels", + "Red": "Rood" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Een perfect getimede ren-spring-draai-slag kan doden in een enkele slag\nen verdien uw levenslange respect van uw vrienden.", + "Always remember to floss.": "Vergeet niet te flossen.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Creëer speler profielen voor uzelf en uw vrienden met\nuw namen en uiterlijk naar voorkeur in plaatsen van de willekeurige.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Vloek dozen veranderen u in een tikkende tijd bom.\nDe enige behandeling is om snel een gezondheid-doos te pakken.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Ondanks hun uiterlijk, de vaardigheden van alle personages zijn identiek,\nu kunt dus gewoon pakken welke u het meeste aantrekt.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Word niet te verwaand met een energie schild; u kunt nog steeds van een klif af gegooid worden.", + "Don't run all the time. Really. You will fall off cliffs.": "Ren niet de hele tijd. Echt waar. U zal van kliffen af vallen.", + "Don't spin for too long; you'll become dizzy and fall.": "Draai niet te lang rond; je zal duizelig worden en vallen.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Houd een knop in om te rennen. (Trigger knoppen werken goed als u die heeft)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Houd een willekeurige knop in om te rennen. Je beweegt hierdoor sneller\nmaar zal niet erg goed kunnen draaien, dus kijk uit voor afgronden.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ijs bommen zijn niet erg krachtig, maar ze bevriezen\nwie ze ook raken, waardoor ze kwetsbaar zijn voor verbrijzeling.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Als iemand u op pakt, sla dan en ze laten los.\nDit werkt ook in het echte leven.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Als je controllers te kort komt, installeer dan de '${REMOTE_APP_NAME}' app\nop je mobiel of tablet om deze als controller te gebruiken.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Als u een tekort hebt aan controller, installeer dan de 'BombSquad Remote' app\nop uw iOS of Android apparaten om ze als controllers te gebruiken.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Als er een plak-bom aan u vast zit, spring rond en draai rondjes. U zou\nde bom nog van u af kunnen schudden, of als het niet werkt zijn uw laatste momenten vermakelijk.", + "If you kill an enemy in one hit you get double points for it.": "Als u een vijand doodt in een slag krijgt u er dubbele punten voor.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Als u een vloek op pakt, is uw enige kans op overleven om\neen gezondheids powerup te vinden in de komende paar seconden.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Als u op een plaats blijft, bent u toast. Ren en ontwijk om te overleven..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Als u veel spelers hebt die komen en gaan, zet dan 'verstoot-afwezige spelers' aan\nin instellingen voor het geval dat iemand vergeet het spel te verlaten.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Als uw apparaat te warm wordt of je als je bettarij wilt besparen,\nzet \"Visueel\" of \"Resolutie\" omlaag bij Instellingen->Grafisch", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Als uw framerate schokkerig is, probeer dan de resolutie of visuele instellingen\nomlaag te zetten bij het spel zijn grafische instellingen.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "In Verover-de-Vlag, moet uw eigen vlag in uw basis zijn om te scoren, als het andere\nteam op het punt staat om te scoren, is het stelen van hun vlag een goede manier om ze te stoppen.", + "In hockey, you'll maintain more speed if you turn gradually.": "In hockey, behoud u meer snelheid als u rustig draait.", + "It's easier to win with a friend or two helping.": "Het is makkelijker om te winnen als een vriend of twee helpen.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Spring precies als u een bom gooit om de bommen op het hoogst mogelijke te krijgen.", + "Land-mines are a good way to stop speedy enemies.": "Land-mijnen zijn een goede manier om snelle vijanden te stoppen.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Veel dingen kunnen opgepakt worden en gegooid, inclusief andere spelers. Vijanden\nvan kliffen af gooien kan een effectieve en emotioneel vervullende strategie zijn.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nee, u kunt niet de richel omhoog klimmen. U moet bommen gooien.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Spelers kunnen meedoen en stoppen midden in de meeste spellen.\nU kunt ook controllers tijdens het spelen aansluiten of ontkoppelen.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Spelers kunnen meedoen en weggaan midden in de meeste spellen,\nje kan ook gamepads in-en uitpluggen tijdens de spellen.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Powerups hebben alleen een tijd limiet in coöperatieve spellen.\nIn teams en ieder-voor-zich zijn ze van jou totdat je dood gaat.", + "Practice using your momentum to throw bombs more accurately.": "Oefen met het gebruiken van uw momentum om uw bommen accurater te gooien.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Uw klappen doen meer schade als uw vuisten in beweging zijn,\ndus probeer te rennen, springen en te draaien als een gek.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Ren heen en weer voordat u een bom gooit\nom deze 'op te zwiepen' en verder te gooien.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Schakel hele groepen vijanden uit door een bom\nte laten ontploffen naast een TNT doos.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Het hoofd is de meest zwakke plek. Dus een plak-bom\nnaar het koppie betekend meestal 'game over'.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Aan dit level komt geen einde, maar haalt u een 'high score'\ndan wacht u eeuwige respect van heel de wereld.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Werp kracht is gebaseerd op de richting die u stuurt.\nStuur in geen enkele richting om iets vlak voor uw voeten te gooien.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Verveeld van de muziek? Vervang het met uw eigen!\nZie Instellingen->Geluid->Muziek", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Zet uw bommen op scherp door ze eerst een seconde of twee vast te houden voordat u gooit.", + "Try tricking enemies into killing eachother or running off cliffs.": "Gebruik schijnbewegingen om uw tegenstanders elkaar op te laten blazen of van de randen te laten lopen.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Gebruik de 'op pak knop' om de vlag te grijpen < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Zwiep uzelf heen en weer om verder te kunnen gooien..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "U kan uw klappen 'mikken' door linksom of rechtsom te tollen.\nDit is handig om slechteriken over de rand te duwen of tijdens hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "U kunt beoordelen of een bom gaat ontploffen door goed naar\nde vonken van de lont te kijken: geel..oranje..rood..BOEM!", + "You can throw bombs higher if you jump just before throwing.": "U kunt bommen hoger gooien als u springt vlak voordat u de bom gooit.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Je bent niet verplicht om je profiel aan te passen om het uiterlijk van je\nkarakter te veranderen; Druk op de 'op pak knop' tijdens de karakter keuze\nom tijdelijk je standaard karakter te veranderen.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "U loopt schade op als u uw hoofd tegen voorwerpen knalt,\ndus probeer uw hoofd niet tegen voorwerpen te knallen.", + "Your punches do much more damage if you are running or spinning.": "Uw klappen doen meer schade als u rent of om uw as tolt." + } + }, + "trialPeriodEndedText": "De proeftijd is voorbij. Wil je BombSquad\naanschaffen om door te kunnen spelen?", + "trophiesRequiredText": "Dit vereist op z'n minst ${NUMBER} trofeeën.", + "trophiesText": "Trofeeën", + "trophiesThisSeasonText": "Trofeeën van dit seizoen", + "tutorial": { + "cpuBenchmarkText": "Uitleg uitvoeren op belachelijke snelheid (test voornamelijk de CPU-snelheid)", + "phrase01Text": "Hallo daar!", + "phrase02Text": "Welkom bij ${APP_NAME}!", + "phrase03Text": "Hier volgen een paar tips voor het besturen van uw karakter:", + "phrase04Text": "Veel dingen in ${APP_NAME} zijn gebaseerd op NATUURKUNDE.", + "phrase05Text": "Als u bijvoorbeeld ergens tegen duwt,..", + "phrase06Text": "..schade is afhankelijk van de snelheid van uw vuist.", + "phrase07Text": "Ziet u wel? We bewogen niet dus we deden ${NAME} amper pijn.", + "phrase08Text": "Laten we nu springen en draaien om meer snelheid te krijgen.", + "phrase09Text": "Ah, dat is beter.", + "phrase10Text": "Rennen helpt ook.", + "phrase11Text": "Hou een willekeurige knop ingedrukt om te rennen.", + "phrase12Text": "Voor extra-geweldige klappen, probeer te rennen EN te draaien.", + "phrase13Text": "Oeps; mijn excuses ${NAME}.", + "phrase14Text": "U kunt dingen oppakken en weggooien zoals vlaggen.. of ${NAME}.", + "phrase15Text": "Als laatste, zijn er ook bommen.", + "phrase16Text": "Bommen gooien vereist oefening.", + "phrase17Text": "Au! Niet zo'n beste worp.", + "phrase18Text": "Als u beweegt gooit u verder.", + "phrase19Text": "Met springen kunt u hoger gooien.", + "phrase20Text": "\"Whiplash\" uw bommen om nog verder te gooien.", + "phrase21Text": "Het juist timen van uw bommen kan lastig zijn.", + "phrase22Text": "Verdraaid.", + "phrase23Text": "Probeer de lont te \"korten\" door een paar seconden te wachten.", + "phrase24Text": "Hoera! Goed gekort.", + "phrase25Text": "Nou, dat is het wel zo'n beetje.", + "phrase26Text": "Neem ze te grazen tijger!", + "phrase27Text": "Denk aan uw training en u ZAL weer tot leven komen!", + "phrase28Text": "...nou ja, misschien...", + "phrase29Text": "Veel succes!", + "randomName1Text": "Fred", + "randomName2Text": "Harry", + "randomName3Text": "Bill", + "randomName4Text": "Chuck", + "randomName5Text": "Phil", + "skipConfirmText": "Wilt u echt de uitleg overslaan? Tik of druk om te bevestigen.", + "skipVoteCountText": "${COUNT}/${TOTAL} overslaan stemmen", + "skippingText": "les wordt overgeslagen...", + "toSkipPressAnythingText": "(tik of druk op iets om de les over te slaan)" + }, + "twoKillText": "TWEE VLIEGEN IN 1 KLAP!", + "unavailableText": "niet beschikbaar", + "unconfiguredControllerDetectedText": "Niet geconfigureerde controller ontdekt:", + "unlockThisInTheStoreText": "Hiervoor moet een aankoop gedaan worden in de winkel.", + "unlockThisProfilesText": "Om meer dan ${NUM} profielen te maken heb je nodig:", + "unlockThisText": "Om dit te ontgrendelen, moet u:", + "unsupportedHardwareText": "Sorry, deze hardware wordt niet ondersteunt door deze versie van het spel.", + "upFirstText": "Als eerste:", + "upNextText": "Daarna volgt in potje ${COUNT}:", + "updatingAccountText": "Bijwerken profiel...", + "upgradeText": "Opwaarderen", + "upgradeToPlayText": "Ontgrendel \"${PRO}\" in de winkel binnen het spel om dit te spelen.", + "useDefaultText": "Gebruik Standaard", + "usesExternalControllerText": "Dit spel maakt gebruik van een externe controller als input.", + "usingItunesText": "De muziek app wordt gebruikt voor de muziek...", + "usingItunesTurnRepeatAndShuffleOnText": "Zorg er er voor dat shuffle AAN staat en herhalen op ALLES staat in iTunes.", + "validatingBetaText": "Beta wordt Gevalideerd...", + "validatingTestBuildText": "Valideren Test Versie...", + "victoryText": "Overwinning!", + "voteDelayText": "Je kan geen andere stemming starten voor ${NUMBER} seconden", + "voteInProgressText": "Er is al een stemming bezig.", + "votedAlreadyText": "Je hebt al gestemd", + "votesNeededText": "${NUMBER} stemmen nodig", + "vsText": "tegen", + "waitingForHostText": "(wachten op ${HOST} om verder te gaan)", + "waitingForLocalPlayersText": "Wachten op lokale spelers...", + "waitingForPlayersText": "wachten op spelers om mee te doen...", + "waitingInLineText": "Wachten in de rij (partij is vol)...", + "watchAVideoText": "Bekijk een video", + "watchAnAdText": "Bekijk een Advertentie", + "watchWindow": { + "deleteConfirmText": "\"${REPLAY}\" Verwijderen?", + "deleteReplayButtonText": "Verwijder\nHerhaling", + "myReplaysText": "Mijn Herhalingen", + "noReplaySelectedErrorText": "Geen Herhaling Gekozen", + "playbackSpeedText": "afspeelsnelheid ${SPEED}", + "renameReplayButtonText": "Hernoem\nHerhaling", + "renameReplayText": "Hernoem \"${REPLAY}\" naar:", + "renameText": "Hernoemen", + "replayDeleteErrorText": "Fout bij verwijderen herhaling.", + "replayNameText": "Herhaling Naam", + "replayRenameErrorAlreadyExistsText": "Een herhaling met die naam bestaat al.", + "replayRenameErrorInvalidName": "Kan herhaling niet hernoemen; ongeldige naam.", + "replayRenameErrorText": "Fout bij hernoemen herhaling.", + "sharedReplaysText": "Gedeelde Herhalingen", + "titleText": "Bekijk", + "watchReplayButtonText": "Bekijk\nHerhaling" + }, + "waveText": "Ronde", + "wellSureText": "Maar Natuurlijk!", + "wiimoteLicenseWindow": { + "licenseTextScale": 0.62, + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Luisteren Naar Wiimotes...", + "pressText": "Druk Wiimote koppen 1 en 2 knop tegelijk in.", + "pressText2": "Gebruik bij de nieuwe Wiimotes, met ingebouwde Motion Plus, de rode 'sync' knop op de achterkant.", + "pressText2Scale": 0.55, + "pressTextScale": 1.0 + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "copyrightTextScale": 0.6, + "listenText": "Luister", + "macInstructionsText": "Zorg er voor dat de Wii uit staat en Bluetooth is ingeschakeld\nop uw Mac. Klik dan op 'Zoeken'. Wiimote ondersteuning\nis soms wat onbetrouwbaar dus het kan zijn dat u het een paar\nkeer moet proberen voordat een connectie tot stand komt.", + "macInstructionsTextScale": 0.7, + "thanksText": "Met dank aan het DarwiinRemote team\ndie dit mogelijk hebben gemaakt.", + "thanksTextScale": 0.8, + "titleText": "Wiimote Instellen" + }, + "winsPlayerText": "${NAME} Wint!", + "winsTeamText": "${NAME} Wint!", + "winsText": "${NAME} Wint!", + "worldScoresUnavailableText": "Wereldwijde scores niet beschikbaar.", + "worldsBestScoresText": "'s Werelds Beste Scores", + "worldsBestTimesText": "'s Werelds Beste Tijden", + "xbox360ControllersWindow": { + "getDriverText": "Driver downloaden", + "macInstructions2Text": "Om de draadloze controller te gebruik heeft u ook de ontvanger nodig\ndie wordt mee geleverd met de 'Xbox 360 Wireless Controller for Windows'.\nMet één ontvanger kunt u 4 controllers verbinden.\n\nBelangrijk: ontvangers van een derde partij werken niet met deze driver;\nzorg er voor dat er op de ontvanger 'Microsoft' staat vermeld, niet\n'XBOX 360'. Microsoft verkoopt deze niet langer los dus u moet de\nontvanger kopen die gebundeld is met de controller en anders zoek op ebay.\n\nAls u gebruik maakt van deze functionaliteit dan kunt u eventueel een\ngeld bedrag doneren op de website van de ontwikkelaar.", + "macInstructions2TextScale": 0.76, + "macInstructionsText": "Om een Xbox 360 controllers te gebruiken met de Mac dient\nu eerst een driver te installeren via de onderstaande link.\nDeze driver werkt met zowel bedrade als draadloze controllers.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Om bedrade Xbox 360 controllers te gebruiken kunt u deze\ndirect een USB poort van uw apparaat aansluiten.\nGebruik een USB hub om meerdere controllers tegelijk aan\nte sluiten.\n\nOm draadloze controllers te gebruiken heeft u een speciale\ndraadloze ontvanger nodig. Deze is onderdeel van het\n\"Xbox 360 wireless Controller for Windows\" pakket maar is ook\nlos verkrijgbaar. Met deze ontvanger kunt u tot en met 4 controllers\ntegelijk verbinden.", + "ouyaInstructionsTextScale": 0.8, + "titleText": "Hoe Xbox 360 Controllers te gebruiken met ${APP_NAME}:" + }, + "yesAllowText": "Ja, Toestaan!", + "yourBestScoresText": "Uw Beste Scores", + "yourBestTimesText": "Uw Beste Tijden" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/english.json b/dist/ba_data/data/languages/english.json new file mode 100644 index 0000000..33b42de --- /dev/null +++ b/dist/ba_data/data/languages/english.json @@ -0,0 +1,1893 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Account names cannot contain emoji or other special characters", + "accountsText": "Accounts", + "achievementProgressText": "Achievements: ${COUNT} out of ${TOTAL}", + "campaignProgressText": "Campaign Progress [Hard]: ${PROGRESS}", + "changeOncePerSeason": "You can only change this once per season.", + "changeOncePerSeasonError": "You must wait until next season to change this again (${NUM} days)", + "customName": "Custom Name", + "googlePlayGamesAccountSwitchText": "If you want to use a different Google account,\nuse the Google Play Games app to switch.", + "linkAccountsEnterCodeText": "Enter Code", + "linkAccountsGenerateCodeText": "Generate Code", + "linkAccountsInfoText": "(share progress across different platforms)", + "linkAccountsInstructionsNewText": "To link two accounts, generate a code on the first\nand enter that code on the second. Data from the\nsecond account will then be shared between both.\n(Data from the first account will be lost)\n\nYou can link up to ${COUNT} accounts.\n\nIMPORTANT: only link accounts that you own;\nIf you link with friends’ accounts you will not\nbe able to play online at the same time.", + "linkAccountsText": "Link Accounts", + "linkedAccountsText": "Linked Accounts:", + "manageAccountText": "Manage Account", + "nameChangeConfirm": "Change your account name to ${NAME}?", + "resetProgressConfirmNoAchievementsText": "This will reset your co-op progress and\nlocal high-scores (but not your tickets).\nThis cannot be undone. Are you sure?", + "resetProgressConfirmText": "This will reset your co-op progress,\nachievements, and local high-scores\n(but not your tickets). This cannot\nbe undone. Are you sure?", + "resetProgressText": "Reset Progress", + "setAccountName": "Set Account Name", + "setAccountNameDesc": "Select the name to display for your account.\nYou can use the name from one of your linked\naccounts or create a unique custom name.", + "signInInfoText": "Sign in to collect tickets, compete online,\nand share progress across devices.", + "signInText": "Sign In", + "signInWithDeviceInfoText": "(an automatic account only available from this device)", + "signInWithDeviceText": "Sign in with device account", + "signInWithGameCircleText": "Sign in with Game Circle", + "signInWithGooglePlayText": "Sign in with Google Play", + "signInWithTestAccountInfoText": "(legacy account type; use device accounts going forward)", + "signInWithTestAccountText": "Sign in with test account", + "signInWithV2InfoText": "(an account that works on all platforms)", + "signInWithV2Text": "Sign in with a BombSquad account", + "signOutText": "Sign Out", + "signingInText": "Signing in...", + "signingOutText": "Signing out...", + "ticketsText": "Tickets: ${COUNT}", + "titleText": "Account", + "unlinkAccountsInstructionsText": "Select an account to unlink", + "unlinkAccountsText": "Unlink Accounts", + "unlinkLegacyV1AccountsText": "Unlink Legacy (V1) Accounts", + "v2LinkInstructionsText": "Use this link to create an account or sign in.", + "viaAccount": "(via account ${NAME})", + "youAreSignedInAsText": "You are signed in as:" + }, + "achievementChallengesText": "Achievement Challenges", + "achievementText": "Achievement", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Kill 3 bad guys with TNT", + "descriptionComplete": "Killed 3 bad guys with TNT", + "descriptionFull": "Kill 3 bad guys with TNT on ${LEVEL}", + "descriptionFullComplete": "Killed 3 bad guys with TNT on ${LEVEL}", + "name": "Boom Goes the Dynamite" + }, + "Boxer": { + "description": "Win without using any bombs", + "descriptionComplete": "Won without using any bombs", + "descriptionFull": "Complete ${LEVEL} without using any bombs", + "descriptionFullComplete": "Completed ${LEVEL} without using any bombs", + "name": "Boxer" + }, + "Dual Wielding": { + "descriptionFull": "Connect 2 controllers (hardware or app)", + "descriptionFullComplete": "Connected 2 controllers (hardware or app)", + "name": "Dual Wielding" + }, + "Flawless Victory": { + "description": "Win without getting hit", + "descriptionComplete": "Won without getting hit", + "descriptionFull": "Win ${LEVEL} without getting hit", + "descriptionFullComplete": "Won ${LEVEL} without getting hit", + "name": "Flawless Victory" + }, + "Free Loader": { + "descriptionFull": "Start a Free-For-All game with 2+ players", + "descriptionFullComplete": "Started a Free-For-All game with 2+ players", + "name": "Free Loader" + }, + "Gold Miner": { + "description": "Kill 6 bad guys with land-mines", + "descriptionComplete": "Killed 6 bad guys with land-mines", + "descriptionFull": "Kill 6 bad guys with land-mines on ${LEVEL}", + "descriptionFullComplete": "Killed 6 bad guys with land-mines on ${LEVEL}", + "name": "Gold Miner" + }, + "Got the Moves": { + "description": "Win without using punches or bombs", + "descriptionComplete": "Won without using punches or bombs", + "descriptionFull": "Win ${LEVEL} without any punches or bombs", + "descriptionFullComplete": "Won ${LEVEL} without any punches or bombs", + "name": "Got the Moves" + }, + "In Control": { + "descriptionFull": "Connect a controller (hardware or app)", + "descriptionFullComplete": "Connected a controller. (hardware or app)", + "name": "In Control" + }, + "Last Stand God": { + "description": "Score 1000 points", + "descriptionComplete": "Scored 1000 points", + "descriptionFull": "Score 1000 points on ${LEVEL}", + "descriptionFullComplete": "Scored 1000 points on ${LEVEL}", + "name": "${LEVEL} God" + }, + "Last Stand Master": { + "description": "Score 250 points", + "descriptionComplete": "Scored 250 points", + "descriptionFull": "Score 250 points on ${LEVEL}", + "descriptionFullComplete": "Scored 250 points on ${LEVEL}", + "name": "${LEVEL} Master" + }, + "Last Stand Wizard": { + "description": "Score 500 points", + "descriptionComplete": "Scored 500 points", + "descriptionFull": "Score 500 points on ${LEVEL}", + "descriptionFullComplete": "Scored 500 points on ${LEVEL}", + "name": "${LEVEL} Wizard" + }, + "Mine Games": { + "description": "Kill 3 bad guys with land-mines", + "descriptionComplete": "Killed 3 bad guys with land-mines", + "descriptionFull": "Kill 3 bad guys with land-mines on ${LEVEL}", + "descriptionFullComplete": "Killed 3 bad guys with land-mines on ${LEVEL}", + "name": "Mine Games" + }, + "Off You Go Then": { + "description": "Toss 3 bad guys off the map", + "descriptionComplete": "Tossed 3 bad guys off the map", + "descriptionFull": "Toss 3 bad guys off the map in ${LEVEL}", + "descriptionFullComplete": "Tossed 3 bad guys off the map in ${LEVEL}", + "name": "Off You Go Then" + }, + "Onslaught God": { + "description": "Score 5000 points", + "descriptionComplete": "Scored 5000 points", + "descriptionFull": "Score 5000 points on ${LEVEL}", + "descriptionFullComplete": "Scored 5000 points on ${LEVEL}", + "name": "${LEVEL} God" + }, + "Onslaught Master": { + "description": "Score 500 points", + "descriptionComplete": "Scored 500 points", + "descriptionFull": "Score 500 points on ${LEVEL}", + "descriptionFullComplete": "Scored 500 points on ${LEVEL}", + "name": "${LEVEL} Master" + }, + "Onslaught Training Victory": { + "description": "Defeat all waves", + "descriptionComplete": "Defeated all waves", + "descriptionFull": "Defeat all waves in ${LEVEL}", + "descriptionFullComplete": "Defeated all waves in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Onslaught Wizard": { + "description": "Score 1000 points", + "descriptionComplete": "Scored 1000 points", + "descriptionFull": "Score 1000 points in ${LEVEL}", + "descriptionFullComplete": "Scored 1000 points in ${LEVEL}", + "name": "${LEVEL} Wizard" + }, + "Precision Bombing": { + "description": "Win without any powerups", + "descriptionComplete": "Won without any powerups", + "descriptionFull": "Win ${LEVEL} without any power-ups", + "descriptionFullComplete": "Won ${LEVEL} without any power-ups", + "name": "Precision Bombing" + }, + "Pro Boxer": { + "description": "Win without using any bombs", + "descriptionComplete": "Won without using any bombs", + "descriptionFull": "Complete ${LEVEL} without using any bombs", + "descriptionFullComplete": "Completed ${LEVEL} without using any bombs", + "name": "Pro Boxer" + }, + "Pro Football Shutout": { + "description": "Win without letting the bad guys score", + "descriptionComplete": "Won without letting the bad guys score", + "descriptionFull": "Win ${LEVEL} without letting the bad guys score", + "descriptionFullComplete": "Won ${LEVEL} without letting the bad guys score", + "name": "${LEVEL} Shutout" + }, + "Pro Football Victory": { + "description": "Win the game", + "descriptionComplete": "Won the game", + "descriptionFull": "Win the game in ${LEVEL}", + "descriptionFullComplete": "Won the game in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Pro Onslaught Victory": { + "description": "Defeat all waves", + "descriptionComplete": "Defeated all waves", + "descriptionFull": "Defeat all waves of ${LEVEL}", + "descriptionFullComplete": "Defeated all waves of ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Pro Runaround Victory": { + "description": "Complete all waves", + "descriptionComplete": "Completed all waves", + "descriptionFull": "Complete all waves on ${LEVEL}", + "descriptionFullComplete": "Completed all waves on ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Rookie Football Shutout": { + "description": "Win without letting the bad guys score", + "descriptionComplete": "Won without letting the bad guys score", + "descriptionFull": "Win ${LEVEL} without letting the bad guys score", + "descriptionFullComplete": "Won ${LEVEL} without letting the bad guys score", + "name": "${LEVEL} Shutout" + }, + "Rookie Football Victory": { + "description": "Win the game", + "descriptionComplete": "Won the game", + "descriptionFull": "Win the game in ${LEVEL}", + "descriptionFullComplete": "Won the game in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Rookie Onslaught Victory": { + "description": "Defeat all waves", + "descriptionComplete": "Defeated all waves", + "descriptionFull": "Defeat all waves in ${LEVEL}", + "descriptionFullComplete": "Defeated all waves in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Runaround God": { + "description": "Score 2000 points", + "descriptionComplete": "Scored 2000 points", + "descriptionFull": "Score 2000 points on ${LEVEL}", + "descriptionFullComplete": "Scored 2000 points on ${LEVEL}", + "name": "${LEVEL} God" + }, + "Runaround Master": { + "description": "Score 500 points", + "descriptionComplete": "Scored 500 points", + "descriptionFull": "Score 500 points in ${LEVEL}", + "descriptionFullComplete": "Scored 500 points in ${LEVEL}", + "name": "${LEVEL} Master" + }, + "Runaround Wizard": { + "description": "Score 1000 points", + "descriptionComplete": "Scored 1000 points", + "descriptionFull": "Score 1000 points on ${LEVEL}", + "descriptionFullComplete": "Scored 1000 points on ${LEVEL}", + "name": "${LEVEL} Wizard" + }, + "Sharing is Caring": { + "descriptionFull": "Successfully share the game with a friend", + "descriptionFullComplete": "Successfully shared the game with a friend", + "name": "Sharing is Caring" + }, + "Stayin' Alive": { + "description": "Win without dying", + "descriptionComplete": "Won without dying", + "descriptionFull": "Win ${LEVEL} without dying", + "descriptionFullComplete": "Won ${LEVEL} without dying", + "name": "Stayin' Alive" + }, + "Super Mega Punch": { + "description": "Inflict 100% damage with one punch", + "descriptionComplete": "Inflicted 100% damage with one punch", + "descriptionFull": "Inflict 100% damage with one punch in ${LEVEL}", + "descriptionFullComplete": "Inflicted 100% damage with one punch in ${LEVEL}", + "name": "Super Mega Punch" + }, + "Super Punch": { + "description": "Inflict 50% damage with one punch", + "descriptionComplete": "Inflicted 50% damage with one punch", + "descriptionFull": "Inflict 50% damage with one punch on ${LEVEL}", + "descriptionFullComplete": "Inflicted 50% damage with one punch on ${LEVEL}", + "name": "Super Punch" + }, + "TNT Terror": { + "description": "Kill 6 bad guys with TNT", + "descriptionComplete": "Killed 6 bad guys with TNT", + "descriptionFull": "Kill 6 bad guys with TNT on ${LEVEL}", + "descriptionFullComplete": "Killed 6 bad guys with TNT on ${LEVEL}", + "name": "TNT Terror" + }, + "Team Player": { + "descriptionFull": "Start a Teams game with 4+ players", + "descriptionFullComplete": "Started a Teams game with 4+ players", + "name": "Team Player" + }, + "The Great Wall": { + "description": "Stop every single bad guy", + "descriptionComplete": "Stopped every single bad guy", + "descriptionFull": "Stop every single bad guy on ${LEVEL}", + "descriptionFullComplete": "Stopped every single bad guy on ${LEVEL}", + "name": "The Great Wall" + }, + "The Wall": { + "description": "Stop every single bad guy", + "descriptionComplete": "Stopped every single bad guy", + "descriptionFull": "Stop every single bad guy on ${LEVEL}", + "descriptionFullComplete": "Stopped every single bad guy on ${LEVEL}", + "name": "The Wall" + }, + "Uber Football Shutout": { + "description": "Win without letting the bad guys score", + "descriptionComplete": "Won without letting the bad guys score", + "descriptionFull": "Win ${LEVEL} without letting the bad guys score", + "descriptionFullComplete": "Won ${LEVEL} without letting the bad guys score", + "name": "${LEVEL} Shutout" + }, + "Uber Football Victory": { + "description": "Win the game", + "descriptionComplete": "Won the game", + "descriptionFull": "Win the game in ${LEVEL}", + "descriptionFullComplete": "Won the game in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Uber Onslaught Victory": { + "description": "Defeat all waves", + "descriptionComplete": "Defeated all waves", + "descriptionFull": "Defeat all waves in ${LEVEL}", + "descriptionFullComplete": "Defeated all waves in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Uber Runaround Victory": { + "description": "Complete all waves", + "descriptionComplete": "Completed all waves", + "descriptionFull": "Complete all waves on ${LEVEL}", + "descriptionFullComplete": "Completed all waves on ${LEVEL}", + "name": "${LEVEL} Victory" + } + }, + "achievementsRemainingText": "Achievements Remaining:", + "achievementsText": "Achievements", + "achievementsUnavailableForOldSeasonsText": "Sorry, achievement specifics are not available for old seasons.", + "activatedText": "${THING} activated.", + "addGameWindow": { + "getMoreGamesText": "Get More Games...", + "titleText": "Add Game" + }, + "allowText": "Allow", + "alreadySignedInText": "Your account is signed in from another device;\nplease switch accounts or close the game on your\nother devices and try again.", + "apiVersionErrorText": "Can't load module ${NAME}; it targets api-version ${VERSION_USED}; we require ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" enables this only when headphones are plugged in)", + "headRelativeVRAudioText": "Head-Relative VR Audio", + "musicVolumeText": "Music Volume", + "soundVolumeText": "Sound Volume", + "soundtrackButtonText": "Soundtracks", + "soundtrackDescriptionText": "(assign your own music to play during games)", + "titleText": "Audio" + }, + "autoText": "Auto", + "backText": "Back", + "banThisPlayerText": "Ban This Player", + "bestOfFinalText": "Best-of-${COUNT} Final", + "bestOfSeriesText": "Best of ${COUNT} series:", + "bestOfUseFirstToInstead": 0, + "bestRankText": "Your best is #${RANK}", + "bestRatingText": "Your best rating is ${RATING}", + "bombBoldText": "BOMB", + "bombText": "Bomb", + "boostText": "Boost", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} is configured in the app itself.", + "buttonText": "button", + "canWeDebugText": "Would you like BombSquad to automatically report\nbugs, crashes, and basic usage info to the developer?\n\nThis data contains no personal information and helps\nkeep the game running smoothly and bug-free.\n", + "cancelText": "Cancel", + "cantConfigureDeviceText": "Sorry, ${DEVICE} is not configurable.", + "challengeEndedText": "This challenge has ended.", + "chatMuteText": "Mute Chat", + "chatMutedText": "Chat Muted", + "chatUnMuteText": "Unmute Chat", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "You must complete\nthis level to proceed!", + "completionBonusText": "Completion Bonus", + "configControllersWindow": { + "configureControllersText": "Configure Controllers", + "configureKeyboard2Text": "Configure Keyboard P2", + "configureKeyboardText": "Configure Keyboard", + "configureMobileText": "Mobile Devices as Controllers", + "configureTouchText": "Configure Touchscreen", + "ps3Text": "PS3 Controllers", + "titleText": "Controllers", + "wiimotesText": "Wiimotes", + "xbox360Text": "Xbox 360 Controllers" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Note: controller support varies by device and Android version.", + "pressAnyButtonText": "Press any button on the controller\n you want to configure...", + "titleText": "Configure Controllers" + }, + "configGamepadWindow": { + "advancedText": "Advanced", + "advancedTitleText": "Advanced Controller Setup", + "analogStickDeadZoneDescriptionText": "(turn this up if your character 'drifts' when you release the stick)", + "analogStickDeadZoneText": "Analog Stick Dead Zone", + "appliesToAllText": "(applies to all controllers of this type)", + "autoRecalibrateDescriptionText": "(enable this if your character does not move at full speed)", + "autoRecalibrateText": "Auto-Recalibrate Analog Stick", + "axisText": "axis", + "clearText": "clear", + "dpadText": "dpad", + "extraStartButtonText": "Extra Start Button", + "ifNothingHappensTryAnalogText": "If nothing happens, try assigning to the analog stick instead.", + "ifNothingHappensTryDpadText": "If nothing happens, try assigning to the d-pad instead.", + "ignoreCompletelyDescriptionText": "(prevent this controller from affecting either the game or menus)", + "ignoreCompletelyText": "Ignore Completely", + "ignoredButton1Text": "Ignored Button 1", + "ignoredButton2Text": "Ignored Button 2", + "ignoredButton3Text": "Ignored Button 3", + "ignoredButton4Text": "Ignored Button 4", + "ignoredButtonDescriptionText": "(use this to prevent 'home' or 'sync' buttons from affecting the UI)", + "pressAnyAnalogTriggerText": "Press any analog trigger...", + "pressAnyButtonOrDpadText": "Press any button or dpad...", + "pressAnyButtonText": "Press any button...", + "pressLeftRightText": "Press left or right...", + "pressUpDownText": "Press up or down...", + "runButton1Text": "Run Button 1", + "runButton2Text": "Run Button 2", + "runTrigger1Text": "Run Trigger 1", + "runTrigger2Text": "Run Trigger 2", + "runTriggerDescriptionText": "(analog triggers let you run at variable speeds)", + "secondHalfText": "Use this to configure the second half\nof a 2-controllers-in-1 device that\nshows up as a single controller.", + "secondaryEnableText": "Enable", + "secondaryText": "Secondary Controller", + "startButtonActivatesDefaultDescriptionText": "(turn this off if your start button is more of a 'menu' button)", + "startButtonActivatesDefaultText": "Start Button Activates Default Widget", + "titleText": "Controller Setup", + "twoInOneSetupText": "2-in-1 Controller Setup", + "uiOnlyDescriptionText": "(prevent this controller from actually joining a game)", + "uiOnlyText": "Limit to Menu Use", + "unassignedButtonsRunText": "All Unassigned Buttons Run", + "unsetText": "", + "vrReorientButtonText": "VR Reorient Button" + }, + "configKeyboardWindow": { + "configuringText": "Configuring ${DEVICE}", + "keyboard2NoteText": "Note: most keyboards can only register a few keypresses at\nonce, so having a second keyboard player may work better\nif there is a separate keyboard attached for them to use.\nNote that you'll still need to assign unique keys to the\ntwo players even in that case." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Action Control Scale", + "actionsText": "Actions", + "buttonsText": "buttons", + "dragControlsText": "< drag controls to reposition them >", + "joystickText": "joystick", + "movementControlScaleText": "Movement Control Scale", + "movementText": "Movement", + "resetText": "Reset", + "swipeControlsHiddenText": "Hide Swipe Icons", + "swipeInfoText": "'Swipe' style controls take a little getting used to but\nmake it easier to play without looking at the controls.", + "swipeText": "swipe", + "titleText": "Configure Touchscreen" + }, + "configureItNowText": "Configure it now?", + "configureText": "Configure", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsScale": 0.65, + "bestResultsText": "For best results you'll need a lag-free wifi network. You can\nreduce wifi lag by turning off other wireless devices, by\nplaying close to your wifi router, and by connecting the\ngame host directly to the network via ethernet.", + "explanationText": "To use a smart-phone or tablet as a wireless controller,\ninstall the \"${REMOTE_APP_NAME}\" app on it. Any number of devices\ncan connect to a ${APP_NAME} game over Wi-Fi, and it's free!", + "forAndroidText": "for Android:", + "forIOSText": "for iOS:", + "getItForText": "Get ${REMOTE_APP_NAME} for iOS at the Apple App Store\nor for Android at the Google Play Store or Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Using Mobile Devices as Controllers:" + }, + "continuePurchaseText": "Continue for ${PRICE}?", + "continueText": "Continue", + "controlsText": "Controls", + "coopSelectWindow": { + "activenessAllTimeInfoText": "This does not apply to all-time rankings.", + "activenessInfoText": "This multiplier rises on days when you\nplay and drops on days when you do not.", + "activityText": "Activity", + "campaignText": "Campaign", + "challengesInfoText": "Earn prizes for completing mini-games.\n\nPrizes and difficulty levels increase\neach time a challenge is completed and\ndecrease when one expires or is forfeited.", + "challengesText": "Challenges", + "currentBestText": "Current Best", + "customText": "Custom", + "entryFeeText": "Entry", + "forfeitConfirmText": "Forfeit this challenge?", + "forfeitNotAllowedYetText": "This challenge cannot be forfeited yet.", + "forfeitText": "Forfeit", + "multipliersText": "Multipliers", + "nextChallengeText": "Next Challenge", + "nextPlayText": "Next Play", + "ofTotalTimeText": "of ${TOTAL}", + "playNowText": "Play Now", + "pointsText": "Points", + "powerRankingFinishedSeasonUnrankedText": "(finished season unranked)", + "powerRankingNotInTopText": "(not in the top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} pts)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} of ${REMAINING} pts)", + "powerRankingText": "Power Ranking", + "prizesText": "Prizes", + "proMultInfoText": "Players with the ${PRO} upgrade\nreceive a ${PERCENT}% point boost here.", + "seeMoreText": "More...", + "skipWaitText": "Skip Wait", + "timeRemainingText": "Time Remaining", + "toRankedText": "To Ranked", + "totalText": "total", + "tournamentInfoText": "Compete for high scores with\nother players in your league.\n\nPrizes are awarded to the top scoring\nplayers when tournament time expires.", + "welcome1Text": "Welcome to ${LEAGUE}. You can improve your\nleague rank by earning star ratings, completing\nachievements, and winning trophies in tournaments.", + "welcome2Text": "You can also earn tickets from many of the same activities.\nTickets can be used to unlock new characters, maps, and\nmini-games, to enter tournaments, and more.", + "yourPowerRankingText": "Your Power Ranking:" + }, + "copyConfirmText": "Copied to clipboard.", + "copyOfText": "${NAME} Copy", + "copyText": "Copy", + "createEditPlayerText": "", + "createText": "Create", + "creditsWindow": { + "additionalAudioArtIdeasText": "Additional Audio, Early Artwork, and Ideas by ${NAME}", + "additionalMusicFromText": "Additional music from ${NAME}", + "allMyFamilyText": "All of my friends and family who helped play test", + "codingGraphicsAudioText": "Coding, Graphics, and Audio by ${NAME}", + "languageTranslationsText": "Language Translations:", + "legalText": "Legal:", + "publicDomainMusicViaText": "Public-domain music via ${NAME}", + "softwareBasedOnText": "This software is based in part on the work of ${NAME}", + "songCreditText": "${TITLE} Performed by ${PERFORMER}\nComposed by ${COMPOSER}, Arranged by ${ARRANGER}, Published by ${PUBLISHER},\nCourtesy of ${SOURCE}", + "soundAndMusicText": "Sound & Music:", + "soundsText": "Sounds (${SOURCE}):", + "specialThanksText": "Special Thanks:", + "thanksEspeciallyToText": "Thanks especially to ${NAME}", + "titleText": "${APP_NAME} Credits", + "whoeverInventedCoffeeText": "Whoever invented coffee" + }, + "currentStandingText": "Your current standing is #${RANK}", + "customizeText": "Customize...", + "deathsTallyText": "${COUNT} deaths", + "deathsText": "Deaths", + "debugText": "debug", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Note: it is recommended that you set Settings->Graphics->Textures to 'High' while testing this.", + "runCPUBenchmarkText": "Run CPU Benchmark", + "runGPUBenchmarkText": "Run GPU Benchmark", + "runMediaReloadBenchmarkText": "Run Media-Reload Benchmark", + "runStressTestText": "Run stress test", + "stressTestPlayerCountText": "Player Count", + "stressTestPlaylistDescriptionText": "Stress Test Playlist", + "stressTestPlaylistNameText": "Playlist Name", + "stressTestPlaylistTypeText": "Playlist Type", + "stressTestRoundDurationText": "Round Duration", + "stressTestTitleText": "Stress Test", + "titleText": "Benchmarks & Stress Tests", + "totalReloadTimeText": "Total reload time: ${TIME} (see log for details)" + }, + "defaultGameListNameText": "Default ${PLAYMODE} Playlist", + "defaultNewGameListNameText": "My ${PLAYMODE} Playlist", + "deleteText": "Delete", + "demoText": "Demo", + "denyText": "Deny", + "deprecatedText": "Deprecated", + "desktopResText": "Desktop Res", + "deviceAccountUpgradeText": "Warning:\nYou are signed in with a device account (${NAME}).\nDevice accounts will be removed in a future update.\nUpgrade to a V2 Account if you want to keep your progress.", + "difficultyEasyText": "Easy", + "difficultyHardOnlyText": "Hard Mode Only", + "difficultyHardText": "Hard", + "difficultyHardUnlockOnlyText": "This level can only be unlocked in hard mode.\nDo you think you have what it takes!?!?!", + "directBrowserToURLText": "Please direct a web-browser to the following URL:", + "disableRemoteAppConnectionsText": "Disable Remote-App Connections", + "disableXInputDescriptionText": "Allows more than 4 controllers but may not work as well.", + "disableXInputText": "Disable XInput", + "doneText": "Done", + "drawText": "Draw", + "duplicateText": "Duplicate", + "editGameListWindow": { + "addGameText": "Add\nGame", + "cantOverwriteDefaultText": "Can't overwrite the default playlist!", + "cantSaveAlreadyExistsText": "A playlist with that name already exists!", + "cantSaveEmptyListText": "Can't save an empty playlist!", + "editGameText": "Edit\nGame", + "listNameText": "Playlist Name", + "nameText": "Name", + "removeGameText": "Remove\nGame", + "saveText": "Save List", + "titleText": "Playlist Editor" + }, + "editProfileWindow": { + "accountProfileInfoText": "This special profile has a name\nand icon based on your account.\n\n${ICONS}\n\nCreate custom profiles to use\ndifferent names or custom icons.", + "accountProfileText": "(account profile)", + "availableText": "The name \"${NAME}\" is available.", + "characterText": "character", + "checkingAvailabilityText": "Checking availability for \"${NAME}\"...", + "colorText": "color", + "getMoreCharactersText": "Get More Characters...", + "getMoreIconsText": "Get More Icons...", + "globalProfileInfoText": "Global player profiles are guaranteed to have unique\nnames worldwide. They also include custom icons.", + "globalProfileText": "(global profile)", + "highlightText": "highlight", + "iconText": "icon", + "localProfileInfoText": "Local player profiles have no icons and their names are\nnot guaranteed to be unique. Upgrade to a global profile\nto reserve a unique name and add a custom icon.", + "localProfileText": "(local profile)", + "nameDescriptionText": "Player Name", + "nameText": "Name", + "randomText": "random", + "titleEditText": "Edit Profile", + "titleNewText": "New Profile", + "unavailableText": "\"${NAME}\" is unavailable; try another name.", + "upgradeProfileInfoText": "This will reserve your player name worldwide\nand allow you to assign a custom icon to it.", + "upgradeToGlobalProfileText": "Upgrade to Global Profile" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "You can't delete the default soundtrack.", + "cantEditDefaultText": "Can't edit default soundtrack. Duplicate it or create a new one.", + "cantOverwriteDefaultText": "Can't overwrite default soundtrack", + "cantSaveAlreadyExistsText": "A soundtrack with that name already exists!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Default Soundtrack", + "deleteConfirmText": "Delete Soundtrack:\n\n'${NAME}'?", + "deleteText": "Delete\nSoundtrack", + "duplicateText": "Duplicate\nSoundtrack", + "editSoundtrackText": "Soundtrack Editor", + "editText": "Edit\nSoundtrack", + "fetchingITunesText": "fetching Music App playlists...", + "musicVolumeZeroWarning": "Warning: music volume is set to 0", + "nameText": "Name", + "newSoundtrackNameText": "My Soundtrack ${COUNT}", + "newSoundtrackText": "New Soundtrack:", + "newText": "New\nSoundtrack", + "selectAPlaylistText": "Select A Playlist", + "selectASourceText": "Music Source", + "testText": "test", + "titleText": "Soundtracks", + "useDefaultGameMusicText": "Default Game Music", + "useITunesPlaylistText": "Music App Playlist", + "useMusicFileText": "Music File (mp3, etc)", + "useMusicFolderText": "Folder of Music Files" + }, + "editText": "Edit", + "endText": "End", + "enjoyText": "Enjoy!", + "epicDescriptionFilterText": "${DESCRIPTION} In epic slow motion.", + "epicNameFilterText": "Epic ${NAME}", + "errorAccessDeniedText": "access denied", + "errorDeviceTimeIncorrectText": "Your device's time is incorrect by ${HOURS} hours.\nThis is likely to cause problems.\nPlease check your time and time-zone settings.", + "errorOutOfDiskSpaceText": "out of disk space", + "errorSecureConnectionFailText": "Unable to establish secure cloud connection; network functionality may fail.", + "errorText": "Error", + "errorUnknownText": "unknown error", + "exitGameText": "Exit ${APP_NAME}?", + "exportSuccessText": "'${NAME}' exported.", + "externalStorageText": "External Storage", + "failText": "Fail", + "fatalErrorText": "Uh oh; something is missing or broken.\nPlease try reinstalling the app or\ncontact ${EMAIL} for help.", + "fileSelectorWindow": { + "titleFileFolderText": "Select a File or Folder", + "titleFileText": "Select a File", + "titleFolderText": "Select a Folder", + "useThisFolderButtonText": "Use This Folder" + }, + "filterText": "Filter", + "finalScoreText": "Final Score", + "finalScoresText": "Final Scores", + "finalTimeText": "Final Time", + "finishingInstallText": "Finishing install; one moment...", + "fireTVRemoteWarningText": "* For a better experience, use\nGame Controllers or install the\n'${REMOTE_APP_NAME}' app on your\nphones and tablets.", + "firstToFinalText": "First-to-${COUNT} Final", + "firstToSeriesText": "First-to-${COUNT} Series", + "fiveKillText": "FIVE KILL!!!", + "flawlessWaveText": "Flawless Wave!", + "fourKillText": "QUAD KILL!!!", + "friendScoresUnavailableText": "Friend scores unavailable.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Game ${COUNT} Leaders", + "gameListWindow": { + "cantDeleteDefaultText": "You can't delete the default playlist.", + "cantEditDefaultText": "Can't edit the default playlist! Duplicate it or create a new one.", + "cantShareDefaultText": "You can't share the default playlist.", + "deleteConfirmText": "Delete \"${LIST}\"?", + "deleteText": "Delete\nPlaylist", + "duplicateText": "Duplicate\nPlaylist", + "editText": "Edit\nPlaylist", + "newText": "New\nPlaylist", + "showTutorialText": "Show Tutorial", + "shuffleGameOrderText": "Shuffle Game Order", + "titleText": "Customize ${TYPE} Playlists" + }, + "gameSettingsWindow": { + "addGameText": "Add Game" + }, + "gamesToText": "${WINCOUNT} games to ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Remember: any device in a party can have more\nthan one player if you have enough controllers.", + "aboutDescriptionText": "Use these tabs to assemble a party.\n\nParties let you play games and tournaments\nwith your friends across different devices.\n\nUse the ${PARTY} button at the top right to\nchat and interact with your party.\n(on a controller, press ${BUTTON} while in a menu)", + "aboutText": "About", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} sent you ${COUNT} tickets in ${APP_NAME}", + "appInviteSendACodeText": "Send Them A Code", + "appInviteTitleText": "${APP_NAME} App Invite", + "bluetoothAndroidSupportText": "(works with any Android device supporting Bluetooth)", + "bluetoothDescriptionText": "Host/join a party over Bluetooth:", + "bluetoothHostText": "Host over Bluetooth", + "bluetoothJoinText": "Join over Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "checking...", + "copyCodeConfirmText": "Code copied to clipboard.", + "copyCodeText": "Copy Code", + "dedicatedServerInfoText": "For best results, set up a dedicated server. See bombsquadgame.com/server to learn how.", + "disconnectClientsText": "This will disconnect the ${COUNT} player(s)\nin your party. Are you sure?", + "earnTicketsForRecommendingAmountText": "Friends will receive ${COUNT} tickets if they try the game\n(and you will receive ${YOU_COUNT} for each who does)", + "earnTicketsForRecommendingText": "Share the game\nfor free tickets...", + "emailItText": "Email It", + "favoritesSaveText": "Save As Favorite", + "favoritesText": "Favorites", + "freeCloudServerAvailableMinutesText": "Next free cloud server available in ${MINUTES} minutes.", + "freeCloudServerAvailableNowText": "Free cloud server available!", + "freeCloudServerNotAvailableText": "No free cloud servers available.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} tickets from ${NAME}", + "friendPromoCodeAwardText": "You will receive ${COUNT} tickets each time it is used.", + "friendPromoCodeExpireText": "The code will expire in ${EXPIRE_HOURS} hours and only works for new players.", + "friendPromoCodeInstructionsText": "To use it, open ${APP_NAME} and go to \"Settings->Advanced->Enter Code\".\nSee bombsquadgame.com for download links for all supported platforms.", + "friendPromoCodeRedeemLongText": "It can be redeemed for ${COUNT} free tickets by up to ${MAX_USES} people.", + "friendPromoCodeRedeemShortText": "It can be redeemed for ${COUNT} tickets in the game.", + "friendPromoCodeWhereToEnterText": "(in \"Settings->Advanced->Enter Code\")", + "getFriendInviteCodeText": "Get Friend Invite Code", + "googlePlayDescriptionText": "Invite Google Play players to your party:", + "googlePlayInviteText": "Invite", + "googlePlayReInviteText": "There are ${COUNT} Google Play player(s) in your party\nwho will be disconnected if you start a new invite.\nInclude them in the new invitation to get them back.", + "googlePlaySeeInvitesText": "See Invites", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play version)", + "hostPublicPartyDescriptionText": "Host a Public Party", + "hostingUnavailableText": "Hosting Unavailable", + "inDevelopmentWarningText": "Note:\n\nNetwork play is a new and still-evolving feature.\nFor now, it is highly recommended that all\nplayers be on the same Wi-Fi network.", + "internetText": "Internet", + "inviteAFriendText": "Friends don't have the game? Invite them to\ntry it and they'll receive ${COUNT} free tickets.", + "inviteFriendsText": "Invite Friends", + "joinPublicPartyDescriptionText": "Join a Public Party", + "localNetworkDescriptionText": "Join a Nearby Party (LAN, Bluetooth, etc.)", + "localNetworkText": "Local Network", + "makePartyPrivateText": "Make My Party Private", + "makePartyPublicText": "Make My Party Public", + "manualAddressText": "Address", + "manualConnectText": "Connect", + "manualDescriptionText": "Join a party by address:", + "manualJoinSectionText": "Join By Address", + "manualJoinableFromInternetText": "Are you joinable from the internet?:", + "manualJoinableNoWithAsteriskText": "NO*", + "manualJoinableYesText": "YES", + "manualRouterForwardingText": "*to fix this, try configuring your router to forward UDP port ${PORT} to your local address", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Your address from the internet:", + "manualYourLocalAddressText": "Your local address:", + "nearbyText": "Nearby", + "noConnectionText": "", + "otherVersionsText": "(other versions)", + "partyCodeText": "Party Code", + "partyInviteAcceptText": "Accept", + "partyInviteDeclineText": "Decline", + "partyInviteGooglePlayExtraText": "(see the 'Google Play' tab in the 'Gather' window)", + "partyInviteIgnoreText": "Ignore", + "partyInviteText": "${NAME} has invited\nyou to join their party!", + "partyNameText": "Party Name", + "partyServerRunningText": "Your party server is running.", + "partySizeText": "party size", + "partyStatusCheckingText": "checking status...", + "partyStatusJoinableText": "your party is now joinable from the internet", + "partyStatusNoConnectionText": "unable to connect to server", + "partyStatusNotJoinableText": "your party is not joinable from the internet", + "partyStatusNotPublicText": "your party is not public", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Private parties run on dedicated cloud servers; no router configuration required.", + "privatePartyHostText": "Host a Private Party", + "privatePartyJoinText": "Join a Private Party", + "privateText": "Private", + "publicHostRouterConfigText": "This may require configuring port-forwarding on your router. For an easier option, host a private party.", + "publicText": "Public", + "requestingAPromoCodeText": "Requesting a code...", + "sendDirectInvitesText": "Send Direct Invites", + "shareThisCodeWithFriendsText": "Share this code with friends:", + "showMyAddressText": "Show My Address", + "startHostingPaidText": "Host Now For ${COST}", + "startHostingText": "Host", + "startStopHostingMinutesText": "You can start and stop hosting for free for the next ${MINUTES} minutes.", + "stopHostingText": "Stop Hosting", + "titleText": "Gather", + "wifiDirectDescriptionBottomText": "If all devices have a 'Wi-Fi Direct' panel, they should be able to use it to find\nand connect to each other. Once all devices are connected, you can form parties\nhere using the 'Local Network' tab, just the same as with a regular Wi-Fi network.\n\nFor best results, the Wi-Fi Direct host should also be the ${APP_NAME} party host.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct can be used to connect Android devices directly without\nneeding a Wi-Fi network. This works best on Android 4.2 or newer.\n\nTo use it, open Wi-Fi settings and look for 'Wi-Fi Direct' in the menu.", + "wifiDirectOpenWiFiSettingsText": "Open Wi-Fi Settings", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(works between all platforms)", + "worksWithGooglePlayDevicesText": "(works with devices running the Google Play (android) version of the game)", + "youHaveBeenSentAPromoCodeText": "You have been sent a ${APP_NAME} promo code:" + }, + "getTicketsWindow": { + "freeText": "FREE!", + "freeTicketsText": "Free Tickets", + "inProgressText": "A transaction is in progress; please try again in a moment.", + "purchasesRestoredText": "Purchases restored.", + "receivedTicketsText": "Received ${COUNT} tickets!", + "restorePurchasesText": "Restore Purchases", + "ticketPack1Text": "Small Ticket Pack", + "ticketPack2Text": "Medium Ticket Pack", + "ticketPack3Text": "Large Ticket Pack", + "ticketPack4Text": "Jumbo Ticket Pack", + "ticketPack5Text": "Mammoth Ticket Pack", + "ticketPack6Text": "Ultimate Ticket Pack", + "ticketsFromASponsorText": "Watch an ad\nfor ${COUNT} tickets", + "ticketsText": "${COUNT} Tickets", + "titleText": "Get Tickets", + "unavailableLinkAccountText": "Sorry, purchases are not available on this platform.\nAs a workaround, you can link this account to an account on\nanother platform and make purchases there.", + "unavailableTemporarilyText": "This is currently unavailable; please try again later.", + "unavailableText": "Sorry, this is not available.", + "versionTooOldText": "Sorry, this version of the game is too old; please update to a newer one.", + "youHaveShortText": "you have ${COUNT}", + "youHaveText": "you have ${COUNT} tickets" + }, + "googleMultiplayerDiscontinuedText": "Sorry, Google’s multiplayer service is no longer available.\nI am working on a replacement as fast as possible.\nUntil then, please try another connection method.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Google Play purchases are not available.\nYou may need to update your store app.", + "googlePlayServicesNotAvailableText": "Google Play Services is not available.\nSome app functionality may be disabled.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Always", + "fullScreenCmdText": "Fullscreen (Cmd-F)", + "fullScreenCtrlText": "Fullscreen (Ctrl-F)", + "gammaText": "Gamma", + "highText": "High", + "higherText": "Higher", + "lowText": "Low", + "mediumText": "Medium", + "neverText": "Never", + "resolutionText": "Resolution", + "showFPSText": "Show FPS", + "texturesText": "Textures", + "titleText": "Graphics", + "tvBorderText": "TV Border", + "verticalSyncText": "Vertical Sync", + "visualsText": "Visuals" + }, + "helpWindow": { + "bombInfoText": "- Bomb -\nStronger than punches, but\ncan result in grave self-injury.\nFor best results, throw towards\nenemy before fuse runs out.", + "bombInfoTextScale": 0.6, + "canHelpText": "${APP_NAME} can help.", + "controllersInfoText": "You can play ${APP_NAME} with friends over a network, or you\ncan all play on the same device if you have enough controllers.\n${APP_NAME} supports a variety of them; you can even use phones\nas controllers via the free '${REMOTE_APP_NAME}' app.\nSee Settings->Controllers for more info.", + "controllersInfoTextRemoteOnly": "You can play ${APP_NAME} with friends over a network, or you\ncan all play on the same device by using phones as\ncontrollers via the free '${REMOTE_APP_NAME}' app.", + "controllersText": "Controllers", + "controlsSubtitleText": "Your friendly ${APP_NAME} character has a few basic actions:", + "controlsText": "Controls", + "devicesInfoText": "The VR version of ${APP_NAME} can be played over the network with\nthe regular version, so whip out your extra phones, tablets,\nand computers and get your game on. It can even be useful to\nconnect a regular version of the game to the VR version just to\nallow people outside to watch the action.", + "devicesText": "Devices", + "friendsGoodText": "These are good to have. ${APP_NAME} is most fun with several\nplayers and can support up to 8 at a time, which leads us to:", + "friendsText": "Friends", + "jumpInfoText": "- Jump -\nJump to cross small gaps,\nto throw things higher, and\nto express feelings of joy.", + "jumpInfoTextScale": 0.6, + "orPunchingSomethingExtraSpace": 0, + "orPunchingSomethingText": "Or punching something, throwing it off a cliff, and blowing it up on the way down with a sticky bomb.", + "pickUpInfoText": "- Pick Up -\nGrab flags, enemies, or anything\nelse not bolted to the ground.\nPress again to throw.", + "pickUpInfoTextScale": 0.6, + "powerupBombDescriptionText": "Lets you whip out three bombs\nin a row instead of just one.", + "powerupBombNameText": "Triple-Bombs", + "powerupCurseDescriptionText": "You probably want to avoid these.\n ...or do you?", + "powerupCurseNameText": "Curse", + "powerupHealthDescriptionText": "Restores you to full health.\nYou'd never have guessed.", + "powerupHealthNameText": "Med-Pack", + "powerupIceBombsDescriptionText": "Weaker than normal bombs\nbut leave your enemies frozen\nand particularly brittle.", + "powerupIceBombsNameText": "Ice-Bombs", + "powerupImpactBombsDescriptionText": "Slightly weaker than regular\nbombs, but they explode on impact.", + "powerupImpactBombsNameText": "Trigger-Bombs", + "powerupLandMinesDescriptionText": "These come in packs of 3;\nUseful for base defense or\nstopping speedy enemies.", + "powerupLandMinesNameText": "Land-Mines", + "powerupPunchDescriptionText": "Makes your punches harder,\nfaster, better, stronger.", + "powerupPunchNameText": "Boxing-Gloves", + "powerupShieldDescriptionText": "Absorbs a bit of damage\nso you don't have to.", + "powerupShieldNameText": "Energy-Shield", + "powerupStickyBombsDescriptionText": "Stick to anything they hit.\nHilarity ensues.", + "powerupStickyBombsNameText": "Sticky-Bombs", + "powerupsSubtitleText": "Of course, no game is complete without powerups:", + "powerupsSubtitleTextScale": 0.8, + "powerupsText": "Powerups", + "punchInfoText": "- Punch -\nPunches do more damage the\nfaster your fists are moving, so\nrun and spin like a madman.", + "punchInfoTextScale": 0.6, + "runInfoText": "- Run -\nHold ANY button to run. Triggers or shoulder buttons work well if you have them.\nRunning gets you places faster but makes it hard to turn, so watch out for cliffs.", + "runInfoTextScale": 0.6, + "someDaysExtraSpace": 0, + "someDaysText": "Some days you just feel like punching something. Or blowing something up.", + "titleText": "${APP_NAME} Help", + "toGetTheMostText": "To get the most out of this game, you'll need:", + "welcomeText": "Welcome to ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} is navigating menus like a boss -", + "importPlaylistCodeInstructionsText": "Use the following code to import this playlist elsewhere:", + "importPlaylistSuccessText": "Imported ${TYPE} playlist '${NAME}'", + "importText": "Import", + "importingText": "Importing...", + "inGameClippedNameText": "in-game will be\n\"${NAME}\"", + "installDiskSpaceErrorText": "ERROR: Unable to complete the install.\nYou may be out of space on your device.\nClear some space and try again.", + "internal": { + "arrowsToExitListText": "press ${LEFT} or ${RIGHT} to exit list", + "buttonText": "button", + "cantKickHostError": "You can't kick the host.", + "chatBlockedText": "${NAME} is chat-blocked for ${TIME} seconds.", + "connectedToGameText": "Joined '${NAME}'", + "connectedToPartyText": "Joined ${NAME}'s party!", + "connectingToPartyText": "Connecting...", + "connectionFailedHostAlreadyInPartyText": "Connection failed; host is in another party.", + "connectionFailedPartyFullText": "Connection failed; the party is full.", + "connectionFailedText": "Connection failed.", + "connectionFailedVersionMismatchText": "Connection failed; host is running a different version of the game.\nMake sure you are both up-to-date and try again.", + "connectionRejectedText": "Connection rejected.", + "controllerConnectedText": "${CONTROLLER} connected.", + "controllerDetectedText": "1 controller detected.", + "controllerDisconnectedText": "${CONTROLLER} disconnected.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} disconnected. Please try connecting again.", + "controllerForMenusOnlyText": "This controller can not be used to play; only to navigate menus.", + "controllerReconnectedText": "${CONTROLLER} reconnected.", + "controllersConnectedText": "${COUNT} controllers connected.", + "controllersDetectedText": "${COUNT} controllers detected.", + "controllersDisconnectedText": "${COUNT} controllers disconnected.", + "corruptFileText": "Corrupt file(s) detected. Please try re-installing, or email ${EMAIL}", + "errorPlayingMusicText": "Error playing music: ${MUSIC}", + "errorResettingAchievementsText": "Unable to reset online achievements; please try again later.", + "hasMenuControlText": "${NAME} has menu control.", + "incompatibleNewerVersionHostText": "Host is running a newer version of the game.\nUpdate to the latest version and try again.", + "incompatibleVersionHostText": "Host is running a different version of the game.\nMake sure you are both up-to-date and try again.", + "incompatibleVersionPlayerText": "${NAME} is running a different version of the game.\nMake sure you are both up-to-date and try again.", + "invalidAddressErrorText": "Error: invalid address.", + "invalidNameErrorText": "Error: invalid name.", + "invalidPortErrorText": "Error: invalid port.", + "invitationSentText": "Invitation sent.", + "invitationsSentText": "${COUNT} invitations sent.", + "joinedPartyInstructionsText": "Someone has joined your party.\nGo to 'Play' to start a game.", + "keyboardText": "Keyboard", + "kickIdlePlayersKickedText": "Kicking ${NAME} for being idle.", + "kickIdlePlayersWarning1Text": "${NAME} will be kicked in ${COUNT} seconds if still idle.", + "kickIdlePlayersWarning2Text": "(you can turn this off in Settings -> Advanced)", + "leftGameText": "Left '${NAME}'.", + "leftPartyText": "Left ${NAME}'s party.", + "noMusicFilesInFolderText": "Folder contains no music files.", + "playerJoinedPartyText": "${NAME} joined the party!", + "playerLeftPartyText": "${NAME} left the party.", + "rejectingInviteAlreadyInPartyText": "Rejecting invite (already in a party).", + "serverRestartingText": "Server is restarting. Please rejoin in a moment...", + "serverShuttingDownText": "Server is shutting down...", + "signInErrorText": "Error signing in.", + "signInNoConnectionText": "Unable to sign in. (no internet connection?)", + "telnetAccessDeniedText": "ERROR: user has not granted telnet access.\n", + "timeOutText": "(times out in ${TIME} seconds)", + "touchScreenJoinWarningText": "You have joined with the touchscreen.\nIf this was a mistake, tap 'Menu->Leave Game' with it.", + "touchScreenText": "TouchScreen", + "unableToResolveHostText": "Error: unable to resolve host.", + "unavailableNoConnectionText": "This is currently unavailable (no internet connection?)", + "vrOrientationResetCardboardText": "Use this to reset the VR orientation.\nTo play the game you'll need an external controller.", + "vrOrientationResetText": "VR orientation reset.", + "willTimeOutText": "(will time out if idle)" + }, + "jumpBoldText": "JUMP", + "jumpText": "Jump", + "keepText": "Keep", + "keepTheseSettingsText": "Keep these settings?", + "keyboardChangeInstructionsText": "Double press space to change keyboards.", + "keyboardNoOthersAvailableText": "No other keyboards available.", + "keyboardSwitchText": "Switching keyboard to \"${NAME}\".", + "kickOccurredText": "${NAME} was kicked.", + "kickQuestionText": "Kick ${NAME}?", + "kickText": "Kick", + "kickVoteCantKickAdminsText": "Admins can't be kicked.", + "kickVoteCantKickSelfText": "You can't kick yourself.", + "kickVoteFailedNotEnoughVotersText": "Not enough players for a vote.", + "kickVoteFailedText": "Kick-vote failed.", + "kickVoteStartedText": "A kick vote has been started for ${NAME}.", + "kickVoteText": "Vote to Kick", + "kickVotingDisabledText": "Kick voting is disabled.", + "kickWithChatText": "Type ${YES} in chat for yes and ${NO} for no.", + "killsTallyText": "${COUNT} kills", + "killsText": "Kills", + "kioskWindow": { + "easyText": "Easy", + "epicModeText": "Epic Mode", + "fullMenuText": "Full Menu", + "hardText": "Hard", + "mediumText": "Medium", + "singlePlayerExamplesText": "Single Player / Co-op Examples", + "versusExamplesText": "Versus Examples" + }, + "languageSetText": "Language is now \"${LANGUAGE}\".", + "lapNumberText": "Lap ${CURRENT}/${TOTAL}", + "lastGamesText": "(last ${COUNT} games)", + "leaderboardsText": "Leaderboards", + "league": { + "allTimeText": "All Time", + "currentSeasonText": "Current Season (${NUMBER})", + "leagueFullText": "${NAME} League", + "leagueRankText": "League Rank", + "leagueText": "League", + "rankInLeagueText": "#${RANK}, ${NAME} League${SUFFIX}", + "seasonEndedDaysAgoText": "Season ended ${NUMBER} days ago.", + "seasonEndsDaysText": "Season ends in ${NUMBER} days.", + "seasonEndsHoursText": "Season ends in ${NUMBER} hours.", + "seasonEndsMinutesText": "Season ends in ${NUMBER} minutes.", + "seasonText": "Season ${NUMBER}", + "tournamentLeagueText": "You must reach ${NAME} league to enter this tournament.", + "trophyCountsResetText": "Trophy counts will reset next season." + }, + "levelBestScoresText": "Best scores on ${LEVEL}", + "levelBestTimesText": "Best times on ${LEVEL}", + "levelIsLockedText": "${LEVEL} is locked.", + "levelMustBeCompletedFirstText": "${LEVEL} must be completed first.", + "levelText": "Level ${NUMBER}", + "levelUnlockedText": "Level Unlocked!", + "livesBonusText": "Lives Bonus", + "loadingText": "loading", + "loadingTryAgainText": "Loading; try again in a moment...", + "macControllerSubsystemBothText": "Both (not recommended)", + "macControllerSubsystemClassicText": "Classic", + "macControllerSubsystemDescriptionText": "(try changing this if your controllers aren't working)", + "macControllerSubsystemMFiNoteText": "Made-for-iOS/Mac controller detected;\nYou may want to enable these in Settings -> Controllers", + "macControllerSubsystemMFiText": "Made-for-iOS/Mac", + "macControllerSubsystemTitleText": "Controller Support", + "mainMenu": { + "creditsText": "Credits", + "demoMenuText": "Demo Menu", + "endGameText": "End Game", + "endTestText": "End Test", + "exitGameText": "Exit Game", + "exitToMenuText": "Exit to menu?", + "howToPlayText": "How to Play", + "justPlayerText": "(Just ${NAME})", + "leaveGameText": "Leave Game", + "leavePartyConfirmText": "Really leave the party?", + "leavePartyText": "Leave Party", + "quitText": "Quit", + "resumeText": "Resume", + "settingsText": "Settings" + }, + "makeItSoText": "Make it So", + "mapSelectGetMoreMapsText": "Get More Maps...", + "mapSelectText": "Select...", + "mapSelectTitleText": "${GAME} Maps", + "mapText": "Map", + "maxConnectionsText": "Max Connections", + "maxPartySizeText": "Max Party Size", + "maxPlayersText": "Max Players", + "merchText": "Merch!", + "modeArcadeText": "Arcade Mode", + "modeClassicText": "Classic Mode", + "modeDemoText": "Demo Mode", + "mostValuablePlayerText": "Most Valuable Player", + "mostViolatedPlayerText": "Most Violated Player", + "mostViolentPlayerText": "Most Violent Player", + "moveText": "Move", + "multiKillText": "${COUNT}-KILL!!!", + "multiPlayerCountText": "${COUNT} players", + "mustInviteFriendsText": "Note: you must invite friends in\nthe \"${GATHER}\" panel or attach\ncontrollers to play multiplayer.", + "nameBetrayedText": "${NAME} betrayed ${VICTIM}.", + "nameDiedText": "${NAME} died.", + "nameKilledText": "${NAME} killed ${VICTIM}.", + "nameNotEmptyText": "Name cannot be empty!", + "nameScoresText": "${NAME} Scores!", + "nameSuicideKidFriendlyText": "${NAME} accidentally died.", + "nameSuicideText": "${NAME} committed suicide.", + "nameText": "Name", + "nativeText": "Native", + "newPersonalBestText": "New personal best!", + "newTestBuildAvailableText": "A newer test build is available! (${VERSION} build ${BUILD}).\nGet it at ${ADDRESS}", + "newText": "New", + "newVersionAvailableText": "A newer version of ${APP_NAME} is available! (${VERSION})", + "nextAchievementsText": "Next Achievements:", + "nextLevelText": "Next Level", + "noAchievementsRemainingText": "- none", + "noContinuesText": "(no continues)", + "noExternalStorageErrorText": "No external storage found on this device", + "noGameCircleText": "Error: not logged into GameCircle", + "noScoresYetText": "No scores yet.", + "noThanksText": "No Thanks", + "noTournamentsInTestBuildText": "WARNING: Tournament scores from this test build will be ignored.", + "noValidMapsErrorText": "No valid maps found for this game type.", + "notEnoughPlayersRemainingText": "Not enough players remaining; exit and start a new game.", + "notEnoughPlayersText": "You need at least ${COUNT} players to start this game!", + "notNowText": "Not Now", + "notSignedInErrorText": "You must sign in to do this.", + "notSignedInGooglePlayErrorText": "You must sign in with Google Play to do this.", + "notSignedInText": "not signed in", + "notUsingAccountText": "Note: ignoring ${SERVICE} account.\nGo to 'Account -> Sign in with ${SERVICE}' if you want to use it.", + "nothingIsSelectedErrorText": "Nothing is selected!", + "numberText": "#${NUMBER}", + "offText": "Off", + "okText": "Ok", + "onText": "On", + "oneMomentText": "One Moment...", + "onslaughtRespawnText": "${PLAYER} will respawn in wave ${WAVE}", + "orText": "${A} or ${B}", + "otherText": "Other...", + "outOfText": "(#${RANK} out of ${ALL})", + "ownFlagAtYourBaseWarning": "Your own flag must be\nat your base to score!", + "partyWindow": { + "chatMessageText": "Chat Message", + "emptyText": "Your party is empty", + "hostText": "(host)", + "sendText": "Send", + "titleText": "Your Party" + }, + "pausedByHostText": "(paused by host)", + "perfectWaveText": "Perfect Wave!", + "pickUpText": "Pick Up", + "playModes": { + "coopText": "Co-op", + "freeForAllText": "Free-for-All", + "multiTeamText": "Multi-Team", + "singlePlayerCoopText": "Single Player / Co-op", + "teamsText": "Teams" + }, + "playText": "Play", + "playWindow": { + "oneToFourPlayersText": "1-4 players", + "titleText": "Play", + "twoToEightPlayersText": "2-8 players" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} will enter at the start of the next round.", + "playerInfoText": "Player Info", + "playerLeftText": "${PLAYER} left the game.", + "playerLimitReachedText": "Player limit of ${COUNT} reached; no joiners allowed.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "You can't delete your account profile.", + "deleteButtonText": "Delete\nProfile", + "deleteConfirmText": "Delete '${PROFILE}'?", + "editButtonText": "Edit\nProfile", + "explanationText": "(custom player names and appearances for this account)", + "newButtonText": "New\nProfile", + "titleText": "Player Profiles" + }, + "playerText": "Player", + "playlistNoValidGamesErrorText": "This playlist contains no valid unlocked games.", + "playlistNotFoundText": "playlist not found", + "playlistText": "Playlist", + "playlistsText": "Playlists", + "pleaseRateText": "If you're enjoying ${APP_NAME}, please consider taking a\nmoment and rating it or writing a review. This provides\nuseful feedback and helps support future development.\n\nthanks!\n-eric", + "pleaseWaitText": "Please wait...", + "pluginClassLoadErrorText": "Error loading plugin class '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Error initing plugin '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Plugin Settings", + "pluginsAutoEnableNewText": "Auto Enable New Plugins", + "pluginsDetectedText": "New plugin(s) detected. Restart to activate them, or configure them in settings.", + "pluginsDisableAllText": "Disable All Plugins", + "pluginsEnableAllText": "Enable All Plugins", + "pluginsRemovedText": "${NUM} plugin(s) no longer found.", + "pluginsText": "Plugins", + "practiceText": "Practice", + "pressAnyButtonPlayAgainText": "Press any button to play again...", + "pressAnyButtonText": "Press any button to continue...", + "pressAnyButtonToJoinText": "press any button to join...", + "pressAnyKeyButtonPlayAgainText": "Press any key/button to play again...", + "pressAnyKeyButtonText": "Press any key/button to continue...", + "pressAnyKeyText": "Press any key...", + "pressJumpToFlyText": "** Press jump repeatedly to fly **", + "pressPunchToJoinText": "press PUNCH to join...", + "pressToOverrideCharacterText": "press ${BUTTONS} to override your character", + "pressToSelectProfileText": "press ${BUTTONS} to select a player", + "pressToSelectTeamText": "press ${BUTTONS} to select a team", + "promoCodeWindow": { + "codeText": "Code", + "enterText": "Enter" + }, + "promoSubmitErrorText": "Error submitting code; check your internet connection", + "ps3ControllersWindow": { + "macInstructionsText": "Switch off the power on the back of your PS3, make sure\nBluetooth is enabled on your Mac, then connect your controller\nto your Mac via a USB cable to pair the two. From then on, you\ncan use the controller's home button to connect it to your Mac\nin either wired (USB) or wireless (Bluetooth) mode.\n\nOn some Macs you may be prompted for a passcode when pairing.\nIf this happens, see the following tutorial or google for help.\n\n\n\n\nPS3 controllers connected wirelessly should show up in the device\nlist in System Preferences->Bluetooth. You may need to remove them\nfrom that list when you want to use them with your PS3 again.\n\nAlso make sure to disconnect them from Bluetooth when not in\nuse or their batteries will continue to drain.\n\nBluetooth should handle up to 7 connected devices,\nthough your mileage may vary.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "To use a PS3 controller with your OUYA, simply connect it with a USB cable\nonce to pair it. Doing this may disconnect your other controllers, so\nyou should then restart your OUYA and unplug the USB cable.\n\nFrom then on you should be able to use the controller's HOME button to\nconnect it wirelessly. When you are done playing, hold the HOME button\nfor 10 seconds to turn the controller off; otherwise it may remain on\nand waste batteries.", + "ouyaInstructionsTextScale": 0.74, + "pairingTutorialText": "pairing tutorial video", + "titleText": "Using PS3 Controllers with ${APP_NAME}:" + }, + "punchBoldText": "PUNCH", + "punchText": "Punch", + "purchaseForText": "Purchase for ${PRICE}", + "purchaseGameText": "Purchase Game", + "purchasingText": "Purchasing...", + "quitGameText": "Quit ${APP_NAME}?", + "quittingIn5SecondsText": "Quitting in 5 seconds...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Random", + "rankText": "Rank", + "ratingText": "Rating", + "reachWave2Text": "Reach wave 2 to rank.", + "readyText": "ready", + "recentText": "Recent", + "remoteAppInfoShortText": "${APP_NAME} is most fun when played with family & friends.\nConnect one or more hardware controllers or install the\n${REMOTE_APP_NAME} app on phones or tablets to use them\nas controllers.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Button Position", + "button_size": "Button Size", + "cant_resolve_host": "Can't resolve host.", + "capturing": "Capturing…", + "connected": "Connected.", + "description": "Use your phone or tablet as a controller with BombSquad.\nUp to 8 devices can connect at once for epic local multiplayer madness on a single TV or tablet.", + "disconnected": "Disconnected by server.", + "dpad_fixed": "fixed", + "dpad_floating": "floating", + "dpad_position": "D-Pad Position", + "dpad_size": "D-Pad Size", + "dpad_type": "D-Pad Type", + "enter_an_address": "Enter an Address", + "game_full": "The game is full or not accepting connections.", + "game_shut_down": "The game has shut down.", + "hardware_buttons": "Hardware Buttons", + "join_by_address": "Join by Address…", + "lag": "Lag: ${SECONDS} seconds", + "reset": "Reset to default", + "run1": "Run 1", + "run2": "Run 2", + "searching": "Searching for BombSquad games…", + "searching_caption": "Tap on the name of a game to join it.\nMake sure you are on the same wifi network as the game.", + "start": "Start", + "version_mismatch": "Version mismatch.\nMake sure BombSquad and BombSquad Remote\nare the latest versions and try again." + }, + "removeInGameAdsText": "Unlock \"${PRO}\" in the store to remove in-game ads.", + "renameText": "Rename", + "replayEndText": "End Replay", + "replayNameDefaultText": "Last Game Replay", + "replayReadErrorText": "Error reading replay file.", + "replayRenameWarningText": "Rename \"${REPLAY}\" after a game if you want to keep it; otherwise it will be overwritten.", + "replayVersionErrorText": "Sorry, this replay was made in a different\nversion of the game and can't be used.", + "replayWatchText": "Watch Replay", + "replayWriteErrorText": "Error writing replay file.", + "replaysText": "Replays", + "reportPlayerExplanationText": "Use this email to report cheating, inappropriate language, or other bad behavior.\nPlease describe below:", + "reportThisPlayerCheatingText": "Cheating", + "reportThisPlayerLanguageText": "Inappropriate Language", + "reportThisPlayerReasonText": "What would you like to report?", + "reportThisPlayerText": "Report This Player", + "requestingText": "Requesting...", + "restartText": "Restart", + "retryText": "Retry", + "revertText": "Revert", + "runText": "Run", + "saveText": "Save", + "scanScriptsErrorText": "Error(s) scanning scripts; see log for details.", + "scoreChallengesText": "Score Challenges", + "scoreListUnavailableText": "Score list unavailable.", + "scoreText": "Score", + "scoreUnits": { + "millisecondsText": "Milliseconds", + "pointsText": "Points", + "secondsText": "Seconds" + }, + "scoreWasText": "(was ${COUNT})", + "selectText": "Select", + "seriesWinLine1PlayerText": "WINS THE", + "seriesWinLine1TeamText": "WINS THE", + "seriesWinLine1Text": "WINS THE", + "seriesWinLine2Text": "SERIES!", + "settingsWindow": { + "accountText": "Account", + "advancedText": "Advanced", + "audioText": "Audio", + "controllersText": "Controllers", + "graphicsText": "Graphics", + "playerProfilesMovedText": "Note: Player Profiles have moved to the Account window in the main menu.", + "titleText": "Settings" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(a simple, controller-friendly on-screen keyboard for text editing)", + "alwaysUseInternalKeyboardText": "Always Use Internal Keyboard", + "benchmarksText": "Benchmarks & Stress-Tests", + "disableCameraGyroscopeMotionText": "Disable Camera Gyroscope Motion", + "disableCameraShakeText": "Disable Camera Shake", + "disableThisNotice": "(you can disable this notice in advanced settings)", + "enterPromoCodeText": "Enter Code", + "forTestingText": "Note: these values are only for testing and will be lost when the app exits.", + "helpTranslateText": "${APP_NAME}'s non-English translations are a community\nsupported effort. If you'd like to contribute or correct\na translation, follow the link below. Thanks in advance!", + "kickIdlePlayersText": "Kick Idle Players", + "kidFriendlyModeText": "Kid-Friendly Mode (reduced violence, etc)", + "languageText": "Language", + "moddingGuideText": "Modding Guide", + "mustRestartText": "You must restart the game for this to take effect.", + "netTestingText": "Network Testing", + "resetText": "Reset", + "showBombTrajectoriesText": "Show Bomb Trajectories", + "showInGamePingText": "Show In-Game Ping", + "showPlayerNamesText": "Show Player Names", + "showUserModsText": "Show Mods Folder", + "titleText": "Advanced", + "translationEditorButtonText": "${APP_NAME} Translation Editor", + "translationFetchErrorText": "translation status unavailable", + "translationFetchingStatusText": "checking translation status...", + "translationInformMe": "Inform me when my language needs updates", + "translationNoUpdateNeededText": "the current language is up to date; woohoo!", + "translationUpdateNeededText": "** the current language needs updates!! **", + "vrTestingText": "VR Testing" + }, + "shareText": "Share", + "sharingText": "Sharing...", + "showText": "Show", + "signInForPromoCodeText": "You must sign in to an account for codes to take effect.", + "signInWithGameCenterText": "To use a Game Center account,\nsign in with the Game Center app.", + "singleGamePlaylistNameText": "Just ${GAME}", + "singlePlayerCountText": "1 player", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Character Selection", + "Chosen One": "Chosen One", + "Epic": "Epic Mode Games", + "Epic Race": "Epic Race", + "FlagCatcher": "Capture the Flag", + "Flying": "Happy Thoughts", + "Football": "Football", + "ForwardMarch": "Assault", + "GrandRomp": "Conquest", + "Hockey": "Hockey", + "Keep Away": "Keep Away", + "Marching": "Runaround", + "Menu": "Main Menu", + "Onslaught": "Onslaught", + "Race": "Race", + "Scary": "King of the Hill", + "Scores": "Score Screen", + "Survival": "Elimination", + "ToTheDeath": "Death Match", + "Victory": "Final Score Screen" + }, + "spaceKeyText": "space", + "statsText": "Stats", + "storagePermissionAccessText": "This requires storage access", + "store": { + "alreadyOwnText": "You already own ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Removes in-game ads and nag-screens\n• Unlocks more game settings\n• Also includes:", + "buyText": "Buy", + "charactersText": "Characters", + "comingSoonText": "Coming Soon...", + "extrasText": "Extras", + "freeBombSquadProText": "BombSquad is now free, but since you originally purchased it you are\nreceiving the BombSquad Pro upgrade and ${COUNT} tickets as a thank-you.\nEnjoy the new features, and thank you for your support!\n-Eric", + "holidaySpecialText": "Holiday Special", + "howToSwitchCharactersText": "(go to \"${SETTINGS} -> ${PLAYER_PROFILES}\" to assign & customize characters)", + "howToUseIconsText": "(create global player profiles (in the account window) to use these)", + "howToUseMapsText": "(use these maps in your own teams/free-for-all playlists)", + "iconsText": "Icons", + "loadErrorText": "Unable to load page.\nCheck your internet connection.", + "loadingText": "loading", + "mapsText": "Maps", + "miniGamesText": "MiniGames", + "oneTimeOnlyText": "(one time only)", + "purchaseAlreadyInProgressText": "A purchase of this item is already in progress.", + "purchaseConfirmText": "Purchase ${ITEM}?", + "purchaseNotValidError": "Purchase not valid.\nContact ${EMAIL} if this is an error.", + "purchaseText": "Purchase", + "saleBundleText": "Bundle Sale!", + "saleExclaimText": "Sale!", + "salePercentText": "(${PERCENT}% off)", + "saleText": "SALE", + "searchText": "Search", + "teamsFreeForAllGamesText": "Teams / Free-for-All Games", + "totalWorthText": "*** ${TOTAL_WORTH} value! ***", + "upgradeQuestionText": "Upgrade?", + "winterSpecialText": "Winter Special", + "youOwnThisText": "- you own this -" + }, + "storeDescriptionText": "8 Player Party Game Madness!\n\nBlow up your friends (or the computer) in a tournament of explosive mini-games such as Capture-the-Flag, Bomber-Hockey, and Epic-Slow-Motion-Death-Match!\n\nSimple controls and extensive controller support make it easy for up to 8 people to get in on the action; you can even use your mobile devices as controllers via the free ‘BombSquad Remote’ app!\n\nBombs Away!\n\nCheck out www.froemling.net/bombsquad for more info.\n", + "storeDescriptions": { + "blowUpYourFriendsText": "Blow up your friends.", + "competeInMiniGamesText": "Compete in mini-games ranging from racing to flying.", + "customize2Text": "Customize characters, mini-games, and even the soundtrack.", + "customizeText": "Customize characters and create your own mini-game playlists.", + "sportsMoreFunText": "Sports are more fun with explosives.", + "teamUpAgainstComputerText": "Team up against the computer." + }, + "storeText": "Store", + "submitText": "Submit", + "submittingPromoCodeText": "Submitting Code...", + "teamNamesColorText": "Team Names/Colors...", + "telnetAccessGrantedText": "Telnet access enabled.", + "telnetAccessText": "Telnet access detected; allow?", + "testBuildErrorText": "This test build is no longer active; please check for a new version.", + "testBuildText": "Test Build", + "testBuildValidateErrorText": "Unable to validate test build. (no net connection?)", + "testBuildValidatedText": "Test Build Validated; Enjoy!", + "thankYouText": "Thank you for your support! Enjoy the game!!", + "threeKillText": "TRIPLE KILL!!", + "timeBonusText": "Time Bonus", + "timeElapsedText": "Time Elapsed", + "timeExpiredText": "Time Expired", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Tip", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Top Friends", + "tournamentCheckingStateText": "Checking tournament state; please wait...", + "tournamentEndedText": "This tournament has ended. A new one will start soon.", + "tournamentEntryText": "Tournament Entry", + "tournamentResultsRecentText": "Recent Tournament Results", + "tournamentStandingsText": "Tournament Standings", + "tournamentText": "Tournament", + "tournamentTimeExpiredText": "Tournament Time Expired", + "tournamentsDisabledWorkspaceText": "Tournaments are disabled when workspaces are active.\nTo re-enable tournaments, disable your workspace and restart.", + "tournamentsText": "Tournaments", + "translations": { + "characterNames": { + "Agent Johnson": null, + "B-9000": null, + "Bernard": null, + "Bones": null, + "Butch": null, + "Easter Bunny": null, + "Flopsy": null, + "Frosty": null, + "Gretel": null, + "Grumbledorf": null, + "Jack Morgan": null, + "Kronk": null, + "Lee": null, + "Lucky": null, + "Mel": null, + "Middle-Man": null, + "Minimus": null, + "Pascal": null, + "Pixel": null, + "Sammy Slam": null, + "Santa Claus": null, + "Snake Shadow": null, + "Spaz": null, + "Taobao Mascot": null, + "Todd McBurton": null, + "Zoe": null, + "Zola": null + }, + "coopLevelNames": { + "${GAME} Training": null, + "Infinite ${GAME}": null, + "Infinite Onslaught": null, + "Infinite Runaround": null, + "Onslaught Training": null, + "Pro ${GAME}": null, + "Pro Football": null, + "Pro Onslaught": null, + "Pro Runaround": null, + "Rookie ${GAME}": null, + "Rookie Football": null, + "Rookie Onslaught": null, + "The Last Stand": null, + "Uber ${GAME}": null, + "Uber Football": null, + "Uber Onslaught": null, + "Uber Runaround": null + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": null, + "Bomb as many targets as you can.": null, + "Carry the flag for ${ARG1} seconds.": null, + "Carry the flag for a set length of time.": null, + "Crush ${ARG1} of your enemies.": null, + "Defeat all enemies.": null, + "Dodge the falling bombs.": null, + "Final glorious epic slow motion battle to the death.": null, + "Gather eggs!": null, + "Get the flag to the enemy end zone.": null, + "How fast can you defeat the ninjas?": null, + "Kill a set number of enemies to win.": null, + "Last one standing wins.": null, + "Last remaining alive wins.": null, + "Last team standing wins.": null, + "Prevent enemies from reaching the exit.": null, + "Reach the enemy flag to score.": null, + "Return the enemy flag to score.": null, + "Run ${ARG1} laps.": null, + "Run ${ARG1} laps. Your entire team has to finish.": null, + "Run 1 lap.": null, + "Run 1 lap. Your entire team has to finish.": null, + "Run real fast!": null, + "Score ${ARG1} goals.": null, + "Score ${ARG1} touchdowns.": null, + "Score a goal.": null, + "Score a touchdown.": null, + "Score some goals.": null, + "Secure all ${ARG1} flags.": null, + "Secure all flags on the map to win.": null, + "Secure the flag for ${ARG1} seconds.": null, + "Secure the flag for a set length of time.": null, + "Steal the enemy flag ${ARG1} times.": null, + "Steal the enemy flag.": null, + "There can be only one.": null, + "Touch the enemy flag ${ARG1} times.": null, + "Touch the enemy flag.": null, + "carry the flag for ${ARG1} seconds": null, + "kill ${ARG1} enemies": null, + "last one standing wins": null, + "last team standing wins": null, + "return ${ARG1} flags": null, + "return 1 flag": null, + "run ${ARG1} laps": null, + "run 1 lap": null, + "score ${ARG1} goals": null, + "score ${ARG1} touchdowns": null, + "score a goal": null, + "score a touchdown": null, + "secure all ${ARG1} flags": null, + "secure the flag for ${ARG1} seconds": null, + "touch ${ARG1} flags": null, + "touch 1 flag": null + }, + "gameNames": { + "Assault": null, + "Capture the Flag": null, + "Chosen One": null, + "Conquest": null, + "Death Match": null, + "Easter Egg Hunt": null, + "Elimination": null, + "Football": null, + "Hockey": null, + "Keep Away": null, + "King of the Hill": null, + "Meteor Shower": null, + "Ninja Fight": null, + "Onslaught": null, + "Race": null, + "Runaround": null, + "Target Practice": null, + "The Last Stand": null + }, + "inputDeviceNames": { + "Keyboard": null, + "Keyboard P2": null + }, + "languages": { + "Arabic": null, + "Belarussian": null, + "Chinese": "Chinese Simplified", + "ChineseTraditional": "Chinese Traditional", + "Croatian": null, + "Czech": null, + "Danish": null, + "Dutch": null, + "English": null, + "Esperanto": null, + "Filipino": null, + "Finnish": null, + "French": null, + "German": null, + "Gibberish": null, + "Greek": null, + "Hindi": null, + "Hungarian": null, + "Indonesian": null, + "Italian": null, + "Japanese": null, + "Korean": null, + "Malay": null, + "Persian": null, + "Polish": null, + "Portuguese": null, + "Romanian": null, + "Russian": null, + "Serbian": null, + "Slovak": null, + "Spanish": null, + "Swedish": null, + "Tamil": null, + "Thai": null, + "Turkish": null, + "Ukrainian": null, + "Venetian": null, + "Vietnamese": null + }, + "leagueNames": { + "Bronze": null, + "Diamond": null, + "Gold": null, + "Silver": null + }, + "mapsNames": { + "Big G": null, + "Bridgit": null, + "Courtyard": null, + "Crag Castle": null, + "Doom Shroom": null, + "Football Stadium": null, + "Happy Thoughts": null, + "Hockey Stadium": null, + "Lake Frigid": null, + "Monkey Face": null, + "Rampage": null, + "Roundabout": null, + "Step Right Up": null, + "The Pad": null, + "Tip Top": null, + "Tower D": null, + "Zigzag": null + }, + "playlistNames": { + "Just Epic": null, + "Just Sports": null + }, + "scoreNames": { + "Flags": null, + "Goals": null, + "Score": null, + "Survived": null, + "Time": null, + "Time Held": null + }, + "serverResponses": { + "A code has already been used on this account.": null, + "A reward has already been given for that address.": null, + "Account linking successful!": null, + "Account unlinking successful!": null, + "Accounts are already linked.": null, + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": null, + "An error has occurred; (${ERROR})": null, + "An error has occurred; please contact support. (${ERROR})": null, + "An error has occurred; please contact support@froemling.net.": null, + "An error has occurred; please try again later.": null, + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": null, + "BombSquad Pro unlocked!": null, + "Can't link 2 accounts of this type.": null, + "Can't link 2 diamond league accounts.": null, + "Can't link; would surpass maximum of ${COUNT} linked accounts.": null, + "Cheating detected; scores and prizes suspended for ${COUNT} days.": null, + "Could not establish a secure connection.": null, + "Daily maximum reached.": null, + "Entering tournament...": null, + "Invalid code.": null, + "Invalid payment; purchase canceled.": null, + "Invalid promo code.": null, + "Invalid purchase.": null, + "Invalid tournament entry; score will be ignored.": null, + "Item unlocked!": null, + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": null, + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": null, + "Max number of playlists reached.": null, + "Max number of profiles reached.": null, + "Maximum friend code rewards reached.": null, + "Message is too long.": null, + "No servers are available. Please try again soon.": null, + "Profile \"${NAME}\" upgraded successfully.": null, + "Profile could not be upgraded.": null, + "Purchase successful!": null, + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": null, + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": null, + "Sorry, there are no uses remaining on this code.": null, + "Sorry, this code has already been used.": null, + "Sorry, this code has expired.": null, + "Sorry, this code only works for new accounts.": null, + "Still searching for nearby servers; please try again soon.": null, + "Temporarily unavailable; please try again later.": null, + "The tournament ended before you finished.": null, + "This account cannot be unlinked for ${NUM} days.": null, + "This code cannot be used on the account that created it.": null, + "This is currently unavailable; please try again later.": null, + "This requires version ${VERSION} or newer.": null, + "Tournaments disabled due to rooted device.": null, + "Tournaments require ${VERSION} or newer": null, + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": null, + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": null, + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": null, + "You already own this!": null, + "You can join in ${COUNT} seconds.": null, + "You don't have enough tickets for this!": null, + "You don't own that.": null, + "You got ${COUNT} tickets!": null, + "You got a ${ITEM}!": null, + "You have been promoted to a new league; congratulations!": null, + "You must update to a newer version of the app to do this.": null, + "You must update to the newest version of the game to do this.": null, + "You must wait a few seconds before entering a new code.": null, + "You ranked #${RANK} in the last tournament. Thanks for playing!": null, + "Your account was rejected. Are you signed in?": null, + "Your copy of the game has been modified.\nPlease revert any changes and try again.": null, + "Your friend code was used by ${ACCOUNT}": null + }, + "settingNames": { + "1 Minute": null, + "1 Second": null, + "10 Minutes": null, + "2 Minutes": null, + "2 Seconds": null, + "20 Minutes": null, + "4 Seconds": null, + "5 Minutes": null, + "8 Seconds": null, + "Allow Negative Scores": null, + "Balance Total Lives": null, + "Bomb Spawning": null, + "Chosen One Gets Gloves": null, + "Chosen One Gets Shield": null, + "Chosen One Time": null, + "Enable Impact Bombs": null, + "Enable Triple Bombs": null, + "Entire Team Must Finish": null, + "Epic Mode": null, + "Flag Idle Return Time": null, + "Flag Touch Return Time": null, + "Hold Time": null, + "Kills to Win Per Player": null, + "Laps": null, + "Lives Per Player": null, + "Long": null, + "Longer": null, + "Mine Spawning": null, + "No Mines": null, + "None": null, + "Normal": null, + "Pro Mode": null, + "Respawn Times": null, + "Score to Win": null, + "Short": null, + "Shorter": null, + "Solo Mode": null, + "Target Count": null, + "Time Limit": null + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": null, + "Killing ${NAME} for skipping part of the track!": null, + "Warning to ${NAME}: turbo / button-spamming knocks you out.": null + }, + "teamNames": { + "Bad Guys": null, + "Blue": null, + "Good Guys": null, + "Red": null + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": null, + "Always remember to floss.": null, + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": null, + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": null, + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": null, + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": null, + "Don't run all the time. Really. You will fall off cliffs.": null, + "Don't spin for too long; you'll become dizzy and fall.": null, + "Hold any button to run. (Trigger buttons work well if you have them)": null, + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": null, + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": null, + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": null, + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": null, + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": null, + "If you kill an enemy in one hit you get double points for it.": null, + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": null, + "If you stay in one place, you're toast. Run and dodge to survive..": null, + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": null, + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": null, + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": null, + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": null, + "In hockey, you'll maintain more speed if you turn gradually.": null, + "It's easier to win with a friend or two helping.": null, + "Jump just as you're throwing to get bombs up to the highest levels.": null, + "Land-mines are a good way to stop speedy enemies.": null, + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": null, + "No, you can't get up on the ledge. You have to throw bombs.": null, + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": null, + "Practice using your momentum to throw bombs more accurately.": null, + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": null, + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": null, + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": null, + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": null, + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": null, + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": null, + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": null, + "Try 'Cooking off' bombs for a second or two before throwing them.": null, + "Try tricking enemies into killing eachother or running off cliffs.": null, + "Use the pick-up button to grab the flag < ${PICKUP} >": null, + "Whip back and forth to get more distance on your throws..": null, + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": null, + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": null, + "You can throw bombs higher if you jump just before throwing.": null, + "You take damage when you whack your head on things,\nso try to not whack your head on things.": null, + "Your punches do much more damage if you are running or spinning.": null + } + }, + "trophiesRequiredText": "This requires at least ${NUMBER} trophies.", + "trophiesText": "Trophies", + "trophiesThisSeasonText": "Trophies This Season", + "tutorial": { + "cpuBenchmarkText": "Running tutorial at ludicrous-speed (primarily tests CPU speed)", + "phrase01Text": "Hi there!", + "phrase02Text": "Welcome to ${APP_NAME}!", + "phrase03Text": "Here's a few tips for controlling your character:", + "phrase04Text": "Many things in ${APP_NAME} are PHYSICS based.", + "phrase05Text": "For example, when you punch,..", + "phrase06Text": "..damage is based on the speed of your fists.", + "phrase07Text": "See? We weren't moving, so that barely hurt ${NAME}.", + "phrase08Text": "Now let's jump and spin to get more speed.", + "phrase09Text": "Ah, that's better.", + "phrase10Text": "Running helps too.", + "phrase11Text": "Hold down ANY button to run.", + "phrase12Text": "For extra-awesome punches, try running AND spinning.", + "phrase13Text": "Whoops; sorry 'bout that ${NAME}.", + "phrase14Text": "You can pick up and throw things such as flags.. or ${NAME}.", + "phrase15Text": "Lastly, there's bombs.", + "phrase16Text": "Throwing bombs takes practice.", + "phrase17Text": "Ouch! Not a very good throw.", + "phrase18Text": "Moving helps you throw farther.", + "phrase19Text": "Jumping helps you throw higher.", + "phrase20Text": "\"Whiplash\" your bombs for even longer throws.", + "phrase21Text": "Timing your bombs can be tricky.", + "phrase22Text": "Dang.", + "phrase23Text": "Try \"cooking off\" the fuse for a second or two.", + "phrase24Text": "Hooray! Nicely cooked.", + "phrase25Text": "Well, that's just about it.", + "phrase26Text": "Now go get 'em, tiger!", + "phrase27Text": "Remember your training, and you WILL come back alive!", + "phrase28Text": "...well, maybe...", + "phrase29Text": "Good luck!", + "randomName1Text": "Fred", + "randomName2Text": "Harry", + "randomName3Text": "Bill", + "randomName4Text": "Chuck", + "randomName5Text": "Phil", + "skipConfirmText": "Really skip the tutorial? Tap or press to confirm.", + "skipVoteCountText": "${COUNT}/${TOTAL} skip votes", + "skippingText": "skipping tutorial...", + "toSkipPressAnythingText": "(tap or press anything to skip tutorial)" + }, + "twoKillText": "DOUBLE KILL!", + "unavailableText": "unavailable", + "unconfiguredControllerDetectedText": "Unconfigured controller detected:", + "unlockThisInTheStoreText": "This must be unlocked in the store.", + "unlockThisProfilesText": "To create more than ${NUM} profiles, you need:", + "unlockThisText": "To unlock this, you need:", + "unsupportedHardwareText": "Sorry, this hardware is not supported by this build of the game.", + "upFirstText": "Up first:", + "upNextText": "Up next in game ${COUNT}:", + "updatingAccountText": "Updating your account...", + "upgradeText": "Upgrade", + "upgradeToPlayText": "Unlock \"${PRO}\" in the in-game store to play this.", + "useDefaultText": "Use Default", + "usesExternalControllerText": "This game uses an external controller for input.", + "usingItunesText": "Using Music App for soundtrack...", + "v2AccountLinkingInfoText": "To link V2 accounts, use the 'Manage Account' button.", + "validatingTestBuildText": "Validating Test Build...", + "victoryText": "Victory!", + "voteDelayText": "You can't start another vote for ${NUMBER} seconds", + "voteInProgressText": "A vote is already in progress.", + "votedAlreadyText": "You already voted", + "votesNeededText": "${NUMBER} votes needed", + "vsText": "vs.", + "waitingForHostText": "(waiting for ${HOST} to continue)", + "waitingForPlayersText": "waiting for players to join...", + "waitingInLineText": "Waiting in line (party is full)...", + "watchAVideoText": "Watch a Video", + "watchAnAdText": "Watch an Ad", + "watchWindow": { + "deleteConfirmText": "Delete \"${REPLAY}\"?", + "deleteReplayButtonText": "Delete\nReplay", + "myReplaysText": "My Replays", + "noReplaySelectedErrorText": "No Replay Selected", + "playbackSpeedText": "Playback Speed: ${SPEED}", + "renameReplayButtonText": "Rename\nReplay", + "renameReplayText": "Rename \"${REPLAY}\" to:", + "renameText": "Rename", + "replayDeleteErrorText": "Error deleting replay.", + "replayNameText": "Replay Name", + "replayRenameErrorAlreadyExistsText": "A replay with that name already exists.", + "replayRenameErrorInvalidName": "Can't rename replay; invalid name.", + "replayRenameErrorText": "Error renaming replay.", + "sharedReplaysText": "Shared Replays", + "titleText": "Watch", + "watchReplayButtonText": "Watch\nReplay" + }, + "waveText": "Wave", + "wellSureText": "Well Sure!", + "whatIsThisText": "What is this?", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Listening For Wiimotes...", + "pressText": "Press Wiimote buttons 1 and 2 simultaneously.\n", + "pressText2": "On newer Wiimotes with Motion Plus built in, press the red 'sync' button on the back instead." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "listenText": "Listen", + "macInstructionsText": "Make sure your Wii is off and Bluetooth is enabled\non your Mac, then press 'Listen'. Wiimote support can\nbe a bit flaky, so you may have to try a few times\nbefore you get a connection.\n\nBluetooth should handle up to 7 connected devices,\nthough your mileage may vary.\n\nBombSquad supports the original Wiimotes, Nunchuks,\nand the Classic Controller.\nThe newer Wii Remote Plus now works too\nbut not with attachments.", + "thanksText": "Thanks to the DarwiinRemote team\nFor making this possible.\n", + "titleText": "Wiimote Setup" + }, + "winsPlayerText": "${NAME} Wins!", + "winsTeamText": "${NAME} Wins!", + "winsText": "${NAME} Wins!", + "workspaceSyncErrorText": "Error syncing ${WORKSPACE}. See log for details.", + "workspaceSyncReuseText": "Can't sync ${WORKSPACE}. Reusing previous synced version.", + "worldScoresUnavailableText": "World scores unavailable.", + "worldsBestScoresText": "World's Best Scores", + "worldsBestTimesText": "World's Best Times", + "xbox360ControllersWindow": { + "getDriverText": "Get Driver", + "macInstructions2Text": "To use controllers wirelessly, you'll also need the receiver that\ncomes with the 'Xbox 360 Wireless Controller for Windows'.\nOne receiver allows you to connect up to 4 controllers.\n\nImportant: 3rd-party receivers will not work with this driver;\nmake sure your receiver says 'Microsoft' on it, not 'XBOX 360'.\nMicrosoft no longer sells these separately, so you'll need to get\nthe one bundled with the controller or else search ebay.\n\nIf you find this useful, please consider a donation to the\ndriver developer at his site.", + "macInstructionsText": "To use Xbox 360 controllers, you'll need to install\nthe Mac driver available at the link below.\nIt works with both wired and wireless controllers.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "To use wired Xbox 360 controllers with BombSquad, simply\nplug them into your device's USB port. You can use a USB hub\nto connect multiple controllers.\n\nTo use wireless controllers you'll need a wireless receiver,\navailable as part of the \"Xbox 360 wireless Controller for Windows\"\npackage or sold separately. Each receiver plugs into a USB port and\nallows you to connect up to 4 wireless controllers.", + "titleText": "Using Xbox 360 Controllers with ${APP_NAME}:" + }, + "yesAllowText": "Yes, Allow!", + "yourBestScoresText": "Your Best Scores", + "yourBestTimesText": "Your Best Times" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/esperanto.json b/dist/ba_data/data/languages/esperanto.json new file mode 100644 index 0000000..c2663da --- /dev/null +++ b/dist/ba_data/data/languages/esperanto.json @@ -0,0 +1,1610 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Kontoj nomoj ne povas enhavi emoji aŭ aliajn specialajn signojn", + "accountProfileText": "(konta profilo)", + "accountsText": "Kontoj", + "achievementProgressText": "Atingoj: ${COUNT} el ${TOTAL}", + "campaignProgressText": "Kampanja progreso [malfacila]: ${PROGRESS}", + "changeOncePerSeason": "Vi povas ŝanĝi ĉi tion nur unufoje por sezono.", + "changeOncePerSeasonError": "Vi devas atendi ĝis la venonta sezono por ŝanĝi ĉi tion denove (${NUM} tagoj)", + "customName": "Adaptita nomo", + "linkAccountsEnterCodeText": "Enigi kodon", + "linkAccountsGenerateCodeText": "Generu Kodon", + "linkAccountsInfoText": "(dividu progreson tra malsamaj platformoj)", + "linkAccountsInstructionsNewText": "Por ligi du kontojn, generu kodon sur la unua\nkaj enigu tiun kodon sur la dua. Datumoj de la\ndua konto tiam estos dividita inter ambaŭ.\n(Datumoj de la unua konto estos perditaj)\n\nVi povas ligi ĝis ${COUNT} kontoj.\n\nGRAVA: nur ligu kontojn kiujn vi posedas;\nSe vi ligas kun la kontoj de amikoj, vi ne faros\npovi ludi interrete samtempe.", + "linkAccountsText": "Ligi kontojn", + "linkedAccountsText": "Ligitaj kontoj:", + "manageAccountText": "Administri Konton", + "nameChangeConfirm": "Ĉu redakti vian kontan nomon al ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Ĉi tio reigos vian kunlaboran progreson\nkaj lokajn plej altajn poentojn (sed ne\nviajn biletojn). Ne eblas malfari.\nĈu vi certas?", + "resetProgressConfirmText": "Ĉi tio reigos vian kunlaboran\nprogreson, atingojn kaj lokajn\nplej altajn poentojn (sed ne\nviajn biletojn). Ne eblas malfari.\nĈu vi certas?", + "resetProgressText": "Reigi progreson", + "setAccountName": "Difini Konton Nomon", + "setAccountNameDesc": "Elektu la nomon por montri por via konto.\nVi povas uzi la nomon de unu el viaj ligitaj\nkontoj aŭ krei unikan kutiman nomon.", + "signInInfoText": "Ensalutu por konservi vian progreson\nen la nubon, gajni biletojn kaj\npartopreni en turniroj.", + "signInText": "Ensaluti", + "signInWithDeviceText": "Ensaluti per aparatkonto", + "signInWithGameCircleText": "Ensaluti per Game Circle", + "signInWithGooglePlayText": "Ensaluti per Google Play", + "signOutText": "Elsaluti", + "signingInText": "Ensalutas...", + "signingOutText": "Elsalutas...", + "testAccountWarningCardboardText": "Atentu: vi ensalutis per testa konto.\nĜin anstataŭos Google-konto kiam ili haveblos\npor cardboard-aplikaĵoj.\n\nPor nun vi devos akiri ĉiujn biletojn enlude.\n(tamen, vi ricevas la ĝisdatigon BombSquad Pro senpage)", + "testAccountWarningOculusText": "Atentu: vi ensalutiĝis per test-konto.\nPli poste ĉi-jare tion anstataŭos Oculus-kontoj,\ndonante aĉetadon de biletoj kaj aliaj ebloj.\n\nPor nun vi devos gajni biletojn enlude.\n(tamen, vi havos la ĝisdatigon Bombsquad Pro senpage)", + "testAccountWarningText": "Atentu: vi estas ensalutita per test-konto.\nĈi tiu konto estas specifa por ĉi tiu aparato kaj\npovas esti fojfoje reigata. (do ne dum multa tempo\nkolektu kaj malŝlosu aferojn per ĝi)\n\nUzu vendo-version de la ludo por uzi \"veran\" konton\n(Game-Center, Google Plus ktp). Tio ankaŭ permesas\nal vi konservi progreson en la nubon kaj kunhavigi\ntion inter diversaj aparatoj.", + "ticketsText": "Biletoj: ${COUNT}", + "titleText": "Konto", + "unlinkAccountsText": "Malligi kontojn", + "viaAccount": "(per konto ${NAME})", + "youAreLoggedInAsText": "Vi ensalutis kiel:", + "youAreSignedInAsText": "Vi ensalutiĝis kiel:" + }, + "achievementChallengesText": "Atingaj defioj", + "achievementText": "Atingo", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Mortigu 3 fiulojn per dinamito", + "descriptionComplete": "Mortigis 3 fiulojn per dinamito", + "descriptionFull": "Mortigu 3 fiulojn per dinamito en ${LEVEL}", + "descriptionFullComplete": "Mortigis 3 fiulojn per dinamito en ${LEVEL}", + "name": "Bum-as la dinamito" + }, + "Boxer": { + "description": "Venku sen uzi bombojn", + "descriptionComplete": "Venkis sen uzi bombojn", + "descriptionFull": "Kompletigu ${LEVEL} sen uzi bombojn", + "descriptionFullComplete": "Kompletigis ${LEVEL} sen uzi bombojn", + "name": "Batadanto" + }, + "Flawless Victory": { + "description": "Venku sen esti batata", + "descriptionComplete": "Venkis sen esti batata", + "descriptionFull": "Venku ${LEVEL} sen esti batata", + "descriptionFullComplete": "Venkis ${LEVEL} sen esti batata", + "name": "Perfekta venko" + }, + "Gold Miner": { + "description": "Mortigu 6 fiulojn per minoj", + "descriptionComplete": "Mortigis 6 fiulojn per minoj", + "descriptionFull": "Mortigu 6 fiulojn per minoj en ${LEVEL}", + "descriptionFullComplete": "Mortigis 6 fiulojn per minoj en ${LEVEL}", + "name": "Orministo" + }, + "Got the Moves": { + "description": "Venku sen uzi batojn aŭ bombojn", + "descriptionComplete": "Venkis sen uzi batojn aŭ bombojn", + "descriptionFull": "Venku ${LEVEL} sen uzi batojn aŭ bombojn", + "descriptionFullComplete": "Venkis ${LEVEL} sen uzi batojn aŭ bombojn", + "name": "Movadano" + }, + "Last Stand God": { + "description": "Poentu 1000 poentojn", + "descriptionComplete": "Poentis 1000 poentojn", + "descriptionFull": "Poentu 1000 poentojn en ${LEVEL}", + "descriptionFullComplete": "Poentis 1000 poentojn en ${LEVEL}", + "name": "Dio de ${LEVEL}" + }, + "Last Stand Master": { + "description": "Poentu 250 poentojn", + "descriptionComplete": "Poentis 250 poentojn", + "descriptionFull": "Poentu 250 poentojn en ${LEVEL}", + "descriptionFullComplete": "Poentis 250 poentojn en ${LEVEL}", + "name": "Majstro de ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Poentu 500 poentojn", + "descriptionComplete": "Poentis 500 poentojn", + "descriptionFull": "Poentu 500 poentojn en ${LEVEL}", + "descriptionFullComplete": "Poentis 500 poentojn en ${LEVEL}", + "name": "Sorĉisto de ${LEVEL}" + }, + "Mine Games": { + "description": "Mortigu 3 fiulojn per minoj", + "descriptionComplete": "Mortigis 3 fiulojn per minoj", + "descriptionFull": "Mortigu 3 fiulojn per minoj en ${LEVEL}", + "descriptionFullComplete": "Mortigis 3 fiulojn per minoj en ${LEVEL}", + "name": "Minoludoj" + }, + "Off You Go Then": { + "description": "Ĵetu 3 fiulojn ekster la mapon", + "descriptionComplete": "Ĵetis 3 fiulojn ekster la mapon", + "descriptionFull": "Ĵetu 3 fiulojn ekster la mapon en ${LEVEL}", + "descriptionFullComplete": "Ĵetis 3 fiulojn ekster la mapon en ${LEVEL}", + "name": "Do jen vi iras" + }, + "Onslaught God": { + "description": "Poentu 5000 poentojn", + "descriptionComplete": "Poentis 5000 poentojn", + "descriptionFull": "Poentu 5000 poentojn en ${LEVEL}", + "descriptionFullComplete": "Poentis 5000 poentojn en ${LEVEL}", + "name": "Dio de ${LEVEL}" + }, + "Onslaught Master": { + "description": "Poentu 500 poentojn", + "descriptionComplete": "Poentis 500 poentojn", + "descriptionFull": "Poentu 500 poentojn en ${LEVEL}", + "descriptionFullComplete": "Poentis 500 poentojn en ${LEVEL}", + "name": "Majstro de ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Superu ĉiujn ondojn", + "descriptionComplete": "Superis ĉiujn ondojn", + "descriptionFull": "Superu ĉiujn ondojn en ${LEVEL}", + "descriptionFullComplete": "Superis ĉiujn ondojn en ${LEVEL}", + "name": "Venko de ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Poentu 1000 poentojn", + "descriptionComplete": "Poentis 1000 poentojn", + "descriptionFull": "Poentu 1000 poentojn en ${LEVEL}", + "descriptionFullComplete": "Poentis 1000 poentojn en ${LEVEL}", + "name": "Sorĉisto de ${LEVEL}" + }, + "Precision Bombing": { + "description": "Venku sen donacetojn", + "descriptionComplete": "Venkis sen donacetoj", + "descriptionFull": "Venku ${LEVEL} sen donacetoj", + "descriptionFullComplete": "Venkis ${LEVEL} sen donacetoj", + "name": "Precizbombado" + }, + "Pro Boxer": { + "description": "Venku sen uzi bombojn", + "descriptionComplete": "Venkis sen uzi bombojn", + "descriptionFull": "Kompletigu ${LEVEL} sen uzi bombojn", + "descriptionFullComplete": "Kompletigis ${LEVEL} sen uzi bombojn", + "name": "Profesia batadanto" + }, + "Pro Football Shutout": { + "description": "Venku sen ke la fiuloj poentu", + "descriptionComplete": "Venkis sen poentoj por la fiuloj", + "descriptionFull": "Venku ${Level} sen ke la fiuloj poentu", + "descriptionFullComplete": "Venkis ${LEVEL} sen poentoj por la fiuloj", + "name": "Eltenanto de ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Venku la ludon", + "descriptionComplete": "Venkis la ludon", + "descriptionFull": "Venku la ludon en ${LEVEL}", + "descriptionFullComplete": "Venkis la ludon en ${LEVEL}", + "name": "Venko de ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Superu ĉiujn ondojn", + "descriptionComplete": "Superis ĉiujn ondojn", + "descriptionFull": "Superu ĉiujn ondojn de ${LEVEL}", + "descriptionFullComplete": "Superis ĉiujn ondojn de ${LEVEL}", + "name": "Venko de ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Kompletigu ĉiujn ondojn", + "descriptionComplete": "Kompletigis ĉiujn ondojn", + "descriptionFull": "Kompletigu ĉiujn ondojn en ${LEVEL}", + "descriptionFullComplete": "Kompletigis ĉiujn ondojn en ${LEVEL}", + "name": "Venko de ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Venku sen ke la fiuloj poentu", + "descriptionComplete": "Venkis sen poentoj por la fiuloj", + "descriptionFull": "Venku ${LEVEL} sen ke la fiuloj poentu", + "descriptionFullComplete": "Venkis ${LEVEL} sen poentoj por la fiuloj", + "name": "Eltenanto de ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Venku la ludon", + "descriptionComplete": "Venkis la ludon", + "descriptionFull": "Venku la ludon en ${LEVEL}", + "descriptionFullComplete": "Venkis la ludon en ${LEVEL}", + "name": "Venko de ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Superu ĉiujn ondojn", + "descriptionComplete": "Superis ĉiujn ondojn", + "descriptionFull": "Superu ĉiujn ondojn en ${LEVEL}", + "descriptionFullComplete": "Superis ĉiujn ondojn en ${LEVEL}", + "name": "Venko de ${LEVEL}" + }, + "Runaround God": { + "description": "Poenti 2000 poentojn", + "descriptionComplete": "Poentis 2000 poentojn", + "descriptionFull": "Poentu 2000 poentojn en ${LEVEL}", + "descriptionFullComplete": "Poentis 2000 poentojn en ${LEVEL}", + "name": "Dio de ${LEVEL}" + }, + "Runaround Master": { + "description": "Poentu 500 poentojn", + "descriptionComplete": "Poentis 500 poentojn", + "descriptionFull": "Poentu 500 poentojn en ${LEVEL}", + "descriptionFullComplete": "Poentis 500 poentojn en ${LEVEL}", + "name": "Majstro de ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Poentu 1000 poentojn", + "descriptionComplete": "Poentis 1000 poentojn", + "descriptionFull": "Poentu 1000 poentojn en ${LEVEL}", + "descriptionFullComplete": "Poentis 1000 poentojn en ${LEVEL}", + "name": "Sorĉisto de ${LEVEL}" + }, + "Stayin' Alive": { + "description": "Venku sen morti", + "descriptionComplete": "Venkis sen morti", + "descriptionFull": "Venku ${LEVEL} sen morti", + "descriptionFullComplete": "Venkis ${LEVEL} sen morti", + "name": "Resti viva" + }, + "Super Mega Punch": { + "description": "Efiku 100% da damaĝo per unu bato", + "descriptionComplete": "Efikis 100% da damaĝo per unu bato", + "descriptionFull": "Efiku 100% da damaĝo per unu bato en ${LEVEL}", + "descriptionFullComplete": "Efikis 100% da damaĝo per unu bato en ${LEVEL}", + "name": "Superbatego" + }, + "Super Punch": { + "description": "Efiku 50% da damaĝo per unu bato", + "descriptionComplete": "Efikis 50% da damaĝo per unu bato", + "descriptionFull": "Efiku 50% da damaĝo per unu bato en ${LEVEL}", + "descriptionFullComplete": "Efikis 50% da damaĝo per unu bato en ${LEVEL}", + "name": "Superbato" + }, + "TNT Terror": { + "description": "Mortigu 6 fiulojn per dinamito", + "descriptionComplete": "Mortigis 6 fiulojn per dinamito", + "descriptionFull": "Mortigu 6 fiulojn per dinamito en ${LEVEL}", + "descriptionFullComplete": "Mortigis 6 fiulojn per dinamito en ${LEVEL}", + "name": "Dinamitoteroro" + }, + "The Great Wall": { + "description": "Haltigu ĉiun fiulon", + "descriptionComplete": "Haltigis ĉiun fiulon", + "descriptionFull": "Haltigu ĉiun fiulon en ${LEVEL}", + "descriptionFullComplete": "Haltigis ĉiun fiulon en ${LEVEL}", + "name": "La granda muro" + }, + "The Wall": { + "description": "Haltigu ĉiun fiulon", + "descriptionComplete": "Haltigis ĉiun fiulon", + "descriptionFull": "Haltigu ĉiun fiulon en ${LEVEL}", + "descriptionFullComplete": "Haltigis ĉiun fiulon en ${LEVEL}", + "name": "La muro" + }, + "Uber Football Shutout": { + "description": "Venku sen ke la fiuloj poentu", + "descriptionComplete": "Venkis sen poentoj por la fiuloj", + "descriptionFull": "Venku ${LEVEL} sen ke la fiuloj poentu", + "descriptionFullComplete": "Venkis ${LEVEL} sen poentoj por la fiuloj", + "name": "Eltenanto de ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Venku la ludon", + "descriptionComplete": "Venkis la ludon", + "descriptionFull": "Venku la ludon en ${LEVEL}", + "descriptionFullComplete": "Venkis la ludon en ${LEVEL}", + "name": "Venko de ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Superu ĉiujn ondojn", + "descriptionComplete": "Superis ĉiujn ondojn", + "descriptionFull": "Superu ĉiujn ondojn en ${LEVEL}", + "descriptionFullComplete": "Superis ĉiujn ondojn en ${LEVEL}", + "name": "Venko de ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Kompletigu ĉiujn ondojn", + "descriptionComplete": "Kompletigis ĉiujn ondojn", + "descriptionFull": "Kompletigu ĉiujn ondojn en ${LEVEL}", + "descriptionFullComplete": "Kompletigis ĉiujn ondojn en ${LEVEL}", + "name": "Venko de ${LEVEL}" + } + }, + "achievementsRemainingText": "Restantaj atingoj:", + "achievementsText": "Atingoj", + "achievementsUnavailableForOldSeasonsText": "Pardonu, atingaj specifaĵoj ne haveblas por malnovaj sezonoj.", + "addGameWindow": { + "getMoreGamesText": "Pli da ludoj...", + "titleText": "Aldoni ludon" + }, + "allowText": "Permesi", + "apiVersionErrorText": "Ne eblas ŝargi modulon ${NAME}; ĝi celas api-version ${VERSION_USED}; ni bezonas ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Aŭtomate\" nur ebligas tion kiam kapaŭskultiloj enestas)", + "headRelativeVRAudioText": "Kap-rilata VR-aŭdsistemo", + "musicVolumeText": "Laŭteco de muziko", + "soundVolumeText": "Sonlaŭteco", + "soundtrackButtonText": "Sontrakoj", + "soundtrackDescriptionText": "(elektu vian propran muzikon por ludi dum ludoj)", + "titleText": "Aŭdaĵoj" + }, + "autoText": "Aŭtomate", + "backText": "Reen", + "bestOfFinalText": "Plejbona-el-${COUNT}-finalo", + "bestOfSeriesText": "Plejbona el ${COUNT} serio:", + "bestRankText": "Via plejbono estas #${RANK}", + "bestRatingText": "Via plej bona ranko estas ${RATING}", + "betaErrorText": "Ĉi tiu beta ne plu estas aktiva; bonvolu kontroli por pli nova versio.", + "betaValidateErrorText": "Ne eblas validigi betan. (ĉu sen retkonekto?)", + "betaValidatedText": "Beta validiĝis; Ĝuu!", + "bombBoldText": "BOMBO", + "bombText": "Bombo", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} estas konfigurita en la aplikaĵo mem.", + "buttonText": "butono", + "canWeDebugText": "Ĉu vi ŝatus ke BombSquad aŭtomate raportu cimojn,\nkraŝojn kaj bazajn uzadajn informojn al la programisto?\n\nĈi tiuj datumoj ne enhavas personajn informojn kaj helpas\npor manteni la ludon flua kaj sencima.", + "cancelText": "Nuligi", + "cantConfigureDeviceText": "Bedaŭrinde ${DEVICE} ne konfigureblas.", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Vi devas kompletigi ĉi\ntiun nivelon por pluiri!", + "completionBonusText": "Kompletiga premio", + "configControllersWindow": { + "configureControllersText": "Konfiguri regilojn", + "configureGamepadsText": "Agordi ludregtabulojn", + "configureKeyboard2Text": "Konfiguri klavaron Lud2", + "configureKeyboardText": "Konfiguri klavaron", + "configureMobileText": "Poŝaparatoj kiel regiloj", + "configureTouchText": "Konfiguri tuŝekranon", + "ps3Text": "PS3-regiloj", + "titleText": "Ludregiloj", + "wiimotesText": "Wii-regiloj", + "xbox360Text": "Regiloj de Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Notu: regila subteno varias laŭ aparato kaj versio de Android.", + "pressAnyButtonText": "Premu ajnan butonon sur la regilo\n kiun vi volas konfigurigi...", + "titleText": "Konfiguri regilojn" + }, + "configGamepadWindow": { + "advancedText": "Por spertuloj", + "advancedTitleText": "Pli specifaj regilaj agordoj", + "analogStickDeadZoneDescriptionText": "(altigu ĉi tion se via rolulo 'ŝoviĝas' post stirado per la bastoneto)", + "analogStickDeadZoneText": "Analogbastoneta morta regiono", + "appliesToAllText": "(aplikiĝas al ĉiuj regiloj de ĉi tiu tipo)", + "autoRecalibrateDescriptionText": "(ebligu ĉi tion se via rolulo ne moviĝas je plena rapideco)", + "autoRecalibrateText": "Aŭtomate rekalibrigi analogan bastoneton", + "axisText": "akso", + "clearText": "viŝi", + "dpadText": "stirkruceto", + "extraStartButtonText": "Aldona start-butono", + "ifNothingHappensTryAnalogText": "Se nenio okazas, provu anstataŭe konfiguri per la analoga bastoneto.", + "ifNothingHappensTryDpadText": "Se nenio okazas, provu anstataŭe konfiguri per la stirkruceto.", + "ignoredButton1Text": "Ignorata butono 1", + "ignoredButton2Text": "Ignorata butono 2", + "ignoredButton3Text": "Ignorata butono 3", + "ignoredButtonDescriptionText": "(uzu ĉi tion por eviti ke butonoj 'home' aŭ 'sync' efiku al la interfaco)", + "ignoredButtonText": "Ignorata butono", + "pressAnyAnalogTriggerText": "Premu ajnan analogan klavaĵon...", + "pressAnyButtonOrDpadText": "Premu ajnan butonon aŭ stirkruceton...", + "pressAnyButtonText": "Premu ajnan butonon...", + "pressLeftRightText": "Premu dekstren aŭ maldekstren...", + "pressUpDownText": "Premu supren aŭ malsupren...", + "runButton1Text": "Kurbutono 1", + "runButton2Text": "Kurbutono 2", + "runTrigger1Text": "Kurklavaĵo 1", + "runTrigger2Text": "Kurklavaĵo 2", + "runTriggerDescriptionText": "(analogaj klavaĵoj ebligas al vi kuri laŭ diversaj rapidecoj)", + "secondHalfText": "Uzu ĉi tion por konfiguri duan duonon\nde 2-reguloj-en-1-aparato kiu montriĝas\nkiel ununura regilo.", + "secondaryEnableText": "Ebligi", + "secondaryText": "Aldona regilo", + "startButtonActivatesDefaultDescriptionText": "(malŝaltu ĉi tion se via startbutono estas fakte menubutono)", + "startButtonActivatesDefaultText": "Startbutono aktivigas defaŭltan umaĵon", + "titleText": "Regilaj agordoj", + "twoInOneSetupText": "Agordoj por regilo 2-en-1", + "unassignedButtonsRunText": "Ĉiuj nekonfiguritaj butonoj kurigas", + "unsetText": "" + }, + "configKeyboardWindow": { + "configuringText": "Konfiguriĝas ${DEVICE}", + "keyboard2NoteText": "Notu: plej multaj klavaroj nur registras kelkajn klavojn\nsamtempe, do eblas ke plej bone funkcias dua klavara\nludanto en disa klavaro. Tamen eĉ tiel vi devos konfiguri\nunikajn klavojn por ambaŭ ludantoj." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Grandeco de ago-regumo", + "actionsText": "Agoj", + "buttonsText": "butonoj", + "dragControlsText": "< ŝovu regumojn por repoziciigi ilin >", + "joystickText": "bastoneto", + "movementControlScaleText": "Grandeco de movo-regumo", + "movementText": "Movado", + "resetText": "Reigi", + "swipeControlsHiddenText": "Ne montri glittuŝajn bildetojn", + "swipeInfoText": "Glittuŝaj regumoj bezonas iom da kutimiĝo, sed pli\nfaciligas ludadon sen rigardi la regumojn.", + "swipeText": "glittuŝi", + "titleText": "Konfiguri tuŝekranon", + "touchControlsScaleText": "Grandeco de tuŝregumoj" + }, + "configureItNowText": "Ĉu konfiguri nun?", + "configureText": "Agordi", + "connectMobileDevicesWindow": { + "amazonText": "Aplikaĵvendejo de Amazon", + "appStoreText": "Aplikaĵvendejo", + "bestResultsText": "Por plej bonaj rezultoj vi bezonas senhezitan reton. Vi povas\nmalpliigi heziton de sendrata reto malŝaltante aliajn sendratajn\naparatojn, ludante proksime de la disvojilo kaj ligante la ludan\ngastiganton rekte al la reto per drato.", + "explanationText": "Por uzi poŝtelefonon aŭ tabletkomputilon kiel sendratan\nregilon, instalu la aplikaĵon \"BombSquad Remote\" en ĝi.\nKiom ajn da aparatoj povas konektiĝi sendratrete, kaj senpage!", + "forAndroidText": "por Android:", + "forIOSText": "por iOS:", + "getItForText": "Akiru ${REMOTE_APP_NAME} por iOS ĉe la Apple App Store\naŭ por Android ĉe la Google Play Store aŭ Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Uzi poŝaparatojn kiel regilojn:" + }, + "continuePurchaseText": "Ĉu pluiri por ${PRICE}?", + "continueText": "Pluiri", + "controlsText": "Kontrolklavoj", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Tio ne aplikeblas al rankoj pri ĉiam.", + "activenessInfoText": "Ĉi tiu multobligo supreniras en tagoj\nkiam vi ludas, kaj malsupreniras se ne.", + "activityText": "Aktiveco", + "campaignText": "Kampanjo", + "challengesText": "Defioj", + "currentBestText": "Nuna plejbono", + "customText": "Adaptite", + "entryFeeText": "Enirpago", + "multipliersText": "Multobligiloj", + "ofTotalTimeText": "el ${TOTAL}", + "playNowText": "Ludi nun", + "pointsText": "Poentoj", + "powerRankingNotInTopText": "(ne en la supraj ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} poentoj", + "powerRankingPointsMultText": "(x ${NUMBER} poentoj)", + "powerRankingPointsText": "${NUMBER} ptj", + "powerRankingPointsToRankedText": "(${CURRENT} el ${REMAINING} poentoj)", + "powerRankingText": "Ranka supervido", + "prizesText": "Premioj", + "proMultInfoText": "Ludantoj kun la ĝisdatigo ${PRO}\nricevas ${PERCENT}% poentan supreniĝon ĉi tie.", + "seeMoreText": "Pli...", + "timeRemainingText": "Restanta tempo", + "titleText": "Kunlabore", + "toRankedText": "Ĝis rankumita", + "totalText": "entute", + "welcome1Text": "Bonvenon al ${LEAGUE}. Vi povas plibonigi vian\nligan rankon gajnante stelajn rankojn, kompletante\natingojn, kaj gajnante trofeojn en turniroj.", + "welcome2Text": "Vi ankaŭ povas gajni biletojn per multaj de la samaj aktivaĵoj.\nBiletoj povas esti uzataj por malŝlosi novajn rolulojn, mapojn\nkaj ludetojn, por eniri turnirojn ktp.", + "yourPowerRankingText": "Via ranka pozicio:" + }, + "copyOfText": "Kopio de ${NAME}", + "createAPlayerProfileText": "Ĉu krei ludantprofilon?", + "createEditPlayerText": "", + "createText": "Krei", + "creditsWindow": { + "additionalAudioArtIdeasText": "Aldonaj aŭdaĵoj, unuaj artaĵoj kaj ideoj fare de ${NAME}", + "additionalMusicFromText": "Aldona muziko de ${NAME}", + "allMyFamilyText": "Ĉiuj miaj amikoj kaj familio kiuj helpis ludtesti", + "codingGraphicsAudioText": "Kodumado, grafikaĵoj kaj aŭdaĵoj fare de ${NAME}", + "languageTranslationsText": "Lingvotradukoj:", + "legalText": "Leĝaj aferoj:", + "publicDomainMusicViaText": "Publikdomajna muziko per ${NAME}", + "softwareBasedOnText": "Ĉi tiu programaro estas parte bazita je la laboro de ${NAME}", + "songCreditText": "${TITLE} plenumita de ${PERFORMER}\nKomponita de ${COMPOSER}, aranĝita de ${ARRANGER}, publikigita de ${PUBLISHER},\nDanke al ${SOURCE}", + "soundAndMusicText": "Sono kaj muziko:", + "soundsText": "Sonoj (${SOURCE}):", + "specialThanksText": "Speciale dankon:", + "thanksEspeciallyToText": "Specife dankon al ${NAME}", + "titleText": "Dankdiroj de ${APP_NAME}", + "whoeverInventedCoffeeText": "Kiu ajn inventis kafon" + }, + "currentStandingText": "Via nuna pozicio estas #${RANK}", + "customizeText": "Adapti...", + "deathsTallyText": "${COUNT} mortoj", + "deathsText": "Mortoj", + "debugText": "sencimigi", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Notu: ni rekomendas ke vi konfiguru Agordoj->Grafikaĵoj->Teksturoj kiel 'Alta' dum vi testas tion.", + "runCPUBenchmarkText": "Kompartesto por CPU", + "runGPUBenchmarkText": "Kompartesto por GPU", + "runMediaReloadBenchmarkText": "Kompartesto de rimeda reŝargo", + "runStressTestText": "Streĉtesti", + "stressTestPlayerCountText": "Ludantokvanto", + "stressTestPlaylistDescriptionText": "Streĉtesta ludlisto", + "stressTestPlaylistNameText": "Ludlista nomo", + "stressTestPlaylistTypeText": "Ludlista tipo", + "stressTestRoundDurationText": "Daŭro de ludvico", + "stressTestTitleText": "Streĉtesto", + "titleText": "Kompartestoj kaj streĉtestoj", + "totalReloadTimeText": "Entuta reŝargtempo: ${TIME} (vidu protokolon por detaloj)", + "unlockCoopText": "Malŝlosi kunlaborajn nivelojn" + }, + "defaultFreeForAllGameListNameText": "Normala ludaro por Ĉiuj kune", + "defaultGameListNameText": "Kutima ludlisto de ${PLAYMODE}", + "defaultNewFreeForAllGameListNameText": "Mia ludaro por Ĉiuj kune", + "defaultNewGameListNameText": "Mia ludlisto de ${PLAYMODE}", + "defaultNewTeamGameListNameText": "Miaj teamludoj", + "defaultTeamGameListNameText": "Normala teamludaro", + "deleteText": "Forigi", + "denyText": "Rifuzi", + "desktopResText": "Distingivo", + "difficultyEasyText": "Facile", + "difficultyHardOnlyText": "Nurmalfacila", + "difficultyHardText": "Malfacile", + "difficultyHardUnlockOnlyText": "Ĉi tiu nivelo nur estas malŝlosebla en la \nmalfacila modo. Ĉu vi kapablas fari tion!?!?!", + "directBrowserToURLText": "Bonvolu viziti en retumilo la jenan ligilon:", + "doneText": "Farite", + "drawText": "Egalludo", + "duplicateText": "Duobligi", + "editGameListWindow": { + "addGameText": "Aldoni\nludon", + "cantOverwriteDefaultText": "Ne eblas transskribi la implicitan ludliston!", + "cantSaveAlreadyExistsText": "Ludlisto kun tiu nomo jam ekzistas!", + "cantSaveEmptyListText": "Ne eblas savi malplenan ludliston!", + "editGameText": "Redakti\nludon", + "gameListText": "Ludolisto", + "listNameText": "Ludlista nomo", + "nameText": "Nomo", + "removeGameText": "Forigi\nludon", + "saveText": "Savi liston", + "titleText": "Ludlista redaktilo" + }, + "editProfileWindow": { + "changesNotAffectText": "Notu: ŝanĝoj ne efikos al ludantoj jam enludaj", + "characterText": "rolulo", + "colorText": "koloro", + "getMoreCharactersText": "Ekhavi pli da roluloj...", + "highlightText": "kromkoloro", + "nameDescriptionText": "Ludantonomo", + "nameText": "Nomo", + "randomText": "hazarde", + "titleEditText": "Redakti profilon", + "titleNewText": "Novan profilon" + }, + "editProfilesAnyTimeText": "(vi povas redakti profilojn iam ajn sub 'agordoj')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Vi ne povas forviŝi la dekomencan sontrakon.", + "cantEditDefaultText": "Ne eblas redakti implicitan sontrakon. Duobligu ĝin aŭ kreu novan.", + "cantEditWhileConnectedOrInReplayText": "Ne eblas redakti sontrakojn dum vi estas konektita al ludantaro aŭ en remontro.", + "cantOverwriteDefaultText": "Ne eblas transskribi implicitan sontrakon", + "cantSaveAlreadyExistsText": "Sontrako kun tiu nomo jam ekzistas!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Normala sontrako", + "deleteConfirmText": "Ĉu forviŝi sontrakon:\n\n'${NAME}'?", + "deleteText": "Forviŝi\nsontrakon", + "duplicateText": "Duobligi\nsontrakon", + "editSoundtrackText": "Sontraka redaktilo", + "editText": "Redakti\nsontrakon", + "fetchingITunesText": "kaptante ludlistojn de iTunes...", + "musicVolumeZeroWarning": "Averto: muzika laŭteco estas je 0", + "nameText": "Nomo", + "newSoundtrackNameText": "Mia sontrako ${COUNT}", + "newSoundtrackText": "Nova sontrako:", + "newText": "Nova\nsontrako", + "selectAPlaylistText": "Elektu ludliston", + "selectASourceText": "Muzikfonto", + "soundtrackText": "SonTrako", + "testText": "testi", + "titleText": "Sontrakoj", + "useDefaultGameMusicText": "Kunliverita ludmuziko", + "useITunesPlaylistText": "Ludlisto de iTunes", + "useMusicFileText": "Muzikdosiero (mp3, k.s.)", + "useMusicFolderText": "Dosierujo da muzikdosieroj" + }, + "editText": "Redakti", + "endText": "Fini", + "epicDescriptionFilterText": "${DESCRIPTION} en brila malrapideco", + "epicNameFilterText": "Brila ${NAME}", + "errorAccessDeniedText": "malpermeso aliri", + "errorOutOfDiskSpaceText": "elĉerpiĝis diskspaco", + "errorText": "Eraro", + "errorUnknownText": "nekonata eraro", + "exitGameText": "Ĉu eliri el ${APP_NAME}?", + "externalStorageText": "Ekstera konservujo", + "failText": "Fiasko", + "fatalErrorText": "Ho ve; io mankas aŭ rompiĝis.\nBonvolu provi reinstali la apon aŭ\nkontaktu ${EMAIL} por helpo.", + "fileSelectorWindow": { + "titleFileFolderText": "Elektu dosieron aŭ dosierujon", + "titleFileText": "Elektu dosieron", + "titleFolderText": "Elektu dosierujon", + "useThisFolderButtonText": "Uzi ĉi tiun dosierujon" + }, + "finalScoreText": "Fina poentaro", + "finalScoresText": "Finaj poentoj", + "finalTimeText": "Fina tempo", + "finishingInstallText": "Finante instaliĝon, bonvolu atendi...", + "fireTVRemoteWarningText": "* Por pli bona sperto, uzu\nludregilojn aŭ instalu la\n'${REMOTE_APP_NAME}'-aplikaĵon\nen viaj telefonoj kaj tabuletoj.", + "firstToFinalText": "Unua-ĝis-${COUNT} finalo", + "firstToSeriesText": "Unua-ĝis-${COUNT} serio", + "fiveKillText": "KVINMORTIGO!!!", + "flawlessWaveText": "Perfekta ondo!", + "fourKillText": "KVARMORTIGO!!!", + "freeForAllText": "Ĉiuj kune", + "friendScoresUnavailableText": "Amikaj poentoj nehaveblas.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Plejpoentuloj en ludo ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "Vi ne povas forviŝi la implicitan ludliston!", + "cantEditDefaultText": "Ne eblas redakti la implicitan ludliston! Duobligu ĝin aŭ kreu novan.", + "deleteConfirmText": "Ĉu forviŝi \"${LIST}\"?", + "deleteText": "Forviŝi\nludliston", + "duplicateText": "Duobligi\nludliston", + "editText": "Redakti\nludliston", + "gameListText": "Ludolisto", + "newText": "Nova\nludlisto", + "showTutorialText": "Montri klarigon", + "shuffleGameOrderText": "Miksi ludsinsekvon", + "titleText": "Adapti ludliston de ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Aldoni ludon" + }, + "gamepadDetectedText": "1 ludregtabulo detektita", + "gamepadsDetectedText": "${COUNT} ludregtabuloj detektitaj.", + "gamesToText": "per ${WINCOUNT} ludoj kontraŭ ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Memoru: ajna aparato en ludantaro povas havi\npli ol unu ludanto se vi havas sufiĉe da regiloj.", + "aboutDescriptionText": "Uzu ĉi tiujn paĝojn por kunigi ludantaron.\n\nPer ludantaroj vi povas ludi ludojn kaj turnirojn\nkun viaj amikoj inter diversaj aparatoj.\n\nUzu la butonon ${PARTY} supre dekstre por\nbabili kaj interagi kun la ludantaro.\n(per regilo, premu ${BUTTON} dum vi estas en menuo)", + "aboutText": "Pri", + "addressFetchErrorText": "", + "bluetoothAndroidSupportText": "(funkcias kun ajna Android-aparato kiu subtenas Bluetooth)", + "bluetoothDescriptionText": "Gastigi/aliĝi ludantaron per Bluetooth", + "bluetoothHostText": "Gastigi per Bluetooth", + "bluetoothJoinText": "Aliĝi per Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "kontrolante...", + "disconnectClientsText": "Tio malkonektos la ${COUNT} ludanto(j)n\nen via ludantaro. Ĉu vi certas?", + "friendPromoCodeWhereToEnterText": "(en \"Agordoj->Por spertuloj->Enigu kodon\")", + "googlePlayDescriptionText": "Inviti ludantojn al la ludantaro per Google Play:", + "googlePlayInviteText": "Inviti", + "googlePlayReInviteText": "Estas ${COUNT} ludanto(j) de Google Play en via ludantaro\nkiuj malkonektiĝos se vi komencos novan inviton.\nEnmetu ilin en la nova invito por rehavi ilin.", + "googlePlaySeeInvitesText": "Vidi invitojn", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(versio de Android / Google Play)", + "inDevelopmentWarningText": "Notu:\n\nReta ludado estas nova kaj ankoraŭ disvolvata.\nPor nun, estas rekomendate ke ĉiuj ludantoj\nestu en la sama sendrata reto.", + "internetText": "Interreto", + "inviteFriendsText": "Inviti amikojn", + "joinPublicPartyDescriptionText": "Aliĝi al publika ludantaro", + "localNetworkDescriptionText": "Aliĝi al ludantaro en via reto:", + "localNetworkText": "Loka reto", + "makePartyPrivateText": "Privatigi mian ludantaron", + "makePartyPublicText": "Publikigi mian ludantaron", + "manualAddressText": "Adreso", + "manualConnectText": "Konekti", + "manualDescriptionText": "Aliĝi al ludantaro per adreso:", + "manualJoinSectionText": "Aliĝi per adreso", + "manualJoinableFromInternetText": "Ĉu eblas aliĝi al vi de la interreto?:", + "manualJoinableNoWithAsteriskText": "NE*", + "manualJoinableYesText": "JES", + "manualRouterForwardingText": "*por ebligi tion, provu konfiguri vian disvojilon sendante UDP-pordon ${PORT} al via loka adreso", + "manualText": "Mane", + "manualYourAddressFromInternetText": "Via adreso de la interreto:", + "manualYourLocalAddressText": "Via loka adreso:", + "nearbyText": "Proksime", + "noConnectionText": "", + "otherVersionsText": "(aliaj versioj)", + "partyInviteAcceptText": "Akcepti", + "partyInviteDeclineText": "Malakcepti", + "partyInviteGooglePlayExtraText": "(vidu la paĝon 'Google Play' en la fenestro 'Kolektiĝi')", + "partyInviteIgnoreText": "Ignori", + "partyInviteText": "${NAME} invitis vin\npor aliĝi al la ludantaro!", + "partySizeText": "ludantaro grandeco", + "portText": "Pordo", + "privateText": "Privataj", + "publicText": "Publikaj", + "showMyAddressText": "Montri mian adreson", + "titleText": "Kolektiĝi", + "wifiDirectDescriptionBottomText": "Se ĉiuj aparatoj havas panelon 'Wi-Fi Direct', ili devus povi uzi tion por trovi\nkaj konektiĝi unu al la alia. Kiam ĉiuj aparatoj estas konektitaj, vi povas formi\nludantarojn ĉi tie per la paĝo 'Loka reto', same kiel kun normala Vifi-reto.\n\nPrefere la gastiganto 'Wi-Fi Direct' ankaŭ estu la ludantargastiganto de BombSquad.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct povas esti uzata por konekti Android-aparatojn rekte sen\nbezoni Vifi-reton. Tio plej bone funkcias per Android 4.2 aŭ pli nova.\n\nPor uzi ĝin, malfermu la Vifiajn agordojn kaj serĉu 'Wi-Fi Direct' en la menuo.", + "wifiDirectOpenWiFiSettingsText": "Malfermi Vifiajn agordojn", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(funkcias inter ĉiuj platformoj)", + "worksWithGooglePlayDevicesText": "(funkcias kun aparatoj kun la versio Google Play (android) de la ludo)" + }, + "getCoinsWindow": { + "coinDoublerText": "Monerduobligilo", + "coinsText": "${COUNT} moneroj", + "freeCoinsText": "Senpagaj moneroj", + "restorePurchasesText": "Rehavigi aĉetojn", + "titleText": "Ekhavi monerojn" + }, + "getTicketsWindow": { + "freeText": "SENPAGE!", + "freeTicketsText": "Senpagaj biletoj", + "inProgressText": "Transakcio okazas; bonvolu provi denove baldaŭ.", + "purchasesRestoredText": "Aĉetoj restarigitaj.", + "receivedTicketsText": "Riceviĝis ${COUNT} biletoj!", + "restorePurchasesText": "Restarigi aĉetojn", + "ticketDoublerText": "Biletduobligilo", + "ticketPack1Text": "Eta biletopakaĵo", + "ticketPack2Text": "Meza biletopakaĵo", + "ticketPack3Text": "Granda biletopakaĵo", + "ticketPack4Text": "Ega biletopakaĵo", + "ticketPack5Text": "Egega biletopakaĵo", + "ticketPack6Text": "Plejega biletopakaĵo", + "ticketsFromASponsorText": "Akiri ${COUNT} biletojn\nde sponsoro", + "ticketsText": "${COUNT} biletoj", + "titleText": "Ekhavi biletojn", + "unavailableTemporarilyText": "Nun tio ne haveblas; provu denove poste.", + "unavailableText": "Pardonu, tio ne haveblas.", + "versionTooOldText": "Pardonu, ĉi tiu ludversio tro malnovas; bonvolu ĝisdatigi al pli nova.", + "youHaveShortText": "vi havas ${COUNT}", + "youHaveText": "vi havas ${COUNT} biletojn" + }, + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Ĉiam", + "fullScreenCmdText": "Plena ekrano (Cmd-F)", + "fullScreenCtrlText": "Plena ekrano (Stir-F)", + "gammaText": "Gamo (brileco)", + "highText": "Alta", + "higherText": "Pli alta", + "lowText": "Malalta", + "mediumText": "Meza", + "neverText": "Neniam", + "resolutionText": "Distingivo", + "showFPSText": "Montri FPS", + "texturesText": "Teksturoj", + "titleText": "Grafikaĵoj", + "tvBorderText": "Rando por televido", + "verticalSyncText": "Vertikala sinkronigo", + "visualsText": "Vidaĵoj" + }, + "helpWindow": { + "bombInfoText": "- Bombo -\nPli forta ol batoj, sed povas\nefektivigi gravan sindifekton.\nPor plej bonaj rezultoj, ĵetu al\nmalamiko antaŭ ol la drato finiĝas.", + "canHelpText": "${APP_NAME} povas helpi.", + "controllersInfoText": "Vi povas ludi ${APP_NAME} kun amikoj en reto, aŭ vi povas\nĉiuj ludi en la sama aparato se vi havas sufiĉe da regiloj.\n${APP_NAME} subtenas multajn regilojn; vi eĉ povas uzi vian\npoŝtelefonon kiel regilon per la senpaga aplikaĵo '${REMOTE_APP_NAME}'.\nVidu Agordoj->Regiloj por pliaj informoj.", + "controllersInfoTextFantasia": "Unu persono povas uzi la teleregilon kiel regilo, sed mi forte\nrekomendus uzi ludregtabulojn. Vi ankaŭ povas uzi viajn poŝ-\naparatojn per la senpaga aplikaĵo 'BombSquad Remote'.\nVidu 'Regiloj' sub 'Agordoj' por pliaj informoj.", + "controllersInfoTextMac": "Unu aŭ du ludantoj povas uzi la klavaron, sed BombSquad plej bonas kun\nludregtabuloj. BombSquad povas uzi USB-ludregtabulojn, PS3-regilojn, regilojn\nde XBox 360, Wii-regilojn kaj iOS/Android-aparatojn por regi rolulojn. Espereble\nvi havas kelkajn tiajn disponeblaj. Vidu 'Regiloj' sub 'Agordoj' por pliaj informoj.", + "controllersInfoTextOuya": "Vi povas uzi OUYA-regilon, PS3-regilojn, regilojn de XBox 360 kaj multajn\naliajn ludregtabulojn Bludentajn kaj USBajn ene de BombSquad.\nVi ankaŭ povas uzi iOS-aparatojn kaj Android por regi la ludon per la\nsenpaga aplikaĵo 'BombSquad Remote'. Vidu 'Regiloj' sub 'Agordoj' por\npliaj informoj.", + "controllersText": "Regiloj", + "controlsSubtitleText": "Via amikema ${APP_NAME}-rolulo havas kelkajn bazajn agojn:", + "controlsText": "Regumoj", + "devicesInfoText": "La VR-versio de ${APP_NAME} povas esti ludata en la reto kun la\nnormala versio, do ektrovu viajn aldonajn telefonojn, tabuletojn\nkaj komputilojn, kaj ekludu. Eĉ povas esti utile konekti normalan\nversion de la ludo al la VR-versio por permesi al homoj ekster vi\nkunvidi la agadon.", + "devicesText": "Aparatoj", + "friendsGoodText": "Bonas havi ilin. ${APP_NAME} plej amuzas kun pluraj ludantoj kaj\npovas subteni ĝis 8 samtempe, kio kondukas nin al:", + "friendsText": "Amikoj", + "jumpInfoText": "- Salti -\nSaltu por transiri truetojn,\npor ĵeti pli alten, kaj por\nesprimi ĝojsentojn.", + "orPunchingSomethingText": "Aŭ bati ion, ĵeti ion de deklivo, kaj eksplodigi ĝin survoje malsupren per gluanta bombo.", + "pickUpInfoText": "- Preni -\nPreni flagojn, malamikojn, aŭ ion\najn ne fiksitan je la planko.\nPremu denove por ĵeti.", + "powerupBombDescriptionText": "Ebligas al vi ĵeti tri bombojn\nen vico anstataŭ nur unu.", + "powerupBombNameText": "Trioblaj bomboj", + "powerupCurseDescriptionText": "Vi verŝajne volas eviti ĉi tiujn.\n...ĉu ne?", + "powerupCurseNameText": "Malbeno", + "powerupHealthDescriptionText": "Tutreplenigas vian sanon.\nVi neniam divenintus.", + "powerupHealthNameText": "Sanpakaĵo", + "powerupIceBombsDescriptionText": "Malpli fortaj ol normalaj bomboj\nsed lasas viajn malamikojn\nfrostitaj kaj rompiĝemaj.", + "powerupIceBombsNameText": "Glacibomboj", + "powerupImpactBombsDescriptionText": "Iom malpli fortaj ol normalaj\nbomboj, sed eksplodas je impakto.", + "powerupImpactBombsNameText": "Ekpafbomboj", + "powerupLandMinesDescriptionText": "Ili venas triope;\nUtilas por defendi bazon aŭ\nhaltigi rapidajn malamikojn.", + "powerupLandMinesNameText": "Minoj", + "powerupPunchDescriptionText": "Faras viajn batojn pli duraj,\nrapidaj, bonaj, fortaj.", + "powerupPunchNameText": "Boksglovoj", + "powerupShieldDescriptionText": "Absorbas iom da damaĝo\npor ke vi ne bezonu.", + "powerupShieldNameText": "Energiŝirmilo", + "powerupStickyBombsDescriptionText": "Gluiĝas al ĉio kion ĝi tuŝas.\nVidu kaj ridu.", + "powerupStickyBombsNameText": "Glubomboj", + "powerupsSubtitleText": "Kompreneble, neniu ludo kompletas sen donacetoj:", + "powerupsText": "Donacetoj", + "punchInfoText": "- Bato -\nBatoj pli damaĝas ju pli viaj\npugnoj moviĝas, do kuru kaj\nrotaciu kiel frenezulo.", + "runInfoText": "- Kuri -\nPremadu AJNAN butonon por kuri. Flankbutonoj kaj pafkliko taŭgas se vi havas ilin.\nKurado helpas vin iri ien pli rapide, sed malpli facilas turni, do atentu deklivojn.", + "someDaysText": "Fojfoje vi simple sentas emon bati ion. Aŭ eksplodigi ion.", + "titleText": "Helpo de ${APP_NAME}", + "toGetTheMostText": "Por profiti plej de ĉi tiu ludo, necesos:", + "welcomeText": "Bonvenon al ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} majstre tranavigas menuojn", + "installDiskSpaceErrorText": "ERARO: Neeble kompletigi la instalon.\nEble ne estas sufiĉe da spaco en via\naparato. Viŝu ion kaj provu denove.", + "internal": { + "arrowsToExitListText": "premu ${LEFT} aŭ ${RIGHT} por eliri liston", + "buttonText": "butono", + "connectedToPartyText": "En la ludantaro de ${NAME}!", + "connectingToPartyText": "Konektiĝas...", + "connectionFailedHostAlreadyInPartyText": "Konekto fiaskis; gastiganto estas en alia ludantaro.", + "connectionFailedText": "Konekto fiaskis.", + "connectionFailedVersionMismatchText": "Konekto fiaskis; gastiganto havas alian version de la ludo.\nCertigu vin ke vi ambaŭ estu ĝisdataj kaj provu denove.", + "connectionRejectedText": "Konekto malakceptita.", + "controllerConnectedText": "${CONTROLLER} konektiĝis.", + "controllerDetectedText": "1 regilo detektita.", + "controllerDisconnectedText": "${CONTROLLER} malkonektiĝis.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} malkonektiĝis. Bonvolu reprovi konektiĝi.", + "controllerReconnectedText": "${CONTROLLER} rekonektiĝis.", + "controllersConnectedText": "${COUNT} regiloj konektitaj.", + "controllersDetectedText": "${COUNT} regiloj detektitaj.", + "controllersDisconnectedText": "${COUNT} regiloj malkonektitaj.", + "corruptFileText": "Detektiĝis koruptaj dosieroj. Bonvolu provi reinstali, aŭ retpoŝtu ${EMAIL}", + "errorPlayingMusicText": "Eraro ludante muzikon: ${MUSIC}", + "errorResettingAchievementsText": "Ne eblas reigi enretajn atingojn; provu denove pli malfrue.", + "hasMenuControlText": "${NAME} regas la menuon.", + "incompatibleVersionHostText": "Gastiganto uzas alian version de la ludo.\nCertigu vin ke vi ambaŭ estu ĝisdataj kaj provu denove.", + "incompatibleVersionPlayerText": "${NAME} uzas alian version de la ludo.\nCertigu vin ke vi ambaŭ estu ĝisdataj kaj provu denove.", + "invalidAddressErrorText": "Eraro: nevalida adreso.", + "invalidNameErrorText": "Eraro: nevalida nomo.", + "invalidPortErrorText": "Eraro: nevalida pordo.", + "invitationSentText": "Invito sendiĝis.", + "invitationsSentText": "${COUNT} invitoj sendiĝis.", + "joinedPartyInstructionsText": "Iu aliĝis al via ludantaro.\nIru al 'Ekludi' por komenci ludon.", + "keyboardText": "Klavaro", + "kickIdlePlayersKickedText": "${NAME} forpuŝiĝas pro neaktiveco.", + "kickIdlePlayersWarning1Text": "${NAME} forpuŝiĝos post ${COUNT} sekundoj se ankoraŭ neaktiva.", + "kickIdlePlayersWarning2Text": "(eblas malŝalti tion en Agordoj -> Por spertuloj)", + "leftGameText": "Forlasis '${NAME}'.", + "leftPartyText": "Eliris el ludantaro de ${NAME}.", + "noMusicFilesInFolderText": "Dosierujo ne enhavas muzikdosierojn.", + "playerJoinedPartyText": "${NAME} aliĝis al la ludantaro!", + "playerLeftPartyText": "${NAME} foriris de la ludantaro.", + "rejectingInviteAlreadyInPartyText": "Malakceptiĝas invito (jam en ludantaro).", + "signInErrorText": "Eraro ensaluti.", + "signInNoConnectionText": "Ne eblas ensaluti. (ĉu sen retkonekto?)", + "teamNameText": "Teamo ${NAME}", + "telnetAccessDeniedText": "ERARO: uzanto ne donis telnet-aliron.", + "timeOutText": "(tempo elĉerpiĝos post ${TIME} sekundoj)", + "touchScreenJoinWarningText": "Vi aliĝis per la tuŝekrano.\nSe tio estis eraro, tuŝu 'Menuo->Foriri de ludo' per ĝi.", + "touchScreenText": "TuŝEkrano", + "trialText": "provversio", + "unavailableNoConnectionText": "Ĉi tio momente ne haveblas (manko de retkonekto?)", + "vrOrientationResetCardboardText": "Uzu ĉi tion por reigi la VR-orientiĝon.\nPor ludi la ludon vi bezonos aldonan regilon.", + "vrOrientationResetText": "Reiĝis orientiĝo de VR.", + "willTimeOutText": "(sen aktiveco tempo elĉerpiĝos)" + }, + "jumpBoldText": "SALTI", + "jumpText": "Salti", + "keepText": "Teni", + "keepTheseSettingsText": "Ĉu teni ĉi tiujn agordojn?", + "killsTallyText": "${COUNT} mortigoj", + "killsText": "Mortigoj", + "kioskWindow": { + "easyText": "Facile", + "epicModeText": "Brila modo", + "fullMenuText": "Plena menuo", + "hardText": "Malfacile", + "mediumText": "Mezfacile", + "singlePlayerExamplesText": "Ekzemploj de unu ludanto / kunlabore", + "versusExamplesText": "Ekzemploj de ludoj unu kontraŭ la alia" + }, + "languageSetText": "Lingvo nun estas \"${LANGUAGE}\".", + "lapNumberText": "Ĉirkaŭiro ${CURRENT} el ${TOTAL}", + "lastGamesText": "(lastaj ${COUNT} ludoj)", + "leaderboardsText": "Plejpoentularoj", + "league": { + "allTimeText": "Pri ĉiam", + "currentSeasonText": "Nuna sezono (${NUMBER})", + "leagueFullText": "Ligo ${NAME}", + "leagueRankText": "Liga ranko", + "leagueText": "Ligo", + "seasonEndedDaysAgoText": "Sezono finiĝis antaŭ ${NUMBER} tagoj.", + "seasonEndsDaysText": "Sezono finiĝos en ${NUMBER} tagoj.", + "seasonEndsHoursText": "Sezono finiĝos en ${NUMBER} horoj.", + "seasonEndsMinutesText": "Sezono finiĝos en ${NUMBER} minutoj.", + "seasonText": "Sezono ${NUMBER}", + "tournamentLeagueText": "Vi devas atingi la ligon ${NAME} por eniri ĉi tiun turniron.", + "trophyCountsResetText": "Premikalkuloj reiĝos sekvasezone." + }, + "levelFastestTimesText": "Plej rapidaj tempoj en ${LEVEL}", + "levelHighestScoresText": "Plej altaj poentoj en ${LEVEL}", + "levelIsLockedText": "${LEVEL} estas ŝlosita.", + "levelMustBeCompletedFirstText": "Unue necesas kompletigi ${LEVEL}.", + "levelText": "Nivelo ${NUMBER}", + "levelUnlockedText": "Nivelo malŝlosita!", + "livesBonusText": "Vivopremio", + "loadingText": "ŝargas", + "macControllerSubsystemBothText": "Ambaŭ (ne rekomendita)", + "mainMenu": { + "creditsText": "Dankdiroj", + "demoMenuText": "Montromenuo", + "endGameText": "Fini ludon", + "exitGameText": "Eliri de ludo", + "exitToMenuText": "Ĉu reiri al menuo?", + "howToPlayText": "Kiel ludi", + "justPlayerText": "(Nur ${NAME})", + "leaveGameText": "Foriri de ludo", + "leavePartyConfirmText": "Ĉu vere foriri de la ludantaro?", + "leavePartyText": "For de la ludantaro", + "leaveText": "Foriri", + "quitText": "Fermi", + "resumeText": "Pluiri", + "settingsText": "Agordoj" + }, + "makeItSoText": "Tiel estu", + "mapSelectGetMoreMapsText": "Pli da mapoj...", + "mapSelectText": "Elektu...", + "mapSelectTitleText": "Mapoj de ${GAME}", + "mapText": "Mapo", + "maxPartySizeText": "Maksimuma grandeco de ludantaro", + "maxPlayersText": "Maksimumaj ludantoj", + "mostValuablePlayerText": "Plej valora ludanto", + "mostViolatedPlayerText": "Plej perfortita ludanto", + "mostViolentPlayerText": "Plej perforta ludanto", + "moveText": "Movi", + "multiKillText": "${COUNT}-MORTIGO!!!", + "multiPlayerCountText": "${COUNT} ludantoj", + "mustInviteFriendsText": "Notu: vi devas inviti amikojn en\nla panelo \"${GATHER}\" aŭ ligi\nregilojn por ludi plurope.", + "nameBetrayedText": "${NAME} perfidis al ${VICTIM}", + "nameDiedText": "${NAME} mortis.", + "nameKilledText": "${VICTIM} estas mortigita de ${NAME}", + "nameNotEmptyText": "Nomo ne povas esti malplena!", + "nameScoresText": "${NAME} poentas!", + "nameSuicideKidFriendlyText": "${NAME} ging per ongeluk dood", + "nameSuicideText": "${NAME} mortigis sin.", + "nameText": "Nomo", + "nativeText": "Propra", + "newPersonalBestText": "Nova persona plejbono!", + "newTestBuildAvailableText": "Nova testkonstruo haveblas! (${VERSION} konstruo ${BUILD}).\nEkhavu ĝin ĉe ${ADDRESS}", + "newText": "Nova", + "newVersionAvailableText": "Nova versio de ${APP_NAME} estas havebla! (${VERSION})", + "nextLevelText": "Sekva nivelo", + "noAchievementsRemainingText": "- neniom", + "noContinuesText": "(sen pluiroj)", + "noExternalStorageErrorText": "Ne trovis eksteran konservujon en ĉi tiu aparato", + "noGameCircleText": "Eraro: ne ensalutita en GameCircle", + "noJoinCoopMidwayText": "Ne eblas aliĝi al kunlaboraj ludoj dumlude.", + "noProfilesErrorText": "Vi ne havas ludantoprofilojn, do ni devos nomi vin '${NAME}'.\nIru al Agordoj->Ludantprofiloj por fari profilon por vi.", + "noScoresYetText": "Ne jam poentoj.", + "noThanksText": "Ne dankon", + "noValidMapsErrorText": "Ne trovis validajn mapojn por ĉi tiu ludotipo.", + "notEnoughPlayersRemainingText": "Ne sufiĉe da ludantoj restas; eliri kaj komenci novan ludon.", + "notEnoughPlayersText": "Vi bezonas almenaŭ ${COUNT} ludantojn por komenci ĉi tiun ludon!", + "notNowText": "Ne nun", + "notSignedInErrorText": "Vi devas ensaluti por fari tion.", + "notSignedInGooglePlayErrorText": "Vi devas ensaluti per Google Play por fari tion.", + "notSignedInText": "ne ensalutita", + "nothingIsSelectedErrorText": "Nenio elektiĝis!", + "numberText": "#${NUMBER}", + "offText": "Malŝaltite", + "okText": "Bone", + "onText": "Ŝaltite", + "oneMomentText": "Unu momenton...", + "onslaughtRespawnText": "${PLAYER} reviviĝos en ondo ${WAVE}", + "orText": "${A} aŭ ${B}", + "otherText": "Aliaj...", + "outOfText": "(#${RANK} el ${ALL})", + "ownFlagAtYourBaseWarning": "Via propra flago estu\nje via bazo por poenti!", + "packageModsEnabledErrorText": "Reta ludado ne estas permesata dum lokaj pakaĵaj modifikaĵoj estas aktivaj (vidu Agordoj->Por spertuloj)", + "partyWindow": { + "chatMessageText": "Babilmesaĝo", + "emptyText": "Via ludantaro estas malplena", + "hostText": "(gastiganto)", + "sendText": "Sendi", + "titleText": "Via ludantaro" + }, + "pausedByHostText": "(paŭzigita de gastiganto)", + "perfectWaveText": "Perfekta ondo!", + "pickUpText": "Preni", + "playModes": { + "coopText": "Kunlabore", + "freeForAllText": "Ĉiuj kune", + "multiTeamText": "Plurteame", + "singlePlayerCoopText": "Unuope aŭ kunlabore", + "teamsText": "Teame" + }, + "playText": "Ekludi", + "playWindow": { + "coopText": "Kunlabore", + "freeForAllText": "Ĉiuj kune", + "oneToFourPlayersText": "1 ĝis 4 ludantoj", + "teamsText": "Teamoj", + "titleText": "Ludi", + "twoToEightPlayersText": "2 ĝis 8 ludantoj" + }, + "playerCountAbbreviatedText": "${COUNT}lud", + "playerDelayedJoinText": "${PLAYER} eniros komence de la sekva ludo.", + "playerInfoText": "Informoj pri ludanto", + "playerLeftText": "${PLAYER} foriris de la ludo.", + "playerLimitReachedText": "Ludanto-limo de ${COUNT} atingita; neniu plu aliĝu.", + "playerLimitReachedUnlockProText": "Ĝisdatigu al \"${PRO}\" en la vendejo por ludi kun pli ol ${COUNT} ludantoj.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Vi ne povas forviŝi vian konto-profilon.", + "deleteButtonText": "Forviŝi\nprofilon", + "deleteConfirmText": "Ĉu forviŝi '${PROFILE}'?", + "editButtonText": "Redakti\nprofilon", + "explanationText": "(adaptitaj ludantnomoj kaj aperojn por ĉi tiu konto)", + "newButtonText": "Nova\nprofilo", + "titleText": "Ludanto-profiloj" + }, + "playerText": "Ludanto", + "playlistNoValidGamesErrorText": "Ĉi tiu ludlisto ne enhavas validajn malŝlositajn ludojn.", + "playlistNotFoundText": "ludlisto ne troviĝis", + "playlistText": "Ludlisto", + "playlistsText": "Ludlistoj", + "pleaseRateText": "Se vi ŝatas ${APP_NAME}, bonvolu konsideri momenton\npor rankumi ĝin aŭ verki prijuĝon. Tio donos utilan\nretrokuplon kaj helpos subteni pluan disvolviĝon.\n\nDankon!\n- Eriko", + "pleaseWaitText": "Bonvolu atendi...", + "pluginsText": "Kromaĵoj", + "pressAnyButtonPlayAgainText": "Premu ajnan butonon por reekludi...", + "pressAnyButtonText": "Premu ajnan butonon por pluiri...", + "pressAnyButtonToJoinText": "premu ajnan butonon por aliĝi...", + "pressAnyKeyButtonPlayAgainText": "Premu ajnan klavon/butonon por reekludi...", + "pressAnyKeyButtonText": "Premu ajnan klavon/butonon por pluiri...", + "pressAnyKeyText": "Premu ajnan klavon...", + "pressJumpToFlyText": "** Sinripete premu salti por flugi **", + "pressPunchToJoinText": "premu BATI por aliĝi...", + "pressToOverrideCharacterText": "premu ${BUTTONS} por ŝanĝi vian rolulon", + "pressToSelectProfileText": "premu ${BUTTONS} por elekti vian profilon", + "pressToSelectTeamText": "premu ${BUTTONS} por elekti vian teamon", + "profileInfoText": "Kreu profilojn por vi mem kaj viajn amikojn\npor adapti viajn nomojn, rolulojn kaj kolorojn.", + "promoCodeWindow": { + "codeText": "Kodo", + "codeTextDescription": "Promocia kodo", + "enterText": "Enigi" + }, + "promoSubmitErrorText": "Eraro aplikante vian kodon; kontrolu vian retkonekton", + "ps3ControllersWindow": { + "macInstructionsText": "Malŝaltu la energion malantaŭe de via PS3, certigu ke Bludento\nestu aktiva en via Makintoŝo, tiam konektu vian regilon al via\nMakintoŝo per USB-kablo por parigi ilin. De tiam, vi povas uzi la\nhejmbutonon de la regilo por konekti ĝin kun via Makintoŝo ĉu\ndrate (USB) ĉu sendrate (Bludento).\n\nEn kelkaj Makintoŝo la sistemo povas peti vin enigi paskodon por\nparigi. Se tio okazas, jen la sekva klarigo aŭ guglu por helpo.\n\n\n\n\nPS3-regiloj konektitaj sendrate aperu en la aparatlisto en Sistem-\npreferoj->Bludento. Povas esti necese forigi ilin de tiu listo por\nuzi ilin denove kun via PS3.\n\nAnkaŭ certiĝu diskonekti ilin de Bludento kiam ne en uzo, alikaze\nmalŝparante la bateriojn.\n\nBludento povu trakti ĝis 7 konektitajn aparatojn, sed via sperto\npovus esti alia.", + "ouyaInstructionsText": "Por uzi PS3-regilon kun via OUYA, simple konektu ĝin per USB-kablo unufoje\npor parigi ĝin. Farante tion viaj aliaj regiloj povas malŝaltiĝi, do tiam restartu\nvian OUYA kaj malligu la USB-kablon.\n\nDe tiam sufiĉu uzi la regilan hejmbutonon por konekti ĝin sendrate. Post kiam\nvi ludis, premu la HEJM-butonon dum 10 sekundoj por malŝalti la regilon; alie\nĝi povas resti ŝaltita, tiel malŝparante bateriojn.", + "pairingTutorialText": "klariga video por parigi", + "titleText": "Uzi PS3-regilojn kun ${APP_NAME}:" + }, + "publicBetaText": "PUBLIKA BETA", + "punchBoldText": "BATO", + "punchText": "Bato", + "purchaseForText": "Aĉetu por ${PRICE}", + "purchaseGameText": "Aĉeti ludon", + "purchasingText": "Aĉetiĝas...", + "quitGameText": "Ĉu fermi ${APP_NAME}?", + "quittingIn5SecondsText": "Fermos en 5 sekundoj...", + "randomText": "Hazarde", + "rankText": "Ranko", + "ratingText": "Ranko", + "reachWave2Text": "Atingu la duan ondon por ranki.", + "readyText": "preta", + "recentText": "Lastatempaj", + "remainingInTrialText": "restas en elprovo", + "remote_app": { + "start": "Komenci" + }, + "removeInGameAdsText": "Malŝlosu \"${PRO}\" en la vendejo por forigi enludajn reklamojn.", + "renameText": "Renomi", + "replayEndText": "Fini remontron", + "replayNameDefaultText": "Lastluda remontro", + "replayReadErrorText": "Eraro legante remontran dosieron.", + "replayRenameWarningText": "Ŝangu la nomon de \"${REPLAY}\" post ludo por teni ĝin; alikaze ĝi transskribiĝos.", + "replayVersionErrorText": "Pardonu, ĉi tiu remontro estas farita en alia\nversio de la ludo kaj ne povas esti uzata.", + "replayWatchText": "Spekti remontron", + "replayWriteErrorText": "Eraro skribante remontran dosieron.", + "replaysText": "Remontroj", + "requestingText": "Petante...", + "restartText": "Restarti", + "retryText": "Reprovi", + "revertText": "Reigi", + "runText": "Kuri", + "saveText": "Savi", + "scoreChallengesText": "Poentaraj defioj", + "scoreListUnavailableText": "Poentara listo nehavebla.", + "scoreText": "Poentaro", + "scoreUnits": { + "millisecondsText": "Milisekundoj", + "pointsText": "Poentoj", + "secondsText": "Sekundoj" + }, + "scoreWasText": "(estis ${COUNT})", + "selectText": "Elektu", + "seriesWinLine1PlayerText": "VENKAS LA", + "seriesWinLine1TeamText": "VENKAS LA", + "seriesWinLine1Text": "VENKAS LA", + "seriesWinLine2Text": "SERION!", + "settingsWindow": { + "accountText": "Konto", + "advancedText": "Por spertuloj", + "audioText": "Aŭdaĵoj", + "controllersText": "Regiloj", + "graphicsText": "Grafikaĵoj", + "playerProfilesText": "Ludantprofiloj", + "titleText": "Agordoj" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(facila, regilo-amika surekrana klavaro por redakti tekstojn)", + "alwaysUseInternalKeyboardText": "Ĉiam uzi internan klavaron", + "benchmarksText": "Kompartestoj kaj streĉtestoj", + "enablePackageModsDescriptionText": "(ebligas aldonajn modifikajn kapablojn sed malebligas retludadon)", + "enablePackageModsText": "Ebligi lokajn pakaĵajn modifikaĵojn", + "enterPromoCodeText": "Enigu kodon", + "forTestingText": "Notu: ĉi tiuj valoroj estas nur por testado kaj perdiĝos je fermiĝo de la aplikaĵo.", + "helpTranslateText": "La neanglaj tradukoj de ${APP_NAME} nur eblas pro\nla komunumo. Se vi volas kontribui aŭ korekti tradukon,\nsekvu la suban ligilon. Jam antaŭe dankon!", + "kickIdlePlayersText": "Forpuŝi neaktivajn ludantojn", + "kidFriendlyModeText": "Infanamika modo (malpli da perforto ktp)", + "languageText": "Lingvo", + "moddingGuideText": "Modifikaĵa gvidlibro", + "mustRestartText": "Vi devas restarti la ludon por efektivigi tion.", + "netTestingText": "Testi la reton", + "resetText": "Reigi", + "showPlayerNamesText": "Montri ludantonomojn", + "showUserModsText": "Montri modifikaĵujon", + "titleText": "Por spertuloj", + "translationEditorButtonText": "${APP_NAME} traduko-redaktilo", + "translationFetchErrorText": "tradukstato ne haveblas", + "translationFetchingStatusText": "kontrolante staton de traduko...", + "translationNoUpdateNeededText": "la nuna lingvo estas ĝisdata, hura!", + "translationUpdateNeededText": "** la nuna lingvo bezonas ĝisdatigojn!! **", + "vrTestingText": "Testo de VR" + }, + "shareText": "Kunhavigi", + "showText": "Montri", + "signInWithGameCenterText": "Uzu la Ludcentran aplikaĵon por ensaluti.", + "singleGamePlaylistNameText": "Nur ${GAME}", + "singlePlayerCountText": "1 ludanto", + "soloNameFilterText": "Unuopa ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Elekti rolulon", + "Chosen One": "La elektita", + "Epic": "Brilmodaj ludoj", + "Epic Race": "Brila konkurso", + "FlagCatcher": "Kaptu la flagon", + "Flying": "Feliĉaj pensoj", + "Football": "Futbalo", + "ForwardMarch": "Sturmo", + "GrandRomp": "Konkero", + "Hockey": "Hokeo", + "Keep Away": "Fortenu", + "Marching": "Trakuri", + "Menu": "Ĉefmenuo", + "Onslaught": "Impeto", + "Race": "Konkurso", + "Scary": "Reĝo de la monto", + "Scores": "Poenta ekrano", + "Survival": "Eliminado", + "ToTheDeath": "Ĝismorte", + "Victory": "Finpoenta ekrano" + }, + "spaceKeyText": "spaco", + "statsText": "Statistiko", + "store": { + "alreadyOwnText": "Vi jam posedas ${NAME}!", + "bombSquadProDescriptionText": "Duobligos biletojn gajnitajn enlude\n\nForigos enludan reklamon\n\nInkluzivas ${COUNT} aldonajn biletojn\n\n+${PERCENT}% aldone en ligaj poentoj\n\nMalŝlosos nivelojn '${INF_ONSLAUGHT}'\n kaj '${INF_RUNAROUND}' (kunlaborajn)", + "bombSquadProFeaturesText": "Avantaĝoj:", + "bombSquadProNameText": "${APP_NAME} Pro", + "buyText": "Aĉeti", + "charactersText": "Roluloj", + "comingSoonText": "Baldaŭ...", + "extrasText": "Aldonaĵoj", + "freeBombSquadProText": "BombSquad nun estas senpaga, sed ĉar vi origine aĉetis ĝin vi ricevas\nla ĝisdatigon BombSquad Pro kaj ${COUNT} biletojn kiel dankomontro.\nĜuu la novajn funkciojn, kaj dankon pro via subteno!\n- Eriko", + "gameUpgradesText": "Ludaj ĝisdatigoj", + "getCoinsText": "Ekhavi monerojn", + "holidaySpecialText": "Feria specialaĵo", + "howToSwitchCharactersText": "(iru al \"${SETTINGS} -> ${PLAYER_PROFILES}\" por konfiguri kaj adapti rolulojn)", + "loadErrorText": "Ne eblas ŝargi paĝon.\nKontrolu vian retkonekton.", + "loadingText": "ŝargas", + "mapsText": "Mapoj", + "miniGamesText": "Ludetoj", + "oneTimeOnlyText": "(nur unufoje)", + "purchaseAlreadyInProgressText": "Aĉeto de ĉi tio jam okazas.", + "purchaseConfirmText": "Ĉu aĉeti ${ITEM}?", + "purchaseNotValidError": "Aĉeto ne validas.\nKontaktu ${EMAIL} se tio estas eraro.", + "purchaseText": "Aĉeti", + "saleBundleText": "Kombin-rabato!", + "saleExclaimText": "Rabato!", + "salePercentText": "(${PERCENT} malpli)", + "saleText": "RABATE", + "searchText": "Serĉi", + "teamsFreeForAllGamesText": "Ludoj teamaj / Ĉiuj kune", + "upgradeQuestionText": "Ĉu ĝisdatigi?", + "winterSpecialText": "Vintra specialaĵo", + "youOwnThisText": "- jam havas tion -" + }, + "storeDescriptionText": "Festluda frenezo kun 8 ludantoj!\n\nEksplodigu viajn amikojn (aŭ la komputilon) en turniro da eksplodemaj ludetoj kiel Kaptu la flagon, Bomba hokeo kaj Brila-malrapida-Ĝis-la-morto!!\n\nSimplaj regumoj kaj bonega regila subteno faciligas 8ope ekagi; vi eĉ povas uzi viajn poŝaparatojn kiel regiloj per la senpaga aplikaĵo 'BombSquad Remote'!\n\nEkbombu!\n\nVidu www.froemling.net/bombsquad por pliaj informoj.", + "storeDescriptions": { + "blowUpYourFriendsText": "Eksplodigu viajn amikojn.", + "competeInMiniGamesText": "Batalu en ludetoj kiaj kurado kaj flugado.", + "customize2Text": "Adaptu rolulojn, ludetojn kaj eĉ la sontrakon.", + "customizeText": "Adaptu rolulojn kaj kreu viajn proprajn ludlistojn da ludetoj.", + "sportsMoreFunText": "Sporto pli amuzas kun eksplodiloj.", + "teamUpAgainstComputerText": "Teame alfrontu la komputilon." + }, + "storeText": "Vendejo", + "teamsText": "Teamoj", + "telnetAccessGrantedText": "Telnet-aliro ebligita.", + "telnetAccessText": "Telnet-aliro detektita, ĉu permesi?", + "testBuildErrorText": "Ĉi tiu testkonstruo ne plu estas aktiva; bonvolu kontroli por nova versio.", + "testBuildText": "Testkonstruo", + "testBuildValidateErrorText": "Ne eblas validigi testkonstruon. (ĉu sen retkonekto?)", + "testBuildValidatedText": "Testkonstruo validas; ĝuu!", + "thankYouText": "Dankon pro via subteno! Ĝuu la ludon!!", + "threeKillText": "TRIOBLA MORTIGO!!", + "timeBonusText": "Tempopremio", + "timeElapsedText": "Tempo pasis", + "timeExpiredText": "Tempo elĉerpiĝis", + "tipText": "Konsilo", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Plej bonaj amikoj", + "tournamentCheckingStateText": "Kontrolante turniran staton; bonvolu atendi...", + "tournamentEndedText": "Ĉi tiu turniro finiĝis. Nova baldaŭ komenciĝos.", + "tournamentEntryText": "Eniri turniron", + "tournamentResultsRecentText": "Lastatempaj turniraj rezultoj", + "tournamentStandingsText": "Turniraj pozicioj", + "tournamentText": "Turniro", + "tournamentTimeExpiredText": "Turnira tempo elĉerpiĝis", + "tournamentsText": "Turniroj", + "translations": { + "characterNames": { + "B-9000": "B-9000", + "Bernard": "Bernardo", + "Bones": "Ĝisostulo", + "Santa Claus": "Sankta Nikolao" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} trejniĝo", + "Infinite ${GAME}": "Senfina ${GAME}", + "Infinite Onslaught": "Senfina impeto", + "Infinite Runaround": "Senfina trakuro", + "Onslaught Training": "Impeta trejniĝo", + "Pro ${GAME}": "Profesia ${GAME}", + "Pro Football": "Profesia futbalo", + "Pro Onslaught": "Profesia impeto", + "Pro Runaround": "Profesia trairo", + "Rookie ${GAME}": "Komencanta ${GAME}", + "Rookie Football": "Komencanta futbalo", + "Rookie Onslaught": "Komencanta impeto", + "The Last Stand": "Ĝis la lasta", + "Uber ${GAME}": "Ega ${GAME}", + "Uber Football": "Futbalego", + "Uber Onslaught": "Impetego", + "Uber Runaround": "Trairego" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Estu la elektita dum tiom da tempo por venki.\nMortigu la elektitan por mem fariĝi.", + "Bomb as many targets as you can.": "Bombigu kiel eble plej da celoj.", + "Carry the flag for ${ARG1} seconds.": "Portu la flagon dum ${ARG1} sekundoj.", + "Carry the flag for a set length of time.": "Portu la flagon dum difinita tempo.", + "Crush ${ARG1} of your enemies.": "Detruu ${ARG1} el viaj malamikoj.", + "Defeat all enemies.": "Superu ĉiujn malamikojn.", + "Dodge the falling bombs.": "Evitu la falantajn bombojn.", + "Final glorious epic slow motion battle to the death.": "Fina glora brila malrapida batalo ĝis la morto.", + "Get the flag to the enemy end zone.": "Portu la flagon ĝis la malamika finregiono.", + "How fast can you defeat the ninjas?": "Kiom rapide vi povas privenki la ŝinobojn.", + "Kill a set number of enemies to win.": "Mortigu difinitan kvanton da malamikoj por venki.", + "Last one standing wins.": "La lasta restanta venkas.", + "Last remaining alive wins.": "La lasta kiu ankoraŭ vivas, venkas.", + "Last team standing wins.": "Lasta teamo restanta venkas.", + "Prevent enemies from reaching the exit.": "Malhelpu al malamikoj atingi la elirejon.", + "Reach the enemy flag to score.": "Atingu la malamikan flagon por poenti.", + "Return the enemy flag to score.": "Reportu la malamikan flagon por poenti.", + "Run ${ARG1} laps.": "Kuru ${ARG1} ĉirkaŭirojn.", + "Run ${ARG1} laps. Your entire team has to finish.": "Kuru ${ARG1} ĉirkaŭirojn. Via tuta teamo devos alveni.", + "Run 1 lap.": "Kuru 1 ĉirkaŭiron.", + "Run 1 lap. Your entire team has to finish.": "Kuru 1 ĉirkaŭiron. Via tuta teamo devos alveni.", + "Run real fast!": "Kuru tre rapide!", + "Score ${ARG1} goals.": "Poentu ${ARG1} golojn.", + "Score ${ARG1} touchdowns.": "Poentu ${ARG1} postliniaĵojn.", + "Score a goal.": "Poentu golon.", + "Score a touchdown.": "Poentu postliniaĵon.", + "Score some goals.": "Poentu golojn.", + "Secure all ${ARG1} flags.": "Sekurigu ĉiujn ${ARG1} flagojn.", + "Secure all flags on the map to win.": "Sekurigu ĉiujn flagojn sur la mapo por gajni.", + "Secure the flag for ${ARG1} seconds.": "Sekurigu la flagon por ${ARG1} sekundoj.", + "Secure the flag for a set length of time.": "Sekurigu la flagon por difinita daŭro.", + "Steal the enemy flag ${ARG1} times.": "Ŝtelu la malamikan flagon ${ARG1}-foje.", + "Steal the enemy flag.": "Ŝtelu la malamikan flagon.", + "There can be only one.": "Nur povas esti unu.", + "Touch the enemy flag ${ARG1} times.": "Tuŝu la malamikan flagon ${ARG1}-foje.", + "Touch the enemy flag.": "Tuŝu la malamikan flagon.", + "carry the flag for ${ARG1} seconds": "portu la flagon dum ${ARG1} sekundoj", + "kill ${ARG1} enemies": "mortigu ${ARG1} malamikojn", + "last one standing wins": "la lasta restanta venkas", + "last team standing wins": "lasta teamo restanta venkas", + "return ${ARG1} flags": "reportu ${ARG1} flagojn", + "return 1 flag": "reportu 1 flagon", + "run ${ARG1} laps": "kuru ${ARG1} ĉirkaŭirojn", + "run 1 lap": "kuru 1 ĉirkaŭiron", + "score ${ARG1} goals": "poentu ${ARG1} golojn", + "score ${ARG1} touchdowns": "poentu ${ARG1} postliniaĵojn", + "score a goal": "poentu golon", + "score a touchdown": "poentu postliniaĵon", + "secure all ${ARG1} flags": "sekurigu ĉiujn ${ARG1} flagojn", + "secure the flag for ${ARG1} seconds": "sekurigu la flagon por ${ARG1} sekundoj", + "touch ${ARG1} flags": "tuŝu ${ARG1} flagojn", + "touch 1 flag": "tuŝu 1 flagon" + }, + "gameNames": { + "Assault": "Sturmo", + "Capture the Flag": "Kaptu la flagon", + "Chosen One": "La elektita", + "Conquest": "Konkero", + "Death Match": "Ĝis la morto", + "Elimination": "Eliminado", + "Football": "Futbalo", + "Hockey": "Hokeo", + "Keep Away": "Fortenu", + "King of the Hill": "Reĝo de la monto", + "Meteor Shower": "Meteora pluvo", + "Ninja Fight": "Ŝinoba batalo", + "Onslaught": "Impeto", + "Race": "Konkurso", + "Runaround": "Trairo", + "Target Practice": "Cel-praktikado", + "The Last Stand": "Ĝis la lasta" + }, + "inputDeviceNames": { + "Keyboard": "Klavaro", + "Keyboard P2": "Klavaro Lud2" + }, + "languages": { + "Arabic": "Araba", + "Belarussian": "Belorusa", + "Chinese": "Ĉina simpligita", + "ChineseTraditional": "Ĉina tradicia", + "Croatian": "Kroata", + "Czech": "Ĉeĥa", + "Danish": "Dana", + "Dutch": "Nederlanda", + "English": "Angla", + "Esperanto": "Esperanto", + "Finnish": "Finna", + "French": "Franca", + "German": "Germana", + "Gibberish": "Sensenca", + "Greek": "Greka", + "Hindi": "Hindia", + "Hungarian": "Hungara", + "Indonesian": "Indonezia", + "Italian": "Itala", + "Japanese": "Japana", + "Korean": "Korea", + "Persian": "Persa", + "Polish": "Pola", + "Portuguese": "Portugala", + "Romanian": "Rumana", + "Russian": "Rusa", + "Serbian": "Serba", + "Slovak": "Slovaka", + "Spanish": "Hispana", + "Swedish": "Sveda", + "Tamil": "Tamila", + "Thai": "Tajlanda", + "Turkish": "Turka", + "Ukrainian": "Ukraina", + "Venetian": "Venecia", + "Vietnamese": "Vjetnama" + }, + "leagueNames": { + "Bronze": "Bronza", + "Diamond": "Diamanta", + "Gold": "Ora", + "Silver": "Arĝenta" + }, + "mapsNames": { + "Big G": "Granda G", + "Bridgit": "Trapontu", + "Courtyard": "Korto", + "Crag Castle": "Brikkastelo", + "Doom Shroom": "Fungegaĉo", + "Football Stadium": "Futbala stadio", + "Happy Thoughts": "Feliĉaj pensoj", + "Hockey Stadium": "Hokea stadio", + "Lake Frigid": "Frosta lago", + "Monkey Face": "Simivizaĝo", + "Rampage": "Rultabulejo", + "Roundabout": "Rondiro", + "Step Right Up": "Supreniru", + "The Pad": "La platformo", + "Tip Top": "Piramido", + "Tower D": "Turo D", + "Zigzag": "Zigzago" + }, + "playlistNames": { + "Just Epic": "Nur brile", + "Just Sports": "Nur sportoj" + }, + "promoCodeResponses": { + "invalid promo code": "nevalida promocia kodo" + }, + "scoreNames": { + "Flags": "Flagoj", + "Goals": "Goloj", + "Score": "Poentoj", + "Survived": "Supervivis", + "Time": "Tempo", + "Time Held": "Tenodaŭro" + }, + "serverResponses": { + "BombSquad Pro unlocked!": "BombSquad Pro malŝlosiĝis!", + "Entering tournament...": "Enirante turniron...", + "Invalid code.": "Nevalida kodo.", + "Invalid promo code.": "Nevalida promocia kodo.", + "Invalid purchase.": "Nevalida aĉeto.", + "Max number of playlists reached.": "Atingiĝis maksimumo da ludlistoj.", + "Max number of profiles reached.": "Atingiĝis maksimumo da profiloj.", + "Purchase successful!": "Aĉeto sukcesa!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Vi ricevis ${COUNT} biletojn por ensaluti.\nRevenu morgaŭ por ricevi ${TOMORROW_COUNT}.", + "The tournament ended before you finished.": "La turniro finiĝis antaŭ ol vi finis.", + "This requires version ${VERSION} or newer.": "Ĉi tio petas version ${VERSION} aŭ pli nova.", + "You already own this!": "Vi jam posedas ĉi tion!", + "You don't have enough tickets for this!": "Vi ne havas sufiĉe da biletoj por ĉi tio!", + "You don't own that.": "Vi ne posedas tion.", + "You got ${COUNT} tickets!": "Vi havas ${COUNT} biletojn!", + "You got a ${ITEM}!": "Vi havas ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Vi promoviĝis al nova ligo; gratulojn!", + "You must wait a few seconds before entering a new code.": "Vi devas atendi kelkajn sekundojn antaŭ ol enigi novan kodon.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Vi rankis #${RANK} en la lasta turniro. Dankon por ludi!", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Via kopio de la ludo adaptiĝis.\nBonvolu reigi ajnajn ŝanĝojn kaj provu denove." + }, + "settingNames": { + "1 Minute": "1 minuto", + "1 Second": "1 sekundo", + "10 Minutes": "10 minutoj", + "2 Minutes": "2 minutoj", + "2 Seconds": "2 sekundoj", + "20 Minutes": "20 minutoj", + "4 Seconds": "4 sekundoj", + "5 Minutes": "5 minutoj", + "8 Seconds": "8 sekundoj", + "Balance Total Lives": "Samigu entutajn vivojn", + "Chosen One Gets Gloves": "La elektita havos glovojn", + "Chosen One Gets Shield": "La elektita havos ŝirmilon", + "Chosen One Time": "Daŭro de la elektita", + "Enable Impact Bombs": "Ebligi ekpafbombojn", + "Enable Triple Bombs": "Ebligi trioblajn bombojn", + "Epic Mode": "Brila modo", + "Flag Idle Return Time": "Reirtempo de senaktiva flago", + "Flag Touch Return Time": "Reirtempo de tuŝita flago", + "Hold Time": "Tenodaŭro", + "Kills to Win Per Player": "Po mortigoj por venki", + "Laps": "Ĉirkaŭiroj", + "Lives Per Player": "Vivoj laŭ ludanto", + "Long": "Longa", + "Longer": "Pli longa", + "Mine Spawning": "Minaj ekaperoj", + "No Mines": "Sen minoj", + "None": "Neniom", + "Normal": "Normala", + "Respawn Times": "Reventempo", + "Score to Win": "Poenti por venki", + "Short": "Mallonga", + "Shorter": "Pli mallonga", + "Solo Mode": "Unuopa modo", + "Target Count": "Kiom da celoj", + "Time Limit": "Templimo" + }, + "statements": { + "Killing ${NAME} for skipping part of the track!": "${NAME} mortas pro nefaro de parto de la trako!" + }, + "teamNames": { + "Bad Guys": "Fiuloj", + "Blue": "Blua", + "Good Guys": "Bonuloj", + "Red": "Ruĝa" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Perfekttempa kur-salt-rotaci-bato povas mortigi en unu bato kaj\ngajnigi al vi eternan respekton de viaj amikoj.", + "Always remember to floss.": "Purigante viajn dentojn, ne forgesu la malfacilajn partojn.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Kreu ludanto-profilojn por vi kaj viaj amikoj kun\nviaj preferataj nomoj kaj aperoj anstataŭ uzi hazardajn.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Malbeno-kestoj ŝanĝas vin en tempobombon.\nLa sola kuracilo estas rapide kapti sanopakaĵon.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Malgraŭ iliaj aspektoj, la ebloj de la roluloj estas tutsamaj,\ndo simple elektu kiun ajn plej similan al vi.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Ne tro atendu de la energiŝirmilo; vi ankoraŭ povas fali de deklivo.", + "Don't run all the time. Really. You will fall off cliffs.": "Ne kuru la tutan tempon. Vere. Vi falos de deklivoj.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Premadu ajnan butonon por kuri. (La malantaŭaj pafbutonoj bone funkcias se vi havas ilin)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Premadu ajnan butonon por kuri. Vi pli rapide atingos\nlokojn sed ne bone turniĝos, do atentu pri deklivoj.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Glacibomboj ne estas tre potencaj, sed ili frostigos\nĉiujn kiujn ili tuŝas, tiel ebligante ke ili dispeciĝu.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Se iu prenas vin, batu al tiu kaj vi povos foriri.\nTio ankaŭ funkcias en la vera vivo.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Se vi havas maltro da regiloj, instalu la aplikaĵon 'BombSquad Remote'\nen viaj iOS-aparatoj kaj Android por uzi ilin kiel regiloj.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Se glubombo ekgluas al vi, eksaltu kaj rotaciadu. Eble vi tiel seniĝos de la bombo\nkaj almenaŭ viaj lastaj momentoj estos amuzaj.", + "If you kill an enemy in one hit you get double points for it.": "Se vi mortigas malamikon tuj unuafoje, vi duoble poentas.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Se vi prenas malbenon, via sola espero por supervivi\nestas trovi sanpakaĵon en la sekvaj sekundetoj.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Se vi restas en unu loko, vi tuj foros. Kuru kaj evitu por travivi..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Se multaj ludantoj venas kaj iras, enŝaltu 'aŭtomate-forigu-neaktivajn-ludantojn'\nsub la agordoj, kaze ke iu forgesas foriri en la ludo.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Se via aparato tro varmiĝas aŭ vi volas konservi baterian potencon,\nmalpliigu \"Vidaĵoj\" aŭ \"Distingivo\" en Agordoj->Grafikaĵoj", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Se la ludo malrapide montras la ekranojn, provu malpliigi\nla distingivon aŭ vidaĵojn en la grafikaĵo-agordoj.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "En Kaptu la flagon, via propra flago devas esti en via bazo por poenti. Se la alia\nteamo preskaŭ poentas, ŝteli ilian flagon povas esti bona maniero haltigi ilin.", + "In hockey, you'll maintain more speed if you turn gradually.": "En hokeo, via rapideco restas pli konstanta se vi laŭgrade turnas.", + "It's easier to win with a friend or two helping.": "Pli facilas venki se unu aŭ du amikoj helpas.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Saltu kiam vi ĵetas por meti bombojn je la plej altajn nivelojn.", + "Land-mines are a good way to stop speedy enemies.": "Minoj estas bona maniero haltigi rapidegajn malamikojn.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Multajn aferojn vi povas preni kaj ĵeti, eĉ aliajn ludantojn. Ĵeti viajn malamikojn\nde deklivo povas esti efika kaj emocie plenuma strategio.", + "No, you can't get up on the ledge. You have to throw bombs.": "Ne, ne eblas suriri la bretojn. Vi devas ĵeti bombojn.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Ludantoj povas aliĝi kaj foriri meze de plej da ludoj,\nkaj vi ankaŭ povas enmeti kaj forigi regilojn dum la ludo.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Ludantoj povas aliĝi kaj foriri meze de plejmulto da ludoj,\nkaj vi ankaŭ povas elpreni kaj aldoni regilojn dum la ludo.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Donacetoj nur havas tempolimojn en kunlaboraj ludoj.\nEn teamaj ludoj kaj Ĉiuj kune vi povas uzi ilin ĝismorte.", + "Practice using your momentum to throw bombs more accurately.": "Trejnu vian movefikon por ĵeti bombojn pli precize.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Batoj pli damaĝas se viaj pugnoj pli rapide moviĝas, do\nprovu kuri, salti kaj rotacii kiel frenezulo.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Kuru tien kaj reen antaŭ ĵeti bombon por\nrotaciadumi ĝin kaj ĵeti pli for.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Forigu grupon da malamikoj metante\nbombon proksime de dinamitujo.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "La kapo estas la plej sentema regiono, do glubombo\nal la okulujo kutime signifas ĝis ĝis.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Ĉi tiu nivelo neniam finiĝas, sed altaj poentoj ĉi tie\ngajnigos al vi eternan respekton tra la mondo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Ĵetoforto estas bazita je la tenata direkto.\nPor ĵeti ion dolĉe antaŭ vi, ne tenu direkton.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Ĉu lacigas vin la sono? Faru mem sontrakojn!\nVidu Agordoj->Aŭdaĵoj->Sontrako", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Provu 'trankviligi' bombojn por unuj du sekundoj antaŭ ol ĵeti ilin.", + "Try tricking enemies into killing eachother or running off cliffs.": "Provu igi viajn malamikojn mortigi unu la alian aŭ kuri de deklivoj.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Uzu la preno-buteno por preni la flagon < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Balancu tien kaj reen por havi pli da distanco en viaj ĵetoj..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Vi povas 'celi' viajn batojn rotaciante maldekstren aŭ dekstren.\nTio utilas por puŝi fiulojn de randoj aŭ por poenti en hokeo.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Vi povas scii kiam bombo eksplodos laŭ la koloro\nde la fajreroj je la drato: flava..oranĝa..ruĝa..BUM.", + "You can throw bombs higher if you jump just before throwing.": "Vi povas ĵeti bombojn pli alten se vi saltas ĝuste antaŭ ĵeti.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Vi damaĝas vin se vi kapbatas kontraŭ aferoj,\ndo provu ne kapbati kontraŭ aferoj.", + "Your punches do much more damage if you are running or spinning.": "Viaj batoj pli damaĝas se vi kuras aŭ rotacias." + } + }, + "trialPeriodEndedText": "Via provperiodo finiĝis. Ĉu vi ŝatus aĉeti\nBombSquad kaj pluludi?", + "trophiesText": "Trofeoj", + "tutorial": { + "cpuBenchmarkText": "Rapidege irante tra la klarigo (precipe por testi la rapidecon de CPU)", + "phrase01Text": "Saluton!", + "phrase02Text": "Bonvenon al ${APP_NAME}!", + "phrase03Text": "Jen kelkaj konsiloj por regi vian rolulon:", + "phrase04Text": "Multaj aferoj en ${APP_NAME} estas bazitaj je FIZIKO.", + "phrase05Text": "Ekzemple, se vi batas,...", + "phrase06Text": "...damaĝo estas bazita je la rapideco de viaj pugnoj.", + "phrase07Text": "Ĉu vi vidis? Ni ne movis, do tio apenaŭ damaĝis al ${NAME}", + "phrase08Text": "Nun ni eksaltu kaj rotaciu por havi pli da rapideco.", + "phrase09Text": "Jen, jam pli bone.", + "phrase10Text": "Kurado ankaŭ helpas.", + "phrase11Text": "Premadu AJNAN butonon por kuri.", + "phrase12Text": "Por pli mojosaj batoj, provu kuri KAJ rotacii.", + "phrase13Text": "Ups; pardonu pri tio ${NAME}.", + "phrase14Text": "Vi povas kapti kaj ĵeti aferojn kiel flagoj.. aŭ ${NAME}.", + "phrase15Text": "Laste, estas bomboj.", + "phrase16Text": "Necesas trejniĝi por ĵeti bombojn.", + "phrase17Text": "Aj! Ne vere bona ĵeto.", + "phrase18Text": "Movi helpas vin ĵeti pli for.", + "phrase19Text": "Saltado helpas vin ĵeti pli alten.", + "phrase20Text": "Rotaciadumu viajn bombojn por eĉ pli longaj ĵetoj.", + "phrase21Text": "Tempumi viajn bombojn povas esti tikla.", + "phrase22Text": "Fek.", + "phrase23Text": "Provu \"trankviligi\" la ŝnuron por unuj du sekundoj.", + "phrase24Text": "Hura! Bone farite.", + "phrase25Text": "Nu, jen pli-malpli ĉio.", + "phrase26Text": "Nun ek al la venk', mojosul'!", + "phrase27Text": "Memoru vian trejnadon, kaj vi JA revenos viva!", + "phrase28Text": "...nu, eble...", + "phrase29Text": "Bonan ŝancon!", + "randomName1Text": "Zamĉjo", + "randomName2Text": "Joĉjo", + "randomName3Text": "Klara", + "randomName4Text": "Ivo", + "randomName5Text": "Osmo", + "skipConfirmText": "Ĉu vi vere volas transsalti la klarigon? Tuŝu aŭ premu por konfirmi.", + "skipVoteCountText": "${COUNT} el ${TOTAL} voĉdonoj por transsalti", + "skippingText": "saltante klarigon...", + "toSkipPressAnythingText": "(tuŝu aŭ premu ion ajn por transsalti klarigon)" + }, + "twoKillText": "DUOBLA MORTIGO!", + "unavailableText": "nehavebla", + "unconfiguredControllerDetectedText": "Detektis nekonfiguritan regilon:", + "unlockThisInTheStoreText": "Ĉi tio devas malŝlosiĝi en la vendejo.", + "unsupportedHardwareText": "Pardonu, ĉi tiu aparato ne estas subtenata de ĉi tiu konstruo de la ludo.", + "upFirstText": "Venos unue:", + "upNextText": "Venos poste en ludo ${COUNT}:", + "updatingAccountText": "Ĝisdatigante vian konton...", + "upgradeText": "Ĝisdatigi", + "upgradeToPlayText": "Malŝlosu \"${PRO}\" en la enluda vendejo por ludi ĉi tion.", + "useDefaultText": "Uzi ekvaloron", + "usesExternalControllerText": "Ĉi tiu ludo uzas eksteran regilon por enigo.", + "usingItunesText": "Uzante iTunes por sontrako...", + "usingItunesTurnRepeatAndShuffleOnText": "Bonvolu certigi ke miksmodo estu AKTIVA kaj ripetmodo je ĈIUJ en iTunes.", + "validatingBetaText": "Validigas betan...", + "validatingTestBuildText": "Kontrolas validecon de testkonstruo...", + "victoryText": "Venko!", + "vsText": "kontraŭ", + "waitingForHostText": "(atendas ${HOST} por pluiri)", + "waitingForLocalPlayersText": "atendante lokajn ludantojn...", + "waitingForPlayersText": "atendas aliĝon de ludantoj...", + "watchAnAdText": "Spekti reklamon", + "watchWindow": { + "deleteConfirmText": "Ĉu forviŝi \"${REPLAY}\"?", + "deleteReplayButtonText": "Forviŝi\nremontron", + "myReplaysText": "Miaj remontroj", + "noReplaySelectedErrorText": "Vi ne selektis remontron", + "renameReplayButtonText": "Renomi\nremontron", + "renameReplayText": "Ŝanĝi nomon de \"${REPLAY}\" al:", + "renameText": "Renomi", + "replayDeleteErrorText": "Eraro forviŝante remontron.", + "replayNameText": "Remontra nomo", + "replayRenameErrorAlreadyExistsText": "Jam ekzistas remontro kun tiu nomo.", + "replayRenameErrorInvalidName": "Ne povas renomi remontron; nomo ne validas.", + "replayRenameErrorText": "Eraro renomante remontron.", + "sharedReplaysText": "Remontroj kun aliaj", + "titleText": "Spekti", + "watchReplayButtonText": "Spekti\nremontron" + }, + "waveText": "Ondo", + "wellSureText": "Nu certe!", + "wiimoteLicenseWindow": { + "titleText": "Kopirajto DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "Aŭskultante por Wii-regiloj...", + "pressText": "Premu la Wii-regilajn butonojn 1 kaj 2 samtempe.", + "pressText2": "En pli novaj Wii-regiloj kun Motion Plus en ili, anstataŭe premu la ruĝan butonon 'sync' dorsflanke." + }, + "wiimoteSetupWindow": { + "copyrightText": "Kopirajto DarwiinRemote", + "listenText": "Aŭskulti", + "macInstructionsText": "Certigu ke via Wii estas malŝaltitia kaj Bludento estas\naktiva en via Makintoŝo, kaj premu 'Aŭskulti'. Wii-regila\nsubteno povas esti iom fuŝa, do foje reprovu kelkfoje\npor ekhavi konekton.\n\nBludento devus subteni ĝis 7 konektitaj aparatoj, sed\nvia sperto povus esti alia.\n\nBombSquad subtenas la originajn Wii-regilojn, Nunchuk\nkaj la klasikan regilon.\nLa pli nova Wii Remote Plus nun ankaŭ funcias\nsed sen etendaĵoj.", + "thanksText": "Dankon al la teamo DarwiinRemote\npor ebligi ĉi tion.", + "titleText": "Agordado de Wii-regilo" + }, + "winsPlayerText": "${NAME} venkas!", + "winsTeamText": "${NAME} venkas!", + "winsText": "${NAME} venkas!", + "worldScoresUnavailableText": "Mondaj poentoj nehaveblas.", + "worldsBestScoresText": "Mondaj plej bonaj poentoj", + "worldsBestTimesText": "Mondaj plej bonaj tempoj", + "xbox360ControllersWindow": { + "getDriverText": "Ekhavi pelilon", + "macInstructions2Text": "Por uzi regilojn sendrate, vi ankaŭ bezonos la ricevilon kiu\nvenas kun 'Xbox 360 Wireless Controller for Windows'.\nUnu ricevilo permesas konekti ĝis 4 regilojn.\n\nGrave: riceviloj de ekstera deveno ne funkcios kun ĉi tiu pelilo;\ncertigu vin ke la ricevilo diras 'Microsoft' kaj ne 'XBOX 360'.\nMicrosoft ne plu vendas ĉi tiujn dise, do vi bezonos ekhavi tiun\nkiu venas kune kun la regilo aŭ serĉi per vendaj retejoj kiel eBay.\n\nSe vi trovas ĉi tion utila, bonvolu konsideri mondonon al la pelila\nprogramisto per lia retejo.", + "macInstructionsText": "Por uzi la regilojn Xbox 360, vi devas instali la pelilon\npor Makintoŝo havebla je la malsupra ligilo.\nĜi funkcias kaj por drataj kaj sendrataj regiloj.", + "ouyaInstructionsText": "Por uzi dratajn regilojn de Xbox 360 kun BombSquad, simple\nkonektu ilin al la USB-eniro de via aparato. Vi povas uzi USB-nabon\npor konekti al pluraj regiloj.\n\nPor uzi sendratajn regilojn, ‎vi bezonas sendratan ricevilon,\nhaveblan kiel parto de la pakaĵo \"Xbox 360 wireless Controller\nfor Windows\" aŭ vendite dise. Ĉiu ricevilo eniras USB-pordon kaj\npermesas al vi konekti ĝis 4 sendratajn regilojn.", + "titleText": "Uzi regilojn de Xbox 360 kun ${APP_NAME}:" + }, + "yesAllowText": "Jes, permesu!", + "yourBestScoresText": "Viaj plej bonaj poentoj", + "yourBestTimesText": "Viaj plej bonaj tempoj" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/filipino.json b/dist/ba_data/data/languages/filipino.json new file mode 100644 index 0000000..1b7d4e8 --- /dev/null +++ b/dist/ba_data/data/languages/filipino.json @@ -0,0 +1,1883 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Marapat na ang pangalan ng account na iyon ay walang mga special characters o mga emoji", + "accountsText": "Mga Account", + "achievementProgressText": "Mga Nakamtan: ${COUNT} sa ${TOTAL}", + "campaignProgressText": "Ang Progreso sa Laro [Mahirap]: ${PROGRESS}", + "changeOncePerSeason": "Mapapalit mo lang ito isa-isa kada season", + "changeOncePerSeasonError": "Kailangan mo muna maghintay ng susunod na season para mapalitan ito. (${NUM} araw)", + "customName": "Custom na Pangalan", + "googlePlayGamesAccountSwitchText": "Kung gusto mong gamitin ang iba ninyong Google Account,\nGumamit ka ng Google Play Games app upang maipalit.", + "linkAccountsEnterCodeText": "Ilagay ang Code", + "linkAccountsGenerateCodeText": "Gumawa ng Code", + "linkAccountsInfoText": "(ibahagi ang pag-usad sa iba't ibang platform)", + "linkAccountsInstructionsNewText": "Para maiugnay ang dalawang accounts, gumawa ka ng code sa una at ilagay \nyung code sa pangalawa. Data na galing sa pangalawang account ay \nmaibabahagi sa dalawa.\n(Data na nasa unang account ay mawawala)\n\nMaari kang magugnay ng hangang ${COUNT} accounts.\n\nIMPORTANTE: Iugnay lamang ang iyong mga accounts, \ndahil kapag iuugnay mo sa kaibigan mo ang iyong \naccount,hindi kayo makakapaglaro ng sabay.", + "linkAccountsInstructionsText": "Para mag-ugnay ng dalawang account, gumawa ng code\nsa isa at ilagay ang code na iyon sa kabila.\nAng iyong pag-usad at imbentaryo ay pagsasamahin.\nMaaari mong i-ugnay hanggang sa ${COUNT} accounts.\n\nBabala lang; hindi na ito maibabalik!", + "linkAccountsText": "Iugnay ang mga Account", + "linkedAccountsText": "Naka-ugnay na mga Account", + "manageAccountText": "I-Manage ang Account", + "nameChangeConfirm": "Baguhin ang pangalan ng iyong account sa ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Ibabalik nito sa dati ang iyong pag-usad,\nat lokal na mga high-score (pwera sa ticket).\nHindi na ito maibabalik pa. Ipagpatuloy pa rin?", + "resetProgressConfirmText": "Ibabalik nito sa dati ang iyong pag-usad,\nmga nakamtan, at lokal na mga high-score\n(pwera sa ticket). Hindi na ito maibabalik\npa. Ipagpatuloy pa rin?", + "resetProgressText": "I-reset ang Progreso", + "setAccountName": "I-set ang Account name", + "setAccountNameDesc": "Piliin ang pangalan na ipapakita para sa iyong account.\nMaaari mong gamitin ang pangalan mula sa isa sa iyong mga naka-link \nna account o lumikha ng isang natatanging pasadyang pangalan.", + "signInInfoText": "Magsign-in para kumolekta ng mga ticket, makipagkompetensya online,\nat makabahagi ng pag-usad sa iba't ibang mga device.", + "signInText": "Mag-sign in", + "signInWithDeviceInfoText": "(isang automatic account na magagamit lamang sa device na ito)", + "signInWithDeviceText": "Mag-sign in gamit ang device", + "signInWithGameCircleText": "Magsign-in gamit ang Game Circle", + "signInWithGooglePlayText": "Magsign-in gamit ang Google Play", + "signInWithTestAccountInfoText": "(uri ng legacy account; gamitin ang mga account ng device na pasulong)", + "signInWithTestAccountText": "Magsign in gamit ang test account", + "signInWithV2InfoText": "(ang account na gumagana sa lahat na platforms)", + "signInWithV2Text": "Mag sign in gamit ang BombSquad account", + "signOutText": "Mag-sign out", + "signingInText": "Nagsasign-in...", + "signingOutText": "Nagsasign-out...", + "ticketsText": "Mga ticket: ${COUNT}", + "titleText": "Account", + "unlinkAccountsInstructionsText": "Pumili ng account na i-uunlink", + "unlinkAccountsText": "I-unlink ang mga accounts", + "unlinkLegacyV1AccountsText": "I-unlink ang mga Legacy (V1) Account", + "v2LinkInstructionsText": "Gamitin ang link na ito para gumawa ng account o mag sign in.", + "viaAccount": "(sa pamamagitan ng account ${NAME})", + "youAreSignedInAsText": "Nakasign-in ka bilang:" + }, + "achievementChallengesText": "Mga nakamit", + "achievementText": "Mga Nakamtan", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Mapasabog ang 3 kalaban gamit ang TNT", + "descriptionComplete": "Napasabog ang 3 kalaban gamit ang TNT", + "descriptionFull": "Mapasabog ang 3 kalaban gamit ang TNT sa ${LEVEL}", + "descriptionFullComplete": "Napasabog ang 3 kalabangamit ang TNT sa ${LEVEL}", + "name": "Sabog ang Sabi ng Dinamita" + }, + "Boxer": { + "description": "Manalo sa laro ng hindi gumagamit ng bomba", + "descriptionComplete": "Nanalo sa laro ng hindi gumagamit ng bomba", + "descriptionFull": "Tapusin ang ${LEVEL} na walang gamit na bomba", + "descriptionFullComplete": "Natapos ang ${LEVEL} na himdi gumagamit ng bomba", + "name": "Boksingero" + }, + "Dual Wielding": { + "descriptionFull": "Ikonekta ang 2 controllers (hardware o app)", + "descriptionFullComplete": "Konektado ang 2 controllers (hardware o app)", + "name": "Dalawang Nangalaro" + }, + "Flawless Victory": { + "description": "Manalo nang hindi natatamaan", + "descriptionComplete": "Nanalo nang hindi natamaan", + "descriptionFull": "Manalo sa ${LEVEL} nang hindi makakakuha ng hit", + "descriptionFullComplete": "Nanalo sa ${LEVEL} nang hindi nakakakuha ng hit", + "name": "‘Di Mintis Na Pagtagumpay" + }, + "Free Loader": { + "descriptionFull": "Magsimula ng isang Awayang Rambulan na may 2+ manlalaro", + "descriptionFullComplete": "Nagsimula ang isang Free-For-All na may 2+ manlalaro", + "name": "Manggagamit" + }, + "Gold Miner": { + "description": "Pumatay Ng 6 na kalaban gamit ang mga land-mine", + "descriptionComplete": "Pumatay ng 6 na kalaban gamit ang mga land-mine", + "descriptionFull": "Pumatay ng 6 na kalaban gamit ang mga land -mine sa ${LEVEL}", + "descriptionFullComplete": "Nakapatay ng 6 na kalaban gamit ang mga land-mine sa ${LEVEL}", + "name": "Minahang Lagayan" + }, + "Got the Moves": { + "description": "Manalo ng ‘di sumusuntok o gumagamit ng mga bomba", + "descriptionComplete": "Nanalo ng ‘di sumusuntok o gumagamit ng bomba", + "descriptionFull": "Manalo sa ${LEVEL} ng ‘di sumusuntok o gumagamit ng bomba", + "descriptionFullComplete": "Nanalo sa ${LEVEL} ng ‘di sumusuntok o gumagamit ng bomba", + "name": "May Galaw" + }, + "In Control": { + "descriptionFull": "Magconnect ng controller (hardware o app)", + "descriptionFullComplete": "Nagconnect ng controller (hardware o app)", + "name": "Kumokontrol" + }, + "Last Stand God": { + "description": "Maka-iskor ng 1000 na puntos", + "descriptionComplete": "Naka-iskor ng 1000 na puntos", + "descriptionFull": "Naka-iskor ng 1000 na puntos sa ${LEVEL}", + "descriptionFullComplete": "Naka-iskor ng 1000 na puntos sa ${LEVEL}", + "name": "Bathala ng ${LEVEL}" + }, + "Last Stand Master": { + "description": "Naka-iskor ng 250 na puntos", + "descriptionComplete": "Naka-iskor ng 250 na puntos", + "descriptionFull": "Maka-iskor ng 250 na puntos sa ${LEVEL}", + "descriptionFullComplete": "Naka-iskor ng 250 na puntos sa ${LEVEL}", + "name": "Pinuno ng ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Maka-iskor ng 500 na puntos", + "descriptionComplete": "Naka-iskor ng 500 na puntos", + "descriptionFull": "Maka-iskor ng 500 na puntos sa ${LEVEL}", + "descriptionFullComplete": "Naka-iskor ng 500 na puntos sa ${LEVEL}", + "name": "Salamangkero ng ${LEVEL}" + }, + "Mine Games": { + "description": "Pumatay ng 3 kalaban gamit ang land-mine", + "descriptionComplete": "Nakatay ng 3 kalaban gamit ang land-mine", + "descriptionFull": "Pumatay ng 3 kalaban gamit ang land-mine sa ${LEVEL}", + "descriptionFullComplete": "Nakapatay ng 3 kalaban gamit ang land-mine sa ${LEVEL}", + "name": "Laro ng mga mina" + }, + "Off You Go Then": { + "description": "Maghagis ng 3 kalaban palabas sa mapa", + "descriptionComplete": "Nakapaghagis ng 3 kalaban palabas ng mapa", + "descriptionFull": "Maghagis ng 3 kalaban palabas ng mapa sa ${LEVEL}", + "descriptionFullComplete": "Nakapaghagis ng 3 kalaban palabas ng mapa sa ${LEVEL}", + "name": "Lumayas Ka Dito" + }, + "Onslaught God": { + "description": "Maka-iskor ng 5000 na puntos", + "descriptionComplete": "Naka-iskor ng 5000 na puntos", + "descriptionFull": "Maka-iskor ng 5000 na puntos sa ${LEVEL}", + "descriptionFullComplete": "Naka-iskor ng 5000 na puntos sa ${LEVEL}", + "name": "Bathala ng ${LEVEL}" + }, + "Onslaught Master": { + "description": "Maka-iskor ng 500 na puntos", + "descriptionComplete": "Naka-iskor ng 500 na puntos", + "descriptionFull": "Maka-iskor ng 500 na puntos sa ${LEVEL}", + "descriptionFullComplete": "Naka-iskor ng 500 na puntos sa ${LEVEL}", + "name": "Pinuno ng ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Talunin lahat ng kalaban", + "descriptionComplete": "Natalo lahat ng kalaban", + "descriptionFull": "Talunin lahat ng kalaban sa ${LEVEL}", + "descriptionFullComplete": "Natalo lahat ng kalaban sa ${LEVEL}", + "name": "Kampeon ng ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Maka-iskor ng 1000 na puntos", + "descriptionComplete": "Naka-iskor ng 1000 na puntos", + "descriptionFull": "Maka-iskor ng 1000 na puntos sa ${LEVEL}", + "descriptionFullComplete": "Naka-iskor ng 1000 na puntos sa ${LEVEL}", + "name": "Salamangkero ng ${LEVEL}" + }, + "Precision Bombing": { + "description": "Manalo ng walang kahit anong pampalakas", + "descriptionComplete": "Nanalo ng walang kahit anong powerups", + "descriptionFull": "Manalo sa ${LEVEL} ng walang kahit anong pampalakas", + "descriptionFullComplete": "Manalo sa ${LEVEL} ng walang kahit anong pampalakas", + "name": "Talas sa Pagpapasabog" + }, + "Pro Boxer": { + "description": "Manalo ng di gumagamit ng Bomba", + "descriptionComplete": "Nanalo ng di gumagamit ng bomba", + "descriptionFull": "Manalo sa ${LEVEL} ng di gumagamit ng bomba", + "descriptionFullComplete": "Nanalo sa ${LEVEL} ng gumagamit ng bomba", + "name": "Bihasang Boksingero" + }, + "Pro Football Shutout": { + "description": "Manalo ng walang puntos ang kalaban", + "descriptionComplete": "Nanalo ng walang puntos ang kalaban", + "descriptionFull": "Manalo sa ${LEVEL} ng walang puntos ang kalaban", + "descriptionFullComplete": "Nanalo sa ${LEVEL} ng walang puntos ang kalaban", + "name": "Pagsarhan ng ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Panalunin ang laro", + "descriptionComplete": "Manalo sa laro", + "descriptionFull": "Manalo sa laro sa ${LEVEL}", + "descriptionFullComplete": "Nanalo sa laro sa ${LEVEL}", + "name": "Kampeon ng ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Matalo lahat ng mga kaway", + "descriptionComplete": "Natalo lahat ng mga kaway", + "descriptionFull": "Matalo lahat ng mga kaway sa ${LEVEL}", + "descriptionFullComplete": "Natalo lahat ng mga kaway sa ${LEVEL}", + "name": "Kampeon ng ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Tapusin lahat ng mga kaway", + "descriptionComplete": "Natapos lahat ng mga kaway", + "descriptionFull": "Tapusin ang lahat ng mg kaway sa ${LEVEL}", + "descriptionFullComplete": "Tinapos lahat ng mga kaway sa ${LEVEL}", + "name": "Kampeon ng ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Manalo nang hindi hinahayaang makapuntos ang kalaban", + "descriptionComplete": "Nanalo nang hindi hinahayaang makapuntos ang kalaban", + "descriptionFull": "Manalo sa ${LEVEL} nang hindi hinahayaang makapuntos ang kalaban", + "descriptionFullComplete": "Nanalo sa ${LEVEL} nang hindi hinahayaang makapuntos ang kalaban", + "name": "Pagsarhan ng ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Ipanalo ang laro", + "descriptionComplete": "Naipanalo ang laro", + "descriptionFull": "Panalunin ang laro sa ${LEVEL}", + "descriptionFullComplete": "Pinanalo ang laro sa ${LEVEL}", + "name": "Nanalo sa ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Italo lahat ang mga kaway", + "descriptionComplete": "Natalo lahat ang mga kaway", + "descriptionFull": "Italo lahat ang mga kaway sa ${LEVEL}", + "descriptionFullComplete": "Natalo lahat ng mga kaway sa ${LEVEL}", + "name": "Nanalo sa ${LEVEL}" + }, + "Runaround God": { + "description": "Maka-iskor ng 2000 na Puntos", + "descriptionComplete": "Naka-iskor ng 2000 na puntos", + "descriptionFull": "Maka-iskor ng 2000 na puntos sa ${LEVEL}", + "descriptionFullComplete": "Naka-iskorng 2000 na puntos sa ${LEVEL}", + "name": "${LEVEL} Panginoon" + }, + "Runaround Master": { + "description": "Pumuntos ng 500", + "descriptionComplete": "Nakapuntos ng 500", + "descriptionFull": "Pumuntos ng 500 sa ${LEVEL}", + "descriptionFullComplete": "Nakakuha ng 500 puntos sa ${LEVEL}", + "name": "Pinuno ng ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Pumuntos ng 1000", + "descriptionComplete": "Naka score ng 1000 points", + "descriptionFull": "Mag score ng 1000 points sa ${LEVEL}", + "descriptionFullComplete": "Naka score ng 1000 points sa ${LEVEL}", + "name": "Salamangkero ng ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "I-share ang game sa iyong kaibigan", + "descriptionFullComplete": "Natapos na ang pag share sa game sa iyong kaibigan", + "name": "Ang pagbigay ay pag-alaga" + }, + "Stayin' Alive": { + "description": "Manalo nang hindi namatay", + "descriptionComplete": "Nanalo nang hindi namatay", + "descriptionFull": "Nanalo ${LEVEL} nang hindi namatay", + "descriptionFullComplete": "Nanalo sa ${LEVEL} nang hindi namatay", + "name": "Manatiling Buhay" + }, + "Super Mega Punch": { + "description": "Magdulot ng 100% damage sa isang suntok", + "descriptionComplete": "Nagdulot ng 100% damage sa isang suntok", + "descriptionFull": "Magdulot ng 100% damage ng isang suntok sa ${LEVEL}", + "descriptionFullComplete": "Nagdulot ng 100% damage sa isang suntok sa ${LEVEL}", + "name": "Sobrang Mega Na Suntok" + }, + "Super Punch": { + "description": "Magdulot ng 50% damage sa isang suntok", + "descriptionComplete": "Nagdulot ng 50% damage sa isang suntok", + "descriptionFull": "Magdulot ng 50% damage sa isang suntok sa ${LEVEL}", + "descriptionFullComplete": "Nagdulot ng 50% damage sa isang suntok sa ${LEVEL}", + "name": "Sobrang Suntok" + }, + "TNT Terror": { + "description": "Pumatay ng 6 na kalaban gamit ang TNT", + "descriptionComplete": "Pinatay ng 6 na kalaban gamit ang TNT", + "descriptionFull": "Pumatay ng 6 na kalaban gamit ang TNT sa ${LEVEL}", + "descriptionFullComplete": "Pinatay ng 6 na kalaban gamit ang TNT sa ${LEVEL}", + "name": "Takutan ng TNT" + }, + "Team Player": { + "descriptionFull": "Magsimula ng laro na mayroong 4+ na manlalaro", + "descriptionFullComplete": "Nagsimula ng laro na mayroong 4+ na manlalaro", + "name": "Manlalaro Ng Koponan" + }, + "The Great Wall": { + "description": "Itigil ang bawat kalaban", + "descriptionComplete": "Pinigilan ang bawat kalaban", + "descriptionFull": "Itigil ang bawat kalaban sa ${LEVEL}", + "descriptionFullComplete": "Pinigilan ang bawat kalaban sa ${LEVEL}", + "name": "Ang Malaking Pader" + }, + "The Wall": { + "description": "Itigil ang bawat kalaban", + "descriptionComplete": "Pinigilan ang bawat kalaban", + "descriptionFull": "Itigil ang bawat kalaban sa ${LEVEL}", + "descriptionFullComplete": "Pinigilan ang bawat kalaban sa ${LEVEL}", + "name": "Ang Pader" + }, + "Uber Football Shutout": { + "description": "Manalo nang hindi maka puntos ang mga kalaban", + "descriptionComplete": "Manalo nang hindi maka puntos ang mga kalaban", + "descriptionFull": "Manalo sa ${LEVEL} na hindi maka puntos ang mga kalaban", + "descriptionFullComplete": "Manalo sa ${LEVEL} na hindi maka puntos ang mga kalaban", + "name": "Pagsarhan ng ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Ipanalo ang laro", + "descriptionComplete": "Nanalo ang laro", + "descriptionFull": "I-panalo ang laro sa ${LEVEL}", + "descriptionFullComplete": "Manalo ang laro sa ${LEVEL}", + "name": "${LEVEL} Natagumpay" + }, + "Uber Onslaught Victory": { + "description": "Talunin ang lahat na mga kaway", + "descriptionComplete": "Natalo ang lahat na mga kaway", + "descriptionFull": "Talunin ang lahat na mga kaway sa ${LEVEL}", + "descriptionFullComplete": "Natalo ang lahat na mga kaway sa ${LEVEL}", + "name": "Nanalo sa ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Tapusin ang lahat na kaway", + "descriptionComplete": "Natapos ang lahat na mga kaway", + "descriptionFull": "Tapusin ang lahat na mga kaway sa ${LEVEL}", + "descriptionFullComplete": "Natapos ang lahat na mga kaway sa ${LEVEL}", + "name": "${LEVEL} Natagumpay" + } + }, + "achievementsRemainingText": "Ang Mga Natitirang Nakamtan:", + "achievementsText": "Achievements", + "achievementsUnavailableForOldSeasonsText": "Pasensya na, hindi available ang mga detalye ng achievements para sa mga lumang seasons.", + "activatedText": "Na-aktibo ang ${THING}.", + "addGameWindow": { + "getMoreGamesText": "Kukuha ng higit pang mga laro…", + "titleText": "Magdagdag Ng Laro" + }, + "allowText": "Payagan", + "alreadySignedInText": "Ang iyong account ay naka-sign in mula sa isa pang device;\nMangyaring lumipat ng mga accounts o isara ang laro sa iyong\niba pang mga device at subukan muli.", + "apiVersionErrorText": "Hindi ma-load ang module ${NAME}; naka-target ang api-version ${VERSION_USED}; kailangan namin ${VERSION_REQUIRED}", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(Lalabas ang “Auto” ng ito kapag nakasaksak ang headphones)", + "headRelativeVRAudioText": "Head-Relative VR Audio", + "musicVolumeText": "Volume ng Musika", + "soundVolumeText": "Lakas ng Tunog", + "soundtrackButtonText": "Mga Soundtrack", + "soundtrackDescriptionText": "(I-assign ang iyong sariling musika para magtugtug kapag naglalaro)", + "titleText": "Audio" + }, + "autoText": "Auto", + "backText": "Bumalik", + "banThisPlayerText": "I-ban ang Manlalarong Ito", + "bestOfFinalText": "Pinakamahusay-sa-${COUNT} Final", + "bestOfSeriesText": "Pinakamahusay sa ${COUNT} series:", + "bestOfUseFirstToInstead": 0, + "bestRankText": "Ang iyong pinakamahusay ay #${RANK}", + "bestRatingText": "Ang iyong pinakamahusay na rating ay ${RATING}", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Palakasin", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} naka-configure ito sa mismong app.", + "buttonText": "pindutan", + "canWeDebugText": "Gusto mo ba na ang BombSquad ay automatic na mag report ng\nbugs, crashes, at mga basic usage na info na i-sent sa developer?\n\nHindi ito naglalaman ng mga personal information at makatulong ito\npara ang laro ay gumagana at bug-free.", + "cancelText": "Kanselahin", + "cantConfigureDeviceText": "Pasensya na, ang ${DEVICE} na ito ay hindi ma-configure.", + "challengeEndedText": "Natapos na ang challenge na ito.", + "chatMuteText": "I-mute ang Chat", + "chatMutedText": "Na-mute ang Chat", + "chatUnMuteText": "I-unmute ang Chat", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "I complete mo muna\nang level na ito bago ka mag-proceed!", + "completionBonusText": "Bonus sa Pagkumpleto nito:", + "configControllersWindow": { + "configureControllersText": "I-configure ang mga Controller", + "configureKeyboard2Text": "I-configure ang Keyboard sa P2", + "configureKeyboardText": "I-configure ang Keyboard", + "configureMobileText": "Mobile Devices bilang Controllers", + "configureTouchText": "I-configure ang Touchscreen", + "ps3Text": "PS3 Controllers", + "titleText": "Mga Controller", + "wiimotesText": "Wiimotes", + "xbox360Text": "Xbox 360 Controllers" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Tandaan: nag-iiba-iba ang suporta sa controller sa mga devices at bersyon ng Andriod.", + "pressAnyButtonText": "Pindutin ang anumang button sa controller\nna gusto mong i-configure…", + "titleText": "I-configure ang mga Controller" + }, + "configGamepadWindow": { + "advancedText": "Advanced", + "advancedTitleText": "Advanced na Setup ng Controller", + "analogStickDeadZoneDescriptionText": "(itaas ito kapag ang iyong karakter ay nag ‘d-drift’ kapag binitawan mo ang stick)", + "analogStickDeadZoneText": "Analog Stick Dead Zone", + "appliesToAllText": "(nalalapat sa lahat ng controller ng ganitong uri)", + "autoRecalibrateDescriptionText": "(paganahin ito kung ang iyong karakter ay hindi gumagalaw ng buong bilis)", + "autoRecalibrateText": "Auto-Recalibrate Analog Stick", + "axisText": "aksis", + "clearText": "alisin", + "dpadText": "dpad", + "extraStartButtonText": "Extra na Start Button", + "ifNothingHappensTryAnalogText": "Kapag walang gumagana, i-try na i-assign sa analog stick.", + "ifNothingHappensTryDpadText": "Kapag hindi gumana, i-try na i-assign sa d-pad.", + "ignoreCompletelyDescriptionText": "(pigilan ang controller na ito na maapektuhan ang alinman sa laro o mga menu)", + "ignoreCompletelyText": "Huwag Pansinin", + "ignoredButton1Text": "Pindutan Na ‘Di Pansinin 1", + "ignoredButton2Text": "Pindutan Na ‘Di Pansinin 2", + "ignoredButton3Text": "Pindutan Na ‘Di Pansinin 3", + "ignoredButton4Text": "Pindutan Na ‘Di Pansinin 4", + "ignoredButtonDescriptionText": "(gamitin ito para ma-prevent ang ‘home’ o ‘sync’ buttons na nakakaapekto sa UI)", + "pressAnyAnalogTriggerText": "Pindutin ang anumang analog trigger…", + "pressAnyButtonOrDpadText": "Pindutin ang anumang pindutan o dpad…", + "pressAnyButtonText": "Pindutin ang anumang pindutan…", + "pressLeftRightText": "Pindutin ang left o right…", + "pressUpDownText": "Pindutin ang up o down…", + "runButton1Text": "Run Button 1", + "runButton2Text": "Run Button 2", + "runTrigger1Text": "Run Trigger 1", + "runTrigger2Text": "Run Trigger 2", + "runTriggerDescriptionText": "(ang analog triggers ay pwede ka makatakbo sa mabilisang speeds)", + "secondHalfText": "Gamitin ito para i-configure ang pangalawang kalahati \nng 2-controllers-sa-1 device na \nnagpapakita ng iisang controller.", + "secondaryEnableText": "Paganahin", + "secondaryText": "Pangalawang Controller", + "startButtonActivatesDefaultDescriptionText": "(i-off ito kung ang iyong start button ay higit pa sa isang ‘menu’ button)", + "startButtonActivatesDefaultText": "Start Button Activates Defualt Widget", + "titleText": "Setup ng Controller", + "twoInOneSetupText": "2-in-1 na Setup ng Controller", + "uiOnlyDescriptionText": "(pigilan ang controller na ito mula sa aktwal na pagsali sa isang laro)", + "uiOnlyText": "I-limit ito para lang sa Menu Use", + "unassignedButtonsRunText": "Tumatakbo ang Lahat ng Hindi Nakatalagang Pindutan", + "unsetText": "", + "vrReorientButtonText": "VR Reorient Button" + }, + "configKeyboardWindow": { + "configuringText": "Nag-configure ${DEVICE}", + "keyboard2NoteText": "Tandaan: karamihan sa mga keyboard ay maaari lamang magrehistro ng ilang mga keypress sa\nminsan, kaya ang pagkakaroon ng pangalawang keyboard player ay maaaring gumana nang mas mahusay\nkung may nakadikit na hiwalay na keyboard para magamit nila.\nTandaan na kakailanganin mo pa ring magtalaga ng mga natatanging key sa\ndalawang manlalaro kahit na sa kasong iyon." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Aksyon Control Scale", + "actionsText": "Mga aksyon", + "buttonsText": "buttons", + "dragControlsText": "< i-drag ang mga kontrol upang muling iposisyon ang mga ito >", + "joystickText": "joystick", + "movementControlScaleText": "Sukat ng Kontrol ng Paggalaw", + "movementText": "Paggalaw", + "resetText": "I-reset", + "swipeControlsHiddenText": "Itago ang mga Swipe Icon", + "swipeInfoText": "Ang mga kontrol sa pag-swipe ay medyo nasanay ngunit\ngawing mas madali ang paglalaro nang hindi tumitingin sa mga kontrol.", + "swipeText": "mag-swipe", + "titleText": "I-configure ang Touchscreen" + }, + "configureItNowText": "I-configure ngayon?", + "configureText": "Configure", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Para sa pinakamahusay na mga resulta, kakailanganin mo ng isang lag-free na wifi network. Kaya mo\nbawasan ang wifi lag sa pamamagitan ng pag-off ng iba pang mga wireless na device, sa pamamagitan ng\nnaglalaro malapit sa iyong wifi router, at sa pamamagitan ng pagkonekta sa\ndirektang host ng laro sa network sa pamamagitan ng ethernet.", + "explanationText": "Para gumamit ng smart-phone o tablet bilang wireless controller,\ni-install ang \"${REMOTE_APP_NAME}\" na app dito. Anumang bilang ng mga device\nmaaaring kumonekta sa isang larong ${APP_NAME} sa Wi-Fi, at libre ito!", + "forAndroidText": "para sa Andriod:", + "forIOSText": "para sa iOS:", + "getItForText": "Kumuha ng ${REMOTE_APP_NAME} para sa iOS sa Apple App Store\no para sa Android sa Google Play Store o Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Paggamit ng Mga Mobile Device bilang Mga Controller:" + }, + "continuePurchaseText": "Magpatuloy sa halagang ${PRICE}?", + "continueText": "Magpatuloy", + "controlsText": "Mga Kontrol", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Hindi ito nag a-apply sa all-time rankings.", + "activenessInfoText": "Ang multiplier na ito ay tumataas sa mga araw kung kailan ka\nmaglaro at bumaba sa mga araw na hindi mo ginagawa.", + "activityText": "Aktibidad", + "campaignText": "Kampanya", + "challengesInfoText": "Makakuha ng mga premyo para sa pagkumpleto ng mga mini-game.\n\nAng mga premyo at antas ng kahirapan ay tumataas\nsa bawat oras na ang isang hamon ay nakumpleto at\nbumaba kapag ang isa ay nag-expire o na-forfeit.", + "challengesText": "Mga Challenges", + "currentBestText": "Kasalukuyang Pinakamahusay", + "customText": "Kustom", + "entryFeeText": "Pasok", + "forfeitConfirmText": "Isuko ang hamon na ito?", + "forfeitNotAllowedYetText": "Ang hamon na ito ay hindi pa maaaring mawala.", + "forfeitText": "Forfeit", + "multipliersText": "Mga multiplier", + "nextChallengeText": "Susunod na Challenge", + "nextPlayText": "Susunod na Play", + "ofTotalTimeText": "ng ${TOTAL}", + "playNowText": "Maglaro Ngayon", + "pointsText": "Puntos", + "powerRankingFinishedSeasonUnrankedText": "(tapos na season walang ranggo", + "powerRankingNotInTopText": "(hindi sa taas ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} pts)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} sa ${REMAINING} pts)", + "powerRankingText": "Kakayahang Ranggo", + "prizesText": "Premyo", + "proMultInfoText": "Ang manlalaro na may ${PRO} pagtaas\nay tumanggap na ${PERCENT}% dagdag puntos dito.", + "seeMoreText": "Tingnan pa...", + "skipWaitText": "Lagktawang Paghintay", + "timeRemainingText": "Natitirang Oras", + "toRankedText": "Sagad Sa Ranggo", + "totalText": "kabuuan", + "tournamentInfoText": "Makipagkumpitensya para sa matataas na marka sa\nibang mga manlalaro sa iyong liga.\n\nAng mga premyo ay iginagawad sa pinakamataas na iskor\nmga manlalaro kapag nag-expire ang oras ng tournament.", + "welcome1Text": "Maligayang pagdating sa ${LEAGUE}. Maaari mong pagbutihin ang iyong\nranggo ng liga sa pamamagitan ng pagkamit ng mga star rating, pagkumpleto\nmga tagumpay, at panalong tropeo sa mga paligsahan.", + "welcome2Text": "Maaari ka ring makakuha ng mga tiket mula sa marami sa parehong mga aktibidad.\nMaaaring gamitin ang mga tiket para i-unlock ang mga bagong character, mapa, at\nmini-games, para makapasok sa mga tournament, at higit pa.", + "yourPowerRankingText": "Iyong Power Ranking:" + }, + "copyConfirmText": "Nakopya sa clipboard.", + "copyOfText": "Kopya ng ${NAME}", + "copyText": "I-kopya", + "createEditPlayerText": "", + "createText": "Gumawa", + "creditsWindow": { + "additionalAudioArtIdeasText": "Adisyonal Audio, Agang Artwork, Ideya ni ${NAME}", + "additionalMusicFromText": "Adisyonal musika galing kay ${NAME}", + "allMyFamilyText": "Lahat sa aking kaibigan at pamilya ko na tumulong sa play test", + "codingGraphicsAudioText": "Coding, Graphics, at Audio ni ${NAME}", + "languageTranslationsText": "Pagsasalin Ng Wika:", + "legalText": "Ligal:", + "publicDomainMusicViaText": "Public-domain music mula sa ${NAME}", + "softwareBasedOnText": "Ang software na ito ay batay sa bahagi ng gawain ng ${NAME}", + "songCreditText": "${TITLE} Ginawa ni ${PERFORMER}\nBinubuo ni ${COMPOSER}, Inayos ni ${ARRANGER}, Na-publish ni ${PUBLISHER},\nSa kagandahang-loob ng ${SOURCE}", + "soundAndMusicText": "Tunog at Musika", + "soundsText": "Mga Tunog (${SOURCE}):", + "specialThanksText": "Espesyal Na Pasasalamat:", + "thanksEspeciallyToText": "Salamat, lalo na kay ${NAME}", + "titleText": "${APP_NAME} Mga Kredito", + "whoeverInventedCoffeeText": "At ang sino man na nag-imbento ng kape" + }, + "currentStandingText": "Ang kasalukuyang tayo mo ay #${RANK}", + "customizeText": "I-customize...", + "deathsTallyText": "${COUNT} pagkamatay", + "deathsText": "Pagkamatay", + "debugText": "debug", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Pakiusap: pwedeng inirerekomenda na itakda mo ang Settings->Graphics->Texture sa 'Mataas' habang isinusuri nito", + "runCPUBenchmarkText": "I-takbo ang CPU Benchmark", + "runGPUBenchmarkText": "I-takbo ang GPU Benchmark", + "runMediaReloadBenchmarkText": "I-takbo ang Media-Reload Benchmark", + "runStressTestText": "I-takbo ang stress test", + "stressTestPlayerCountText": "Bilang Ng Manlalaro", + "stressTestPlaylistDescriptionText": "Stress Test Playlist", + "stressTestPlaylistNameText": "Pangalan Ng Playlist", + "stressTestPlaylistTypeText": "Playlist Type", + "stressTestRoundDurationText": "Pagtagal Ng Round", + "stressTestTitleText": "Stress Test", + "titleText": "Benchmarks at Stress Test", + "totalReloadTimeText": "Kabuuang reload time: ${TIME} (tingnan Ang log para sa mga detalye)" + }, + "defaultGameListNameText": "Default ${PLAYMODE} Playlist", + "defaultNewGameListNameText": "Ang aking ${PLAYMODE} Playlist", + "deleteText": "Tanggalin", + "demoText": "Demo", + "denyText": "Tanggihan", + "deprecatedText": "Hindi Na Uso", + "desktopResText": "Desktop Res", + "deviceAccountUpgradeText": "Babala:\nNaka-sign in ka gamit ang isang device account (${NAME}).\nMawawala na yan sa kinakabukasang update.\nMag-upgrade sa isang V2 Account kung gusto mong panatilihin ang iyong pag-unlad.", + "difficultyEasyText": "Madali", + "difficultyHardOnlyText": "Mahirap Na Mode Lang", + "difficultyHardText": "Mahirap", + "difficultyHardUnlockOnlyText": "Itong level na ito ay naka-unlock sa Mahirap na mode lang.\nSa tingin mo ba mayroong ano ang kinakailangan!?!?!", + "directBrowserToURLText": "Mangyaring idirekta Ang isang web-browser sa sumusunod na URL:", + "disableRemoteAppConnectionsText": "I-disable Ang Mga Remote-App Na Konekyson", + "disableXInputDescriptionText": "Pumayag ng higit sa 4 na controllers ngunit maaaring hindi mabuti ang kalagay", + "disableXInputText": "Disable XInput", + "doneText": "Tapos", + "drawText": "Patas", + "duplicateText": "I-duplicate", + "editGameListWindow": { + "addGameText": "Idagdag na\nLaro", + "cantOverwriteDefaultText": "Hindi ma-overwrite ang default playlist!", + "cantSaveAlreadyExistsText": "Isang playlist na may ganyang pangalan na!", + "cantSaveEmptyListText": "Hindi ma-save ang walang laman na playlist!", + "editGameText": "I-Edit ang\nLaro", + "listNameText": "Pangalan Ng Playlist", + "nameText": "Pangalan", + "removeGameText": "Tanggalin ang\nLaro", + "saveText": "I-save Ang Listahan", + "titleText": "Editor Ng Playlist" + }, + "editProfileWindow": { + "accountProfileInfoText": "Itong espesyal na profile ay may\npangalan at icon batay sa iyong account.\n\n${ICONS}\n\nGumawa ng custom na profile para gamitin ng \nmagkaibang pangalan o custom icons.", + "accountProfileText": "(account profile)", + "availableText": "Ang pangalang \"${NAME}” na ito ay maari mong gamitin pang-icon", + "characterText": "karakter", + "checkingAvailabilityText": "Titignan ko kung maaari mo gamitin ang \"${NAME}\"...", + "colorText": "kulay", + "getMoreCharactersText": "Kumuha Ka Pang Mga Karakter...", + "getMoreIconsText": "Kumuha Ka Pang Mga Icons...", + "globalProfileInfoText": "Golbal player profiles ay garantisadong magkaroon ng unique na pangalan worldwide.\nNa-include nila rin ang custom icons.", + "globalProfileText": "(global na profile)", + "highlightText": "highlight", + "iconText": "Mga icon", + "localProfileInfoText": "Ang mga profile Ng lokal na manlalaro ay walang mga icon at ang kanilang mga \npangalan ay hindi garantisadong unique. I-upgrade para maging isang global \nprofile at ma-reserve ng isang unique na pangalan at ma-add ng custom icon.", + "localProfileText": "(lokal na profile)", + "nameDescriptionText": "Pangalan Ng Manlalaro", + "nameText": "Pangalan", + "randomText": "random", + "titleEditText": "I-Edit Ang Profile", + "titleNewText": "Bagong Profile", + "unavailableText": "hindi available ang \"${NAME}\"; sumubok ng ibang pangalan", + "upgradeProfileInfoText": "Irereserba nito ang pangalan ng iyong manlalaro sa buong mundo\nat nagbibigay-daan sa iyong magtalaga ng custom na icon dito.", + "upgradeToGlobalProfileText": "Upgrade sa Global na Profile" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Hindi mo maitanggal Ang default soundtrack", + "cantEditDefaultText": "Hindi ma-edit ang default soundtrack. I-duplicate mo o gumawa Ng bago", + "cantOverwriteDefaultText": "Hindi ma-overwrite ang default soundtrack", + "cantSaveAlreadyExistsText": "Isang soundtrack na may ganyang pangalan na!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Default na Soundtrack", + "deleteConfirmText": "Itanggal Ang Soundtrack:\n\n'${NAME}'?", + "deleteText": "I-delete Ang\nSoundtrack", + "duplicateText": "I-duplicate Ang\nSoundtrack", + "editSoundtrackText": "Editor Ng Soundtrack", + "editText": "I-edit Ang\nSoundtrack", + "fetchingITunesText": "kumuha ng Music App playlists...", + "musicVolumeZeroWarning": "Paunawa: Ang volume ng musika ay nakatakda sa 0", + "nameText": "Pangalan", + "newSoundtrackNameText": "Ang Aking Soundtrack ${COUNT}", + "newSoundtrackText": "Bagong Soundtrack:", + "newText": "Bagong \nSoundtrack", + "selectAPlaylistText": "Pumili Ng Playlist", + "selectASourceText": "Music Source", + "testText": "test", + "titleText": "Soundtracks", + "useDefaultGameMusicText": "Default na Laro ng Musika", + "useITunesPlaylistText": "Music App Playlist", + "useMusicFileText": "File Ng Musika (mp3, etc)", + "useMusicFolderText": "Folder Ng Mga File Ng Musika" + }, + "editText": "I-edit", + "endText": "Itigil", + "enjoyText": "Ikasiya!", + "epicDescriptionFilterText": "${DESCRIPTION} sa isang epic na slow motion.", + "epicNameFilterText": "Epikong ${NAME}", + "errorAccessDeniedText": "walang pahintulot", + "errorDeviceTimeIncorrectText": "Ang oras ng iyong device ay di tama nang ${HOURS} na oras.\nIto ay malamang na magdulot ng mga iba’t ibang problema.\nPakisuri ang mga setting ng iyong oras at time-zone.", + "errorOutOfDiskSpaceText": "Wala sa puwang ng disk", + "errorSecureConnectionFailText": "Hindi mapatunayan ng secure na “cloud connection”; maaaring mabigo ang pagpapagana ng network.", + "errorText": "Error", + "errorUnknownText": "error na ‘di malaman", + "exitGameText": "Exit mula sa ${APP_NAME}?", + "exportSuccessText": "Na-export ang '${NAME}'.", + "externalStorageText": "External na Storage", + "failText": "Bigo", + "fatalErrorText": "Uh oh; may kulang o sira.\nPakisubukang muling i-install ang app o\nmakipag-ugnayan kay ${EMAIL} para sa tulong.", + "fileSelectorWindow": { + "titleFileFolderText": "Pumili ng File o Folder", + "titleFileText": "Pumili ng File", + "titleFolderText": "Pumili ng Folder", + "useThisFolderButtonText": "Gamitin Ang Folder Na Ito" + }, + "filterText": "Salain", + "finalScoreText": "Huling Marka", + "finalScoresText": "Huling Mga Marka", + "finalTimeText": "Huling Oras", + "finishingInstallText": "Pagtatapos ng pag-install; sandali lang...", + "fireTVRemoteWarningText": "* Para sa isang mas mahusay na karanasan, gamitin\nGame Controllers o i-install ang\n'${REMOTE_APP_NAME}' app sa iyong\nmga telepono at tablet.", + "firstToFinalText": "Una-sa-${COUNT} Wakas", + "firstToSeriesText": "Una-sa-${COUNT} Panunuran", + "fiveKillText": "LIMANG PAGPATAY!!!", + "flawlessWaveText": "Walang Kapintasan na Kaway!", + "fourKillText": "APAT NA PAGPATAY!!!", + "friendScoresUnavailableText": "Hindi available ang marka ng kaibigan", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Mga Pinuno Ng Pang-${COUNT} na Laro", + "gameListWindow": { + "cantDeleteDefaultText": "Hindi pwedeng itanggal ang default na playlist.", + "cantEditDefaultText": "Hindi ma-edit ang default playlist! I-duplicate mo o gumawa ng bago.", + "cantShareDefaultText": "Hindi pwede ma-share ang default na playlist.", + "deleteConfirmText": "Tanggalin ang \"${LIST}\"?", + "deleteText": "Tanggalin ang\nPlaylist", + "duplicateText": "I-duplicate ang\nPlaylist", + "editText": "I-edit ang\nPlaylist", + "newText": "Gumawa ng\nPlaylist", + "showTutorialText": "Ipakita Ang Tutorial", + "shuffleGameOrderText": "I-shuffle Ang Kaayusan Ng Laro", + "titleText": "I-customize Ang ${TYPE} Playlists" + }, + "gameSettingsWindow": { + "addGameText": "Maglagay ng Laro" + }, + "gamesToText": "${WINCOUNT} na laro sa ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Tandaan: anumang device sa isang party ay maaaring magkaroon ng higit pa\nkaysa sa isang manlalaro kung mayroon kang sapat na mga controller.", + "aboutDescriptionText": "Gamitin ang mga tab na ito para mag-assemble ng party.\n\nPwede kang maglaro at mag paligsahan kasama ang iyong mga kaibigan sa \niba't ibang device sa pamamagitan ng “Party”.\n\nGamitin ang pindutin na ${PARTY} sa kanang tuktok upang\nmakipag-chat at makipag-ugnayan sa iyong partido.\n(sa isang controller, pindutin ang ${BUTTON} habang nasa isang menu)", + "aboutText": "Tungkulin", + "addressFetchErrorText": "", + "appInviteMessageText": "Pinadalhan ka ni ${NAME} ng ${COUNT} ticket sa ${APP_NAME}", + "appInviteSendACodeText": "Mag-send ka sa Kanila ng Code", + "appInviteTitleText": "${APP_NAME} App Invite", + "bluetoothAndroidSupportText": "(gumagana sa anumang Android device na mayroong Bluetooth)", + "bluetoothDescriptionText": "Mag-host/sumali sa isang party sa pamamagitan ng Bluetooth:", + "bluetoothHostText": "Mag-host gamit ang Bluetooth", + "bluetoothJoinText": "Sumali gamit ang Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "nag-checking…", + "copyCodeConfirmText": "Nakopya ang code sa clipboard.", + "copyCodeText": "I-kopya ang Code", + "dedicatedServerInfoText": "Para sa pinakamahusay na mga resulta, mag-set up ng nakalaang server. Tingnan ang bombsquadgame.com/server para malaman kung paano.", + "disconnectClientsText": "Ididiskonekta nito ang ${COUNT} (mga) manlalaro\nsa iyong party. Sigurado ka ba?", + "earnTicketsForRecommendingAmountText": "Makakatanggap ang mga kaibigan ng ${COUNT} na tiket kung susubukan nila ang laro\n(at makakatanggap ka ng ${YOU_COUNT} para sa bawat gagawa)", + "earnTicketsForRecommendingText": "I-share ang laro\npara makatanggap ng libreng tickets…", + "emailItText": "I-email", + "favoritesSaveText": "I-save bilang paborito", + "favoritesText": "Mga Paborito", + "freeCloudServerAvailableMinutesText": "Available ang susunod na libreng cloud server sa loob ng ${MINUTES} (na) minuto.", + "freeCloudServerAvailableNowText": "Mayroong libreng cloud server!", + "freeCloudServerNotAvailableText": "Walang available na libreng cloud server.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} na mga tiket mula sa ${NAME}", + "friendPromoCodeAwardText": "Makakatanggap ka ng ${COUNT} na tiket sa tuwing ito ay gagamitin.", + "friendPromoCodeExpireText": "Mag-e-expire ang code sa loob ng ${EXPIRE_HOURS} na oras at gagana lang para sa mga bagong manlalaro.", + "friendPromoCodeInstructionsText": "Upang gamitin ito, buksan ang ${APP_NAME} at pumunta sa \"Mga Setting->Advanced->Ilagay ang Code\".\nTingnan ang bombsquadgame.com para sa mga link sa pag-download para sa lahat ng sinusuportahang platform.", + "friendPromoCodeRedeemLongText": "Maaari itong ma-redem ng ${COUNT} na libreng tiket ng hanggang ${MAX_USES} na tao.", + "friendPromoCodeRedeemShortText": "Maaari itong ma-redem ng ${COUNT} na tiket sa larong ito.", + "friendPromoCodeWhereToEnterText": "(sa \"Settings->Advanced->Ilagay Ang Code\")", + "getFriendInviteCodeText": "Kumuha ng imbitasyon ng code ng kaibigan", + "googlePlayDescriptionText": "Mag-imbita ng mga manlalaro ng Google Play sa iyong party:", + "googlePlayInviteText": "Mag-imbita", + "googlePlayReInviteText": "Mayroong ${COUNT} (mga) Google Play na manlalaro sa iyong party \nna madidiskonekta kung magsisimula ka ng bagong imbitasyon.\nIsama sila sa bagong imbitasyon para maibalik mo sila.", + "googlePlaySeeInvitesText": "Ipakita Ang Mga Imbitasyon", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Bersyon ng Android / Google Play)", + "hostPublicPartyDescriptionText": "Mag-host ng Pampublikong Party", + "hostingUnavailableText": "Hindi Available Ang Pagho-host", + "inDevelopmentWarningText": "Note:\n\nAng Network Play ay bago at patuloy na umuunlad na feature.\nSa ngayon, Ito'y lubos na inirerekomenda na ang lahat ng \nmga manlalaro ay nasa parehong Wi-Fi network.", + "internetText": "Internet", + "inviteAFriendText": "Walang laro ang mga kaibigan mo nito? Mag-imbita mo sila \npara sila'y subukan maglaro ito at makakatanggap sila ng ${COUNT} libreng tiket.", + "inviteFriendsText": "Mag-imbita ng mga kaibigan", + "joinPublicPartyDescriptionText": "Sumali sa isang Pampublikong Party", + "localNetworkDescriptionText": "Sumali sa malapit na party (LAN, Bluetooth, etc.)", + "localNetworkText": "Lokal na Network", + "makePartyPrivateText": "Gawing Pribado Ang Party Ko", + "makePartyPublicText": "Gawing Publiko Ang Party Ko", + "manualAddressText": "Address", + "manualConnectText": "I-connect", + "manualDescriptionText": "Sumali sa isang party sa pamamagitan ng address:", + "manualJoinSectionText": "Sumali Sa Pamamagitan Ng Address", + "manualJoinableFromInternetText": "Pwede ka bang sumali sa internet?:", + "manualJoinableNoWithAsteriskText": "HINDI*", + "manualJoinableYesText": "OO*", + "manualRouterForwardingText": "*upang ayusin ito, subukang i-configure ang iyong router para ipasa ang UDP port ${PORT} sa iyong lokal na address", + "manualText": "Manwal", + "manualYourAddressFromInternetText": "Ang iyong address mula sa internet:", + "manualYourLocalAddressText": "Iyong lokal na address:", + "nearbyText": "Malapit", + "noConnectionText": "", + "otherVersionsText": "", + "partyCodeText": "Code ng Partido", + "partyInviteAcceptText": "Tanggapin", + "partyInviteDeclineText": "Tanggihan", + "partyInviteGooglePlayExtraText": "(tingnan ang 'Google Play' tab sa 'Sumama' window)", + "partyInviteIgnoreText": "Ignorahin", + "partyInviteText": "Inimbitahan ka ni ${NAME} \nna sumali sa kanilang party", + "partyNameText": "Pangalan Ng Partido", + "partyServerRunningText": "Tumatakbo ang iyong party server.", + "partySizeText": "Dami Ng Partido", + "partyStatusCheckingText": "sinusuri ang katayuan...", + "partyStatusJoinableText": "ang iyong party ay maaari na ngayong sumali mula sa internet", + "partyStatusNoConnectionText": "hindi makakonekta sa server", + "partyStatusNotJoinableText": "ang iyong party ay hindi maaaring sumali mula sa internet", + "partyStatusNotPublicText": "hindi publiko Ang iyong partido", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Ang mga pribadong partido ay tumatakbo sa mga nakalaang cloud server; Hindi kailangan ng router configuration", + "privatePartyHostText": "Mag-host ng Pribadong Party", + "privatePartyJoinText": "Sumali sa Pribadong Party", + "privateText": "Pribado", + "publicHostRouterConfigText": "Maaaring mangailangan nito ng pag-configure ng port-forwarding sa iyong router. Para sa mas madaling opsyon, mag-host ng pribadong party.", + "publicText": "Publiko", + "requestingAPromoCodeText": "Humihiling ng code...", + "sendDirectInvitesText": "I-send ng direktang imbitasyon", + "shareThisCodeWithFriendsText": "Ibahagi ang code na ito sa iyong mga kaibigan:", + "showMyAddressText": "Ipakita Ang Address Ko", + "startHostingPaidText": "Mag-host ngayon ng ${COST}", + "startHostingText": "Host", + "startStopHostingMinutesText": "Maaari kang magsimula at huminto sa pa nang libre sa susunod na ${MINUTES} minuto.", + "stopHostingText": "Itigil Ang Pagho-host", + "titleText": "Sumama", + "wifiDirectDescriptionBottomText": "Kung ang lahat ng device ay may panel na 'Wi-Fi Direct', dapat ay magagamit nila ito upang maghanap\nat kumonekta sa isa't isa. Kapag nakakonekta na ang lahat ng device, maaari kang bumuo ng mga party\ndito gamit ang tab na 'Local Network', katulad lang ng sa isang regular na Wi-Fi network.\n\nPara sa pinakamahusay na mga resulta, ang Wi-Fi Direct host ay dapat ding ang ${APP_NAME} party host", + "wifiDirectDescriptionTopText": "Maaaring gamitin ang Wi-Fi Direct upang direktang ikonekta ang mga Android device nang wala\nnangangailangan ng Wi-Fi network. Ito ay pinakamahusay na gumagana sa Android 4.2 o mas mataas.\n\nUpang magamit nito, buksan ang mga settings ng iyong Wi-Fi at hanapin ang 'Wi-Fi Direct' sa menu.", + "wifiDirectOpenWiFiSettingsText": "Buksan Ang Mga Settings ng Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(ito’y gumagana sa pagitan ng lahat ng mga platform)", + "worksWithGooglePlayDevicesText": "(ito’y gumagana sa mga devices na tumatakbo ang bersyon ng Google Play (android) ng larong ito)", + "youHaveBeenSentAPromoCodeText": "Pinadalhan ka ng promo code na ${APP_NAME}:" + }, + "getTicketsWindow": { + "freeText": "LIBRE!", + "freeTicketsText": "Libreng Tiket", + "inProgressText": "Ang isang transaksyon ay isinasagawa; mangyaring subukan muli ng saglit.", + "purchasesRestoredText": "Naibalik na ang mga nabili.", + "receivedTicketsText": "Nakatanggap ka ng ${COUNT} tiket!", + "restorePurchasesText": "Ibalik Ang Mga Nabili", + "ticketPack1Text": "Kaunting Pakete Ng Tiket", + "ticketPack2Text": "Katamtamang Pakete Ng Tiket", + "ticketPack3Text": "Maraming Pakete Ng Tiket", + "ticketPack4Text": "Malaking Pakete Ng Tiket", + "ticketPack5Text": "Mas Malaking Pakete Ng Tiket", + "ticketPack6Text": "Pinakamalaking Pakete Ng Tiket", + "ticketsFromASponsorText": "Manood ng Ad\npara makuha ang ${COUNT} na tiket", + "ticketsText": "${COUNT} Tiket", + "titleText": "Kumuha Ng Tiket", + "unavailableLinkAccountText": "Pasensya na, hindi available ang pagbili sa platform na ito.\nBilang isang solusyon, maaari mong i-link ang account na ito sa isang account na nasa\nisa pang platform at bumili doon.", + "unavailableTemporarilyText": "Hindi available ito. Subukang muli mamaya.", + "unavailableText": "Pasensya na, hindi ito available.", + "versionTooOldText": "Pasensya na, ang bersyon ng laro na ito ay masyadong luma; mangyaring mag-update sa isang mas bagong bersyon.", + "youHaveShortText": "mayroon kang ${COUNT}", + "youHaveText": "mayroon kang ${COUNT} na tiket" + }, + "googleMultiplayerDiscontinuedText": "Pasensya na, hindi na available ang multiplayer na serbisyo ng Google.\nGumagawa ako ng kapalit sa lalong madaling panahon.\nHanggang doon, mangyaring sumubok ng ibang paraan ng koneksyon.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Hindi puwede ang mga pagbili sa Google Play nito.\nMaaaring kailanganin mong i-update ang iyong store app.", + "googlePlayServicesNotAvailableText": "Hindi available ang Google Play Services sa ngayon.\n‘Di magagana ang takbo ng ilang mga app.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Palagi", + "fullScreenCmdText": "Fullscreen (Cmd-F)", + "fullScreenCtrlText": "Fullscreen (Ctrl-F)", + "gammaText": "Gama", + "highText": "Mataas", + "higherText": "Napakataas", + "lowText": "Mababa", + "mediumText": "Katamtaman", + "neverText": "Wala", + "resolutionText": "Resolusyon", + "showFPSText": "Ipakita ang FPS", + "texturesText": "Mga Texture", + "titleText": "Grapika", + "tvBorderText": "TV Na Border", + "verticalSyncText": "Patagong Pag-sync", + "visualsText": "Biswal" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nMas malakas pa sa suntok, pero\nmaaaring magresulta sa matinding pananakit sa sarili.\nPara sa pinakamahusay na mga resulta, itapon patungo\nkalaban bago maubos ang fuse.", + "bombInfoTextScale": 0.5, + "canHelpText": "Makakatulong ang ${APP_NAME}.", + "controllersInfoText": "Maaari mong laruin ang ${APP_NAME} kasama ng mga kaibigan sa isang network, o ikaw\nlahat ay maaaring maglaro sa parehong device kung mayroon kang sapat na mga controller.\nSinusuportahan ng ${APP_NAME} ang iba't ibang mga ito; maaari ka ring gumamit ng mga telepono\nbilang mga controller sa pamamagitan ng libreng '${REMOTE_APP_NAME}' app.\nTingnan ang Mga Setting->Controller para sa higit pang impormasyon.", + "controllersInfoTextRemoteOnly": "Maaari mong laruin ang ${APP_NAME} kasama ng mga kaibigan sa isang network, o ikaw\nlahat ay maaaring maglaro sa parehong device sa pamamagitan ng paggamit ng mga phones bilang\nmga controller sa pamamagitan ng libreng '${REMOTE_APP_NAME}' app.", + "controllersText": "Mga Controllers", + "controlsSubtitleText": "Ang iyong magiliw na ${APP_NAME} ay may ilang mga pangunahing aksyon", + "controlsText": "Mga Kontrol", + "devicesInfoText": "Maaaring laruin ang VR na bersyon ng ${APP_NAME} sa network\nang regular na bersyon, kaya tanggalin ang iyong mga karagdagang telepono, tablet,\nat mga computer at simulan ang iyong laro. Maaari itong maging kapaki-pakinabang sa\nikonekta ang isang regular na bersyon ng laro sa bersyon ng VR para lang\npayagan ang mga tao sa labas na manood ng aksyon.", + "devicesText": "Mga Device", + "friendsGoodText": "Ang mga ito ay magandang pagkakaroon. Ang ${APP_NAME} ay pinakanakakatuwa sa ilan\nmga manlalaro at maaaring sumuporta ng hanggang 8 sa isang pagkakataon, na humahantong sa:", + "friendsText": "Mga Kaibigan", + "jumpInfoText": "-Tumalon-\nTumalon upang tumawid sa maliliit na puwang,\nupang ihagis ang mga bagay na mas mataas, at\nupang ipahayag ang damdamin ng kagalakan.", + "jumpInfoTextScale": 0.5, + "orPunchingSomethingText": "O sumuntok ng isang bagay, itinapon ito sa isang bangin, at pinasabog ito habang pababa gamit ang isang malagkit na bomba.", + "pickUpInfoText": "- Pulutin -\nKunin ang mga flag, mga kaaway, o anumang bagay\nkung hindi ay hindi naka-bold sa lupa.\nPindutin muli upang ihagis.", + "pickUpInfoTextScale": 0.5, + "powerupBombDescriptionText": "Payagan kang maglabas ng tatlong bomba\nsa isang hilera sa halip na isa lamang.", + "powerupBombNameText": "Tatlong-Bomba", + "powerupCurseDescriptionText": "Malamang na gusto mong iwasan ang mga ganito.\n ...o sige lang?", + "powerupCurseNameText": "Sumpa", + "powerupHealthDescriptionText": "Ibangon ka sa buong kalusugan.\nHindi mo naisip nito.", + "powerupHealthNameText": "Medikal-Pakete", + "powerupIceBombsDescriptionText": "Mas mahina kaysa sa mga normal na bomba\nngunit nagyelo ang iyong mga kalaban\nat partikular na mabasag.", + "powerupIceBombsNameText": "Bombang-Yelo", + "powerupImpactBombsDescriptionText": "Medyo mahina kaysa sa regular\nbomba, ngunit sumasabog ito kapag nabagsak.", + "powerupImpactBombsNameText": "Gatilyong-Bomba", + "powerupLandMinesDescriptionText": "Ang mga ito ay dumating sa mga pakete ng 3;\nKapaki-pakinabang para sa base defense o\npaghinto ng mabilis na mga kalaban.", + "powerupLandMinesNameText": "Mina", + "powerupPunchDescriptionText": "Ang iyong mga suntok ay mas mahirap,\nmas mabilis, mas mahusay, at mas malakas.", + "powerupPunchNameText": "Boxing-Gloves", + "powerupShieldDescriptionText": "Pumigil na pagsakit\nkaya hindi mo kailangan.", + "powerupShieldNameText": "Enrhiyang-Kalasag", + "powerupStickyBombsDescriptionText": "Dumikit sa anumang matamaan nila.\nIto’y naging pagtawanan.", + "powerupStickyBombsNameText": "Malagkit-Bomba", + "powerupsSubtitleText": "Siyempre, walang larong kumpleto pag walang powerups:", + "powerupsText": "Powerups", + "punchInfoText": "- Suntok -\nAng mga suntok ay mas nakakasakit\nmas mabilis ang paggalaw ng iyong mga kamay, kaya\ntumakbo at umiikot na parang baliw.", + "runInfoText": "- Takbo -\nPindutin ang ANY button para tumakbo. Ang mga trigger o mga button sa balikat ay gumagana nang maayos kung mayroon ka ng mga ito.\nAng pagtakbo ay nagpapabilis sa iyo ng mga lugar ngunit nahihirapan kang lumiko, kaya mag-ingat sa mga bangin.", + "someDaysText": "May mga araw na parang gusto mong sumuntok ng kung ano. O nagpapasabog ng isang bagay.", + "titleText": "Tulong ng ${APP_NAME}", + "toGetTheMostText": "Upang masulit ang larong ito, kakailanganin mo:", + "welcomeText": "Maligayang Pagdating sa ${APP_NAME}" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- Ang ${HOST} ay nagna-navigate sa mga menu tulad ng isang boss -", + "importPlaylistCodeInstructionsText": "Gamitin ang sumusunod na code upang i-import ang playlist na ito sa ibang lugar:", + "importPlaylistSuccessText": "Na-import na ${TYPE} na playlist '${NAME}'", + "importText": "I-Import", + "importingText": "Nag-Iimport…", + "inGameClippedNameText": "Sa in-game ay naging\n\"${NAME}\"", + "installDiskSpaceErrorText": "ERROR: Hindi makumpleto ang pag-install.\nMaaaring wala ka nang espasyo sa iyong device.\nMag-clear ng ilang espasyo at subukang muli.", + "internal": { + "arrowsToExitListText": "pindutin ang ${LEFT} o ${RIGHT} upang mawala sa listahan", + "buttonText": "pindutan", + "cantKickHostError": "Hindi mo maaaring I-kick ang host.", + "chatBlockedText": "Na-block si ${NAME} sa loob ng ${TIME} segundo.", + "connectedToGameText": "Sumali sa '${NAME}'", + "connectedToPartyText": "Sumali sa party ni ${NAME}!", + "connectingToPartyText": "Nagdudugtong….", + "connectionFailedHostAlreadyInPartyText": "Nabigo ang koneksyon; nasa ibang party ang host.", + "connectionFailedPartyFullText": "Nabigo ang koneksyon; puno na ang party.", + "connectionFailedText": "Nabigo ang koneksyon.", + "connectionFailedVersionMismatchText": "Nabigo ang koneksyon; nagpapatakbo ang host ng ibang bersyon ng laro.\nTiyaking pareho kayong napapanahon at subukang muli sumali.", + "connectionRejectedText": "Tinanggihan ang koneksyon.", + "controllerConnectedText": "Nakakonekta si ${CONTROLLER}.", + "controllerDetectedText": "1 controller ang natuklasan.", + "controllerDisconnectedText": "Nadiskonekta si ${CONTROLLER}.", + "controllerDisconnectedTryAgainText": "Nadiskonekta si ${CONTROLLER}. Pakisubukang kumonekta muli.", + "controllerForMenusOnlyText": "Ang controller na ito ay hindi maaaring gamitin sa paglalaro; para lamang mag-navigate sa mga menu.", + "controllerReconnectedText": "Muling kumonekta si ${CONTROLLER}.", + "controllersConnectedText": "Nakakonekta ang ${COUNT} controllers.", + "controllersDetectedText": "${COUNT} controller ang natukalsan.", + "controllersDisconnectedText": "${COUNT} controller ang nadiskonekta.", + "corruptFileText": "Natukoy ang (mga) corrupted na file. Pakisubukang muling i-install, o mag-email sa ${EMAIL}", + "errorPlayingMusicText": "Error sa paglalaro ng musika: ${MUSIC}", + "errorResettingAchievementsText": "Hindi ma-reset ang mga online na achievements; Subukang muli mamaya.", + "hasMenuControlText": "Si ${NAME} lang ay may kontrol sa menu.", + "incompatibleNewerVersionHostText": "Ang host ay nagpapatakbo ng mas bagong bersyon ng laro.\nMag-update sa pinakabagong bersyon at subukang muli.", + "incompatibleVersionHostText": "Ang host ay nagpapatakbo ng ibang bersyon ng laro.\nTiyaking pareho kayong napapanahong bersyon at subukang muli.", + "incompatibleVersionPlayerText": "Ang ${NAME} ay nagpapatakbo ng ibang bersyon ng laro.\nTiyaking pareho kayong napapanahong bersyon at subukang muli.", + "invalidAddressErrorText": "Error: di-wastong address.", + "invalidNameErrorText": "Errol: di-wastong pangalan.", + "invalidPortErrorText": "Error: di-wastong port.", + "invitationSentText": "Napadala na ang imbitasyon.", + "invitationsSentText": "${COUNT} (na) imbitasyon ang napadala.", + "joinedPartyInstructionsText": "May sumali sa iyong partido.\nPumunta sa 'Maglaro' para magsimula ng laro.", + "keyboardText": "Keyboard", + "kickIdlePlayersKickedText": "na-kicked si ${NAME} dahil sa pagiging idle.", + "kickIdlePlayersWarning1Text": "I-kikick si ${NAME} sa loob ng ${COUNT} (na) segundo kung idle pa rin.", + "kickIdlePlayersWarning2Text": "(maaari mong i-off ito sa Mga Setting -> Advanced)", + "leftGameText": "Umalis ka sa '${NAME}'.", + "leftPartyText": "Umalis ka sa party ni ${NAME}.", + "noMusicFilesInFolderText": "Walang mga file ng musika ang folder.", + "playerJoinedPartyText": "Sumali si ${NAME} sa party mo!", + "playerLeftPartyText": "Umalis si ${NAME} sa party mo.", + "rejectingInviteAlreadyInPartyText": "Pagtanggi sa imbitasyon (nasa isang party na).", + "serverRestartingText": "Nagre-restart ang server. Mangyaring sumali muli sa isang saglit…", + "serverShuttingDownText": "Nagsasara ang server...", + "signInErrorText": "Error sa pag-sign in.", + "signInNoConnectionText": "Hindi makapag-sign in. (walang koneksyon ang Wi-Fi mo?)", + "telnetAccessDeniedText": "ERROR: ang user ay hindi nagbigay ng access sa telnet.", + "timeOutText": "(time out sa ${TIME} segundo)", + "touchScreenJoinWarningText": "Sumali ka gamit ang touchscreen.\nKung ito ay isang pagkakamali, i-tap ang 'Menu->Umalis sa Laro' kasama nito.", + "touchScreenText": "TouchScreen", + "unableToResolveHostText": "Error: hindi malutas ang host.", + "unavailableNoConnectionText": "Ito’y kasalukuyang hindi magagamit (walang koneksyon sa internet?)", + "vrOrientationResetCardboardText": "Gamitin ito upang i-reset ang oryentasyon ng VR.\nUpang maglaro ng laro kakailanganin mo ng isang panlabas na controller.", + "vrOrientationResetText": "Pag-reset ng oryentasyon ng VR.", + "willTimeOutText": "(magta-time out kung idle)" + }, + "jumpBoldText": "TALON", + "jumpText": "Talon", + "keepText": "Panatilihin", + "keepTheseSettingsText": "Panatilihin ang mga setting na ito?", + "keyboardChangeInstructionsText": "I-double press space para mapalitan ang mga keyboard.", + "keyboardNoOthersAvailableText": "Walang ibang mga keyboard na magagamit.", + "keyboardSwitchText": "Nagpapalit ng keyboard sa \"${NAME}\".", + "kickOccurredText": "na-kicked si ${NAME}", + "kickQuestionText": "I-Kick si ${NAME}?", + "kickText": "I-Kick", + "kickVoteCantKickAdminsText": "Hindi ma-kick ang mga admin.", + "kickVoteCantKickSelfText": "Hindi mo ma-kick ng sarili mo.", + "kickVoteFailedNotEnoughVotersText": "Hindi marami ang mga manlalaro para sa isang boto.", + "kickVoteFailedText": "Nabigo ang kick-vote.", + "kickVoteStartedText": "Sinimulan na ang isang kick vote para kay ${NAME}.", + "kickVoteText": "Bumoto sa Pagki-kick", + "kickVotingDisabledText": "Naka-disable ang kick voting.", + "kickWithChatText": "I-type ang ${YES} sa chat para sa oo at ${NO} para sa hindi.", + "killsTallyText": "${COUNT} ang pinatay", + "killsText": "Pinatay", + "kioskWindow": { + "easyText": "Madali", + "epicModeText": "Mode na Epic", + "fullMenuText": "Buong Menu", + "hardText": "Mahirap", + "mediumText": "Katamtaman", + "singlePlayerExamplesText": "Mga Halimbawa ng Single Player / Co-op", + "versusExamplesText": "Halimbawa ng mga Versus" + }, + "languageSetText": "Ang wika ay \"${LANGUAGE}\" sa ngayon.", + "lapNumberText": "Ikot ${CURRENT}/${TOTAL}", + "lastGamesText": "(huling ${COUNT} na laro)", + "leaderboardsText": "Mga Leaderboard", + "league": { + "allTimeText": "Lahat Ng Oras", + "currentSeasonText": "Kasalukuyang Season (${NUMBER})", + "leagueFullText": "Ligang ${NAME}.", + "leagueRankText": "Ranggo ng Liga", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} ${SUFFIX} na Liga", + "seasonEndedDaysAgoText": "Natapos ang season noing ${NUMBER} na araw.", + "seasonEndsDaysText": "Matatapos ang season sa ${NUMBER} (na) araw.", + "seasonEndsHoursText": "Matatapos ang season sa ${NUMBER} (na) oras.", + "seasonEndsMinutesText": "Matatapos ang season sa ${NUMBER} (na) minuto.", + "seasonText": "Ika-${NUMBER} na season", + "tournamentLeagueText": "Dapat mong maabot ang liga ng ${NAME} upang makapasok sa paligsahan na ito.", + "trophyCountsResetText": "Ire-reset ang mga bilang ng tropeo sa susunod na season." + }, + "levelBestScoresText": "Pinakamahusay na mga iskor sa ${LEVEL}", + "levelBestTimesText": "Pinakamahusay na lahat sa ${LEVEL}", + "levelIsLockedText": "Naka-lock ang ${LEVEL}.", + "levelMustBeCompletedFirstText": "Dapat makumpleto muna ang ${LEVEL}.", + "levelText": "Antas ${NUMBER}", + "levelUnlockedText": "Unlocked ang Level na Ito!", + "livesBonusText": "Bonus ng Buhay", + "loadingText": "saglit lang...", + "loadingTryAgainText": "Naglo-load; subukan muli sa isang saglit…", + "macControllerSubsystemBothText": "Pareho (hindi inirerekomenda)", + "macControllerSubsystemClassicText": "Klasiko", + "macControllerSubsystemDescriptionText": "(subukang baguhin ito kung ang iyong mga controllers ay hindi gumagana)", + "macControllerSubsystemMFiNoteText": "Natukoy ang Made-for-iOS/Mac controller;\nMaaaring gusto mong paganahin ang mga ito sa Mga Setting -> Mga Controller", + "macControllerSubsystemMFiText": "Made-for-iOS/Mac", + "macControllerSubsystemTitleText": "Suporta sa Controller", + "mainMenu": { + "creditsText": "Mga Kredito", + "demoMenuText": "Demo na Menu", + "endGameText": "Itigil ang Laro", + "endTestText": "Itigil ang Test", + "exitGameText": "Umalis sa Laro", + "exitToMenuText": "Balik sa menu?", + "howToPlayText": "Paano Maglaro", + "justPlayerText": "(Si ${NAME} lang)", + "leaveGameText": "Umalis sa Laro", + "leavePartyConfirmText": "Talagang aalis sa party na ito?", + "leavePartyText": "Umalis sa Party", + "quitText": "Umalis", + "resumeText": "Ipatuloy", + "settingsText": "Mga Setting" + }, + "makeItSoText": "Gawin itong Kaya", + "mapSelectGetMoreMapsText": "Kumuha ng Higit pang Mapa...", + "mapSelectText": "Pumili…", + "mapSelectTitleText": "Mapa ng ${GAME}", + "mapText": "Mapa", + "maxConnectionsText": "Max na Koneksyon", + "maxPartySizeText": "Max ng Pagdami ng Party", + "maxPlayersText": "Pagdami ng Mga Manlalaro", + "merchText": "Paninda!", + "modeArcadeText": "Arcade na Mode", + "modeClassicText": "Klasikong Mode", + "modeDemoText": "Mode na Demo", + "mostValuablePlayerText": "Pinakamalupit sa lahat", + "mostViolatedPlayerText": "Pinakanakawawa sa lahat", + "mostViolentPlayerText": "Pinakamadugo sa lahat", + "moveText": "Galaw", + "multiKillText": "${COUNT}-PAGPATAY!!!", + "multiPlayerCountText": "${COUNT} na manlalaro", + "mustInviteFriendsText": "Tandaan: dapat kang mag-imbita ng mga kaibigan\nang panel na \"${GATHER}\" o i-attach\nmga controller para maglaro ng multiplayer.", + "nameBetrayedText": "${VICTIM} ay pinagtaksilan ni ${NAME}.", + "nameDiedText": "${NAME} ay namatay.", + "nameKilledText": "${VICTIM} ay pinatay ni ${NAME}.", + "nameNotEmptyText": "Hindi pwede ang walang pangalan!", + "nameScoresText": "${NAME} Naka-score!", + "nameSuicideKidFriendlyText": "Hindi sinasadyang namatay si ${NAME}.", + "nameSuicideText": "Nagpakamatay si ${NAME}.", + "nameText": "Pangalan", + "nativeText": "Natural", + "newPersonalBestText": "Bagong personal na pinakamahusay!", + "newTestBuildAvailableText": "Available ang isang mas bagong pagsubok na build! (${VERSION} build ${BUILD}).\nKunin ito sa ${ADDRESS}", + "newText": "Bago", + "newVersionAvailableText": "Available ang isang mas bagong bersyon ng ${APP_NAME}! (${VERSION})", + "nextAchievementsText": "Mga Susunod na Nakamit:", + "nextLevelText": "Mga Susunod na Level", + "noAchievementsRemainingText": "- wala", + "noContinuesText": "(hindi i-continue)", + "noExternalStorageErrorText": "Walang nakitang external na storage sa device na ito", + "noGameCircleText": "Error: hindi naka-log in sa GameCircle", + "noScoresYetText": "Wala pang score.", + "noThanksText": "Salamat Nalang", + "noTournamentsInTestBuildText": "BABALA: Babalewalain ang mga score sa tournament mula sa test build na ito.", + "noValidMapsErrorText": "Walang nakitang valid na mapa para sa ganitong uri ng laro.", + "notEnoughPlayersRemainingText": "Hindi marami na manlalaro ang natitira; umalis at magsimula ng bagong laro.", + "notEnoughPlayersText": "Kailangan mo ng atleast ${COUNT} na manlalaro upang simulan ang larong ito!", + "notNowText": "Hindi muna ngayon", + "notSignedInErrorText": "Dapat kang mag-sign in para magawa ito.", + "notSignedInGooglePlayErrorText": "Dapat kang mag-sign in gamit ang Google Play para magawa ito.", + "notSignedInText": "hindi naka-sign in", + "notUsingAccountText": "Note: hindi pinapansin ang account ng ${SERVICE}.\nPumunta sa 'Account -> Mag-sign in gamit ang ‘${SERVICE}' kung gusto mo itong gamitin.", + "nothingIsSelectedErrorText": "Walang napili!", + "numberText": "#${NUMBER}", + "offText": "Naka-Off", + "okText": "Ok lang", + "onText": "Naka-On", + "oneMomentText": "Saglit lang…", + "onslaughtRespawnText": "Ang ${PLAYER} ay respawn sa wave na ${WAVE}", + "orText": "${A} o ${B}", + "otherText": "Iba Pa…", + "outOfText": "(#${RANK} sa ${ALL})", + "ownFlagAtYourBaseWarning": "Ang iyong sariling watawat ay dapat na\nsa iyong base upang makapuntos!", + "packageModsEnabledErrorText": "Ang network-play ay hindi pinapayagan habang ang local-package-mods ay pinagana (tingnan ang Mga Setting->Advanced)", + "partyWindow": { + "chatMessageText": "Mensahe", + "emptyText": "Walang tao ang iyong party", + "hostText": "(ang host)", + "sendText": "I-send", + "titleText": "Iyong Party" + }, + "pausedByHostText": "(naka-pause ng host)", + "perfectWaveText": "Perpekto na Kaway!", + "pickUpText": "Pulutin", + "playModes": { + "coopText": "Kooperatiba", + "freeForAllText": "Awayang Rambulan", + "multiTeamText": "Maraming Team", + "singlePlayerCoopText": "Nag-iisa / Kooperatiba", + "teamsText": "Mga Teams" + }, + "playText": "Maglaro", + "playWindow": { + "oneToFourPlayersText": "1-4 na manlalaro", + "titleText": "Maglaro", + "twoToEightPlayersText": "2-8 na manlalaro" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "Papasok si ${PLAYER} sa simula ng susunod na round.", + "playerInfoText": "Impormasyon ng Manlalaro", + "playerLeftText": "Umalis si ${PLAYER} sa laro.", + "playerLimitReachedText": "Naabot na ang limitasyon ng manlalaro na ${COUNT}; hindi pinapayagan ang mga ibang sumali.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Hindi mo matatanggal ang profile ng iyong account.", + "deleteButtonText": "Itangal ang\nProfile", + "deleteConfirmText": "Itangal si ‘${PROFILE}’?", + "editButtonText": "I-edit ang\nProfile", + "explanationText": "(mga pangalan at hitsura ng custom na manlalaro para sa account na ito)", + "newButtonText": "Gumawa ng\nProfile", + "titleText": "Profile ng Manlalaro" + }, + "playerText": "Manlalaro", + "playlistNoValidGamesErrorText": "Ang playlist na ito ay hindi naglalaman ng mga wastong naka-unlock na laro.", + "playlistNotFoundText": "hindi nahanap ang playlist", + "playlistText": "Playlist", + "playlistsText": "Mga Playlist", + "pleaseRateText": "Kung nae-enjoy mo ang ${APP_NAME}, mangyaring isaalang-alang ang \npagkuha na sandali lang at i-rate ito o pagsulat ng isang pagsusuri. Nagbibigay ito ngkapaki-pakinabang na feedback at \ntumutulong sa pagsuporta sa pag-unlad sa hinaharap.\n\nsalamat!\n-eric", + "pleaseWaitText": "Hintay lang…", + "pluginClassLoadErrorText": "Error sa paglo-load ang '${PLUGIN}' na klaseng plugin : ${ERROR}", + "pluginInitErrorText": "Error sa pagsisimula ang '${PLUGIN}' na plugin: ${ERROR}", + "pluginsDetectedText": "May nakitang bagong (mga) plugin. I-restart para i-activate ang mga ito, o i-configure ang mga ito sa mga setting.", + "pluginsRemovedText": "Hindi na nahanapan ang ${NUM} ng (mga) plugin.", + "pluginsText": "Mga Plugin", + "practiceText": "Pagsasagawa", + "pressAnyButtonPlayAgainText": "Pindutin ang anumang button para maglaro muli...", + "pressAnyButtonText": "Pindutin ang anumang button para magpatuloy...", + "pressAnyButtonToJoinText": "pindutin ang anumang button para sumali...", + "pressAnyKeyButtonPlayAgainText": "Pindutin ang anumang key/button para maglaro muli...", + "pressAnyKeyButtonText": "Pindutin ang anumang key/button para magpatuloy...", + "pressAnyKeyText": "Pindutin ang anumang key…", + "pressJumpToFlyText": "** Pindutin ang tumalon nang paulit-ulit upang lumipad **", + "pressPunchToJoinText": "Pindutin ang SUNTOK para sumali...", + "pressToOverrideCharacterText": "pindutin ang ${BUTTONS} upang i-override ang iyong karakter", + "pressToSelectProfileText": "pindutin ang ${BUTTONS} upang pumili ng manlalaro", + "pressToSelectTeamText": "pindutin ang ${BUTTONS} para pumili ng team", + "promoCodeWindow": { + "codeText": "Code", + "enterText": "I-enter" + }, + "promoSubmitErrorText": "Error sa pagsusumite ng code; suriin ang iyong koneksyon ng internet", + "ps3ControllersWindow": { + "macInstructionsText": "I-off ang power sa likod ng iyong PS3, siguraduhin\nNaka-enable ang Bluetooth sa iyong Mac, pagkatapos ay ikonekta ang iyong controller\nsa iyong Mac sa pamamagitan ng USB cable upang ipares ang dalawa. Mula noon, ikaw\nmaaaring gamitin ang home button ng controller para ikonekta ito sa iyong Mac\nsa alinman sa wired (USB) o wireless (Bluetooth) mode.\n\nSa ilang mga Mac maaari kang ma-prompt para sa isang passcode kapag nagpapares.\nKung mangyari ito, tingnan ang sumusunod na tutorial o google para sa tulong.\n\n\n\n\nDapat lumabas sa device ang mga PS3 controller na nakakonekta nang wireless\nlistahan sa System Preferences->Bluetooth. Maaaring kailanganin mong alisin ang mga ito\nmula sa listahang iyon kapag gusto mong gamitin muli ang mga ito sa iyong PS3.\n\nTiyakin din na idiskonekta ang mga ito sa Bluetooth kapag hindi naka-in\ngamitin o ang kanilang mga baterya ay patuloy na mauubos.\n\nDapat hawakan ng Bluetooth ang hanggang 7 konektadong device,\nkahit na ang iyong mileage ay maaaring mag-iba.", + "ouyaInstructionsText": "Para gumamit ng PS3 controller sa iyong OUYA, ikonekta lang ito gamit ang USB cable\nisang beses upang ipares ito. Ang paggawa nito ay maaaring madiskonekta ang iyong iba pang mga controller, kaya\ndapat mong i-restart ang iyong OUYA at i-unplug ang USB cable.\n\nMula noon, magagamit mo na ang HOME button ng controller para\nikonekta ito nang wireless. Kapag tapos ka nang maglaro, pindutin nang matagal ang HOME button\npara sa 10 segundo upang i-off ang controller; kung hindi, maaari itong manatili sa\nat mga basurang baterya.", + "pairingTutorialText": "pagpapares ng tutorial na video", + "titleText": "Paggamit ng mga PS3 Controller sa ${APP_NAME}:" + }, + "punchBoldText": "SUNTOK", + "punchText": "Suntok", + "purchaseForText": "Ibili para sa ${PRICE}", + "purchaseGameText": "Ibili ang laro", + "purchasingText": "Nagbabayad...", + "quitGameText": "Ihinto ang ${APP_NAME}?", + "quittingIn5SecondsText": "Humihinto sa loob ng 5 segundo...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Random", + "rankText": "Ranggo", + "ratingText": "Marka", + "reachWave2Text": "Abutin ang kaway 2 para ma-ranggo.", + "readyText": "nakahanda", + "recentText": "Makabago", + "remoteAppInfoShortText": "Ang ${APP_NAME} ay pinakanakakatuwa kapag nilalaro kasama ng pamilya at mga kaibigan.\nIkonekta ang isa o higit pang mga controller ng hardware o i-install ang\n${REMOTE_APP_NAME} app sa mga phone o tablet upang magamit ang mga ito\nbilang mga controllers.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Posisyon ng Pindutan", + "button_size": "Laki ng Pindutan", + "cant_resolve_host": "Hindi malutas ang host.", + "capturing": "Kumukuha…", + "connected": "Konektdo.", + "description": "Gamitin ang iyong mga phone o tablet bilang controller sa BombSquad.\nHanggang 8 device ang maaaring kumonekta nang sabay-sabay para sa epic na lokal na multiplayer na kabaliwan sa isang TV o tablet", + "disconnected": "Nadiskonekta ng server.", + "dpad_fixed": "nakapirmi", + "dpad_floating": "lumulutang", + "dpad_position": "Posisyon ng D-Pad", + "dpad_size": "Laki ng D-Pad", + "dpad_type": "Uri ng D-Pad", + "enter_an_address": "Maglagay ng Address", + "game_full": "Ang laro ay puno na o hindi tumatanggap ng mga koneksyon.", + "game_shut_down": "Nagsara ang laro.", + "hardware_buttons": "Mga Pindutan ng Hardware", + "join_by_address": "Sumali sa pamamagitan ng Address...", + "lag": "Lag: ${SECONDS} na segundo", + "reset": "I-reset sa default", + "run1": "Takbo 1", + "run2": "Takbo 2", + "searching": "Naghahanap ng mga laro sa BombSquad...", + "searching_caption": "I-tap ang pangalan ng laro para sumali dito.\nTiyaking nasa parehong kang wifi network sa laro.", + "start": "Simulan", + "version_mismatch": "Hindi tugma ang bersyon.\nTiyaking BombSquad at BombSquad Remote\nay ang mga pinakabagong bersyon at subukang muli." + }, + "removeInGameAdsText": "I-unlock ang \"${PRO}\" sa tindahan upang alisin ang mga in-game na ad.", + "renameText": "I-palitan", + "replayEndText": "Itigil Ang Replay", + "replayNameDefaultText": "Replay ng Huling Laro", + "replayReadErrorText": "Error sa pagbabasa ng replay file.", + "replayRenameWarningText": "Palitan ang pangalan ng \"${REPLAY}\" pagkatapos ng isang laro kung gusto mong panatilihin ito; kung hindi, ito ay mapapatungan.", + "replayVersionErrorText": "Pasensya na, ginawa ang replay na ito sa ibang paraang\nbersyon ng laro at hindi magagamit.", + "replayWatchText": "Panoorin ang replay", + "replayWriteErrorText": "Error sa pagsulat ng replay file.", + "replaysText": "Mga Replay", + "reportPlayerExplanationText": "Gamitin ang email na ito upang mag-ulat ng pagdaya, hindi naaangkop na pananalita, o iba pang masamang gawin.\nPakilarawan sa ibaba:", + "reportThisPlayerCheatingText": "Pagdaya", + "reportThisPlayerLanguageText": "Hindi Angkop na Salita", + "reportThisPlayerReasonText": "Ano ang gusto mong iulat?", + "reportThisPlayerText": "Iulat ang Manlalaro na Ito", + "requestingText": "Humihiling", + "restartText": "I-restart", + "retryText": "I-retry", + "revertText": "Ibalik", + "runText": "Takbo", + "saveText": "I-save", + "scanScriptsErrorText": "(Mga) error sa pag-scan ng mga script; tingnan ang log para sa mga detalye.", + "scoreChallengesText": "Mga Hamon sa Iskor", + "scoreListUnavailableText": "Hindi available ang listahan ng iskor", + "scoreText": "Iskor", + "scoreUnits": { + "millisecondsText": "Milisegundo", + "pointsText": "Puntos", + "secondsText": "Segundo" + }, + "scoreWasText": "(ay nasa ${COUNT})", + "selectText": "Piliin", + "seriesWinLine1PlayerText": "ANG NANALO SA", + "seriesWinLine1TeamText": "ANG NANALO SA", + "seriesWinLine1Text": "ANG NANALO SA", + "seriesWinLine2Text": "SERYE!", + "settingsWindow": { + "accountText": "Account", + "advancedText": "Advanced", + "audioText": "Audio", + "controllersText": "Mga Controller", + "graphicsText": "Grapika", + "playerProfilesMovedText": "Tandaan: Ang mga Profile ng Manlalaro ay inilipat sa Account window sa pangunahing menu.", + "titleText": "Mga Setting" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(isang simpleng, controller-friendly na on-screen na keyboard para sa pag-edit ng teksto)", + "alwaysUseInternalKeyboardText": "Laging Gumamit ng Panloob na Keyboard", + "benchmarksText": "Mga Benchmark at Stress-Test", + "disableCameraGyroscopeMotionText": "I-disable ang Camera Gyroscope Motion", + "disableCameraShakeText": "Huwag paganahin ang Camera Shake", + "disableThisNotice": "(maaari mong i-disable ang notice na ito sa mga advanced na setting)", + "enablePackageModsDescriptionText": "(nagpapagana ng mga karagdagang kakayahan sa pag-modding ngunit hindi pinapagana ang net-play)", + "enablePackageModsText": "Paganahin ang Lokal na Package Mods", + "enterPromoCodeText": "Ilagay ang Code", + "forTestingText": "Tandaan: ang mga value na ito ay para lamang sa pagsubok at mawawala kapag lumabas ang app.", + "helpTranslateText": "Ang mga pagsasalin na hindi Ingles ng ${APP_NAME} ay isang komunidad\nsuportadong pagsisikap. Kung gusto mong mag-ambag o magtama\nisang pagsasalin, sundan ang link sa ibaba. Salamat!", + "kickIdlePlayersText": "I-kick Ang Mga Idle na Manlalaro", + "kidFriendlyModeText": "Kid-Friendly Mode (binawasan ang karahasan, atbp)", + "languageText": "Wika", + "moddingGuideText": "Gabay sa Modding", + "mustRestartText": "Dapat mong i-restart ang laro para magka-epekto ito.", + "netTestingText": "Pagsusuri ng Network", + "resetText": "I-reset", + "showBombTrajectoriesText": "Ipakita ang Mga Trajectory ng Bomba", + "showPlayerNamesText": "Ipakita ang Mga Pangalan ng Manlalaro", + "showUserModsText": "Ipakita ang Mods Folder", + "titleText": "Advanced", + "translationEditorButtonText": "Editor ng Wika ng ${APP_NAME}.", + "translationFetchErrorText": "hindi available ang katayuan ng wika", + "translationFetchingStatusText": "sinusuri ang status ng lengguwahe…", + "translationInformMe": "Ipaalam sa akin kapag ang aking wika ay nangangailangan ng mga update", + "translationNoUpdateNeededText": "ang kasalukuyang wika ay makabago; woohoo!", + "translationUpdateNeededText": "** ang kasalukuyang wika ay nangangailangan ng mga update!! **", + "vrTestingText": "Testing ng VR" + }, + "shareText": "I-share", + "sharingText": "Nagbabahagi….", + "showText": "Ipakita", + "signInForPromoCodeText": "Dapat kang mag-sign in sa isang account para magkabisa ang mga code.", + "signInWithGameCenterText": "Para gumamit ng Game Center account,\nmag-sign in gamit ang Game Center app.", + "singleGamePlaylistNameText": "${GAME} lang", + "singlePlayerCountText": "1 manlalaro", + "soloNameFilterText": "Solo na ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Pagpili ng Karakter", + "Chosen One": "Napili ng Isa", + "Epic": "Larong Epic na Mode", + "Epic Race": "Epic na Takbuan", + "FlagCatcher": "Kunin ang Bandila", + "Flying": "Masayang Isip", + "Football": "Rugbi", + "ForwardMarch": "Pag-atake", + "GrandRomp": "Pagsakop", + "Hockey": "Hockey", + "Keep Away": "Layuan Mo", + "Marching": "Bantayan", + "Menu": "Pangunahing Menu", + "Onslaught": "Pagsalakay", + "Race": "Takbuan", + "Scary": "Hari Ng Burol", + "Scores": "Screen Ng Iskor", + "Survival": "Kaligtasan", + "ToTheDeath": "Laban Ng Kamatayan", + "Victory": "Final Na Screen Ng Iskor" + }, + "spaceKeyText": "space", + "statsText": "Katayuan", + "storagePermissionAccessText": "Nangangailangan ito ng access sa storage", + "store": { + "alreadyOwnText": "Nabili mo na ang ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Nag-aalis ng mga in-game na ad at nag-screen\n• Nagbubukas ng higit pang mga setting ng laro\n• Kasama rin ang:", + "buyText": "Ibili", + "charactersText": "Mga Karakter", + "comingSoonText": "Abangan...", + "extrasText": "Padagdag", + "freeBombSquadProText": "Ang BombSquad ay libre na ngayon, ngunit dahil ikaw ang orihinal na bumili nito, ikaw na\npagtanggap ng BombSquad Pro upgrade at ${COUNT} na mga tiket bilang pasasalamat.\nTangkilikin ang mga bagong feature, at salamat sa iyong suporta!\n-Eric", + "holidaySpecialText": "Espesyal Na Holiday", + "howToSwitchCharactersText": "(pumunta sa \"${SETTINGS} -> ${PLAYER_PROFILES}\" para magtalaga at mag-customize ng mga character)", + "howToUseIconsText": "(gumawa ng mga global profile ng manlalaro (sa window ng account) para magamit ang mga ito)", + "howToUseMapsText": "(gamitin ang mga mapa na ito sa sarili mong Mga Team/Rambulan na mga playlist)", + "iconsText": "Mga Icon", + "loadErrorText": "Hindi ma-load ang page.\nSuriin ang iyong koneksyon sa internet.", + "loadingText": "Saglit lang…", + "mapsText": "Mga Mapa", + "miniGamesText": "Mga MiniGames", + "oneTimeOnlyText": "(isang beses lamang)", + "purchaseAlreadyInProgressText": "Ang isang nabilhin ng item na ito ay isinasagawa na.", + "purchaseConfirmText": "Ibili ang ${ITEM}?", + "purchaseNotValidError": "Hindi wasto ang nabilhin.\nMakipag-ugnayan kay ${EMAIL} kung ito ay isang error.", + "purchaseText": "Bilhin", + "saleBundleText": "Diskwento ng Bundle!", + "saleExclaimText": "Diskwento!", + "salePercentText": "(${PERCENT}% diskwento)", + "saleText": "BAWAS", + "searchText": "Hanapin", + "teamsFreeForAllGamesText": "Mga Team / Rambulan Na Mga Laro", + "totalWorthText": "*** ${TOTAL_WORTH} na halaga! ***", + "upgradeQuestionText": "I-upgrade?", + "winterSpecialText": "Espesyal na Taglamig", + "youOwnThisText": "- nabilhin mo na ito -" + }, + "storeDescriptionText": "8 Player Party Game Kabaliwan!\n\nIsabugin ang iyong mga kaibigan (o ang computer) sa isang tournament ng mga putok na mini-game gaya ng Kunin-Ang-Bandila, Bombang-Hockey, at Epic-Na-Bagalan-Ng-Laban-Ng-Kamatayan!\n\nPinapadali ng mga simpleng kontrol at malawak na suporta sa controller para sa hanggang 8 tao na makilahok sa aksyon; maaari mo ring gamitin ang iyong mga mobile device bilang mga controller sa pamamagitan ng libreng 'BombSquad Remote' app!\n\nIhagis Ang Mga Bomba!\n\nTingnan ang www.froemling.net/bombsquad para sa karagdagang impormasyon.", + "storeDescriptions": { + "blowUpYourFriendsText": "Isabog ang iyong mga kaibigan", + "competeInMiniGamesText": "Makipagkumpitensya sa mga mini-game mula sa takbuan hanggang sa paglipad.", + "customize2Text": "I-customize ang mga character, mini-game, at maging ang mga soundtrack.", + "customizeText": "I-customize ang mga character at gumawa ng sarili mong mga mini-game playlist.", + "sportsMoreFunText": "Mas masaya ang sports na may pampasabog.", + "teamUpAgainstComputerText": "Makipagtulungan laban sa computer." + }, + "storeText": "Tindahan", + "submitText": "Ipasa", + "submittingPromoCodeText": "Nagsusumite ng Code...", + "teamNamesColorText": "Mga Pangalan/Kulay ng Team…", + "telnetAccessGrantedText": "Pinagana ang pag-access sa Telnet..", + "telnetAccessText": "Natuklasan ang pag-access sa Telnet; payagan?", + "testBuildErrorText": "Ang test build na ito ay hindi na aktibo; mangyaring suriin para sa isang bagong bersyon.", + "testBuildText": "Test Build", + "testBuildValidateErrorText": "Hindi ma-validate ang test build. (walang koneksyon sa internet?)", + "testBuildValidatedText": "Na-validate ang Test Build; Tamasahin!", + "thankYouText": "Salamat sa iyong suporta! Tangkilikin ang laro!!", + "threeKillText": "TRIPLENG PAGPATAY!!", + "timeBonusText": "Bonus Ng Oras", + "timeElapsedText": "Oras Na Lumipas", + "timeExpiredText": "Nag-expire Na Ang Oras!", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Tip", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Pangunahing Kaibigan", + "tournamentCheckingStateText": "Sinusuri ang estado ng paligsahan; pakihintay...", + "tournamentEndedText": "Natapos na ang paligsahan na ito. Magsisimula ng bago mamaya.", + "tournamentEntryText": "Pagpasok sa Paligsahan", + "tournamentResultsRecentText": "Mga Resulta ng Kamakailang Paligsahan", + "tournamentStandingsText": "Mga Paninindigan sa Paligsahan", + "tournamentText": "Paligsahan", + "tournamentTimeExpiredText": "Na-expire Na Ang Oras Ng Paligsahan", + "tournamentsDisabledWorkspaceText": "Naka-disable ang mga paligsahan kapag aktibo ang mga workspace. \nHuwag munang paganahin muli ang iyong workspace at i-restart upang makipaglaro sa paligsahan.", + "tournamentsText": "Mga Paligsahan", + "translations": { + "characterNames": { + "Agent Johnson": "Ahente Johnson", + "B-9000": "B-9000", + "Bernard": "Oso", + "Bones": "Buto", + "Butch": "Bakero", + "Easter Bunny": "Kuneho", + "Flopsy": "Malambot", + "Frosty": "Taong Niyebe", + "Gretel": "Mag-aawit Na Manananggal", + "Grumbledorf": "Manggagaway", + "Jack Morgan": "Pirata", + "Kronk": "Salbahe", + "Lee": "Lee", + "Lucky": "Swerte", + "Mel": "Malagkitang Pagluto", + "Middle-Man": "Astig Na Lalaki", + "Minimus": "Minimus", + "Pascal": "Ibong Lamig", + "Pixel": "Diwata", + "Sammy Slam": "Mambubuno", + "Santa Claus": "Santa Klaus", + "Snake Shadow": "Aninong Balatkayo", + "Spaz": "Kawal", + "Taobao Mascot": "Taobao Maskot", + "Todd McBurton": "Todd McBurton", + "Zoe": "Dalagang Bombero", + "Zola": "Gererong Babae" + }, + "coopLevelNames": { + "${GAME} Training": "Pagsasanay Sa ${GAME}", + "Infinite ${GAME}": "Walang Katapusang ${GAME}", + "Infinite Onslaught": "Walang Katapusang Pagsalakay", + "Infinite Runaround": "Walang Katapusang Bantayan", + "Onslaught Training": "Pagsasanay Sa Pagsalakay", + "Pro ${GAME}": "Batidong ${GAME}", + "Pro Football": "Batidong Rugbi", + "Pro Onslaught": "Batidong Pagsalakay", + "Pro Runaround": "Batidong Bantayan", + "Rookie ${GAME}": "Bagitong ${GAME}", + "Rookie Football": "Bagitong Rugbi", + "Rookie Onslaught": "Bagitog Pagsalakay", + "The Last Stand": "Ang Huling Labanan", + "Uber ${GAME}": "Kasukdulang ${GAME}", + "Uber Football": "Kasukdulang Rugbi", + "Uber Onslaught": "Kasukdulang Pagsalakay", + "Uber Runaround": "Kasukdulang Bantayan" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Maging ang napili ng tiyak na oras para manalo.\nPatayin ang napili para maging isa nito.", + "Bomb as many targets as you can.": "Bomba ng maraming target hangga't maaari mo.", + "Carry the flag for ${ARG1} seconds.": "Hawakan ang bandila sa loob ng ${ARG1} segundo.", + "Carry the flag for a set length of time.": "Hawakan ang bandila para sa isang nakatakdang haba ng oras.", + "Crush ${ARG1} of your enemies.": "Patayin ang ${ARG1} ng iyong mga kalaban", + "Defeat all enemies.": "Talunin ang lahat ng iyong mga kalaban", + "Dodge the falling bombs.": "Umiwas sa mga bumabagsak na bomba.", + "Final glorious epic slow motion battle to the death.": "Huling maluwalhating epic slow motion na labanan hanggang kamatayan.", + "Gather eggs!": "Ipunin ng mga itlog!", + "Get the flag to the enemy end zone.": "Kunin ang bandila sa end zone ng kalaban.", + "How fast can you defeat the ninjas?": "Gaano kabilis mo matatalo ang mga ninja?", + "Kill a set number of enemies to win.": "Pumatay ng isang set na bilang ng mga kalaban upang manalo.", + "Last one standing wins.": "Kung sino ang huling nakatayo ang siyang mananalo.", + "Last remaining alive wins.": "Kung sino ang huling natitirang buhay ang siyang mananalo.", + "Last team standing wins.": "Kung sino ang huling katayuan ng koponan ang siyang mananalo", + "Prevent enemies from reaching the exit.": "Pigilan ang mga kalaban na makarating at makalabas sa labasan.", + "Reach the enemy flag to score.": "Abutin ang bandila ng kalaban upang maka-iskor.", + "Return the enemy flag to score.": "Ibalik ang watawat ng kalaban upang maka-iskor.", + "Run ${ARG1} laps.": "Tumakbo ng ${ARG1} ikot", + "Run ${ARG1} laps. Your entire team has to finish.": "Tumakbo ng {ARG1} ikot. Kailangang matapos ang iyong buong team na ito.", + "Run 1 lap.": "Tumakbo ng 1 ikot.", + "Run 1 lap. Your entire team has to finish.": "Tumakbo ng 1 ikot. Kailangang matapos ang iyong buong team na ito.", + "Run real fast!": "Tumakbo ng mabilis!", + "Score ${ARG1} goals.": "Makaiskor ng ${ARG1} gol.", + "Score ${ARG1} touchdowns.": "Makaiskor ng ${ARG1} touchdowns.", + "Score a goal.": "Makaiskor ng isang gol.", + "Score a touchdown.": "Makaiskor ng isang touchdown.", + "Score some goals.": "Makaiskor ng ilang gol.", + "Secure all ${ARG1} flags.": "Bantayinang lahat ng ${ARG1} na bandila.", + "Secure all flags on the map to win.": "Bantayin ang lahat ng mga bandila sa mapa na ito upang manalo.", + "Secure the flag for ${ARG1} seconds.": "Bantayin ang bandila ng ${ARG1} segundo", + "Secure the flag for a set length of time.": "Bantayin ang banila sa isang nakatakdang haba ng oras.", + "Steal the enemy flag ${ARG1} times.": "Nakawin ang watawat ng kalaban ng ${ARG1} beses.", + "Steal the enemy flag.": "Nakawin ang watawat ng kalaban.", + "There can be only one.": "Maaaring isa lamang dito.", + "Touch the enemy flag ${ARG1} times.": "Humawak sa bandera ng iyong kalaban ng ${ARG1} beses.", + "Touch the enemy flag.": "Humawak sa bandera ng iyong kalaban.", + "carry the flag for ${ARG1} seconds": "Hawakan ang bandila ng ${ARG1} segundo", + "kill ${ARG1} enemies": "patayin ang ${ARG1} na mga kalaban.", + "last one standing wins": "kung sino ang huling nakatayo ang siyang mananalo", + "last team standing wins": "kung sino ang huling katayuan ng team ang siyang mananalo", + "return ${ARG1} flags": "Magnakaw ng ${ARG1} na mga bandera", + "return 1 flag": "ibalik ang 1 bandila", + "run ${ARG1} laps": "Tumakbo ng ${ARG1} ikot", + "run 1 lap": "tumakbo ng 1 ikot", + "score ${ARG1} goals": "makaiskor ng ${ARG1} gol", + "score ${ARG1} touchdowns": "makaiskor ng ${ARG1} touchdowns", + "score a goal": "makaiskor ng isang gol.", + "score a touchdown": "makaiskor ng isang touchdown.", + "secure all ${ARG1} flags": "bantayin ang lahat ng ${ARG1} na bandila", + "secure the flag for ${ARG1} seconds": "bantayin ang bandila ng ${ARG1} segundo", + "touch ${ARG1} flags": "humawak ng ${ARG1} na mga bandila", + "touch 1 flag": "humawak ng 1 bandila" + }, + "gameNames": { + "Assault": "Pag-atake", + "Capture the Flag": "Kunin ang Bandila", + "Chosen One": "Napili ang Isa", + "Conquest": "Pagsakop", + "Death Match": "Laban ng Kamatayan", + "Easter Egg Hunt": "Paghahanap ng mga Easter Egg", + "Elimination": "Kaligtasan", + "Football": "Rugbi", + "Hockey": "Hockey", + "Keep Away": "Layuan Mo", + "King of the Hill": "Hari ng Burol", + "Meteor Shower": "Ulan ng mga Bulalakaw", + "Ninja Fight": "Labanan ng mga Ninja", + "Onslaught": "Pagsalakay", + "Race": "Takbuan", + "Runaround": "Bantayan", + "Target Practice": "Pagsasanay ng Patamaan", + "The Last Stand": "Ang Huling Labanan" + }, + "inputDeviceNames": { + "Keyboard": "Keyboard", + "Keyboard P2": "Keyboard F2" + }, + "languages": { + "Arabic": "Arabe", + "Belarussian": "Belaruso", + "Chinese": "Tsino", + "ChineseTraditional": "Tsinong Tradisyonal", + "Croatian": "Kroatyano", + "Czech": "Tsek", + "Danish": "Makadenmark", + "Dutch": "Olandes", + "English": "Ingles", + "Esperanto": "Esperanto", + "Filipino": "Tagalog", + "Finnish": "Finnish", + "French": "Pranses", + "German": "Aleman", + "Gibberish": "Walang Kwentang Linguahe", + "Greek": "Griyego", + "Hindi": "Indiyano", + "Hungarian": "Hanggaryan", + "Indonesian": "Indonesiyo", + "Italian": "Italiyano", + "Japanese": "Nippongo", + "Korean": "Koreano", + "Malay": "Malay", + "Persian": "Persyano", + "Polish": "Polish", + "Portuguese": "Portuges", + "Romanian": "Rumano", + "Russian": "Ruso", + "Serbian": "Serbyan", + "Slovak": "Eslobako", + "Spanish": "Espanyol", + "Swedish": "Suweko", + "Tamil": "Tamil", + "Thai": "Siyam", + "Turkish": "Turko", + "Ukrainian": "Ukranyo", + "Venetian": "Benesiya", + "Vietnamese": "Byetnam" + }, + "leagueNames": { + "Bronze": "Tanso", + "Diamond": "Diyamante", + "Gold": "Ginto", + "Silver": "Pilak" + }, + "mapsNames": { + "Big G": "Malaking G", + "Bridgit": "Tawiring Tulay", + "Courtyard": "Looban Patyo", + "Crag Castle": "Kastilyong Bangin", + "Doom Shroom": "Itim na Kabute", + "Football Stadium": "Istadyum", + "Happy Thoughts": "Masayang Isip", + "Hockey Stadium": "Istadyum ng Hockey", + "Lake Frigid": "Yelong Lawa", + "Monkey Face": "Mukha ng Unggoy", + "Rampage": "Mandaluhong", + "Roundabout": "Paliguy-ligoy", + "Step Right Up": "Hakbang Pataas", + "The Pad": "Ang Pad", + "Tip Top": "Tulis na Mataas", + "Tower D": "Taasang D", + "Zigzag": "Sigsag" + }, + "playlistNames": { + "Just Epic": "Epic Lang", + "Just Sports": "Shorts Lang" + }, + "scoreNames": { + "Flags": "Watawat", + "Goals": "Layunin", + "Score": "Iskor", + "Survived": "Nakaligtas", + "Time": "Oras", + "Time Held": "Oras na Gaganapin" + }, + "serverResponses": { + "A code has already been used on this account.": "Nagamit na ang isang code sa account na ito.", + "A reward has already been given for that address.": "Naibigay na ang reward para sa address na iyon.", + "Account linking successful!": "Matagumpay ang pag-link ng account!", + "Account unlinking successful!": "Matagumpay ang pag-unlink ng account!", + "Accounts are already linked.": "Naka-link na ang mga account.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Hindi ma-verify ang ad view.\nMangyaring siguraduhin na ikaw ay nagpapatakbo ng isang opisyal at bago na bersyon ng laro.", + "An error has occurred; (${ERROR})": "May nangyaring pagakamali; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "May nangyaring pagakamali; mangyaring makipag-ugnayan sa contact support. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "May nangyaring pagakamali; mangyaring makipag-ugnayan sa support@froemling.net.", + "An error has occurred; please try again later.": "May nangyaring pagakamali; Subukang muli mamaya.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Sigurado ka bang gusto mong i-link ang mga account na ito?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nHindi na ito maaaring bawiin!", + "BombSquad Pro unlocked!": "Na-unlock ang BombSquad Pro!", + "Can't link 2 accounts of this type.": "Hindi ma-link ang 2 account na may ganitong uri.", + "Can't link 2 diamond league accounts.": "Hindi ma-link ang 2 dyamante na ligang account.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Hindi ma-link; ito ay lalampas sa maximum na ${COUNT} na naka-link na account.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Natukoy ang pagdadaya; nasuspinde ang mga iskor at premyo sa loob ng ${COUNT} (na) araw.", + "Could not establish a secure connection.": "Hindi makapagtatag ng secure na koneksyon.", + "Daily maximum reached.": "Naabot na ang pang-araw-araw ng request.", + "Entering tournament...": "Papasok sa paligsahan…", + "Invalid code.": "Di-wastong code.", + "Invalid payment; purchase canceled.": "Di-wastong pagbabayad; kinansela ang pagbili.", + "Invalid promo code.": "Di-wastong promo code.", + "Invalid purchase.": "Di-wastong bilihin", + "Invalid tournament entry; score will be ignored.": "Di-wastong entry sa paligsahan; hindi papansinin ang mga iskor.", + "Item unlocked!": "Na-unlock ang aytem!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "TINANGGI ANG PAG-LINK. ang ${ACCOUNT} na ito\nay may makabuluhang data na maaaring MAWAWALA LAHAT.\nMaaari kang mag-link sa kabaligtaran na pagkakasunud-sunod kung gusto mo\n(at sa halip ay mawala ang data ng account na ITO)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "I-link ang account na ${ACCOUNT} sa account na ito?\nMawawala ang lahat ng umiiral na data sa ${ACCOUNT}.\nHindi na ito maaaring bawiin. Sigurado ka ba?", + "Max number of playlists reached.": "Naabot na ang maximum na bilang ng mga playlist.", + "Max number of profiles reached.": "Naabot na ang maximum na bilang ng mga profile.", + "Maximum friend code rewards reached.": "Naabot ang maximum na mga reward sa code ng kaibigan.", + "Message is too long.": "Ang mensahe ay napakahaba.", + "No servers are available. Please try again soon.": "Walang makakuha na mga server. Pakisubukang muli sa lalong madaling oras.", + "Profile \"${NAME}\" upgraded successfully.": "Matagumpay na na-upgrade ang profile na \"${NAME}\".", + "Profile could not be upgraded.": "Hindi ma-upgrade ang profile.", + "Purchase successful!": "Matagumpay ang pagbili!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Nakatanggap ng ${COUNT} na tiket para sa pag-sign in.\nBumalik bukas para makatanggap ng ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Hindi na sinusuportahan ang functionality ng server sa bersyong ito ng laro;\nMangyaring mag-update sa isang mas bagong bersyon.", + "Sorry, there are no uses remaining on this code.": "Pasensya na, wala nang natitirang gamit sa code na ito.", + "Sorry, this code has already been used.": "Pasensya na, nagamit na ang code na ito.", + "Sorry, this code has expired.": "Pasensya na, nag-expire na ang code na ito.", + "Sorry, this code only works for new accounts.": "Pasensya na, gumagana lang ang code na ito para sa mga bagong account.", + "Still searching for nearby servers; please try again soon.": "Naghahanap pa rin ng mga kalapit na server; mangyaring subukan muli sa lalong madaling oras.", + "Temporarily unavailable; please try again later.": "Pansamantalang hindi magagamit; Subukang muli mamaya.", + "The tournament ended before you finished.": "Natapos ang tournament bago ka natapos.", + "This account cannot be unlinked for ${NUM} days.": "Ang account na ito ay hindi maaaring i-unlink sa loob ng ${NUM} (na) araw.", + "This code cannot be used on the account that created it.": "Hindi magagamit ang code na ito sa account na lumikha nito.", + "This is currently unavailable; please try again later.": "Ito ay kasalukuyang hindi magagamit; Subukang muli mamaya.", + "This requires version ${VERSION} or newer.": "Nangangailangan ito ng bersyon na ${VERSION} o mas bago.", + "Tournaments disabled due to rooted device.": "Na-disable ang mga tournament dahil sa na-root na device.", + "Tournaments require ${VERSION} or newer": "Ang mga paligsahan ay nangangailangan ng ${VERSION} o mas bago", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "I-unlink ang ${ACCOUNT} mula sa account na ito?\nIre-reset ang lahat ng data sa ${ACCOUNT}.\n(maliban sa mga nakamit sa ilang pagkakataon)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "BABALA: ang mga reklamo ng pag-hack ay inilabas laban sa iyong account.\nIpagbabawal ang mga account na makikitang nagha-hack. Mangyaring maglaro ng patas.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Gusto mo bang i-link ang iyong device account sa isang ito?\n\nAng iyong device account ay ${ACCOUNT1}\nAng account na ito ay ${ACCOUNT2}\n\nPapayagan ka nitong panatilihin ang iyong progress.\nBabala: hindi na ito maaaring bawiin!", + "You already own this!": "Nabili mo na ito!", + "You can join in ${COUNT} seconds.": "Makakasali ka sa loob ng ${COUNT} segundo.", + "You don't have enough tickets for this!": "Hindi sapat ang tickets mo para dito!", + "You don't own that.": "Hindi sayo iyan.", + "You got ${COUNT} tickets!": "Nakakuha ka ng ${COUNT} tickets!", + "You got a ${ITEM}!": "Nakakuha ka ng ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Na-promote ka sa isang bagong liga; congrats!", + "You must update to a newer version of the app to do this.": "Dapat kang mag-update sa mas bagong bersyon ng app para magawa ito.", + "You must update to the newest version of the game to do this.": "Dapat kang mag-update sa pinakabagong bersyon ng laro upang magawa ito.", + "You must wait a few seconds before entering a new code.": "Dapat kang maghintay ng ilang segundo bago maglagay ng bagong code.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ikaw ay niraranggo ng #${RANK} sa huling paligsahan. Salamat sa paglalaro!", + "Your account was rejected. Are you signed in?": "Tinanggihan ang iyong account. Naka-sign in ka ba?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ang iyong kopya ng laro ay na-modified.\nMangyaring ibalik ang anumang mga pagbabago at subukang muli.", + "Your friend code was used by ${ACCOUNT}": "Ang code ng iyong kaibigan ay ginamit ng ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minuto", + "1 Second": "1 Segundo", + "10 Minutes": "10 Minuto", + "2 Minutes": "2 minuto", + "2 Seconds": "2 segundo", + "20 Minutes": "20 minuto", + "4 Seconds": "4 segundo", + "5 Minutes": "5 minuto", + "8 Seconds": "8 segundo", + "Allow Negative Scores": "Payagan ang Mga Negatibong Iskor", + "Balance Total Lives": "Balansehin ang Kabuuang Buhay", + "Bomb Spawning": "Paglitaw ng Bomba", + "Chosen One Gets Gloves": "Ang Isa Sa Napili Ay Makukuha Ng Gloves", + "Chosen One Gets Shield": "Ang Isa Sa Napili Ay Makukuha Ng Kalasag", + "Chosen One Time": "Oras Ng Isa Sa Napili", + "Enable Impact Bombs": "I-enable Ang Mga Gatilyong Bomba", + "Enable Triple Bombs": "I-enable Ang Mga Tatlong Bomba", + "Entire Team Must Finish": "Dapat Tapusin ng Buong Team.", + "Epic Mode": "Epic na Mode", + "Flag Idle Return Time": "Oras Ang Hindi Paggalaw Ng Watawat", + "Flag Touch Return Time": "Oras Sa Pag-balik Na Paghawak Ng Watawat", + "Hold Time": "Oras Ng Paghahawak", + "Kills to Win Per Player": "Pumapatay sa Pagpanalo Bawat Manlalaro", + "Laps": "Mga Lap", + "Lives Per Player": "Mga Buhay Bawat Manlalaro", + "Long": "Matagal", + "Longer": "Mas Matagal", + "Mine Spawning": "Lumilitaw Ng Mina", + "No Mines": "Bawal Ang Mina", + "None": "Wala", + "Normal": "Normal", + "Pro Mode": "Pangmagalingan Mode", + "Respawn Times": "Oras Sa Pag-respawn", + "Score to Win": "Iskor Para Manalo", + "Short": "Maikli", + "Shorter": "Mas Maikli", + "Solo Mode": "Mapagisa Mode", + "Target Count": "Bilang ng target", + "Time Limit": "Limitadong oras" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "Na-disqualify ang ${TEAM} dahil umalis si ${PLAYER}.", + "Killing ${NAME} for skipping part of the track!": "Pinapatayin si ${NAME} dahil sa paglaktaw sa bahagi ng track!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Babala kay ${NAME}: turbo / button-spamming ang pagpapatayin sayo." + }, + "teamNames": { + "Bad Guys": "Mga masasama", + "Blue": "Asul", + "Good Guys": "Mga mabubuti", + "Red": "Pula" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Ang isang perpektong naka-time na takbo-talon-ikot-suntok ay maaaring makapatay sa isang hit\nat magkaroon ka ng panghabambuhay na paggalang mula sa iyong mga kaibigan.", + "Always remember to floss.": "Laging tandaan na mag-floss.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Gumawa ng mga profile ng player para sa iyong sarili at sa iyong mga kaibigan\nang iyong mga gustong pangalan at hitsura sa halip na gumamit ng mga random.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Ginagawa ka ng sumpa sa isang ticking time na bomba.\nAng tanging lunas ay ang mabilisang kumuha ng health-pack.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Sa kabila ng kanilang hitsura, lahat ng kakayahan ng mga karakter ay magkapareho,\nkaya pumili lang kung alin ang pinakahawig mo.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Huwag masyadong maangas sa enerhiya na kalasag na iyon; ihahagis ka nila sa isang platform", + "Don't run all the time. Really. You will fall off cliffs.": "Huwag tumakbo sa lahat ng oras. Talaga. Mahuhulog ka sa platform", + "Don't spin for too long; you'll become dizzy and fall.": "Huwag paikutin nang masyadong mahaba; mahihilo ka at mahulog.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Pindutin ang anumang pindutan upang tumakbo. (Mahusay na gumagana ang mga pindutan ng pag-trigger kung mayroon ka nito)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Pindutin nang matagal ang anumang button para tumakbo. Mas mabilis kang makakakuha ng mga lugar\nngunit hindi lumiko nang mahusay, kaya mag-ingat sa matalim na mga gilid", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ang mga bomba ng yelo ay hindi masyadong malakas, ngunit nagyeyelo\nkung sino man ang kanilang natamaan, na nag-yelo sa kanila na madaling masira.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Kung may napulot sa iyo, suntukin mo siya at bibitaw siya.\nGumagana rin ito sa totoong buhay.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Kung kulang ka sa mga controller, i-install ang '${REMOTE_APP_NAME}' app\nsa iyong mga mobile device upang gamitin ang mga ito bilang mga controller.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Kung nakadikit sa iyo ang isang malagkit na bomba, tumalon at paikutin. Baka \ni-alis mo ang bomba, o kung wala na ang iyong mga huling sandali ay nakakaaliw.", + "If you kill an enemy in one hit you get double points for it.": "Kung pumatay ka ng isang kalaban sa isang hit makakakuha ka ng dobleng puntos para dito.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Kung nakatanggap ka ng sumpa, ang tanging pag-asa mo para mabuhay ay\nmaghanap ng health powerup sa susunod na ilang segundo.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Kung manatili ka sa isang lugar, toasted ka. Tumakbo at umigtad para mabuhay..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Kung marami kang manlalaro na dumarating at pupunta, i-on ang 'auto-kick-ng-idle-na-manlalaro’\nsa ilalim ng mga setting kung sakaling may makakalimutang umalis sa laro.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Kung masyadong mainit ang iyong device o gusto mong makatipid ng baterya,\ni-down ang \"Biswal” o \"Resolusyon\" sa Mga Setting->Grapika", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Kung hindi mabuti ang iyong framerate, subukang ibaba ang resolusyon\no mga biswal sa mga setting ng grapika ng laro.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Sa Kunin-ang-Bandila, ang iyong sariling bandila ay dapat nasa iyong base para makaiskor, Kung ang isa\nang team ay malapit nang makapuntos, ang pagnanakaw ng kanilang bandila ay maaaring maging isang magandang paraan upang pigilan sila.", + "In hockey, you'll maintain more speed if you turn gradually.": "Sa hockey, mapapanatili mo ang higit na bilis kung unti-unti kang lumiko.", + "It's easier to win with a friend or two helping.": "mas madaling manalo sa tulong ng isa o dalawang kaibigan.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Tumalon habang humagis upang makakuha ng mga bomba hanggang sa pinakamataas na antas.", + "Land-mines are a good way to stop speedy enemies.": "Ang mga mina ay isang mahusay na paraan upang pigilan ang mabilis na mga kalaban.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Maraming bagay ang maaaring kunin at ihagis, kabilang ang iba pang mga manlalaro. Paghahagis\nang iyong mga kalaban mula sa mga gilid ay maaaring maging isang epektibo at emosyonal na diskarte.", + "No, you can't get up on the ledge. You have to throw bombs.": "Hindi, hindi ka makakabangon sa pag-ungos. Kailangan mong maghagis ng bomba.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Maaaring sumali at umalis ang mga manlalaro sa gitna ng karamihan ng mga laro,\nat maaari mo ring isaksak at i-unplug ang mga controller nang mabilis.", + "Practice using your momentum to throw bombs more accurately.": "Magsanay gamit ang iyong momentum para maghagis ng mga bomba nang mas tumpak.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Ang mga suntok ay mas nagdudulot ng saktan sa mas mabilis na paggalaw ng iyong mga kamay,\nkaya subukang tumakbo, tumalon, at umiikot na parang baliw.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Patakbong pabalik-balik bago maghagis ng bomba\nupang ‘ma-ikot’ ito at ihagis ito nang mas malayo.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Ilabas ang isang grupo ng mga kalaban sa pamamagitan ng\nnaglalagay ng bomba malapit sa isang TNT box.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Ang ulo ay ang pinaka-mahina na lugar, kaya isang malagkit-bomba \nna lumapag sa ulo mo ay game-over na.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Ang level na ito ay hindi kailanman nagtatapos, ngunit isang mataas na iskor dito\nbibigyan ka ng walang hanggang paggalang sa buong mundo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Ang lakas ng paghagis ay batay sa direksyon na iyong hinahawakan.\nUpang ihagis ang isang bagay nang malumanay sa harap mo, huwag humawak sa anumang direksyon.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Pagod na sa mga soundtrack? Palitan nito ng iyong sarili!\nTingnan ang Mga Setting->Audio->Soundtrack", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Try mo ‘I-timing” ang mga bomba sa isang segundo o dalawa bag mo ihagis.", + "Try tricking enemies into killing eachother or running off cliffs.": "Subukang linlangin ang mga kalaban sa pagpatay sa isa't isa o pahulog sa mga gilid.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Gamitin ang pick-up button para kunin ang bandera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Paikut-ikot upang makakuha ng higit na distansya sa iyong mga paghagis..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Maaari mong 'itutok' ang iyong mga suntok sa pamamagitan ng pag-ikot pakaliwa o pakanan.\nIto ay kapaki-pakinabang para sa pagtanggal ng mga kalaban sa mga gilid o pag-iskor sa hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Maaari mong hatulan kung kailan sasabog ang isang bomba batay sa\nkulay ng sparks mula sa fuse nito: Dilaw..Kahel..Pula..SABOG.", + "You can throw bombs higher if you jump just before throwing.": "Maaari kang maghagis ng mga bomba nang mas mataas kung tumalon ka bago ihagis.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Pwede kang masaktan kapag natamaan mo ang iyong ulo sa mga bagay,\nkaya't subukang huwag ipilit ang iyong ulo sa iyan.", + "Your punches do much more damage if you are running or spinning.": "Ang iyong mga suntok ay nagdudulot ng higit na damage kung ikaw ay tumatakbo o umiikot." + } + }, + "trophiesRequiredText": "Nangangailangan ito ng ${NUMBER} na trophies.", + "trophiesText": "Mga Tropeo", + "trophiesThisSeasonText": "Mga Tropeo Ngayong Season", + "tutorial": { + "cpuBenchmarkText": "Pagpapatakbo ng tutorial sa nakakatawang bilis (pangunahing test sa bilis ng CPU)", + "phrase01Text": "Kamusta!", + "phrase02Text": "Maligayang pagdating sa ${APP_NAME}!", + "phrase03Text": "Narito ang ilang mga tip para sa pagkontrol ng iyong karakter:", + "phrase04Text": "Maraming bagay sa ${APP_NAME} ang nakabatay sa PISIKA", + "phrase05Text": "Halimbawa, kapag sumuntok ka,..", + "phrase06Text": "..binase ang damage sa bilis ng mga kamay mo.", + "phrase07Text": "Kita mo? Hindi kami gumagalaw, kaya halos hindi nasaktan si ${NAME}", + "phrase08Text": "Ngayon, tumalon at umikot tayo upang makakuha ng higit na bilis.", + "phrase09Text": "Ayan, mas maganda", + "phrase10Text": "Ang pagtakbo ay nakakatulong din.", + "phrase11Text": "Pindutin nang matagal ang KAHIT ANONG pindutan para tumakbo.", + "phrase12Text": "Para sa sobrang kahanga-hangang mga suntok, subukang tumakbo AT umikot.", + "phrase13Text": "Oops; pasensya na ${NAME}.", + "phrase14Text": "Maaari mong kunin at ihagis ang mga bagay tulad ng mga bandera.. o si ${NAME}.", + "phrase15Text": "Sa huli, meron pampasabog", + "phrase16Text": "Ang paghagis ng bomba ay kailangan may practice", + "phrase17Text": "Aray! Hindi napakahusay na hagis.", + "phrase18Text": "Ang paggalaw ay nakakatulong sa iyo na ihagis ng mas malayo.", + "phrase19Text": "Ang pagtalon tumutulong para matapon mo na masmataas", + "phrase20Text": "Ikot at ihagis ang iyong mga bomba para sa mas mahabang paghagis.", + "phrase21Text": "Ang pagtiming sa bomba ay pwedeng tricky", + "phrase22Text": "Aba.", + "phrase23Text": "Subukang “i-timing” fuse para sa isang segundo o dalawa.", + "phrase24Text": "Yay! Magaling na gawa.", + "phrase25Text": "Well, hanggang doon lang.", + "phrase26Text": "Ngayon kunin mo sila, tigre!", + "phrase27Text": "Alalahanin ang iyong pagsasanay, at babalik KANG buhay!", + "phrase28Text": "...siguro...", + "phrase29Text": "Paalam!", + "randomName1Text": "Fernandez", + "randomName2Text": "Angelo", + "randomName3Text": "Stephen", + "randomName4Text": "Joshua", + "randomName5Text": "Villar", + "skipConfirmText": "Sure ka ba na i-skip ang tutorial? Tap o pindutin para ma i-confirm.", + "skipVoteCountText": "${COUNT}/${TOTAL} boto na gustong laktawan", + "skippingText": "Nilalaktawan ang tutorial", + "toSkipPressAnythingText": "(i-tap o pindutin ang anuman para laktawan ang tutorial)" + }, + "twoKillText": "DOBLENG PAGPATAY!!", + "unavailableText": "hindi available", + "unconfiguredControllerDetectedText": "Naktuklas ang hindi naka-configure na controller:", + "unlockThisInTheStoreText": "Ito ay dapat na naka-unlock sa tindahan.", + "unlockThisProfilesText": "Upang lumikha ng higit sa ${NUM} na mga profile, kailangan mo:", + "unlockThisText": "Upang i-unlock ito, kailangan mo ng:", + "unsupportedHardwareText": "Pasensya na, ang hardware na ito ay hindi suportado ng build na ito ng laro.", + "upFirstText": "Bumangon muna:", + "upNextText": "Susunod sa larong ${COUNT}:", + "updatingAccountText": "Ina-update ang iyong account...", + "upgradeText": "I-upgrade", + "upgradeToPlayText": "I-unlock ang \"${PRO}\" sa in-game store upang i-play ito.", + "useDefaultText": "Gamitin ang default", + "usesExternalControllerText": "Gumagamit ang larong ito ng external na controller para sa input.", + "usingItunesText": "Paggamit ng Music App para sa soundtrack...", + "v2AccountLinkingInfoText": "Upang ma-link ang mga V2 account mo, dumeretso ka sa “I-Manage ang Account“.", + "validatingTestBuildText": "Pinapatunayan ang Test Build...", + "victoryText": "Panalo!", + "voteDelayText": "Hindi ka makapagsimula ng bagong botohan sa ${NUMBER} segundo", + "voteInProgressText": "Ang pagboboto ay isinasagawa na.", + "votedAlreadyText": "Nakaboto ka na", + "votesNeededText": "Kailangan ng ${NUMBER} (na) boto", + "vsText": "vs.", + "waitingForHostText": "(naghihintay para kay ${HOST} na magpatuloy)", + "waitingForPlayersText": "naghihintay ng mga manlalaro na sumali...", + "waitingInLineText": "Naghihintay sa pila (puno ang party)...", + "watchAVideoText": "Manood ng Isang video", + "watchAnAdText": "Manood ng Ad", + "watchWindow": { + "deleteConfirmText": "Tangalin ang \"${REPLAY}\"?", + "deleteReplayButtonText": "Itanggal ang \nReplay", + "myReplaysText": "Ang Mga Replay Ko", + "noReplaySelectedErrorText": "Walang Napiling Replay", + "playbackSpeedText": "Bilis ng Pag-playback: ${SPEED}", + "renameReplayButtonText": "I-palitan ang\nReplay", + "renameReplayText": "Palitan ang pangalan ng \"${REPLAY}\" sa:", + "renameText": "I-palitan", + "replayDeleteErrorText": "Error sa pagtanggal ng replay", + "replayNameText": "Pangalan ng Replay", + "replayRenameErrorAlreadyExistsText": "Mayroon nang replay na may ganoong pangalan.", + "replayRenameErrorInvalidName": "Hindi mapalitan ang pangalan ng replay; hindi wastong pangalan.", + "replayRenameErrorText": "Error sa pagpapalit ng pangalan ng replay.", + "sharedReplaysText": "Ang mga binigay na replays", + "titleText": "Manood", + "watchReplayButtonText": "Ipanood ang\nReplay" + }, + "waveText": "Kaway", + "wellSureText": "Oo Syempre!", + "whatIsThisText": "Ano ito?", + "wiimoteLicenseWindow": { + "titleText": "Copyright ni DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "Nakikinig sa Wiimote...", + "pressText": "Pindutin ang mga pindutan ng Wiimote 1 at 2 nang sabay-sabay.", + "pressText2": "Sa mas bagong Wiimotes na may built in na Motion Plus, pindutin na lang ang pulang 'sync' na button sa likod." + }, + "wiimoteSetupWindow": { + "copyrightText": "Copyright ni DarwinRemote", + "listenText": "Makinig", + "macInstructionsText": "Tiyaking naka-off ang iyong Wii at naka-enable ang Bluetooth\nsa iyong Mac, pagkatapos ay pindutin ang 'Makinig'. Maaari ang suporta ng Wiimote\nmaging medyo patumpik-tumpik, kaya maaaring kailanganin mong subukan ng ilang beses\nbago ka magkaroon ng koneksyon.\n\nDapat hawakan ng Bluetooth ang hanggang 7 konektadong device,\nkahit na ang iyong mileage ay maaaring mag-iba.\n\nSinusuportahan ng BombSquad ang orihinal na Wiimotes, Nunchuks,\nat ang Klasikong Controller.\nGumagana na rin ang mas bagong Wii Remote Plus\nngunit hindi sa mga kalakip.", + "thanksText": "Salamat sa DarwiinRemote team\nPara maging posible ito.", + "titleText": "Pag-setup ng Wiimote" + }, + "winsPlayerText": "Nanalo si ${NAME}!", + "winsTeamText": "Nanalo ang ${NAME}!", + "winsText": "${NAME} Nanalo!", + "workspaceSyncErrorText": "Error sa pag-sync ng ${WORKSPACE}. Tingnan ang log para sa mga detalye.", + "workspaceSyncReuseText": "Hindi ma-sync ang ${WORKSPACE}. Muling paggamit ng nakaraang naka-sync na bersyon.", + "worldScoresUnavailableText": "Ang scores sa buong mundo ay hindi pa handa", + "worldsBestScoresText": "Pinakamahusay na Iskor ng Mundo", + "worldsBestTimesText": "Oras ng Pinakamahusay sa Mundo", + "xbox360ControllersWindow": { + "getDriverText": "Kunin ang Driver", + "macInstructions2Text": "Upang gumamit ng mga controller nang wireless, kakailanganin mo rin ang receiver na iyon\nay kasama ang 'Xbox 360 Wireless Controller para sa Windows'.\nPinapayagan ka ng isang receiver na kumonekta hanggang sa 4 na controllers.\n\nMahalaga: Ang mga 3rd-party na receiver ay hindi gagana sa driver na ito;\ntiyaking 'Microsoft' ang nakasulat dito sa iyong receiver, hindi 'XBOX 360'.\nHindi na ibinebenta ng Microsoft ang mga ito nang hiwalay, kaya kakailanganin mong makuha\nyung naka-bundle sa controller or else search ebay.\n\nKung sa tingin mo ay kapaki-pakinabang ito, mangyaring isaalang-alang ang isang donasyon sa\ndeveloper ng driver sa kanilang site.", + "macInstructionsText": "Upang magamit ang mga controller ng Xbox 360, kakailanganin mong mag-install\nang Mac driver na available sa link sa ibaba.\nGumagana ito sa parehong wired at wireless controllers.", + "ouyaInstructionsText": "Para gumamit ng mga wired na Xbox 360 controllers sa BombSquad, simple lang\nisaksak ang mga ito sa USB port ng iyong device. Maaari kang gumamit ng USB hub\nupang ikonekta ang maramihang mga controller.\n\nPara gumamit ng mga wireless na controller, kakailanganin mo ng wireless na receiver,\nmagagamit bilang bahagi ng \"Xbox 360 wireless Controller para sa Windows\"\npakete o ibinebenta nang hiwalay. Ang bawat receiver ay nakasaksak sa isang USB port at\nnagbibigay-daan sa iyong kumonekta ng hanggang 4 na wireless controllers.", + "titleText": "Ginagamit ang Xbox 360 Controllers sa ${APP_NAME}:" + }, + "yesAllowText": "Sige!", + "yourBestScoresText": "Pinakamataas Mong Iskor", + "yourBestTimesText": "Pinakamabilis Mong Oras" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/french.json b/dist/ba_data/data/languages/french.json new file mode 100644 index 0000000..873fadf --- /dev/null +++ b/dist/ba_data/data/languages/french.json @@ -0,0 +1,1989 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Les noms de compte ne peuvent pas contenir d'emoji ou d'autres caractères spéciaux", + "accountProfileText": "(profil compte)", + "accountsText": "Comptes", + "achievementProgressText": "Succès: ${COUNT} sur ${TOTAL}", + "campaignProgressText": "Progression de la campagne [Difficile]: ${PROGRESS}", + "changeOncePerSeason": "Vous ne pouvez changer cela qu'une fois par saison.", + "changeOncePerSeasonError": "Vous devez attendre la prochaine saison pour le modifier à nouveau (${NUM} jours)", + "customName": "Nom personnalisé", + "googlePlayGamesAccountSwitchText": "Si vous voulez utiliser un autre compte Google, \nutilisez l'application Google Play Games pour le changer.", + "linkAccountsEnterCodeText": "Entrer code", + "linkAccountsGenerateCodeText": "Générez votre code", + "linkAccountsInfoText": "(partager la progression entre différentes plateformes)", + "linkAccountsInstructionsNewText": "Pour lier deux comptes, générez un code sur le premier\net entrez ce code sur la seconde. Les données du\nle second compte sera ensuite partagé entre les deux.\n(Les données du premier compte seront perdues)\n\nVous pouvez lier jusqu' à ${COUNT} comptes.\n\nIMPORTANT: ne lier que les comptes que vous possédez; et\nSi vous créez un lien avec des comptes d'amis, vous ne pourrez pas\npouvoir jouer en ligne en même temps.", + "linkAccountsInstructionsText": "Pour lier deux comptes, générez un code sur l'un\nd'entre eux et entrer ce code sur l'autre.\nLes progrès et l'inventaire seront combinés.\nVous pouvez lier jusqu'à ${COUNT} comptes.\n\nIMPORTANT: reliez uniquement les comptes que vous possédez!\nSi vous reliez des comptes à vos amis, vous\nne pourrais pas jouer en même temps!\n\nAussi: cela ne peut actuellement pas être annulé, alors faites attention!", + "linkAccountsText": "Lier vos comptes", + "linkedAccountsText": "Comptes Liés:", + "manageAccountText": "Gérer compte", + "nameChangeConfirm": "Changer le nom de votre compte pour ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Ceci réinitialisera votre progression co-op et\nvos meilleurs scores locaux (mais pas vos tickets).\nCette action est irréversible. Êtes-vous certain(e)?", + "resetProgressConfirmText": "Ceci réinitialisera votre progression co-op,\nvos succès, et vos meilleurs scores\nlocaux (mais pas vos tickets). Cette action\nest irréversible. Êtes-vous certain(e)?", + "resetProgressText": "Réinitialiser votre progression", + "setAccountName": "Définir le nom du compte", + "setAccountNameDesc": "Sélectionnez le nom à afficher pour votre compte.\nVous pouvez utiliser le nom d'un de vos comptes\n associés ou créer un nom personnalisé unique.", + "signInInfoText": "Connectez-vous pour gagner des tickets, participer aux tournois en ligne,\net partager votre progression entre plusieurs appareils.", + "signInText": "Connexion", + "signInWithDeviceInfoText": "(un compte généré automatiquement utilisable seulement sur cet appareil)", + "signInWithDeviceText": "Connectez-vous avec le compte de cet appareil", + "signInWithGameCircleText": "Connectez-vous avec Game Circle", + "signInWithGooglePlayText": "Connectez-vous avec Google Play", + "signInWithTestAccountInfoText": "(ancien compte; utilisez les comptes de cet appareil pour les prochaines fois)", + "signInWithTestAccountText": "Connectez-vous avec un compte test", + "signInWithV2InfoText": "(un compte qui fonctionne sur toutes les plateformes)", + "signInWithV2Text": "Connectez-vous avec un compte Bombsquad", + "signOutText": "Se déconnecter", + "signingInText": "Connexion...", + "signingOutText": "Déconnexion...", + "testAccountWarningCardboardText": "Attention: vous êtes connectés avec un compte \"test\".\nIl va être remplacé par un comte Google lorsque ces\nderniers seront supportés dans les apps cardboard.\n\nPour l'instant vous devrez gagner les tickets en jeu.\n(vous pourrez cependant obtenir l'amélioration BombSquad Pro gratuitement)", + "testAccountWarningOculusText": "Attention: vous vous connectez avec un compte \"test\".\nIl sera remplacé par un compte Oculus plus tard cette année\nce qui incluera l'achat de tickets et de bien d'autres choses.\n\nPour l'instant, vous devez gagner les tickets en jeu.\n(Vous pourrez tout de même bénéficier de BombSquad Pro gratuitement)", + "testAccountWarningText": "Attention: vous vous connectez avec un compte \"test\".\nCe compte est relié à une machine spécifique et peut\nêtre effacé périodiquement. (ne passez trop de temps \ndessus pour débloquer/collecter des trucs svp)\n\nLancer une version officielle du jeu pour utiliser un\n\"vrai\" compte (Game-Center, Google Plus, etc.)\nCela vous permettra aussi de sauvegarder votre\nprogression dans le cloud et le partager avec vos\nautres machines. ", + "ticketsText": "Tickets: ${COUNT}", + "titleText": "Compte", + "unlinkAccountsInstructionsText": "Sélectionnez un compte à délier", + "unlinkAccountsText": "Délier des comptes", + "unlinkLegacyV1AccountsText": "Dissocier les anciens comptes (V1)", + "v2LinkInstructionsText": "Utiliser ce lien pour créer un compte ou se connecter.", + "viaAccount": "(via le compte ${NAME})", + "youAreLoggedInAsText": "Vous êtes connecté en temps que :", + "youAreSignedInAsText": "Vous êtes connecté(e) en tant que:" + }, + "achievementChallengesText": "Succès", + "achievementText": "Succès", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Éliminer 3 méchants avec une caisse de TNT", + "descriptionComplete": "Vous avez éliminé 3 méchants avec une caisse de TNT", + "descriptionFull": "Éliminer 3 méchants avec une caisse de TNT dans ${LEVEL}", + "descriptionFullComplete": "Vous avez éliminé 3 méchants avec une caisse de TNT dans ${LEVEL}", + "name": "La dynamite fait \"Boum\"" + }, + "Boxer": { + "description": "Gagner sans utiliser de bombes", + "descriptionComplete": "Vous avez gagné sans utiliser de bombes", + "descriptionFull": "Finir le niveau ${LEVEL} sans utiliser de bombes", + "descriptionFullComplete": "Vous avez fini ${LEVEL} sans utiliser de bombes", + "name": "Boxeur" + }, + "Dual Wielding": { + "descriptionFull": "Connecter 2 manettes (hardware ou app)", + "descriptionFullComplete": "Vous avez connecté 2 manettes (hardware ou app)", + "name": "Ambidextre" + }, + "Flawless Victory": { + "description": "Gagner sans égratinures", + "descriptionComplete": "Vous avez gagné sans une égratinure", + "descriptionFull": "Gagner ${LEVEL} sans égratinures", + "descriptionFullComplete": "Vous avez gagné ${LEVEL} sans une égratinure", + "name": "Victoire parfaite" + }, + "Free Loader": { + "descriptionFull": "Lancer une mêlée générale avec au moins 2 joueurs", + "descriptionFullComplete": "Vous avez lancé une mêlée générale avec au moins 2 joueurs", + "name": "Lanceurs en plus" + }, + "Gold Miner": { + "description": "Tuer 6 méchants avec des mines", + "descriptionComplete": "Vous avez tué 6 méchants avec des mines", + "descriptionFull": "Tuer 6 méchants avec des mines dans ${LEVEL}", + "descriptionFullComplete": "Vous avez tué 6 méchants avec des mines dans ${LEVEL}", + "name": "Chercheur d'Or" + }, + "Got the Moves": { + "description": "Gagner sans utiliser de bombes ou de gants de boxe", + "descriptionComplete": "Vous avez gagné sans utiliser de bombes ou de gants de boxe", + "descriptionFull": "Gagner ${LEVEL} sans utiliser de bombes ou de gants de boxe", + "descriptionFullComplete": "Vous avez gagné ${LEVEL} sans utiliser de bombes ou de gants de boxe", + "name": "Chorégraphe" + }, + "In Control": { + "descriptionFull": "Connecter une manette (hardware ou app)", + "descriptionFullComplete": "Vous avez connecté une manette. (hardware ou app)", + "name": "Sous Contrôle" + }, + "Last Stand God": { + "description": "Obtenir 1000 points", + "descriptionComplete": "Vous avez obtenu 1000 points", + "descriptionFull": "Obtenir 1000 point dans ${LEVEL}", + "descriptionFullComplete": "Vous avez obtenu 1000 points dans ${LEVEL}", + "name": "Dieu de ${LEVEL}" + }, + "Last Stand Master": { + "description": "Obtenir 250 points", + "descriptionComplete": "Vous avez obtenu 250 points", + "descriptionFull": "Obtenir 250 points dans ${LEVEL}", + "descriptionFullComplete": "Vous avez obtenu 250 points dans ${LEVEL}", + "name": "Maître de ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Obtenir 500 points", + "descriptionComplete": "Vous avez obtenu 500 points", + "descriptionFull": "Obtenir 500 points dans ${LEVEL}", + "descriptionFullComplete": "Vous avez obtenu 500 points dans ${LEVEL}", + "name": "Magicien de ${LEVEL}" + }, + "Mine Games": { + "description": "Tuer 3 méchants avec des mines", + "descriptionComplete": "Vous avez tué 3 méchants avec des mines", + "descriptionFull": "Tuer 3 méchants avec des mines dans ${LEVEL}", + "descriptionFullComplete": "Vous avez tué 3 méchants avec des mines dans ${LEVEL}", + "name": "Démineur" + }, + "Off You Go Then": { + "description": "Jeter 3 méchants hors du champ de bataille", + "descriptionComplete": "Vous avez jeté 3 méchants hors du champ de bataille", + "descriptionFull": "Jeter 3 méchants hors du champ de bataille dans ${LEVEL}", + "descriptionFullComplete": "Vous avez jeté 3 méchants hors du champ de bataille dans ${LEVEL}", + "name": "Bon Débarras" + }, + "Onslaught God": { + "description": "Obtenir 5000 points", + "descriptionComplete": "Vous avez obtenu 5000 points", + "descriptionFull": "Obtenir 5000 points dans ${LEVEL}", + "descriptionFullComplete": "Vous avez obtenu 5000 points dans ${LEVEL}", + "name": "Dieu de ${LEVEL}" + }, + "Onslaught Master": { + "description": "Obtenir 500 points", + "descriptionComplete": "Vous avez obtenu 500 points", + "descriptionFull": "Obtenir 500 points dans ${LEVEL}", + "descriptionFullComplete": "Vous avez obtenu 500 points dans ${LEVEL}", + "name": "Maître de ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Survivre à toutes les vagues", + "descriptionComplete": "Vous avez survécu à toutes les vagues", + "descriptionFull": "Survivre à toutes les vagues dans ${LEVEL}", + "descriptionFullComplete": "Vous avez survécu à toutes les vagues dans ${LEVEL}", + "name": "Victoire à ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Obtenir 1000 points", + "descriptionComplete": "Vous avez obtenu 1000 points", + "descriptionFull": "Obtenir 1000 points dans ${LEVEL}", + "descriptionFullComplete": "Vous avez obtenu 1000 points dans ${LEVEL}", + "name": "Magicien de ${LEVEL}" + }, + "Precision Bombing": { + "description": "Gagner sans utiliser de bonus", + "descriptionComplete": "Vous avez gagné sans utiliser de bonus", + "descriptionFull": "Gagner ${LEVEL} sans utiliser de bonus", + "descriptionFullComplete": "Vous avez gagné ${LEVEL} sans utiliser de bonus", + "name": "Bombardement précis" + }, + "Pro Boxer": { + "description": "Gagner sans utiliser de bombes", + "descriptionComplete": "Vous avez gagné sans utiliser de bombes", + "descriptionFull": "Compléter ${LEVEL} sans utiliser de bombes", + "descriptionFullComplete": "Vous avez complété ${LEVEL} sans utiliser de bombes", + "name": "Boxeur Professionnel" + }, + "Pro Football Shutout": { + "description": "Gagner sans laisser les méchants marquer", + "descriptionComplete": "Vous avez gagné sans laisser les méchants marquer", + "descriptionFull": "Gagner ${LEVEL} sans laisser les méchants marquer", + "descriptionFullComplete": "Vous avez gagné ${LEVEL} sans laisser les méchants marquer", + "name": "${LEVEL} Blanchissage" + }, + "Pro Football Victory": { + "description": "Gagner le match", + "descriptionComplete": "Vous avez gagné le match", + "descriptionFull": "Gagner le match dans ${LEVEL}", + "descriptionFullComplete": "Vous avez gagné le match dans ${LEVEL}", + "name": "Victoire dans ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Survivre à toutes les vagues", + "descriptionComplete": "Vous avez survécu à toutes les vagues", + "descriptionFull": "Survivre à toutes les vagues dans ${LEVEL}", + "descriptionFullComplete": "Vous avez survécu à toutes les vagues dans ${LEVEL}", + "name": "Victoire dans ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Compléter toutes les vagues", + "descriptionComplete": "Vous avez complété toutes les vagues", + "descriptionFull": "Compléter toutes les vagues dans ${LEVEL}", + "descriptionFullComplete": "Vous avez complété toutes les vagues dans ${LEVEL}", + "name": "Victoire dans ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Gagner sans laisser les méchants marquer", + "descriptionComplete": "Vous avez gagné sans laisser les méchants marquer", + "descriptionFull": "Gagner ${LEVEL} sans laisser les méchants marquer", + "descriptionFullComplete": "Vous avez gagné ${LEVEL} sans laisser les méchants marquer", + "name": "Blanchissage dans ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Gagner le match", + "descriptionComplete": "Vous avez gagné le match", + "descriptionFull": "Gagner le match dans ${LEVEL}", + "descriptionFullComplete": "Vous avez gagné le match dans ${LEVEL}", + "name": "Victoire dans ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Survivre à toutes les vagues", + "descriptionComplete": "Vous avez survécu à toutes les vagues", + "descriptionFull": "Vaincre toutes les vagues dans ${LEVEL}", + "descriptionFullComplete": "Vous avez vaincu toutes les vagues dans ${LEVEL}", + "name": "Victoire dans ${LEVEL}" + }, + "Runaround God": { + "description": "Obtenir 2000 points", + "descriptionComplete": "Vous avez obtenu 2000 points", + "descriptionFull": "Obtenir 2000 points dans ${LEVEL}", + "descriptionFullComplete": "Vous avez obtenu 2000 points dans ${LEVEL}", + "name": "Dieu de ${LEVEL}" + }, + "Runaround Master": { + "description": "Obtenir 500 points", + "descriptionComplete": "Vous avez obtenu 500 points", + "descriptionFull": "Obtenir 500 points dans ${LEVEL}", + "descriptionFullComplete": "Vous avez obtenu 500 points dans ${LEVEL}", + "name": "Maitre de ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Obtenir 1000 points", + "descriptionComplete": "Vous avez obtenu 1000 points", + "descriptionFull": "Obtenir 1000 points dans ${LEVEL}", + "descriptionFullComplete": "Vous avez obtenu 1000 points dans ${LEVEL}", + "name": "Magicien de ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Partager le jeu avec un ami", + "descriptionFullComplete": "Vous avez partagé le jeu avec un ami", + "name": "Partager c'est aimer" + }, + "Stayin' Alive": { + "description": "Gagner sans mourir", + "descriptionComplete": "Vous avez gagné sans mourir", + "descriptionFull": "Gagner ${LEVEL} sans mourir", + "descriptionFullComplete": "Vous avez gagné ${LEVEL} sans mourir", + "name": "Rester en vie" + }, + "Super Mega Punch": { + "description": "Infliger 100% de dommage avec un seul coup de poing", + "descriptionComplete": "Vous avez infligé 100% de dommage avec un seul coup de poing", + "descriptionFull": "Infliger 100% de dommage avec un seul coup de poing dans ${LEVEL}", + "descriptionFullComplete": "Vous avez infligé 100% de dommage avec un seul coup de poing dans ${LEVEL}", + "name": "One Punch Man" + }, + "Super Punch": { + "description": "Infliger 50% de dommage avec un seul coup de poing", + "descriptionComplete": "Vous avez infligé 50% de dommage avec un seul coup de poing", + "descriptionFull": "Infliger 50% de dommage avec un seul coup de poing dans ${LEVEL}", + "descriptionFullComplete": "Infliger 50% de dommage avec un seul coup de poing dans ${LEVEL}", + "name": "Poing d'acier" + }, + "TNT Terror": { + "description": "Tuer 6 méchants avec de la TNT", + "descriptionComplete": "Vous avez tué 6 méchants avec de la TNT", + "descriptionFull": "Tuer 6 méchants avec de la TNT dans ${LEVEL}", + "descriptionFullComplete": "Vous avez tué 6 méchants avec de la TNT dans ${LEVEL}", + "name": "Feu d'Artifice" + }, + "Team Player": { + "descriptionFull": "Lancer un jeu en équipe avec au moins 4 joueurs", + "descriptionFullComplete": "Vous avez lancé un jeu en équipe avec au moins 4 joueurs", + "name": "Esprit d'Équipe" + }, + "The Great Wall": { + "description": "Arrêter tous les méchants", + "descriptionComplete": "Vous avez arrêté tous les méchants", + "descriptionFull": "Arrêter tous les méchants dans ${LEVEL}", + "descriptionFullComplete": "Vous avez arrêté tous les méchants dans ${LEVEL}", + "name": "La Grande Muraille" + }, + "The Wall": { + "description": "Arrêter tous les méchants", + "descriptionComplete": "Vous avez arrêté tous les méchants", + "descriptionFull": "Arrêter tous les méchants dans ${LEVEL}", + "descriptionFullComplete": "Vous avez arrêté tous les méchants dans ${LEVEL}", + "name": "La Muraille" + }, + "Uber Football Shutout": { + "description": "Gagner sans laisser les méchants marqués", + "descriptionComplete": "Vous avez gagné sans laisser les méchants marqués", + "descriptionFull": "Gagner ${LEVEL} sans laisser les méchants marqués", + "descriptionFullComplete": "Vous avez gagné ${LEVEL} sans laisser les méchants marqués", + "name": "Blanchissage dans ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Gagner le match", + "descriptionComplete": "Vous avez gagné le match", + "descriptionFull": "Gagner le match dans ${LEVEL}", + "descriptionFullComplete": "Vous avez gagné le match dans ${LEVEL}", + "name": "Victoire dans ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Survivre à toutes les vagues", + "descriptionComplete": "Vous avez survécu à toutes les vagues", + "descriptionFull": "Survivre à toutes les vagues dans ${LEVEL}", + "descriptionFullComplete": "Vous avez survécu à toutes les vagues dans ${LEVEL}", + "name": "Victoire dans ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Compléter toutes les vagues", + "descriptionComplete": "Vous avez complété toutes les vagues", + "descriptionFull": "Compléter toutes les vagues dans ${LEVEL}", + "descriptionFullComplete": "Vous avez complété toutes les vagues dans ${LEVEL}", + "name": "Victoire dans ${LEVEL}" + } + }, + "achievementsRemainingText": "Succès restant à remporter :", + "achievementsText": "Succès", + "achievementsUnavailableForOldSeasonsText": "Désolé, les spécifications des succès ne sont pas disponibles pour les saisons passées.", + "activatedText": "${THING} activé.", + "addGameWindow": { + "getMoreGamesText": "Obtenir plus de jeux...", + "titleText": "Ajouter un Jeu" + }, + "allowText": "Autoriser", + "alreadySignedInText": "Votre compte est connecté sur un autre appareil;\nveuillez changer de compte ou fermez le jeu sur \nles autres appareils et réessayez.", + "apiVersionErrorText": "Impossible de charger le jeu ${NAME}; sa version api est ${VERSION_USED}; nous demandons la version ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" s'active seulement quand un casque est branché)", + "headRelativeVRAudioText": "Son à position relative (RV)", + "musicVolumeText": "Volume de la musique", + "soundVolumeText": "Volume des bruitages", + "soundtrackButtonText": "Bandes son", + "soundtrackDescriptionText": "(Ecouter votre propre musique durant les matchs)", + "titleText": "Son" + }, + "autoText": "Auto", + "backText": "Retour", + "banThisPlayerText": "Bannir ce joueur", + "bestOfFinalText": "Finale du meilleur en ${COUNT} points", + "bestOfSeriesText": "Premier à ${COUNT} points:", + "bestOfUseFirstToInstead": 1, + "bestRankText": "Votre meilleur est #${RANK}", + "bestRatingText": "Votre meilleure évaluation est ${RATING}", + "betaErrorText": "Cette version beta n'est plus active, veuillez rechercher la nouvelle version.", + "betaValidateErrorText": "Impossible de valider la beta. (pas de connection internet?)", + "betaValidatedText": "Version bêta validée ; bon jeu !", + "bombBoldText": "BOMBE", + "bombText": "Bombe", + "boostText": "Accroître", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} est configuré dans sa propre application.", + "buttonText": "bouton", + "canWeDebugText": "Voulez-vous que BombSquad envoie automatiquement un rapport des bugs, \ncrashs et certaines informations relatives au jeu au développeur?\n\nCes rapports ne contiendront aucune information personnelle \net aideront à maintenir un jeu sans bugs ni ralentissements.", + "cancelText": "Annuler", + "cantConfigureDeviceText": "Désolé, ${DEVICE} ne peut pas être configuré.", + "challengeEndedText": "Ce défi est terminé.", + "chatMuteText": "Tchat muet", + "chatMutedText": "Tchat muet", + "chatUnMuteText": "Réactiver tchat", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Vous devez compléter ce \nniveau pour continuer!", + "completionBonusText": "Bonus de fin", + "configControllersWindow": { + "configureControllersText": "Configurer les Manettes", + "configureGamepadsText": "Configurer les Manettes", + "configureKeyboard2Text": "Configurer Clavier J2", + "configureKeyboardText": "Configurer le Clavier", + "configureMobileText": "Appareils Mobiles comme Manettes", + "configureTouchText": "Configurer l'Ecran Tactile", + "ps3Text": "Manettes de PS3", + "titleText": "Manettes", + "wiimotesText": "Wiimotes", + "xbox360Text": "Manettes Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Note: le support varie selon l'appareil et la version Android.", + "pressAnyButtonText": "Appuyez sur n'importe quel bouton du support\nque vous voulez configurer...", + "titleText": "Configurer les manettes" + }, + "configGamepadWindow": { + "advancedText": "Avancé", + "advancedTitleText": "Configuration Avancée de la manette", + "analogStickDeadZoneDescriptionText": "(augmentez ceci si votre personnage bouge quand vous relachez le stick)", + "analogStickDeadZoneText": "Zone Morte du Stick Analogique", + "appliesToAllText": "(s'applique à toutes les manettes de ce type)", + "autoRecalibrateDescriptionText": "(activez ceci si votre personnage ne se déplace pas à vitesse normale)", + "autoRecalibrateText": "Recalibrage-Auto du Stick Analogique", + "axisText": "axe", + "clearText": "effacer", + "dpadText": "croix directionnelle", + "extraStartButtonText": "Bouton Start supplémentaire", + "ifNothingHappensTryAnalogText": "Si rien ne se passe, essayez plutôt d'assigner le stick analogique à la place.", + "ifNothingHappensTryDpadText": "Si rien ne se passe, essayez plutôt d'assigner à la croix directionnelle à la place.", + "ignoreCompletelyDescriptionText": "(empêcher cette manette d'interférer avec le jeu ou les menus)", + "ignoreCompletelyText": "Ignorer complètement", + "ignoredButton1Text": "Bouton Ignoré 1", + "ignoredButton2Text": "Bouton Ignoré 2", + "ignoredButton3Text": "Bouton Ignoré 3", + "ignoredButton4Text": "Bouton Ignoré 4", + "ignoredButtonDescriptionText": "(utilisez ceci pour empêcher les boutons 'home' ou 'sync' d’interférer avec l'interface)", + "ignoredButtonText": "Bouton Ignoré", + "pressAnyAnalogTriggerText": "Appuyez sur n'importe quelle commande analogique...", + "pressAnyButtonOrDpadText": "Appuyez sur n'importe quel bouton ou croix directionnelle...", + "pressAnyButtonText": "Appuyez sur n'importe quel bouton...", + "pressLeftRightText": "Appuyez à gauche ou à droite...", + "pressUpDownText": "Appuyez en haut ou en bas...", + "runButton1Text": "Appuyez sur le Bouton 1", + "runButton2Text": "Appuyez sur le Bouton 2", + "runTrigger1Text": "Appuyez sur la Gâchette 1", + "runTrigger2Text": "Appuyez sur la Gâchette 2", + "runTriggerDescriptionText": "(les gachettes analogiques vous permettent de courir à des vitesses variables)", + "secondHalfText": "Utilisez ceci pour configurer la deuxième \nmoitié d'un système de 2-manettes-en-un\nqui se comportent comme une seule manette.", + "secondaryEnableText": "Activer", + "secondaryText": "Manette Secondaire", + "startButtonActivatesDefaultDescriptionText": "(décochez ceci si votre bouton start est considéré comme un bouton 'menu')", + "startButtonActivatesDefaultText": "Le Bouton Start Active Le Widget Par Défaut", + "titleText": "Configuration de la Manette", + "twoInOneSetupText": "Configuration de la Manette 2-en-1", + "uiOnlyDescriptionText": "(empêcher cette manette de rejoindre une partie)", + "uiOnlyText": "Limiter cette manette à l’utilisation du menu seulement", + "unassignedButtonsRunText": "Tous Les Boutons Non-Assignés Fonctionnent", + "unsetText": "", + "vrReorientButtonText": "Bouton de réorientation RV" + }, + "configKeyboardWindow": { + "configuringText": "Configuration de ${DEVICE}", + "keyboard2NoteText": "Attention: la plupart des claviers ne peuvent enregistrer \nune multitude de commandes en même temps. Il est donc préférable \nd'avoir un deuxième clavier branché à l'ordinateur. Mais, \nmême dans ce cas, il faudra assigner des touches différentes \npour les deux joueurs." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Taille des boutons d'actions", + "actionsText": "Actions", + "buttonsText": "boutons", + "dragControlsText": "< bougez les commandes pour les repositionner >", + "joystickText": "Joystick", + "movementControlScaleText": "Taille des boutons de mouvements", + "movementText": "Mouvement", + "resetText": "Réinitialiser", + "swipeControlsHiddenText": "Masquer les Icônes de Contrôle en mode libre", + "swipeInfoText": "Le style 'Libre' demande un peu de pratique pour s'y habituer mais\nrend les contrôles plus intuitifs en évitant de regarder les touches à l'écran.", + "swipeText": "Libre", + "titleText": "Configurer l'Écran Tactile", + "touchControlsScaleText": "Taille des boutons tactiles" + }, + "configureItNowText": "Configurer maintenant?", + "configureText": "Configurer", + "connectMobileDevicesWindow": { + "amazonText": "Appstore Amazon", + "appStoreText": "App Store", + "bestResultsText": "Pour de meilleurs résultats, il est nécessaire d'avoir un wifi qui fonctionne\ncorrectement. Vous pouvez réduire les ralentissements de votre wifi en\ndésactivant les autres appareils utilisant le wifi, en jouant à côté de l'émetteur\nwifi, ou en vous connectant à l'hôte directement par ethernet.", + "explanationText": "Pour utiliser un smartphone ou une tablette comme manette, installez \nl'application \"${REMOTE_APP_NAME}\" sur l'appareil. Plusieurs appareils \npeuvent se connecter à la partie ${APP_NAME} par WiFi, et c'est gratuit!", + "forAndroidText": "pour Android:", + "forIOSText": "pour iOS:", + "getItForText": "Téléchargez ${REMOTE_APP_NAME} pour iOS dans l'App Store d'Apple\nou pour Android dans le Google Play Store ou l'Amazon Appstore.", + "googlePlayText": "Google Play", + "titleText": "Utiliser des Appareils Mobiles comme manettes:" + }, + "continuePurchaseText": "Continuer pour ${PRICE}?", + "continueText": "Continuer", + "controlsText": "Commandes", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Ceci ne s'applique pas au classement permanent.", + "activenessInfoText": "Ce bonus multiplicateur augmente lorsque vous jouez\net baisse quand vous ne jouez pas.", + "activityText": "Activité", + "campaignText": "Campagne", + "challengesInfoText": "Gagnez des prix en remportant des mini-jeux.\n\nLes prix et la difficulté des niveaux augmentent\ndès qu'un défi est remporté et diminuent\nlorsqu'un défi expire ou est abandonné.", + "challengesText": "Défis", + "currentBestText": "Meilleur Score Actuel", + "customText": "Personnaliser", + "entryFeeText": "Accès", + "forfeitConfirmText": "Abandonner ce défi?", + "forfeitNotAllowedYetText": "Vous ne pouvez pas abandonner ce défi pour le moment.", + "forfeitText": "Abandonner", + "multipliersText": "Bonus Multiplicateurs", + "nextChallengeText": "Prochain Défi", + "nextPlayText": "Prochain Jeu", + "ofTotalTimeText": "de ${TOTAL}", + "playNowText": "Jouer Maintenant", + "pointsText": "Points", + "powerRankingFinishedSeasonUnrankedText": "(saison terminée non-classé)", + "powerRankingNotInTopText": "(pas dans les meilleurs ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} pts)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)", + "powerRankingText": "Classement Mondial", + "prizesText": "Prix", + "proMultInfoText": "Les joueurs en version ${PRO} \nreçoivent ${PERCENT}% de points en plus.", + "seeMoreText": "Plus...", + "skipWaitText": "Ne pas attendre", + "timeRemainingText": "Temps Restant", + "titleText": "Co-op", + "toRankedText": "Avant d'Être Classé", + "totalText": "total", + "tournamentInfoText": "Commencez la course au meilleur score\navec les joueurs de votre ligue.\n\nLes prix seront décernés à la fin du tournoi \naux joueurs ayant totalisé le score le plus haut.", + "welcome1Text": "Bienvenue à ${LEAGUE}. Vous pouvez améliorer votre\nrang en gagnant des étoiles, en complétant des\nsuccès et en gagnant des trophées durant les tournois.", + "welcome2Text": "Vous pouvez aussi gagner des tickets en participant à bien d'autres activités.\nLes tickets sont utiles pour débloquer de nouveaux personnages, \ndes nouvelles cartes, mini-jeux, participer à des tournois et bien plus.", + "yourPowerRankingText": "Votre Classement Mondial:" + }, + "copyConfirmText": "Copié dans le presse papier.", + "copyOfText": "Copie de ${NAME}", + "copyText": "Copier", + "copyrightText": "© 2013 Eric Froemling", + "createAPlayerProfileText": "Créer un profil de joueur?", + "createEditPlayerText": "", + "createText": "Créer", + "creditsWindow": { + "additionalAudioArtIdeasText": "Son Additionnel, Design Initial, et Idées par ${NAME}", + "additionalMusicFromText": "Musique additionnelle par ${NAME}", + "allMyFamilyText": "Toute ma famille et mes amis qui m'ont aidé à tester le jeu", + "codingGraphicsAudioText": "Codage, Graphiques, et Audio par ${NAME}", + "languageTranslationsText": "Traductions:", + "legalText": "Légal:", + "publicDomainMusicViaText": "Musique du domaine publique par ${NAME}", + "softwareBasedOnText": "Ce logiciel est basé en partie du travail de ${NAME}", + "songCreditText": "${TITLE} Exécutée par ${PERFORMER}\nComposé par ${COMPOSER}, Arrangé par ${ARRANGER}, Publié par ${PUBLISHER},\nCourtoisie de ${SOURCE}", + "soundAndMusicText": "Son et Musique:", + "soundsText": "Sons (${SOURCE}):", + "specialThanksText": "Remerciement Spécial:", + "thanksEspeciallyToText": "Remerciement surtout à ${NAME}", + "titleText": "Crédits de ${APP_NAME}", + "whoeverInventedCoffeeText": "Celui qui a inventé le café" + }, + "currentStandingText": "Votre Classement Actuel #${RANK}", + "customizeText": "Customiser...", + "deathsTallyText": "${COUNT} morts", + "deathsText": "Morts", + "debugText": "déboguer", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Note: il est recommandé de changer Paramètres->Graphismes->Textures à 'Élevé' pour tester ceci.", + "runCPUBenchmarkText": "Lancer le test CPU (processeur)", + "runGPUBenchmarkText": "Lancer le test GPU (carte graphique)", + "runMediaReloadBenchmarkText": "Lancer le test de Media-Reload", + "runStressTestText": "Test de robustesse", + "stressTestPlayerCountText": "Nombre de Joueurs", + "stressTestPlaylistDescriptionText": "Playlist des tests de robustesse", + "stressTestPlaylistNameText": "Nom de la Playlist", + "stressTestPlaylistTypeText": "Genre de la Playlist", + "stressTestRoundDurationText": "Durée du Niveau", + "stressTestTitleText": "Test de robustesse", + "titleText": "Tests graphiques/processeur & de robustesse", + "totalReloadTimeText": "Temps de redémarrage total: ${TIME} (référez-vous au registre plus de détails)", + "unlockCoopText": "Débloquer les niveaux co-op" + }, + "defaultFreeForAllGameListNameText": "Partie Mélée-Générale par défaut", + "defaultGameListNameText": "Playlist ${PLAYMODE} Défaut", + "defaultNewFreeForAllGameListNameText": "Mes parties Mélée-Générale", + "defaultNewGameListNameText": "Ma Playlist ${PLAYMODE}", + "defaultNewTeamGameListNameText": "Mes parties en équipes", + "defaultTeamGameListNameText": "Partie en Equipes par défaut", + "deleteText": "Supprimer", + "demoText": "Démo", + "denyText": "Refuser", + "deprecatedText": "Obsolète", + "desktopResText": "Résolution de l'Ordinateur", + "deviceAccountUpgradeText": "Avertissement:\nVous etes connecté avec un compte d'appareil (${NAME}).\nLes comptes d'appareils seront enlevés dans une future mise à jour.\nMettez à jour vers un compte V2 si vous voulez garder votre progression.", + "difficultyEasyText": "Facile", + "difficultyHardOnlyText": "Mode Difficile Seulement", + "difficultyHardText": "Difficile", + "difficultyHardUnlockOnlyText": "Ce niveau ne peut être débloqué qu'en mode difficile.\nPensez-vous être à la hauteur!?!?!", + "directBrowserToURLText": "Entrez cette URL dans un navigateur:", + "disableRemoteAppConnectionsText": "Désactiver les connexions d'applications-manettes", + "disableXInputDescriptionText": "Permet plus que 4 manettes mais risque de malfonctionner.", + "disableXInputText": "Désactiver XInput", + "doneText": "Terminé", + "drawText": "Égalité", + "duplicateText": "Dupliquer", + "editGameListWindow": { + "addGameText": "Ajouter\nUn jeu", + "cantOverwriteDefaultText": "Vous ne pouvez pas remplacer la playlist par défaut!", + "cantSaveAlreadyExistsText": "Une playlist existe déjà avec ce nom!", + "cantSaveEmptyListText": "Vous ne pouvez pas sauvegarder une playlist vide!", + "editGameText": "Modifer\nce Match", + "gameListText": "Liste de Parties", + "listNameText": "Nom de la Playlist", + "nameText": "Nom", + "removeGameText": "Enlever\nCe jeu", + "saveText": "Sauvegarder la Playlist", + "titleText": "Éditeur de Playlist" + }, + "editProfileWindow": { + "accountProfileInfoText": "Ce profil spécial a un nom \net une icône basés sur votre compte. \n\n${ICONS}\n\nCréez des profils personnalisés pour \nutiliser d'autres noms et icônes.", + "accountProfileText": "(profil du compte)", + "availableText": "Le nom \"${NAME}\" est disponible.", + "changesNotAffectText": "Note: les changements n'auront pas d'effet sur les personnages déjà présent dans le jeu", + "characterText": "personnage", + "checkingAvailabilityText": "Vérifier la disponibilité pour \"${NAME}\"...", + "colorText": "couleur", + "getMoreCharactersText": "Obtenir plus de personnages...", + "getMoreIconsText": "Obtenir plus d'icônes...", + "globalProfileInfoText": "Chaque profil Mondial de chaque joueur est sûr d'avoir un unique nom\ndans le monde entier. De même pour les icônes personnalisées.", + "globalProfileText": "(profil Mondial)", + "highlightText": "Variante", + "iconText": "icône", + "localProfileInfoText": "Un profil Local ne possède pas d'icône ou d'un unique nom \ndans le monde entier. Passez à un profil Mondial\npour réserver un unique nom et y ajouter une icône personnalisée.", + "localProfileText": "(profil local)", + "nameDescriptionText": "Nom du Joueur", + "nameText": "Nom", + "randomText": "aléatoire", + "titleEditText": "Éditer ce Profil", + "titleNewText": "Nouveau Profil", + "unavailableText": "\"${NAME}\" n'est pas disponible; essayez un autre nom.", + "upgradeProfileInfoText": "Ceci vous réserve le droit à un nom de joueur unique dans le monde\net vous permet d'y assigner une icône personnalisée.", + "upgradeToGlobalProfileText": "Passer à un Profil Mondial" + }, + "editProfilesAnyTimeText": "(vous pouvez éditer les profils à tout moment dans 'paramètres')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Vous ne pouvez pas effacer la bande sonore par défaut.", + "cantEditDefaultText": "Vous ne pouvez pas modifier la bande sonore par défaut. Dupliquez-la ou créez-en une nouvelle.", + "cantEditWhileConnectedOrInReplayText": "Impossible d'éditer la bande-son en étant connecté à un groupe ou en visionnant un replay.", + "cantOverwriteDefaultText": "Vous ne pouvez pas remplacer la bande sonore par défaut", + "cantSaveAlreadyExistsText": "Une bande sonore avec ce nom existe déjà!", + "copyText": "Copier", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Bande sonore par défaut", + "deleteConfirmText": "Effacer la Bande Sonore:\n\n'${NAME}'?", + "deleteText": "Effacer la \nBande Sonore", + "duplicateText": "Dupliquer la\nBande Sonore", + "editSoundtrackText": "Éditeur de Bandes Sonores", + "editText": "Modifier la\nBande Sonore", + "fetchingITunesText": "chercher des playlists Music App", + "musicVolumeZeroWarning": "Attention: le volume de la musique est à 0", + "nameText": "Nom", + "newSoundtrackNameText": "Ma Bande Sonore ${COUNT}", + "newSoundtrackText": "Nouvelle Bande Sonore:", + "newText": "Nouvelle\nBande Sonore", + "selectAPlaylistText": "Séléctionner une Playlist", + "selectASourceText": "Source de la Musique", + "soundtrackText": "Musique", + "testText": "test", + "titleText": "Bandes Sonores", + "useDefaultGameMusicText": "Musique par Défaut du Jeu", + "useITunesPlaylistText": "Playlist Music App", + "useMusicFileText": "Fichier Musique (mp3, etc)", + "useMusicFolderText": "Dossier de Fichiers Musicaux" + }, + "editText": "Éditer", + "endText": "Terminé", + "enjoyText": "Amusez-vous Bien!", + "epicDescriptionFilterText": "${DESCRIPTION} Dans un \"slow-motion\" épique.", + "epicNameFilterText": "${NAME} Épique", + "errorAccessDeniedText": "accès refusé", + "errorDeviceTimeIncorrectText": "L'heure affichée par votre appareil est décalée de ${HOURS} heures.\nCeci pourrait causer des problèmes.\nVeuillez vérifier l'heure et vos paramètres de fuseau horaire.", + "errorOutOfDiskSpaceText": "pas d'éspace sur le disque", + "errorSecureConnectionFailText": "Impossible d'établir une connexion sécurisée au stockage en ligne ; les fonctionnalités en ligne pourraient disfonctionner.", + "errorText": "Erreur", + "errorUnknownText": "erreur inconnue", + "exitGameText": "Quitter ${APP_NAME}?", + "exportSuccessText": "'${NAME}' exporté.", + "externalStorageText": "Stockage Externe", + "failText": "Échec", + "fatalErrorText": "Oh zut; quelque chose manque ou est endommagé.\nEssayez de réinstaller l'application ou \ncontactez ${EMAIL} pour de l'aide.", + "fileSelectorWindow": { + "titleFileFolderText": "Sélectionner un Fichier ou un Dossier", + "titleFileText": "Sélectionner un Fichier", + "titleFolderText": "Sélectionner un Dossier", + "useThisFolderButtonText": "Utiliser ce Dossier" + }, + "filterText": "Filtre", + "finalScoreText": "Score Final", + "finalScoresText": "Scores Finaux", + "finalTimeText": "Temps Final", + "finishingInstallText": "L'installation se termine; un moment s'il vous plaît...", + "fireTVRemoteWarningText": "* Pour une meilleure expérience, utilisez \ndes manettes ou installez l'application\n'${REMOTE_APP_NAME}' sur vos smartphones et \ntablettes.", + "firstToFinalText": "Final du premier à ${COUNT} points", + "firstToSeriesText": "Le premier à ${COUNT} points", + "fiveKillText": "QUINTUPLE MEURTRE!!!", + "flawlessWaveText": "Vague Parfaite!", + "fourKillText": "QUADRUPLE MEURTRE!!!", + "freeForAllText": "Mélée générale", + "friendScoresUnavailableText": "Les scores de vos amis sont indisponibles.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Les ${COUNT} meilleurs du jeu", + "gameListWindow": { + "cantDeleteDefaultText": "Vous ne pouvez pas effacer la playlist par défaut.", + "cantEditDefaultText": "Vous ne pouvez pas modifier la playlist par défaut! Dupliquez-la ou créez-en une nouvelle.", + "cantShareDefaultText": "Partage de la playlist par défaut impossible", + "deleteConfirmText": "Effacer \"${LIST}\"?", + "deleteText": "Effacer\nLa Playlist", + "duplicateText": "Dupliquer\nLa Playlist", + "editText": "Modifier\nLa Playlist", + "gameListText": "Liste de jeu", + "newText": "Nouvelle\nPlaylist", + "showTutorialText": "Voir le Tutoriel", + "shuffleGameOrderText": "Mélanger l'ordre des jeux", + "titleText": "Personnaliser les Playlists ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Ajouter un Match" + }, + "gamepadDetectedText": "1 manette détecté", + "gamepadsDetectedText": "${COUNT} manettes détectés.", + "gamesToText": "${WINCOUNT} jeux à ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Rappel: n'importe quelle appareil peut supporter\nplus d'un joueur si vous avez plusieurs manettes.", + "aboutDescriptionText": "Utilisez ces onglets pour créer une partie.\n\nLes parties vous permettent de faire des jeux et \ntournois avec vos amis entre différents appareils.\n\nUtilisez le bouton ${PARTY} en haut à droite pour\ndiscuter et interagir avec votre partie. (sur une \nmanette, appuyez sur ${BUTTON} lorsque vous êtes dans le menu)", + "aboutText": "Info", + "addressFetchErrorText": "", + "appInviteInfoText": "Invitez vos amis pour jouer BombSquad et \nils gagneraient ${COUNT} billets. Vous \ngagneriez ${YOU_COUNT} pour chaque ami.", + "appInviteMessageText": "${NAME} vous a envoyé ${COUNT} tickets sur ${APP_NAME}", + "appInviteSendACodeText": "Envoyer un code", + "appInviteTitleText": "Invitation à ${APP_NAME}", + "bluetoothAndroidSupportText": "(fonctionne avec n'importe quel appareil Android équipé de Bluetooth)", + "bluetoothDescriptionText": "Héberger/joindre une partie via Bluetooth:", + "bluetoothHostText": "Héberger via Bluetooth", + "bluetoothJoinText": "Joindre via Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "vérification...", + "copyCodeConfirmText": "Le code a bien été copié dans le presse-papier.", + "copyCodeText": "Copier le code", + "dedicatedServerInfoText": "Pour un meilleur résultat, créez un server dédié. Voir bombsquadgame.com/server pour plus d'infos.", + "disconnectClientsText": "Ceci déconnectera le(s) ${COUNT} joueur(s)\nde votre partie. Êtes-vous sûr?", + "earnTicketsForRecommendingAmountText": "Vos amis recevront ${COUNT} tickets si ils essayent le jeu\n(et vous recevrez ${YOU_COUNT} pour chacun d'entre eux qui le feront)", + "earnTicketsForRecommendingText": "Partagez le jeu pour \ndes tickets gratuits...", + "emailItText": "Evoyer par e-mail", + "favoritesSaveText": "Mettre en favori", + "favoritesText": "Favoris", + "freeCloudServerAvailableMinutesText": "Le prochain serveur libre sera disponible dans ${MINUTES} minutes.", + "freeCloudServerAvailableNowText": "Un serveur libre est disponible !", + "freeCloudServerNotAvailableText": "Aucun serveur libre n'est disponible...", + "friendHasSentPromoCodeText": "${COUNT} tickets ${APP_NAME} de la part de ${NAME}", + "friendPromoCodeAwardText": "Vous recevrez ${COUNT} tickets à chaque fois qu'il sera utilisé.", + "friendPromoCodeExpireText": "Ce code expirera dans ${EXPIRE_HOURS} heures et ne fonctionne que pour les nouveaux joueurs.", + "friendPromoCodeInstructionsText": "Pour l'utiliser, ouvrez ${APP_NAME} puis aller dans \"Paramètres->Avancé->Entrer code\".\nAllez sur bombsquadgame.com pour les liens de téléchargement pour toutes les plateformes supportées.", + "friendPromoCodeRedeemLongText": "Peut être utilisé pour ${COUNT} tickets gratuits jusqu'à ${MAX_USES} personnes maximum.", + "friendPromoCodeRedeemShortText": "Il peut-être utilisé pour ${COUNT} tickets dans le jeu.", + "friendPromoCodeWhereToEnterText": "(dans \"Paramètres->Avancé->Entrer code\")", + "getFriendInviteCodeText": "Obtenir un Code pour Inviter mes Amis", + "googlePlayDescriptionText": "Invitez des joueurs Google Play à votre partie:", + "googlePlayInviteText": "Inviter", + "googlePlayReInviteText": "Le(s) ${COUNT} joueur(s) Google Play seront déconnectés \nsi vous faites une autre invitation. Incluez-les dans \nla nouvelle invitation pour continuer de jouer avec eux.", + "googlePlaySeeInvitesText": "Voir les Invitations", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Version Android / Google Play)", + "hostPublicPartyDescriptionText": "Héberger une partie publique", + "hostingUnavailableText": "Hébergement de serveur indisponible", + "inDevelopmentWarningText": "Note:\n\nLe jeu en réseau est une fonctionnalité encore en \ndéveloppement. Pour l'instant, il est recommandé \nque tous les joueurs soient sur le même réseau Wi-Fi.", + "internetText": "Internet", + "inviteAFriendText": "Vos amis n'ont pas le jeu? Invitez-les à\nl'essayer et ils recevront ${COUNT} tickets gratuit.", + "inviteFriendsText": "Invitez vos Amis", + "joinPublicPartyDescriptionText": "Rejoindre une Partie Publique", + "localNetworkDescriptionText": "Rejoindre une partie sur votre réseau (LAN, Bluetooth, Wi-Fi, etc.)", + "localNetworkText": "Réseau Local", + "makePartyPrivateText": "Rendre Ma Partie Privée", + "makePartyPublicText": "Rendre Ma Partie Publique", + "manualAddressText": "Adresse", + "manualConnectText": "Connexion", + "manualDescriptionText": "Joindre une partie par adresse:", + "manualJoinSectionText": "Rejoindre un utilisateur par Adresse IP", + "manualJoinableFromInternetText": "Peut-on vous rejoindre via internet?:", + "manualJoinableNoWithAsteriskText": "NON*", + "manualJoinableYesText": "OUI", + "manualRouterForwardingText": "*pour arranger ceci, configurez votre routeur pour rediriger le port UDP ${PORT} à votre adresse locale", + "manualText": "Manuel", + "manualYourAddressFromInternetText": "Votre adresse depuis internet:", + "manualYourLocalAddressText": "Votre adresse locale:", + "nearbyText": "Proche", + "noConnectionText": "", + "otherVersionsText": "(autres versions)", + "partyCodeText": "Code de la partie", + "partyInviteAcceptText": "Accepter", + "partyInviteDeclineText": "Refuser", + "partyInviteGooglePlayExtraText": "(référez-vous à l'onglet 'Google Play' dans 'Rassembler')", + "partyInviteIgnoreText": "Ignorer", + "partyInviteText": "${NAME} a vous invité \ndans sa partie!", + "partyNameText": "Nom de la Partie", + "partyServerRunningText": "Votre serveur est en train de fonctionner.", + "partySizeText": "nombre joueurs", + "partyStatusCheckingText": "Vérifie le status...", + "partyStatusJoinableText": "votre partie est maintenant joignable via l'internet", + "partyStatusNoConnectionText": "incapable à connecter au serveur", + "partyStatusNotJoinableText": "votre partie n'est pas joignable via l'internet", + "partyStatusNotPublicText": "votre partie n'est pas publique", + "pingText": "vitesse", + "portText": "Port", + "privatePartyCloudDescriptionText": "Les parties privées tournent dans les serveurs cloud dédiés; aucune configuration de routeur n'est requise", + "privatePartyHostText": "Héberger une partie privée", + "privatePartyJoinText": "Rejoindre une partie privée", + "privateText": "Privé", + "publicHostRouterConfigText": "Vous pourriez avoir besoin de configurer la redirection de port sur votre routeur. Pour une option plus facile, hébergez une partie privée.", + "publicText": "Public", + "requestingAPromoCodeText": "Demande d'un code...", + "sendDirectInvitesText": "Envoyez des invitations directes", + "shareThisCodeWithFriendsText": "Partagez ce code avec vos amis:", + "showMyAddressText": "Montrer mon adresse", + "startAdvertisingText": "Démarrer la diffussion", + "startHostingPaidText": "Héberger maintenant pour ${COST}", + "startHostingText": "Héberger", + "startStopHostingMinutesText": "Vous pourrez commencer et arrêter d'héberger une partie privée dans les ${MINUTES} prochaines minutes.", + "stopAdvertisingText": "Arrêter la diffusion", + "stopHostingText": "Arrêter d'héberger", + "titleText": "Rassembler", + "wifiDirectDescriptionBottomText": "Si tous les appareils ont un onglet 'Wi-Fi Direct', ils devraient être capables de \nse connecter entre eux. Quand tous les appareils sont connectés, vous pouvez créer des \nparties en utilisant l'onglet 'Réseau Local', comme pour un réseau Wi-Fi ordinaire. \n\nPour des résultats optimaux, l'hôte de ${APP_NAME} devrait être l'hôte de la partie.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct peux être utilisé pour connecter des appareils Android directement\nsans besoin un réseau Wi-Fi. Fonctionne mieux avec Android 4.2 ou plus récent.\n\nPour l'utiliser, ouvrez les paramètres Wi-Fi et cherchez 'Wi-Fi Direct' dans le menu.", + "wifiDirectOpenWiFiSettingsText": "Ouvrir les Paramètres Wi-Fi", + "wifiDirectText": "Direct Wi-Fi", + "worksBetweenAllPlatformsText": "(fonctionne avec toutes les plateformes)", + "worksWithGooglePlayDevicesText": "(fonctionne avec les appareils qui ont la version Google Play (android) du jeu)", + "youHaveBeenSentAPromoCodeText": "Vous avez reçu un code promo pour ${APP_NAME}:" + }, + "getCoinsWindow": { + "coinDoublerText": "Doubleur de pièces", + "coinsText": "${COUNT} Pièces", + "freeCoinsText": "Pièces gratuites", + "restorePurchasesText": "Actualiser les achats", + "titleText": "Avoir des pièces" + }, + "getTicketsWindow": { + "freeText": "GRATUIT!", + "freeTicketsText": "Tickets gratuit", + "inProgressText": "Une transaction est encore en cours; réessayez dans un insatant.", + "purchasesRestoredText": "Achats réinitialisés.", + "receivedTicketsText": "Vous avez reçu ${COUNT} tickets!", + "restorePurchasesText": "Restaurer les achats", + "ticketDoublerText": "Doubleur des Billets", + "ticketPack1Text": "Petit pack de tickets", + "ticketPack2Text": "Pack moyen de tickets", + "ticketPack3Text": "Gros pack de tickets", + "ticketPack4Text": "Pack de tickets géant", + "ticketPack5Text": "Énorme pack de tickets", + "ticketPack6Text": "Ultime pack de tickets", + "ticketsFromASponsorText": "Regarder un sponsors \nPour ${COUNT} ticket", + "ticketsText": "${COUNT} Tickets", + "titleText": "Plus de tickets", + "unavailableLinkAccountText": "Désolé , les achats ne sont pas disponibles sur cette plateforme.\nSi vous voulez , vous pouvez lier ce compte à une\nautre plateforme et faire vos achats sur celle-ci.", + "unavailableTemporarilyText": "Non disponible pour le moment; merci de réessayez plus tard.", + "unavailableText": "Désolé, ceci n'est pas disponible.", + "versionTooOldText": "Désolé, cette version du jeu est trop vieille; télécharger la dernière version.", + "youHaveShortText": "vous avez ${COUNT}", + "youHaveText": "vous avez ${COUNT} tickets" + }, + "googleMultiplayerDiscontinuedText": "Désolé, le service multijoueur de Google n'est plus disponible.\nJe travaille sur un moyen de le remplacer aussi vite que possible.\nEn attendant, veuillez essayer une nouvelle méthode de connexion.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Les achats Google Play ne sont pas disponibles.\nVous avez peut-être besoin de mettre à jour votre Google play", + "googlePlayServicesNotAvailableText": "Les services Google Play sont indisponibles.\nCertaines fonctions de l'application peuvent être désactivées.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Toujours", + "fullScreenCmdText": "Plein Écran (Cmd-F)", + "fullScreenCtrlText": "Plein Écran (Ctrl-F)", + "gammaText": "Gamma", + "highText": "Élevé", + "higherText": "Très élevé", + "lowText": "Bas", + "mediumText": "Moyen", + "neverText": "Jamais", + "resolutionText": "Résolution", + "showFPSText": "Montrer les FPS", + "texturesText": "Textures", + "titleText": "Graphismes", + "tvBorderText": "Bordure TV", + "verticalSyncText": "Synchronisation Verticale", + "visualsText": "Visuels" + }, + "helpWindow": { + "bombInfoText": "- Bombe -\nPlus fort que les coups de poing, mais\npeut entraîner une grave automutilation.\nPour bien faire, jetez-la vers l'ennemi\navant que la mèche n'arrive au bout.", + "bombInfoTextScale": 0.6, + "canHelpText": "${APP_NAME} peut aider.", + "controllersInfoText": "Vous pouvez jouer à ${APP_NAME} avec des amis par réseau, ou vous \npouvez tous jouer sur le même appareil avec assez de contrôleurs. \n${APP_NAME} en supporte une variété; vous pouvez même utiliser des \nsmartphones comme contrôleurs avec l'app '${REMOTE_APP_NAME}' \ngratuite. Allez à Paramètres->Contrôleurs pour plus d'info.", + "controllersInfoTextFantasia": "Un joueur peut utiliser la télécommande comme manette, mais les\nmanettes sont vivement recommandées. Vous pouvez toujours utiliser\ndes systèmes iOS/Android comme manettes via l'application gratuite\n'BombSquad'. Allez voir 'Manettes' dans 'Paramètres' pour plus d'infos.", + "controllersInfoTextMac": "Un ou deux joueurs peuvent utiliser le clavier, mais Bombsquad est meilleur avec\nmanettes. BombSquad supporte des manettes USB, PS3, XBOX 360, Wiimotes\net des systèmes iOS/Android pour controler les personnages. J'espere que vous en avez. Allez voir 'Manettes' dans 'Paramètres' pour plus d'info.", + "controllersInfoTextOuya": "Vous pouvez utiliser des manettes OUYA, PS3, XBOX 360 et beaucoup \nd'autres manettes USB et Bluetooth avec BombSquad. Vous pouvez aussi \nutiliser des sytèmes iOS et Android comme manette gratuitement via \nl'application 'BombSquad Remote'. Allez voir 'Manettes' dans 'Paramètres' \npour plus d'info.", + "controllersInfoTextRemoteOnly": "Vous pouvez jouer à ${APP_NAME} avec vos amis sur internet, ou vous\npouvez tous jouer sur le même appareil en utilisant des téléphones\ncomme manettes avec l'application gratuite '${REMOTE_APP_NAME}'", + "controllersText": "Manettes", + "controlsSubtitleText": "Votre personnage ${APP_NAME} possède plusieurs actions basiques:", + "controlsText": "Contrôles", + "devicesInfoText": "La version RV de ${APP_NAME} peut être jouée par réseau avec \nla version originale, alors utilisez vos smartphones, tablettes, \net ordinateurs et jouer ensemble. Il peut aussi être utile \nde connecter une version originale du jeu à la version RV \npour permettre aux gens autour de visionner l'action.", + "devicesText": "Appareils", + "friendsGoodText": "Il est bon d'en avoir. ${APP_NAME} est plus amusant avec plusieurs\njoueurs et peut en supporter jusqu'à 8 en même temps, ce qui nous mène à:", + "friendsText": "Amis", + "jumpInfoText": "- Sauter -\nSautez pour éviter les trous,\npour jeter des objets plus haut,\nou pour la beauté du geste.", + "jumpInfoTextScale": 0.6, + "orPunchingSomethingExtraSpace": 0, + "orPunchingSomethingText": "Ou frapper quelque chose, la jeter d'une falaise, et l'exploser en descendant avec une bombe gluante.", + "pickUpInfoText": "- Ramasser -\nSaisissez des drapeaux, ennemis, ou \ntout autre chose non boulonné au sol.\nAppuyez à nouveau pour lancer.", + "powerupBombDescriptionText": "Vous permet de lancer trois bombes \nd'affilée au lieu d'une seule.", + "powerupBombNameText": "Triple bombes", + "powerupCurseDescriptionText": "Vous ne voulez probablement pas y toucher.\n...ou peut-être que si?", + "powerupCurseNameText": "Malédiction", + "powerupHealthDescriptionText": "Vous restaure votre santé.\nVous n'aurez jamais pu deviner.", + "powerupHealthNameText": "Trousse de soin", + "powerupIceBombsDescriptionText": "Moins puissantes que les bombes normales \nmais congèlent vos ennemis et les \nrendent particulièrement cassant.", + "powerupIceBombsNameText": "Bombes glacées", + "powerupImpactBombsDescriptionText": "Un peu moins puissantes que les bombes \nnormales, elles explosent à l'impact.", + "powerupImpactBombsNameText": "Bombes d'impact", + "powerupLandMinesDescriptionText": "3 pour le prix d'une, \nutile pour se défendre \nou arrêter les ennemis rapides.", + "powerupLandMinesNameText": "Mines", + "powerupPunchDescriptionText": "Rend vos poings durs\ntrès, très durs.", + "powerupPunchNameText": "Gants de boxe", + "powerupShieldDescriptionText": "Absorbe les dommages\npour préserver votre santé.", + "powerupShieldNameText": "Bouclier d'énergie", + "powerupStickyBombsDescriptionText": "Collent à tout ce qu'elles touchent.\nFous rires garantis.", + "powerupStickyBombsNameText": "Bombes gluantes", + "powerupsSubtitleText": "Évidemment, aucun jeu n'est complet sans bonus:", + "powerupsSubtitleTextScale": 0.8, + "powerupsText": "Bonus", + "powerupsTextScale": 1.4, + "punchInfoText": "- Frapper -\nLes poings font plus de dégât \nplus vite ils bougent, donc courez\net tournoyez comme un fou.", + "punchInfoTextScale": 0.6, + "runInfoText": "- Courir -\nMaintenez n'importe quel bouton pour courir. Ceci fonctionne aussi avec les gâchettes. \nCourir est rapide, mais tourner devient difficile, attention aux falaises.", + "runInfoTextScale": 0.6, + "someDaysExtraSpace": 0, + "someDaysText": "Parfois vous désirez frapper quelque chose. Ou exploser quelque chose.", + "someDaysTextScale": 0.66, + "titleText": "Aide de ${APP_NAME}", + "toGetTheMostText": "Pour profiter à fond du jeu, vous aurez besoin:", + "toGetTheMostTextScale": 1.0, + "welcomeText": "Bienvenue dans ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} navigue dans les menus comme un chef -", + "importPlaylistCodeInstructionsText": "Utilisez le code suivant pour importer cette playlist ailleurs:", + "importPlaylistSuccessText": "${TYPE} playlist '${NAME}' importée", + "importText": "Importer", + "importingText": "Importation...", + "inGameClippedNameText": "dans le jeu sera\n\"${NAME}\"", + "installDiskSpaceErrorText": "ERREUR: Incapable de compléter l'installation.\nL'appareil manque paut-être d'espace.\nLibérez de l'espace et ressayez.", + "internal": { + "arrowsToExitListText": "appuyez sur ${LEFT} ou ${RIGHT} pour quitter la liste", + "buttonText": "bouton", + "cantKickHostError": "Impossible d’éjecter l'hôte.", + "chatBlockedText": "Tchat bloqué pour ${NAME} pendant ${TIME} secondes.", + "connectedToGameText": "Vous avez rejoint '${NAME}'.", + "connectedToPartyText": "Vous avez joint la partie de ${NAME}!", + "connectingToPartyText": "Connexion...", + "connectionFailedHostAlreadyInPartyText": "La connexion a échoué; l'hôte est dans une autre partie.", + "connectionFailedPartyFullText": "Connexion échouée; la partie est pleine.", + "connectionFailedText": "La connexion a échouée.", + "connectionFailedVersionMismatchText": "La connexion a échouée; l'hôte joue avec une version différente du jeu.\nVérifiez que vous avez la même version et réessayez.", + "connectionRejectedText": "La connexion a été rejetée.", + "controllerConnectedText": "${CONTROLLER} connecté.", + "controllerDetectedText": "1 manette détectée.", + "controllerDisconnectedText": "${CONTROLLER} déconnecté.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} déconnecté. Réessayez de le/la reconnecter.", + "controllerForMenusOnlyText": "Ce contrôleur ne peut pas être utilisé pour jouer; seulement pour naviguer les menus.", + "controllerReconnectedText": "${CONTROLLER} reconnecté.", + "controllersConnectedText": "${COUNT} manettes connectées.", + "controllersDetectedText": "${COUNT} manettes détectées.", + "controllersDisconnectedText": "${COUNT} manettes déconnectées.", + "corruptFileText": "Fichier(s) corrompu(s) détecté(s). Essayez de réinstaller, ou email à ${EMAIL} (En Anglais SVP)", + "errorPlayingMusicText": "Impossible de jouer la musique: ${MUSIC}", + "errorResettingAchievementsText": "Impossible de réinitialiser les succès en ligne; merci de réessayez plus tard.", + "hasMenuControlText": "${NAME} à le contrôle du menu.", + "incompatibleNewerVersionHostText": "L'hôte utilise une version plus récente du jeu. \nMettez à jour vers la dernière version et réessayez.", + "incompatibleVersionHostText": "L'hôte execute une version différente du jeu.\nVérifiez que vous êtes tous les deux à jour et réessayez.", + "incompatibleVersionPlayerText": "${NAME} execute une version différente du jeu.\nVérifiez que vous êtes tous les deux à jour et réessayez.", + "invalidAddressErrorText": "Erreur: adresse invalide.", + "invalidNameErrorText": "Erreur: nom invalide.", + "invalidPortErrorText": "Erreure:port invalide", + "invitationSentText": "Invitation envoyée.", + "invitationsSentText": "${COUNT} invitations envoyées.", + "joinedPartyInstructionsText": "Quelqu'un a rejoint votre partie.\nAllez à 'Jouer' pour commencer un match.", + "keyboardText": "Clavier", + "kickIdlePlayersKickedText": "${NAME} été éjecté pour inactivité.", + "kickIdlePlayersWarning1Text": "${NAME} sera éjecté dans ${COUNT} secondes s'il reste inactif.", + "kickIdlePlayersWarning2Text": "(vous pouvez désactiver ceci dans Paramètres -> Avancé)", + "leftGameText": "Vous avez quitté '${NAME}'.", + "leftPartyText": "Vous avez quitté la partie de ${NAME}.", + "noMusicFilesInFolderText": "Ce dossier contient aucun fichier musical.", + "playerJoinedPartyText": "${NAME} a joint la partie!", + "playerLeftPartyText": "${NAME} a quitté la partie.", + "rejectingInviteAlreadyInPartyText": "Rejete l'invitation (déjà dans une partie).", + "serverRestartingText": "Le serveur redémarre. Rejoignez dans un moment", + "serverShuttingDownText": "Arrêt du serveur...", + "signInErrorText": "Erreur pendant la connexion.", + "signInNoConnectionText": "Impossible de se connecter. (pas de connexion internet?)", + "teamNameText": "L'équipe ${NAME} ", + "telnetAccessDeniedText": "ERREUR: l'utilisateur n'a pas autorisé l'accès telnet.", + "timeOutText": "(expire dans ${TIME} secondes)", + "touchScreenJoinWarningText": "Vous avez joint avec l'écran tactile.\nSi c'était une erreur, touchez 'Menu->Quitter le Jeu'.", + "touchScreenText": "Écran Tactile", + "trialText": "test", + "unableToResolveHostText": "Erreur: impossible de résoudre l'hôte.", + "unavailableNoConnectionText": "Pas disponible à l'instant (pas de connexion internet?)", + "vrOrientationResetCardboardText": "Utilisez ceci pour réinitialiser l'orientation RV.\nPour jouer au jeu vous aurez besoin d'un contrôleur externe.", + "vrOrientationResetText": "Réinitialiser l'orientation RV.", + "willTimeOutText": "(expirera si inactive)" + }, + "jumpBoldText": "SAUT", + "jumpText": "Saut", + "keepText": "Garder", + "keepTheseSettingsText": "Garder ces paramètres?", + "keyboardChangeInstructionsText": "Appuyez deux fois sur espace pour changer le clavier.", + "keyboardNoOthersAvailableText": "Aucun autre clavier n'est disponible.", + "keyboardSwitchText": "Changer le clavier vers \"${NAME}\".", + "kickOccurredText": "${NAME} a été renvoyé(e) du serveur", + "kickQuestionText": "Ban ${NAME} ?", + "kickText": "Renvoyer", + "kickVoteCantKickAdminsText": "L'administrateur ne peut pas être expulsée.", + "kickVoteCantKickSelfText": "Tu ne peut pas t'expulsé toi-même.", + "kickVoteFailedNotEnoughVotersText": "Pas assez de joueurs pour un vote.", + "kickVoteFailedText": "Le vote de renvoi est annulé.", + "kickVoteStartedText": "Un vote pour exclure '${NAME}' a commencé.", + "kickVoteText": "Vote pour exclure", + "kickVotingDisabledText": "Le vote d'expulsion est désactivé.", + "kickWithChatText": "Écrit ${YES} dans le chat pour Oui et ${NO} pour Non", + "killsTallyText": "${COUNT} meurtres", + "killsText": "Meurtres", + "kioskWindow": { + "easyText": "Facile", + "epicModeText": "Mode Épique", + "fullMenuText": "Menu Complet", + "hardText": "Difficile", + "mediumText": "Moyen", + "singlePlayerExamplesText": "Exemples Solo / Co-op", + "versusExamplesText": "Exemples de Versus" + }, + "languageSetText": "La langue est maintenant \"${LANGUAGE}\".", + "lapNumberText": "Tour ${CURRENT}/${TOTAL}", + "lastGamesText": "(dernier ${COUNT} jeux)", + "leaderboardsText": "Classements", + "league": { + "allTimeText": "De tous les temps", + "currentSeasonText": "Saison en Cours (${NUMBER})", + "leagueFullText": "Ligue ${NAME}", + "leagueRankText": "Classement de Ligue", + "leagueText": "Ligue", + "rankInLeagueText": "#${RANK}, Ligue ${NAME}${SUFFIX}", + "seasonEndedDaysAgoText": "La saison est terminée depuis ${NUMBER} jours.", + "seasonEndsDaysText": "La saison se termine dans ${NUMBER} jours.", + "seasonEndsHoursText": "La saison termine dans ${NUMBER} heures.", + "seasonEndsMinutesText": "La saison se termine dans ${NUMBER} minutes.", + "seasonText": "Saison ${NUMBER}", + "tournamentLeagueText": "Vous devez atteindre la ligue ${NAME} pour participer à ce tournoi.", + "trophyCountsResetText": "Les trophées seront remis à zéro la saison suivante." + }, + "levelBestScoresText": "Meilleurs scores dans ${LEVEL}", + "levelBestTimesText": "Meilleurs temps dans ${LEVEL}", + "levelFastestTimesText": "Meilleurs temps en ${LEVEL}", + "levelHighestScoresText": "Meilleurs marques en ${LEVEL}", + "levelIsLockedText": "${LEVEL} est verrouillé.", + "levelMustBeCompletedFirstText": "${LEVEL} doit être complété d'abord.", + "levelText": "Niveau ${NUMBER}", + "levelUnlockedText": "Niveau Déverrouillé!", + "livesBonusText": "Bonus à vie", + "loadingText": "chargement", + "loadingTryAgainText": "Chargement; réessayez dans quelques instants...", + "macControllerSubsystemBothText": "Les deux (non recommandé)", + "macControllerSubsystemClassicText": "Manettes classiques", + "macControllerSubsystemDescriptionText": "(changez ceci si vos manettes ne marchent pas)", + "macControllerSubsystemMFiNoteText": "Une manette IOS/Mac détectée;\nVous pouvez les activer dans réglages -> manettes", + "macControllerSubsystemMFiText": "IOS/Mac", + "macControllerSubsystemTitleText": "Aide manette", + "mainMenu": { + "creditsText": "Crédits", + "demoMenuText": "Menu Démo", + "endGameText": "Terminer le jeu", + "endTestText": "Terminer test", + "exitGameText": "Quitter le jeu", + "exitToMenuText": "Retourner au menu?", + "howToPlayText": "Guide Pratique", + "justPlayerText": "(Seulement ${NAME})", + "leaveGameText": "Quitter le jeu", + "leavePartyConfirmText": "Voulez-vous vraiment quitter la partie?", + "leavePartyText": "Quitter la Partie", + "leaveText": "Retour au menu", + "quitText": "Quitter", + "resumeText": "Reprendre", + "settingsText": "Paramètres" + }, + "makeItSoText": "Appliquer", + "mapSelectGetMoreMapsText": "Obtenir plus de cartes...", + "mapSelectText": "Choisir...", + "mapSelectTitleText": "Cartes pour ${GAME}", + "mapText": "Carte", + "maxConnectionsText": "Limite de Connexions", + "maxPartySizeText": "Maximum Participants", + "maxPlayersText": "Joueurs Max", + "merchText": "Boutique!", + "modeArcadeText": "Mode Arcade", + "modeClassicText": "Mode classique", + "modeDemoText": "Mode Demo", + "mostValuablePlayerText": "Meilleur joueur", + "mostViolatedPlayerText": "Joueur le plus violenté", + "mostViolentPlayerText": "Joueur le plus violent", + "moveText": "Bouger", + "multiKillText": "${COUNT}-MEURTRES!!!", + "multiPlayerCountText": "${COUNT} joueurs", + "mustInviteFriendsText": "Note: vous devez inviter des amis dans \nle menu \"${GATHER}\" ou brancher des \ncontrôleurs pour jouer en multi-joueurs.", + "nameBetrayedText": "${NAME} a trahi ${VICTIM}", + "nameDiedText": "${NAME} est mort.", + "nameKilledText": "${NAME} a tué ${VICTIM}.", + "nameNotEmptyText": "Le nom ne peut pas être vide!", + "nameScoresText": "${NAME} a marqué!", + "nameSuicideKidFriendlyText": "${NAME} est mort accidentellement.", + "nameSuicideText": "${NAME} s'est suicidé.", + "nameText": "Nom", + "nativeText": "Native", + "newPersonalBestText": "Nouveau record personnel!", + "newTestBuildAvailableText": "Une nouvelle version test est disponible ! (${VERSION} ${BUILD}).\nObtenez à ${ADDRESS}", + "newText": "Nouveau", + "newVersionAvailableText": "Une nouvelle version de ${APP_NAME} est disponible! (${VERSION})", + "nextAchievementsText": "Prochains Succès:", + "nextLevelText": "Niveau Suivant", + "noAchievementsRemainingText": "- aucun", + "noContinuesText": "(sans continus)", + "noExternalStorageErrorText": "Aucun stockage externe a été trouvé pour cet appareil", + "noGameCircleText": "Erreur: vous n'êtes pas connecté au GameCircle", + "noJoinCoopMidwayText": "Vous ne pouvez pas rejoindre une partie co-cop en plein milieu.", + "noProfilesErrorText": "Vous avez aucun profil de joueur, vous êtes donc coincés avec '${NAME}'.\nAllez à Paramètres->Profils des Joueurs pour vous créer un profil.", + "noScoresYetText": "Aucun score pour le moment.", + "noThanksText": "Non Merci", + "noTournamentsInTestBuildText": "AVERTISSEMENT: les scores de tournoi de cette version de test seront ignorés.", + "noValidMapsErrorText": "Aucune carte valide a été trouvée pour ce type de jeu.", + "notEnoughPlayersRemainingText": "Pas assez de joueurs restant; quittez et commencez un nouveau jeu.", + "notEnoughPlayersText": "Vous avez besoin d'au moins ${COUNT} joueurs pour commencer ce jeu!", + "notNowText": "Pas maintenant", + "notSignedInErrorText": "Vous devez vous connecter pour faire ceci.", + "notSignedInGooglePlayErrorText": "Vous devez vous connecter avec Google Play pour faire ceci.", + "notSignedInText": "pas connecté", + "notUsingAccountText": "Note: ignorer le compte ${SERVICE}.\nAllez à 'Compte -> Connectez-vous avec ${SERVICE}' si vous voulons le utiliser.", + "nothingIsSelectedErrorText": "Rien n'est sélectionné!", + "numberText": "#${NUMBER}", + "offText": "Désactivé", + "okText": "Ok", + "onText": "Activé", + "oneMomentText": "Juste un moment...", + "onslaughtRespawnText": "${PLAYER} réapparaîtra à la vague ${WAVE}", + "orText": "${A} ou ${B}", + "otherText": "Autre...", + "outOfText": "(#${RANK} sur ${ALL})", + "ownFlagAtYourBaseWarning": "Votre drapeau doit être\nà votre base pour marquer!", + "packageModsEnabledErrorText": "Le jeu en réseau n'est pas autorisé tant que les package mods locaux sont activés (référez à Paramètres->Avancé)", + "partyWindow": { + "chatMessageText": "Message", + "emptyText": "Votre partie est vide", + "hostText": "(hôte)", + "sendText": "Envoyer", + "titleText": "Votre Partie" + }, + "pausedByHostText": "(pausé par l'hôte)", + "perfectWaveText": "Vague parfaite!", + "pickUpBoldText": "PRIS", + "pickUpText": "Ramasser", + "playModes": { + "coopText": "Co-op", + "freeForAllText": "Mêlée Générale", + "multiTeamText": "Multi-Équipes", + "singlePlayerCoopText": "Mode Solo / Co-op", + "teamsText": "Équipes" + }, + "playText": "Jouer", + "playWindow": { + "coopText": "Co-op", + "freeForAllText": "Mêlée générale", + "oneToFourPlayersText": "1-4 joueurs", + "teamsText": "Équipes", + "titleText": "Jouer", + "twoToEightPlayersText": "2-8 joueurs" + }, + "playerCountAbbreviatedText": "${COUNT}j", + "playerDelayedJoinText": "${PLAYER} rejoindra au debut de la prochaine partie.", + "playerInfoText": "Info du Joueur", + "playerLeftText": "${PLAYER} a quitté le jeu.", + "playerLimitReachedText": "La limite de ${COUNT} joueurs est atteinte; aucun autre joueur ne pourra rejoindre.", + "playerLimitReachedUnlockProText": "Évoluez en \"${PRO}\" dans le magasin pour jouer avec plus de ${COUNT} joueurs. ", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Vous ne pouvez pas effacer le profil de votre compte.", + "deleteButtonText": "Effacer \nCe Profil", + "deleteConfirmText": "Effacer '${PROFILE}'?", + "editButtonText": "Éditer\nCe Profil", + "explanationText": "(noms et apparences personalisés pour ce compte)", + "newButtonText": "Nouveau\nProfil", + "titleText": "Profils Des Joueurs" + }, + "playerText": "Joueur", + "playlistNoValidGamesErrorText": "Cette playlist ne contient pas des jeux valides débloqués.", + "playlistNotFoundText": "playlist introuvable", + "playlistText": "Playlist", + "playlistsText": "Playlists", + "pleaseRateText": "Si vous aimez ${APP_NAME}, SVP, prenez un moment pour \névaluez ou écrire un commentaire. Ceci nous donnera un \nretour d'info utile pour le développement futur du jeu.\n\nmerci!\n-eric", + "pleaseWaitText": "Veuillez patienter...", + "pluginClassLoadErrorText": "Une erreur est survenue en chargeant la classe de plugins '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Une erreur est survenue en démarrant le plugin '${PLUGIN}' : ${ERROR}", + "pluginsDetectedText": "Nouveaux plugins détectés. Redémarrez l'application pour les activer, ou configurez-les dans les paramètres.", + "pluginsRemovedText": "${NUM} plugin(s) ne sont plus disponibles.", + "pluginsText": "Plugins", + "practiceText": "Entraînement", + "pressAnyButtonPlayAgainText": "Appuyez n'importe quel bouton pour rejouer...", + "pressAnyButtonText": "Appuyez n'importe quel bouton pour continuer...", + "pressAnyButtonToJoinText": "Appuyez n'importe quel bouton pour joindre...", + "pressAnyKeyButtonPlayAgainText": "Appuyez sur n'importe quel touche/bouton pour rejouer...", + "pressAnyKeyButtonText": "Appuyez n'importe quel touche/bouton pour continuer...", + "pressAnyKeyText": "Appuyez sur n'importe quelle touche...", + "pressJumpToFlyText": "** Appuyez SAUTE à plusieurs reprises pour voler **", + "pressPunchToJoinText": "appuyez sur FRAPPER pour joindre...", + "pressToOverrideCharacterText": "appuyez sur ${BUTTONS} pour remplacer votre personnage", + "pressToSelectProfileText": "appuyez sur ${BUTTONS} pour sélectionner un joueur", + "pressToSelectTeamText": "appuyez ${BUTTONS} pour sélectionner une équipe", + "profileInfoText": "Créez des profils pour vous et vos amis\npour customizer vos noms, personnages, et couleurs.", + "promoCodeWindow": { + "codeText": "Code", + "codeTextDescription": "Code Promo", + "enterText": "Vérifier" + }, + "promoSubmitErrorText": "Erreur lors de la soumission du code; vérifiez votre connexion internet", + "ps3ControllersWindow": { + "macInstructionsText": "Coupez l'alimentation de votre PS3, soyez certain que le\nBluetooth est activé sur votre Mac, puis connectez votre manette\nà votre Mac par USB pour lier les deux. À partir de ce moment, vous\npouvez utiliser le bouton d'accueil de la manette pour la connectée au \nMac par USB (filaire) ou Bluetooth (sans-fil).\n\nQuelques Macs demandent un code d'accès quand vous liez la manette.\nDans ce cas, référez vous à Google ou le tutoriel qui suit.\n\n\n\n\nLes manettes de PS3 connectées sans-fil devraient être présentes dans la liste\ndes Préférences du Système->Bluetooth. Vous devrez peut-être l'enlever de cette\nliste pour l'utiliser de nouveau avec votre PS3.\n\nSoyez certain de déconnecter vos manettes lorsqu'elles sont inactives, sinon, \nles batteries continueront à s'épuiser. \n\nLe bluetooth peut supporter jusqu'à 7 manettes,\nmais ce n'est pas garanti.", + "ouyaInstructionsText": "Pour utiliser un contrôleur de PS3 avec votre OUYA, connectez le avec un \ncâble USB. Faites ceci pouvoir déconnecter vos autres contrôleurs, vous \ndevez donc redémarrer votre OUYA et débrancher le câble USB.\n\nÀ partir de maintenant, vous devriez être capable d'utiliser le bouton \nd'accueil pour connecter sans fil. Quand vous avez finir de jouer, \nappuyez sur le bouton d'accueil pour 10 seconds pour éteindre le \ncontrôleur; si non les batteries continueraient à épuiser.", + "pairingTutorialText": "Vidéo Tutoriel - Liaisons des manettes PS3", + "titleText": "Utiliser les manettes PS3 avec ${APP_NAME}:" + }, + "publicBetaText": "BETA PUBLIQUE", + "punchBoldText": "FRAPPER", + "punchText": "Frapper", + "purchaseForText": "Achetez pour ${PRICE}", + "purchaseGameText": "Acheter le Jeu", + "purchasingText": "Achat en cours...", + "quitGameText": "Quitter ${APP_NAME}?", + "quittingIn5SecondsText": "Le jeu fermera dans 5 secondes...", + "randomPlayerNamesText": "DEFAULT_NAMES, Guy, Jean, Jacques, Jérémy, Maurice, Henri, Patrick, François, Frédéric, Éric, Gabrielle, Érica, Marie, Hélène, Isabelle, Jacqueline, Jasmine, Zoé, Juliette, Catherine, Natalie, Alexandra, Alexandre, Claire, Christophe, Pierre, Quentin, Philippe, Francis", + "randomText": "Hasard", + "rankText": "Classement", + "ratingText": "Évaluation", + "reachWave2Text": "Atteignez la 2e vague pour être classé.", + "readyText": "prêt", + "recentText": "Récents", + "remainingInTrialText": "restant en test", + "remoteAppInfoShortText": "${APP_NAME} est plus amusant quand vous jouez avec votre famille ou des amis.\nBranchez une ou plusieurs manettes ou installez l'application \n${REMOTE_APP_NAME} sur des téléphones ou des tablettes \npour les utiliser en tant que manettes.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Position du Bouton", + "button_size": "Taille du Bouton", + "cant_resolve_host": "Ne peut pas résoudre l'hôte.", + "capturing": "Capturer...", + "connected": "Connecté.", + "description": "Utilisez votre smartphone ou tablette comme manette avec BombSquad. \nJusqu'à 8 appareils peuvent se connecter en même temps pour des parties locales épiques sur un seul écran.", + "disconnected": "Déconnecté par le serveur", + "dpad_fixed": "fixé", + "dpad_floating": "flotter", + "dpad_position": "Position D-Pad", + "dpad_size": "Taille du D-Pad", + "dpad_type": "Type D-Pad", + "enter_an_address": "Tapez une Adresse", + "game_full": "Le jeu est plein ou n'accepte pas d'autres joueurs.", + "game_shut_down": "Le jeu a fermé.", + "hardware_buttons": "Boutons d'Hardware", + "join_by_address": "Joindre par adresse ip...", + "lag": "Décalage: ${SECONDS} secondes", + "reset": "Réinitialiser", + "run1": "Exécution 1", + "run2": "Exécution 2", + "searching": "Rechercher pour les jeux de BombSquad...", + "searching_caption": "Touchez le nom d'un jeu pour rejoindre.\nVérifiez que vous êtes sur le même réseau wifi que le jeu.", + "start": "Commencer", + "version_mismatch": "Mauvaise version.\nVérifiez que BombSquad et BombSquad Remote \nsont mis à jour et réessayez." + }, + "removeInGameAdsText": "Débloquez \"${PRO}\" dans le magasin pour enlever les annonces.", + "renameText": "Renommer", + "replayEndText": "Terminer la Reprise", + "replayNameDefaultText": "Reprise du Match Précédent", + "replayReadErrorText": "Erreur de lecture de la reprise.", + "replayRenameWarningText": "Renommer \"${REPLAY}\" après un jeu si vous voulez le conserver; autrement il sera écrasé.", + "replayVersionErrorText": "Désolé, cette reprise a été créée avec une version \ndifférente du jeu et ne peut pas être utilisé.", + "replayWatchText": "Regarder La Reprise", + "replayWriteErrorText": "Erreur d'écriture du fichier de la reprise.", + "replaysText": "Reprises", + "reportPlayerExplanationText": "Utilisez cet email pour rapporter tricherie, langage inapproprié, ou d'autres comportements mauvais.\nDécrivez en-dessous:", + "reportThisPlayerCheatingText": "Tricherie", + "reportThisPlayerLanguageText": "Langage Inapproprié", + "reportThisPlayerReasonText": "Que voulez-vous rapporter?", + "reportThisPlayerText": "Envoyez Un Rapport", + "requestingText": "En cours de demande...", + "restartText": "Redémarrer", + "retryText": "Réessayer", + "revertText": "Retour", + "runBoldText": "COURIR", + "runText": "Courir", + "saveText": "Sauvegarder", + "scanScriptsErrorText": "Erreur(s) dans les scripts; voir journal pour détails.", + "scoreChallengesText": "Défis de Score", + "scoreListUnavailableText": "Liste des scores indisponible.", + "scoreText": "Score", + "scoreUnits": { + "millisecondsText": "Millisecondes", + "pointsText": "Points", + "secondsText": "Secondes" + }, + "scoreWasText": "(A été ${COUNT})", + "selectText": "Sélectionner", + "seriesWinLine1PlayerText": "A GAGNÉ LA", + "seriesWinLine1TeamText": "A GAGNÉ LA", + "seriesWinLine1Text": "A GAGNÉ", + "seriesWinLine2Text": "SÉRIE!", + "settingsWindow": { + "accountText": "Compte", + "advancedText": "Avancé", + "audioText": "Son", + "controllersText": "Contrôleurs", + "enterPromoCodeText": "Entrer un code promotionnel", + "graphicsText": "Graphiques", + "playerProfilesMovedText": "Note: les Profiles de Joueurs ont été déplacés dans la page de Compte, dans le menu principal.", + "playerProfilesText": "Profils des Joueurs", + "titleText": "Paramètres" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(un simple clavier sur l'écran pour taper du texte)", + "alwaysUseInternalKeyboardText": "Toujours utiliser le clavier interne", + "benchmarksText": "Benchmarks et Tests de Stress", + "disableCameraGyroscopeMotionText": "Désactiver le mouvement de gyroscope de la caméra", + "disableCameraShakeText": "Désactiver le tremblement de la camera", + "disableThisNotice": "(vous pouvez désactiver cette notification dans les paramètres avancés)", + "enablePackageModsDescriptionText": "(activer plusieurs capabilités des mods mais désactiver le jeu en réseau)", + "enablePackageModsText": "Activer les Packages Mods Locaux", + "enterPromoCodeText": "Entrez code", + "forTestingText": "Note: ces valeurs sont exclusivement pour les tests et seront perdus à la fermeture de l'application.", + "helpTranslateText": "Les traductions de ${APP_NAME} proviennent des efforts de \nla communauté. Si vous voulez contribuer ou corriger une \ntraduction, suivez le lien ci-dessous. Merci d'avance!", + "kickIdlePlayersText": "Déconnecter les joueurs inactifs", + "kidFriendlyModeText": "Mode Enfant-Gentil (moins de violence, etc)", + "languageText": "Langage", + "moddingGuideText": "Guide pour Modder", + "mustRestartText": "Vous devez redémarrer le jeu pour que les changements prennent effet.", + "netTestingText": "Tester Votre Réseau", + "resetText": "Réinitialiser", + "showBombTrajectoriesText": "Montrer les trajectoires de bombe", + "showPlayerNamesText": "Montrer les Noms des Joueurs", + "showUserModsText": "Montrer le Dossier des Mods", + "titleText": "Avancé", + "translationEditorButtonText": "Éditeur des Traductions de ${APP_NAME}", + "translationFetchErrorText": "statut de la traduction indisponible", + "translationFetchingStatusText": "vérification du statut de la traduction...", + "translationInformMe": "M'avertir quand ma langue a besoin de mises à jour", + "translationNoUpdateNeededText": "ce langage est à jour; woohoo!", + "translationUpdateNeededText": "** ce langage à besoin des modifications!! **", + "vrTestingText": "Test de la RV" + }, + "shareText": "Partager", + "sharingText": "Partage...", + "showText": "Montre", + "signInForPromoCodeText": "Vous devez vous connecter à un compte pour que les codes prennent effet.", + "signInWithGameCenterText": "Pour l'utilisation d'un compte Game \nCenter, connectez-vous avec l'application Game Center.", + "singleGamePlaylistNameText": "Seulement ${GAME}", + "singlePlayerCountText": "1 joueur", + "soloNameFilterText": "${NAME} Solo", + "soundtrackTypeNames": { + "CharSelect": "Sélection du Personnage", + "Chosen One": "Élu", + "Epic": "Jeux Épiques", + "Epic Race": "Course Épique", + "FlagCatcher": "Capturer le Drapeau", + "Flying": "Pensées Heureuses", + "Football": "Football", + "ForwardMarch": "Assaut", + "GrandRomp": "Conquête", + "Hockey": "Hockey", + "Keep Away": "Tenir à l'Écart", + "Marching": "Défense du portail", + "Menu": "Menu Principal", + "Onslaught": "Bousculade", + "Race": "Course", + "Scary": "Roi de la Colline", + "Scores": "Écran des scores", + "Survival": "Élimination", + "ToTheDeath": "Tuerie", + "Victory": "Écran des scores finaux" + }, + "spaceKeyText": "espace", + "statsText": "Stats", + "storagePermissionAccessText": "Cette action a besoin de l'accès au stockage", + "store": { + "alreadyOwnText": "Vous avez déja acheté ${NAME}!", + "bombSquadProDescriptionText": "• Double le nombre des billets gagnés grâce aux succès\n• Enlève les annonces\n• Inclus ${COUNT} billets bonus\n• +${PERCENT}% de score dans la ligue\n• Débloque les niveaux co-op\n '${INF_ONSLAUGHT}' et '${INF_RUNAROUND}'", + "bombSquadProFeaturesText": "Fonctionnalités:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "* Supprime les annonces et publicités dans le jeu\n* Déverrouille des paramètres supplémentaires\n* Comprend également:", + "buyText": "Acheter", + "charactersText": "Personnages", + "comingSoonText": "À Venir...", + "extrasText": "Extras", + "freeBombSquadProText": "BombSquad est désormais gratuit, mais comme vous l'avez acheté, vous\nrecevez la mise à jour BombSquad Pro et ${COUNT} tickets en remerciement.\nAmusez-vous bien avec les nouveautés, et merci pour votre soutien!\n-Eric", + "gameUpgradesText": "Les Mises À Niveau", + "getCoinsText": "Avoir des pièces", + "holidaySpecialText": "Spécial Vacances", + "howToSwitchCharactersText": "(allez à \"${SETTINGS} -> ${PLAYER_PROFILES}\" pour assigner et customiser des personnages)", + "howToUseIconsText": "(créez des profils de joueur global (dans la page du compte) pour les utiliser)", + "howToUseMapsText": "(utilisez ces cartes dans vos propres playlists équipes/mêlée générale)", + "iconsText": "Icônes", + "loadErrorText": "Impossible de charger la page.\nVérifiez votre connexion internet.", + "loadingText": "chargement en cours", + "mapsText": "Cartes", + "miniGamesText": "Mini Jeux", + "oneTimeOnlyText": "(une fois seulement)", + "purchaseAlreadyInProgressText": "Un achat de ceci est déjà en cours.", + "purchaseConfirmText": "Acheter ${ITEM}?", + "purchaseNotValidError": "L'Achat n'est pas valide.\nContactez ${EMAIL} (En anglais) si c'est une erreur.", + "purchaseText": "Acheter", + "saleBundleText": "Vente Groupée!", + "saleExclaimText": "Promo!", + "salePercentText": "(${PERCENT}% de rabais)", + "saleText": "PROMO", + "searchText": "Rechercher", + "teamsFreeForAllGamesText": "Jeux d'Équipes / Mêlée Générale", + "totalWorthText": "*** une valeur de ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Une amélioration ?", + "winterSpecialText": "Spéciale Hivernale", + "youOwnThisText": "- vous possédez ceci -" + }, + "storeDescriptionText": "Un Jeu Fou à 8 Joueurs!\n\nExplosez vos amis (ou l'ordinateur) dans un tournoi de mini-jeux explosifs comme la capture du drapeau, le hockey à la bombe, et les Match-à-Mort dans un slow-motion épique!\n\nLes contrôles simples et l'ajout facile de contrôleur permet de regrouper jusqu'à 8 personnes dans l'action; vous pouvez même utiliser vos appareils mobiles comme contrôleurs via l'application 'BombSquad Remote' gratuite!\n\nLarguez Les Bombes!\n\nVisitez www.froemling.net/bombsquad pour plus d'information.", + "storeDescriptions": { + "blowUpYourFriendsText": "Explosez vos amis.", + "competeInMiniGamesText": "Participez aux mini-jeux délirants.", + "customize2Text": "Customisez les personnages, les mini-jeux, et même la bande-sonore.", + "customizeText": "Customisez les personnages et créez vos propres playlists de mini-jeux.", + "sportsMoreFunText": "Les sports sont plus amusants avec des explosifs.", + "teamUpAgainstComputerText": "Faites equipe contre l'ordinateur." + }, + "storeText": "Magasin", + "submitText": "Soumettre", + "submittingPromoCodeText": "Envoi du code...", + "teamNamesColorText": "Noms d'équipe/Couleurs...", + "teamsText": "Équipes", + "telnetAccessGrantedText": "L'accès Telnet est activé.", + "telnetAccessText": "Accès Telnet détecté; autoriser?", + "testBuildErrorText": "Cette version test n'est plus active; cherchez une version nouvelle.", + "testBuildText": "Version Test", + "testBuildValidateErrorText": "Impossible de valider cette version de test. (pas de connexion internet?)", + "testBuildValidatedText": "Version Test Validée; Amusez-Vous!", + "thankYouText": "Merci pour votre soutien! Amusez-vous!!", + "threeKillText": "TRIPLE MEURTRE!!!", + "timeBonusText": "Bonus de Temps", + "timeElapsedText": "Temps Passé", + "timeExpiredText": "Temps Expiré", + "timeSuffixDaysText": "${COUNT}j", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Conseil", + "titleText": "BombSquad", + "titleVRText": "RV BombSquad", + "topFriendsText": "Les amis les mieux classés", + "tournamentCheckingStateText": "Vérification de l'état du tournoi; attendez SVP...", + "tournamentEndedText": "Ce tournoi est terminé. Un nouveau commencera bientôt.", + "tournamentEntryText": "Inscription au Tournoi", + "tournamentResultsRecentText": "Résultats des Tournois Récents", + "tournamentStandingsText": "Classements du Tournoi", + "tournamentText": "Tournoi", + "tournamentTimeExpiredText": "Le temps de ce tournoi a expiré", + "tournamentsDisabledWorkspaceText": "Les tournois sont désactivés lorsque les espaces de travail sont actifs.\nPour réactiver les tournois, désactivez votre espace de travail et redémarrez.", + "tournamentsText": "Tournois", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Osseux", + "Butch": "Butch", + "Easter Bunny": "Lapin de Pâques", + "Flopsy": "Flopsy", + "Frosty": "Gel", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Sp'Arr", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Middle-Man", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Chelem", + "Santa Claus": "Père Noël", + "Snake Shadow": "Ombre du Serpent", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao Mascot", + "Todd": "Todd", + "Todd McBurton": "Todd McBurton", + "Xara": "Xara", + "Zoe": "Zoé", + "Zola": "Zola" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Boucherie\nInfinie", + "Infinite\nRunaround": "Défense du portail\nInfinie", + "Onslaught\nTraining": "Boucherie\nEntrainement", + "Pro\nFootball": "Football\nPro", + "Pro\nOnslaught": "Boucherie\nPro", + "Pro\nRunaround": "Pro\nDéfense du portail", + "Rookie\nFootball": "Football\nDébutant", + "Rookie\nOnslaught": "Boucherie\nDébutant", + "The\nLast Stand": "Le\nDernier Rempart", + "Uber\nFootball": "Über\nFootball", + "Uber\nOnslaught": "Über\nBoucherie", + "Uber\nRunaround": "Über\nDéfense du portail" + }, + "coopLevelNames": { + "${GAME} Training": "Entraînement pour ${GAME}", + "Infinite ${GAME}": "${GAME} Infini", + "Infinite Onslaught": "Boucherie Infinie", + "Infinite Runaround": "Défense du portail infinie", + "Onslaught": "Boucherie Infinie", + "Onslaught Training": "Entraînement pour Bousculade", + "Pro ${GAME}": "${GAME} Pro", + "Pro Football": "Football Pro", + "Pro Onslaught": "Bousculade Pro", + "Pro Runaround": "Défense du portail Pro", + "Rookie ${GAME}": "${GAME} Novice", + "Rookie Football": "Football Novice", + "Rookie Onslaught": "Bousculade Novice", + "Runaround": "Défense du portail infinie", + "The Last Stand": "Le Dernier Rempart", + "Uber ${GAME}": "${GAME} Uber", + "Uber Football": "Football Uber", + "Uber Onslaught": "Bousculade Uber", + "Uber Runaround": "Défense du portail Uber" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Restez l'élu pendant un certain temps pour gagner.\nTuez l'élu pour devenir l'élu.", + "Bomb as many targets as you can.": "Bombardez autant de cibles que vous pouvez.", + "Carry the flag for ${ARG1} seconds.": "Tenez le drapeau pendant ${ARG1} secondes.", + "Carry the flag for a set length of time.": "Tenez le drapeau pendant une durée définie.", + "Crush ${ARG1} of your enemies.": "Terrassez ${ARG1} de vos ennemis.", + "Defeat all enemies.": "Tuez tous les ennemis.", + "Dodge the falling bombs.": "Esquivez les bombes chutantes.", + "Final glorious epic slow motion battle to the death.": "Bataille finale jusqu'à la mort dans un glorieux slow-motion épique.", + "Gather eggs!": "Ramassez les œufs !", + "Get the flag to the enemy end zone.": "Amenez le drapeau à la zone de but opposée.", + "How fast can you defeat the ninjas?": "À quelle vitesse pouvez-vous vaincre les ninjas?", + "Kill a set number of enemies to win.": "Tuez plusieurs ennemis pour gagner.", + "Last one standing wins.": "Le dernier joueur debout gagne.", + "Last remaining alive wins.": "Le dernier joueur debout gagne.", + "Last team standing wins.": "La dernière équipe debout gagne.", + "Prevent enemies from reaching the exit.": "Empêchez les ennemis d'arriver au portail.", + "Reach the enemy flag to score.": "Touchez le drapeau ennemi pour marquer.", + "Return the enemy flag to score.": "Ramener le drapeau ennemi pour marquer.", + "Run ${ARG1} laps.": "Faites ${ARG1} tours.", + "Run ${ARG1} laps. Your entire team has to finish.": "Faites ${ARG1} tours. Toute votre équipe doit finir.", + "Run 1 lap.": "Faites 1 tour.", + "Run 1 lap. Your entire team has to finish.": "Faites 1 tour. Toute votre équipe doit finir.", + "Run real fast!": "Courez très rapidement!", + "Score ${ARG1} goals.": "Marquez ${ARG1} buts.", + "Score ${ARG1} touchdowns.": "Marquez ${ARG1} touchés.", + "Score a goal": "Marquez un but.", + "Score a goal.": "Marquez un but.", + "Score a touchdown.": "Marquez un touché.", + "Score some goals.": "Marquez quelques buts.", + "Secure all ${ARG1} flags.": "Sécurisez tous les ${ARG1} drapeaux.", + "Secure all flags on the map to win.": "Sécurisez tous les drapeaux sur la carte pour gagner.", + "Secure the flag for ${ARG1} seconds.": "Sécurisez le drapeau pendant ${ARG1} secondes.", + "Secure the flag for a set length of time.": "Sécurisez le drapeau pendant une durée définie.", + "Steal the enemy flag ${ARG1} times.": "Volez le drapeau ennemi ${ARG1} fois.", + "Steal the enemy flag.": "Volez le drapeau ennemi.", + "There can be only one.": "Il ne peut y'en avoir qu'un seul.", + "Touch the enemy flag ${ARG1} times.": "Touchez le drapeau ennemi ${ARG1} fois.", + "Touch the enemy flag.": "Touchez le drapeau ennemi.", + "carry the flag for ${ARG1} seconds": "Tenez le drapeau pendant ${ARG1} secondes", + "kill ${ARG1} enemies": "Tuez ${ARG1} ennemis", + "last one standing wins": "Le dernier joueur debout gagne", + "last team standing wins": "La dernière équipe debout gagne", + "return ${ARG1} flags": "Ramener ${ARG1} drapeaux", + "return 1 flag": "Ramener 1 drapeau", + "run ${ARG1} laps": "Faites ${ARG1} tours", + "run 1 lap": "Faites 1 tour", + "score ${ARG1} goals": "Marquez ${ARG1} buts", + "score ${ARG1} touchdowns": "Marquez ${ARG1} touchés", + "score a goal": "Marquez un but", + "score a touchdown": "Marquez un touché", + "secure all ${ARG1} flags": "Sécurisez tous les ${ARG1} drapeaux", + "secure the flag for ${ARG1} seconds": "Sécurisez le drapeau pendant ${ARG1} secondes", + "touch ${ARG1} flags": "Touchez ${ARG1} drapeaux", + "touch 1 flag": "Touchez 1 drapeau" + }, + "gameNames": { + "Assault": "Assaut", + "Capture the Flag": "Capturer le Drapeau", + "Chosen One": "L'Élu", + "Conquest": "Conquête", + "Death Match": "Tuerie", + "Easter Egg Hunt": "Chasse aux œufs", + "Elimination": "Élimination", + "Football": "Football", + "Hockey": "Hockey", + "Keep Away": "Tenir à l'Écart", + "King of the Hill": "Roi de La colline", + "Meteor Shower": "Pluie de météorites", + "Ninja Fight": "Lutte des Ninjas", + "Onslaught": "Bousculade", + "Race": "Course", + "Runaround": "Défense du portail", + "Target Practice": "Tir sur Cible", + "The Last Stand": "Le dernier rempart" + }, + "inputDeviceNames": { + "Keyboard": "Clavier", + "Keyboard P2": "Clavier J2" + }, + "languages": { + "Arabic": "Arabe", + "Belarussian": "Biélorusse", + "Chinese": "Chinois simplifié", + "ChineseTraditional": "Chinois Traditionnel", + "Croatian": "Croate", + "Czech": "Tchèque", + "Danish": "Danois", + "Dutch": "Néerlandais", + "English": "Anglais", + "Esperanto": "Espéranto", + "Filipino": "Philippin", + "Finnish": "Finnois", + "French": "Français", + "German": "Allemand", + "Gibberish": "Charabia", + "Greek": "Grec", + "Hindi": "Hindi", + "Hungarian": "Hongrois", + "Indonesian": "Indonésien", + "Italian": "Italien", + "Japanese": "Japonais", + "Korean": "Coréen", + "Malay": "Malais", + "Persian": "Persan", + "Polish": "Polonais", + "Portuguese": "Portugais", + "Romanian": "Roumain", + "Russian": "Russe", + "Serbian": "Serbe", + "Slovak": "Slovaque", + "Spanish": "Espagnol", + "Swedish": "Suédois", + "Tamil": "Tamil", + "Thai": "Thaïlandais", + "Turkish": "Turc", + "Ukrainian": "Ukrainien", + "Venetian": "Vénitien", + "Vietnamese": "Vietnamien" + }, + "leagueNames": { + "Bronze": "Bronze", + "Diamond": "Diamant", + "Gold": "Or", + "Silver": "Argent" + }, + "mapsNames": { + "Big G": "Grand G", + "Bridgit": "Bridgit", + "Courtyard": "Cour", + "Crag Castle": "Château Escarpé", + "Doom Shroom": "Champignon de la Tragédie", + "Football Stadium": "Stade de Football", + "Happy Thoughts": "Pensées Heureuses", + "Hockey Stadium": "Stade de Hockey", + "Lake Frigid": "Lac Frigo", + "Monkey Face": "Visage d'un Singe", + "Rampage": "Carnage", + "Roundabout": "Rond-Point", + "Step Right Up": "Prendre un Pas", + "The Pad": "La Plate-Forme", + "Tip Top": "Le Sommet", + "Tower D": "Tour D", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Seulement Épique", + "Just Sports": "Seulement les Sports" + }, + "promoCodeResponses": { + "invalid promo code": "Code promo invalide" + }, + "scoreNames": { + "Flags": "Drapeaux", + "Goals": "Buts", + "Score": "Points", + "Survived": "A Survécu", + "Time": "Temps", + "Time Held": "Temps Tenu" + }, + "serverResponses": { + "A code has already been used on this account.": "Un code a déjà été utilisé sur ce compte.", + "A reward has already been given for that address.": "Une récompense a déjà été attribuée pour cette adresse.", + "Account linking successful!": "Liaison des comptes réussie!", + "Account unlinking successful!": "Compte dissocié avec succès!", + "Accounts are already linked.": "Ces comptes sont déjà liés.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "La vue de l'annonce n'a pas pu être vérifiée.\nVeuillez vous assurer que vous utilisez une version officielle et à jour du jeu.", + "An error has occurred; (${ERROR})": "Une erreur est survenue; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Une erreur est survenue; veuillez contacter le support.(${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Une erreur est survenue; SVP contacter support@froemling.net.", + "An error has occurred; please try again later.": "Une erreur s'est produite. Réessayez plus tard.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Voulez-vous vraiment lier ces comptes?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nAction irréversible!", + "BombSquad Pro unlocked!": "Bombsquad Pro débloqué!", + "Can't link 2 accounts of this type.": "Impossible de lier 2 comptes de ce genre.", + "Can't link 2 diamond league accounts.": "Impossible de lier 2 comptes dans la ligue diamant.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Impossible de lier les comptes, le maximum de ${COUNT} comptes liés est déjà atteint.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Tricherie détectée, scores et prix suspendus pour ${COUNT} jours.", + "Could not establish a secure connection.": "Impossible d'établir une connexion sécurisé.", + "Daily maximum reached.": "Limite quotidienne atteinte.", + "Entering tournament...": "Accès au tournoi...", + "Invalid code.": "Code invalide.", + "Invalid payment; purchase canceled.": "Payement invalide. Achat annulé.", + "Invalid promo code.": "Code promo invalide.", + "Invalid purchase.": "Achat invalide.", + "Invalid tournament entry; score will be ignored.": "Entrée invalide; votre score sera ignoré.", + "Item unlocked!": "Article débloqué!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LIEN REFUSÉ. ${ACCOUNT} contient des\ndonnées importantes qui seraient perdus.\nVous pouvez lier dans l'ordre inverse si vous le souhaitez\n(et perdre les données de CE compte à la place)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Lier le compte ${ACCOUNT} à ce compte?\nToutes les données existantes sur ${ACCOUNT} seront perdues.\nCela ne peut pas être annulé. Vous en êtes sûr", + "Max number of playlists reached.": "Nombre maximum de playlists atteint.", + "Max number of profiles reached.": "Nombre maximum de profils atteint.", + "Maximum friend code rewards reached.": "Maximum récompenses de code ami atteint.", + "Message is too long.": "Message trop long.", + "No servers are available. Please try again soon.": "Aucun serveur disponible. S'il vous plaît réessayez plus tard.", + "Profile \"${NAME}\" upgraded successfully.": "Le profil \"${NAME}\" à été mis à jour.", + "Profile could not be upgraded.": "Le profil ne peut pas être mis à jour.", + "Purchase successful!": "Achat réussi!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Vous avez reçu ${COUNT} tickets pour votre connexion.\nRevenez demain pour en recevoir ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La fonctionnalité serveur n'est plus prise en charge dans cette version du jeu;\nVeuillez mettre à jour vers une version plus récente", + "Sorry, there are no uses remaining on this code.": "Désolé, ce code ne peut plus être utilisé.", + "Sorry, this code has already been used.": "Désolé, ce code a déjà été utilisé.", + "Sorry, this code has expired.": "Désolé, ce code a expiré.", + "Sorry, this code only works for new accounts.": "Désolé, ce code fonctionne seulement pour les nouveaux comptes.", + "Still searching for nearby servers; please try again soon.": "Recherche de serveurs à proximité en cours; s'il vous plaît réessayez plus tard.", + "Temporarily unavailable; please try again later.": "Temporairement indisponible; veuillez réessayer plus tard.", + "The tournament ended before you finished.": "Le tournoi s'est terminé avant que vous finissiez.", + "This account cannot be unlinked for ${NUM} days.": "Ce compte ne peux pas être dissocié pendant ${NUM} jours.", + "This code cannot be used on the account that created it.": "Ce code ne peut pas être utilisé par le compte qui l'a créé.", + "This is currently unavailable; please try again later.": "Ceci est actuellement indisponible ; s'il vous plaît essayez plus tard.", + "This requires version ${VERSION} or newer.": "Ceci requiert la version ${VERSION} ou plus récente.", + "Tournaments disabled due to rooted device.": "Tournois désactivés car appareil rooté.", + "Tournaments require ${VERSION} or newer": "Les tournois nécessitent ${VERSION} ou plus récent", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Dissocier ${ACCOUNT} de ce compte?\nToutes les données sur ${ACCOUNT} seront réinitialisées.\n(à l'exception des achèvements dans certains cas)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ATTENTION: des plaintes de piratage/tricherie ont été émises contre votre compte.\nLes comptes piratés sont interdits et bannis. S'il vous plaît, jouez fair play", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Voulez-vous lier votre compte d'appareil à celui-ci?\n\nVotre compte d'appareil est ${ACCOUNT1}\nCe compte est ${ACCOUNT2}\n\nCeci vous permet de garder votre progression.\nAttention: ceci est permanent!", + "You already own this!": "Vous possédez déjà ceci!", + "You can join in ${COUNT} seconds.": "Vous pouvez rejoindre dans ${COUNT} secondes.", + "You don't have enough tickets for this!": "Vous n'avez pas assez de tickets pour ça!", + "You don't own that.": "Cela ne vous appartient pas!", + "You got ${COUNT} tickets!": "Vous avez reçu ${COUNT} tickets!", + "You got a ${ITEM}!": "Vous avez reçu un ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Vous avez été promu à une ligue supérieure; félicitations!", + "You must update to a newer version of the app to do this.": "L'app doit être mise à jour pour faire ceci.", + "You must update to the newest version of the game to do this.": "Vous devez mettre à jour vers une version plus récente pour faire ça.", + "You must wait a few seconds before entering a new code.": "Vous devez attendre quelques secondes avant d'entrer un nouveau code.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Vous avez été classé #${RANK} au dernier tournoi. Merci d'avoir participé!", + "Your account was rejected. Are you signed in?": "Votre compte a été rejeté. Êtes-vous connecté?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Votre copie du jeu a été modifié.\nRéinitialisez tous changements et réessayez.", + "Your friend code was used by ${ACCOUNT}": "Votre code d'ami a été utilisé par ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minute", + "1 Second": "1 Seconde", + "10 Minutes": "10 Minutes", + "2 Minutes": "2 Minutes", + "2 Seconds": "2 Secondes", + "20 Minutes": "20 Minutes", + "4 Seconds": "4 Secondes", + "5 Minutes": "5 Minutes", + "8 Seconds": "8 Secondes", + "Allow Negative Scores": "Permettre des scores négatifs", + "Balance Total Lives": "Équilibrer total des vies", + "Bomb Spawning": "Apparitions de bombes", + "Chosen One Gets Gloves": "L'élu reçoit des gants de boxe", + "Chosen One Gets Shield": "L'élu reçoit un bouclier", + "Chosen One Time": "Temps pour l'élu", + "Enable Impact Bombs": "Activer les bombes d'impact", + "Enable Triple Bombs": "Activer les triples bombes", + "Entire Team Must Finish": "L'équipe entière doit finir", + "Epic Mode": "Mode épique", + "Flag Idle Return Time": "délai de retour drapeau perdu", + "Flag Touch Return Time": "Temps à toucher drapeau pour retour", + "Hold Time": "Temps de possession", + "Kills to Win Per Player": "Meurtres par joueur pour gagner", + "Laps": "Tours", + "Lives Per Player": "Vies par joueur", + "Long": "Long", + "Longer": "Plus long", + "Mine Spawning": "Apparition des mines", + "No Mines": "Aucune mines", + "None": "Aucun", + "Normal": "Normal", + "Pro Mode": "Mode Pro", + "Respawn Times": "Temps de réapparition", + "Score to Win": "Score pour gagner", + "Short": "Court", + "Shorter": "Très court", + "Solo Mode": "Mode solo", + "Target Count": "Nombre de cibles", + "Time Limit": "Limite de temps" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "L'équipe ${TEAM} est disqualifiée parce que ${PLAYER} a quitté la partie", + "Killing ${NAME} for skipping part of the track!": "${NAME} a été tué pour avoir pris un raccourci!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Attention à ${NAME}: turbo / bouton-spamming vous assomme." + }, + "teamNames": { + "Bad Guys": "Méchants", + "Blue": "Bleu", + "Good Guys": "Gentils", + "Red": "Rouge" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Un coup de poing avec le saut, la vitesse et la bonne rotation fait au \nmoment opportun, peut tuer un ennemi en un coup.", + "Always remember to floss.": "Rappelez-vous de la patate suprême.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Créez un profil de joueur pour vous même et vos amis avec vos noms\net apparences préférés au lieu d'utiliser ceux au hasard.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Les boites de malédiction vous transforment en bombe à retardement. \nLe seul remède est un paquet de santé.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Malgré leurs apparences, toutes les personnages ont les mêmes \nabilités, donc choisissez celui qui vous ressemble le plus.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Ne soyez pas trop sûr de vous avec le bouclier d'énergie; vous pouvez toujours être jeté hors de la falaise.", + "Don't run all the time. Really. You will fall off cliffs.": "Ne courez pas tout le temps. Vraiment. Vous chuterez hors des falaises.", + "Don't spin for too long; you'll become dizzy and fall.": "Ne tournez pas trop longtemps; vous allez avoir le tournis et tomber.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Gardez n'importe quel bouton appuyé pour courir. (Les gâchettes marchent aussi si vous avez)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Gardez n'importe quel bouton appuyé pour courir. Vous arriverez aux endroits \nplus rapidement mais tourner c'est plus difficile, donc faites attention aux falaises.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Les bombes glacées ne sont pas très puissantes, mais elles\ngèlent tous ce qu'elles touchent, ce qui facilite le fracassement.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Si quelqu'un vous ramasse, frappez-le et il vous lâchera. \nCeci fonctionne en réalité aussi.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Si vous manquez de manettes, installez l'app '${REMOTE_APP_NAME}'\nsur vos appareils mobiles pour les utiliser comme manettes.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Si vous manquez les contrôleurs, installez l'application 'BombSquad Remote' \nsur votre système iOS/Android pour les utiliseront comme contrôleurs.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Si une bombe gluante est collée sur vous, sautez et tournez en rond. Vous pourriez\nvous en débarrasser, ou sinon vos derniers moments seront divertissants.", + "If you kill an enemy in one hit you get double points for it.": "Si vous tuez un ennemi en un coup vous obtiendriez deux fois plus de points.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Si vous prenez une malédiction, votre seule chance est de\ntrouver un paquet de santé dans les prochaines secondes.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Si vous restez en place, vous êtes foutu. Courez et esquiver pour survivre..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Si vous avez plusieurs joueurs qui sont intermittent, activez 'déconnecter-les-joueurs-inactifs'\ndans les paramètres au cas où quelqu'un oublierait de quitter le jeu.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Si votre appareil chauffe trop ou vous souhaitez économiser de la batterie,\nbaissez les \"Graphiques\" ou \"Résolution\" dans Paramètres->Graphiques", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Si votre fréquence d'images est agité, essayez de diminuer la résolution\nou les visuels dans les options graphiques.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Dans Capturer le Drapeau, votre propre drapeau doit être à votre base pour marquer un point. Si l'autre\néquipe est proche de marquer, vous pouvez les ralentir en volant leur drapeau.", + "In hockey, you'll maintain more speed if you turn gradually.": "Dans hockey, vous maintiendrez votre vitesse si vous tournez graduellement.", + "It's easier to win with a friend or two helping.": "C'est plus facile de gagner avec l'aide d'un ou deux amis.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Sautez quand vous lancez une bombe pour envoyer le plus loin possible.", + "Land-mines are a good way to stop speedy enemies.": "Les mines terrestres sont un bon moyen pour ralentir les ennemis.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Beaucoup de choses peuvent être ramassées et jetées, même les autres joueurs. Jetez vos \nennemis hors des falaises est une stratégie efficace et hilarante.", + "No, you can't get up on the ledge. You have to throw bombs.": "Non, vous ne pouvez pas monter sur le rebord. Vous devez lancer des bombes.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Les joueurs peuvent joindre et quitter quand les jeux sont en cours, \nvous pouvez aussi brancher et débrancher les contrôleurs rapidement.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Les joueurs peuvent rejoindre et quitter en jeu dans la plupart des modes de jeu,\nvous pouvez aussi débrancher et rebrancher une manette en cours de partie.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Les bonus ont seulement une limite de temps en co-op.\nEn équipe et en mêlée générale ils sont à vous jusqu'à ce que vous mouriez.", + "Practice using your momentum to throw bombs more accurately.": "Entraînez vous à utiliser votre momentum pour vous lancez les bombes plus précisément.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Les coups de poing font plus de dommage quand vous bougez plus vite,\nessayez de courir, sauter, et tourner comme un fou.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Courez en arrière et en avant avant de lancer votre bombe pour lancer plus loin.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Éliminez un groupe d'ennemis en fesant\nexploser une bombe près du TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "La tête est la plus vulnérable, une bombe gluante sur \nla caboche et c'est généralement la fin de la partie.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Ce niveau ne finit jamais, mais un score élevé vous \nfera gagner le respect éternel à travers le monde.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "La force du lancé est basée sur la direction que vous maintenez.\nPour lancez gentiment devant vous, ne maintenez aucune direction.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Ennuyé par la bande sonore? Remplacez la avec votre propre musique!\nAllez à Paramètres->Audio->Bande Sonore", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Essayez de 'tenir au chaud' les bombes une ou deux secondes avant de les lancer.", + "Try tricking enemies into killing eachother or running off cliffs.": "Essayez de duper vos ennemis pour qu'ils se tuent entre eux ou les faire sauter des falaises.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Utilisez le bouton rammaser pour saisir le drapeau < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Marchez en arrière puis en avant pour avoir plus de distance avec vos lances..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Vous pouvez 'viser' avec vos poings en tournant à droite ou à gauche.\nC'est utile pour frappez les \"bad guys\" hors des bords ou marquez en hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Vous pouvez juger quand la bombe va exploser basant sur la \ncouleur de la mèche: jaune..orange..rouge..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Vous pouvez lancer les bombes plus loin en sautant avant de lancer.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Vous n'avez pas besoin d'éditer votre profil pour changer de personnage; appuyez juste sur\nle bouton du haut (prendre) quand vous rejoignez une partie pour remplacer celui par défaut.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Vous subissez des dégâts quand vous vous cognez la tête,\nalors essayez de ne pas vous cogner la tête.", + "Your punches do much more damage if you are running or spinning.": "Vos poings font plus de dommage si vous êtes en train de courir ou tourner." + } + }, + "trialPeriodEndedText": "Votre période d'essai est terminée. Voulez vous\nacheter BombSquad et continuer à jouer?", + "trophiesRequiredText": "Cela nécessite au moins ${NUMBER} trophées.", + "trophiesText": "Trophées", + "trophiesThisSeasonText": "Trophées de cette saison", + "tutorial": { + "cpuBenchmarkText": "Exécution tutoriel à vitesse grotesque (teste principalement la vitesse CPU)", + "phrase01Text": "Bonjour!", + "phrase02Text": "Bienvenue à ${APP_NAME}!", + "phrase03Text": "Voici quelques conseils pour contrôler votre personnage:", + "phrase04Text": "Beaucoup de choses sont basées sur la PHYSIQUE dans ${APP_NAME}.", + "phrase05Text": "Par exemple, quand vous frappez,..", + "phrase06Text": "..le dommage est basé sur la vitesse de vos poings.", + "phrase07Text": "Vous avez vu? Nous n'avons pas bougé et les dégâts ont été minuscule pour ${NAME}.", + "phrase08Text": "Maintenant nous allons sauter et tourner pour gagner plus de vitesse.", + "phrase09Text": "Voilà, c'est mieux.", + "phrase10Text": "Courir aide aussi.", + "phrase11Text": "Gardez N'IMPORTE quel bouton enfoncé pour courir.", + "phrase12Text": "Pour des coup de poings extraordinaires, essayez de courir ET tourner.", + "phrase13Text": "Oups; pardon ${NAME}.", + "phrase14Text": "Vous pouvez ramasser et jeter des choses comme des drapeaux... ou ${NAME}.", + "phrase15Text": "Enfin, il y a les bombes.", + "phrase16Text": "Lancer les bombes demande de la pratique.", + "phrase17Text": "Ouch! Mauvais lancé.", + "phrase18Text": "Bouger vous permet de lancer plus loin.", + "phrase19Text": "Sauter vous permet de lancer plus haut.", + "phrase20Text": "Donnez un \"Coup de fouet\" à vos bombes pour des lancés encore plus long.", + "phrase21Text": "Synchroniser vos bombes peut-être difficile.", + "phrase22Text": "Zut.", + "phrase23Text": "Essayez de \"garder au chaud\" les bombes pour réduire la mèche.", + "phrase24Text": "Hourra! Une bombe chaude, une !", + "phrase25Text": "Et bien, c'est à peu près tout.", + "phrase26Text": "Maintenant, terrassez vos ennemis!", + "phrase27Text": "Souvenez-vous de votre entraînement, et vous allez revenir en vie!", + "phrase28Text": "...bien, peut-être...", + "phrase29Text": "Bonne Chance!", + "randomName1Text": "Jean", + "randomName2Text": "Foux", + "randomName3Text": "David", + "randomName4Text": "Julie", + "randomName5Text": "Marie", + "skipConfirmText": "Vraiment passer le tutoriel? Appuyez pour confirmer.", + "skipVoteCountText": "${COUNT}/${TOTAL} votes pour passer", + "skippingText": "passage du tutoriel...", + "toSkipPressAnythingText": "(appuyez n'importe où pour passer le tutoriel)" + }, + "twoKillText": "DOUBLE MEURTRE!", + "unavailableText": "indisponible", + "unconfiguredControllerDetectedText": "Contrôleur non-configuré détecté:", + "unlockThisInTheStoreText": "Cela doit être débloqué dans le magasin.", + "unlockThisProfilesText": "Pour créer plus de ${NUM} profiles, vous avez besoin de:", + "unlockThisText": "Pour débloquer ceci, vous avez besoin:", + "unsupportedHardwareText": "Désolé, ce hardware n'est pas supporté par cette version du jeu.", + "upFirstText": "En premier:", + "upNextText": "Le jeu ${COUNT} sera:", + "updatingAccountText": "Mise à jour du compte...", + "upgradeText": "Mise à jour", + "upgradeToPlayText": "Débloquez \"${PRO}\" dans le magasin pour jouer ceci.", + "useDefaultText": "Utilisez le Défaut", + "usesExternalControllerText": "Ce jeu utilise un contrôleur externe pour l'input.", + "usingItunesText": "Utilisez Music App pour la bande-son...", + "usingItunesTurnRepeatAndShuffleOnText": "Vérifiez que 'Lecture Aléatoire'='ACTIF' et 'Reprise'='TOUT' dans iTunes.", + "v2AccountLinkingInfoText": "Pour lier des comptes V2, utilisez le bouton 'Gérer compte'.", + "validatingBetaText": "Validation de la beta...", + "validatingTestBuildText": "Validation de la Version Test...", + "victoryText": "Victoire!", + "voteDelayText": "Vous ne pouvez commencer un autre vote que dans ${NUMBER} secondes", + "voteInProgressText": "Un vote est déjà en cours.", + "votedAlreadyText": "Vous avez déjà voté", + "votesNeededText": "${NUMBER} Vote son requis", + "vsText": "vs.", + "waitingForHostText": "(en attente de ${HOST} pour continuer)", + "waitingForLocalPlayersText": "En attente de joueur en local...", + "waitingForPlayersText": "attente de connexion d'autres joueurs...", + "waitingInLineText": "En attente (la partie est pleine)...", + "watchAVideoText": "Regarder une vidéo", + "watchAnAdText": "Visionnez une Annonce", + "watchWindow": { + "deleteConfirmText": "Effacer \"${REPLAY}\"?", + "deleteReplayButtonText": "Effacer\nLa Reprise", + "myReplaysText": "Mes Reprises", + "noReplaySelectedErrorText": "Aucun Reprise Sélectionné", + "playbackSpeedText": "Vitesse de lecture: ${SPEED}", + "renameReplayButtonText": "Renommer\nLa Reprise", + "renameReplayText": "Renommer \"${REPLAY}\" à:", + "renameText": "Renommer", + "replayDeleteErrorText": "Impossible d'effacer la reprise.", + "replayNameText": "Nom de la Reprise", + "replayRenameErrorAlreadyExistsText": "Une reprise avec ce nom existe déjà.", + "replayRenameErrorInvalidName": "Impossible de renommer la reprise; nom invalide.", + "replayRenameErrorText": "Impossible de renommer la reprise.", + "sharedReplaysText": "Reprises Partagées", + "titleText": "Reprises", + "watchReplayButtonText": "Visionner\nLa Reprise" + }, + "waveText": "Vague", + "wellSureText": "Bien Sûr!", + "whatIsThisText": "C'est quoi ça?", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "En attente de connexion de wiimotes...", + "pressText": "Appuyez sur les boutons 1 et 2 simultanément.", + "pressText2": "Avec les nouveaux wiimotes avec Motion Plus, appuyez le bouton rouge 'sync' en arrière." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "listenText": "Écoute", + "macInstructionsText": "Vérifiez que votre Wii est éteinte et que le Bluetooth est\nactivé sur votre Mac, puis appuyez sur 'Écoute'. Le support\nWiimote peut-être un peu incertain, alors vous devrez (peut-\nêtre) essayer plusieurs fois avant d'avoir une connection.\n\nBluetooth doit supporter jusqu'à 7 appareils,\nmais ce n'est pas garanti.\n\nBombSquad supporte les Wiimotes originales, les Nunchuks,\net le Contrôleur Classique.\nLe nouvel Wii Remote Plus fonctionne\naussi mais sans attachements.", + "thanksText": "Merci à l'équipe DarwiinRemote pour\navoir rendu ceci possible.", + "titleText": "Configuration Wiimote" + }, + "winsPlayerText": "${NAME} a Gagné!", + "winsTeamText": "${NAME} a Gagné!", + "winsText": "${NAME} a Gagné!", + "workspaceSyncErrorText": "Erreur de synchronisation avec ${WORKSPACE}. Veuillez consulter les logs pour plus de détails.", + "workspaceSyncReuseText": "Impossible de se synchroniser avec ${WORKSPACE}. Réutilisez la version synchronisée précédente.", + "worldScoresUnavailableText": "Les scores mondial sont indisponibles.", + "worldsBestScoresText": "Meilleurs scores mondiaux", + "worldsBestTimesText": "Meilleurs temps mondiaux", + "xbox360ControllersWindow": { + "getDriverText": "Obtenez les pilotes", + "macInstructions2Text": "Pour utiliser les contrôleurs sans-fils, vous avez besoin du récepteur \nqui vient avec le 'Contrôleur Xbox 360 Sans-Fils pour Windows'.\nUn seul récepteur est suffisante pour jusqu'à 4 contrôleurs.\n\nImportant: les recepteurs 3e-Party ne fonctionneront pas avec\nce pilote; soyez sûr que votre récepteur a 'Microsoft' écrit,\npas 'Xbox 360'. Microsoft ne vend plus séparément, alors vous \ndevez acheter avec le ontrôleur ou cherchez sur eBay.\n\nSi vous avez trouvé ceci utile, considerez à contribuer au développeur\ndu pilote sur son site-web.", + "macInstructionsText": "Pour utiliser les contrôleurs Xbox 360, vous devez installer \nle pilote pour Mac qui est disponible au lien en-dessous. \nIl fonctionne avec les contrôleurs sans-fils et filaires.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Pour utiliser les contrôleurs filaires Xbox 360 avec BombSquad,\nbranchez simplement dans le port USB. Vous pouvez utiliser\nun hub USB pour connecter plusieurs contrôleurs.\n\nPour utilisez les contrôleurs sans-fils, vous devez avoir un récepteur, \ndisponible avec le \"Contrôleur Xbox 360 sans-fils pour Windows\"\npaquet ou vendre individuellement. Chaque récepteur se branche dans un port\nUSB et vous permet à connecter 4 contrôleurs sans-fils", + "titleText": "Utiliser les Contrôleurs Xbox 360 avec ${APP_NAME}:" + }, + "yesAllowText": "Oui, Autoriser!", + "yourBestScoresText": "Vos meilleurs scores", + "yourBestTimesText": "Vos meilleurs temps" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/german.json b/dist/ba_data/data/languages/german.json new file mode 100644 index 0000000..34bb04d --- /dev/null +++ b/dist/ba_data/data/languages/german.json @@ -0,0 +1,2026 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Der Konto Name darf kein Emoji oder andere spezielle Buchstaben enthalten.", + "accountProfileText": "Benutzerprofil", + "accountsText": "Konten", + "achievementProgressText": "Erfolge: ${COUNT} von ${TOTAL}", + "campaignProgressText": "Kampagnen Fortschritt [Schwer]: ${PROGRESS}", + "changeOncePerSeason": "Du kannst dies nur einmal pro Saison ändern.", + "changeOncePerSeasonError": "Du musst warten bis du das wieder in der nächsten Saison ändern kannst. (${NUM} Tage)", + "customName": "Benutzerdefinierter Name", + "googlePlayGamesAccountSwitchText": "Wenn Sie ein anderes Google-Konto verwenden möchten,\nVerwenden Sie die Google Play Games-App, um zu wechseln.", + "linkAccountsEnterCodeText": "Code eingeben", + "linkAccountsGenerateCodeText": "Code generieren", + "linkAccountsInfoText": "(Teile deine Erfolge über verschiedene Platformen)", + "linkAccountsInstructionsNewText": "Um zwei Konten zu verknüpfen muss ein Code auf dem ersten Gerät generiert\nund auf dem zweiten Gerät eingegeben werden.\nDaten von dem zweiten Konto werden dann zwischen beiden Geräten geteilt.\n(Daten vom ersten Konto gehen verloren!)\n\nDu kannst bis zu ${COUNT} Kontos verknüpfen.\n\nWICHTIG: Verknüpfe nur Kontos die dir gehören;\nWenn du deine Kontos mit denen deiner Freunde\nverknüpfst, kannst du nicht mit deinen Freunden gleichzeitig Online spielen.", + "linkAccountsInstructionsText": "Um zwei Accounts miteinander zu verknüpfen,generiere einen \nCode auf einem der Geräte und trage ihn auf dem anderen ein.\nFortschritt und Inventar werden kombiniert.\nDu kannst bis zu ${COUNT} Accounts miteinander verknüpfen.\n\nSei vorsichtig; das kann nicht rückgängig gemacht werden!", + "linkAccountsText": "Konten verknüpfen", + "linkedAccountsText": "Verknüpfte Konten:", + "manageAccountText": "Konto verwalten", + "nameChangeConfirm": "Möchtest du deinen Konto Namen in ${NAME} ändern?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Das wird deinen Koop-Fortschritt und deine\nHigh-Scores zurücksetzen (aber nicht deine Tickets).\nDies kann nicht rückgängig gemacht werden. Bist du sicher?", + "resetProgressConfirmText": "Das wird deinen Koop-Fortschritt, deine\nErfolge und deine lokalen High-Scores\nzurücksetzen (aber nicht deine Tickets). Dies kann\nnicht rückgängig gemacht werden. Bist du sicher?", + "resetProgressText": "Fortschritt zurücksetzen", + "setAccountName": "Konto Namen festlegen", + "setAccountNameDesc": "Wählen Sie den Namen aus, der für Ihr Konto angezeigt werden soll.\nSie können den Namen von einem Ihrer verlinkten\nKonten benutzen oder erstellen Sie einen einzigartigen benutzerdefinierten Name.", + "signInInfoText": "Melde dich an, um deinen Fortschritt in der Cloud zu speichern,\nTickets zu verdienen und an Turnieren teilzunehmen.", + "signInText": "Anmelden", + "signInWithDeviceInfoText": "(ein automatisches Konto, das du nur auf diesem Gerät benutzen kannst)", + "signInWithDeviceText": "Mit Gerät-Konto einloggen", + "signInWithGameCircleText": "Mit Game Circle einloggen", + "signInWithGooglePlayText": "Mit Google Play anmelden", + "signInWithTestAccountInfoText": "(veraltete Kontoart, benutze Geräte-Kontos)", + "signInWithTestAccountText": "Mit Testkonto einloggen", + "signInWithV2InfoText": "(Ein Account der auf allen Plattformen funktioniert)", + "signInWithV2Text": "Einloggen mit einem BombSquad Account", + "signOutText": "Abmelden", + "signingInText": "Anmelden...", + "signingOutText": "Abmelden...", + "testAccountWarningCardboardText": "Achtung: Du bist mit einen \"Testaccount\" angemeldet.\nDiese werden durch Google-Konten ersetzt, sobald\ndiese in Google Cardboard unterstützt werden.\n\nFürs erste wirst du alle Tickets im Spiel verdienen müssen.\n(Du bekommst aber dafür das BombSquad Pro Upgrade umsonst)", + "testAccountWarningOculusText": "Achtung: Du bist mit einen \"Testaccount\" angemeldet.\nDieser wird im Laufe diesen Jahres mit einem Oculus Account ersetzt. \nDadurch kann man Tickets kaufen und vieles mehr.\n\nFürs erste wirst du alle Tickets im Spiel verdienen müssen.\n(Du bekommst aber dafür das BombSquad Pro Upgrade umsonst)", + "testAccountWarningText": "Achtung: Du meldest dich mit einem \"Testaccount\" an.\nDieser Account ist an dieses Gerät gebunden und wird\nregelmäßig zurückgesetzt. (Also bitte gib dir nicht \nzuviel Mühe um etwas zu sammeln/freizuschalten)\n\nVerwende eine offizielle Version des Spiels, um einen \"echten\" \nAccount zu benutzen (Game-Center, Google Plus, etc.) \nDas erlaubt es dir auch, deinen Spielstand in der Cloud zu \nspeichern und auf einem anderen Gerät weiterzuspielen.", + "ticketsText": "Tickets: ${COUNT}", + "titleText": "Konto", + "unlinkAccountsInstructionsText": "Wähle ein Konto aus um die Verknüpfung zu trennen", + "unlinkAccountsText": "Kontos entknüpfen", + "unlinkLegacyV1AccountsText": "Heben Sie die Verknüpfung von Legacy-Konten (V1) auf", + "v2LinkInstructionsText": "Benutze diesen Link um einen Account zu erstellen oder dich einzuloggen.", + "viaAccount": "(über das Konto ${NAME})", + "youAreLoggedInAsText": "Du bist eingeloggt als:", + "youAreSignedInAsText": "Du bist angemeldet als:" + }, + "achievementChallengesText": "Herausforderungen", + "achievementText": "Erfolg", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Töte 3 Bösewichte mit TNT", + "descriptionComplete": "3 Bösewichte mit TNT getötet", + "descriptionFull": "Töte 3 Bösewichte mit TNT bei ${LEVEL}", + "descriptionFullComplete": "3 Bösewichte mit TNT bei ${LEVEL} getötet", + "name": "Bumm macht das Dynamit" + }, + "Boxer": { + "description": "Gewinne ohne Bomben zu nutzen", + "descriptionComplete": "Ohne Bomben zu nutzen gewonnen", + "descriptionFull": "Bestehe ${LEVEL} ohne Bomben zu nutzen", + "descriptionFullComplete": "${LEVEL} beendet ohne Bomben zu nutzen", + "name": "Boxer" + }, + "Dual Wielding": { + "descriptionFull": "Verbinde 2 Controller (Hardware oder App.)", + "descriptionFullComplete": "Verbinde 2 Controller (Hardware oder App.)", + "name": "Beidhändig" + }, + "Flawless Victory": { + "description": "Gewinne ohne getroffen zu werden", + "descriptionComplete": "Gewonnen ohne getroffen zu werden", + "descriptionFull": "Gewinne ${LEVEL} ohne getroffen zu werden", + "descriptionFullComplete": "${LEVEL} gewonnen ohne getroffen zu werden", + "name": "Tadelloser Sieg" + }, + "Free Loader": { + "descriptionFull": "Starte ein freies Spiel für alle (2+ Spieler)", + "descriptionFullComplete": "Starte ein freies Spiel für alle (2+ Spieler)", + "name": "Schnorrer" + }, + "Gold Miner": { + "description": "Töte 6 Bösewichte mit Landminen", + "descriptionComplete": "6 Bösewichte mit Landminen getötet", + "descriptionFull": "Töte 6 Bösewichte mit Landminen bei ${LEVEL}", + "descriptionFullComplete": "6 Bösewichte mit Landminen bei ${LEVEL} getötet", + "name": "Goldgräber" + }, + "Got the Moves": { + "description": "Gewinne ohne Schläge und Bomben", + "descriptionComplete": "Ohne Schläge und Bomben gewonnen", + "descriptionFull": "Gewinne ${LEVEL} ohne Schläge und Bomben", + "descriptionFullComplete": "${LEVEL} ohne Schläge und Bomben gewonnen", + "name": "Du hast es raus" + }, + "In Control": { + "descriptionFull": "Verbinde einen Controller (Hardware oder App.)", + "descriptionFullComplete": "Verbinde einen Controller. (Hardware oder App.)", + "name": "Am Steuer" + }, + "Last Stand God": { + "description": "Sammle 1000 Punkte", + "descriptionComplete": "1000 Punkte gesammelt", + "descriptionFull": "Sammle 1000 Punkte in ${LEVEL}", + "descriptionFullComplete": "1000 Punkte in ${LEVEL} erreicht", + "name": "${LEVEL} Gott" + }, + "Last Stand Master": { + "description": "Sammle 250 Punkte", + "descriptionComplete": "250 Punkte gesammelt", + "descriptionFull": "Sammle 250 Punkte in ${LEVEL}", + "descriptionFullComplete": "250 Punkte in ${LEVEL} gesammelt", + "name": "${LEVEL} Meister" + }, + "Last Stand Wizard": { + "description": "Sammle 500 Punkte", + "descriptionComplete": "500 Punkte gesammelt", + "descriptionFull": "Sammle 500 Punkte in ${LEVEL}", + "descriptionFullComplete": "500 Punkte in ${LEVEL} gesammelt", + "name": "${LEVEL} Magier" + }, + "Mine Games": { + "description": "Töte 3 Bösewichte mit Landminen", + "descriptionComplete": "3 Bösewichte mit Landminen getötet", + "descriptionFull": "Töte 3 Bösewichte mit Landminen bei ${LEVEL}", + "descriptionFullComplete": "3 Bösewichte mit Landminen bei ${LEVEL} getötet", + "name": "Minenspiele" + }, + "Off You Go Then": { + "description": "Wirf 3 Bösewichte vom Schlachtfeld", + "descriptionComplete": "3 Bösewichte vom Schlachtfeld geworfen", + "descriptionFull": "Wirf 3 Bösewichte vom Schlachtfeld bei ${LEVEL}", + "descriptionFullComplete": "3 Bösewichte vom Schlachtfeld geworfen bei ${LEVEL}", + "name": "Und raus bist du" + }, + "Onslaught God": { + "description": "Sammle 5000 Punkte", + "descriptionComplete": "5000 Punkte gesammelt", + "descriptionFull": "Sammle 5000 Punkte in ${LEVEL}", + "descriptionFullComplete": "5000 Punkte in ${LEVEL} gesammelt", + "name": "${LEVEL} Gott" + }, + "Onslaught Master": { + "description": "Sammle 500 Punkte", + "descriptionComplete": "500 Punkte gesammelt", + "descriptionFull": "Sammle 500 Punkte in ${LEVEL}", + "descriptionFullComplete": "500 Punkte in ${LEVEL} gesammelt", + "name": "${LEVEL} Meister" + }, + "Onslaught Training Victory": { + "description": "Vernichte alle Wellen", + "descriptionComplete": "Alle Wellen vernichtet", + "descriptionFull": "Vernichte alle Wellen bei ${LEVEL}", + "descriptionFullComplete": "Alle Wellen bei ${LEVEL} vernichtet", + "name": "${LEVEL} Sieg" + }, + "Onslaught Wizard": { + "description": "Sammle 1000 Punkte", + "descriptionComplete": "1000 Punkte gesammelt", + "descriptionFull": "Sammle 1000 Punkte in ${LEVEL}", + "descriptionFullComplete": "1000 Punkte in ${LEVEL} gesammelt", + "name": "${LEVEL} Magier" + }, + "Precision Bombing": { + "description": "Gewinne ohne Powerups", + "descriptionComplete": "Ohne Powerups gewonnen", + "descriptionFull": "Gewinne ${LEVEL} ohne Powerups", + "descriptionFullComplete": "${LEVEL} ohne Powerups gewonnen", + "name": "Präzisionsbomben" + }, + "Pro Boxer": { + "description": "Gewinne ohne Bomben zu nutzen", + "descriptionComplete": "Gewonnen ohne Bomben zu nutzen", + "descriptionFull": "Bestehe ${LEVEL} ohne Bomben zu nutzen", + "descriptionFullComplete": "${LEVEL} bestanden ohne Bomben zu nutzen", + "name": "Pro Boxer" + }, + "Pro Football Shutout": { + "description": "Gewinne ohne dass die Bösewichte punkten", + "descriptionComplete": "Gewonnen ohne dass die Bösewichte punkten", + "descriptionFull": "Gewinne ${LEVEL} ohne dass die Bösewichte punkten", + "descriptionFullComplete": "${LEVEL} gewonnen ohne dass die Bösewichte punkten", + "name": "${LEVEL} Shutout" + }, + "Pro Football Victory": { + "description": "Gewinne das Spiel", + "descriptionComplete": "Spiel gewonnen", + "descriptionFull": "Gewinne das Spiel in ${LEVEL}", + "descriptionFullComplete": "${LEVEL} Spiel gewonnen", + "name": "${LEVEL} Sieg" + }, + "Pro Onslaught Victory": { + "description": "Vernichte alle Wellen", + "descriptionComplete": "Alle Wellen vernichtet", + "descriptionFull": "Vernichte alle Wellen bei ${LEVEL}", + "descriptionFullComplete": "Alle Wellen bei ${LEVEL} vernichtet", + "name": "${LEVEL} Sieg" + }, + "Pro Runaround Victory": { + "description": "Überstehe alle Wellen", + "descriptionComplete": "Alle Wellen überstanden", + "descriptionFull": "Überstehe alle Wellen bei ${LEVEL}", + "descriptionFullComplete": "Alle Wellen bei ${LEVEL} überstanden", + "name": "${LEVEL} Sieg" + }, + "Rookie Football Shutout": { + "description": "Gewinne ohne dass die Bösewichte punkten", + "descriptionComplete": "Gewonnen ohne dass die Bösewichte punkten", + "descriptionFull": "Gewinne ${LEVEL} ohne dass die Bösewichte punkten", + "descriptionFullComplete": "${LEVEL} gewonnen ohne dass die Bösewichte punkten", + "name": "${LEVEL} Shutout" + }, + "Rookie Football Victory": { + "description": "Gewinne das Spiel", + "descriptionComplete": "Spiel gewonnen", + "descriptionFull": "Gewinne das ${LEVEL} Spiel", + "descriptionFullComplete": "${LEVEL} Spiel gewonnen", + "name": "${LEVEL} Sieg" + }, + "Rookie Onslaught Victory": { + "description": "Vernichte alle Wellen", + "descriptionComplete": "Alle Wellen vernichtet", + "descriptionFull": "Vernichte alle Wellen bei ${LEVEL}", + "descriptionFullComplete": "Alle Wellen bei ${LEVEL} vernichtet", + "name": "${LEVEL} Sieg" + }, + "Runaround God": { + "description": "Sammle 2000 Punkte", + "descriptionComplete": "2000 Punkte gesammelt", + "descriptionFull": "Sammle 2000 Punkte bei ${LEVEL}", + "descriptionFullComplete": "2000 Punkte bei ${LEVEL} gesammelt", + "name": "${LEVEL} Gott" + }, + "Runaround Master": { + "description": "Sammle 500 Punkte", + "descriptionComplete": "500 Punkte gesammelt", + "descriptionFull": "Sammle 500 Punkte bei ${LEVEL}", + "descriptionFullComplete": "500 Punkte bei ${LEVEL} gesammelt", + "name": "${LEVEL} Meister" + }, + "Runaround Wizard": { + "description": "Sammle 1000 Punkte", + "descriptionComplete": "1000 Punkte gesammelt", + "descriptionFull": "Erreiche 1000 Punkte bei ${LEVEL}", + "descriptionFullComplete": "1000 Punkte bei ${LEVEL} erreicht", + "name": "${LEVEL} Magier" + }, + "Sharing is Caring": { + "descriptionFull": "Teile das Spiel erfolgreich mit einem Freund", + "descriptionFullComplete": "Erfolgreich das Spiel mit einem Freund geteilt.", + "name": "Teilen ist freundlich" + }, + "Stayin' Alive": { + "description": "Gewinne ohne zu sterben", + "descriptionComplete": "Gewonnen ohne zu sterben", + "descriptionFull": "Gewinne ${LEVEL} ohne zu sterben", + "descriptionFullComplete": "${LEVEL} gewonnen ohne zu sterben", + "name": "Am Leben bleiben" + }, + "Super Mega Punch": { + "description": "Verursache 100% Schaden mit einem Schlag", + "descriptionComplete": "100% Schaden mit einem Schlag verursacht", + "descriptionFull": "Verursache 100% Schaden mit einem Schlag bei ${LEVEL}", + "descriptionFullComplete": "100% Schaden mit einem Schlag bei ${LEVEL} verursacht", + "name": "Super Mega Schlag" + }, + "Super Punch": { + "description": "Verursache 50% Schaden mit einem Schlag", + "descriptionComplete": "50% Schaden mit einem Schlag verursacht", + "descriptionFull": "Verursache 50% Schaden mit einem Schlag bei ${LEVEL}", + "descriptionFullComplete": "50% Schaden mit einem Schlag bei ${LEVEL} verursacht", + "name": "Super Schlag" + }, + "TNT Terror": { + "description": "Töte 6 Bösewichte mit TNT", + "descriptionComplete": "6 Bösewichte mit TNT getötet", + "descriptionFull": "Töte 6 Bösewichte mit TNT bei ${LEVEL}", + "descriptionFullComplete": "6 Bösewichte in ${LEVEL} mit TNT getötet", + "name": "TNT Terror" + }, + "Team Player": { + "descriptionFull": "Starte ein Team Spiel mit 4+ Spielern", + "descriptionFullComplete": "Ein Spiel mit 4+ Spielern gestartet.", + "name": "Team Spieler" + }, + "The Great Wall": { + "description": "Halte jeden einzelnen Bösewicht auf", + "descriptionComplete": "Jeden einzelnen Bösewicht aufgehalten", + "descriptionFull": "Halte jeden einzelnen Bösewicht in ${LEVEL} auf", + "descriptionFullComplete": "Jeden einzelnen Bösewicht in ${LEVEL} aufgehalten", + "name": "Die große Mauer" + }, + "The Wall": { + "description": "Halte jeden einzelnen Bösewicht auf", + "descriptionComplete": "Jeden einzelnen Bösewichte aufgehalten", + "descriptionFull": "Halte jeden einzelnen Bösewicht bei ${LEVEL} auf", + "descriptionFullComplete": "Jeden einzelnen Bösewicht bei ${LEVEL} aufgehalten", + "name": "Die Mauer" + }, + "Uber Football Shutout": { + "description": "Gewinne ohne dass die Bösewichte punkten", + "descriptionComplete": "Gewonnen ohne dass die Bösewichte punkten", + "descriptionFull": "Gewinne ${LEVEL} ohne dass die Bösewichte punkten", + "descriptionFullComplete": "${LEVEL} gewonnen ohne dass die Bösewichte punkten", + "name": "${LEVEL} Shutout" + }, + "Uber Football Victory": { + "description": "Gewinne das Spiel", + "descriptionComplete": "Spiel gewonnen", + "descriptionFull": "Gewinne das Spiel in ${LEVEL}", + "descriptionFullComplete": "Spiel gewonnen in ${LEVEL}", + "name": "${LEVEL} Sieg" + }, + "Uber Onslaught Victory": { + "description": "Vernichte alle Wellen", + "descriptionComplete": "Alle Wellen vernichtet", + "descriptionFull": "Vernichte alle Wellen in ${LEVEL}", + "descriptionFullComplete": "Alle Wellen in ${LEVEL} vernichtet", + "name": "${LEVEL} Sieg" + }, + "Uber Runaround Victory": { + "description": "Überstehe alle Wellen", + "descriptionComplete": "Alle Wellen überstanden", + "descriptionFull": "Überstehe alle Wellen in ${LEVEL}", + "descriptionFullComplete": "Alle Wellen in ${LEVEL} überstanden", + "name": "${LEVEL} Sieg" + } + }, + "achievementsRemainingText": "Fehlende Erfolge:", + "achievementsText": "Erfolge", + "achievementsUnavailableForOldSeasonsText": "Leider Leistung Besonderheiten nicht für alte Jahreszeiten zur Verfügung.", + "activatedText": "${THING} aktiviert.", + "addGameWindow": { + "getMoreGamesText": "Hol dir mehr Spiele...", + "titleText": "Spiel hinzufügen", + "titleTextScale": 1.0 + }, + "allowText": "Erlauben", + "alreadySignedInText": "Dein Account wird schon von einem anderen Gerät verwendet;\nbitte wechsle den Account oder schließe das Spiel auf\ndeinem anderen Gerät und versuche es nochmal.", + "apiVersionErrorText": "Das Modul ${NAME} kann nicht geladen werden. Es benutzt API-Version ${VERSION_USED}, aber wir brauchen ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" erlaubt das nur, wenn Kopfhörer angeschlossen sind)", + "headRelativeVRAudioText": "Kopf-Orientiertes VR Audio", + "musicVolumeText": "Musiklautstärke", + "soundVolumeText": "Soundlautstärke", + "soundtrackButtonText": "Musiktitel", + "soundtrackDescriptionText": "(Lasse deine eigene Musik während dem Spielen laufen)", + "titleText": "Audio" + }, + "autoText": "Automatisch", + "backText": "Zurück", + "banThisPlayerText": "Diesen Spieler verbannen", + "bestOfFinalText": "Bester-aus-${COUNT} Finale", + "bestOfSeriesText": "Bester-aus-${COUNT} Serie:", + "bestRankText": "Dein Rekord ist #${RANK}", + "bestRatingText": "Dein bestes Ergebnis ist ${RATING}", + "betaErrorText": "Diese Beta ist nicht mehr aktiv; bitte hole dir die neueste Version.", + "betaValidateErrorText": "Beta nicht verifizierbar. (keine Internetverbindung?)", + "betaValidatedText": "Beta verifiziert; Viel Spaß!", + "bombBoldText": "BOMBE", + "bombText": "Bombe", + "boostText": "Boost", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} ist in der App konfiguriert.", + "buttonText": "Taste", + "canWeDebugText": "Möchtest du, dass BombSquad automatisch Fehler, Abstürze\nund Benutzeraktivitäten an den Entwickler sendet?\n\nDiese Daten enthalten keinerlei persönliche Informationen\nund helfen, das Spiel reibungslos und fehlerfrei zu erhalten.", + "cancelText": "Abbrechen", + "cantConfigureDeviceText": "Entschuldigung, ${DEVICE} ist nicht konfigurierbar.", + "challengeEndedText": "Diese Herausforderung ist beendet.", + "chatMuteText": "Chat stummschalten", + "chatMutedText": "Chat stumm", + "chatUnMuteText": "Chat aktivieren", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Du musst dieses Level\nabschließen um fortzufahren!", + "completionBonusText": "Bewältigungsbonus", + "configControllersWindow": { + "configureControllersText": "Controller Einstellungen", + "configureGamepadsText": "Gamepads Konfigurieren", + "configureKeyboard2Text": "Tastatur konfigurieren P2", + "configureKeyboardText": "Tastatur konfigurieren", + "configureMobileText": "Mobilgeräte als Controller", + "configureTouchText": "Touchscreen konfigurieren", + "ps3Text": "PS3 Controller", + "titleText": "Controllers", + "wiimotesText": "Wiimotes", + "xbox360Text": "Xbox 360 Controller" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Info: Controller Unterstützung ist vom Gerät und der Android Version abhängig", + "pressAnyButtonText": "Drücke einen Knopf am Controller, um ihn zu konfigurieren...", + "titleText": "Controller konfigurieren" + }, + "configGamepadWindow": { + "advancedText": "Erweitert", + "advancedTitleText": "Erweiterte Controller Einstellungen", + "analogStickDeadZoneDescriptionText": "(Erhöhen, wenn dein Charakter beim Loslassen des Sticks abtreibt)", + "analogStickDeadZoneText": "Analog Stick Dead Zone", + "appliesToAllText": "(wird auf alle Controller dieses Typs angewendet)", + "autoRecalibrateDescriptionText": "(aktivieren, falls dein Charakter sich nicht in voller Geschwindigkeit bewegt)", + "autoRecalibrateDescriptionTextScale": 0.4, + "autoRecalibrateText": "Automatisches Kalibrieren des Analog Sticks", + "autoRecalibrateTextScale": 0.65, + "axisText": "Achsen", + "clearText": "Löschen", + "dpadText": "Steuerkreuz", + "extraStartButtonText": "Extra Start Button", + "ifNothingHappensTryAnalogText": "Wenn nichts passiert, versuche den Analog Stick zuzuweisen.", + "ifNothingHappensTryDpadText": "Wenn nichts passiert, versuche das Steuerkreuz zuzuweisen.", + "ignoreCompletelyDescriptionText": "(verhindere, dass dieser Controller das Spiel oder Menüs beeinflusst)", + "ignoreCompletelyText": "Komplett ignorieren", + "ignoredButton1Text": "Ignorierte Taste 1", + "ignoredButton2Text": "Ignorierte Taste 2", + "ignoredButton3Text": "Ignorierte Taste 3", + "ignoredButton4Text": "Ignorierte Taste 4", + "ignoredButtonDescriptionText": "(Benutze das, damit die \"Home\" oder \"Sync\" Tasten nicht ausversehen das Spiel beeinflussen)", + "ignoredButtonDescriptionTextScale": 0.4, + "ignoredButtonText": "Ignorierter Button", + "pressAnyAnalogTriggerText": "Drücke einen beliebigen Analogknopf...", + "pressAnyButtonOrDpadText": "Drücke einen beliebigen Button oder Steuerkreuz...", + "pressAnyButtonText": "Drücke eine beliebige Taste...", + "pressLeftRightText": "Drücke links oder rechts...", + "pressUpDownText": "Drücke hoch oder runter...", + "runButton1Text": "Renntaste 1", + "runButton2Text": "Renntaste 2", + "runTrigger1Text": "Rennauslöser 1", + "runTrigger2Text": "Rennauslöser 2", + "runTriggerDescriptionText": "(Analoge Auslöser für unterschiedliche Laufgeschwindigkeiten)", + "secondHalfText": "Benutze das, um die zweite Seite\neines 2-Controllers-in-1 Gerätes einzustellen\ndass als ein einzelner Controller angezeigt wird.", + "secondaryEnableText": "Aktivieren", + "secondaryText": "Zweiter Controller", + "startButtonActivatesDefaultDescriptionText": "Deaktivieren, wenn dein Startbutton eher ein Menübutton ist", + "startButtonActivatesDefaultText": "Starttaste aktiviert Standard-Widget", + "startButtonActivatesDefaultTextScale": 0.65, + "titleText": "Controllereinstellungen", + "twoInOneSetupText": "2-in-1 Controllereinstellungen", + "uiOnlyDescriptionText": "Verhindere, dass dieser Controller dem Spiel beitritt.", + "uiOnlyText": "Nur das Menü bedienen lassen", + "unassignedButtonsRunText": "Alle unbelegten Tasten zum Rennen", + "unassignedButtonsRunTextScale": 0.8, + "unsetText": "", + "vrReorientButtonText": "VR Neu Ausrichten Taste" + }, + "configKeyboardWindow": { + "configuringText": "${DEVICE} Konfigurieren", + "keyboard2NoteScale": 0.7, + "keyboard2NoteText": "Notiz: Die meisten Tastaturen können nur wenige Tastendrücke\ngleichzeitig registrieren, deshalb funktioniert es möglicherweise\nbesser, wenn der zweite Tastaturspieler eine separate Tastatur\nbenutzt. Beachte, dass du trotzem verschiedene Tasten für die\neinzelnen Spieler belegen musst." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Größe der Aktionstasten", + "actionsText": "Aktionen", + "buttonsText": "Tasten", + "dragControlsText": "< ziehe die Steuerungen, um sie neu zu positionieren >", + "joystickText": "Joystick", + "movementControlScaleText": "Steuerkreuzgröße", + "movementText": "Bewegung", + "resetText": "Reset", + "swipeControlsHiddenText": "Steuerkreuz ausblenden", + "swipeInfoText": "'Wisch'-Steuerung braucht etwas Eingewöhnungszeit, macht\nes aber leichter zu spielen, ohne auf die Steuerung zu sehen.", + "swipeText": "wischen", + "titleText": "Touchscreen einstellen", + "touchControlsScaleText": "Touch Steuerung Skalierung" + }, + "configureItNowText": "Konfiguriere es jetzt?", + "configureText": "Konfigurieren", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsScale": 0.65, + "bestResultsText": "Um das beste Ergebnis zu erzielen, benötigst du ein verzögerungsfreies\nWlan Netzwerk. Du kannst die Verzögerung reduzieren, indem du\nandere drahtlose Geräte abschaltest, näher am WLan-Rounter spielst\nund indem du dich direkt per Ethernet mit dem Spiele-Host verbindest.", + "explanationScale": 0.8, + "explanationText": "Um ein Smartphone oder Tablet als kabellosen Controller zu nutzen,\nmuss die \"${REMOTE_APP_NAME}\"-App installiert werden. Jegliche Anzahl an Geräten\nkönnen sich mit ${APP_NAME} per WLAN verbinden, und es ist kostenlos!", + "forAndroidText": "für Android:", + "forIOSText": "für iOS:", + "getItForText": "Hol dir ${REMOTE_APP_NAME} für iOS im Apple App Store,\noder für Android im Google Play Store oder Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Mobilgeräte als Controller nutzen:" + }, + "continuePurchaseText": "Für ${PRICE} fortfahren?", + "continueText": "Fortfahren", + "controlsText": "Steuerung", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Das ändert nichts an der dauerhaften Rangliste.", + "activenessInfoText": "Der Multiplikator steigt, wenn du viel spielst...\nWenn du weniger spielst sinkt er wieder", + "activityText": "Aktivität", + "campaignText": "Kampagne", + "challengesInfoText": "Gewinne Preise für das Beenden von Mini-Spielen.\n\nPreise und Schwierigkeitsgrade steigen mit jeder\nbeendeten Herausforderung und fallen, wenn\nHerausforderungen ablaufen oder aufgegeben werden.", + "challengesText": "Herausforderungen", + "currentBestText": "Aktueller Highscore", + "customText": "Benutzerdefiniert", + "entryFeeText": "Einsatz", + "forfeitConfirmText": "Diese Herausforderung aufgeben?", + "forfeitNotAllowedYetText": "Diese Herausforderung kann noch nicht aufgegeben werden.", + "forfeitText": "Aufgeben", + "multipliersText": "Multiplikatoren", + "nextChallengeText": "Nächste Herausforderung", + "nextPlayText": "Nächstes Spiel", + "ofTotalTimeText": "Von ${TOTAL}", + "playNowText": "Jetzt spielen", + "pointsText": "Punkte", + "powerRankingFinishedSeasonUnrankedText": "(Beendete Saison nicht plaziert)", + "powerRankingNotInTopText": "(Nicht in der top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} Pkt", + "powerRankingPointsMultText": "(x ${NUMBER} Pkt)", + "powerRankingPointsText": "${NUMBER} pkte", + "powerRankingPointsToRankedText": "(${CURRENT} von ${REMAINING} pkte)", + "powerRankingText": "Power Rang", + "prizesText": "Preise", + "proMultInfoText": "Spieler mit dem ${PRO} Upgrade\nbekommen zu ${PERCENT}% mehr Punkte hier.", + "seeMoreText": "Sieh weitere...", + "skipWaitText": "Überspringen", + "timeRemainingText": "Übrige Zeit", + "titleText": "Koop", + "toRankedText": "Bis zu den Rängen", + "totalText": "Gesamt", + "tournamentInfoText": "Trete gegen andere Spieler in deiner Liga an\nund ringe mit ihnen um die High-Scores.\n\nNach Ablauf der Turnierzeit werden die Preise \nan die Spieler mit den höchsten Punkten verliehen.", + "welcome1Text": "Wilkommen zur ${LIGA}.Du kannst einen Liga-rang\n ereichen, indem du Sterne bei deiner Bewertung \nkriegst,achivements erfüllstoder indem du Trophähen\n bei Tournamenten gewinnst.", + "welcome2Text": "Sie können auch Tickets zu verdienen aus viele der Aktivitäten.\nKarten können verwendet werden, um neue Charaktere, Karten freizuschalten , und\nMini-Spiele , Turniere und mehr geben .", + "yourPowerRankingText": "Dein Power Rang:" + }, + "copyConfirmText": "In die Zwischenablage kopiert.", + "copyOfText": "${NAME} Kopieren", + "copyText": "Kopieren", + "copyrightText": "© 2013 Eric Froemling", + "createAPlayerProfileText": "Erstelle ein Spielerprofil?", + "createEditPlayerText": "", + "createText": "Erstellen", + "creditsWindow": { + "additionalAudioArtIdeasText": "Zusätzlicher Ton, frühes Artwork und Ideen von ${NAME}", + "additionalMusicFromText": "Zusätzliche Musik von ${NAME}", + "allMyFamilyText": "All meine Freunde und meine Familie, die mir beim Testspielen halfen", + "codingGraphicsAudioText": "Programmierung, Grafiken und Ton von ${NAME}", + "creditsText": " Coding, Graphics, and Audio by Eric Froemling\n \n Additional Audio, Early Artwork, and Ideas by Raphael Suter\n \n Sound & Music:\n\n${SOUND_AND_MUSIC}\n\n Public-domain music via Musopen.com (a great site for classical music)\n Thanks especially to the US Army, Navy, and Marine Bands.\n\n Big thanks to the following freesound.org contributors for use of their sounds:\n${FREESOUND_NAMES}\n\n Special Thanks:\n\n Todd, Laura, and Robert Froemling\n All of my friends and family who helped play test\n Whoever invented coffee\n\n Legal:\n\n${LEGAL_STUFF}\n\n www.froemling.net", + "languageTranslationsText": "Sprachübersetzung:", + "legalText": "Rechtlich:", + "publicDomainMusicViaText": "Public-domain Musik durch ${NAME}", + "softwareBasedOnText": "Diese Software basiert teilweise auf der Arbeit von ${NAME}", + "songCreditText": "${TITLE} aufgeführt von ${PERFORMER}\nkomponiert von ${COMPOSER}, arrangiert von ${ARRANGER}, Veröffentlicht von ${PUBLISHER},\nmit großzügiger Erlaubnis von ${SOURCE}", + "soundAndMusicText": "Ton & Musik:", + "soundsText": "Sounds (${SOURCE}):", + "specialThanksText": "Besonderen Dank:", + "thanksEspeciallyToText": "Speziellen Dank an ${NAME}", + "titleText": "${APP_NAME} Credits", + "whoeverInventedCoffeeText": "Wer auch immer Kaffee erfunden hat" + }, + "currentStandingText": "Dein derzeitiger Rang ist #${RANK}", + "customizeText": "Anpassen...", + "deathsTallyText": "${COUNT} Tode", + "deathsText": "Tode", + "debugText": "Fehler beseitigen", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Für den Test wird empfohlen, Einstellungen->Grafik->Texturen auf \"Hoch\" zu stellen", + "runCPUBenchmarkText": "CPU Benchmark starten", + "runGPUBenchmarkText": "GPU Benchmark starten", + "runMediaReloadBenchmarkText": "Media-Reload Benchmark starten", + "runStressTestText": "Starte Leistungstest", + "stressTestPlayerCountText": "Spielerzahl", + "stressTestPlaylistDescriptionText": "Stresstest Playlist", + "stressTestPlaylistNameText": "Name der Playlist", + "stressTestPlaylistTypeText": "Art der Playlist", + "stressTestRoundDurationText": "Rundendauer", + "stressTestTitleText": "Stresstest", + "titleText": "Benchmarks & Stress Tests", + "totalReloadTimeText": "Gesamt Nachladezeit : ${TIME} (siehe Protokoll für Details )", + "unlockCoopText": "Schalte Koop-Levels frei" + }, + "defaultFreeForAllGameListNameText": "Standard Jeder gegen Jeden Spiele", + "defaultGameListNameText": "Standard ${PLAYMODE} Playlist", + "defaultNewFreeForAllGameListNameText": "Meine Jeder gegen Jeden Spiele", + "defaultNewGameListNameText": "Meine ${PLAYMODE} Playlist", + "defaultNewTeamGameListNameText": "Meine Teamspiele", + "defaultTeamGameListNameText": "Standard Teamspiele", + "deleteText": "Löschen", + "demoText": "Demo", + "denyText": "Verweigern", + "deprecatedText": "Veraltet", + "desktopResText": "Desktop Auflösung", + "deviceAccountUpgradeText": "Achtung:\nDu bist mit einem Gerät-Konto angemeldet (${NAME}).\nGerät-Konten werden in einem kommendem Update entfernt.\nVerbessere zu einem V2 Konto, wenn du deinen Fortschritt behalten willst.", + "difficultyEasyText": "Leicht", + "difficultyHardOnlyText": "Nur auf Schwer", + "difficultyHardText": "Schwer", + "difficultyHardUnlockOnlyText": "Dieser Level kann nur auf Schwer freigeschaltet werden.\nDenkst du, du könntest es schaffen!?!?!", + "directBrowserToURLText": "Bitte navigieren Sie einen Web-Browser auf die folgende URL:", + "disableRemoteAppConnectionsText": "Remote-App Verbindungen verbieten", + "disableXInputDescriptionText": "Erlaubt mehr als 4 Controller aber kann schlechter funktionieren.", + "disableXInputText": "XInput deaktivieren", + "doneText": "Fertig", + "drawText": "Unentschieden", + "duplicateText": "dublizieren", + "editGameListWindow": { + "addGameText": "Spiel\nhinzufügen", + "cantOverwriteDefaultText": "Standard Liste kann nicht überschrieben werden!", + "cantSaveAlreadyExistsText": "Eine Liste mit diesem Namen existiert bereits!", + "cantSaveEmptyListText": "Leere Liste kann nicht gespeichert werden!", + "editGameText": "Spiel\nbearbeiten", + "gameListText": "Spielliste", + "listNameText": "Listenname", + "nameText": "Name", + "removeGameText": "Spiel\nentfernen", + "saveText": "Liste Speichern", + "titleText": "Playlist Editor" + }, + "editProfileWindow": { + "accountProfileInfoText": "Diese spezielles Spielerprofil mit Namen und Symbol\nbezieht sich auf dein Konto mit dem du momentan eingeloggt bist.\n\n${ICONS}\n\nErstelle ein Benutzerprofil wenn du andere\nNamen und Symbole benutzen willst.", + "accountProfileText": "Profilkonto", + "availableText": "Der Name \"${NAME}\" ist verfügbar.", + "changesNotAffectText": "Hinweis: Änderungen wirken sich nicht auf Charaktere aus, die schon im Spiel sind", + "characterText": "Charakter", + "checkingAvailabilityText": "Prüfe Verfügbarkeit von \"${NAME}\"...", + "colorText": "Farbe", + "getMoreCharactersText": "Mehr Charaktere...", + "getMoreIconsText": "Bekomme mehr Symbole...", + "globalProfileInfoText": "Globale Spielerprofile haben garantiert einzigartige\nNamen weweltweit. Sie beinhalten auch eigene Benutzersymbole.", + "globalProfileText": "Globales Profil", + "highlightText": "Hervorhebung", + "iconText": "Symbol", + "localProfileInfoText": "Lokale Spielerprofile haben keine Symbole und die Namen haben keine Garantie\neinzigartig zu sein. Aktualisiere zu einem globalen Profil um einen\neinzigartigen Namen zu bekommen und ein Benutzersymbol hinzuzufügen.", + "localProfileText": "Lokales Profil", + "nameDescriptionText": "Spielername", + "nameText": "Name", + "randomText": "zufällig", + "titleEditText": "Profil bearbeiten", + "titleNewText": "Neues Profil", + "unavailableText": "\"${NAME}\" ist nicht verfügbar; versuche einen anderen Namen.", + "upgradeProfileInfoText": "Reserviert ihren Spielernamen weltweit und\nerlaubt ihnen das Hinzufügen eines Symbols.", + "upgradeToGlobalProfileText": "Aktualisiere zu einem globalen Profil" + }, + "editProfilesAnyTimeText": "(du kannst das Profil unter \"Einstellungen\" jederzeit ändern)", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Du kannst den Standard-Soundtrack nicht löschen.", + "cantEditDefaultText": "Standard Soundtrack kann nicht geändert werden. Dupliziere ihn oder erstelle einen neuen.", + "cantEditWhileConnectedOrInReplayText": "Soundtracks können während einer Party oder einem Replay bearbeitet werden.", + "cantOverwriteDefaultText": "Der Standard-Soundtrack kann nicht überschrieben werden", + "cantSaveAlreadyExistsText": "Ein Soundtrack mit diesem Namen existiert bereits!", + "copyText": "Kopieren", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Standard Musiktitel", + "deleteConfirmText": "Lösche Musiktitel:\n\n'${NAME}'?", + "deleteText": "Musiktitel\nlöschen", + "duplicateText": "Musiktitel\nduplizieren", + "editSoundtrackText": "Musiktitel Editor", + "editText": "Musiktitel\nändern", + "fetchingITunesText": "übertrage Musik-App Playlisten...", + "musicVolumeZeroWarning": "Achtung: Musiklautstärke ist auf 0 gesetzt", + "nameText": "Name", + "newSoundtrackNameText": "Mein Musiktitel ${COUNT}", + "newSoundtrackText": "Neuer Musiktitel", + "newText": "Neuer\nMusiktitel", + "selectAPlaylistText": "Wähle eine Playlist aus", + "selectASourceText": "Musikquelle", + "soundtrackText": "SoundTrack", + "testText": "Test", + "titleText": "Musiktitel", + "useDefaultGameMusicText": "Voreingestellte Spielemusik", + "useITunesPlaylistText": "Musik-App Playlist", + "useMusicFileText": "Musikdatei (mp3, usw.)", + "useMusicFolderText": "Ordner mit Musikdateien" + }, + "editText": "bearbeiten", + "endText": "Ende", + "enjoyText": "Viel Spaß!", + "epicDescriptionFilterText": "${DESCRIPTION} In epischer Zeitlupe.", + "epicNameFilterText": "Episch ${NAME}", + "errorAccessDeniedText": "Zugriff verweigert", + "errorDeviceTimeIncorrectText": "Die Zeit deines Gerätes ist um ${HOURS} Stunden verschoben.\nDas kann Probleme verursachen.\nBitte überprüfe deine Zeit und Zeit-Zonen Einstellungen.", + "errorOutOfDiskSpaceText": "Nicht genug Speicherplatz", + "errorSecureConnectionFailText": "Nicht möglich, eine sichere Cloud-Verbindung herzustellen; Netzwerk funktionalität kann versagen.", + "errorText": "Fehler", + "errorUnknownText": "unbekannter Fehler", + "exitGameText": "${APP_NAME} verlassen?", + "exportSuccessText": "'${NAME}' exportiert.", + "externalStorageText": "externer Datenspeicher", + "failText": "Fehlgeschlagen", + "fatalErrorText": "Oh oh; Etwas fehlt oder ist beschädigt.\nVersuche das Spiel neu zu installieren\noder kontaktiere ${EMAIL} für Hilfe.", + "fileSelectorWindow": { + "titleFileFolderText": "Wähle Datei oder Ordner aus", + "titleFileText": "Wähle Datei", + "titleFolderText": "Wähle Ordner", + "useThisFolderButtonText": "Nutze diesen Ordner" + }, + "filterText": "Filter", + "finalScoreText": "Gesamtergebnis", + "finalScoresText": "Gesamtergebnisse", + "finalTimeText": "Gesamtzeit", + "finishingInstallText": "Installation wird beendet; einen moment...", + "fireTVRemoteWarningText": "* Für ein besseres Spielerlebnis benutze\nbitte Controller oder lade die\n'${REMOTE_APP_NAME}' App auf dein\nHandy oder Tablet.", + "firstToFinalText": "Erster-aus-${COUNT} Finale", + "firstToSeriesText": "Erster-aus-${COUNT} Serie", + "fiveKillText": "MONSTER KILL!!!", + "flawlessWaveText": "Tadellose Welle!", + "fourKillText": "QUAD KILL!!!", + "freeForAllText": "Jeder gegen Jeden", + "friendScoresUnavailableText": "Ergebnisse des Freundes nicht verfügbar.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Spiel ${COUNT} Führer", + "gameListWindow": { + "cantDeleteDefaultText": "Standard-Playlist kann nicht gelöscht\nwerden!", + "cantEditDefaultText": "Standard Playlist kann nicht geändert\nwerden! Dupliziere sie, oder erstelle\neine Neue.", + "cantShareDefaultText": "Die Standartplaylist kann nicht geteilt werden.", + "deleteConfirmText": "Lösche \"${LIST}\"?", + "deleteText": "Playlist löschen", + "duplicateText": "Playlist\nduplizieren", + "editText": "Playlist\nbearbeiten", + "gameListText": "Spieleliste", + "newText": "Neue\nPlaylist", + "showTutorialText": "Tutorial anzeigen", + "shuffleGameOrderText": "Zufällige Spielreihenfolge", + "titleText": "${TYPE}-Playlists bearbeiten" + }, + "gameSettingsWindow": { + "addGameText": "Spiel hinzufügen" + }, + "gamepadDetectedText": "1 Gamepad gefunden.", + "gamepadsDetectedText": "${COUNT} Gamepads gefunden.", + "gamesToText": "${WINCOUNT} Siege zu ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Vergiss nicht: Jedes Gerät in einer Party kann mehr als\neinen Spieler haben, wenn du genug Controller hast.", + "aboutDescriptionText": "Benutze diese Tabs, um eine Party zu erstellen.\n\nIn Partys kannst du Spiele und Turniere\nmit deinen Freunden über verschiedene Geräte spielen.\n\nBenutze den ${PARTY} Button oben rechts um\nmit deiner Party zu interagieren oder zu chatten.\n(Im Menü ${BUTTON} auf einem Controller drücken)", + "aboutText": "Über", + "addressFetchErrorText": "", + "appInviteInfoText": "Lade Freunde ein, BombSquad auszuprobieren und sie \nbekommen kostenlos ${COUNT} Tickets. Du bekommst\n${YOU_COUNT} für jeden Freund der dies tut.", + "appInviteMessageText": "${NAME} sendet dir ${COUNT} Tickets in\n${APP_NAME}", + "appInviteSendACodeText": "Ihnen ein Code senden", + "appInviteTitleText": "Einladung zu ${APP_NAME}", + "bluetoothAndroidSupportText": "(Funktioniert auf jedem Android-Gerät das Bluetooth unterstützt)", + "bluetoothDescriptionText": "Erstelle oder tritt einer Party über Bluetooth bei:", + "bluetoothHostText": "Über Bluetooth erstellen", + "bluetoothJoinText": "Über Bluetooth beitreten", + "bluetoothText": "Bluetooth", + "checkingText": "überprüfe...", + "copyCodeConfirmText": "Veranstalten Sie eine private Party", + "copyCodeText": "Code kopieren", + "dedicatedServerInfoText": "Das beste Ergebnis wird mit einem dedizierten Server erreicht. Auf bombsquadgame.com/server steht wie es geht.", + "disconnectClientsText": "Dadurch werden die ${COUNT} Spieler in Ihrer\nParty getrennt. Sind Sie sicher ?", + "earnTicketsForRecommendingAmountText": "Freunde bekommen ${COUNT} Tickets, wenn sie das Spiel ausprobieren.\n(Du bekommst ${YOU_COUNT} für jeden, der es tut.)", + "earnTicketsForRecommendingText": "Empfehle das Spiel an Freunde \nund ihr bekommt beide Tickets.", + "emailItText": "E-Mail an ihn", + "favoritesSaveText": "Als Favorit speichern", + "favoritesText": "Favoriten", + "freeCloudServerAvailableMinutesText": "Nächster kostenloser Cloud-Server in ${MINUTES} Minuten verfügbar.", + "freeCloudServerAvailableNowText": "Kostenloser Cloud-Server verfügbar!", + "freeCloudServerNotAvailableText": "Keine kostenlosen Cloud-Server verfügbar.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} Tickets von ${NAME}", + "friendPromoCodeAwardText": "Du bekommst ${COUNT} Tickets bei jeder Verwendung.", + "friendPromoCodeExpireText": "Der Code wird in ${EXPIRE_HOURS} Stunden ungültig und funktioniert nur für neue Spieler.", + "friendPromoCodeInfoText": "Kann für ${COUNT} Tickets eingelöst werden.\n\nGehe zu \"Einstellungen -> Erweitert -> Gutscheincode eingeben\" im Spiel um den Code einzulösen.\nBesuche bombsquadgame.com um das Spiel für alle unterstützten Platformen herunterzuladen.\nDieser Code wird in ${EXPIRE_HOURS} Stunden ungültig und kann nur von neuen Spielern eingelöst werden.", + "friendPromoCodeInstructionsText": "Um ihn einzulösen, öffne ${APP_NAME} und gehe zu \"Einstellungen->Erweitert->Gutscheincode eingeben\".\nAuf bombsquadgame.com findest du Links zum Download für alle unterstützten Plattformen.", + "friendPromoCodeRedeemLongText": "Er kann für ${COUNT} kostenlose Tickets von bis zu ${MAX_USES} Personen eingelöst werden.", + "friendPromoCodeRedeemShortText": "Es kann im Spiel für ${COUNT} eingelöst werden.", + "friendPromoCodeWhereToEnterText": "(in \"Einstellungen->Erweitert->Gutscheincode eingeben\")", + "getFriendInviteCodeText": "Bekomme einen Einladungscode für Freunde", + "googlePlayDescriptionText": "Lade Google Play Freunde zu deiner Party ein:", + "googlePlayInviteText": "Einladen", + "googlePlayReInviteText": "Es sind ${COUNT} Google Play Spieler in deiner Party,\ndie getrennt werden, wenn du neue Spieler einlädst.\nFüge sie deiner neuen Einladung hinzu, um sie wiederzubekommen.", + "googlePlaySeeInvitesText": "Einladungen anzeigen", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play Version)", + "hostPublicPartyDescriptionText": "Veranstalten Sie eine öffentliche Party", + "hostingUnavailableText": "Hosting nicht verfügbar", + "inDevelopmentWarningText": "Achtung:\n\nDer Online-Modus ist ein neues Feature, das noch in\nder Entwicklung ist. Zurzeit wird es dringend empfohlen,\ndass alle Spieler im selben Netzwerk sind.", + "internetText": "Internet", + "inviteAFriendText": "Deine Freunde haben dieses Spiel noch nicht?\nLade sie ein und sie erhalten ${COUNT} gratis Tickets.", + "inviteFriendsText": "Lade Freunde ein", + "joinPublicPartyDescriptionText": "Treten Sie einer öffentlichen Party bei", + "localNetworkDescriptionText": "Nehmen Sie an einer Party in der Nähe teil (LAN, Bluetooth usw.)", + "localNetworkText": "Lokales Netzwerk", + "makePartyPrivateText": "Stelle die Party privat", + "makePartyPublicText": "Stelle die Party öffentlich", + "manualAddressText": "Adresse", + "manualConnectText": "Verbinden", + "manualDescriptionText": "Einer Party per Adresse beitreten:", + "manualJoinSectionText": "Per Adresse beitreten", + "manualJoinableFromInternetText": "Bist du über das Internet zu erreichen?:", + "manualJoinableNoWithAsteriskText": "NEIN*", + "manualJoinableYesText": "JA", + "manualRouterForwardingText": "*um das zu beheben, versuche in deinem Router den UDP Port ${PORT} für deine Lokale Adresse freizugeben", + "manualText": "Manuell", + "manualYourAddressFromInternetText": "Deine Adresse über das Internet:", + "manualYourLocalAddressText": "Deine Lokale Adresse", + "nearbyText": "In der Nähe", + "noConnectionText": "", + "otherVersionsText": "(andere Versionen)", + "partyCodeText": "Party Code", + "partyInviteAcceptText": "Akzeptieren", + "partyInviteDeclineText": "Ablehnen", + "partyInviteGooglePlayExtraText": "(Schaue beim 'Google Play' Tab im 'Versammeln' Fenster)", + "partyInviteIgnoreText": "Ignorieren", + "partyInviteText": "${NAME} hat dich eingeladen\nseiner Party beizutreten!", + "partyNameText": "Party Name", + "partyServerRunningText": "Ihr Partyserver wird ausgeführt.", + "partySizeText": "Gruppengröße", + "partyStatusCheckingText": "Status wird überprüft...", + "partyStatusJoinableText": "Man kann deiner Party jetzt aus dem Internet beitreten", + "partyStatusNoConnectionText": "keine Verbindung zum Server möglich", + "partyStatusNotJoinableText": "Man kann deiner Party nicht mehr aus dem Internet beitreten", + "partyStatusNotPublicText": "Deine Party ist nicht public", + "pingText": "Ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Private Partys werden auf dedizierten Cloud-Servern ausgeführt. Keine Routerkonfiguration erforderlich.", + "privatePartyHostText": "Veranstalten Sie eine private Party", + "privatePartyJoinText": "Treten Sie einer privaten Party bei", + "privateText": "Privat", + "publicHostRouterConfigText": "Dies erfordert möglicherweise die Konfiguration der Portweiterleitung auf Ihrem Router. Veranstalten Sie für eine einfachere Option eine private Party.", + "publicText": "Öffentlich", + "requestingAPromoCodeText": "Gutscheincode anfordern...", + "sendDirectInvitesText": "Einladungen direkt versenden", + "sendThisToAFriendText": "Sende diesen Code einem Freund:", + "shareThisCodeWithFriendsText": "Teile diesen Code mit Freunden:", + "showMyAddressText": "Meine Adresse anzeigen", + "startHostingPaidText": "Jetzt für ${COST} hosten", + "startHostingText": "Gastgeber", + "startStopHostingMinutesText": "Sie können das Hosting für die nächsten ${MINUTES} Minuten kostenlos starten und beenden.", + "stopHostingText": "Beenden Sie das Hosting", + "titleText": "Versammeln", + "wifiDirectDescriptionBottomText": "Wenn alle Geräte ein 'Wi-Fi Direktfeld' haben, sollten sie in der Lage sein, sich\ngegenseitig zu finden und zu verbinden. Sind alle Geräte miteinander verbunden, kannst\ndu in dem Tab 'Lokales Netzwerk' genauso wie in einem normalen Wi-Fi Netzwerk Partys erstellen.\n\nUm Probleme zu vermeiden, sollte der Wi-Fi Direct host auch der ${APP_NAME} Party host sein.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct kann genutzt werden, um Android-Geräte direkt miteinander\nzu Verbinden, ohne ein Wi-Fi Netzwerk zu benötigen. Das funktioniert am\nbesten auf Android 4.2 oder neuer.\n\nUm es zu benutzen, öffne die Wi-Fi Einstellungen und aktiviere 'Wi-Fi Direct' im Menü.", + "wifiDirectOpenWiFiSettingsText": "Wi-Fi Einstellungen öffnen", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(Funktioniert zwischen allen Plattformen)", + "worksWithGooglePlayDevicesText": "(Funktioniert auf Geräten mit der Google Play (Android) Version von dem Spiel)", + "youHaveBeenSentAPromoCodeText": "Dir wurde ein ${APP_NAME} Gutscheincode geschickt:" + }, + "getCoinsWindow": { + "coinDoublerText": "Münzenverdoppler", + "coinsText": "${COUNT} Münzen", + "freeCoinsText": "Gratis Münzen", + "restorePurchasesText": "Kauf wiederherstellen", + "titleText": "Münzen holen" + }, + "getTicketsWindow": { + "freeText": "KOSTENLOS!", + "freeTicketsText": "Gratis Tickets", + "inProgressText": "Es wird bereits etwas eingekauft; Bitte\nversuche es später nochmal.", + "purchasesRestoredText": "Einkäufe wiederhergestellt.", + "receivedTicketsText": "${COUNT} Tickets erhalten!", + "restorePurchasesText": "Einkäufe wiederherstellen", + "ticketDoublerText": "Tickets verdoppeln", + "ticketPack1Text": "Kleines Ticketpack", + "ticketPack2Text": "Mittleres Ticketpack", + "ticketPack3Text": "Großes Ticketpack", + "ticketPack4Text": "Riesiges Ticketpack", + "ticketPack5Text": "Kolossales Ticketpack", + "ticketPack6Text": "Ultimatives Ticketpack", + "ticketsFromASponsorText": "Sehen Sie sich eine Anzeige an\nfür ${COUNT} Tickets", + "ticketsText": "${COUNT} Tickets", + "titleText": "Hol dir Tickets", + "unavailableLinkAccountText": "Sorry, Einkäufe sind auf dieser Plattform nicht verfügbar.\nUm das zu umgehen verlinke deinen Account mit einem Account auf\neiner anderen Plattform, um dort Einkäufe zu machen.", + "unavailableTemporarilyText": "Dies ist zur Zeit nicht verfügbar; bitte versuch es später nochmal.", + "unavailableText": "Sorry, zur Zeit leider nicht verfügbar.", + "versionTooOldText": "Sorry, diese Version von dem Spiel ist zu alt; Bitte update es zu einer neueren Version.", + "youHaveShortText": "Du hast ${COUNT}", + "youHaveText": "Du hast ${COUNT} Tickets" + }, + "googleMultiplayerDiscontinuedText": "Sorry, Googles Multiplayerservice ist nicht länger verfügbar.\nIch arbeite so schnell wie möglich an einem Ersatz.\nBis dahin, versuche bitte eine andere Verbindungsmethode.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Google Play-Käufe sind nicht verfügbar.\nMöglicherweise müssen Sie Ihre Store-App aktualisieren.", + "googlePlayServicesNotAvailableText": "Google Play-Dienste sind nicht verfügbar.\nEinige App-Funktionen sind möglicherweise deaktiviert.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Immer", + "autoText": "Automatisch", + "fullScreenCmdText": "Vollbildmodus (Cmd-F)", + "fullScreenCtrlText": "Vollbildmodus (Strg-F)", + "gammaText": "Gamma", + "highText": "Hoch", + "higherText": "Höher", + "lowText": "Niedrig", + "mediumText": "Mittel", + "neverText": "Niemals", + "resolutionText": "Auflösung", + "showFPSText": "Zeige FPS", + "texturesText": "Texturen", + "titleText": "Grafik", + "tvBorderText": "TV Rand", + "verticalSyncText": "Verticale Synchronisation", + "visualsText": "Visuelles" + }, + "helpWindow": { + "bombInfoText": "- Bombe -\nStärker als Schläge, kann\naber zum eigenen Grab führen.\nWerfe in die Richtung der Gegner,\nbevor die Zündschnur abbrennt,\num die besten Ergebnisse zu erzielen.", + "bombInfoTextScale": 0.6, + "canHelpText": "${APP_NAME} kann helfen.", + "controllersInfoText": "Du kannst ${APP_NAME} mit Freunden übers Netzwerk spielen, oder\nihr könnt alle auf demselben Gerät spielen wenn ihr genug\nController habt. ${APP_NAME} unterstützt eine Menge von ihnen:\nüber die kostenlose '${REMOTE_APP_NAME}' App kannst du sogar Handys als Controller nutzen.\nGehe zu Einstellungen->Controller für mehr Informationen", + "controllersInfoTextFantasia": "Ein Spieler kann die Fernbedienung als Controller verwenden,\naber Gamepads sind empfolen. Du kannst auch mobile Geräte\nals Controller benutzen. Downlode die kostenlose\n'BombSquad Remote' App. Schau unter 'Controller' in den \n'Einstellungen' für mehr Info.", + "controllersInfoTextMac": "Ein oder zwei Spieler können die Tastatur benutzen, allerdings spielt sich\nBombSquad am Besten mit Gamepads. Bombsquad kann USB Gamepads,\nPS3 Controller, XBox 360 Controller, Wiimotes und iOS-/Androidgeräte\nbenutzen, um die Charakter zu steuern. Hoffentlich hast du einige von Diesen.\nIn den Einstellungen unter 'Controller' findest du weitere Informationen.", + "controllersInfoTextOuya": "Du kannst OUYA Controller, PS3 Controller, XBox 360 Controller und viele weitere\nUSB und Bluetooth Gamepads mit BombSquad benutzen. Desweiteren kannst du\nauch iOS- und Androidgeräte mit der kostenlosen 'BombSquad Remote' App nutzen.\nIn den Einstellungen unter 'Controller' findest du weitere Informationen.", + "controllersInfoTextRemoteOnly": "Du kannst ${APP_NAME} mit freunden über ein Netzwerk, oder ihr\nkönnt alle auf einem Gerät spielen in dem ihr das Handy als\nController nutzt mit der kostenlosen app '${REMOTE_APP_NAME}'", + "controllersInfoTextScaleFantasia": 0.51, + "controllersInfoTextScaleMac": 0.58, + "controllersInfoTextScaleOuya": 0.63, + "controllersText": "Controller", + "controllersTextScale": 0.67, + "controlsSubtitleText": "Dein befreundeter ${APP_NAME} Charakter hat ein paar Basisfähigkeiten.", + "controlsSubtitleTextScale": 0.7, + "controlsText": "Steuerung", + "controlsTextScale": 1.4, + "devicesInfoText": "Die VR Version von ${APP_NAME} kann übers Netzerk mit der normalen\nVersion gespielt werden, also packt eure Handys, Tablets\nund Computer aus und los gehts. Es kann auch nützlich sein eine\nnormale Version des Spiels mit der VR Version zu Verbinden,\ndamit Leute von außen zuschauen können.", + "devicesText": "Geräte", + "friendsGoodText": "es ist gut, sie zu haben. ${APP_NAME} macht am meisten Spaß mit mehreren\nSpielern und unterstützt bis zu 8 Spieler gleichzeitig, was zu folgemdem führt:", + "friendsGoodTextScale": 0.62, + "friendsText": "Freunde", + "friendsTextScale": 0.67, + "jumpInfoText": "- Springen -\nSpringe, um kleine Lücken zu überwinden,\num Dinge höher zu werfen, und\num Glücksgefühle zu zeigen.", + "jumpInfoTextScale": 0.54, + "orPunchingSomethingText": "Oder um etwas zu schlagen, eine Klippe herunterzuwerfen und es fertigzumachen, auf dem Weg hinunter mit einer Klebebombe.", + "orPunchingSomethingTextScale": 0.44, + "pickUpInfoText": "- Aufnehmen -\nNimm Fahnen, Gegner oder alles\nandere, dass nicht auf dem Boden\nfestgemacht wurde. Drücke\nnochmal, um zu werfen.", + "pickUpInfoTextScale": 0.6, + "powerupBombDescriptionText": "Lässt dich drei, anstatt nur\neiner Bombe werfen.", + "powerupBombNameText": "Dreifach-Bomben", + "powerupCurseDescriptionText": "Diese möchtest du wohl vermeiden.\n ...oder etwa nicht?", + "powerupCurseNameText": "Fluch", + "powerupHealthDescriptionText": "Stellt dein vollständiges Leben wieder her.\nHättest du nie erraten.", + "powerupHealthNameText": "Medipack", + "powerupIceBombsDescriptionText": "Schwächer als normale Bomben,\nallerdings frierst du deine Gegner ein,\nund sie werden ziemlich zerbrechlich.", + "powerupIceBombsNameText": "Frostbomben", + "powerupImpactBombsDescriptionText": "Etwas schwächer als normale Bomben,\naber sie explodieren bei Berührung", + "powerupImpactBombsNameText": "Auslöserbomben", + "powerupLandMinesDescriptionText": "Diese kommen immer im Dreierpack;\nNützlich um die Basis zu verteidigen\noder schnelle Gegner zu stoppen.", + "powerupLandMinesNameText": "Landminen", + "powerupPunchDescriptionText": "Macht deine Schläge härter,\nschneller, besser, stärker.", + "powerupPunchNameText": "Boxhandschuhe", + "powerupShieldDescriptionText": "Absorbiert etwas Schaden,\ndeshalb musst du nicht wegrennen.", + "powerupShieldNameText": "Energieschild", + "powerupStickyBombsDescriptionText": "Kleben an allem, was sie berühren.\nDas wird lustig.", + "powerupStickyBombsNameText": "Klebebomben", + "powerupsSubtitleText": "Natürlich ist kein Spiel vollständig ohne Powerups:", + "powerupsSubtitleTextScale": 0.8, + "powerupsText": "Powerups", + "powerupsTextScale": 1.4, + "punchInfoText": "- Schlagen -\nSchlagen macht mehr Schaden, je\nschneller sich deine Fäuste bewegen, deshalb\nrenn und dreh dich, so schnell es geht.", + "punchInfoTextScale": 0.54, + "runInfoText": "- Rennen -\nHalte IRGENDEINEN Knopf gedrückt, um zu rennen. Drücker oder Schultertasten sind gut dafür geeignet, wenn\ndu welche hast. Rennen bringt dich schnell voran, macht es aber schwer zu steuern, also pass auf Abgründe auf.", + "runInfoTextScale": 0.6, + "someDaysText": "Manchmal ist einem einfach danach, etwas zu schlagen. Oder etwas in die Luft zu jagen.", + "someDaysTextScale": 0.64, + "titleText": "${APP_NAME} Hilfe", + "toGetTheMostText": "Um alles aus diesem Spiel herauszuholen, brauchst du folgendes:", + "toGetTheMostTextScale": 0.85, + "welcomeText": "Willkommen zu ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} navigiert die Menüs wie ein Boss -", + "importPlaylistCodeInstructionsText": "Benutze den folgenden Code, um diese Playlist irgendwo anders zu importieren:", + "importPlaylistSuccessText": "Die ${TYPE} Playlist '${NAME}' wurde importiert", + "importText": "Importieren", + "importingText": "Wird importiert...", + "inGameClippedNameText": "Im Spiel angezeigter Name wird \n\"${NAME}\"", + "installDiskSpaceErrorText": "ERROR: Installation wurde nicht abgeschlossen.\nEs ist nicht genug Speicherplatz verfügbar.\nVersuche es erneut, nachdem genügend Speicher freigegeben wurde.", + "internal": { + "arrowsToExitListText": "drücke ${LEFT} oder ${RIGHT}, um die Liste zu verlassen", + "buttonText": "Knopf", + "cantKickHostError": "Der Host kann nicht entfernt werden!", + "chatBlockedText": "Die Kommunikation von ${NAME} wurde für ${TIME} Sekunden blockiert.", + "connectedToGameText": "'${NAME}' beigetreten", + "connectedToPartyText": "Ist ${NAME}'s Party beigetreten!", + "connectingToPartyText": "verbindet...", + "connectionFailedHostAlreadyInPartyText": "Verbindung fehlgeschlagen; Host ist in einer anderen Party.", + "connectionFailedPartyFullText": "Verbindung fehlgeschlagen; Die Gruppe ist voll.", + "connectionFailedText": "Verbindung fehlgeschlagen.", + "connectionFailedVersionMismatchText": "Verbindung fehlgeschlagen; Der Host hat eine andere Version des Spiels.\nStellt sicher, dass ihr beide die neuste Version habt und versucht es erneut.", + "connectionRejectedText": "Verbindung abgelehnt.", + "controllerConnectedText": "${CONTROLLER} verbunden.", + "controllerDetectedText": "1 Controller entdeckt.", + "controllerDisconnectedText": "${CONTROLLER} getrennt.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} getrennt. Bitte versuche erneut zu verbinden.", + "controllerForMenusOnlyText": "Dieser Controller kann nicht zum spielen verwendet werden, nur zur Bedienung des Menüs.", + "controllerReconnectedText": "${CONTROLLER} wieder verbunden.", + "controllersConnectedText": "${COUNT} Controllers sind verbunden.", + "controllersDetectedText": "${COUNT} Controllers entdeckt.", + "controllersDisconnectedText": "${COUNT} Controllers sind nicht mehr verbunden.", + "corruptFileText": "Beschädigte Datei(en) Gefunden. Bitte Neu installieren, oder kontaktiere ${EMAIL}", + "errorPlayingMusicText": "Fehler beim abspielen der Musik: ${MUSIC}", + "errorResettingAchievementsText": "Es ist nicht möglich, die Online-Erfolge zurückzusetzen; Bitte versuche es später nochmal.", + "hasMenuControlText": "${NAME} hat die Menükontrolle", + "incompatibleNewerVersionHostText": "Der Host besitzt eine neuere Version des Spiels. \nAktualisiere es und versuche es erneut.", + "incompatibleVersionHostText": "Der Host hat eine andere Version des Spiels.\nStellt sicher, dass ihr beide die neuste Version habt und versucht es erneut.", + "incompatibleVersionPlayerText": "${NAME} hat eine andere Version des Spiels.\nStellt sicher, dass ihr beide die neuste Version habt und versuchts erneut.", + "invalidAddressErrorText": "Fehler: Ungültige Adresse.", + "invalidNameErrorText": "Error: ungültiger Name", + "invalidPortErrorText": "Fehler: Falscher Port", + "invitationSentText": "Einladung wurde gesendet.", + "invitationsSentText": "${COUNT} Einladungen wurden gesendet.", + "joinedPartyInstructionsText": "Jemand ist deiner Party beigetreten.\nDrücke 'Spielen' um das Spiel zu starten.", + "keyboardText": "Tastatur", + "kickIdlePlayersKickedText": "${NAME} wird rausgeschmissen, weil er untätig ist!", + "kickIdlePlayersWarning1Text": "Mach was ${NAME}, sonst wirst du in ${COUNT} Sekunden rausgeschmissen.", + "kickIdlePlayersWarning2Text": "(Du kannst das in den Einstellungen ausschalten -> Erweitert)", + "leftGameText": "'${NAME}' hat verlassen", + "leftPartyText": "hat ${NAME}'s Party verlassen.", + "noMusicFilesInFolderText": "Der Ordner enthält keine Musikdateien.", + "playerJoinedPartyText": "${NAME} ist der Party beigetreten!", + "playerLeftPartyText": "${NAME} hat die Party verlassen.", + "rejectingInviteAlreadyInPartyText": "Lehne Einladung ab (bereits in einer Party).", + "serverRestartingText": "Server wird neugestartet. Bitte trete gleich erneut bei...", + "serverShuttingDownText": "Server wird abgeschaltet...", + "signInErrorText": "Error beim Einloggen.", + "signInNoConnectionText": "Login nicht möglich. (Keine Internetverbindung?)", + "teamNameText": "Team ${NAME}", + "telnetAccessDeniedText": "FEHLER: Benutzer hat keinen telnet-Zugang gewährt.", + "timeOutText": "(unterbreche in ${TIME} Sekunden)", + "touchScreenJoinWarningText": "Du bist mit dem Touchscreen beigetreten.\nWenn das ein Versehen war, drücke 'Menü->Spiel Beenden' damit.", + "touchScreenText": "TouchScreen", + "trialText": "Testversion", + "unableToResolveHostText": "Fehler: Verbindung zum Host konnte nicht aufgelöst werden.", + "unavailableNoConnectionText": "Zurzeit nicht verfügbar. (Keine Internetverbindung?)", + "vrOrientationResetCardboardText": "Benutze dies,um die VR orientierung zurückzusetzen.\nUm das Spiel spielen zu können, brauchst du einen externen controller.", + "vrOrientationResetText": "Kalibriere VR Orientierung.", + "willTimeOutText": "(wird unterbrochen, wenn keine Eingabe)" + }, + "jumpBoldText": "SPRING", + "jumpText": "Spring", + "keepText": "Halten", + "keepTheseSettingsText": "Diese Einstellungen beibehalten?", + "keyboardChangeInstructionsText": "Drücke die Leertaste doppelt, um die Tastaturen zu wechseln.", + "keyboardNoOthersAvailableText": "Keine anderen Tastaturen verfügbar.", + "keyboardSwitchText": "Tastatur umschalten auf \"${NAME}\".", + "kickOccurredText": "${NAME} wurde entfernt.", + "kickQuestionText": "${NAME} entfernen?", + "kickText": "Entfernen", + "kickVoteCantKickAdminsText": "Admins können nicht rausgeworfen werden.", + "kickVoteCantKickSelfText": "Du kannst dich nicht selber rauswerfen.", + "kickVoteFailedNotEnoughVotersText": "Nicht genügend Spieler für eine Abstimmung.", + "kickVoteFailedText": "Abstimmung zum Hinauswerfen fehlgeschlagen.", + "kickVoteStartedText": "Abstimmung zum Hinauswerfen von ${NAME}.", + "kickVoteText": "Stimme zum Hinauswerfen ab", + "kickVotingDisabledText": "Votekick ist deaktiviert.", + "kickWithChatText": "Tippe ${YES} für Ja oder ${NO} für Nein in den Chat.", + "killsTallyText": "${COUNT} Kills", + "killsText": "Kills", + "kioskWindow": { + "easyText": "Anfänger", + "epicModeText": "Episch", + "fullMenuText": "Vollständiges Menü", + "hardText": "Schwer", + "mediumText": "Mittel", + "singlePlayerExamplesText": "Einzelspieler / Koop Beispiele", + "versusExamplesText": "Gegeneinander Beispiele" + }, + "languageSetText": "Sprache ist nun \"${LANGUAGE}\".", + "lapNumberText": "Runde ${CURRENT}/${TOTAL}", + "lastGamesText": "(letzte ${COUNT} Spiele)", + "leaderboardsText": "Rangliste", + "league": { + "allTimeText": "Gesamt", + "currentSeasonText": "Aktuelle Saison (${NUMBER})", + "leagueFullText": "${NAME} Liga", + "leagueRankText": "Liga Rang", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "Die Saison ist vor ${NUMBER} Tagen abgelaufen.", + "seasonEndsDaysText": "Die Saison endet in ${NUMBER} Tagen.", + "seasonEndsHoursText": "Die Saison endet in ${NUMBER} Stunden.", + "seasonEndsMinutesText": "Die Saison endet in ${NUMBER} Minuten.", + "seasonText": "Saison ${NUMBER}", + "tournamentLeagueText": "Du musst die ${NAME} Liga erreichen um dieses Turnier zu spielen.", + "trophyCountsResetText": "Die Trophäenzahl wird nächste Season zurückgesetzt." + }, + "levelBestScoresText": "Bestes Ergebnis bei ${LEVEL}", + "levelBestTimesText": "Beste Zeiten bei ${LEVEL}", + "levelFastestTimesText": "Schnellste Zeit auf ${LEVEL}", + "levelHighestScoresText": "Höchste Punktzahl auf ${LEVEL}", + "levelIsLockedText": "${LEVEL} ist gesperrt.", + "levelMustBeCompletedFirstText": "${LEVEL} muss zuerst abgeschlossen werden.", + "levelText": "Level ${NUMBER}", + "levelUnlockedText": "Level entsperrt!", + "livesBonusText": "Lebensbonus", + "loadingText": "lädt", + "loadingTryAgainText": "Lädt; Bitte gleich nochmal versuchen...", + "macControllerSubsystemBothText": "Beide (nicht empfohlen)", + "macControllerSubsystemClassicText": "Klassisch", + "macControllerSubsystemDescriptionText": "(versuche das zu ändern wenn deine Controller nicht funktionieren)", + "macControllerSubsystemMFiNoteText": "Gemacht-für-iOS/Mac Controller erkannt;\nDu solltest diese aktivieren in Einstellungen -> Controller", + "macControllerSubsystemMFiText": "Gemacht-für-iOS/Mac", + "macControllerSubsystemTitleText": "Controller Unterstützung", + "mainMenu": { + "creditsText": "Credits", + "demoMenuText": "Demo Menü", + "endGameText": "Spiel beenden", + "endTestText": "Test beenden", + "exitGameText": "Spiel verlassen", + "exitToMenuText": "Zurück zum Menü?", + "howToPlayText": "Anleitung", + "justPlayerText": "(Nur ${NAME})", + "leaveGameText": "Spiel beenden", + "leavePartyConfirmText": "Willst du die Party wirklich\nverlassen?", + "leavePartyText": "Party verlassen", + "leaveText": "Verlassen", + "quitText": "Verlassen", + "resumeText": "Weiter", + "settingsText": "Einstellungen" + }, + "makeItSoText": "Mach es so", + "mapSelectGetMoreMapsText": "Hol dir mehr Karten...", + "mapSelectText": "Auswählen...", + "mapSelectTitleText": "${GAME} Karten", + "mapText": "Karte", + "maxConnectionsText": "Maximale Anzahl verbundener Geräte", + "maxPartySizeText": "Maximale Gruppengröße", + "maxPlayersText": "Maximale Spielerzahl", + "merchText": "Fanartikel!", + "modeArcadeText": "Arcade-Modus", + "modeClassicText": "Klassischer Modus", + "modeDemoText": "Demo Modus", + "mostValuablePlayerText": "Wertvollster Spieler", + "mostViolatedPlayerText": "Meist getöteter Spieler", + "mostViolentPlayerText": "Brutalster Spieler", + "moveText": "Bewegen", + "multiKillText": "${COUNT}-KILL!!!", + "multiPlayerCountText": "${COUNT} Spieler", + "mustInviteFriendsText": "Achtung: Du musst Freunde im\n\"${GATHER}\" Feld einladen oder Controller \nhinzufügen, um im Multiplayer spielen zu können.", + "nameBetrayedText": "${NAME} hat ${VICTIM} verraten.", + "nameDiedText": "${NAME} ist gestorben.", + "nameKilledText": "${NAME} hat ${VICTIM} getötet.", + "nameNotEmptyText": "Name kann nicht leer sein!", + "nameScoresText": "${NAME} punktet!", + "nameSuicideKidFriendlyText": "${NAME} starb versehentlich.", + "nameSuicideText": "${NAME} begeht Selbstmord.", + "nameText": "Name", + "nativeText": "Native Einstellung", + "newPersonalBestText": "Neuer persönlicher Rekord!", + "newTestBuildAvailableText": "Ein neuerer Test-Build ist erhältlich (${VERSION} Build ${BUILD}).\nZu holen auf ${ADDRESS}", + "newText": "Neu", + "newVersionAvailableText": "Eine neuere Version von ${APP_NAME} ist erhältlich! (${VERSION})", + "nextAchievementsText": "Nächste Erfolge:", + "nextLevelText": "Nächstes Level", + "noAchievementsRemainingText": "- keine", + "noContinuesText": "(keine weiterführung)", + "noExternalStorageErrorText": "Kein externer Datenspeicher auf dem Gerät gefunden", + "noGameCircleText": "Fehler: nicht in GameCircle eingeloggt", + "noJoinCoopMidwayText": "Koop-Spiele können nicht während des Spiels betreten werden.", + "noProfilesErrorText": "Du hast kein Spielerprofil, deshalb ist dein Name \"${NAME}\".\nGehe zu Einstellungen->Spielerprofile um ein Profil anzulegen.", + "noScoresYetText": "Noch kein Punktestand.", + "noThanksText": "Nein Danke", + "noTournamentsInTestBuildText": "WARNUNG: Turnierpunkte von dieser Testversion werden ignoriert.", + "noValidMapsErrorText": "Keine gültigen Karten für diesen Spieltyp gefunden.", + "notEnoughPlayersRemainingText": "Nicht genug Spieler übrig; Spiel verlassen oder neues Spiel starten.", + "notEnoughPlayersText": "Du benötigst mindestens ${COUNT} Spieler, um dieses Spiel zu starten.", + "notNowText": "Nicht jetzt", + "notSignedInErrorText": "Du musst dich hierfür einloggen.", + "notSignedInGooglePlayErrorText": "Hierfür musst du dich mit Google Play anmelden", + "notSignedInText": "Nicht angemeldet", + "notUsingAccountText": "Achtung: ${SERVICE} Konto wird ignoriert.\nGehe zu 'Konto -> Mit ${SERVICE} anmelden', wenn du es benutzen willst.", + "nothingIsSelectedErrorText": "Nichts ausgewählt!", + "numberText": "#${NUMBER}", + "offText": "Aus", + "okText": "Ok", + "onText": "An", + "oneMomentText": "Einen Moment...", + "onslaughtRespawnText": "${PLAYER} steigt in Welle ${WAVE} wieder ein", + "orText": "${A} oder ${B}", + "otherText": "Sonstiges...", + "outOfText": "(#${RANK} von ${ALL})", + "ownFlagAtYourBaseWarning": "Deine Flagge muss in deiner\nBasis sein um zu punkten!", + "packageModsEnabledErrorText": "Netzwerkmodus ist nicht erlaubt wenn local-package-mods aktiv sind (Einstellungen->Erweitert)", + "partyWindow": { + "chatMessageText": "Chat Nachricht", + "emptyText": "Deine Party ist leer", + "hostText": "(Moderator)", + "sendText": "Senden", + "titleText": "Deine Party" + }, + "pausedByHostText": "(Pausiert vom Host)", + "perfectWaveText": "Perfekte Welle!", + "pickUpBoldText": "PICKUP", + "pickUpText": "Aufsammeln", + "playModes": { + "coopText": "Koop", + "freeForAllText": "Frei für alle", + "multiTeamText": "Mutli-Team", + "singlePlayerCoopText": "Einzelspieler / Co-op", + "teamsText": "Teams" + }, + "playText": "Spielen", + "playWindow": { + "coopText": "Koop", + "freeForAllText": "Jeder gegen Jeden", + "oneToFourPlayersText": "1-4 Spieler", + "teamsText": "Teams", + "titleText": "Spiel starten", + "twoToEightPlayersText": "2-8 Spieler" + }, + "playerCountAbbreviatedText": "${COUNT}S", + "playerDelayedJoinText": "${PLAYER} spielt ab der nächsten Runde mit.", + "playerInfoText": "Spieler Information", + "playerLeftText": "${PLAYER} hat das Spiel verlassen.", + "playerLimitReachedText": "Die maximale Spieleranzahl von ${COUNT} ist erreicht; kein Beitritt möglich.", + "playerLimitReachedUnlockProText": "Upgrade auf \"${PRO}\" im Store um mit mehr als ${COUNT} Spielern zu spielen.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Du kannst dein Account Profil nicht löschen.", + "deleteButtonText": "Profil\nlöschen", + "deleteConfirmText": "'${PROFILE}' löschen?", + "editButtonText": "Profil\nBearbeiten", + "explanationText": "(Erstelle eigene Namen & Skins für Spieler auf diesem Account)", + "newButtonText": "Neues\nProfil", + "titleText": "Spieler Profile" + }, + "playerText": "Spieler", + "playlistNoValidGamesErrorText": "Diese Playlist enthält nicht zulässig freigeschaltete Spiele.", + "playlistNotFoundText": "Wiedergabeliste konnte nicht gefunden werden", + "playlistText": "Wiedergabeliste", + "playlistsText": "Playlists", + "pleaseRateText": "Wenn dir ${APP_NAME} Spaß macht, nimm dir kurz die Zeit\nund bewerte es oder schreib ein Review. Durch das Feedback\nwird zukünftige Arbeit an dem Spiel unterstützt.\n\nVielen Dank!\n-eric", + "pleaseWaitText": "Bitte warte...", + "pluginClassLoadErrorText": "Fehler beim laden der plugin class '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Fehler beim einleiten des plugins '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Plugin Einstellungen", + "pluginsAutoEnableNewText": "Aktiviere neue Plugins automatisch", + "pluginsDetectedText": "Neue Plugins erkannt. Neustarten, um sie zu aktivieren oder in den Einstellungen konfigurieren.", + "pluginsDisableAllText": "Deaktiviere alle Plugins", + "pluginsEnableAllText": "Aktiviere alle Plugins", + "pluginsRemovedText": "${NUM} plugin(s) wurden nicht mehr gefunden.", + "pluginsText": "Plugins", + "practiceText": "Übung", + "pressAnyButtonPlayAgainText": "Drücke einen Knopf um nochmal zu spielen...", + "pressAnyButtonText": "Drücke einen Knopf um fortzufahren...", + "pressAnyButtonToJoinText": "Drücke einen Knopf um beizutreten...", + "pressAnyKeyButtonPlayAgainText": "Drücke einen Knopf/Taste um nochmal zu spielen...", + "pressAnyKeyButtonText": "Drücke einen Knopf/Taste um fortzufahren...", + "pressAnyKeyText": "Drücke eine Taste...", + "pressJumpToFlyText": "** Drücke wiederholt Springen zum Fliegen **", + "pressPunchToJoinText": "Drücke SCHLAG um beizutreten...", + "pressToOverrideCharacterText": "Drücke ${BUTTONS}, um deinen Charakter zu überschreiben", + "pressToSelectProfileText": "Drücke ${BUTTONS}, um deinen Spieler auszuwählen", + "pressToSelectTeamText": "Drücke ${BUTTONS}, um ein Team auszuwählen", + "profileInfoText": "Erstelle Profile für dich und deine Freunde,\num Namen, Charakter und Farben anzupassen.", + "promoCodeWindow": { + "codeText": "Code", + "codeTextDescription": "Gutscheincode", + "enterText": "Bestätigen" + }, + "promoSubmitErrorText": "Fehler beim Senden des Codes; bitte überprüfe deine Internetverbindung", + "ps3ControllersWindow": { + "macInstructionsText": "Schalte die PS3 an ihrer Rückseite aus, versichere dich, dass\nBluetooth an deinem Mac aktiviert ist, verbinde dann deinen Controller\nmit dem Mac mit einem USB Kabel, um beide zu verbinden. Danach kannst du\nden Home-Button des Controllers benutzen, um ihn entweder per Kabel (USB),\noder drahtlos (Bluetooth) mit deinem Mac zu verbinden.\n\nAn manchen Macs wird möglicherweise die Nachricht erscheinen, dass du einen Code\neigeben musst. Falls dies passiert, findest du in der folgenden Anleitung oder bei Google Hilfe.\n\n\n\n\nPS3 Controller, die drahtlos verbunden sind, werden in den Systemeinstellungen unter\nBluetooh aufgelistet. Es kann sein, dass du sie von dieser Liste entfernen musst,\nfalls du sie wieder an deiner PS3 benutzen möchtest.\n\nUm die Batterien zu schonen, versichere dich zudem, dass du die Bluetooth-Verbindung\nkappst, wenn du sie nicht benutzt.\n\nBluetooth kann in der Regel bis zu 7 Geräte verwalten,\nwobei die Leistung variieren kann.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "Um einen PS3 Controller mit deiner OUYA zu benutzen, verbinde ihn einfach mit einem USB-Kabel,\num ihn zu aktivieren. Dies kann bewirken, dass deine anderen Controller die Verbindung verlieren,\ndeshalb solltest du danach deine OUYA neu starten und das USB-Kabel entfernen.\n\nAb dann solltest du die Möglichkeit haben, den HOME-Button des Controllers zu verwenden,\num ihn kabellos zu verbinden. Sobald du fertig bist mit spielen, halte den Home-Button\nfür 10 Sekunden gedrückt, um den Controller auszuschalten; ansonsten bleibt dieser möglicherweise an\nund verschwendet Batterien.", + "ouyaInstructionsTextScale": 0.74, + "pairingTutorialText": "Verbindungsanleitung Video", + "titleText": "Benutzt PS3 Controller mit ${APP_NAME}:" + }, + "publicBetaText": "PUBLIC BETA", + "punchBoldText": "SCHLAGEN", + "punchText": "Schlagen", + "purchaseForText": "Für ${PRICE} kaufen", + "purchaseGameText": "Spiel kaufen", + "purchasingText": "Bezahlt...", + "quitGameText": "${APP_NAME} beenden?", + "quittingIn5SecondsText": "Verlasse das Spiel in 5 Sekunden...", + "randomPlayerNamesText": "DEFAULT_NAMES, Horst, Eugen, Lutz, Kai", + "randomText": "Zufällig", + "rankText": "Rang", + "ratingText": "Bewertung", + "reachWave2Text": "Erreiche Welle 2 für die Rangliste.", + "readyText": "bereit", + "recentText": "kürzlich", + "remainingInTrialText": "verbleibend in der Testphase", + "remoteAppInfoShortText": "${APP_NAME} macht am meisten Spaß, wenn Ihr mit Freunden & Familie spielt.\nSchließen einen oder mehr Hardware Controller oder installiere die ${REMOTE_APP_NAME}\napp auf deinem Handy oder Tablet,\num diese als Controller zu nutzen.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Knopfposition", + "button_size": "Knopfgröße", + "cant_resolve_host": "Kann Host nicht finden.", + "capturing": "Drück eine Taste...", + "connected": "Verbunden.", + "description": "Nutze dein Handy / Tablet als controller für BombSquad.\nBis zu 8 Geräte können gleichzeitig für epischen lokalen Multiplayer-Wahnsinn an einem einzigen TV oder Tablet verbunden werden.", + "disconnected": "Verbindung vom Server getrennt.", + "dpad_fixed": "statisch", + "dpad_floating": "bewegend", + "dpad_position": "D-Pad Position", + "dpad_size": "D-Pad Größe", + "dpad_type": "D-Pad Typ", + "enter_an_address": "Gib eine Adresse ein", + "game_full": "Das Spiel ist voll oder akzeptiert keine Verbindungen", + "game_shut_down": "Das Spiel wurde beendet.", + "hardware_buttons": "Hardwaretasten", + "join_by_address": "Mit Adresse verbinden...", + "lag": "Lag: ${SECONDS} Sekunden", + "reset": "Zurücksetzen", + "run1": "Rennen 1", + "run2": "Rennen 2", + "searching": "Suche nach BombSquad Spielen...", + "searching_caption": "Tippe auf den Namen des Spieles, um es bei zu treten.\nAchte darauf, auf dem selben Netzwerk wie der Spiel zu sein.", + "start": "Starten", + "version_mismatch": "Versionskonflikt.\nVersuch es mit den aktuellen Versionen von\nBombSquad und BombSquad Remote noch einmal." + }, + "removeInGameAdsText": "Schalte \"${PRO}\" im Store frei, um Werbung zu entfernen.", + "renameText": "Name ändern", + "replayEndText": "Wiederholung beenden", + "replayNameDefaultText": "Letztes Spiel ansehen", + "replayReadErrorText": "Die Wiederholung kann nicht abgespielt werden.", + "replayRenameWarningText": "Benenne \"${REPLAY}\" nach einem Spiel um, um es zu behalten; Sonst wird es überschrieben.", + "replayVersionErrorText": "Es tut mir leid, diese Spielwiederholung wurde in einer anderen\nVersion erstellt und kann deswegen nicht angeschaut werden.", + "replayWatchText": "Wiederholung anschauen", + "replayWriteErrorText": "Wiederholungsdatei kann nicht erstellt werden.", + "replaysText": "Wiederholungen", + "reportPlayerExplanationText": "Benutze diese Email, um Cheating, unangemessene Sprache oder anderes schlechtes Verhalten zu melden.\nBeschreibe das Verhalten bitte:", + "reportThisPlayerCheatingText": "Cheating", + "reportThisPlayerLanguageText": "unangemessen Sprache", + "reportThisPlayerReasonText": "Was möchten sie melden?", + "reportThisPlayerText": "Spieler melden", + "requestingText": "Fordert an...", + "restartText": "Neustart", + "retryText": "Nochmal", + "revertText": "Zurücksetzen", + "runText": "Rennen", + "saveText": "Speichern", + "scanScriptsErrorText": "Fehler beim scannen der Skripts; sehe Protokoll für Details.", + "scoreChallengesText": "Punkte Herausforderungen", + "scoreListUnavailableText": "Bestenliste ist nicht verfügbar", + "scoreText": "Punkte", + "scoreUnits": { + "millisecondsText": "Millisekunden", + "pointsText": "Punkte", + "secondsText": "Sekunden" + }, + "scoreWasText": "(war ${COUNT})", + "selectText": "Auswählen", + "seriesWinLine1PlayerText": "GEWINNT DIE", + "seriesWinLine1Scale": 0.65, + "seriesWinLine1TeamText": "GEWINNT DIE", + "seriesWinLine1Text": "GEWINNT DIE", + "seriesWinLine2Scale": 1.0, + "seriesWinLine2Text": "SERIE!", + "settingsWindow": { + "accountText": "Konto", + "advancedText": "Erweitert", + "audioText": "Audio", + "controllersText": "Controller", + "enterPromoCodeText": "Gib einen Gutschein ein", + "graphicsText": "Grafik", + "kickIdlePlayersText": "Untätige Mitspieler rauswerfen", + "playerProfilesMovedText": "Beachte: Spieler Profil wurde zum Account Fenster verschoben.", + "playerProfilesText": "Spielerprofile", + "showPlayerNamesText": "Zeige die Spielernamen an", + "titleText": "Einstellungen" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(Eine einfache, Controller-freundliche Bildschirmtastatur für Texte)", + "alwaysUseInternalKeyboardText": "Immer interne Tastatur benutzen", + "benchmarksText": "Benchmarks & Stress-Tests", + "disableCameraGyroscopeMotionText": "Deaktivieren Sie die Kamera-Gyroskop-Bewegung", + "disableCameraShakeText": "Deaktivieren Sie Camera Shake", + "disableThisNotice": "(Du kannst diese Notiz in den erweiterten Einstellungen ändern.)", + "enablePackageModsDescriptionText": "(Aktiviert installierte Mods aber deaktiviert den Mehrspielermodus)", + "enablePackageModsText": "Local Package Mods aktivieren", + "enterPromoCodeText": "Gutscheincode eingeben", + "forTestingText": "Wichtig: Diese Werte sind nur für Tests und werden später wieder zurückgesetzt.", + "helpTranslateText": "${APP_NAME}'s Übersetzungen sind der Community zu\nverdanken. Wenn du eine Übersetzung hinzufügen oder \nverbessern willst, folge dem Link unten. Danke im Voraus!", + "kickIdlePlayersText": "Inaktive Spieler verbannen", + "kidFriendlyModeText": "Kinderfreundlicher Modus (Reduzierte Gewalt, etc.)", + "languageText": "Sprache", + "moddingGuideText": "Modding Anleitung", + "mustRestartText": "Das Spiel muss neugestartet werden um die Änderungen wirksam zu machen.", + "netTestingText": "Netzwerk Tests", + "resetText": "Zurücksetzen", + "showBombTrajectoriesText": "Zeige die Bomben-Flugbahn", + "showInGamePingText": "Zeige Ping im Spiel", + "showPlayerNamesText": "Zeige Spielernamen", + "showUserModsText": "Zeige Mods-Ordner", + "titleText": "Erweitert", + "translationEditorButtonText": "${APP_NAME} Übersetzungseditor", + "translationFetchErrorText": "Übersetzungsstatus nicht verfügbar....", + "translationFetchingStatusText": "prüfe Übersetzungsstatus...", + "translationInformMe": "Informiere mich, wenn meine Sprache Updates benötigt.", + "translationNoUpdateNeededText": "Die ausgewählte Sprache ist aktuell; Juhuuu!", + "translationUpdateNeededText": "** die ausgewählte Sprache ist nicht aktuell!! **", + "vrTestingText": "VR Tests" + }, + "shareText": "Teilen", + "sharingText": "Teilt...", + "showText": "Zeige", + "signInForPromoCodeText": "Du musst dich bei einem Account anmelden um den Code einzulösen.", + "signInWithGameCenterText": "Nutze die Game Center app,\num dich anzumelden.", + "singleGamePlaylistNameText": "Nur ${GAME}", + "singlePlayerCountText": "1 Spieler", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Charakterauswahl", + "Chosen One": "Auserwählter", + "Epic": "Spiele im Epik-Modus", + "Epic Race": "Epik-Rennen", + "FlagCatcher": "Fahne erobern", + "Flying": "Glückliche Gedanken", + "Football": "Football", + "ForwardMarch": "Überfall", + "GrandRomp": "Eroberung", + "Hockey": "Hockey", + "Keep Away": "Fernhalten", + "Marching": "An der Nase herumführen", + "Menu": "Hauptmenü", + "Onslaught": "Heftiger Angriff", + "Race": "Rennen", + "Scary": "Bergkönig", + "Scores": "Punktebildschirm", + "Survival": "Eliminieren", + "ToTheDeath": "Deathmatch", + "Victory": "Endpunktestand Bildschirm" + }, + "spaceKeyText": "Leer", + "statsText": "Statistiken", + "storagePermissionAccessText": "Dies benötigt Zugriff auf deinen Speicher", + "store": { + "alreadyOwnText": "Du besitzt bereits ${NAME}!", + "bombSquadProDescriptionText": "• Verdoppelt die Erfolge-Tickets Belohnung\n• Entfernt Werbung\n• Enthält ${COUNT} Bonustickets\n• +${PERCENT}% Ranglisten Bonus\n• Schaltet '${INF_ONSLAUGHT}' und\n '${INF_RUNAROUND}' Koop Spiele frei", + "bombSquadProFeaturesText": "Eigenschaften:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Entfernt die Werbung\n• Schaltet weitere Spieleinstellungen frei\n• Enthält außerdem:", + "buyText": "kaufen", + "charactersText": "Charaktere", + "comingSoonText": "Kommt bald...", + "extrasText": "Extras", + "freeBombSquadProText": "BombSquad ist nun kostenlos, aber da du es bereits gekauft hast, bekommst\ndu das BombSquad Pro Upgrade und ${COUNT} Tickets als ein Dankeschön.\nGenieße die neuen Funktionen, und danke für die Unterstützung!\n-Eric", + "gameUpgradesText": "Spiel Upgrades", + "getCoinsText": "Münzen holen", + "holidaySpecialText": "Ferien Spezial", + "howToSwitchCharactersText": "(Gehe zu \"${SETTINGS} -> ${PLAYER_PROFILES}\" um deine Charactere zu bearbeiten)", + "howToUseIconsText": "(Erstelle öffentliche Spieler Profile (im Account Fenster), um diese zu benutzen.)", + "howToUseMapsText": "(Benutze diese Karten in deinen eigenen Teams/Frei-für-alle Playlisten)", + "iconsText": "Symbole", + "loadErrorText": "Seite kann nicht geladen werden.\nÜberprüfe deine Internetverbindung.", + "loadingText": "lade", + "mapsText": "Karten", + "miniGamesText": "MiniSpiele", + "oneTimeOnlyText": "(einmalig)", + "purchaseAlreadyInProgressText": "Das Item wird gerade bezahlt. Bitte warte ein bisschen.", + "purchaseConfirmText": "${ITEM} kaufen?", + "purchaseNotValidError": "Kauf nicht gültig.\nKontaktiere ${EMAIL} wenn es ein Fehler ist.", + "purchaseText": "Einkaufen", + "saleBundleText": "Paket Rabatt!", + "saleExclaimText": "Sale!", + "salePercentText": "(um ${PERCENT}% reduziert)", + "saleText": "SALE", + "searchText": "Suchen", + "teamsFreeForAllGamesText": "Teams / Frei für alle Spiele", + "totalWorthText": "*** Wert: ${TOTAL_WORTH}!", + "upgradeQuestionText": "Upgraden?", + "winterSpecialText": "Weihnachtsspezial", + "youOwnThisText": "- In Besitz -" + }, + "storeDescriptionText": "Verrücktes Partyspiel mit bis zu 8 Mitspielern.\n\nZeige es deinen Freunden (oder dem Computer) in einem Turnier explosiver Minispiele, wie beispielsweise Fahne erobern, Bomben-Hockey und Epik-Zeitlupen-Deathmatch!\n\nEinfache Bedienung und ein erweiterter Controller-Support vereinfachen es mit bis zu 8 Spielern sofort durchzustarten; du kannst sogar dein Mobilgerät mit der kostenlosen 'BombSquad Remote' App als Controller benutzen!\n\nBomb sie alle weg!\n\nFür weitere Informationen, besuche www.froemling.net/bombsquad.", + "storeDescriptions": { + "blowUpYourFriendsText": "Jag deine Freunde in die Luft.", + "competeInMiniGamesText": "Behaupte dich in Minispielen von Wettrennen bis hin zu Fliegen.", + "customize2Text": "Passe Charaktere, Minispiele und sogar die Musik an.", + "customizeText": "Passe Charaktere an und erstelle deine eigenen Listen von Minispielen.", + "sportsMoreFunText": "Mit Sprengstoff macht Sport mehr Spaß.", + "teamUpAgainstComputerText": "Verbündet euch gegen den Computer." + }, + "storeText": "Laden", + "submitText": "Bestätigen", + "submittingPromoCodeText": "Code wird übertragen...", + "teamNamesColorText": "Team Namen/Farben...", + "teamsText": "Teams", + "telnetAccessGrantedText": "Telnet Zugang aktiviert.", + "telnetAccessText": "Telnet Zugang erkannt; erlauben?", + "testBuildErrorText": "Diese Testversion ist veraltet; Bitte überprüfe auf Updates.", + "testBuildText": "Testversion", + "testBuildValidateErrorText": "Unfähig die Testversion zu bestätigen. (Kein Internet?)", + "testBuildValidatedText": "Testversion ist gültig; Viel Spaß!", + "thankYouText": "Vielen Dank für deine Hilfe und viel Spaß!!", + "threeKillText": "DREIFACH KILL!!", + "timeBonusText": "Zeitbonus", + "timeElapsedText": "Vergangene Zeit", + "timeExpiredText": "Zeit abgelaufen!", + "timeSuffixDaysText": "${COUNT}T", + "timeSuffixHoursText": "${COUNT}S", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Tipp", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Top Freunde", + "tournamentCheckingStateText": "Überprüfe Turnier Status; Bitte warten...", + "tournamentEndedText": "Dieses Turnier ist zu Ende. Ein Neues startet bald.", + "tournamentEntryText": "Turnier beitreten", + "tournamentResultsRecentText": "Neueste Turnierergebnisse", + "tournamentStandingsText": "Tournier Tabelle", + "tournamentText": "Turnier", + "tournamentTimeExpiredText": "Turnierzeit abgelaufen", + "tournamentsDisabledWorkspaceText": "Turniere sind deaktiviert, wenn Arbeitsbereiche aktiv sind.\nUm Turniere wieder zu aktivieren, deaktivieren Sie Ihren Workspace und starten Sie neu.", + "tournamentsText": "Turniere", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "Roboter", + "Bernard": "Bernard", + "Bones": "Gebeine", + "Butch": "Butch", + "Easter Bunny": "Osterhase", + "Flopsy": "Flopsy", + "Frosty": "Eisi", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledore", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Glückspilz", + "Mel": "Mel", + "Middle-Man": "Mittelmann", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Weihnachtsmann", + "Snake Shadow": "Schlangenschatten", + "Spaz": "Spaz", + "Taobao Mascot": "TaoBao", + "Todd": "Todd", + "Todd McBurton": "Todd McBurton", + "Xara": "Xara", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Endlos\nOnslaught", + "Infinite\nRunaround": "Endlos\nRunaround", + "Onslaught\nTraining": "Onslaught\nTraining", + "Pro\nFootball": "Pro\nFootball", + "Pro\nOnslaught": "Pro\nOnslaught", + "Pro\nRunaround": "Pro\nRunaround", + "Rookie\nFootball": "Anfänger\nFootball", + "Rookie\nOnslaught": "Anfänger\nOnslaught", + "The\nLast Stand": "The\nLast Stand", + "Uber\nFootball": "Über\nFootball", + "Uber\nOnslaught": "Über\nOnslaught", + "Uber\nRunaround": "Über\nRunaround" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Training", + "Infinite ${GAME}": "Unendliches ${GAME}", + "Infinite Onslaught": "Endlos heftige Angriffe", + "Infinite Runaround": "Endlos an der Nase herumführen", + "Onslaught": "Endlos Onslaught", + "Onslaught Training": "heftiger Angriff Training", + "Pro ${GAME}": "Profi ${GAME}", + "Pro Football": "Profi Football", + "Pro Onslaught": "Profi heftiger Angriff", + "Pro Runaround": "Profi an der Nase herumführen", + "Rookie ${GAME}": "Anfänger ${GAME}", + "Rookie Football": "Anfänger Football", + "Rookie Onslaught": "Anfänger heftiger Angriff", + "Runaround": "Endlos Runaround", + "The Last Stand": "Der letzte Widerstand", + "Uber ${GAME}": "Unmöglich ${GAME}", + "Uber Football": "Unmöglich Football", + "Uber Onslaught": "Unmöglich heftiger Angriff", + "Uber Runaround": "Unmöglich an der Nase herumführen" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Sei eine Zeit lang der Auserwählte, um zu gewinnen.\nTöte ihn, um selbst zum Auserwählten zu werden.", + "Bomb as many targets as you can.": "Zerbombe so viele Ziele wie Du kannst.", + "Carry the flag for ${ARG1} seconds.": "Trage die Fahne für ${ARG1} Sekunden.", + "Carry the flag for a set length of time.": "Trage die Fahne über den eingestellten Zeitraum.", + "Crush ${ARG1} of your enemies.": "Zerquetsche ${ARG1} deiner Gegner.", + "Defeat all enemies.": "Besiege alle Gegner.", + "Dodge the falling bombs.": "Weiche den fallenden Bomben aus.", + "Final glorious epic slow motion battle to the death.": "Letzter, glorreicher, epischer Kampf bis in den Tod in Zeitlupe.", + "Gather eggs!": "Sammle Eier!", + "Get the flag to the enemy end zone.": "Bring die Fahne bis zum Endbereich deiner Gegner.", + "How fast can you defeat the ninjas?": "Wie schnell kannst du die Ninjas besiegen?", + "Kill a set number of enemies to win.": "Töte die eingestellte Anzahl an Gegner, um zu gewinnen.", + "Last one standing wins.": "Der letzte Überlebende gewinnt.", + "Last remaining alive wins.": "Der letzte Überlebende gewinnt.", + "Last team standing wins.": "Das letzte überlebende Team gewinnt.", + "Prevent enemies from reaching the exit.": "Halte die Gegner davon ab, den Ausgang zu erreichen.", + "Reach the enemy flag to score.": "Erreiche die gegnerische Fahne, um zu punkten.", + "Return the enemy flag to score.": "Bringe die gegnerische Fahne zurück, um zu punkten.", + "Run ${ARG1} laps.": "Renne ${ARG1} Runden.", + "Run ${ARG1} laps. Your entire team has to finish.": "Renne ${ARG1} Runden. Dein gesamtes Team muss das Ziel erreichen.", + "Run 1 lap.": "Renne 1 Runde.", + "Run 1 lap. Your entire team has to finish.": "Renne 1 Runde. Dein gesamtes Team muss das Ziel erreichen.", + "Run real fast!": "Renne richtig schnell!", + "Score ${ARG1} goals.": "Schieße ${ARG1} Tore.", + "Score ${ARG1} touchdowns.": "Mache ${ARG1} Touchdowns.", + "Score a goal": "Schieße ein Tor", + "Score a goal.": "Schieß ein Tor.", + "Score a touchdown.": "Erziel einen Touchdown.", + "Score some goals.": "Schieße ein paar Tore.", + "Secure all ${ARG1} flags.": "Nimm alle ${ARG1} Fahnen ein.", + "Secure all flags on the map to win.": "Nimm alle Fahnen auf der Karte ein, um zu gewinnen.", + "Secure the flag for ${ARG1} seconds.": "Nimm die Fahne für ${ARG1} Sekunden ein.", + "Secure the flag for a set length of time.": "Nimm die Fahne für die Länge der eingestellten Zeit ein.", + "Steal the enemy flag ${ARG1} times.": "Stehle die gegnerische Fahne ${ARG1} Mal.", + "Steal the enemy flag.": "Stehle die gegnerische Fahne.", + "There can be only one.": "Es kann nur Einen geben.", + "Touch the enemy flag ${ARG1} times.": "Berühre die gegnerische Fahne ${ARG1} Mal.", + "Touch the enemy flag.": "Berühre die gegnerische Fahne.", + "carry the flag for ${ARG1} seconds": "Trage die Fahne für ${ARG1} Sekunden", + "kill ${ARG1} enemies": "töte ${ARG1} Gegner", + "last one standing wins": "der letzte Überlebende gewinnt", + "last team standing wins": "das letzte überlebende Team gewinnt", + "return ${ARG1} flags": "Gib ${ARG1} Flaggen zurück", + "return 1 flag": "Gib eine Flagge zurück", + "run ${ARG1} laps": "renne ${ARG1} runden", + "run 1 lap": "renne 1 runde", + "score ${ARG1} goals": "schieße ${ARG1} Tore", + "score ${ARG1} touchdowns": "mache ${ARG1} Touchdowns", + "score a goal": "schieß ein Tor", + "score a touchdown": "erziel einen Touchdown", + "secure all ${ARG1} flags": "Sichere alle ${ARG1} Flaggen", + "secure the flag for ${ARG1} seconds": "beschütze die Flagge ${ARG1} Sekunden", + "touch ${ARG1} flags": "berühre ${ARG1} Flaggen", + "touch 1 flag": "berühre eine Flagge" + }, + "gameNames": { + "Assault": "Überfall", + "Capture the Flag": "Fahne erobern", + "Chosen One": "Auserwählte", + "Conquest": "Eroberung", + "Death Match": "Deathmatch", + "Easter Egg Hunt": "Ostereier-Jagd", + "Elimination": "Eliminieren", + "Football": "Football", + "Hockey": "Hockey", + "Keep Away": "Fernhalten", + "King of the Hill": "Bergkönig", + "Meteor Shower": "Kometenschauer", + "Ninja Fight": "Ninjakampf", + "Onslaught": "heftiger Angriff", + "Race": "Rennen", + "Runaround": "An der Nase herumführen", + "Target Practice": "Zielübung", + "The Last Stand": "Der letzte Widerstand" + }, + "inputDeviceNames": { + "Keyboard": "Tastatur", + "Keyboard P2": "Tastatur Spieler 2" + }, + "languages": { + "Arabic": "Arabisch", + "Belarussian": "Weißrussland", + "Chinese": "Chinesisch vereinfacht", + "ChineseTraditional": "Chinesisch Traditionell", + "Croatian": "Kroatisch", + "Czech": "Tschechisch", + "Danish": "Dänisch", + "Dutch": "Holländisch", + "English": "Englisch", + "Esperanto": "Esperanto", + "Filipino": "Philippinisch", + "Finnish": "Finnisch", + "French": "Französisch", + "German": "Deutsch", + "Gibberish": "Kauderwelsch", + "Greek": "Griechisch", + "Hindi": "Hindi", + "Hungarian": "Ungarisch", + "Indonesian": "Indonesisch", + "Italian": "Italienisch", + "Japanese": "Japanisch", + "Korean": "Koreanisch", + "Malay": "Malaiisch", + "Persian": "Persisch", + "Polish": "Polnisch", + "Portuguese": "Portugiesisch", + "Romanian": "Rumänisch", + "Russian": "Russisch", + "Serbian": "Serbisch", + "Slovak": "Slovakisch", + "Spanish": "Spanisch", + "Swedish": "Schwedisch", + "Tamil": "Tamil", + "Thai": "Thailändisch", + "Turkish": "Türkisch", + "Ukrainian": "Ukrainisch", + "Venetian": "Venezianisch", + "Vietnamese": "Vietnamesisch" + }, + "leagueNames": { + "Bronze": "Bronze", + "Diamond": "Diamant", + "Gold": "Gold", + "Silver": "Silber" + }, + "mapsNames": { + "Big G": "Großes G", + "Bridgit": "Steg", + "Courtyard": "Innenhof", + "Crag Castle": "Felszacken-Schloss", + "Doom Shroom": "Verhängnis-Pilz", + "Football Stadium": "Football Stadion", + "Happy Thoughts": "Glückliche Gedanken", + "Hockey Stadium": "Hockey Stadion", + "Lake Frigid": "Eisiger See", + "Monkey Face": "Affengesicht", + "Rampage": "Randale", + "Roundabout": "Drunter und Drüber", + "Step Right Up": "Treppe nach oben", + "The Pad": "Das Pad", + "Tip Top": "Gipfel", + "Tower D": "Turm D", + "Zigzag": "Zick-Zack" + }, + "playlistNames": { + "Just Epic": "Einfach episch", + "Just Sports": "Nur Sport" + }, + "promoCodeResponses": { + "invalid promo code": "ungültiger Promo Code" + }, + "scoreNames": { + "Flags": "Flaggen", + "Goals": "Tore", + "Score": "Punktestand", + "Survived": "Überlebt", + "Time": "Zeit", + "Time Held": "Haltezeit" + }, + "serverResponses": { + "A code has already been used on this account.": "Mit diesem Account wurde bereits ein Code eingelöst.", + "A reward has already been given for that address.": "Eine Belohnung wurde bereits vergeben für diese Adresse.", + "Account linking successful!": "Accounts erfolgreich verknüpft!", + "Account unlinking successful!": "Aufheben der Kontoverknüpfung erfolgreich!", + "Accounts are already linked.": "Accounts sind schon verknüpft.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Die Anzeigenansicht konnte nicht überprüft werden.\nBitte stellen Sie sicher, dass Sie eine offizielle und aktuelle Version des Spiels verwenden.", + "An error has occurred; (${ERROR})": "Ein Fehler ist aufgetreten; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Ein Fehler ist aufgetreten; bitte kontaktiere den Support. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Ein Fehler ist aufgetreten; bitte kontaktiere: support@froemling.net.", + "An error has occurred; please try again later.": "Ein Error ist aufgetreten; bitte später nochmal versuchen.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Bist du sicher, dass du diese Accounts verlinken willst?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nDu kannst das nicht mehr rückgängig machen!", + "BombSquad Pro unlocked!": "BombSquad Pro freigeschaltet!", + "Can't link 2 accounts of this type.": "Du kannst nicht 2 Accounts des selben Typs verknüpfen.", + "Can't link 2 diamond league accounts.": "Du kannst keine 2 Accounts der Diamanten Liga verknüpfen.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Kann nicht verlinken; Maximum sind ${COUNT} verknüpfte Accounts.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Cheating erkannt; deine Punkte und Preise sind für ${COUNT} Tage gesperrt.", + "Could not establish a secure connection.": "Konnte keine sichere Verbindung herstellen.", + "Daily maximum reached.": "Tageslimit erreicht.", + "Entering tournament...": "Trete Turnier bei...", + "Invalid code.": "Ungültiger Code", + "Invalid payment; purchase canceled.": "Ungültige Zahlung; Einkauf abgebrochen.", + "Invalid promo code.": "Ungültiger Promo Code.", + "Invalid purchase.": "Einkauf ungültig.", + "Invalid tournament entry; score will be ignored.": "Ungültiger Turnier Eintrag; die Punktzahl wird ignoriert.", + "Item unlocked!": "Gegenstand freigeschaltet!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VERLINKUNG VERWEIGERT. ${ACCOUNT} beinhaltet\nwichtige Daten, die ALLE VERLOREN wären.\nDu kannst andersherum verlinken, wenn du willst\n(Du würdest stattdessen DIESE Account-Daten verlieren)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Den Account ${ACCOUNT} mit diesem Account verknüpfen?\nJeglicher Fortschritt des Accounts ${ACCOUNT} wird verloren gehen!\nDies kann nicht rückgängig gemacht werden! Fortfahren?", + "Max number of playlists reached.": "Max Anzahl von Wiedergabelisten erreicht.", + "Max number of profiles reached.": "Max Anzahl der Profile erreicht.", + "Maximum friend code rewards reached.": "Maximale Anzahl an Einladungsbelohnungen erreicht.", + "Message is too long.": "Nachricht ist zu lang.", + "No servers are available. Please try again soon.": "Keine Server verfügbar. Schau nachher noch einmal vorbei.", + "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" erfolgreich aktualisiert.", + "Profile could not be upgraded.": "Profil konnte nicht aktualisiert werden.", + "Purchase successful!": "Einkauf erfolgreich!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "${COUNT} Tickets für den Login erhalten.\nKomm morgen wieder für ${TOMORROW_COUNT}!", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Die Funktionalität des Servers wird nicht länger in dieser Spielversion unterstützt;\nBitte updaten sie eine aktuellere Version.", + "Sorry, there are no uses remaining on this code.": "Leider ist das Nutzungs-Limit für diesen Code schon erreicht.", + "Sorry, this code has already been used.": "Tut uns leid, dieser Code wurde bereits eingelöst.", + "Sorry, this code has expired.": "Tut uns leid, dieser Code ist nicht mehr gültig.", + "Sorry, this code only works for new accounts.": "Tut uns leid, dieser Code kann nur mit einem neuen Account eingelöst werden.", + "Still searching for nearby servers; please try again soon.": "Suche immernoch nach Servern in der Nähe; schau nachher noch einmal vorbei.", + "Temporarily unavailable; please try again later.": "Vorübergehend nicht verfügbar. Bitte versuche es später noch einmal.", + "The tournament ended before you finished.": "Das Turnier endete bevor du ins Ziel kamst.", + "This account cannot be unlinked for ${NUM} days.": "Dieser Account kann nicht für ${NUM} Tage entknüpft werden.", + "This code cannot be used on the account that created it.": "Dieser Code kann nur mit dem Account eingelöst werden, mit dem er erzeugt wurde.", + "This is currently unavailable; please try again later.": "Dies ist derzeit nicht verfügbar. Bitte versuchen Sie es später noch einmal.", + "This requires version ${VERSION} or newer.": "Hierfür wird Version ${VERSION} oder neuer benötigt.", + "Tournaments disabled due to rooted device.": "Tourniere wegen gerootetem Gerät deaktiviert.", + "Tournaments require ${VERSION} or newer": "Turniere benötigen Version ${VERSION} oder neuer", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Den Account ${ACCOUNT} von diesem Account entknüpfen?\nJeglicher Fortschritt auf ${ACCOUNT} wird zurückgesetzt.\n(außer Erfolge in manchen Fällen)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "Beschwerden von Hacking sind für deinen Account aufgetreten.\nAccount, welche des Hackings verdächtigt werden, werden gesperrt. Bitte spiele gerecht.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Willst du deinen Gerät-Account mit diesem Account verlinken?\n\nDein Gerät-Account: ${ACCOUNT1}\nDieser Account: ${ACCOUNT2}\n\nDies wird dir ermöglichen, deinen Fortschritt zu behalten.\nAchtung: Du kannst es nicht rückgängig machen!", + "You already own this!": "Du besitzt es bereits!", + "You can join in ${COUNT} seconds.": "Du kannst in ${COUNT} Sekunden beitreten", + "You don't have enough tickets for this!": "Du hast nicht genug Tickets dafür!", + "You don't own that.": "Du besitzt das nicht.", + "You got ${COUNT} tickets!": "Du hast ${COUNT} Tickets!", + "You got a ${ITEM}!": "Du kriegst ein ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Du bist eine Liga aufgestiegen; Glückwunsch!", + "You must update to a newer version of the app to do this.": "Du musst deine Version updaten, um dies zu tun.", + "You must update to the newest version of the game to do this.": "Du musst zur neusten Version des Spiels updaten um dies zu tun.", + "You must wait a few seconds before entering a new code.": "Du musst ein wenig warten bevor du einen neuen Code eingeben kannst.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Du hast den #${RANK} Platz im letzten Turnier erreicht. Danke fürs Spielen!", + "Your account was rejected. Are you signed in?": "Dein Account wurde abgelehnt. Bist du eingeloggt?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Die Kopie dieses Spiels wurde modifiziert.\nÄnderungen rückgängig machen & neu versuchen.", + "Your friend code was used by ${ACCOUNT}": "Dein Freundschafts-Code wurde von ${ACCOUNT} verwendet." + }, + "settingNames": { + "1 Minute": "1 Minute", + "1 Second": "1 Sekunde", + "10 Minutes": "10 Minuten", + "2 Minutes": "2 Minuten", + "2 Seconds": "2 Sekunden", + "20 Minutes": "20 Minuten", + "4 Seconds": "4 Sekunden", + "5 Minutes": "5 Minuten", + "8 Seconds": "8 Sekunden", + "Allow Negative Scores": "Erlaube negative Punktzahlen.", + "Balance Total Lives": "Ausgleich der gesamten Leben", + "Bomb Spawning": "Bomben spawnen", + "Chosen One Gets Gloves": "Auserwählter bekommt Handschuhe", + "Chosen One Gets Shield": "Auserwählter bekommt ein Schild", + "Chosen One Time": "Wähle eine Zeit", + "Enable Impact Bombs": "Sofortbomben aktivieren", + "Enable Triple Bombs": "Dreifachbomben altivieren", + "Entire Team Must Finish": "Das ganze Team muss die Ziellinie überqueren.", + "Epic Mode": "Epischer Modus", + "Flag Idle Return Time": "Reset der fallengelassenen Fahne", + "Flag Touch Return Time": "Flaggen Rückkehr Zeit", + "Hold Time": "Haltezeit", + "Kills to Win Per Player": "Abschüsse zum Sieg pro Spieler", + "Laps": "Runden", + "Lives Per Player": "Leben pro Spieler", + "Long": "Lang", + "Longer": "Länger", + "Mine Spawning": "Erscheinende Minen", + "No Mines": "Keine Minen", + "None": "Keine", + "Normal": "Normal", + "Pro Mode": "Pro Mode", + "Respawn Times": "Wiederbelebungszeit", + "Score to Win": "Punkte zum Sieg", + "Short": "Kurz", + "Shorter": "Kürzer", + "Solo Mode": "Eins-gegen-Eins", + "Target Count": "Anzahl der Ziele", + "Time Limit": "Zeitlimit" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} ist disqualifiziert, da ${PLAYER} verlassen hat.", + "Killing ${NAME} for skipping part of the track!": "${NAME} wurde wegen Betrugsversuch ausgeschaltet!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Warnung an ${NAME}: turbo / Knopf spammen macht dich bewusstlos." + }, + "teamNames": { + "Bad Guys": "Die Bösen", + "Blue": "Blau", + "Good Guys": "Die Guten", + "Red": "Rot" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Ein perfekter Lauf-Sprung-Dreh-Kick haut jeden um \nund sichert dir den Respekt deiner Freunde.", + "Always remember to floss.": "Vergesse es nie, Zahnseide zu verwenden.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Erstelle Spielerprofile für dich und deine Freunde, mit den von\neuch gewünschten Namen und Aussehen, anstatt Zufällige zu verwenden.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Fluchkisten verwandeln dich in eine tickende Zeitbombe.\nDie einzige Hoffnung ist es, schnell eine Heilkiste aufzusammeln.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Bis auf das Aussehen sind alle Charaktere gleich.\nNimm deswegen den, mit dem du dich am besten identifizierst.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Werde nicht zu frech mit dem Energieschild; es hilft dir nichts, wenn du die Klippe hinunterstürzt.", + "Don't run all the time. Really. You will fall off cliffs.": "Lauf nicht die ganze Zeit. Wirklich. Du fällst nur runter.", + "Don't spin for too long; you'll become dizzy and fall.": "Drehe dich nicht zu lange, dir wird schwindelig und du fällst herunter.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Halte einen beliebigen Knopf gedrückt um zu rennen. (Auch Schultertasten, falls vorhanden.)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Halte irgendeinen Knopf gedrückt um zu laufen. Du bewegst \ndich schneller aber bist nicht mehr so agil. Vorsicht vor Kanten.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Eisbomben sind nicht gerade die stärksten, aber sie frieren\nandere ein machen sie überaus zerbrechlich.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Falls dich jemand packt, schlag zu und sie lassen dich gehen.\nFunktioniert auch bei Türstehern. Meistens.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Wenn du zu wenige Controller hast,installiere die '${REMOTE_APP_NAME}' App \nauf deinem mobilen Gerät, um diesen als Controller zu nutzen.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Zu wenig Controller für alle? Installier dir die 'BombSquad Remote' App \nauf deinem iOs oder Android Gerät und nutze diese als Controller.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Klebt eine Klebebombe an dir? Spring herum und dreh dich im Kreis. Vielleicht\nkannst du die Bombe abschütteln. Falls nicht, sehen deine letzten Sekunden wenigstens lustig aus.", + "If you kill an enemy in one hit you get double points for it.": "Erledigst du einen Gegner mit 1 Schlag bekommst du dafür doppelte Punkte.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Bist du mit einem Fluch besessen, ist deine einzige Hoffnung des Überlebens ein Erste-Hilfe-Kit", + "If you stay in one place, you're toast. Run and dodge to survive..": "Bleibst du stehen, bist du erledigt. Bleibe in Bewegung um zu überleben...", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Wenn viele Spieler kommen und gehen, (auf einer Party z.b.) stelle, 'auto-kick-idle-players'\nunter Optionen ein, um inaktive Spieler automatisch aus dem Spiel zu entfernen.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Wenn dein Gerät zu warm wird oder du Akku sparen möchtest, stelle\n\"Visuelles\" oder \"Auflösung\" in Einstellungen->Grafik auf Niedrig.", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Zu wenig FPS? Versuche die Auflösung und Details in\nden Einstellungen zu verringern.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "In Fahne erobern muss die eigene Flagge in der Basis sein, um Punkten zu können.\nDie gegnerische Flagge zu stehlen kann also ein guter Weg sein ihn am Punkten zu hindern.", + "In hockey, you'll maintain more speed if you turn gradually.": "Halte deine Geschwindigkeit in Hockey, indem du weite Kurven fährst.", + "It's easier to win with a friend or two helping.": "Es ist leichter zu gewinnen, wenn ein paar deiner Freunde helfen.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Springe und werfe deine Bomben gleichzeitig um höhere Ebenen mit ihnen zu erreichen.", + "Land-mines are a good way to stop speedy enemies.": "Landminen eignen sich gut um rennende Gegner zu stoppen.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Viele Dinge können aufgehoben und geworfen werden, auch andere Spieler.\nGegner in Abgründe zu werfen kann eine effektive und genugtuende Strategie sein.", + "No, you can't get up on the ledge. You have to throw bombs.": "Manche Vorsprünge lassen sich nicht zu Fuß erreichen. Benutze Bomben.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Spieler können mitten im Spiel beitreten und verlassen,\nund du kannst auch Controller im Betrieb an- und abschließen.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Spieler können den meisten Spielmodi mitten im Match beitreten,\ndu kannst auch Gamepads während des Spiels verbinden oder trennen.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Powerups wirken nur in Koop-Spielen für begrenzte Zeit.\nIn Team und Jeder gegen Jeden Spielen wirken sie bis zu deinem Tod.", + "Practice using your momentum to throw bombs more accurately.": "Übe den Schwung einzusetzen, um Bomben noch genauer zu werfen.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Schläge fügen mehr Schaden zu, umso schneller sich deine Fäuste bewegen.\nAlso lauf, spring und dreh dich wie ein Verrückter!", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Lauf vor und zurück bevor du eine Bombe wirfst,\num diese mit Schwung weiter zu werfen.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Erledige eine ganze Gruppe, indem du eine \nBombe neben einer TNT Kiste platzierst", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Der Kopf ist die empfindlichste Stelle. Klebebomben an deiner\nBirne wirst du deswegen fast nie überleben.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Dieses Level endet niemals, aber ein Highscore \nwird dir ewigen Respekt in der Welt einbringen.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Die Wurfkraft hängt von den Richtungstasten ab.\nUm etwas direkt vor dich zu werfen, drücke beim Werfen keine Richtungstaste.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Genervt vom Soundtrack? Wechsel ihn gegen deinen Eigenen!\nSchaue bei Einstellungen->Audio->Soundtrack", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Time Explosionen indem du Bomben noch einen Moment in der Hand hältst bevor du wirfst.", + "Try tricking enemies into killing eachother or running off cliffs.": "Trickse Gegner aus, sich gegenseitig zu töten oder von Klippen zu fallen.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Benutze die Aufnehmen-Taste um die Flagge aufzuheben < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Drehe dich ruckartig um, um Objekte weiter zu werfen.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Du kannst mit deiner Faust \"zielen\" indem du dich nach links oder rechts drehst.\nDas ist nützlich um Gegner von Kanten zu stoßen oder Tore in Hockey zu schießen.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Du weißt nicht wann die Bombe explodiert? Schau auf die Zündschnur!\nGelb..Orange..Rot..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Wirf deine Bomben weiter indem du kurz vor dem Wurf springst.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Du brauchst nicht dein Profil zu bearbeiten um deine Figur zu ändern; Drücke einfach den \nGreifen-Button wenn du einem Spiel beitrittst um deine Standardfigur zu überschreiben.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Du nimmst Schaden, wenn dein Kopf gegen Objekte oder andere Spieler knallt,\nalso versuche das zu vermeiden.", + "Your punches do much more damage if you are running or spinning.": "Deine Schläge verursachen mehr Schaden wenn du dich drehst oder rennst" + } + }, + "trialPeriodEndedText": "Die Demoversion ist vorbei. Willst du \nBombsquad kaufen und weiterspielen?", + "trophiesRequiredText": "Es werden ${NUMBER} Trophäen benötigt.", + "trophiesText": "Trophäen", + "trophiesThisSeasonText": "Erfolge dieser Saison", + "tutorial": { + "cpuBenchmarkText": "Tutorial läuft in Krasser Geschwindigkeit (CPU Leistung wird getestet)", + "phrase01Text": "Hallo Leute!", + "phrase02Text": "Willkommen zu ${APP_NAME}!", + "phrase03Text": "Hier sind ein paar Tipps zur Kontrolle eures Charakters:", + "phrase04Text": "Viele Dinge in ${APP_NAME} basieren auf PHYSIK.", + "phrase05Text": "Zum Beispiel, wenn du jemanden schlägst,..", + "phrase06Text": "..wird mehr Schaden für schnellere Schläge verteilt.", + "phrase07Text": "Bemerkt? Wir haben uns kaum bewegt, das tat ${NAME} also nicht so weh.", + "phrase08Text": "Jetzt lass uns springen und uns drehen um schneller zu werden.", + "phrase09Text": "Ah, schon besser.", + "phrase10Text": "Laufen hilft ebenfalls.", + "phrase11Text": "Halte einen BELIEBIGEN Knopf gedrückt um zu laufen.", + "phrase12Text": "Für besonders tolle Schläge, versuch mal zu laufen und dich zu drehen.", + "phrase13Text": "Huch; tut mir Leid, ${NAME}.", + "phrase14Text": "Du kannst Dinge aufsammeln und werfen, zum Beispiel Flaggen.. oder ${NAME}.", + "phrase15Text": "Schließlich gibt es noch Bomben.", + "phrase16Text": "Bomben zu werfen braucht Übung.", + "phrase17Text": "Aua! Kein wirklich guter Wurf.", + "phrase18Text": "Bewegung hilft weiter zu werfen.", + "phrase19Text": "Sprünge lassen dich höher werfen.", + "phrase20Text": "Schleuder deine Bomben für noch weitere Würfe.", + "phrase21Text": "Das Timen des Abwurfs kann schwierig sein.", + "phrase22Text": "Verdammt.", + "phrase23Text": "Warte ein bis zwei Sekunden.", + "phrase24Text": "Hurra! Du kannst es.", + "phrase25Text": "So, das war's auch schon.", + "phrase26Text": "Und jetzt schnapp sie dir, Tiger!", + "phrase27Text": "Verinnerliche dein Training und du wirst überleben!", + "phrase28Text": "..naja, vielleicht...", + "phrase29Text": "Viel Glück!", + "randomName1Text": "Fred", + "randomName2Text": "Harry", + "randomName3Text": "Bill", + "randomName4Text": "Chuck", + "randomName5Text": "Phil", + "skipConfirmText": "Willst du wirklich das Tutorial überspringen? Drücke einen Knopf, wenn ja.", + "skipVoteCountText": "${COUNT}/${TOTAL} Stimmen für Überspringen", + "skippingText": "überspringe Tutorial...", + "toSkipPressAnythingText": "(beliebige Taste drücken um Tutorial zu überspringen)" + }, + "twoKillText": "DOPPEL KILL!", + "unavailableText": "nicht verfügbar", + "unconfiguredControllerDetectedText": "Unkonfigurierter Controller erkannt:", + "unlockThisInTheStoreText": "Das muss im Store freigeschaltet werden.", + "unlockThisProfilesText": "Um mehr als ${NUM} Profile zu erstellen, brauchst du:", + "unlockThisText": "Um das zu entsperren brauchst du:", + "unsupportedHardwareText": "Entschuldigung, diese Hardware wird nicht unterstützt.", + "upFirstText": "Zuerst:", + "upNextText": "Als Nächstes in Spiel ${COUNT}:", + "updatingAccountText": "Aktualisiere dein Konto...", + "upgradeText": "Verbessern", + "upgradeToPlayText": "Upgrade auf \"${PRO}\" im Store um das zu Spielen.", + "useDefaultText": "Standard benutzen", + "usesExternalControllerText": "Das Spiel nutzt einen externen Controller für die Eingaben.", + "usingItunesText": "benutze Musik-App für Hintergrundmusik...", + "usingItunesTurnRepeatAndShuffleOnText": "Stelle sicher, dass iTunes ZUFÄLLIG wiedergibt und ALLE wiederholt.", + "v2AccountLinkingInfoText": "Um V2 Kontos zu verknüpfen, benutze den 'Konto Verwalten' Knopf.", + "validatingBetaText": "Verifizieren der Beta...", + "validatingTestBuildText": "Bestätige Testversion...", + "victoryText": "Sieg!", + "voteDelayText": "Die nächste Abstimmung kann erst in ${NUMBER} Sekunden gestartet werden.", + "voteInProgressText": "Es wird bereits eine Abstimmung durchgeführt.", + "votedAlreadyText": "Du hast schon abgestimmt", + "votesNeededText": "${NUMBER} Stimmen benötigt", + "vsText": "vs.", + "waitingForHostText": "(Warten auf ${HOST} um fortzufahren)", + "waitingForLocalPlayersText": "Warten auf lokale Spieler...", + "waitingForPlayersText": "Warte auf Spieler...", + "waitingInLineText": "In der Warteschlange (Party ist voll)...", + "watchAVideoText": "Video anschauen", + "watchAnAdText": "Schaue ein Video", + "watchWindow": { + "deleteConfirmText": "\"${REPLAY}\" löschen?", + "deleteReplayButtonText": "Wiederholung \nlöschen", + "myReplaysText": "Meine Wiederholungen", + "noReplaySelectedErrorText": "Keine Wiederholung ausgewählt", + "playbackSpeedText": "Abspielgeschwindigkeit: ${SPEED}", + "renameReplayButtonText": "Wiederholung\numbennen", + "renameReplayText": "\"${REPLAY}\" umbenennen zu:", + "renameText": "Umbennen", + "replayDeleteErrorText": "Fehler beim Löschen.", + "replayNameText": "Wiederholungs Name", + "replayRenameErrorAlreadyExistsText": "Eine Wiederholung mit diesem Namen existiert bereits.", + "replayRenameErrorInvalidName": "Kann nicht umbenannt werden; Name ungültig.", + "replayRenameErrorText": "Konnte nicht umbenannt werden.", + "sharedReplaysText": "geteilte \nWiederholungen", + "titleText": "Anschauen", + "watchReplayButtonText": "Wiederholung\nansehen" + }, + "waveText": "Welle", + "wellSureText": "Natürlich!", + "whatIsThisText": "Was ist das?", + "wiimoteLicenseWindow": { + "licenseText": "Copyright (c) 2007, DarwiinRemote Team\nAll rights reserved.\n\n Redistribution and use in source and binary forms, with or without modification,\n are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice, this\n list of conditions and the following disclaimer in the documentation and/or other\n materials provided with the distribution.\n3. Neither the name of this project nor the names of its contributors may be used to\n endorse or promote products derived from this software without specific prior\n written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.", + "licenseTextScale": 0.62, + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Nach Wiimotes suchen...", + "pressText": "Drücke Wiimote Knöpfe 1 und 2 gleichzeitig.", + "pressText2": "Bei neueren Wiimotes mit Motion Plus, drücke den roten \"sync\" Knopf auf der Unterseite.", + "pressText2Scale": 0.55, + "pressTextScale": 1.0 + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "copyrightTextScale": 0.6, + "listenText": "Suchen", + "macInstructionsText": "Deine Wii muss ausgeschaltet und Bluetooth \nan deinem Mac eingeschaltet sein, anschließend drücke \"Suchen\". \nWiimote Support spinnt häufig. \nDu musst es u.U. mehrmals versuchen.", + "macInstructionsTextScale": 0.7, + "thanksText": "Danke an das DarwiinRemote team\nfür die Umsetzung.", + "thanksTextScale": 0.8, + "titleText": "Wiimote einrichten" + }, + "winsPlayerText": "${NAME} Gewinnt!", + "winsTeamText": "${NAME} Gewinnt!", + "winsText": "${NAME} gewinnt!", + "workspaceSyncErrorText": "Fehler beim synchronisieren von ${WORKSPACE}. Sieh im log für details.", + "workspaceSyncReuseText": "Kann ${WORKSPACE} nicht synchronisieren. Benutze vorher synchronisierte Version.", + "worldScoresUnavailableText": "Weltrangliste ist nicht verfügbar", + "worldsBestScoresText": "Beste Punktzahl weltweit", + "worldsBestTimesText": "Beste Zeit weltweit", + "xbox360ControllersWindow": { + "getDriverText": "Treiber herunterladen", + "macInstructions2Text": "Nur Original Xbox 360 Controller funktionieren mit dem\n'Xbox 360 Wireless Controller for Windows'.\nDieser erlaubt bis zu vier Verbindungen.\n\nAchtung: Der Treiber funktioniert nicht mit Drittanbietern;\nGekennzeichnet mit 'Microsoft' nicht 'XBOX 360'.\nMicrosoft verkauft diese nicht mehr einzeln. Also muss man\nmit Controller oder woanders kaufen, zBsp. bei eBay.", + "macInstructions2TextScale": 0.76, + "macInstructionsText": "Um den Xbox 360 Controller benutzen zu können,\ninstalliere folgenden Mac Treiber.\nGilt für Kabel und Wireless Controller.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Um einen Xbox 360 Controller mit Kabel benutzen zu können,\nverbinde diesen einfach über USB. Mehrere Controller können \nüber ein USB Hub verbunden werden.\n\nUm einen Wireless Controller benutzen zu können brauchst du einen\nWireless Adapter, wie er als Teil des \"Xbox 360 wireless Controller for Windows\"\nSet oder einzeln erhältlich ist. Jeder Wireless Adapter wird über USB Port\nverbunden so das du bis zu 4 Wireless Controller benutzen kannst.", + "ouyaInstructionsTextScale": 0.8, + "titleText": "Xbox 360 Controller mit ${APP_NAME} benutzen:" + }, + "yesAllowText": "Ja, erlauben!", + "yourBestScoresText": "Deine besten Punktzahlen", + "yourBestTimesText": "Deine besten Zeiten" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/gibberish.json b/dist/ba_data/data/languages/gibberish.json new file mode 100644 index 0000000..3968829 --- /dev/null +++ b/dist/ba_data/data/languages/gibberish.json @@ -0,0 +1,2039 @@ +{ + "accountRejectedText": "You ac woefije obj acwoew. Aj cowier wore cs?", + "accountSettingsWindow": { + "accountNameRules": "Acoief coej. c woejf. cwoef ocoweofwjfj c wjefowfowef wocjowefffz", + "accountProfileText": "(acczntl prfflzlf)", + "accountsText": "Acctntzz", + "achievementProgressText": "Achilfjasdflz: ${COUNT} ouzt of ${TOTAL}", + "campaignProgressText": "Cmapghan Progflzl: ${PROGRESS}", + "changeOncePerSeason": "owe c wow chofu wefwoefjwofjowcowfwf.", + "changeOncePerSeasonError": "You cows ow woefj woifjwo ec oweo fowijf owiejf (${NUM} cowefwe)", + "customName": "Cow oj wojNaoa", + "deviceSpecificAccountText": "Crrlzfjowf uznfl a divwfo-zpijfwo ancnfo ${NAME}", + "googlePlayGamesAccountSwitchText": "If cows objc aw;eoifjw efoGoogl coweijwoejr,\nOc wore aero two cw oerjwoer jo gw spoeor.", + "linkAccountsEnterCodeText": "Enrlr Cfdsz", + "linkAccountsGenerateCodeText": "Gncowf CFdzz", + "linkAccountsInfoText": "(fwoco par owcj woef oac we paoi oijof)", + "linkAccountsInstructionsNewText": "Tl link j twice. owfj w off jeoifjwocjowiejfowef\ncoajfaocj wfjw efowjo. cowejf DO Oajofjwefjeo\norc aofj agpweoijv aefhwefo dj owiejf ewofj.\n(Dofjw jeotja theatric. owjfwfjjwf)\n\nYouc wfowej toij ${COUNT} cow oef.\n\nICMPEWOT: Coewij wthehowcjwef weofijweof;\ncIf wef htheojc;woej wejocowefjwe f wetowe\nbaoefhcw ecywoeutowermwocwoeitjs.", + "linkAccountsInstructionsText": "Tz lknf twz aoc coj, goi woc woef \nacoweof oac oia oow towjoifowj\nProwfo and in oir wojoc owinofiff.\nYouc owo iwoe oijf ${COUNT} accoaoijf.\n\nIMPCO oOIFOWEFJ\nowijecojwef\noijoicjwe\n\nAOicjowijeojwoeifjwef", + "linkAccountsText": "Lnk Accnffzz", + "linkedAccountsText": "Lnkfdf Accnrts:", + "manageAccountText": "JCowejerwoerjfwff", + "nameChangeConfirm": "Cho weft cowejf coiwjocwe. ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Thzz wflzz resta yrsr co-opz proglfzlz\nand hghzl scrdz. Itz cntljdf be zunfzz.\nArz yoz srz?", + "resetProgressConfirmText": "Thzlz wlz rzlt yrlzz co-pz plglrz,\nachroifzlz, and hghzl-scrlrz.\nTz cndft b undozn.\nAnz youz sér?", + "resetProgressText": "Rztlsf Proggzfrz", + "setAccountName": "Soil owe o animas", + "setAccountNameDesc": "Selcow f cjwo ot afoa fw jcpaoewj fwocowefj.\nYou wolf wc. weowyc oawe awoefm mcapowefi \ncoat aocjweo towirowmcowiefownr.", + "signInInfoText": "Sgn inz tz strz yr prograrzz inz\nthz cld, rnzr tckrz, rnz", + "signInText": "Sggnz Inz", + "signInWithDeviceInfoText": "(an coiwjfow fcoa cowj efj woj cowij eofjwoj foijs aofij )", + "signInWithDeviceText": "Sngi foicj oj de voa cwoiejfw", + "signInWithGameCircleText": "Sgn in gh Gm Cirflc", + "signInWithGooglePlayText": "Snf ocj weo fGOofl Plfl", + "signInWithTestAccountInfoText": "(lgjo cac cojef ot; oeco doic w eofjw oero )", + "signInWithTestAccountText": "Sjc weo fwtjwoefj cowefwf", + "signInWithV2InfoText": "(an zofj c woof woke wo Eire wf ofjjowg)", + "signInWithV2Text": "Sngo cow erwoj CBombSOudds acorjds.", + "signOutText": "Sgngz Ozt", + "signingInText": "Sgngngn infz..", + "signingOutText": "Sngning ozt..", + "testAccountWarningCardboardText": "Wrrjowifj a f;aoiwejc owj efaoiwjef owjef oaje wf\naiwje ofjw eoijaocijw oeifjowefj owijefoiwjefowi ef\naowj aocj weoif ja;woiefj woioc woef woiefjow fjweo.\n\nc weoiwo efjwo cowiejf oaiwje oaiwj i ogamaoiw.\n(yoauc owi odf oaijfo wojaojpjf oafpo ewf owejrw er)", + "testAccountWarningOculusText": "Wrrjowifj a f;aoiwejc owj efaoiwjef owjef oaje wf\naiwje ofjw eoijaocijw oeifjowefj owijefoiwjefowi ef\naowj aocj weoif ja;woiefj woioc woef woiefjow fjweo.\n\nc weoiwo efjwo cowiejf oaiwje oaiwj i ogamaoiw.\n(yoauc owi odf oaijfo wojaojpjf oafpo ewf owejrw er)", + "testAccountWarningText": "Wrznnzn: yzz asdfa aofijs fo asd; ofiasdfo jasdo\na;sdj faoisdfj oiasdfo; asdoi aoisjdfasdf\nasdoj asodi oasdjf osijdf oaijsdf oiasfd\nasdof jaosdfj oasdjf ;oaisjdf;oijas dfoijasdf", + "ticketsText": "Tzcktzz: ${COUNT}", + "titleText": "Acnfnnz", + "unlinkAccountsInstructionsText": "Slj cwefjwe f owcjwoeijowief", + "unlinkAccountsText": "Uldfj owjowerjsr", + "unlinkLegacyV1AccountsText": "Unkind filcher (V1) Acosdf", + "v2LinkInstructionsText": "Usdl ow cweoroe arc o woij erode cowefoweirjewr sers.", + "viaAccount": "(fc cowefjwef ${NAME})", + "youAreLoggedInAsText": "Yzrl arz lgzffd iz az:", + "youAreSignedInAsText": "Yz arz sngnfd inz arz:" + }, + "achievementChallengesText": "Achéivmznt Chalzlngesz", + "achievementText": "Áchíévzmúnt", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Kílzl 3 bád gúyz wúth TNTz", + "descriptionComplete": "Killéd 3 bád gúyz wíth TNT", + "descriptionFull": "Kíll 3 bád gzys wíth TNT ónz ${LEVEL}", + "descriptionFullComplete": "Kzlléd 3 bad gzs wéth TNT ón ${LEVEL}", + "name": "Boóm Gúzz thz Dynámitz" + }, + "Boxer": { + "description": "Win withóut uzing any bómbz", + "descriptionComplete": "Wén withéut uzing any bémbzz", + "descriptionFull": "Czmplétz ${LEVEL} wéithzt uznng anyz bómbz", + "descriptionFullComplete": "Complzzted ${LEVEL} wíthoutz úsing ány bómbz", + "name": "Bóxzr" + }, + "Dual Wielding": { + "descriptionFull": "Coocjf co eofw jc9ha oc jweofi jwoe)", + "descriptionFullComplete": "Cncof o 2 Ocno come o f(hard co who oc)", + "name": "Dual Wlfjl c" + }, + "Flawless Victory": { + "description": "Win withóut getting hit", + "descriptionComplete": "Wén withéut getting hit", + "descriptionFull": "Wín ${LEVEL} wíthozt géttzng hétz", + "descriptionFullComplete": "Wón ${LEVEL} wíthóut géttnz hit", + "name": "Fláwlzzz Victoryz" + }, + "Free Loader": { + "descriptionFull": "Stalk two owiej of ; cow 2+ cpoijefz", + "descriptionFullComplete": "Stoic wo reif owe jo j oweo woeijo 2+ cowpef", + "name": "Frizz Ljdfefwz" + }, + "Gold Miner": { + "description": "Kill 6 búd guyz wíth lánd-minez", + "descriptionComplete": "Killed 6 bad guyz with land-minez", + "descriptionFull": "Kílz 6 bád gzsz wéth lánz-mínz on ${LEVEL}", + "descriptionFullComplete": "Kílzd 6 bád gzsz wéth lánz-mínz on ${LEVEL}", + "name": "Góld Mínzr" + }, + "Got the Moves": { + "description": "Win withóut uzing púnchez ór bómbz", + "descriptionComplete": "Wén withéut uzing punchez ér bémbz", + "descriptionFull": "Wín ${LEVEL} wiznfft ands bpunchpd so bmzlf", + "descriptionFullComplete": "Wonz ${LEVEL} wlznfif anz pnchr or bmzfz", + "name": "Gót thz Móvzz" + }, + "In Control": { + "descriptionFull": "Coin oil of jo owe fo(her dcc oiowe)", + "descriptionFullComplete": "Coco oe owe fwoinoi (where ocwo wjef)", + "name": "Ina Conoiwjef" + }, + "Last Stand God": { + "description": "Zcóre 1000 póintz", + "descriptionComplete": "Zcéred 1000 péintz", + "descriptionFull": "Scorz 1000 prtz on ${LEVEL}", + "descriptionFullComplete": "Scorzed 1000 Ptz onz ${LEVEL}", + "name": "${LEVEL} Gzd" + }, + "Last Stand Master": { + "description": "Zcóre 250 póintz", + "descriptionComplete": "Scórzd 250 póinzfzs", + "descriptionFull": "Scórz 250 póoinzf on ${LEVEL}", + "descriptionFullComplete": "Scórzd 250 póoinzf on ${LEVEL}", + "name": "${LEVEL} Mztstrz" + }, + "Last Stand Wizard": { + "description": "Zcóre 500 póintz", + "descriptionComplete": "Zcéred 500 péintz", + "descriptionFull": "Sczore 500 póintz ón ${LEVEL}", + "descriptionFullComplete": "Sczored 500 póintz ón ${LEVEL}", + "name": "${LEVEL} Wizárd" + }, + "Mine Games": { + "description": "Kill 3 bad guyz with land-minez", + "descriptionComplete": "Killéd 3 bód gúyz with land-minez", + "descriptionFull": "Kzll 3 bd guzl wzz lndz mdnz on ${LEVEL}", + "descriptionFullComplete": "Kzlld 3 bd guzl wzz lndz mdnz on ${LEVEL}", + "name": "Minz Gámzz" + }, + "Off You Go Then": { + "description": "Tózz 3 bad guyz óff the map", + "descriptionComplete": "Tézzed 3 bad guyz éff the map", + "descriptionFull": "Tlzzl 3 bd guzz ofz thz mp in ${LEVEL}", + "descriptionFullComplete": "Tlzzld 3 bd guzz ofz thz mp in ${LEVEL}", + "name": "Ofz Yóú Gú Thzn" + }, + "Onslaught God": { + "description": "Zcóre 5000 póintz", + "descriptionComplete": "Zcéred 5000 péintz", + "descriptionFull": "Scorlz 5000 ptsfz onz ${LEVEL}", + "descriptionFullComplete": "Scorlzd 5000 ptsfz onz ${LEVEL}", + "name": "${LEVEL} Gzd" + }, + "Onslaught Master": { + "description": "Zcóre 500 póintz", + "descriptionComplete": "Zcéred 500 péintz", + "descriptionFull": "Scorzr 500 ptasdf on ${LEVEL}", + "descriptionFullComplete": "Scorzrd 500 ptasdf on ${LEVEL}", + "name": "${LEVEL} Máztzr" + }, + "Onslaught Training Victory": { + "description": "Defeat all wavez", + "descriptionComplete": "Defeated all wavez", + "descriptionFull": "Défzt alzf wavls fn ${LEVEL}", + "descriptionFullComplete": "Défztddz alzf wavls fn ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Onslaught Wizard": { + "description": "Zcóre 1000 póintz", + "descriptionComplete": "Zcéred 1000 péintz", + "descriptionFull": "Scorlz 1000 pointz ín ${LEVEL}", + "descriptionFullComplete": "Scorlz 1000 pointz ín ${LEVEL}", + "name": "${LEVEL} Wizárd" + }, + "Precision Bombing": { + "description": "Win wíthóut any pówerupz", + "descriptionComplete": "Wén withéut any péwerupz", + "descriptionFull": "Wín ${LEVEL} wnthoz anz powr-upz", + "descriptionFullComplete": "Wín ${LEVEL} wnthoz anz powr-upz", + "name": "Przcízion Bombing" + }, + "Pro Boxer": { + "description": "Win withóut uzing any bómbz", + "descriptionComplete": "Wén withéut uzing any bémbz", + "descriptionFull": "Cómplztz ${LEVEL} wiífhaou uzngl fnp bomzz", + "descriptionFullComplete": "Cómplztz ${LEVEL} wiífhaou uzngl fnp bomzz", + "name": "Pró Bzxer" + }, + "Pro Football Shutout": { + "description": "Win withóut letting the bad guyz zcóre", + "descriptionComplete": "Wén withéut letting the bad guyz zcére", + "descriptionFull": "Wén ${LEVEL} winarhoz létngnz thé bád gzzl scéor", + "descriptionFullComplete": "Wénd ${LEVEL} winarhoz létngnz thé bád gzzl scéor", + "name": "${LEVEL} Zhutout" + }, + "Pro Football Victory": { + "description": "Win thé gúme", + "descriptionComplete": "Wén thú game", + "descriptionFull": "Winz thz gmz in ${LEVEL}", + "descriptionFullComplete": "Winzd thz gmz in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Pro Onslaught Victory": { + "description": "Deféat áll wávez", + "descriptionComplete": "Defeáted úll wávez", + "descriptionFull": "Defetzz álz wávz óf ${LEVEL}", + "descriptionFullComplete": "Defetzzd álz wávz óf ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Pro Runaround Victory": { + "description": "Cómplúte all wavez", + "descriptionComplete": "Cémpleted all wavez", + "descriptionFull": "Cómpltz áll wávez on ${LEVEL}", + "descriptionFullComplete": "Cómpltzd áll wávez on ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Rookie Football Shutout": { + "description": "Win withóut letting the bad guyz zcóre", + "descriptionComplete": "Wén withéut letting the bad guyz zcére", + "descriptionFull": "Wiz ${LEVEL} wihtz lettzng the bd gly asorz", + "descriptionFullComplete": "Wizd ${LEVEL} wihtz lettzng the bd gly asorz", + "name": "${LEVEL} Zhutout" + }, + "Rookie Football Victory": { + "description": "Win the game", + "descriptionComplete": "Wén the game", + "descriptionFull": "Wizn thz gmaz in ${LEVEL}", + "descriptionFullComplete": "Wiznd thz gmaz in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Rookie Onslaught Victory": { + "description": "Defeat all wavez", + "descriptionComplete": "Defeated all wavez", + "descriptionFull": "Defetz álz wávnz én ${LEVEL}", + "descriptionFullComplete": "Defetzed álz wávnz én ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Runaround God": { + "description": "Zcóre 2000 póintz", + "descriptionComplete": "Zcéred 2000 péintz", + "descriptionFull": "Scruze 2000 ptznf én ${LEVEL}", + "descriptionFullComplete": "Scruzed 2000 ptznf én ${LEVEL}", + "name": "${LEVEL} God" + }, + "Runaround Master": { + "description": "Zcóre 500 póintz", + "descriptionComplete": "Zcéred 500 péintz", + "descriptionFull": "Scórz 500 ptzfs én ${LEVEL}", + "descriptionFullComplete": "Scórzd 500 ptzfs én ${LEVEL}", + "name": "${LEVEL} Máztzr" + }, + "Runaround Wizard": { + "description": "Zcóre 1000 póintz", + "descriptionComplete": "Zcéred 1000 péintz", + "descriptionFull": "Scórz 1000 póintz ón ${LEVEL}", + "descriptionFullComplete": "Scórzd 1000 póintz ón ${LEVEL}", + "name": "${LEVEL} Wizárd" + }, + "Sharing is Caring": { + "descriptionFull": "Su owe oshoz o owe owejojowjeofjd", + "descriptionFullComplete": "Suo web fsdhare oc ojowijeoioifoidfdf", + "name": "Show zo owefj wojz" + }, + "Stayin' Alive": { + "description": "Win withóut dyíng", + "descriptionComplete": "Wén withéut dying", + "descriptionFull": "Wín ${LEVEL} wíthzoft edynzg", + "descriptionFullComplete": "Wínd ${LEVEL} wíthzoft edynzg", + "name": "Ztáyin' Álivz" + }, + "Super Mega Punch": { + "description": "Inflict 100% damage with óne punch", + "descriptionComplete": "Inflicted 100% damage with éne punch", + "descriptionFull": "Inflgz 100% dmgzz éwth on púnch en ${LEVEL}", + "descriptionFullComplete": "Inflgzdz 100% dmgzz éwth on púnch en ${LEVEL}", + "name": "Zúpzr Mzgá Punch" + }, + "Super Punch": { + "description": "Inflict 50% damage with óne punch", + "descriptionComplete": "Inflicted 50% damage with éne punch", + "descriptionFull": "Inflgtz 50% dmgzn wíth on puzn ón ${LEVEL}", + "descriptionFullComplete": "Inflgtzd 50% dmgzn wíth on puzn ón ${LEVEL}", + "name": "Zupzr Punch" + }, + "TNT Terror": { + "description": "Kill 6 bád gúyz with TNT", + "descriptionComplete": "Killed 6 bad guyz with TNT", + "descriptionFull": "Klzl 6 bad gulf with TNT en ${LEVEL}", + "descriptionFullComplete": "Klzld 6 bad gulf with TNT en ${LEVEL}", + "name": "TNTz Terrór" + }, + "Team Player": { + "descriptionFull": "Sto c weoj woe woe o o4+ pcoiwjef", + "descriptionFullComplete": "Stoic own efoiw ojoiwjeo f woof 4+ pojzoz", + "name": "Tzoij Plzljrz" + }, + "The Great Wall": { + "description": "Ztóp every zíngle bad guy", + "descriptionComplete": "Ztépped every zingle bad guy", + "descriptionFull": "Stopz evryz snglf bádz gzn on ${LEVEL}", + "descriptionFullComplete": "Stopzd evryz snglf bádz gzn on ${LEVEL}", + "name": "Thé Greát Wáll" + }, + "The Wall": { + "description": "Ztóp évery zíngle bad guy", + "descriptionComplete": "Ztépped every zingle bad guy", + "descriptionFull": "Stopz evryz snglf bádz gzn on ${LEVEL}", + "descriptionFullComplete": "Stopzd evryz snglf bádz gzn on ${LEVEL}", + "name": "Thz Wáll" + }, + "Uber Football Shutout": { + "description": "Win withóut létting thé bád guyz zcóre", + "descriptionComplete": "Wén withéut letting the bad guyz zcére", + "descriptionFull": "Winz ${LEVEL} wntho ltnfjf thz bád gzll scófz", + "descriptionFullComplete": "Winzd ${LEVEL} wntho ltnfjf thz bád gzll scófz", + "name": "${LEVEL} Zhútout" + }, + "Uber Football Victory": { + "description": "Wín the gáme", + "descriptionComplete": "Wén the game", + "descriptionFull": "Wínz thez gámz in ${LEVEL}", + "descriptionFullComplete": "Wónz thz gamz én ${LEVEL}", + "name": "${LEVEL} Víctory" + }, + "Uber Onslaught Victory": { + "description": "Defeat all wavez", + "descriptionComplete": "Defeated all wavez", + "descriptionFull": "Defetz álz wves in ${LEVEL}", + "descriptionFullComplete": "Defetzdd álz wves in ${LEVEL}", + "name": "${LEVEL} Victory" + }, + "Uber Runaround Victory": { + "description": "Cómplete áll wavez", + "descriptionComplete": "Cémpleted all wavez", + "descriptionFull": "Completz alz wves on ${LEVEL}", + "descriptionFullComplete": "Czmplétdz álz waves ónz ${LEVEL}", + "name": "${LEVEL} Victory" + } + }, + "achievementsRemainingText": "Azhiévemúnts Rzmáinzng:", + "achievementsText": "Achéevúmentz", + "achievementsUnavailableForOldSeasonsText": "Srrrz, chi faow co wjefo iwefo wef;oiajwf asodvjoa sdfj odfjsodf.", + "activatedText": "${THING} cjwoeifjwer.", + "addGameWindow": { + "getMoreGamesText": "Gztz Mrrz Gmzz...", + "titleText": "Ádzd Gámzé", + "titleTextScale": 1.01 + }, + "allowText": "Alzéow", + "alreadySignedInText": "Yr co wcowief woeijo wife ewf;\norc woeful oj ceofjwoejfowief\nocjwoef weofwocijweofw.", + "apiVersionErrorText": "Cznt lzdz mdls ${NAME}; zt tarng faptr ${VERSION_USED}; wz rojafoqrz ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Aztoz\" enablez thz onlzl when hedifphz arnz plzzdd inz)", + "headRelativeVRAudioText": "Hzad Rlztefijv VRZ Azdjfozl", + "musicVolumeText": "Músíc Vólumze", + "soundVolumeText": "Sóuznd Vólume", + "soundtrackButtonText": "Sóuzdtríckz", + "soundtrackDescriptionText": "(ássigzn yóur ówn músic zo pzlay dúrinzg gzmes)", + "titleText": "Aúdzo" + }, + "autoText": "Aztoz", + "backText": "Bfjack", + "banThisPlayerText": "Bjfo oweijf plfl", + "bestOfFinalText": "Bést-óf-${COUNT} Fínál", + "bestOfSeriesText": "Bést óf ${COUNT} sérzés:", + "bestRankText": "Yz bst rnkf iz #${RANK}", + "bestRatingText": "Yózr bést rátíng ús ${RATING}", + "betaErrorText": "Thís béta ís nz lóngzr áctzve; pléase chéck fór á nzw vérsion.", + "betaValidateErrorText": "Unáble tó válidzte béta. (nó nét cónnectizn?)", + "betaValidatedText": "Bztá Válídatéd; Enjóy!", + "bombBoldText": "BÓZMB", + "bombText": "Bóombz", + "boostText": "Bfzesf", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} ís cónfigúred ín thé ápp itszlf.", + "buttonText": "béttzn", + "canWeDebugText": "Woíld yoí lúké BombZqíád to áítomátúcálly réport\nbígz, crázhéz, ánd bázúc ízágé únfo to thé dévélopér?\n\nThúz dátá contáúnz no pérzonál únformátúon ánd hélpz\nkéép thé gámé rínnúng zmoothly ánd bíg-fréép.", + "cancelText": "Czéanczel", + "cantConfigureDeviceText": "Sórry, ${DEVICE} ús nút cónfígúrzble.", + "challengeEndedText": "Thzl cowfo jan fa eofnwoefnw.", + "chatMuteText": "Mmof wChad", + "chatMutedText": "Chad mamba", + "chatUnMuteText": "Unobiaje Chafb", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Yóz múst cómplítz\nthís lével tú próceed!", + "completionBonusText": "Cúmplezión Búnís", + "configControllersWindow": { + "configureControllersText": "Cnfgjzljrz Gmpzjgdz", + "configureGamepadsText": "Confifignr Gmpndddss", + "configureKeyboard2Text": "Confifif Kebzllszzz P2", + "configureKeyboardText": "Cnfofig Keybbbdzzzrd", + "configureMobileText": "Mozzle Dzdices as Cntlrrlz", + "configureTouchText": "Confifio Tofjafiffffsn", + "ps3Text": "PS3 Czojfijzssz", + "titleText": "Ctnzléfjorss", + "wiimotesText": "Wiizzle", + "xbox360Text": "Xbox 360 Csojfoijssszz" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Note: gzzzmf suzzzort vzzfrs bzz dzzzf anz Androidzzf verzzffrdn.", + "pressAnyButtonText": "Przss anzz butzzon on zzt gamzzzepad\n yozu waznt tzzo confijfgure...", + "titleText": "Confiszzgr Gzramepad" + }, + "configGamepadWindow": { + "advancedText": "Advzzcced", + "advancedTitleText": "Adnvlglz Ctnlglglz Stprurzz", + "analogStickDeadZoneDescriptionText": "(tzrlf upz ifz rzlf charlfzz 'drfgz' whcz yozl rjldf f thz tsicls)", + "analogStickDeadZoneText": "Anazz Séick Dfead Zze", + "appliesToAllText": "(appldf fdojf sfojdf fof thisp)", + "autoRecalibrateDescriptionText": "(ezble thffs fe yoér charawefter dows nwt mze atfull spzzed)", + "autoRecalibrateDescriptionTextScale": 0.4, + "autoRecalibrateText": "Auzo-Zecfélibrate Azzlog Stéck", + "autoRecalibrateTextScale": 0.65, + "axisText": "axéy", + "clearText": "clzár", + "dpadText": "dpéz", + "extraStartButtonText": "Extraflz Starn buTzzlf", + "ifNothingHappensTryAnalogText": "If zzidfeng happzzens, trw asszzning to thf anzlog stewfk efwstead.", + "ifNothingHappensTryDpadText": "Ift nothewfng happezz, tzy asigewning tz the ewd-pad itead.", + "ignoreCompletelyDescriptionText": "(pvojf wocjw oe ifjwo iefow eoijociwj efoij weofj woejf owijef)", + "ignoreCompletelyText": "Igoif Cmwpoifwf", + "ignoredButton1Text": "Ignozfoj Btntlg 1", + "ignoredButton2Text": "Ignogfj Buttlafj 2", + "ignoredButton3Text": "Ignoje Bttnzf 3", + "ignoredButton4Text": "Ignfowf Brtjlaf 4", + "ignoredButtonDescriptionText": "(usz thfs tzzz wrevent 'homez' or 'szync' bzztons éom afctcng thz UI)", + "ignoredButtonDescriptionTextScale": 0.4, + "ignoredButtonText": "Ignzcefd Buttzzn", + "pressAnyAnalogTriggerText": "Préss anz anfzalog tzzgger...", + "pressAnyButtonOrDpadText": "Przzs anfy buttw oz dpad...", + "pressAnyButtonText": "Prezz ayy buzton...", + "pressLeftRightText": "Pzss lefwt zr rewght...", + "pressUpDownText": "Press ufep orz éown...", + "runButton1Text": "Rén Buzzon 1", + "runButton2Text": "Rén Buefwon 2", + "runTrigger1Text": "Rén Trzzger 1", + "runTrigger2Text": "Rén Trizzer 2", + "runTriggerDescriptionText": "(anglaj trgglaf ltz yz rndf at baljfef zpddds)", + "secondHalfText": "Usz tzzs tossc onzzgure the zecond slf\nof a 2-gazzas-in-1 dezzzce zhat\nsdfws up as a segle cntljtlz.", + "secondaryEnableText": "Enzable", + "secondaryText": "Scndofjfsf Cntnglafj", + "startButtonActivatesDefaultDescriptionText": "(tflz thzf offz ifz yourz stfzf butlflz isz morz of a mnzuz bunflz)", + "startButtonActivatesDefaultText": "Stzt Bztton Actfewvates Dzault Wffget", + "startButtonActivatesDefaultTextScale": 0.65, + "titleText": "Ctjglafj Stwwcfp", + "twoInOneSetupText": "2-ér-1 Conzugger Setzzp", + "uiOnlyDescriptionText": "(pcoije oic owejofijwe ocj owejofjwo efjo wejfo)", + "uiOnlyText": "Lmo to Mnf Uslf", + "unassignedButtonsRunText": "All Unzzssigned Befttons Run", + "unassignedButtonsRunTextScale": 0.8, + "unsetText": "", + "vrReorientButtonText": "VR OCjweof jweofOBofw" + }, + "configKeyboardWindow": { + "configuringText": "Cofzzfgurizzf ${DEVICE}", + "keyboard2NoteScale": 0.7, + "keyboard2NoteText": "Nozf: mzost keybfdasdfrds canf oly rezzzfter a fewz kfjwoesses at\nofce, so havifasdf a secffd keydfafrd plzzer maff wrko beéter\nifz tdfere isza sfaate kefdfaoard atzzched fof tfm too zse.\nNfote thtyou'll stdfjill nejfe to asndssgn uniqeeys tfe tnhe\ntzwo payersfeweven inthat ase." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Actglz Cntrflf Sclz", + "actionsText": "Actíóns", + "buttonsText": "búttzns", + "dragControlsText": "< drgz nrltlss tz rpempnzlsdjf tmgj >", + "joystickText": "jóystizk", + "movementControlScaleText": "Mvjtjtg Cntljtfl Sclz", + "movementText": "Múvemznt", + "resetText": "Részt", + "swipeControlsHiddenText": "Hdz Swpnz Icnflfz", + "swipeInfoText": "'Swípe' styze cúntrozs táke ú lúttle gétting úsed tó bút\nmzke ít eásiér tó pláy wíthoút lóoking át thé cóntróls.", + "swipeText": "swípe", + "titleText": "Cónfígúre Tóuchszreen", + "touchControlsScaleText": "Tóuch Cóntróls Scále" + }, + "configureItNowText": "Cónfígzre ít nów?", + "configureText": "Cónfúgzre", + "connectMobileDevicesWindow": { + "amazonText": "Amézon Appstóre", + "appStoreText": "Appz Stózre", + "bestResultsScale": 0.65, + "bestResultsText": "Fór bést részlts yóz'll nééd a lag-fréé wifi nétwórk. Yóz can\nrédzcé wifi lag by tzrning óff óthér wiréléss dévicés, by\nplaying clósé tó yózr wifi rózytér, and by cónnécting thé\ngamé hóst diréctly tó thé nétwórk via éthérnét.", + "explanationScale": 0.8, + "explanationText": "Tz usé á smárt-phzné zr táblét ás á wiréléss gámépád,\ninstáll thé \"${REMOTE_APP_NAME}\" ápp zn it. Up tz 8 dévicés\ncán cznnéct tz á ${APP_NAME} gámé zvér WiFi, ánd it's fréé!", + "forAndroidText": "fór Anzdróid:", + "forIOSText": "fór íOzS:", + "getItForText": "Gét ${REMOTE_APP_NAME} fzr iOS ót thz Applé App Stúre\norz fór Andróid ét the Gozgle Pláy Stóre ur Amázon Appstóre", + "googlePlayText": "Gglgl Plz", + "titleText": "Uzíng Móbíle Dzvíces asz Cntrlflfz:" + }, + "continuePurchaseText": "Continifjz frz ${PRICE}?", + "continueText": "Conttiflz", + "controlsText": "Cztrnlfz", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Thz dfsn not appz to alflz-tmf rnefkz", + "activenessInfoText": "Thz mfijfo roif coiwef ow oijoiwe \npcoi wefoa coiweofi weocoieo dofiw.", + "activityText": "Actlffz", + "campaignText": "Cézmpáignz", + "challengesInfoText": "Winz piorios for complinlt mini-fjgisjf.\n\nPrizoi and office levels cnieicowf\ncaohf im fa chcijlef is copweof and\ndocowei coawijfowieocwiejf owoifoijfow.", + "challengesText": "Chllzlzfnfz", + "currentBestText": "Crrlzz Bzt", + "customText": "Cúztúm", + "entryFeeText": "Enrrz", + "forfeitConfirmText": "Forfojf thosi cowjeofijwf?", + "forfeitNotAllowedYetText": "Thz cowj co woac owienf owj oaijefowf.", + "forfeitText": "Froijfow", + "multipliersText": "Mlflfjzfs", + "nextChallengeText": "Nzt Chclwlfs", + "nextPlayText": "Nxts Plzflz", + "ofTotalTimeText": "ofz ${TOTAL}", + "playNowText": "Plz nfz", + "pointsText": "Pffzfs", + "powerRankingFinishedSeasonUnrankedText": "(finifhs sroic unrnrkken)", + "powerRankingNotInTopText": "(notz inf wociwoef ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pzf", + "powerRankingPointsMultText": "(x ${NUMBER} pzt)", + "powerRankingPointsText": "${NUMBER} pff", + "powerRankingPointsToRankedText": "(${CURRENT} ofz ${REMAINING} wefz)", + "powerRankingText": "Pzwlrrl Rnkflfz", + "prizesText": "Prrzzz", + "proMultInfoText": "Pfofz wf thet ${PRO} yocfz\nrcsfff a ${PERCENT}% poient bsffz hdere.", + "seeMoreText": "Mrrzz...", + "skipWaitText": "Skpz Wzrz", + "timeRemainingText": "Tmmz Rmrmrmfz", + "titleText": "Có-óup", + "toRankedText": "Tz Rnfkfd", + "totalText": "tztrlz", + "tournamentInfoText": "Cmpfowj foij hoihwo jowec\notjo fpcowjefo weyowufowef.\n\nPoriwjf cowiej oaww aor dojofoscore\npacify when fofjocow efoiwje fjoits.", + "welcome1Text": "Wlcojf to ${LEAGUE}. Yz j woej owiejowjef\nflwejfo ocjw oeif weofowewfw ejfwf, comfpof\ncajweoifwoif and fweiningowifj woicoijweorioreors.", + "welcome2Text": "Yz cm alfj fcojwfowiejfo wiejo wfoinoaicoiwefoiwef.\nTickef woioiweofiw efoiauoicoiwefjoaieofaefa\nminf-fizoj , and itner ouacohao,a nd fmofz.", + "yourPowerRankingText": "Yrrlz Powe Rnkkffz:" + }, + "copyConfirmText": "Cpoew cow owes oC.", + "copyOfText": "Copzyz du ${NAME}", + "copyText": "Czópy", + "copyrightText": "© 2013 Eric Froemling", + "createAPlayerProfileText": "Créatz á pláyer prófzle?", + "createEditPlayerText": "", + "createText": "Crziate", + "creditsWindow": { + "additionalAudioArtIdeasText": "Addizijton Audorz, Elralz Artlzl,a ndlad Idlflzf by ${NAME}", + "additionalMusicFromText": "Adiidfjozj amuflzf crjlz ${NAME}", + "allMyFamilyText": "All of mzomf famif lwoh ljfljdf plzl telslfsf", + "codingGraphicsAudioText": "Cdjfozj, Gprhpaz, and Audouz bz ${NAME}", + "creditsText": " COdifid fjaosdjf aona dofii by Eric Froemling\n \n Andofi dsjoasdij dsjoi goingpoin arf Raphael Suter\n \n Snofl and Gramble:\n\n${SOUND_AND_MUSIC} Pblusd asfojasdfj idsfjif Musopen.com (ajfojsdfjfd oisdfjf fijf)\n Thalsjfisjdfoijsf US Army, Navy, and Marine Bands.\n\n Big fpsodfj sdf jdfoasdfij sadfodfj osdfj asdofiwef owefjwiefij foijf:\n${FREESOUND_NAMES} \n SPananf éfodjfij:\n Todd, Laura, arf Robert Froemling\n Al sjfoasd jfisfoas djsdfjsdfoiasdfjjfif\n Whala fjsdofjfisjoiajsjfoafo\n \n www.froemling.net\n", + "languageTranslationsText": "Langlaflzf Translafsjfldzl:", + "legalText": "Leglzfl:", + "publicDomainMusicViaText": "Pbfljzl-zmfmdf mufizlc vz ${NAME}", + "softwareBasedOnText": "Thz sofjtlzf iz blzlf inz prrltzl onz thfz wrkjzl ofz ${NAME}", + "songCreditText": "${TITLE} Perfofzf bzy ${PERFORMER}\nCmpzfjlz bzy ${COMPOSER}, Arrnafflzz byz ${ARRANGER}, Pbllffljfd bzy ${PUBLISHER},\nCrorjlzf ofz ${SOURCE}", + "soundAndMusicText": "Szfjogi & Muzifg:", + "soundsText": "Sndlfjz (${SOURCE}):", + "specialThanksText": "Spzjlfz Thznflz:", + "thanksEspeciallyToText": "Thzjflz epfojaflzf to ${NAME}", + "titleText": "${APP_NAME} Cojweoijwf", + "whoeverInventedCoffeeText": "Whozjfver invjlntlc cffzzre" + }, + "currentStandingText": "Yrz crrlf stnsff is #${RANK}", + "customizeText": "Cztmtlajfz...", + "deathsTallyText": "${COUNT} déathz", + "deathsText": "Déáthzs", + "debugText": "débúg", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Ntzl: itz iz rcmdmfdded thz yz st Sttnggljs->Grphafz->Texjfosijf to \"Hghz\" whlz tsttfng thiz", + "runCPUBenchmarkText": "Rn CPU Bnchfjmzk", + "runGPUBenchmarkText": "Rnz GPU Bnchmrmkz", + "runMediaReloadBenchmarkText": "Rnzl Mdidl-Rlzdd Bnchrmdkz", + "runStressTestText": "Rzn strzzlf tsts", + "stressTestPlayerCountText": "Plzearr Cntntz", + "stressTestPlaylistDescriptionText": "Strezz Tzets Plzltlsz", + "stressTestPlaylistNameText": "Plzlrjtls Nmlgz", + "stressTestPlaylistTypeText": "Plrntllst Tpzfm", + "stressTestRoundDurationText": "Rngjfzfl Drurnastnfn", + "stressTestTitleText": "Strnflz Tstz", + "titleText": "Bnchrmfsjf & Stffz Tsgsz", + "totalReloadTimeText": "Totalf rlslze tmz: ${TIME} (see log for details)", + "unlockCoopText": "Unzllfsf co-op lvlflsz" + }, + "defaultFreeForAllGameListNameText": "Dzfáult Féee-fzr-Azl Gámés", + "defaultGameListNameText": "Defaultz ${PLAYMODE} Plflzjlz", + "defaultNewFreeForAllGameListNameText": "Méz Fée-fzr-Azl Gázmes", + "defaultNewGameListNameText": "Mz ${PLAYMODE} Plzllst", + "defaultNewTeamGameListNameText": "Méz Táam Gézmes", + "defaultTeamGameListNameText": "Dzéaulzt Tzam Gámzz", + "deleteText": "Deferf", + "demoText": "Dmfwef", + "denyText": "Dénziy", + "deprecatedText": "Dowefowicjwer", + "desktopResText": "Dzlflfjz Rzflz", + "deviceAccountUpgradeText": "Wowierj:\nWofiwj c weojfw duo wdjfo weir are(${NAME}).\nDowjc weowje r ofjowei fjwoeodjfowdofijwodfjf.\nUpeworwe coweoijwV2 ocwoe roweijroidjjfj owejowejd.", + "difficultyEasyText": "Ezrz", + "difficultyHardOnlyText": "Hrdf Mdd Onflz", + "difficultyHardText": "Hrefz", + "difficultyHardUnlockOnlyText": "Th cowej fwojco wefj aweoiejroa doif aoef.\nDof coiejwo iefjowei ojcowijeofijeofjwef?", + "directBrowserToURLText": "Plzlsl dirzlt a wblf browlfer tz thz flzllng URL:", + "disableRemoteAppConnectionsText": "Disojf c woij ewof-app cowjf woejwe", + "disableXInputDescriptionText": "Allow mor wow ejo4 cow oeicjwo cobu oaf woejfowie jowrj", + "disableXInputText": "Dio cow eofwije", + "doneText": "Dónz", + "drawText": "Drawz", + "duplicateText": "DSFcoiwjef", + "editGameListWindow": { + "addGameText": "Aédd\nGzéme", + "cantOverwriteDefaultText": "Cznt oéerzwrzite thez dúfauzlt plzlltlz!", + "cantSaveAlreadyExistsText": "A pzlslfz wizh thz nmzl alrzdy exisrarz!", + "cantSaveEmptyListText": "Czn't sévze anz eptóy gze lúst!", + "editGameText": "Edzét\nGzme", + "gameListText": "Gámé Lzúst", + "listNameText": "Plzljlfz Nmflf", + "nameText": "Néáme", + "removeGameText": "Rzmóve\nGzmze", + "saveText": "Sézve Lzést", + "titleText": "Plzltls Edirtzlr" + }, + "editProfileWindow": { + "accountProfileInfoText": "Thi foic oiwe ofijaoijc oppoyw ofiuwo\nico coajob aon fcouaoir coa fosof\n\n${ICONS}\n\nCfocjo cuoso cporijfo oi you anav to sue\ndif o cjoiwnoam ooifon onrs.", + "accountProfileText": "(accfnsf profiofs)", + "availableText": "Thz nmff \"${NAME}\" if oviajvoi fof.", + "changesNotAffectText": "Nótez: chuznges wzll nót azfeét chzráctezrs zlready itze gúme", + "characterText": "chljraflzr", + "checkingAvailabilityText": "Chkfjofwi agavaifj for \"${NAME}\"...", + "colorText": "cólzr", + "getMoreCharactersText": "Gzl Mzrz Chrjafewerz..", + "getMoreIconsText": "Gzzt Mrrz Icnffz...", + "globalProfileInfoText": "Gllfoij coijw pefj acpoiwj poijf oienaowieoia oifof\nnaoim owfoijweof i. THofo oaicjoieoij ocnoso.", + "globalProfileText": "(glfjlic procjof)", + "highlightText": "híghlzght", + "iconText": "icfnfz", + "localProfileInfoText": "Lfjoci fplkw oijcwofj woeif owci owiej foiwjeofi wjeff\nnot oafij aoicjwoeiw ocjoaiw fow. Upfgra foicj oijofaf\nto ojovia cooijf wo oacj oiwejfo wfeoococ cjiocs.", + "localProfileText": "(lcllf proriocf)", + "nameDescriptionText": "Pléyzr Náme", + "nameText": "Núme", + "randomText": "rándzm", + "titleEditText": "Edít Prófílze", + "titleNewText": "Néw Prófílze", + "unavailableText": "\"${NAME}\" i coif owcij owejf; tra coain fname.", + "upgradeProfileInfoText": "Thofi cowie jfojroie osejo voeja;ofowfe\nand foajoai weft oayoucoait onto points.", + "upgradeToGlobalProfileText": "Upoifjo toi Glcojw efProicjoifjz" + }, + "editProfilesAnyTimeText": "(yoú cén údzt prófilzs át úny tíme úndzr 'séttinzs')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Czé't délzte défaúlz sóunztráck.", + "cantEditDefaultText": "Czn't ézit dzfáult sondtrack. Dzplícaze ít ór crezte á nów zne.", + "cantEditWhileConnectedOrInReplayText": "Cfn ef we souf oj woeh oconnnect ot jpa pray or oacnoefof wrpal.", + "cantOverwriteDefaultText": "Cún't ovarwréte dzfaxlt sóunztrack", + "cantSaveAlreadyExistsText": "A snfjdfzzf wzth thz nmxl alreeyx exisarsz!", + "copyText": "Cópy", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Dúfazlt Seóndtrúck", + "deleteConfirmText": "Dzléte Sóuzdtráck:\n\n'${NAME}'?", + "deleteText": "Dúléte\nSndfjflr", + "duplicateText": "Dúplízate\nSndfjrtrzkz", + "editSoundtrackText": "Dúléte\nSndjfrazk", + "editText": "Edjf\nSndfjarljrz", + "fetchingITunesText": "fétczing mUsic zppz plzylísts...", + "musicVolumeZeroWarning": "Wzrnízg: mísuc vólzme ús sét tó 0", + "nameText": "Nzmé", + "newSoundtrackNameText": "Mz Soundtrckz ${COUNT}", + "newSoundtrackText": "Néw Sóundztráck:", + "newText": "Neflw\nSnsdjralrz", + "selectAPlaylistText": "Sélézt A Pláylzst", + "selectASourceText": "Mzicf Srlfflz", + "soundtrackText": "SóuzdTráck", + "testText": "túst", + "titleText": "Sndflarrz", + "useDefaultGameMusicText": "Dfzlfl Gmzl Mzlgl", + "useITunesPlaylistText": "Miwefwef pdf pwefowef", + "useMusicFileText": "Mzlgl Flzl (mp3, tzz)", + "useMusicFolderText": "Fldlzr ofz Mzlfic Flzlz" + }, + "editText": "Edf", + "endText": "Enzf", + "enjoyText": "Enfjofjw!", + "epicDescriptionFilterText": "${DESCRIPTION} Ín ípic slúw mztíon.", + "epicNameFilterText": "${NAME} Epícz", + "errorAccessDeniedText": "acczlr dnfflz", + "errorDeviceTimeIncorrectText": "Yowruc cowier ij incorwjeof ${HOURS} horewif.\noitwocweojowerjiowejjjfwoef.\nPefjwe wehapeocjjgwghwe w e weofwoefjwe.", + "errorOutOfDiskSpaceText": "orz of dkzk spzlfz", + "errorSecureConnectionFailText": "Uweorcjwoef ojcowe werryyeoi nowe; jcnwoeroidfowdffdj.dfsdf.", + "errorText": "Errórz", + "errorUnknownText": "unknznlz errzzz", + "exitGameText": "$Excej ${APP_NAME}", + "exportSuccessText": "'${NAME}' woejpcj", + "externalStorageText": "Extzljrzl Stjrfjzfgz", + "failText": "Fáilz", + "fatalErrorText": "Uz Hofwco wije fowiejf weoifw oef.\npc oef owjcoije ow f wco weofijweo\ncontcat ${EMAIL} fo cowijef.", + "fileSelectorWindow": { + "titleFileFolderText": "Slct a Flzl orz Folzlfld", + "titleFileText": "Slzlclt a Flzlf", + "titleFolderText": "Slzlctz a Fldldfrz", + "useThisFolderButtonText": "Uslz Thizl Fldlrz" + }, + "filterText": "Fjlfowif", + "finalScoreText": "Fínúl Scóze", + "finalScoresText": "Fínúl Scórez", + "finalTimeText": "Fínál Tímz", + "finishingInstallText": "Fbfhaifweuhf Ubsfkasfhdzl onz mmfomasf...", + "fireTVRemoteWarningText": "* Frz z brttlrz wpzjoirzrz, rrz\nGmfj Cnoroajflz rz inglnzf thz\n'${REMOTE_APP_NAME}' app on yrz\nphzjfz anz tbljrzz.", + "firstToFinalText": "Fírzt-tú-${COUNT} Fínzl", + "firstToSeriesText": "First-to-${COUNT} Séréz", + "fiveKillText": "FÍVÍ KZLL!!!", + "flawlessWaveText": "Flúwlzés Wúví!", + "fourKillText": "QÚZD KÍLL!!!", + "freeForAllText": "Fzée-fúr-Azll", + "friendScoresUnavailableText": "Fríénd scóres unávailáblz.", + "gameCenterText": "Gzmz Centerlz", + "gameCircleText": "GamzCírclz", + "gameLeadersText": "Gámé ${COUNT} Léádérs", + "gameListWindow": { + "cantDeleteDefaultText": "Cán't délzte thú défazlt gáme lést!", + "cantEditDefaultText": "Cázn't édit tze défazlt gázme líst! Dúpléczte ít ór créute á néw óne.", + "cantShareDefaultText": "You w wolf wi eofw ec woef ef.", + "deleteConfirmText": "Dzléte Gázme Lísz: ${LIST}?", + "deleteText": "Deletaz\nPltjalsfz", + "duplicateText": "Dupclilar\nPlsfjalfiz", + "editText": "Ezltjf\nPlaflfzlz", + "gameListText": "Gzéme Lízt", + "newText": "Núw\nPlzlrlrzl", + "showTutorialText": "Shzwlf Trltlrjlzjf", + "shuffleGameOrderText": "Shúfflze Gáme Oéder", + "titleText": "Cmtlajrz ${TYPE} Plzlsfwz" + }, + "gameSettingsWindow": { + "addGameText": "Adf Gámé" + }, + "gamepadDetectedText": "1 glmpgpoz detcalfjfz", + "gamepadsDetectedText": "${COUNT} gmdpfzj dtecjterd.", + "gamesToText": "${WINCOUNT} gámzs tú ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Rmgrar z: anzl flje oa aosdfj oaisjdf oaif jewf\nocn cncontjalf iznf foyocu ltafh aconcotrlz.", + "aboutDescriptionText": "Uzl thafl tbs tz assmdlb a pratlzf\n\nPrlajtla lz yzz plz zglmfl and rarntalnflf\npw hfo o fjalr anafdlcl aro doijffljz\n\nUsz thz ${PARTY} bttnz antz tha fpz arnafl tz\nchrhz antz ntinaf c inwhat ptohr\n(ons a cntafljar, przlz ${BUTTON} whz inz a mnf)", + "aboutText": "Abffnlz", + "addressFetchErrorText": "", + "appInviteInfoText": "Ivnir afoc weoif acj w;oejf ;owej owef\ngzt ${COUNT} frr ztoijco . Youcl rlrlrjz\n${YOU_COUNT} frz coe cow eofjwoefs.", + "appInviteMessageText": "${NAME} fwoj fojwc ${COUNT} tijowfi iz ${APP_NAME}", + "appInviteSendACodeText": "Sndf Thm a Cdofoz", + "appInviteTitleText": "${APP_NAME} App Invoff", + "bluetoothAndroidSupportText": "(wrks thz andf Andrjef dvcewf supportsf Blzltahofs)", + "bluetoothDescriptionText": "Hzt/jnz a prrty overer Blzthffz:", + "bluetoothHostText": "Hzts overz Blztnfhfz", + "bluetoothJoinText": "Jnzlz voer Blthfhogz", + "bluetoothText": "Blztthzz", + "checkingText": "chzckinggz..", + "copyCodeConfirmText": "Cdf cpodf to clfjoifjz.", + "copyCodeText": "Cpoef Cwfdf", + "copyConfirmText": "COpic for cowejwdf.", + "dedicatedServerInfoText": "For code wocj woiejfowiejf, loci joweijf owiejfw. Se eocwj efowiejo wcoweijf woeifowoco er.", + "disconnectClientsText": "Thz wlzl dicntjf thz ${COUNT} pljflaf (s)\ninc yrrz prthra. Arz yrz fsrru?", + "earnTicketsForRecommendingAmountText": "Fofofj oicow ${COUNT} ocwjoe f cow ef woefje\n(aocweo fwjoefi jo${YOU_COUNT} cowiejfowi oie)", + "earnTicketsForRecommendingText": "Shz thz gom \nfo cowiej coiwoij...", + "emailItText": "Emcofj It", + "favoritesSaveText": "Sfewoe AL FJOciwefd", + "favoritesText": "Fwewfoiwjfd", + "freeCloudServerAvailableMinutesText": "Nwoeif cowej ocijewa;sjvwe gjzowei jcij ${MINUTES} wocjiwof.", + "freeCloudServerAvailableNowText": "FJwo coin cod owij ijowiwer!", + "freeCloudServerNotAvailableText": "NFo woe. cowej oicjoerowijrd.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} toijcoif cowf ${NAME}", + "friendPromoCodeAwardText": "Yz rceive ${COUNT} tofjow cowe cowejfow jefowei.", + "friendPromoCodeExpireText": "Thz cof wolfl wcpof jin ${EXPIRE_HOURS} hcouwf aono wijfo wjeoiwjfjpo pfsfs.", + "friendPromoCodeInfoText": "It ooijc wolf woiwjeoef ${COUNT} ocjowef.\n\nTz fowl \"Settings->Advanced->Enter Promo Code\" ice wefowcj weofjweoif \nZzz bombsquadgame.com cow efoiwcej woejf woeifjowef.\n awe oiwjefowej owejf ${EXPIRE_HOURS} ;ofj ;woiefj ;oweijf ;woiej", + "friendPromoCodeInstructionsText": "To Us ocj , ofijwe ${APP_NAME} oafn aco\"segoingaf- aocij weoifjwoe fowiejoijcowijcoiwjef.\nSee ofjc oiwejfowje foajfo weofjodijf oiasjgo isjdfo ijaweoijfowije oiwjoifjw.", + "friendPromoCodeRedeemLongText": "It cnf vow weofjwoefi joef ${COUNT} ffoij cowijetoi cwoiej fo ${MAX_USES} pcojfofz.", + "friendPromoCodeRedeemShortText": "It cnf br coefwf fwfof ${COUNT} toico foin ciwfj gmes.", + "friendPromoCodeWhereToEnterText": "(inz \"Settdfings->Adwefwced->Eftcer Codze\")", + "getFriendInviteCodeText": "Gz Frjor Infivo Cdz", + "googlePlayDescriptionText": "Invlt Gglglz Plzlz plzlfer tz yzr prtaryz:", + "googlePlayInviteText": "Invtlzz", + "googlePlayPurchasesNotAvailableText": "JGowej eo owe weoirjweorjf\nYou we r wcowehpaw ecowjeoiwjrperpp.", + "googlePlayReInviteText": "Tnz arzs ${COUNT} Gflf Plzz Plalfjdsf oin weojf wfeoyowiufe\nwhiz ewofij woijdoisoic o asodf wfiawje;aoew aoiwfj.\nTIncowjf oweofjao wotonwei oiacoiw eotijweto tat.", + "googlePlaySeeInvitesText": "Szz Invtlfz", + "googlePlayText": "Gzzlg Plz", + "googlePlayVersionOnlyText": "(Glfl plz versofj coniclfn)", + "hostPublicPartyDescriptionText": "Hewf obj cowijefijdf", + "hostingUnavailableText": "Hweoiwe Unvavoiejfsd", + "inDevelopmentWarningText": "WRNRLJFF\nNt-f psfdo asdj PREPP OE vojoi oweifj owjj.dsas\nFRofj woviow ejpfoiwejf paoij oiwjecojwofj\naojfo aijwco wijeowjf oaijfo jwoefijwoeifj", + "internetText": "Off", + "inviteAFriendText": "FO jwfo wcej owiejf woijf;aowei jf;aowiej;w\ntowyfaoijcowe foaiwj oweijf ${COUNT} fowifj icirks.", + "inviteFriendsText": "Invofj Frirnzz", + "joinPublicPartyDescriptionText": "Jej cw cjwtiefjddj", + "localNetworkDescriptionText": "Jej c Cowej jwei (LDF Clewr , jtwoc)", + "localNetworkText": "Lczflz Nworkrz", + "makePartyPrivateText": "Mk Mow ojpowefjpowjeof", + "makePartyPublicText": "Mk PmY pcowej oacjo wei", + "manualAddressText": "Addrraz", + "manualConnectText": "Cnnzgmc", + "manualDescriptionText": "Jnzlz a prrt brz adrarfs:", + "manualJoinSectionText": "Jwe cowe Afwojicd", + "manualJoinableFromInternetText": "Arz zy joing frmz the winterrws?", + "manualJoinableNoWithAsteriskText": "NZ*", + "manualJoinableYesText": "YZF", + "manualRouterForwardingText": "*tz fgj thzf, tafh confiefjao ayoru routheoafe jfor dsf UDP prt ${PORT} tz yoru local addrrz", + "manualText": "Mnfrulz", + "manualYourAddressFromInternetText": "Yrrz adrar frmz thz internefat:", + "manualYourLocalAddressText": "Yrrz lcl addratrz:", + "nearbyText": "Woiwjefd", + "noConnectionText": "", + "otherVersionsText": "(otco verosfjso)", + "partyCodeText": "Prewjr Cdfew", + "partyInviteAcceptText": "Acczlfp", + "partyInviteDeclineText": "Dclflz", + "partyInviteGooglePlayExtraText": "(szz thz 'Gllglz Plz' tab in the 'Gthfz' wndfj)", + "partyInviteIgnoreText": "Ignfjz", + "partyInviteText": "${NAME} hz invite yz\nto fjoia f fatpartyz.", + "partyNameText": "Poijf OFwoe j", + "partyServerRunningText": "YCowef pvpwerd sev srwerfrzz.", + "partySizeText": "pwtoifj cowief", + "partyStatusCheckingText": "cjoefij cowijefo weft...", + "partyStatusJoinableText": "your cp woefj cow efoajpocjwoe rowijcowijer", + "partyStatusNoConnectionText": "oefj wow jeojrowiejr", + "partyStatusNotJoinableText": "yrowu coe apweo c ojoicowiejoriwodnfdf", + "partyStatusNotPublicText": "your two cow eijowenotcb", + "pingText": "pow", + "portText": "weft", + "privatePartyCloudDescriptionText": "Prewer wpoijer ceo wocj oewdejifoiej cloudf sr wpcoiwje ; ow cowuoru concijowie ocojfwd.", + "privatePartyHostText": "Hoc f cpOer Poweirjd", + "privatePartyJoinText": "Jweorj c po wer Powert", + "privateText": "Prwoecd", + "publicHostRouterConfigText": "The Eocene fowl woes wow poirotoww-e wow vcowejaopoiefj ov oiwje. For www owej odd. cowiejowier p fjfowj paper.", + "publicText": "Pcowijefd", + "requestingAPromoCodeText": "Roifjo jc a promco fojror...", + "sendDirectInvitesText": "Snd Direoc Invirrzz", + "sendThisToAFriendText": "Snd roij coij to fowo owijr:", + "shareThisCodeWithFriendsText": "Shzrr tiz crrd thtf fforjrz.", + "showMyAddressText": "Show oe cow eijfwef", + "startAdvertisingText": "Stasi Advoierowijrz", + "startHostingPaidText": "How cow fi 4t j ${COST}", + "startHostingText": "Hfwef", + "startStopHostingMinutesText": "You co e weorij c obj ads. cowej w oerjw cjwejcwoijrewrs ${MINUTES} ocwiejrd.", + "stopAdvertisingText": "Stop Aodvoierz", + "stopHostingText": "Staff Hororwd", + "titleText": "Gthzrz", + "wifiDirectDescriptionBottomText": "Ifz allz dvicoew hfz a 'WOFJFJ JDf pnc, thoo asdhousdfl lboeij woife oiuzeufnd\nand conecwn to fhaoeiof Onc alz eodoeiv ad caoocnornct, yz can bpzl afprt\naowihe and comlcoa lntoweij ftab, jowf asdms reag awe fiw fnweorwerwekr\n\nFzr befj weojwea, wowf oaf dsfoac aosidjf oasdjf oajsdf ${APP_NAME} party fhofz.", + "wifiDirectDescriptionTopText": "Wjf a can def ajsfd lajsd flakjsdflsdljoiwjef oiwjef oaje ofijwe foijwfe\nnednf and andfoidjf wane two thou foiwa eoiANdo irjo 4.1 or manor.\n\nTh ojfwo uousdf, Opn Witi foiwefoij oiad asd;o awofjweoijfo iwjmne..", + "wifiDirectOpenWiFiSettingsText": "Opnz WifZ Snnfaz", + "wifiDirectText": "Wz-Fz Dract", + "worksBetweenAllPlatformsText": "(wrorkz btwflf alz pltafmmrs)", + "worksWithGooglePlayDevicesText": "(wlokrlz thf divcie srnngaf thz Gllglz Plz (android) gvjerajf ofz thez gmz)", + "youHaveBeenSentAPromoCodeText": "Yo hv ofj wcasn a ${APP_NAME} pwofj wcode:" + }, + "getCoinsWindow": { + "coinDoublerText": "Cznn Dnblzrz", + "coinsText": "${COUNT} Cnfjflz", + "freeCoinsText": "Frzz Cntnz", + "restorePurchasesText": "Rzatlsf Pncharlrzz", + "titleText": "Gzt Cnflzz" + }, + "getTicketsWindow": { + "freeText": "FRZZ!!", + "freeTicketsText": "Frzz Tkkckztz", + "inProgressText": "A tnfajocj in nfo cpoaro fl p lejfaowf oit agiosd fomoemnt.", + "purchasesRestoredText": "Pfojfofjf resotores.", + "receivedTicketsText": "Recvnrrd ${COUNT} rclfjsf!", + "restorePurchasesText": "Rzsgrrz Prchfrrtz", + "ticketDoublerText": "Tckfkrz Dblrrerz", + "ticketPack1Text": "Smllz Tckrt Pck", + "ticketPack2Text": "Mdmfm Tkfkf Pck", + "ticketPack3Text": "Lrggl Tkcct Pck", + "ticketPack4Text": "Jmfpmf Tkckf CPkf", + "ticketPack5Text": "Mmthf Tckff Pckc", + "ticketPack6Text": "Ulzjtla Tkckdf Pck", + "ticketsFromASponsorText": "woejwoe c woeijweo\ncowjeo ${COUNT} weocjw", + "ticketsText": "${COUNT} Tckrtzz", + "titleText": "Gtz Tckrtz", + "unavailableLinkAccountText": "Srryrc, cpofj caodn oiwrj coi weo joweijwoief.\nIf wc woiejf w, cocwi eoiaoth aciw jeojfow iejoijwef\npcoj weo faona omowio wejfowijerwe.", + "unavailableTemporarilyText": "Thz iz cjrntelr unvalijrlwif; plz tarz agagnzl pttzzrz.", + "unavailableText": "Srrz, thz is nz avoarjowwz.", + "versionTooOldText": "Srrr.z haf voij eowij fowj aoig;o wido; ojep aowefj owepaidsof oefwoef.", + "youHaveShortText": "you hv f ${COUNT}", + "youHaveText": "yz hv ${COUNT} tickrrz" + }, + "googleMultiplayerDiscontinuedText": "Sowoer Gojf wel wouwen weoioc long wf won.\nI wow oe wefwjr pif g wfpawouja c oeij fw ocjaoiejowr.\nUntil. cowier oa j fapefij cpoypt ao coonnec awoiery.\n-Ercff", + "googlePlayPurchasesNotAvailableText": "Weofiiwj woe woerd wieofjwe\ncome foe rj eofiaj cpwoe jrowjer..dd", + "googlePlayServicesNotAvailableText": "GOowf cpw ef A coweij woerj.\nWomb woof cape wgwoijc we coowiejrerdss.", + "googlePlayText": "Gzzggl Plzz", + "graphicsSettingsWindow": { + "alwaysText": "Azlwáys", + "autoText": "Aúto", + "fullScreenCmdText": "Fúllézreen (Cmd-F)", + "fullScreenCtrlText": "Fúlzcréen (Ctrl-F)", + "gammaText": "Gámza", + "highText": "Hígh", + "higherText": "Híghrz", + "lowText": "Lózw", + "mediumText": "Mzdíum", + "neverText": "Névzer", + "resolutionText": "Résólution", + "showFPSText": "Shów FPS", + "texturesText": "Téxzures", + "titleText": "Gézphícs", + "tvBorderText": "TV Bórdzr", + "verticalSyncText": "Vértícal Sync", + "visualsText": "Vísuzls" + }, + "helpWindow": { + "bombInfoText": "- Bmmbb -\nStzzzfgr thff pzzfjnch, bfft\ncfn rssltf inf grazzf sfff-injjoiury.\nFr bfzst refuzzts, thzz tzzzff\nenfffmy bezzfere fuése rzs outffz.", + "bombInfoTextScale": 0.6, + "canHelpText": "${APP_NAME} cjo cweoff", + "controllersInfoText": "Yz can fj plsjdf ${APP_NAME} osfasfoiajwefoa soadfove rhte nwgo\ncan fpdalsdf asoifn aodifoeub weofa faodo aoocnaotorlers.\n${APP_NAME} ucouspod ra voarar elfoaf othw. yo aoidf ands ven ae\na sd controajjsdefowfj boijg ${REMOTE_APP_NAME} app\nse t adsoenga;odva;ocntrononrod fomr orminfo.", + "controllersInfoTextFantasia": "Onfe ojfr twjo ploayers cjan usje tjhe keyoiboard, bjut BombjjSquad ifs bfest width gamjepads.\nWiimotejs, adnd iOS/Android devfdsfs to condsdfrol chasdfcters. Hopezzfully you havesf\nsomef of thesfe handffy. See 'Controllefdrs' undzer 'Settinfewgs' fofr moree inefo.", + "controllersInfoTextMac": "Onfe ojfr twjo ploayers cjan usje tjhe keyoiboard, bjut BombjjSquad ifs bfest width gamjepads.\nBombSqufad cajn ufe USB gamepd, PS3 codzntrollers, XBsox 360 codsfnolers,\nWiimotejs, adnd iOS/Android devfdsfs to condsdfrol chasdfcters. Hopezzfully you havesf\nsomef of thesfe handffy. See 'Controllefdrs' undzer 'Settinfewgs' fofr moree inefo.", + "controllersInfoTextOuya": "Yzz czf usfd OUYA contdsfasdf, PS3 conconafdsf, XBox 360 coancofffnf,\nafg ladsf of ofafsdf USB and Bluetooth gamepdfhfj with BombSquadz.\nYouf canzz alssf use ijOS aknd Androioid dejoivices as cojjntrollers vjia thej fjree\n'BombSquadj Remoftef' appf. Seef 'Controllerss' underz 'Settinfgsf' fozr mosre inffo.", + "controllersInfoTextRemoteOnly": "Yeof ocowef ${APP_NAME} owejc oefw eoeo owjocejore,\npower cue afoot focjeo foweifjwoeh coweifowpa oghwoef\ncocwoejrw. cow;oiwjrweirw '${REMOTE_APP_NAME}' apz.", + "controllersInfoTextScaleFantasia": 0.56, + "controllersInfoTextScaleMac": 0.58, + "controllersInfoTextScaleOuya": 0.63, + "controllersText": "Czontrollzerssz", + "controllersTextScale": 0.63, + "controlsSubtitleText": "Yzjfo frrizjfly ${APP_NAME} czlfharcter hasf af fzew bzsic acsszzzcténs:", + "controlsSubtitleTextScale": 0.7, + "controlsText": "Czfontrollzz", + "controlsTextScale": 1.4, + "devicesInfoText": "Thz VR vojeora fo ${APP_NAME} afsdcn ab asdfpladf oasdjfaoveornt\nthwa oefia oerj avoae a;oi joaje fo wfja wfj asodf ;aosj ;af\nand acoapute randf amge aw asm con aofdi jas; oa;oinc;oianr\noncoain;d a; f;a owerj;aogiu;goau;o a;odi a;osidf oto joust\nconasdf as dnl ob pwero pacoi joaijtoiajt.", + "devicesText": "Dvnlfz", + "friendsGoodText": "Frizjdzofs gozn gnno godr poof. ${APP_NAME} za funzzgoo da sevvrzsll playerszgo\nanff supportgo up to 8 at argo time, which leadszfoo usz tof:", + "friendsGoodTextScale": 0.6, + "friendsText": "Friendificzs", + "friendsTextScale": 0.6, + "jumpInfoText": "- Jzzum -\nJumjfp t crodfssfsmall gzps,\ntothroéw thzfjgs farthff, ando\ntof eresffés feezzclings ofjoy.", + "jumpInfoTextScale": 0.6, + "orPunchingSomethingText": "Or punching something, throwing it off a cliff, and blowing it up on the way down with a sticky bomb.", + "orPunchingSomethingTextScale": 0.5, + "pickUpInfoText": "- PizzckUp -\nGrazb flffgs, znemies, or anffhing\nezse notolted toz fji groffnd.\nPresz againf tofféthrow.", + "pickUpInfoTextScale": 0.6, + "powerupBombDescriptionText": "Thf sdf asodjafds sdfosj fosfj\njfoiadf oiisfj owefj aweofj owfj.", + "powerupBombNameText": "Tr asdf Bzzfzz", + "powerupCurseDescriptionText": "Yousd ofjafj osjfj jsis fjiji\n ...orz dfo yodsffu?", + "powerupCurseNameText": "Czzrse", + "powerupHealthDescriptionText": "Rah dsflaj fdhfoifi.\nR dsfojasdofijdsf jfffjf.", + "powerupHealthNameText": "Mzfsdf fff", + "powerupIceBombsDescriptionText": "Walfkjaf dsojsdfj\nbjaosdf jfoasdfj sfdj sdfij\nland foif goaoif.", + "powerupIceBombsNameText": "Icz Fjfiwf", + "powerupImpactBombsDescriptionText": "Osjdf asdofjsdfjifjoasdfj\nobjsd, poig fjidfso fimpac ff.", + "powerupImpactBombsNameText": "Trasdf-Bozmbs", + "powerupLandMinesDescriptionText": "Thsojfi fojsofj of threosfj\nUsefjfojs ofo bjbos\nstoiz fo bosoijji.", + "powerupLandMinesNameText": "Lzjfo-Minfof", + "powerupPunchDescriptionText": "Mzaz yffr pzzches zfffr,\nfzzzrsr, ssbsr, stééger.", + "powerupPunchNameText": "Bzzxing-Gzzoves", + "powerupShieldDescriptionText": "Abslablh sdlfjaisfd fjfo fo sadoijad sf sdfjosaidjf.", + "powerupShieldNameText": "Ezzgy-Szfield", + "powerupStickyBombsDescriptionText": "Sticjf asdofjidf jfjj\nHoidfjfjhll", + "powerupStickyBombsNameText": "Stifiziz-Bzbs", + "powerupsSubtitleText": "Ozf courffse, nof gzme izs cozzlete wizzzut possfaups:", + "powerupsSubtitleTextScale": 0.8, + "powerupsText": "Pzioowers", + "powerupsTextScale": 1.4, + "punchInfoText": "- Pzznch -\nPuzfjoi dof mosefre damafsdfe thfe\nfasdfer yzr fsdfts af mfffng, so\nrzn and szzin lizz a mffffs.", + "punchInfoTextScale": 0.6, + "runInfoText": "- Runf -\nHolf ANZY buttonfo tof runz. Shoullzder buoions workzwell eeifu havfe thez.\nRfzunning getssyou plaffz fastfro butk makezos thaozrd to turnzo, sofjwatch out for cljoiwiffs.", + "runInfoTextScale": 0.6, + "someDaysText": "Sasdfasdf days ydfadf just feelz ldfasdf pujnlching something. Or bzjlowing ztosmethign upz.", + "someDaysTextScale": 0.55, + "titleText": "${APP_NAME} Hfzlf", + "toGetTheMostText": "Tzo grtt thrr mosta oufo zeez gammezsnort, youzl'll needzgo:", + "toGetTheMostTextScale": 0.8, + "welcomeText": "Wwocjowe to ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} isa nfojfo efj emnz klk fj voij -", + "importPlaylistCodeInstructionsText": "Ou o who far cj owejow o woefj aoc oapo paoel cwewer.", + "importPlaylistSuccessText": "Imps wef ${TYPE} cow e ${NAME}", + "importText": "Icwefwe", + "importingText": "Imcowiew..", + "inGameClippedNameText": "ic weof owef\n\"${NAME}\"", + "installDiskSpaceErrorText": "ERROR: Unzlbj ao ppc pwef oj oinosjs.\nYos may aoefo wocw oeitjoidosdfdve.\nCjfewf wocjdo spac ando ro gaing.", + "internal": { + "arrowsToExitListText": "préss ${LEFT} ór ${RIGHT} tó exút lzst", + "buttonText": "béttzn", + "cantKickHostError": "You loci woof woeijcoonh.", + "chatBlockedText": "${NAME} is fwocj woefj woeifj ${TIME} cowejof.", + "connectedToGameText": "Jowiejwf '${NAME}'", + "connectedToPartyText": "Joined ${NAME}'s parthrlz", + "connectingToPartyText": "Cnncttaignz...", + "connectionFailedHostAlreadyInPartyText": "Cnfnecn fjlzlkefe; hzfj iz fjn fnoanowpar ry.", + "connectionFailedPartyFullText": "Coiwje woie fow. oijwfo woecowefu.", + "connectionFailedText": "Cnnflg fnldkfd.", + "connectionFailedVersionMismatchText": "Cnndcat flld; hfdfj orurn sd adoifdoifj oawe ve;woirodfj osdf the gaz.\nMk fowie cowie fowi coc woef woiejfoiafosid oaisdf.", + "connectionRejectedText": "Cnndmcat rnecjected.", + "controllerConnectedText": "${CONTROLLER} czfznnected.", + "controllerDetectedText": "1 cnototlrlfz dtecttzff.", + "controllerDisconnectedText": "${CONTROLLER} dizcénnectud.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} diszcénezctz. Pléaze tréy coznéctíng agáín.", + "controllerForMenusOnlyText": "Thoc weo woef woecowje ofj; cow eocijwoejowiejofj.", + "controllerReconnectedText": "${CONTROLLER} récónnzécted.", + "controllersConnectedText": "${COUNT} czntlafjorrz cntjafoctd.", + "controllersDetectedText": "${COUNT} czntafjlrifl dtctatcz.", + "controllersDisconnectedText": "${COUNT} cntjofaifz dscrontctdz.", + "corruptFileText": "Cppro ff jfosjf dtecoewf w Plz wtoy finwocei wo iefj ro emaf ${EMAIL}", + "errorPlayingMusicText": "Error plzling muicf: ${MUSIC}", + "errorResettingAchievementsText": "Unzlbl tz rezerlz onzlflz achivirmvnrz; plz trz agnz ltrz.", + "hasMenuControlText": "${NAME} owjie. woejf owc.", + "incompatibleNewerVersionHostText": "Howe c ow ego inc wejoijwe ofijweof.\nUps who who ineoifjwoc woejoiw ejorwer.", + "incompatibleVersionHostText": "Hstn iz rningf a difefer ver ejoaf of thz gmz; vn't cndnocet.\nMkf woeic woefj owe cwefowfo woeowei oijtwf.", + "incompatibleVersionPlayerText": "${NAME} iz nfowij f and ifid fioew af versino af oidf c acnat aonncect.\nMk weocijw efow oc awejfowj eojcoiwjeojroewjf.", + "invalidAddressErrorText": "Errrlr; Invalidjf arrddrrs.", + "invalidNameErrorText": "Errr: coijwef noamwef", + "invalidPortErrorText": "Ero cowej woepor.", + "invitationSentText": "Invitiadf sendt.", + "invitationsSentText": "${COUNT} invitaosfod sdnt.", + "joinedPartyInstructionsText": "A frnsd azh joinfiwef yr prtr.\nGz tz 'Plaz' tz start a gmfz.", + "keyboardText": "Kéybzard", + "kickIdlePlayersKickedText": "Kkgjgf ${NAME} frz bnglfz idlzf.", + "kickIdlePlayersWarning1Text": "${NAME} wllz bz kfkzfl in ${COUNT} scirzlr if stfzl idlfz.", + "kickIdlePlayersWarning2Text": "(yz cnz trzn offz inz Sttnglgz -> Advnffzd)", + "leftGameText": "Lefzf '${NAME}'", + "leftPartyText": "Left ${NAME}'s prtatz.", + "noMusicFilesInFolderText": "Fldrz contlfzl nz mzlfig fizlflz.", + "playerJoinedPartyText": "${NAME} jfnd th z parrty!", + "playerLeftPartyText": "${NAME} lft thz party.", + "rejectingInviteAlreadyInPartyText": "Rjcjofe invljf (lweljf cojwe aoaf)", + "serverRestartingText": "Sereo s ewe Lowe. Plwfjw cow erwoejowi domoewner...", + "serverShuttingDownText": "Srjwvoe soc oie weoi ojsldfwef...", + "signInErrorText": "Errlr zinging inf.", + "signInNoConnectionText": "Unzlbl tz fsing fina f(no intnerlafj conencetion?)", + "teamNameText": "Tzlljm ${NAME}", + "telnetAccessDeniedText": "ERZOR: uzér hzs nát grúntzd télnzt accéss.", + "timeOutText": "(tímes óut zn ${TIME} seconds)", + "touchScreenJoinWarningText": "Yz hv jofndsf woijt iafh doctoucohdsf.\nIf oth dfawas do oasdf osdft mwne owijf oadsjf.", + "touchScreenText": "TóuchScrzén", + "trialText": "tríál", + "unableToResolveHostText": "Error: cow e fwjeociwjeorir.", + "unavailableNoConnectionText": "Tho fiw ficj woiejf paowejf (no itnwotower connecotjs?)", + "vrOrientationResetCardboardText": "Us this to weoojeif co VR owfjow ego\nTz pc we fwotj oa ocw eoowf eo awoifoacoincwr.", + "vrOrientationResetText": "VR ooiwjfowif rnefz.", + "willTimeOutText": "(wzlf tmz oat if idle)" + }, + "jumpBoldText": "JZMP", + "jumpText": "Júmp", + "keepText": "Kéepz", + "keepTheseSettingsText": "Kéép thúse síttzngs?", + "keyboardChangeInstructionsText": "Dlbjwf pcowej spec wot cioci ckdosrs.", + "keyboardNoOthersAvailableText": "No code vojwdfkdjcoi osjofwjefs.", + "keyboardSwitchText": "Wjcwoeif cjowefi oto sj \"${NAME}\".", + "kickOccurredText": "${NAME} weir eowifjwoe.", + "kickQuestionText": "Kfoicj ${NAME}?", + "kickText": "Kcwef", + "kickVoteCantKickAdminsText": "Afwoif opowij weka kcijksfd.", + "kickVoteCantKickSelfText": "You cow er wodfijw eofoydf.", + "kickVoteFailedNotEnoughVotersText": "No wc weo ra;so asdpaj cowier.", + "kickVoteFailedText": "Kfeoiw-vofj flwjef", + "kickVoteStartedText": "A cjf co cow ef woa c ocwjeo jwof ${NAME}.", + "kickVoteText": "Voice woes ocowieki", + "kickVotingDisabledText": "Kcjow cowejfdf owdofijwd.", + "kickWithChatText": "Typ ${YES} oef cwoiejf owe ${NO} fojw c.", + "killsTallyText": "${COUNT} kíllz", + "killsText": "Kíllz", + "kioskWindow": { + "easyText": "Ezrz", + "epicModeText": "Epcz Md", + "fullMenuText": "Fllz Menuz", + "hardText": "Hrzzd", + "mediumText": "Mddnfmz", + "singlePlayerExamplesText": "Snflgj Plzlrz / Co-opz Exmapflz", + "versusExamplesText": "Versuz Exmapez" + }, + "languageSetText": "Lngofijf isa tnsfl ${LANGUAGE}", + "lapNumberText": "Lzp ${CURRENT} ofz ${TOTAL}", + "lastGamesText": "(lász ${COUNT} gámúz)", + "launchingItunesText": "Lznching iTnzlflz...", + "leaderboardsText": "Lezérbórdz", + "league": { + "allTimeText": "Allz Tmz", + "currentSeasonText": "Currngjg ZSfowife (${NUMBER})", + "leagueFullText": "${NAME} Lfjofz", + "leagueRankText": "Lglfl Rnrka", + "leagueText": "Lggfzf", + "rankInLeagueText": "#${RANK}, ${NAME} Lzlglf${SUFFIX}", + "seasonEndedDaysAgoText": "Sfsf endf f ${NUMBER} fjosf afoc.", + "seasonEndsDaysText": "Sfowefj wfn dofi ${NUMBER} dfjowf.", + "seasonEndsHoursText": "Swso fo jiwf woie${NUMBER} fowhfz.", + "seasonEndsMinutesText": "Seaonf woeo cowi fj${NUMBER} mcoinwefoij.", + "seasonText": "Seocwofj ${NUMBER}", + "tournamentLeagueText": "Yzz mff erwr ${NAME} leg foic woefin woef oeijfwfew.", + "trophyCountsResetText": "Trphy cofo wuecw owef owioiafowf." + }, + "levelBestScoresText": "Bsfwo cowiejo ef${LEVEL}", + "levelBestTimesText": "Best wfm coi ${LEVEL}", + "levelFastestTimesText": "Fztjst tmzf on ${LEVEL}", + "levelHighestScoresText": "Hghglz scorlz on ${LEVEL}", + "levelIsLockedText": "${LEVEL} ís lúckzd.", + "levelMustBeCompletedFirstText": "${LEVEL} múst bz cómplztíd fúrst.", + "levelText": "Lvfjosfi ${NUMBER}", + "levelUnlockedText": "Lévzl Unlóckzd!", + "livesBonusText": "Lívzs Bónús", + "loadingText": "lztijding", + "loadingTryAgainText": "Lcowejf c weoifj wecoi woeijo...", + "macControllerSubsystemBothText": "Both (eco woicowijef)", + "macControllerSubsystemClassicText": "Cladsfsf", + "macControllerSubsystemDescriptionText": "(tic oc woef. coli hoi ogief eer woeofowiejfoj)", + "macControllerSubsystemMFiNoteText": "Mwoe cw obj c woe kiwi eoijwe;\nYou wo. och weil foeiwjf oiwjc owije - > COijowiejfs.", + "macControllerSubsystemMFiText": "Mcojwe-coj-cwoejowif", + "macControllerSubsystemTitleText": "Coijcw oijSuporer", + "mainMenu": { + "creditsText": "Crizetzzts", + "demoMenuText": "Dmzm Mnzz", + "endGameText": "Enzs Gzmé´fez", + "endTestText": "Erj coiwjef", + "exitGameText": "Excczzt Gamzzéé", + "exitToMenuText": "Exít tzú ménu?", + "howToPlayText": "Hwopm T´wPlayynf", + "justPlayerText": "(Jzft ${NAME})", + "leaveGameText": "Lvffz Gmmz", + "leavePartyConfirmText": "Rellr lvvz thz parrttyz?", + "leavePartyText": "Lvvz Prttzz", + "leaveText": "Lvveeaavv", + "quitText": "Qztiiizt", + "resumeText": "Rssmzmmee", + "settingsText": "Staettengis" + }, + "makeItSoText": "Mrazzk itzz Séooee", + "mapSelectGetMoreMapsText": "Gzzt Mrrz Mppz...", + "mapSelectText": "Sélézt...", + "mapSelectTitleText": "Mápz dú ${GAME}", + "mapText": "Mázp", + "maxConnectionsText": "Mc COnoweijwer", + "maxPartySizeText": "McCoy cpweo fwocwoef", + "maxPlayersText": "Mx Plweffz", + "merchText": "Mower!", + "modeArcadeText": "Aroc Mofwfz", + "modeClassicText": "Cjwofej mDofd", + "modeDemoText": "Dfwocij Mmdff", + "mostValuablePlayerText": "Móst Válúablz Pláyér", + "mostViolatedPlayerText": "Móst Víoláted Pláyer", + "mostViolentPlayerText": "Móst Víolznt Pláyér", + "moveText": "Móvév", + "multiKillText": "${COUNT}-KÍZL!!!", + "multiPlayerCountText": "${COUNT} pláyzrs", + "mustInviteFriendsText": "Ntz: yz mlfj coi jowe oif\noj \"${GATHER}\" cows coe ojwoef\nocnotjoi to pla coimcourlr.", + "nameBetrayedText": "${NAME} bétráyzd ${VICTIM}.", + "nameDiedText": "${NAME} díed.", + "nameKilledText": "${NAME} killzéd ${VICTIM}.", + "nameNotEmptyText": "Náme cúnnzt bé émptz!", + "nameScoresText": "${NAME} Scórzsz!", + "nameSuicideKidFriendlyText": "${NAME} accfijflzfj dzrz.", + "nameSuicideText": "${NAME} cómmittéd súizide.", + "nameText": "Noiwjfe", + "nativeText": "Nztvvz", + "newPersonalBestText": "Néw pérsónzl bést!", + "newTestBuildAvailableText": "A nwlf tat blfjl is aviflflzblz! (${VERSION} blzd ${BUILD}).\nGzt iz tat ${ADDRESS}", + "newText": "Ncw", + "newVersionAvailableText": "A newo coi efo ${APP_NAME} i c ifoi wf ${VERSION}", + "nextAchievementsText": "Nx aoio ijoijefez", + "nextLevelText": "Néxt Lévzl", + "noAchievementsRemainingText": "- nónz", + "noContinuesText": "(nz contoijfows)", + "noExternalStorageErrorText": "Nz xtenrlf stlfsdf fnff onf thz dfvfojfzz", + "noGameCircleText": "Errór: nút lúggzd íntó Góme Cúrclz", + "noJoinCoopMidwayText": "Có-óp gúmzs cán't bz jóinzd mídwáy.", + "noProfilesErrorText": "Yoú hávz nó pláyerz prófilzs, só yóu're stzck wíth '${NAME}'.\nGó tz Sétzings->Pláyerz Prófiles tú mzke yóurszlf á prófile.", + "noScoresYetText": "Nz scrrlz ytz.", + "noThanksText": "Nó Thánkz", + "noTournamentsInTestBuildText": "WOREwr: WOTo cwoefw coif wefiidfjdf cow ekfwoejowijerwdifwdf.", + "noValidMapsErrorText": "Nó válíd máps fóund fúr thzs gáme typz.", + "notEnoughPlayersRemainingText": "Nt zefwnoef plrjr rmeinging; exit anfo iwfj owjf oj ga emga;", + "notEnoughPlayersText": "Yf nfdf a taflew ${COUNT} pfo wotj wofijow afo game!", + "notNowText": "Nót Núw", + "notSignedInErrorText": "Yz mst bz snginf intof yrrz accnt tz dz thzz.", + "notSignedInGooglePlayErrorText": "Ym fij cow fj wo cowe toiw jcoj ojwoefj owi.", + "notSignedInText": "(nf cow eofw)", + "notUsingAccountText": "Wewoeirj: ncowe rower'${SERVICE}'.\nSniff fwefwef ${SERVICE} jogs cpwoeijr odfjowf.", + "nothingIsSelectedErrorText": "Nothflf iz seleftcetzd!", + "numberText": "#${NUMBER}", + "offText": "Ófz", + "okText": "OzKy", + "onText": "Ón", + "oneMomentText": "One Mmcowmerz..", + "onslaughtRespawnText": "${PLAYER} wúll réspawn das wávz ${WAVE}", + "orText": "${A} orz ${B}", + "otherText": "Ofowiejf....", + "outOfText": "(#${RANK} oút ófz ${ALL})", + "ownFlagAtYourBaseWarning": "Yoúr owzn flág múst bé\nát yzúr báse tó scóre!", + "packageModsEnabledErrorText": "Ntwrkz-plz nzt allrzd whlz pcket zmof aosdf oidsfwoe wfe(szz wsetnoaf adsasdnvanoce)", + "partyWindow": { + "chatMessageText": "Chclz Mafnfz", + "emptyText": "Yrrz partzy ist memptyz", + "hostText": "(hzt)", + "sendText": "Snene", + "titleText": "Yrrz Partar" + }, + "pausedByHostText": "(pzzde bz hzstt)", + "perfectWaveText": "Púrfzct Wávz!", + "pickUpBoldText": "PZCKÚP", + "pickUpText": "Píczk Uúp", + "playModes": { + "coopText": "Cz-opz", + "freeForAllText": "Frzz-frz-Alz", + "multiTeamText": "Mzltiz-Tmzz", + "singlePlayerCoopText": "Sion Player /Cpfpowfji", + "teamsText": "Tmmz" + }, + "playText": "Pfnplay", + "playWindow": { + "coopText": "Czoo-op", + "freeForAllText": "Férree-for-Azzxll", + "oneToFourPlayersText": "1-4 plzzrzzz", + "teamsText": "Téééémés", + "titleText": "Plzaayz", + "twoToEightPlayersText": "2-8 zpllzrrz" + }, + "playerCountAbbreviatedText": "${COUNT}pz", + "playerDelayedJoinText": "${PLAYER} wlzl enters atz z stzf nfae ggmmz.", + "playerInfoText": "Plzer Infor", + "playerLeftText": "${PLAYER} lzfjt zjh gzmls.", + "playerLimitReachedText": "Plzer lmzt of ${COUNT} rzched; nz jofjinsdfn allrlwzdz.", + "playerLimitReachedUnlockProText": "Upfjfwef tz \"${PRO}\" wofj coje fwoe cojwiej woe ${COUNT} pffjz.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Yz cntn delfaje coweir anccnoar proffz.", + "deleteButtonText": "Delefa\nPrproif", + "deleteConfirmText": "Delfgt '${PROFILE}'?", + "editButtonText": "Edtz\nPrifaflz", + "explanationText": "(crtz custmo nmcm and appaoarnz frz)", + "newButtonText": "Nwwz\nPoriflrz", + "titleText": "Plzzerr Prfillz" + }, + "playerText": "Pláyér", + "playlistNoValidGamesErrorText": "Thz fpoiwfj coweoo conw ovj aodsf owcoi wefgages.", + "playlistNotFoundText": "plzlst not fozfnd", + "playlistText": "Plzlzlzf", + "playlistsText": "Plzlntsfs", + "pleaseRateText": "If yóu're énjoyíng ${APP_NAME}, pléase cónsider táking z\nmúment ánd rúting zt ór wrúting í reváew. Thzs próvidzs\níseful fzédbíck ánd hélps súpport fútúre dévelópmént.\n\nthénkz!\n-eric", + "pleaseWaitText": "Poke focwoe fjowef.", + "pluginClassLoadErrorText": "Erori cojflw cwoej woer erwe '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Error cowejwoer plugins ${PLUGIN}: ${ERROR}", + "pluginSettingsText": "Plwj coijordsfsddf.", + "pluginsAutoEnableNewText": "Auto f wow rjwo fipawgojsd", + "pluginsDetectedText": "Now cow rwoejcw. Wnewoiow rwepwot ghowcoweior weorjdfdfs.", + "pluginsDisableAllText": "DIsdof All Cplgwerd", + "pluginsEnableAllText": "NEwoc wowed. Aplugiss.", + "pluginsRemovedText": "${NUM} powefjwj no legate fcwdf.", + "pluginsText": "Plfzlfez", + "practiceText": "Pcoifjzzz", + "pressAnyButtonPlayAgainText": "Prézs ánz búttún tóz pláy agánz...", + "pressAnyButtonText": "Prézs ánz búttún tóz cúntinze...", + "pressAnyButtonToJoinText": "przés azny búttoz tz jóin...", + "pressAnyKeyButtonPlayAgainText": "Prézs ánz kéy/búttún tóz pláy agánz...", + "pressAnyKeyButtonText": "Prézs ánz kéy/búttún tóz cúntinze...", + "pressAnyKeyText": "Préss ány kézy...", + "pressJumpToFlyText": "** Przss júmp repéatedly tó flyz **", + "pressPunchToJoinText": "przss PEZCH té júin...", + "pressToOverrideCharacterText": "przss ${BUTTONS} tó óvézríde yózr chárazfter", + "pressToSelectProfileText": "préezs ${BUTTONS} té seézlect yúr prófíle", + "pressToSelectTeamText": "przéss ${BUTTONS} tó sézlezt yoór túém", + "profileInfoText": "Créate prófilzs fór yourself and your friends to assign\nyóurszlf námzs ánz cháractzrs ínstzad óf géttíng rándzm ónzs.", + "promoCodeWindow": { + "codeText": "Czdfé", + "codeTextDescription": "Prémsz Crdde", + "enterText": "Entzzr" + }, + "promoSubmitErrorText": "Errór szbmítting códe; chéck yóur ínternét cznnéctión", + "ps3ControllersWindow": { + "macInstructionsText": "Swízch zff zhe pzwer zn zhe báck zf yzur PS3, máke sure\nBluezzzzh ís enábled zn yzur Mác, zhen cznnecz yzur cznzrzller\nzz yzur Mác víá á USB cáble zz páír zhe zwz. Frzm zhen zn, yzu\ncán use zhe cznzrzller's hzme buzzzn zz cznnecz íz zz yzur Mác\nín eízher wíred (USB) zr wíreless (Bluezzzzh) mzde.\n\nZn szme Mács yzu máy be przmpzed fzr á pássczde when páíríng.\nÍf zhís háppens, see zhe fzllzwíng zuzzríál zr gzzgle fzr help.\n\n\n\n\nPS3 cznzrzllers cznneczed wírelessly shzuld shzw up ín zhe devíce\nlísz ín Syszem Preferences->Bluezzzzh. Yzu máy need zz remzve zhem\nfrzm zház lísz when yzu wánz zz use zhem wízh yzur PS3 ágáín.\n\nÁlsz máke sure zz díscznnecz zhem frzm Bluezzzzh when nzz ín\nuse zr zheír bázzeríes wíll cznzínue zz dráín.\n\nBluezzzzh shzuld hándle up zz 7 cznneczed devíces,\nzhzugh yzur míleáge máy váry.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "Tó usz a PS3 cóntróllzr wsth yóur ÓUYA, ssmply cónnzct st wsth a USB cablz\nóncz tó pasr st. Dósng thss may dsscónnzct yóur óthzr cóntróllzrs, só\nyóu shóuld thzn rzstart yóur ÓUYA and unplug thz USB cablz.\n\nFróm thzn ón yóu shóuld bz ablz tó usz thz cóntróllzr's HÓMZ buttón tó\ncónnzct st wsrzlzssly. Whzn yóu arz dónz playsng, hóld thz HÓMZ buttón\nfór 10 szcónds tó turn thz cóntróllzr óff; óthzrwssz st may rzmasn ón\nand wastz battzrszs.", + "ouyaInstructionsTextScale": 0.74, + "pairingTutorialText": "péiríng tútóríal veídeo", + "titleText": "Uzséng PS3 Cónzrollérs wízh ${APP_NAME}:" + }, + "publicBetaText": "PZÚBLIC BÉZTA", + "punchBoldText": "PÚNZCH", + "punchText": "Púzch", + "purchaseForText": "Púrcháse fúrz ${PRICE}", + "purchaseGameText": "Púrchúze Gáme", + "purchasingText": "Prjrcjfz...", + "quitGameText": "Qcoifj ${APP_NAME}", + "quittingIn5SecondsText": "Quéttzng ín 5 sécznds...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Rzandomz", + "rankText": "Rnkfz", + "ratingText": "Rátzng", + "reachWave2Text": "Réách wávé 2 tó ránk.", + "readyText": "réády", + "recentText": "Rcfjfzz", + "remainingInTrialText": "rémáfiníng ín tríál", + "remoteAppInfoShortText": "${APP_NAME} iz cow eofi co wefjowiej fowiejfowef\nCow enow c oweifj owiej oc owei fowije fowj ;join thsefaf\n${REMOTE_APP_NAME} api c woe fj owiejc owe coiwjeowef\nasdf contorfwefwe.", + "remote_app": { + "app_name": "Bomc Rcorjorj", + "app_name_short": "BSFmowcwe", + "button_position": "Brroz Posijfoiwjr", + "button_size": "Brrltjt Szr", + "cant_resolve_host": "Cntto Rrrlj hrorz.", + "capturing": "Cporrjz...", + "connected": "Ctnntoicc.", + "description": "Usf coi cyao o acj wof joic oaijojef a;owi ocaobOBm.\nUps to co w of avow wf ocw oei iwfor acoa wf mult apc a wefjo cp sonota toav a fowieort.", + "disconnected": "Doc wolf by user vowe.", + "dpad_fixed": "ffojoc", + "dpad_floating": "fljtoffz", + "dpad_position": "D-Pd Pofjoijor", + "dpad_size": "D-Pf zrrz", + "dpad_type": "D-pd Tprpz", + "enter_an_address": "Entro an addrrs", + "game_full": "Thz gmc wif coj f cow tnoac aoj fojwoefjwe.", + "game_shut_down": "Thz gocm ah soc ow townw.", + "hardware_buttons": "Horjr oBurrlzz.", + "join_by_address": "Jrorij boj Addrrzz.", + "lag": "Lggz ${SECONDS} scofjfz", + "reset": "Rzwf tz deferz", + "run1": "Rrrnz", + "run2": "Rnr z2", + "searching": "Serarojc ofwe BBomsojo ggzfz...", + "searching_caption": "Tpa co w toia noa cowef owiejower.\nMkf wuseo youc aeno toi oaoew rowjtooaor.", + "start": "Strwfz", + "start_button": "Stwow", + "version_mismatch": "Veroi jmoiowoejf\nMkac aot co boaisoijero caoioisd fjaoer\nadc ot oacouweotu vowe ron aga." + }, + "removeInGameAdsText": "Unlkjfj \"${PRO}\" in cowj wje of wejfoiwfoo oifoiwjef.", + "renameText": "Rzngmlz", + "replayEndText": "Enz Rpllz", + "replayNameDefaultText": "Lzts Gmzl Rplzlz", + "replayReadErrorText": "Errzr rdnglgz rplzlz flz.", + "replayRenameWarningText": "Renznf \"${REPLAY}\" aftnf gmz oidf aosf asdj aoij keep aoioheor wofijo aivjoe rowijefowif.", + "replayVersionErrorText": "Srrz, tzh replalz wz mddd inzl ad fidfffr\nvererjz o f at the agamemfzz and acjewo tjj zluszd.", + "replayWatchText": "Wzzlt Rlpllzl", + "replayWriteErrorText": "Errzz wrtzzlg rplzl fizlz.", + "replaysText": "Rpzlzz", + "reportPlayerExplanationText": "Uf woc ow efow efiwjco owe,we woi woiej ofijwoe fowe,wd fowidj owejfowief.\nPef woc woejfowifw:", + "reportThisPlayerCheatingText": "Chttocz", + "reportThisPlayerLanguageText": "Inpcowej oij Lnagoijafoj", + "reportThisPlayerReasonText": "Wh cco wefo co aogjwo fjowef?", + "reportThisPlayerText": "Rporijf Thif Plzlirz", + "requestingText": "Rcjowcijc...", + "restartText": "Réstártz", + "retryText": "Rtefnz", + "revertText": "Révúrt", + "runBoldText": "RUZLN", + "runText": "Rúun", + "saveText": "Sávez", + "scanScriptsErrorText": "Error(w) frolic weir ro; cj weowje ici woeijwer.", + "scoreChallengesText": "Scóre Chálléngúz", + "scoreListUnavailableText": "Sczerl lzst unvnslfljblz.", + "scoreText": "Szóre", + "scoreUnits": { + "millisecondsText": "Mzlifjltlfjndfz", + "pointsText": "Pntnz", + "secondsText": "Sclnldfjz" + }, + "scoreWasText": "(wús ${COUNT})", + "selectText": "Slézcz", + "seriesWinLine1PlayerText": "WZNNPLL THZ", + "seriesWinLine1Scale": 0.65, + "seriesWinLine1TeamText": "WNZTTTM THZ", + "seriesWinLine1Text": "WÍNZ THZ", + "seriesWinLine2Scale": 1.0, + "seriesWinLine2Text": "SÉRÍZS!", + "settingsWindow": { + "accountText": "Acncljtz", + "advancedText": "Advnfsdfjzd", + "audioText": "Aédudief", + "controllersText": "Cosljfoiwefjf", + "enterPromoCodeText": "Enlsfl Przmfm Codnfff", + "graphicsText": "Graphzzzz", + "kickIdlePlayersText": "Kzjfk Idlze Plzerrls", + "playerProfilesMovedText": "Ntzz: Plwef Profjowc hsv mcfw tz the Accfoj wenof co omain mcur.", + "playerProfilesText": "Plefzjf Profifjss", + "showPlayerNamesText": "Sfoz Plzersd Nzjmm", + "titleText": "Szeetzgsss" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(a smpd a, condofia efjwefoajewofoiaj;s a sodifj a;osdfjoitest f)", + "alwaysUseInternalKeyboardText": "Alzlt usl Intenralf kyBerz", + "benchmarksText": "Bnchmkwr & Staf-Tsfsfz", + "disableCameraGyroscopeMotion": "Disa fe come won aweGowyeo CMosndf", + "disableCameraGyroscopeMotionText": "Dislike og wefo cwei oweiaMowerdns", + "disableCameraShakeText": "SDi Cmanan Blobofs", + "disableThisNotice": "(you come for wolf jwfowejoijer cowed wfoiwej jay)", + "enablePackageModsDescriptionText": "(enleaf exjpaf mdoodn gcpappwro buf dsilas new t plz)", + "enablePackageModsText": "Ebnblaf Lcjof Pcfowf Mdsfsz", + "enterPromoCodeText": "Eznter Cdzs", + "forTestingText": "Ntz: thz vlarj farz olflf rzz tsffcn anz wllz bz llfsf whnzl thzz app exrtzz.", + "helpTranslateText": "${APP_NAME} lngalsdf transaldflksdfj arz fjocdmaosdf\nsprnarted effrztzs. Ifsdf oud'fu likzz to cmdfoasdf corectsf\na sd fjafdsoijdf, flfowefj thz fljlnkdd blzljf. Thansdlfn in andncas!", + "kickIdlePlayersText": "Kzkck Idlzlf Plzjrs", + "kidFriendlyModeText": "Krz-Frjijglfz-Mzdz (rdfjifz voioifjf, fz)", + "languageText": "Lnglfjslfd", + "moddingGuideText": "Mddzng Gdufnzsd", + "mustRestartText": "Yz msg restar thz gmm fof this tk ttk effectsz.", + "netTestingText": "Ntwkrz Tsstcg", + "resetText": "Rsttz", + "showBombTrajectoriesText": "Shzlz Bomf Tfwoejcwoefz", + "showInGamePingText": "Shoe o co fowl Png", + "showPlayerNamesText": "SHzlfjl Plzlrr Nmzlzlls", + "showUserModsText": "Shzl Mdsz Fldlrz", + "titleText": "Advnafjfljdz", + "translationEditorButtonText": "${APP_NAME} Tjofwijf Eoidjor", + "translationFetchErrorText": "trnzlfgweg stdlsf unvavalrz", + "translationFetchingStatusText": "chcking tranfsldf sttuffsz...", + "translationInformMe": "Ofiw co. eom wccowoijef weiofwe owef wc owefwrs.", + "translationNoUpdateNeededText": "the crjlfidsj lnglfjdz iz upzl tx dtzzfs; woojofjd!", + "translationUpdateNeededText": "** thz furur languares nezdsjd updates!!!! **", + "vrTestingText": "VR Tzntgng" + }, + "shareText": "Shcwef", + "sharingText": "Chwoefz..", + "showText": "Shz", + "signInForPromoCodeText": "Yz mst singo in o accnno for cods ot thk weffets.", + "signInWithGameCenterText": "To loci wo gamg wofiw efoiwjef.\ncoaej goajb oaj Game foc etapp.", + "singleGamePlaylistNameText": "Jzff ${GAME}", + "singlePlayerCountText": "1 pláyzr", + "soloNameFilterText": "${NAME} Sólzo", + "soundtrackTypeNames": { + "CharSelect": "Czárazter Sélection", + "Chosen One": "Chósén Onz", + "Epic": "Epíc Móde Games", + "Epic Race": "Epíc Ráze", + "FlagCatcher": "Cáptúre thz Flág", + "Flying": "Háppy Thózghts", + "Football": "Foótbazll", + "ForwardMarch": "Aszáult", + "GrandRomp": "Cónqúest", + "Hockey": "Hóckzy", + "Keep Away": "Kézp Awáy", + "Marching": "Rúnazróund", + "Menu": "Mzín Ménú", + "Onslaught": "Onéslaúght", + "Race": "Race", + "Scary": "Kíng óf thé Híll", + "Scores": "Scóre Scréen", + "Survival": "Ezíminátion", + "ToTheDeath": "Dáath Mzétch", + "Victory": "Fínal Scóre Scréen" + }, + "spaceKeyText": "spzz", + "statsText": "Sfawfwf", + "storagePermissionAccessText": "Tho cowefj woiejowefw.", + "store": { + "alreadyOwnText": "Yorz alrlfzl wozl ${NAME}!", + "bombSquadProDescriptionText": "• Rmoi come fai oifwjeojf\n• Ubckff ${COUNT} bifn ciuefuh\n• +${PERCENT}% power foiacoiwfl\n• Unlclf '${INF_ONSLAUGHT}' anz\n '${INF_RUNAROUND}' co of jews", + "bombSquadProFeaturesText": "Fettnafars:", + "bombSquadProNameText": "${APP_NAME} Prz", + "bombSquadProNewDescriptionText": "• OWjoc owejfowef dfwefwefwef\n• Woijc wefjweocjjcw fjweofijwef\n• wocje fowiejf:", + "buyText": "Bzy", + "charactersText": "Czharggczzls", + "comingSoonText": "Cmzngl Snznlsz...", + "extrasText": "Extrrfz", + "freeBombSquadProText": "Bfjaoefj ij foawje foijcowje oifjwo jf woaifjo waf\naowf aosdjfoaijcow iejojefo wjfowiefjo ${COUNT} foco wofeij a;iofj woj.\nENojfowaif oithwoefij ac owejfwoef jaoijf owicjoijcowiefj!\n-Erfc", + "gameUpgradesText": "Gzmm Unzprjfzz", + "getCoinsText": "Gzt Cnfljfz", + "holidaySpecialText": "Hzlolidz Spzlzlflz", + "howToSwitchCharactersText": "(gz tz ${SETTINGS} -> ${PLAYER_PROFILES} tz wfoiejf coijwoicoijwf)", + "howToUseIconsText": "(croijoj oaf japocj paowejf owef\"(in thc accj f enfo)\" otj acoiejf w)", + "howToUseMapsText": "(usf thwemc woeifj aojco wefjo wjaocj paowfj woeifjos)", + "iconsText": "Icnofjf", + "loadErrorText": "Unzlblf to zlfl bpgong.\nChlzl yrlzn intnlzfnl cnnfncsz.", + "loadingText": "lzdng", + "mapsText": "Mzpz", + "miniGamesText": "MnflzGmz", + "oneTimeOnlyText": "(onc jf onlyf)", + "purchaseAlreadyInProgressText": "A prnoif of thwf if mwof wofi aoer wofoiefw.", + "purchaseConfirmText": "Prucoief ${ITEM}?", + "purchaseNotValidError": "Prwoj focj owejf\nContoewf ${EMAIL} if fowl efjw oajof.", + "purchaseText": "Pfoijcrz", + "saleBundleText": "Bzfjoc Salfz!", + "saleExclaimText": "Slfo!", + "salePercentText": "(${PERCENT}% fifz)", + "saleText": "SLFL", + "searchText": "Srnczl", + "teamsFreeForAllGamesText": "Tmmg / Frrzz-rff/Allz Gmffz", + "totalWorthText": "*** ${TOTAL_WORTH} vafwf! ***", + "upgradeQuestionText": "Upwfwef?", + "winterSpecialText": "Wznter Spzlflfz", + "youOwnThisText": "- yz wnfz thz -" + }, + "storeDescriptionText": "asdfj fwofjwe fwjfjwf asdlfjsdf fdjatoijw;ojfpwoef wefjwoefjwfe.\n\nBlojsd;flj asdfj asd;ofjasdfoi a;sdijfs;dfsd jfdasoidjf ;aidsjf ;adsf\nasdofa sdfijs;odf ;aosidjf ;asdfj;asdof;ijasdf;\nsdjfsjd fasdf asdfasdfasdf", + "storeDescriptions": { + "blowUpYourFriendsText": "Blzw upz yrzeor frdnfnz", + "competeInMiniGamesText": "Cmplzl in mdmfl gmzlz rnglng fmzz rcngng to flznfg", + "customize2Text": "Cztmzls chrcctsrsl, mnnin-gmzz, and evnf zl snftrrkckz.", + "customizeText": "Cstmzlze chrzclterz dand crzlsldf yrzw ownz emin-gmzm sndorglrks.", + "sportsMoreFunText": "Sprtzs arz mrzr fnzrs wthzr explowoafsdfs.", + "teamUpAgainstComputerText": "Tmzls upz agansft thz cmpturzs." + }, + "storeText": "Stzlrle", + "submitText": "Scowiejfwef", + "submittingPromoCodeText": "Subjfoif Cdssz...", + "teamNamesColorText": "Tmcoj Conor/ Coarle...", + "teamsText": "Tééáémés", + "telnetAccessGrantedText": "Tzélnt acczzss énazledz.", + "telnetAccessText": "Tzélnt azcezs détzfcted; aélow?", + "testBuildErrorText": "Thz tst-bld iz nz lnglsf actv.fz. plz hckc frz nv vnarerz.", + "testBuildText": "Tstg Blldz", + "testBuildValidateErrorText": "Unbblldf tz validfajr tstb blflz. (nz netf cdnfdljfec?)", + "testBuildValidatedText": "Tst Bjldf Vlaldkfsf; Enjzjf!", + "thankYouText": "Thánk yóu fór yóur súppórt! Enjóy thé gáme!!", + "threeKillText": "TRÍPLZ KÚLL!!", + "timeBonusText": "Tíme Bónús", + "timeElapsedText": "Tíme Elápszd", + "timeExpiredText": "Tzmz Exprireizdd", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}hz", + "timeSuffixMinutesText": "${COUNT}mz", + "timeSuffixSecondsText": "${COUNT}sz", + "tipText": "Tízp", + "titleText": "Bmbmsqdz", + "titleVRText": "BomboFjof VR", + "topFriendsText": "Tóp Fríendz", + "tournamentCheckingStateText": "Chkfjfowef oitwof oweifja oef pawoej owef...", + "tournamentEndedText": "This foil jefoi weoa echo sd. An ewoifj wo oowifjowe soon.", + "tournamentEntryText": "Tnofjwfe oecowiejw", + "tournamentResultsRecentText": "Rcnet Touaofius aRamalsdf.", + "tournamentStandingsText": "Tzewfjwoij Stndfalfjz", + "tournamentText": "Tanfowijfowef", + "tournamentTimeExpiredText": "Tmcoef Tm Epzoiejfefz", + "tournamentsDisabledWorkspaceText": "Towejowc we wrjw f;aoweahwe aowwej fwoeij woicjwerwer.\nTow c we rapowi f cjqo qpwpi hgpwiejf. nowe wooer wieje wclcoiwjer.", + "tournamentsText": "Trzzmfnmflfzzs", + "translations": { + "characterNames": { + "Agent Johnson": "Agjofi Jocwef", + "B-9000": "B-90000", + "Bernard": "Brzlfjfoz", + "Bones": "Bnzl", + "Butch": "Brzffd", + "Easter Bunny": "Eefowj Boifjwoef", + "Flopsy": "Flzpzfz", + "Frosty": "Frrozf", + "Gretel": "Gflrlz", + "Grumbledorf": "Goijcowiefdf", + "Jack Morgan": "Jcjo Mrggz", + "Kronk": "Krrorzz", + "Lee": "Lcwef", + "Lucky": "Loiwjef", + "Mel": "Mzzl", + "Middle-Man": "Gmdflj-cmdf", + "Minimus": "Mijowcf", + "Pascal": "Pasclfz", + "Pixel": "Poxiejf", + "Sammy Slam": "Sm df cwoSflm", + "Santa Claus": "Santa Clzous", + "Santa Clause": "Szntana Clzlrnas", + "Snake Shadow": "Snlj Co woefj", + "Spaz": "Spzz", + "Taobao Mascot": "Taco Mcwojefo", + "Todd": "Tweet", + "Todd McBurton": "Taj O woejfd", + "Xara": "Xfwef", + "Zoe": "Zob", + "Zola": "Zlefw" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Infíníte\nÓnsláught", + "Infinite\nRunaround": "Ínfíníte\nRúnaróúnd", + "Onslaught\nTraining": "Onsláughtz\nTráiníng", + "Pro\nFootball": "Pró\nFóotbáll", + "Pro\nOnslaught": "Pró\nOnsláughtz", + "Pro\nRunaround": "Pró\nRúnaróund", + "Rookie\nFootball": "Róokíe\nFóotbálz", + "Rookie\nOnslaught": "Róokze\nOnsláughz", + "The\nLast Stand": "Thé\nLást Stánd", + "Uber\nFootball": "Úbér\nFóotbáll", + "Uber\nOnslaught": "Ubér\nOnsláúght", + "Uber\nRunaround": "Úbér\nRúnároúnd" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Tfjozijzs", + "Infinite ${GAME}": "Infifiew ${GAME}", + "Infinite Onslaught": "Íznfíníte Onzláught", + "Infinite Runaround": "Iznfinite Runaround", + "Onslaught": "Íznfíníte Onzláught", + "Onslaught Training": "Onzláughtz Trzáíníng", + "Pro ${GAME}": "Prz ${GAME}", + "Pro Football": "Pró Football", + "Pro Onslaught": "Pró Onzláught", + "Pro Runaround": "Pró Runáround", + "Rookie ${GAME}": "Rzzlfjf ${GAME}", + "Rookie Football": "Rzokie Fúotbáll", + "Rookie Onslaught": "Rúokíe Onzláught", + "Runaround": "Iznfinite Runaround", + "The Last Stand": "Thú Lázt Ztánd", + "Uber ${GAME}": "Ubezr ${GAME}", + "Uber Football": "Ubúr Football", + "Uber Onslaught": "Ubzr Onzláught", + "Uber Runaround": "Ubúr Runáround" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Bé thé chósen ónz fór a léngth éf tíme tó wzn.\nKzll thé chósen óne tz bécome út.", + "Bomb as many targets as you can.": "Bmb ojwe fo cj woef weoijcoj ofz.", + "Carry the flag for ${ARG1} seconds.": "Cárrz thé flág fór ${ARG1} sécóndz.", + "Carry the flag for a set length of time.": "Cárry thé flág fór á sét léngth oz tíme.", + "Crush ${ARG1} of your enemies.": "Crúsz ${ARG1} óf yóúr énemies", + "Defeat all enemies.": "Défetz álz enemíz.", + "Dodge the falling bombs.": "Ddfjgzl thz flzjflg bjbjlfz.", + "Final glorious epic slow motion battle to the death.": "Fínzl glóriozs épzc slów mótizn báttlz tó thz déath.", + "Gather eggs!": "Gjowicj ewfgw!", + "Get the flag to the enemy end zone.": "Gét thé flág tó thz enémy énd zóne.", + "How fast can you defeat the ninjas?": "Hz wfwe cowej oiwcowiefo idnininas?", + "Kill a set number of enemies to win.": "Kílz á sét númbér óf énmiez tó wín", + "Last one standing wins.": "Lást ónz stándíng wíns.", + "Last remaining alive wins.": "Lást rzmáiníng álzve wíns.", + "Last team standing wins.": "Lást tézm stándíng wíns.", + "Prevent enemies from reaching the exit.": "Prévúnt énemizs fróm reáching thé exít.", + "Reach the enemy flag to score.": "Réach thz enémy flág tó scórz.", + "Return the enemy flag to score.": "Réturz thz énemy flág tó scórz.", + "Run ${ARG1} laps.": "Rún ${ARG1} lápz.", + "Run ${ARG1} laps. Your entire team has to finish.": "Rún ${ARG1} lápz. Yóur éntzre téam has tó fznish.", + "Run 1 lap.": "Rún 1 láp.", + "Run 1 lap. Your entire team has to finish.": "Rún 1 láp. Yóur éntire téam has tó fznish.", + "Run real fast!": "Rún réaz fázt", + "Score ${ARG1} goals.": "Scóré ${ARG1} góalz.", + "Score ${ARG1} touchdowns.": "Scóré ${ARG1} tóuchdównz.", + "Score a goal": "Scórz á góal", + "Score a goal.": "Scórz á góal.", + "Score a touchdown.": "Scórz á tóuchdówz.", + "Score some goals.": "Scórz sómz góalz.", + "Secure all ${ARG1} flags.": "Sécúrz álz ${ARG1} flágz.", + "Secure all flags on the map to win.": "Sécurz álz flúgs ón zú máp té wín", + "Secure the flag for ${ARG1} seconds.": "Séczre thé flág fúr ${ARG1} sécúnds.", + "Secure the flag for a set length of time.": "Séczré thé flúg fzr á sét lzngth óf túme.", + "Steal the enemy flag ${ARG1} times.": "Stéál thé enémy flág ${ARG1} tímés.", + "Steal the enemy flag.": "Stéál thé ezémy flúg", + "There can be only one.": "Théré cán bé ónlz óne.", + "Touch the enemy flag ${ARG1} times.": "Toúch thé enémy flág ${ARG1} tímés.", + "Touch the enemy flag.": "Tóúcz thé ezémy flúg", + "carry the flag for ${ARG1} seconds": "cárrz thé flág fór ${ARG1} sécóndz", + "kill ${ARG1} enemies": "kílz ${ARG1} énzmíez", + "last one standing wins": "lást ónz stándíng wíns", + "last team standing wins": "lást tézm stándíng wíns", + "return ${ARG1} flags": "rétúrn ${ARG1} flágz", + "return 1 flag": "rétúrn 1 flág", + "run ${ARG1} laps": "rún ${ARG1} lápz", + "run 1 lap": "rún 1 láp", + "score ${ARG1} goals": "Scóré ${ARG1} góalz", + "score ${ARG1} touchdowns": "scórz ${ARG1} tóuchdównz", + "score a goal": "scórz á góal", + "score a touchdown": "scóre á tóuchdówn", + "secure all ${ARG1} flags": "sécúrz álz ${ARG1} flágz", + "secure the flag for ${ARG1} seconds": "séczre thé flág fúr ${ARG1} sécúnds", + "touch ${ARG1} flags": "tóúch ${ARG1} flúgz", + "touch 1 flag": "tóúch 1 flúg" + }, + "gameNames": { + "Assault": "Azzáulz", + "Capture the Flag": "Cápzuré thé Flágz", + "Chosen One": "Chzénz Ónez", + "Conquest": "Cónquzézt", + "Death Match": "Déátzh Mátczh", + "Easter Egg Hunt": "Eogwiej owije ghuf", + "Elimination": "Élímznizaín", + "Football": "Fútbolz", + "Hockey": "Hóckzy", + "Keep Away": "Kéép Awáz", + "King of the Hill": "Kíng óf thz Hílz", + "Meteor Shower": "Mtrlrlr Shghglzrz", + "Ninja Fight": "Njnff Fiffz", + "Onslaught": "Ónsláughtz", + "Race": "Ráze", + "Runaround": "Rúnároundz", + "Target Practice": "Tafo Prajcfz", + "The Last Stand": "Thú Lzst Stándz" + }, + "inputDeviceNames": { + "Keyboard": "Kblflzfz", + "Keyboard P2": "Kzboardz P2z" + }, + "languages": { + "Arabic": "Aroijwe", + "Belarussian": "Blfrurzfozz", + "Chinese": "Choifwef Soimcwoef", + "ChineseTraditional": "Cheifwoefjw Trwwefsdfs", + "Croatian": "Crrlzlrrs", + "Czech": "Czffef", + "Danish": "Dnishsdl", + "Dutch": "Dtchjdflz", + "English": "Englfjlzjsh", + "Esperanto": "Esprorjjzlz", + "Filipino": "Fefjwoeifj", + "Finnish": "Fnnizhsh", + "French": "Frnzhfhn", + "German": "Grmmzndn", + "Gibberish": "Gibberish", + "Greek": "Gaofwef", + "Hindi": "Hfjofz", + "Hungarian": "Hngjgozf", + "Indonesian": "Inofiqdson", + "Italian": "Itzllfjssnn", + "Japanese": "Jpndjsjzes", + "Korean": "Kornesnzn", + "Malay": "FJwoerjjdf", + "Persian": "Psdfsdf", + "Polish": "Pzlishz", + "Portuguese": "Portuguenejs", + "Romanian": "Rmrfoijfzf", + "Russian": "Rzznrsn", + "Serbian": "Socowiejf", + "Slovak": "Slihdtbjoy", + "Spanish": "Snsdnsh", + "Swedish": "Swdiiszh", + "Tamil": "Tmfiewf", + "Thai": "Thzff", + "Turkish": "Twfoijwef", + "Ukrainian": "Ukckwef", + "Venetian": "Vwvowefdf", + "Vietnamese": "Vjefowiewer" + }, + "leagueNames": { + "Bronze": "Blfoijzf", + "Diamond": "Dfoifffz", + "Gold": "Glfdf", + "Silver": "Slfjfozz" + }, + "mapsNames": { + "Big G": "Bíg Gz", + "Bridgit": "Brídzgzt", + "Courtyard": "Coúrtyárd", + "Crag Castle": "Crág Cástlé", + "Doom Shroom": "Dóóm Shróóm", + "Football Stadium": "Fóózball Stédzm", + "Happy Thoughts": "Háppy Thóúghts", + "Hockey Stadium": "Hóckzy Stzéimz", + "Lake Frigid": "Lk Frojfz", + "Monkey Face": "Mónkey Fáce", + "Rampage": "Rampágé", + "Roundabout": "Róúndzboót", + "Step Right Up": "Stép Reíghz Úp", + "The Pad": "Thz Péd", + "Tip Top": "Típ Tzp", + "Tower D": "Tówér D", + "Zigzag": "Zigzúzg" + }, + "playlistNames": { + "Just Epic": "Jst Pcpc", + "Just Sports": "Jspsf Zprttz" + }, + "promoCodeResponses": { + "invalid promo code": "invlidf promoz cdfd" + }, + "scoreNames": { + "Flags": "Flágz", + "Goals": "Góálz", + "Score": "Sczórz", + "Survived": "Súrvizvéd", + "Time": "Tímé", + "Time Held": "Tímz Hélz" + }, + "serverResponses": { + "A code has already been used on this account.": "A cfodfj hd cowefj aweof cwjeo fjweo fijw eofjwocij.", + "A reward has already been given for that address.": "Ac wolf wo Code coi weojoifow e ocjw oiejfwer.", + "Account linking successful!": "Accjo link succeosf!", + "Account unlinking successful!": "Accjow cowejowejr sucefwewr!", + "Accounts are already linked.": "Accojif co woie owjilkn.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "And foci wej fowif ijcowjer.\nPle eocj w jocose fowl jeowijeo few fj cijwoiejr. fofofifjow e ciweocywe.", + "An error has occurred; (${ERROR})": "An cow fc woof wcef; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "An cowed c woefj wcoi woof weiojrwe rj goije ${ERROR})", + "An error has occurred; please contact support@froemling.net.": "An f oco ao ocio wj ; pocj oco woei fsuupo co co ifoiwnet", + "An error has occurred; please try again later.": "An cowjef win woes owe p apowejrowjers.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Ac woef oi eowic woiej fowije foijcwe?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nTHci weo woi efoiw ojo ij!!", + "BombSquad Pro unlocked!": "Boijfdfsjef pon occoijfs!", + "Can't link 2 accounts of this type.": "Cnoj' oi n aoco i ot oaifftz.", + "Can't link 2 diamond league accounts.": "Cnoi' oin koci o2 doi co fla cairjrs.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Cn't coi oi; could up vo io ${COUNT} oi c ioicoicuors.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Chowcj eof weoc jco; oe jwoeijf wojcwjeowfj woejf o${COUNT} dzf.", + "Could not establish a secure connection.": "Cjfoi cn ooi a tac c oweocoicoinr.", + "Daily maximum reached.": "Dfilaf mciwfjiwf rechced.", + "Entering tournament...": "Ernwoefijweo jfowjefw...", + "Invalid code.": "Invflijf cddz.", + "Invalid payment; purchase canceled.": "Info ejcwpeopwer; purwup cowefjwef.", + "Invalid promo code.": "Ivnfjfo pmpwf cdffz.", + "Invalid purchase.": "Ivnifjf cnwerojf.", + "Invalid tournament entry; score will be ignored.": "Invoc oic owe fo; co ot coi aingoired.", + "Item unlocked!": "Iwerw cowefjwoeijwer!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LINKING FOFJWEF. ${ACCOUNT} o iwjof\nowe oijwe c woeoijwf oAL FJOEJI OCJW.\nYou off leojwoer wcowe foiwjefojweoiwf\n(a c owfw oefjTHIS c weoojw oesf)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Lcjwe fwofj o ${ACCOUNT} to cowejfweof?\nAll wefoiwejtthosjic w ${ACCOUNT} cowiejf tjsl.\nThis wefowondot onsof. Aojr tyocu wsure?", + "Max number of playlists reached.": "Mx nfmow oijeplyalfaf rcnoahfd.", + "Max number of profiles reached.": "Mc fjpasdofj c owiejfowe oiwjefsd.", + "Maximum friend code rewards reached.": "Cmwoe oc wo Ego wel jacoweij weer.", + "Message is too long.": "CMew ociwje owe el.", + "No servers are available. Please try again soon.": "Ns seroiejwc wefjwoe wj. Ple wer wfwef ewfowes.", + "Profile \"${NAME}\" upgraded successfully.": "Profjojf \"${NAME}\" oupfuap coj woijsfsf.", + "Profile could not be upgraded.": "Profojfo coild onot foj bupfrade.", + "Purchase successful!": "Pcjofj scwcserfflz!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Rclfjoc ${COUNT} otjoa ojofj oweijf.\nComcowef ocw weofjwefjowef ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Sowejr cowj fwoe co wefj owe f c woefijw ego wejfoiwjejwfjoweiwfe;\nPowijfw c wejfwoij oiwje wr erowijrowe.", + "Sorry, there are no uses remaining on this code.": "Srrryr, the war no cufowief rime woijwof con etude.", + "Sorry, this code has already been used.": "Srrc, thiz codds has aoiwjre bndd usdd.", + "Sorry, this code has expired.": "Sorrro, thi cowf ahs arowjers.", + "Sorry, this code only works for new accounts.": "Srror, this cod ojfowf work for know accarrn.", + "Still searching for nearby servers; please try again soon.": "Stjowf sera cj focnwoeir eserevers; pell cutlery a gao cốn.", + "Temporarily unavailable; please try again later.": "Tmwoef wf oucwof wf; cowejf awoj cwoijers.", + "The tournament ended before you finished.": "Thf weoijw oeij aoejf aowejf owjeof aiwjeofjwef.", + "This account cannot be unlinked for ${NUM} days.": "Th ow co ref w owjoso o ${NUM} dyafsoef.", + "This code cannot be used on the account that created it.": "Thiz codf cow oicna weoiw oaijwoefoa sdoausd cjoeri wod.", + "This is currently unavailable; please try again later.": "Tjwoe jej c fjwoief uynvoiejfowij; plaza ffjweo. ona oifowijdfld.", + "This requires version ${VERSION} or newer.": "Thif efowjefo f${VERSION} or wofjweor.", + "Tournaments disabled due to rooted device.": "Toiwfj woicw few doff our r woiwjeowods.", + "Tournaments require ${VERSION} or newer": "Toijfw qojwce ${VERSION} or wcoiwej", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Uncljwf ${ACCOUNT} cowed wthosijf?\nAll cowejt ocjiwf ${ACCOUNT} cowiest dois.\n(expo fowefj etwohoa tand Costers)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "WARNOEF: com owe fw epfojwe. cj weo fjwefo wejfo wef jocij eowiefwef.\nCoaj owe fwefjwoo oweoifwoe fj ewrj woc. Ppel fwo c worywwr.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Wocj weo ocj woiej fowj ofj aioj ojt;oi df joijwotijs?\n\nYoc uweof c owej owijf ${ACCOUNT1}\nThoci wef coj woeijf ${ACCOUNT2}\n\nThoc jweo owej fow cwi efod odo focwoe.\nWocj fo : cwo c weof odo fauoino!", + "You already own this!": "Yz fwowefoi coiweno fjoz!", + "You can join in ${COUNT} seconds.": "You won cowier fwoef ${COUNT} coiwejf.", + "You don't have enough tickets for this!": "Yz dfoiwf ahv weoj fwoitjoicker fz thzz!", + "You don't own that.": "You loci jeff jwoefwe.", + "You got ${COUNT} tickets!": "Y zfowej f${COUNT{ ticeofjwe!", + "You got a ${ITEM}!": "Yzz gtzz z ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Yf co efoj woef woecj owejfoiwef lfj ; congaroiwjf woes!", + "You must update to a newer version of the app to do this.": "Yz mocu upc oig owc owt oc o ca; ;apc oi oj ;oj.", + "You must update to the newest version of the game to do this.": "Yocwe fweoowo weotjosij;ow. woeower weroso taotoautats.", + "You must wait a few seconds before entering a new code.": "Yzz msfgt wt a fz cwcfwf bfrrzz entef wcnfz cdszz.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Yz wf ooiwef #${RANK} ofijwe oijw oijef . Thansf afpaflalay!", + "Your account was rejected. Are you signed in?": "Yoew cowcjwe woe woeiowirwo eirjw co weoijfow ej?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Yr coijw epowf oief oaefoiwfowjef\nPlejasefoaw efojw oefjwoejo aciowejrow.", + "Your friend code was used by ${ACCOUNT}": "Yrrj cof owf owcjowj fwoafeof ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Mínuzz", + "1 Second": "1 Scfmfz", + "10 Minutes": "10 Mínuzz", + "2 Minutes": "2 Mínuzz", + "2 Seconds": "2 Sfljcjfsz", + "20 Minutes": "20 Mínuzz", + "4 Seconds": "4 Sfcljfdz", + "5 Minutes": "5 Mínuzz", + "8 Seconds": "8 Sfcljrjdz", + "Allow Negative Scores": "Alllzz Nglfljcw Scorrzz", + "Balance Total Lives": "Bálncz Tótzl Líves", + "Bomb Spawning": "SOCj efoijw come", + "Chosen One Gets Gloves": "Chózn One Gétz Glóvz", + "Chosen One Gets Shield": "Chózn One Gétz Shíéld", + "Chosen One Time": "Chzénz Ónz Tímz", + "Enable Impact Bombs": "Enfojf Impac BombS", + "Enable Triple Bombs": "Enafojf Tapowef Bobms", + "Entire Team Must Finish": "Enfowief Tem Musc Fiifsf", + "Epic Mode": "Épizc Módz", + "Flag Idle Return Time": "Flág Ídle Rétúrn Tímz", + "Flag Touch Return Time": "Flág Tzch Rétúrn Tímz", + "Hold Time": "Hólz Tímz", + "Kills to Win Per Player": "Kílls tó Wín Pér Plzáyer", + "Laps": "Lápz", + "Lives Per Player": "Lívz Pérz Pláyrr", + "Long": "Lónggz", + "Longer": "Lóngrzz", + "Mine Spawning": "Míne Spáwning", + "No Mines": "Nz Mfjfnzl", + "None": "Núnz", + "Normal": "Nórmzll", + "Pro Mode": "Por Msdf", + "Respawn Times": "Rézpnzz Tímzz", + "Score to Win": "Scúrz té Wínz", + "Short": "Shórtz", + "Shorter": "Shórtzrr", + "Solo Mode": "Sólzo Módz", + "Target Count": "Tfof Coufnfz", + "Time Limit": "Tímz Límtzz" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} oj who cos weoijwoeij c woes ${PLAYER} cjowef", + "Killing ${NAME} for skipping part of the track!": "Kllzng ${NAME} fr ckpoing ocij epo jwof jat!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Wjocief cwf ${NAME}: jojwo / ocjo efoiwefj wcoweok owerjoijdof." + }, + "teamNames": { + "Bad Guys": "Bázd Gúyzs", + "Blue": "Blzúe", + "Good Guys": "Gzóod Gúys", + "Red": "Réd" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Á perfectly timed running-jumping-zpin-punch cán kill in á zingle hit\nánd eárn yóu lifelóng rezpect fróm yóur friendz.", + "Always remember to floss.": "Álwáyz remember tó flózz.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Creáte pláyer prófilez fór yóurzelf ánd yóur friendz with\nyóur preferred námez ánd áppeáráncez inzteád óf uzing rándóm ónez.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Curze bóxez turn yóu intó á ticking time bómb.\nThe ónly cure iz tó quickly gráb á heálth-páck.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Dezpite their lóókz, áll chárácterz' ábilitiez áre identicál,\nzó juzt pick whichever óne yóu mózt clózely rezemble.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Dón't get tóó cócky with thát energy zhield; yóu cán ztill get yóurzelf thrówn óff á cliff.", + "Don't run all the time. Really. You will fall off cliffs.": "Dón't run áll the time. Reálly. Yóu will fáll óff cliffz.", + "Don't spin for too long; you'll become dizzy and fall.": "Dino pcoijw cow erowic ow; ocuwe fowei owie roan faf.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Hóld ány buttón tó run. (Trigger buttónz wórk well if yóu háve them)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Hóld dówn ány buttón tó run. Yóu'll get plácez fázter\nbut wón't turn very well, zó wátch óut fór cliffz.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ice bómbz áre nót very pówerful, but they freeze\nwhóever they hit, leáving them vulneráble tó zháttering.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "If zómeóne pickz yóu up, punch them ánd they'll let gó.\nThiz wórkz in reál life tóó.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Iffz oc wo acoiw oifj woc ojef '${REMOTE_APP_NAME}' ars\noc of code pow c owe fowjfoijweojc oocjwef.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "If yóu áre zhórt ón cóntróllerz, inztáll the 'BómbZquád Remóte' ápp\nón yóur iÓZ ór Ándróid devicez tó uze them áz cóntróllerz.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "If yóu get á zticky-bómb ztuck tó yóu, jump áróund ánd zpin in circlez. Yóu might\nzháke the bómb óff, ór if nóthing elze yóur lázt mómentz will be entertáining.", + "If you kill an enemy in one hit you get double points for it.": "If yóu kill án enemy in óne hit yóu get dóuble póintz fór it.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "If yóu pick up á curze, yóur ónly hópe fór zurvivál iz tó\nfind á heálth pówerup in the next few zecóndz.", + "If you stay in one place, you're toast. Run and dodge to survive..": "If yóu ztáy in óne pláce, yóu're tóázt. Run ánd dódge tó zurvive..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "If yóu've gót lótz óf pláyerz cóming ánd góing, turn ón 'áutó-kick-idle-pláyerz'\nunder zettingz in cáze ányóne fórgetz tó leáve the gáme.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Iw fowj eoaj wecojaw ;eofja ;woefj ;aowiejoawjef;oajw;eofja; wef\naoj etoaj ;cojwe;aoj ef;oawe; faw;oe fj;aow e;owjef;oajf", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "If yóur frámeráte iz chóppy, try turning dówn rezólutión\nór vizuálz in the gáme'z gráphicz zettingz.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "In Cápture-the-Flág, yóur ówn flág muzt be át yóur báze tó zcóre, If the óther\nteám iz ábóut tó zcóre, zteáling their flág cán be á góód wáy tó ztóp them.", + "In hockey, you'll maintain more speed if you turn gradually.": "In hóckey, yóu'll máintáin móre zpeed if yóu turn gráduálly.", + "It's easier to win with a friend or two helping.": "It'z eázier tó win with á friend ór twó helping.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Jump juzt áz yóu're thrówing tó get bómbz up tó the highezt levelz.", + "Land-mines are a good way to stop speedy enemies.": "Lánd-múnes áré z gúod wáy tó stóp spéédy enémíes.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Mány thingz cán be picked up ánd thrówn, including óther pláyerz. Tózzing\nyóur enemiez óff cliffz cán be án effective ánd emótiónálly fulfilling ztrátegy.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nó, yóu cán't get up ón the ledge. Yóu háve tó thrów bómbz.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Plref can join and flasdj afl ion the mdc aosdfoasdf,\naodf sdoyuou can aodfj asdfpluf asdna moasdfp sdfocnor.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Pláyerz cán jóin ánd leáve in the middle óf mózt gámez,\nánd yóu cán álzó plug ánd unplug gámepádz ón the fly.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Pówerupz ónly háve time limitz in có-óp gámez.\nIn teámz ánd free-fór-áll they're yóurz until yóu die.", + "Practice using your momentum to throw bombs more accurately.": "Práctice uzing yóur mómentum tó thrów bómbz móre áccurátely.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Punchez dó móre dámáge the fázter yóur fiztz áre móving,\nzó try running, jumping, ánd zpinning like crázy.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Run báck ánd fórth befóre thrówing á bómb\ntó 'whiplázh' it ánd thrów it fárther.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Táke óut á gróup óf enemiez by\nzetting óff á bómb neár á TNT bóx.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "The heád iz the mózt vulneráble áreá, zó á zticky-bómb\ntó the nóggin uzuálly meánz gáme-óver.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Thiz level never endz, but á high zcóre here\nwill eárn yóu eternál rezpect thróughóut the wórld.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Thrów ztrength iz bázed ón the directión yóu áre hólding.\nTó tózz zómething gently in frónt óf yóu, dón't hóld ány directión.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Trrd fo toasdoasdfm? Ararap cale fasoif;osda!\nSe sdfoajs dof cjspdof apsodi paosdjf", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Try 'Cóóking óff' bómbz fór á zecónd ór twó befóre thrówing them.", + "Try tricking enemies into killing eachother or running off cliffs.": "Try tricking enemiez intó killing eáchóther ór running óff cliffz.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Uze the pick-up buttón tó gráb the flág < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Whip báck ánd fórth tó get móre diztánce ón yóur thrówz..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Yóu cán 'áim' yóur punchez by zpinning left ór right.\nThiz iz uzeful fór knócking bád guyz óff edgez ór zcóring in hóckey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Yóu cán judge when á bómb iz góing tó explóde bázed ón the\ncólór óf zpárkz fróm itz fuze: yellów..óránge..red..BÓÓM.", + "You can throw bombs higher if you jump just before throwing.": "Yóu cán thrów bómbz higher if yóu jump juzt befóre thrówing.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Yóu dón't need tó edit yóur prófile tó chánge chárácterz; Juzt prezz the tóp\nbuttón (pick-up) when jóining á gáme tó óverride yóur defáult.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Yóu táke dámáge when yóu wháck yóur heád ón thingz,\nzó try tó nót wháck yóur heád ón thingz.", + "Your punches do much more damage if you are running or spinning.": "Yóur punchez dó much móre dámáge if yóu áre running ór zpinning." + } + }, + "trialPeriodEndedText": "Yozr tríal púrizd hás úndzd. Wóuld yóu lúke\ntz pórchúse BómbSquád ánd kéép plzying?", + "trophiesRequiredText": "This cow fwoeif of ${NUMBER} cowejfwe", + "trophiesText": "Tjfpojfz", + "trophiesThisSeasonText": "Trphpc Thzi Ssrcon", + "tutorial": { + "cpuBenchmarkText": "Rnnging tuoriral fan lurkdc-spdd (primirarl ytest CPU spd)", + "phrase01Text": "Hz Thrzfl!", + "phrase02Text": "Wlgjlmcz tz ${APP_NAME}!", + "phrase03Text": "Hrllz a fjflf tijpefa fjor conotrlaij yoru chchrirzzzr:", + "phrase04Text": "Mntn thngo foin boia${APP_NAME}foibajsfdo aoh PCHYRALZ bajffz.", + "phrase05Text": "Frjo exnapfdnp, whfz ynz pnpchru...", + "phrase06Text": "..dmglaf iz bzfz onf zpdfz ofz yrz fzfassz.", + "phrase07Text": "Szz.? Wz wrjogz mvojgsfz so that barelzl hurt ${NAME}.", + "phrase08Text": "Nwz ltzf jmpz n spnz tz gtz mrz spdfrz.", + "phrase09Text": "Ahz thzjo's b;rtjz.", + "phrase10Text": "Rngjgojz hpzpoijr too.", + "phrase11Text": "Hzljt fjofj ANZ butlzf tz rnzrlz.", + "phrase12Text": "Frz txpro-apwez pnpghch, trz rnognp ANZ pafong;z.", + "phrase13Text": "Whppz; srryz 'bout that ${NAME}.", + "phrase14Text": "Yz cnz pick ups nz trhowz thgfz szhc az flglafz.. or ${NAME}.", + "phrase15Text": "Lasfzjtoz, thzfzo bmjgz.", + "phrase16Text": "Throwzlf bmgzz tkzgfz prcgjtoz.", + "phrase17Text": "Oucz! Nzt a vrz gdz thrworz.", + "phrase18Text": "Mvngofj hpzrz yz throwz fratherz.", + "phrase19Text": "Jmpngpg hpz yz thorwz highrzr.", + "phrase20Text": "\"whoppers\" yrs bomgjl for enve longer thowawrz.", + "phrase21Text": "Tmingo yr bombos cnz bs trixkrz.", + "phrase22Text": "Dngz.", + "phrase23Text": "Try \"ckkzllj off\" thz fuze frs a scrnd orz stwoz.", + "phrase24Text": "Hrrzrlar! Nirlefzl cokkred.", + "phrase25Text": "Wllz, thrat's jztst borts itz.", + "phrase26Text": "Nowz gz get'z em tzgrrs!", + "phrase27Text": "Rembjgeorz yrz trnings, andz yz WLLZ cmd bazk alvss!", + "phrase28Text": "..wllz.mbbfyz..", + "phrase29Text": "Gddz lkxks!", + "randomName1Text": "Fréz", + "randomName2Text": "Hurrzl", + "randomName3Text": "Bllfz", + "randomName4Text": "Chrjrzl", + "randomName5Text": "Phllz", + "skipConfirmText": "Rlldf asdf oajc sdjf asodf asdf? dfj oasidj foasdc.", + "skipVoteCountText": "${COUNT}/${TOTAL} skpzj vnttjzlz", + "skippingText": "skpzjflj toutoroafjz...", + "toSkipPressAnythingText": "(tpz rz pzrzl anthfljzf tz skpfz tuzfjrlrrz)" + }, + "twoKillText": "DÓÚBLZ KÍLL!", + "unavailableText": "unavlfldsfjlbz", + "unconfiguredControllerDetectedText": "Uncónfzgúred cúntrzllír dítzctíd:", + "unlockThisInTheStoreText": "Thz mf voi eunlcoef owef joiefsfrwe.", + "unlockThisProfilesText": "To cowier co we ${NUM} pcoer, cow oicoj:", + "unlockThisText": "Tz ncowifj ocje, ycon fneeds:", + "unsupportedHardwareText": "Srrz, thz hardwrz isz nt spprted bz thz vejerelr dlzl gmpzz.", + "upFirstText": "Uzp férzt:", + "upNextText": "Úp nézt ín gámz ${COUNT}:", + "updatingAccountText": "Updfoifjz yrrl cacmrmr...", + "upgradeText": "Upgrorz", + "upgradeToPlayText": "Upgglf tz \"${PRO}\" iz j wojcwoef paljf zs.", + "useDefaultText": "Uzl Dflfjtzlz", + "usesExternalControllerText": "Thz gjf coiwjef oif owicoiwefj owejf owejoojof", + "usingItunesText": "Ufwefw Mfwoef co ef srnweoicjowe...", + "usingItunesTurnRepeatAndShuffleOnText": "Plzelz mkdk srzlc shfflds isON anz andpreld is ALZ unz iTunes", + "v2AccountLinkingInfoText": "To ljeowirj V2 sojowe, use fo 'Mnawefw Acoiwo' bons.", + "validatingBetaText": "Válúdztíng Bztá...", + "validatingTestBuildText": "Vldfjdfoi jtese-bsdfasfd...", + "victoryText": "Vúctzry!", + "voteDelayText": "You caecowe oefo wocj woeiwo ${NUMBER} wocijwoef.", + "voteInProgressText": "A voiajf coiwje fwooeio wcwer.", + "votedAlreadyText": "C who foil owejrs", + "votesNeededText": "${NUMBER} vowjeowi jw oefwe", + "vsText": "vús.", + "waitingForHostText": "(twatijf ffarz ${HOST} to cnfojoweifz)", + "waitingForLocalPlayersText": "wzzéatnng fér lzcal pzéayers...", + "waitingForPlayersText": "wtnginag frz plers to jnnz..", + "waitingInLineText": "Wowcij cowije fo wf(powc owe oweir)...", + "watchAVideoText": "Few A covjowdf", + "watchAnAdText": "e aowej ocjowef", + "watchWindow": { + "deleteConfirmText": "Delzdfe \"${REPLAY}\"?", + "deleteReplayButtonText": "Dlrlrjz\nRplrlz", + "myReplaysText": "Mz Rplgllz", + "noReplaySelectedErrorText": "Nz Rplglz Slelectdz", + "playbackSpeedText": "Plwecowi jef SPcowef ${SPEED}", + "renameReplayButtonText": "Rnrmz\nRplrlrz", + "renameReplayText": "Rnmgm \"${REPLAY}\" tz:", + "renameText": "Rnzmz", + "replayDeleteErrorText": "Errlz dlernlg rmllzlz", + "replayNameText": "Rpprlz Nmz", + "replayRenameErrorAlreadyExistsText": "A rnofk wug h af c adfkahf wcuiuhz,", + "replayRenameErrorInvalidName": "Can'f co fojo sf oiejc n vailid anme.", + "replayRenameErrorText": "Errz rnemvifj rpcojz.", + "sharedReplaysText": "Srhrrm Rplclrlz.", + "titleText": "Wtcchs", + "watchReplayButtonText": "Wtchf\nRplzz" + }, + "waveText": "Wávz", + "wellSureText": "Wélz Súre!", + "whatIsThisText": "Who come woeirjwf?", + "wiimoteLicenseWindow": { + "licenseText": "Copyríght (c) 2007, DarwíínRúmotú Túam\nAll ríghtz rúzúrvúd.\n\n Rúdíztríbutíon and uzú ín zourcú and bínary formz, wíth or wíthout modífícatíon,\n arú púrmíttúd provídúd that thú followíng condítíonz arú mút:\n\n1. Rúdíztríbutíonz of zourcú codú muzt rútaín thú abovú copyríght notícú, thíz\n lízt of condítíonz and thú followíng dízclaímúr.\n2. Rúdíztríbutíonz ín bínary form muzt rúproducú thú abovú copyríght notícú, thíz\n lízt of condítíonz and thú followíng dízclaímúr ín thú documúntatíon and/or othúr\n matúríalz provídúd wíth thú díztríbutíon.\n3. Núíthúr thú namú of thíz projúct nor thú namúz of ítz contríbutorz may bú uzúd to\n úndorzú or promotú productz dúrívúd from thíz zoftwarú wíthout zpúcífíc príor\n wríttún púrmízzíon.\n\nTHÍZ ZOFTWARÚ ÍZ PROVÍDÚD BY THÚ COPYRÍGHT HOLDÚRZ AND CONTRÍBUTORZ \"AZ ÍZ\"\nAND ANY ÚXPRÚZZ OR ÍMPLÍÚD WARRANTÍÚZ, ÍNCLUDÍNG, BUT NOT LÍMÍTÚD TO, THÚ\nÍMPLÍÚD WARRANTÍÚZ OF MÚRCHANTABÍLÍTY AND FÍTNÚZZ FOR A PARTÍCULAR PURPOZÚ\nARÚ DÍZCLAÍMÚD. ÍN NO ÚVÚNT ZHALL THÚ COPYRÍGHT OWNÚR OR CONTRÍBUTORZ BÚ\nLÍABLÚ FOR ANY DÍRÚCT, ÍNDÍRÚCT, ÍNCÍDÚNTAL, ZPÚCÍAL, ÚXÚMPLARY, OR\nCONZÚQUÚNTÍAL DAMAGÚZ (ÍNCLUDÍNG, BUT NOT LÍMÍTÚD TO, PROCURÚMÚNT OF\n ZUBZTÍTUTÚ GOODZ OR ZÚRVÍCÚZ; LOZZ OF UZÚ, DATA, OR PROFÍTZ; OR BUZÍNÚZZ\nÍNTÚRRUPTÍON) HOWÚVÚR CAUZÚD AND ON ANY THÚORY OF LÍABÍLÍTY, WHÚTHÚR ÍN\nCONTRACT, ZTRÍCT LÍABÍLÍTY, OR TORT (ÍNCLUDÍNG NÚGLÍGÚNCÚ OR OTHÚRWÍZÚ)\nARÍZÍNG ÍN ANY WAY OUT OF THÚ UZÚ OF THÍZ ZOFTWARÚ, ÚVÚN ÍF ADVÍZÚD OF THÚ\nPOZZÍBÍLÍTY OF ZUCH DAMAGÚ.\n", + "licenseTextScale": 0.62, + "titleText": "DarwiónReéoze Czpyrúght" + }, + "wiimoteListenWindow": { + "listeningText": "Líszéngng Fúr Wíímztes...", + "pressText": "Prész Wíimzte bóttzns 1 azd 2 símultáneoúsly.", + "pressText2": "Onz néwer Wiímótes wíth Moóión Plús búilt ón, przss thé réd 'sync' búttón ón thé bzck ónstzad.", + "pressText2Scale": 0.55, + "pressTextScale": 1.0 + }, + "wiimoteSetupWindow": { + "copyrightText": "DúrwéinRemzote Cúpyrzght", + "copyrightTextScale": 0.6, + "listenText": "Lústzn", + "macInstructionsText": "Makú zurú your Wáá áz off and Bluútooth áz únablúd\non your Mac, thún prúzz 'Láztún'. Wáámotú zupport can\nbú a bát flaky, zo you may havú to try a fúw támúz\nbúforú you gút a connúctáon.\n\nBluútooth zhould handlú up to 7 connúctúd dúvácúz,\nthough your málúagú may vary.\n\nBombZquad zupportz thú orágánal Wáámotúz, Nunchukz,\nand thú Clazzác Controllúr.\nThú núwúr Wáá Rúmotú Pluz now workz too\nbut not wáth attachmúntz.", + "macInstructionsTextScale": 0.7, + "thanksText": "Thznks té thz DérwiinRémote táam\nFúr máking thés pzsséble.", + "thanksTextScale": 0.8, + "titleText": "Wzimóte Sztúp" + }, + "winsPlayerText": "${NAME} Wnzpl!", + "winsPluralText": "${NAME} WznflPP!", + "winsSingularText": "${NAME} WinzfjlzSS!", + "winsTeamText": "${NAME} Wnttm!", + "winsText": "${NAME} Wínsz!", + "workspaceSyncErrorText": "Eeror ocijo itself ${WORKSPACE}. See zoo crew tcowdf.", + "workspaceSyncReuseText": "Cnoiwj zoo ${WORKSPACE}. ROI cw cwoerpwer housers.", + "worldScoresUnavailableText": "Wrlzld scrzzl unvlfldsjbzl.", + "worldsBestScoresText": "Wúrld's Bést Scórzs", + "worldsBestTimesText": "Wúrld's Bzst Tímés", + "xbox360ControllersWindow": { + "getDriverText": "Gét Drúvzr", + "macInstructions2Text": "Tá uzá cántrállárz wirálázzly, yáu'll alzá náád thá rácáivár that\ncámáz with thá 'Xbáx 360 Wirálázz Cántrállár fár Windáwz'.\nÁná rácáivár alláwz yáu tá cánnáct up tá 4 cántrállárz.\n\nImpártant: 3rd-party rácáivárz will nát wárk with thiz drivár;\nmaká zurá yáur rácáivár zayz 'Micrázáft' án it, nát 'XBÁX 360'.\nMicrázáft ná lángár zállz tházá záparatály, zá yáu'll náád tá gát\nthá áná bundlád with thá cántrállár ár álzá záarch ábay.\n\nIf yáu find thiz uzáful, pláazá cánzidár a dánatián tá thá\ndrivár dáválápár at hiz zitá.", + "macInstructions2TextScale": 0.76, + "macInstructionsText": "Tó uzá Xbóx 360 cóntróllárz, yóu'll náád tó inztall\nthá Mac drivár availablá at thá link bálów.\nIt wórkz with bóth wirád and wirálázz cóntróllárz..", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Tz úze wéred Xbzx 360 czntrzllerz wéth yzúr ZÚYA, zémply\nplúg them én the ZÚYA'z ÚZB pzrt. Yzú can úze a ÚZB húb\ntz cznnect múltéple czntrzllerz.\n\nTz úze wérelezz czntrzllerz yzú'll need a wérelezz receéver,\navaélable az part zf the \"Xbzx 360 wérelezz Czntrzller fzr Wéndzwz\"\npackage zr zzld zeparately. Each receéver plúgz éntz a ÚZB pzrt and\nallzwz yzú tz cznnect úp tz 4 wérelezz czntrzllerz..", + "ouyaInstructionsTextScale": 0.8, + "titleText": "Uzíng Xbóx 360 Cónztróllzrs wzth ${APP_NAME}:" + }, + "yesAllowText": "Yús, Allúwz!", + "yourBestScoresText": "Yózr Bést Scúrzszz", + "yourBestTimesText": "Yózr Bést Tímés" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/greek.json b/dist/ba_data/data/languages/greek.json new file mode 100644 index 0000000..decc2bb --- /dev/null +++ b/dist/ba_data/data/languages/greek.json @@ -0,0 +1,1884 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Τα ονόματα δεν μπορούν να περιέχουν emoji ή άλλους ειδικούς χαρακτήρες", + "accountsText": "Λογαριασμοί", + "achievementProgressText": "Επιτεύγματα: ${COUNT} από ${TOTAL}", + "campaignProgressText": "Πρόοδος Ιστορίας [Δύσκολο]: ${PROGRESS}", + "changeOncePerSeason": "Μπορείτε να το αλλάξετε μόνο μία φορά ανά σεζόν.", + "changeOncePerSeasonError": "Πρέπει να περιμένετε μέχρι την επόμενη σεζόν για να το αλλάξετε ξανά (${NUM} days)", + "customName": "Προσαρμοσμένο Όνομα", + "googlePlayGamesAccountSwitchText": "Αν θέλετε να χρησιμοποιείσετε έναν διφορετικό λογαριασμό Google,\nχρησιμοποιείστε την εφαρμογή Google Play Games γιανα αλλάξετε.", + "linkAccountsEnterCodeText": "Εισάγετε Κωδικό", + "linkAccountsGenerateCodeText": "Δημιουργήστε Κωδικό", + "linkAccountsInfoText": "(Μοιραστείτε την πρόοδο ανάμεσα σε διάφορες πλατφόρμες)", + "linkAccountsInstructionsNewText": "Για να δεσμεύσετε δύο λογαριασμούς μεταξύ τους, δημιούργήστε έναν\nκωδικό στον πρώτο και εισάγετέ τον στον δεύτερο. Τα δεδομένα \nμεταξύ των δύο θα συγχωνευτούν με τον δεύτερο λογαριασμό.\n(τα δεδομένα από τον πρώτο λογαριασμό θα χαθούν)\n\nΜπορείτε να δεσμεύσετε εώς και ${COUNT} λογαριασμούς.\n\nΣΗΜΑΝΤΙΚΟ: δεσμεύστε μόνο λογαριασμούς που σας ανήκουν!\nΆμα δεσμεύσετε με τον λογαριασμό ενός φίλου σας δεν θα\nμπορείτε να παίξετε online ταυτόχρονα.", + "linkAccountsInstructionsText": "Για να ενώσετε δυο λογαριασμούς, δημιουργήστε κωδικό\nσε έναν από αυτούς και εισάγετέ τον στον άλλο.\nΗ πρόοδος και τα περιεχόμενα θα συγχωνεύθουν.\nΜπορείτε να ενώσεις μέχρι και ${COUNT} λογαριασμούς.\n\nΠροσοχή: η ενέργεια είναι μη αναστρέψιμη!\n\n", + "linkAccountsText": "Δεσμεύστε Λογαριασμούς", + "linkedAccountsText": "Δεσεμευμένοι λογαριασμοί:", + "manageAccountText": "Διαχείρειση λογαριασμού", + "nameChangeConfirm": "Αλλαγή του ονόματος του λογαριασμού σας σε ${NAME};", + "resetProgressConfirmNoAchievementsText": "Αυτό θα επαναφέρει τη πρόοδο σας στη \"συνεργασία\" και τις\nτοπικές υψηλές σας βαθμολογίες (αλλά όχι τα εισιτήρια).\nΗ ενέργεια είναι μη αντιστρέψιμη. Είστε σίγουροι;", + "resetProgressConfirmText": "Αυτό θα επαναφέρει τη πρόοδο σας στη \"συνεργασία\",\nτα επιτεύγματα και τις τοπικές υψηλές σας\nβαθμολογίες (αλλά όχι τα εισιτήρια). Η ενέργεια\nείναι μη αντιστρέψιμη. Είστε σίγουροι;", + "resetProgressText": "Επαναφορά Προόδου.", + "setAccountName": "Ορισμός Ονόματος Λογαριασμού", + "setAccountNameDesc": "Επιλέξτε το όνομα που θα φαίνεται στο λογαριασμό σας. Μπορείτε\nνα χρησιμοποιήσετε το όνομα ενός από τους δεσμευμένους σας\nλογαριασμούς ή να δημιουργήσετε ένα μοναδικό, προσαρμοσμένο όνομα.", + "signInInfoText": "Συνδεθείτε για να συλλέξετε εισητήρια, να συναγωνιστείτε στο διαδίκτυο\nκαι να μοιραστείτε τη πρόοδο σας ανάμεσα σε διάφορες συσκευές.", + "signInText": "Σύνδεση", + "signInWithDeviceInfoText": "(ένας λογαριασμός μονάχα διαθέσιμος από αυτή τη συσκευή)", + "signInWithDeviceText": "Σύνδεση με λογαριασμό συσκευής", + "signInWithGameCircleText": "Σύνδεση με Game Circle", + "signInWithGooglePlayText": "Σύνδεση με Google Play", + "signInWithTestAccountInfoText": "(προσωρινός λογαριασμός. Δημιουργήστε λογαριασμό συσκευής για συνέχιση προόδου)", + "signInWithTestAccountText": "Σύνδεση με δοκιμαστικό λογαριασμό", + "signInWithV2InfoText": "ένας λογαριασμός που λειτουργεί σε όλες τις πλατφορμες", + "signInWithV2Text": "Συνδεθείτε με ένα λογαριασμό BombSquad", + "signOutText": "Αποσύνδεση", + "signingInText": "Σύνδεση...", + "signingOutText": "Αποσύνδεση...", + "ticketsText": "Εισιτήρια: ${COUNT}", + "titleText": "Λογαριασμός", + "unlinkAccountsInstructionsText": "Επιλέξτε έναν λογαριασμό για αποδέσμευση", + "unlinkAccountsText": "Αποδέσμευση Λογαριασμών", + "v2LinkInstructionsText": "Χρησημοποιήστε αυτόν τον σύνδεσμο για να δημιουργήσετε έναν λογαριασμό ή για να συνδεθείτε.", + "viaAccount": "(μέσω λογαριασμού ${NAME})", + "youAreSignedInAsText": "Είστε συνδεδεμένοι ως:" + }, + "achievementChallengesText": "Προκλήσεις Επιτευγμάτων", + "achievementText": "Επίτευγμα", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Σκοτώστε 3 κακούς με TNT", + "descriptionComplete": "Σκοτώσατε 3 κακούς με TNT", + "descriptionFull": "Σκοτώστε 3 κακούς με TNT στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοτώσατε 3 κακούς με TNT στο επίπεδο ${LEVEL}", + "name": "Ο Δυναμίτης Κάνει Μπούμ" + }, + "Boxer": { + "description": "Νικήστε χωρίς να χρησιμοποιήσετε βόμβες", + "descriptionComplete": "Νικήσατε χωρίς να χρησιμοποιήσετε βόμβες", + "descriptionFull": "Ολοκληρώστε το επίπεδο ${LEVEL} χωρίς να χρησιμοποιήσετε βόμβες", + "descriptionFullComplete": "Ολοκληρώσατε το επίπεδο ${LEVEL} χωρίς να χρησιμοποιήσετε βόμβες", + "name": "Πυγμάχος" + }, + "Dual Wielding": { + "descriptionFull": "Συνδέστε 2 χειριστήρια (υλισμικό ή εφαρμογή)", + "descriptionFullComplete": "Συνδέσατε 2 χειριστήρια (υλισμικό ή εφαρμογή)", + "name": "Διπλό Κράτημα" + }, + "Flawless Victory": { + "description": "Νικήστε χωρίς να χτυπηθείτε", + "descriptionComplete": "Νικήσατε χωρίς να χτυπηθείτε", + "descriptionFull": "Νικήστε το επίπεδο ${LEVEL} χωρίς να χτυπηθείτε", + "descriptionFullComplete": "Νικήσατε το επίπεδο ${LEVEL} χωρίς να χτυπηθείτε", + "name": "Άψογη Νίκη" + }, + "Free Loader": { + "descriptionFull": "Ξεκινήστε ένα παιχνίδι Free-For-All με 2+ παίκτες", + "descriptionFullComplete": "Ξεκινήσατε ένα παιχνίδι Free-For-All με 2+ παίκτες", + "name": "Είσοδος Ελεύθερη" + }, + "Gold Miner": { + "description": "Σκοτώστε 6 κακούς με νάρκες-εδάφους", + "descriptionComplete": "Σκοτώσατε 6 κακούς με νάρκες-εδάφους", + "descriptionFull": "Σκοτώστε 6 κακούς με νάρκες-εδάφους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοτώσατε 6 κακούς με νάρκες-εδάφους στο επίπεδο ${LEVEL}", + "name": "Χρυσορύχος" + }, + "Got the Moves": { + "description": "Νικήστε χωρίς να χρησιμοποιήσετε γροθιές ή βόμβες", + "descriptionComplete": "Νικήσατε χωρίς να χρησιμοποιήσετε γροθιές ή βόμβες", + "descriptionFull": "Νικήστε το επίπεδο ${LEVEL} χωρίς να χρησιμοποιήσετε γροθιές ή βόμβες", + "descriptionFullComplete": "Νικήσατε το επίπεδο ${LEVEL} χωρίς να χρησιμοποιήσετε γροθιές ή βόμβες", + "name": "Επιδέξιες Κινήσεις" + }, + "In Control": { + "descriptionFull": "Συνδέστε ένα χειριστήριο (υλισμικό ή εφαρμογή)", + "descriptionFullComplete": "Συνδέσατε ένα χειριστήριο (υλισμικό ή εφαρμογή)", + "name": "Υπό Έλεγχο" + }, + "Last Stand God": { + "description": "Σκοράρετε 1000 πόντους", + "descriptionComplete": "Σκοράρατε 1000 πόντους", + "descriptionFull": "Σκοράρετε 1000 πόντους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοράρατε 1000 πόντους στο επίπεδο ${LEVEL}", + "name": "Θεός του επιπέδου ${LEVEL}" + }, + "Last Stand Master": { + "description": "Σκοράρετε 250 πόντους", + "descriptionComplete": "Σκοράρατε 250 πόντους", + "descriptionFull": "Σκοράρετε 250 πόντους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοράρατε 250 πόντους στο επίπεδο ${LEVEL}", + "name": "Άρχοντας του επιπέδου ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Σκοράρετε 500 πόντους", + "descriptionComplete": "Σκοράρατε 500 πόντους", + "descriptionFull": "Σκοράρετε 500 πόντους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοράρατε 500 πόντους στο επίπεδο ${LEVEL}", + "name": "Μάγος του επιπέδου ${LEVEL}" + }, + "Mine Games": { + "description": "Σκοτώστε 3 κακούς με νάρκες-εδάφους", + "descriptionComplete": "Σκοτώσατε 3 κακούς με νάρκες-εδάφους", + "descriptionFull": "Σκοτώστε 3 κακούς με νάρκες-εδάφους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοτώσατε 3 κακούς με νάρκες-εδάφους στο επίπεδο ${LEVEL}", + "name": "Αγώνες Νάρκης" + }, + "Off You Go Then": { + "description": "Πετάξτε 3 κακούς εκτός χάρτη", + "descriptionComplete": "Πετάξατε 3 κακούς εκτός χάρτη", + "descriptionFull": "Πετάξτε 3 κακούς εκτός χάρτη στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Πετάξατε 3 κακούς εκτός χάρτη στο επίπεδο ${LEVEL}", + "name": "Πέταξε Το Πουλάκι" + }, + "Onslaught God": { + "description": "Σκοράρετε 5000 πόντους", + "descriptionComplete": "Σκοράρατε 5000 πόντους", + "descriptionFull": "Σκοράρετε 5000 πόντους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοράρατε 5000 πόντους στο επίπεδο ${LEVEL}", + "name": "Θεός του επιπέδου ${LEVEL}" + }, + "Onslaught Master": { + "description": "Σκοράρετε 500 πόντους", + "descriptionComplete": "Σκοράρατε 500 πόντους", + "descriptionFull": "Σκοράρετε 500 πόντους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοράρατε 500 πόντους στο επίπεδο ${LEVEL}", + "name": "Άρχοντας του επιπέδου ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Νικήστε όλα τα κύματα", + "descriptionComplete": "Νικήσατε όλα τα κύματα", + "descriptionFull": "Νικήστε όλα τα κύματα στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Νικήσατε όλα τα κύματα στο επίπεδο ${LEVEL}", + "name": "Νίκη στο επίπεδο ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Σκοράρετε 1000 πόντους", + "descriptionComplete": "Σκοράρατε 1000 πόντους", + "descriptionFull": "Σκοράρετε 1000 πόντους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοράρατε 1000 πόντους στο επίπεδο ${LEVEL}", + "name": "Μάγος του επιπέδου ${LEVEL}" + }, + "Precision Bombing": { + "description": "Νικήστε χωρίς ενισχυτικά", + "descriptionComplete": "Νικήσατε χωρίς ενισχυτικά", + "descriptionFull": "Νικήστε το επίπεδο ${LEVEL} χωρίς ενισχυτικά", + "descriptionFullComplete": "Νικήσατε το επίπεδο ${LEVEL} χωρίς ενισχυτικά", + "name": "Βομβαρδισμός Ακριβείας" + }, + "Pro Boxer": { + "description": "Νικήστε χωρίς να χρησιμοποιήσετε βόμβες", + "descriptionComplete": "Νικήσατε χωρίς να χρησιμοποιήσετε βόμβες", + "descriptionFull": "Ολοκληρώστε το επίπεδο ${LEVEL} χωρίς να χρησιμοποιήσετε βόμβες", + "descriptionFullComplete": "Ολοκληρώσατε το επίπεδο ${LEVEL} χωρίς να χρησιμοποιήσετε βόμβες", + "name": "Επαγγελματίας Πυγμάχος" + }, + "Pro Football Shutout": { + "description": "Νικήστε χωρίς να αφήσετε τους κακούς να σκοράρουν", + "descriptionComplete": "Νικήσατε χωρίς να αφήσετε τους κακούς να σκοράρουν", + "descriptionFull": "Νικήστε το επίπεδο ${LEVEL} χωρίς να αφήσετε τους κακούς να σκοράρουν", + "descriptionFullComplete": "Νικήσατε το επίπεδο ${LEVEL} χωρίς να αφήσετε τους κακούς να σκοράρουν", + "name": "${LEVEL} Απόκλιση" + }, + "Pro Football Victory": { + "description": "Νικήστε τον αγώνα", + "descriptionComplete": "Νικήσατε τον αγώνα", + "descriptionFull": "Νικήστε τον αγώνα στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Νικήσατε τον αγώνα στο επίπεδο ${LEVEL}", + "name": "Νίκη στο επίπεδο ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Νικήστε όλα τα κύματα", + "descriptionComplete": "Νικήσατε όλα τα κύματα", + "descriptionFull": "Νικήστε όλα τα κύματα του επιπέδου ${LEVEL}", + "descriptionFullComplete": "Νικήσατε όλα τα κύματα του επιπέδου ${LEVEL}", + "name": "Νίκη στο επίπεδο ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Απωθήστε όλα τα κύματα", + "descriptionComplete": "Απωθήσατε όλα τα κύματα", + "descriptionFull": "Απωθήστε όλα τα κύματα στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Απωθήσατε όλα τα κύματα στο επίπεδο ${LEVEL}", + "name": "Νίκη στο επίπεδο ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Νικήστε χωρίς να αφήσετε τους κακούς να σκοράρουν", + "descriptionComplete": "Νικήσατε χωρίς να αφήσετε τους κακούς να σκοράρουν", + "descriptionFull": "Νικήστε στο επίπεδο ${LEVEL} χωρίς να αφήσετε τους κακούς να σκοράρουν", + "descriptionFullComplete": "Νικήσατε στο επίπεδο ${LEVEL} χωρίς να αφήσετε τους κακούς να σκοράρουν", + "name": "${LEVEL} Απόκλιση" + }, + "Rookie Football Victory": { + "description": "Νικήστε τον αγώνα", + "descriptionComplete": "Νικήσατε τον αγώνα", + "descriptionFull": "Νικήστε τον αγώνα στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Νικήσατε τον αγώνα στο επίπεδο ${LEVEL}", + "name": "Νίκη στο επίπεδο ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Νικήστε όλα τα κύματα", + "descriptionComplete": "Νικήσατε όλα τα κύματα", + "descriptionFull": "Νικήστε όλα τα κύματα στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Νικήσατε όλα τα κύματα στο επίπεδο ${LEVEL}", + "name": "Νίκη στο επίπεδο ${LEVEL}" + }, + "Runaround God": { + "description": "Σκοράρετε 2000 πόντους", + "descriptionComplete": "Σκοράρατε 2000 πόντους", + "descriptionFull": "Σκοράρετε 2000 πόντους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοράρατε 2000 πόντους στο επίπεδο ${LEVEL}", + "name": "Θεός του επιπέδου ${LEVEL}" + }, + "Runaround Master": { + "description": "Σκοράρετε 500 πόντους", + "descriptionComplete": "Σκοράρατε 500 πόντους", + "descriptionFull": "Σκοράρετε 500 πόντους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοράρατε 500 πόντους στο επίπεδο ${LEVEL}", + "name": "Άρχοντας του επιπέδου ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Σκοράρετε 1000 πόντους", + "descriptionComplete": "Σκοράρατε 1000 πόντους", + "descriptionFull": "Σκοράρετε 1000 πόντους στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοράρατε 1000 πόντους στο επίπεδο ${LEVEL}", + "name": "Μάγος του επιπέδου ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Μοιραστείτε επιτυχώς το παιχνίδι με έναν φίλο", + "descriptionFullComplete": "Μοιραστήκατε επιτυχώς το παιχνίδι με έναν φίλο", + "name": "Μοιραστείτε και Νοιαστείτε" + }, + "Stayin' Alive": { + "description": "Νικήστε χωρίς να πεθάνετε", + "descriptionComplete": "Νικήσατε χωρίς να πεθάνετε", + "descriptionFull": "Νικήστε στο επίπεδο ${LEVEL} χωρίς να πεθάνετε", + "descriptionFullComplete": "Νικήσατε στο επίπεδο ${LEVEL} χωρίς να πεθάνετε", + "name": "Παραμένοντας Ζωντανός" + }, + "Super Mega Punch": { + "description": "Προκαλέστε 100% ζημιά με μιά γροθιά", + "descriptionComplete": "Προκαλέσατε 100% ζημιά με μιά γροθιά", + "descriptionFull": "Προκαλέστε 100% ζημιά με μιά γροθιά στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Προκαλέσατε 100% ζημιά με μιά γροθιά στο επίπεδο ${LEVEL}", + "name": "Πανίσχυρη Γροθιά" + }, + "Super Punch": { + "description": "Προκαλέστε 50% ζημιά με μιά γροθιά", + "descriptionComplete": "Προκαλέσατε 50% ζημιά με μιά γροθιά", + "descriptionFull": "Προκαλέστε 50% ζημιά με μιά γροθιά στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Προκαλέσατε 50% ζημιά με μιά γροθιά στο επίπεδο ${LEVEL}", + "name": "Ισχυρή Γροθιά" + }, + "TNT Terror": { + "description": "Σκοτώστε 6 κακούς με TNT", + "descriptionComplete": "Σκοτώσατε 6 κακούς με TNT", + "descriptionFull": "Σκοτώστε 6 κακούς με TNT στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σκοτώσατε 6 κακούς με TNT στο επίπεδο ${LEVEL}", + "name": "Ο Τρόμος Του Δυναμίτη" + }, + "Team Player": { + "descriptionFull": "Ξεκινήστε Ομαδικό παιχνίδι με 4+ παίκτες", + "descriptionFullComplete": "Ξεκινήσατε Ομαδικό παιχνίδι με 4+ παίκτες", + "name": "Ομαδικός Παίκτης" + }, + "The Great Wall": { + "description": "Σταματήστε όλους τους κακούς", + "descriptionComplete": "Σταματήσατε όλους τους κακούς", + "descriptionFull": "Σταματήστε όλους τους κακούς στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σταματήσατε όλους τους κακούς στο επίπεδο ${LEVEL}", + "name": "Το Μεγάλο Τείχος" + }, + "The Wall": { + "description": "Σταματήστε όλους τους κακούς", + "descriptionComplete": "Σταματήσατε όλους τους κακούς", + "descriptionFull": "Σταματήστε όλους τους κακούς στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Σταματήσατε όλους τους κακούς στο επίπεδο ${LEVEL}", + "name": "Το Τείχος" + }, + "Uber Football Shutout": { + "description": "Νικήστε χωρίς να αφήσετε τους κακούς να σκοράρουν", + "descriptionComplete": "Νικήσατε χωρίς να αφήσετε τους κακούς να σκοράρουν", + "descriptionFull": "Νικήστε το επίπεδο ${LEVEL} χωρίς να αφήσετε τους κακούς να σκοράρουν", + "descriptionFullComplete": "Νικήσατε το επίπεδο ${LEVEL} χωρίς να αφήσετε τους κακούς να σκοράρουν", + "name": "${LEVEL} Απόκλιση" + }, + "Uber Football Victory": { + "description": "Νικήστε τον αγώνα", + "descriptionComplete": "Νικήσατε τον αγώνα", + "descriptionFull": "Νικήστε τον αγώνα στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Νικήσατε τον αγώνα στο επίπεδο ${LEVEL}", + "name": "Νίκη στο επίπεδο ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Νικήστε όλα τα κύματα", + "descriptionComplete": "Νικήσατε όλα τα κύματα", + "descriptionFull": "Νικήστε όλα τα κύματα στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Νικήσατε όλα τα κύματα στο επίπεδο ${LEVEL}", + "name": "Νίκη στο επίπεδο ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Απωθήστε όλα τα κύματα", + "descriptionComplete": "Απωθήσατε όλα τα κύματα", + "descriptionFull": "Απωθήστε όλα τα κύματα στο επίπεδο ${LEVEL}", + "descriptionFullComplete": "Απωθήσατε όλα τα κύματα στο επίπεδο ${LEVEL}", + "name": "Νίκη στο επίπεδο ${LEVEL}" + } + }, + "achievementsRemainingText": "Υπολειπόμενα Επιτεύγματα:", + "achievementsText": "Επιτεύγματα", + "achievementsUnavailableForOldSeasonsText": "Συγνώμη, ακριβείς λεπτομέρειες σχετικές με τα επιτεύγματα είναι μη διαθέσιμες για παλαιότερες σεζόν.", + "activatedText": "Το ${THING} ενεργοποιήθηκε.", + "addGameWindow": { + "getMoreGamesText": "Περισσότερα Παιχνίδια...", + "titleText": "Προσθήκη Παιχνιδιού" + }, + "allowText": "Να Επιτρέπεται", + "alreadySignedInText": "Ο λογαριασμός σας είναι συνδεδεμένος από άλλη συσκευή.\nΠαρακαλώ, άλλαξε το λογαριασμό σας ή απενεργοποίησε \nτο παιχνίδι από τις άλλες συσκευες σας και ξαναπροσπάθηστε.", + "apiVersionErrorText": "Can't load module ${NAME}; it targets api-version ${VERSION_USED}; we require ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(Το \"Αυτόματο\" ενεργοποιεί αυτό μόνο όταν έχουν συνδεθεί ακουστικά)", + "headRelativeVRAudioText": "Ρυθμίσεις σχετικές με VR ακουστικά", + "musicVolumeText": "Ένταση Μουσικής", + "soundVolumeText": "Ένταση Ήχου", + "soundtrackButtonText": "Ηχητική Υπόκρουση", + "soundtrackDescriptionText": "(αναθέστε τη δική σας μουσική να ακούγεται ενώ παίζετε)", + "titleText": "Ήχος" + }, + "autoText": "Αυτόματο", + "backText": "Πίσω", + "banThisPlayerText": "Αποκλεισμός αυτόυ του Παίκτη", + "bestOfFinalText": "Επικρατών-Στα-${COUNT} Αποτελέσμα", + "bestOfSeriesText": "Σειρά επικρατών στα ${COUNT}:", + "bestRankText": "Η καλύτερή σας κατάταξη: #${RANK}", + "bestRatingText": "Η καλύτερή σας βαθμολογία: ${RATING}", + "bombBoldText": "BΟΜΒΑ", + "bombText": "Βόμβα", + "boostText": "Ώθηση", + "bsRemoteConfigureInAppText": "Το ${REMOTE_APP_NAME} είναι οριστικοποιημένο στην εφαρμογή από μόνο του.", + "buttonText": "κουμπί", + "canWeDebugText": "Θα θέλατε το BombSquad να στέλνει αυτόματη αναφορά σφαλμάτων,\nκατάρρευσης, και πληροφορίες βασικής χρήσης στο δημιουργό του;\n\nΤα δεδομένα δε περιέχουν προσωπικές σας πληροφορίες και\nβοηθούν το παιχνίδι να τρέχει ομαλά χωρίς σφάλματα.", + "cancelText": "Άκυρο", + "cantConfigureDeviceText": "Συγνώμη, η συσκευή ${DEVICE} είναι μη οριστικοποιήσιμη.", + "challengeEndedText": "Αυτή η πρόκληση έχει τελειώσει.", + "chatMuteText": "Σίγαση Συζήτησης", + "chatMutedText": "Συζήτηση σε Σίγαση", + "chatUnMuteText": "Απενεργοποίηση Σίγασης", + "choosingPlayerText": "<επιλογή παίκτη>", + "completeThisLevelToProceedText": "Πρέπει να ολοκληρώσετε αυτό\nτο επίπεδο για να προχωρήσετε!", + "completionBonusText": "Μπόνους Ολοκλήρωσης", + "configControllersWindow": { + "configureControllersText": "Οριστικοποίηση Χειριστηρίων", + "configureKeyboard2Text": "Οριστικοποίηση Πληκτρολογίου Π2", + "configureKeyboardText": "Οριστικοποίηση Πληκτρολογίου", + "configureMobileText": "Φορητές Συσκευές ως Χειριστήρια", + "configureTouchText": "Οριστικοποίηση Οθόνης Αφής", + "ps3Text": "Χειριστήρια PS3", + "titleText": "Χειριστήρια", + "wiimotesText": "Wiimotes", + "xbox360Text": "Χειριστήρια Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Σημείωση: η υποστήριξη χειριστηρίων διαφέρει ανάλογα με τη συσκευή και την έκδοση Android.", + "pressAnyButtonText": "Πατήστε οποιοδήποτε πλήκτρο στο χειριστήριο\n που θέλετε να οριστικοποιήσετε...", + "titleText": "Οριστικοποίηση Χειριστηρίων" + }, + "configGamepadWindow": { + "advancedText": "Σύνθετες", + "advancedTitleText": "Σύνθετη Εγκατάσταση Χειριστηρίων", + "analogStickDeadZoneDescriptionText": "(αλλάξτε το εάν ο χαρακτήρας σας 'γλιστράει' όταν αφήνετε το μοχλό)", + "analogStickDeadZoneText": "Νεκρή Ζώνη Αναλογικού Μοχλού", + "appliesToAllText": "(εφαρμόζεται για όλα τα χειριστήρια αυτού του τύπου)", + "autoRecalibrateDescriptionText": "(ενεργοποιήστε το αν ο χαρακτήρας σας δεν κινείται με τη μέγιστη ταχύτητα)", + "autoRecalibrateText": "Αναβαθμονόμηση Αναλογικού Μοχλού", + "axisText": "άξονας", + "clearText": "εκκαθάριση", + "dpadText": "dpad", + "extraStartButtonText": "Επιπλέον Κουμπί Έναρξης", + "ifNothingHappensTryAnalogText": "Αν δε συμβαίνει τίποτα, δοκιμάστε να το αναθέσετε στον αναλογικό μοχλό", + "ifNothingHappensTryDpadText": "Αν δε συμβεί τίποτα, δοκιμάστε να το αναθέσετε στο d-pad.", + "ignoreCompletelyDescriptionText": "(απαγόρευση αυτού του χειριστηρίου να επηρεάσει τόσο το παιχνίδι όσο και τα μενού)", + "ignoreCompletelyText": "Πλήρης Αγνόηση", + "ignoredButton1Text": "Αγνοημένο Πλήκτρο 1", + "ignoredButton2Text": "Αγνοημένο Πλήκτρο 2", + "ignoredButton3Text": "Αγνοημένο Πλήκτρο 3", + "ignoredButton4Text": "Αγνοημένο Πλήκτρο 4", + "ignoredButtonDescriptionText": "(χρησιμοποιήστε αυτή τη ρύθμιση για να απαγορεύσετε στα κουμπιά 'home' ή 'sync' να επηρεάσουν το UI)", + "pressAnyAnalogTriggerText": "Πατήστε οποιονδήποτε αναλογικό διακόπτη...", + "pressAnyButtonOrDpadText": "Πατήστε οποιοδήποτε κουμπί ή dpad...", + "pressAnyButtonText": "Πατήστε οποιοδήποτε κουμπί...", + "pressLeftRightText": "Πατήστε αριστερά ή δεξιά...", + "pressUpDownText": "Πατήστε πάνω ή κάτω", + "runButton1Text": "Κουμπί τρεξίματος 1", + "runButton2Text": "Κουμπί τρεξίματος 2", + "runTrigger1Text": "Αναλογικός Διακόπτης Τρεξίματος 1", + "runTrigger2Text": "Αναλογικός Διακόπτης Τρεξίματος 2", + "runTriggerDescriptionText": "(οι αναλογικοί διακόπτες σας επιτρέπουν να τρέχετε με διαφορετικές ταχύτητες)", + "secondHalfText": "Χρησιμοποιήστε αυτή τη ρύθμιση για να\nοριστικοποιήσετε το δεύτερο μισό συσκευής 2-σε-1\nπου εμφανίζεται ως μονό χειριστήριο.", + "secondaryEnableText": "Ενεργοποίηση", + "secondaryText": "Δευτερεύον Χειριστήριο", + "startButtonActivatesDefaultDescriptionText": "(απενεργοποιήστε αυτή τη ρύθμιση αν το κουμπί έναρξής σας μοιάζει πιό πολύ με κουμπί 'menu')", + "startButtonActivatesDefaultText": "Το Κουμπί Έναρξης Ενεργοποιεί το Προκαθορισμένο Γραφικό Στοιχείο", + "titleText": "Εγκατάσταση Χειριστηρίων", + "twoInOneSetupText": "Εγκατάσταση Χειριστηρίων 2-σε-1", + "uiOnlyDescriptionText": "(απαγόρευση αυτού του χειριστηρίου από το να ενταχθεί σε παιχνίδι)", + "uiOnlyText": "Περιορισμός Χρήσης Μόνο για τα Μενού", + "unassignedButtonsRunText": "Όλα Ανενεργά Κουμπιά Λειτουργούν για Τρέξιμο", + "unsetText": "<μη ορισμένο>", + "vrReorientButtonText": "Κουμπί Αναπροσανατολισμού VR" + }, + "configKeyboardWindow": { + "configuringText": "Οριστικοποιείται η Συσκευή ${DEVICE}", + "keyboard2NoteText": "Σημείωση: τα περισσότερα πληκτρολόγια μπορούν να υποστηρίξουν λίγα\nπατήματα κουμπιών ταυτόχρονα, οπότε έχοντας δεύτερο παίκτη πληκτρολογίου\nμπορεί να λειτουργήσει καλύτερα εάν υπάρχει και άλλο διαθέσιμο πληκτρολόγιο\nγια να χρησιμοποιήσει. Να σημειωθεί επίσης ότι πρέπει να επιλέξετε επιπλέον\nκουμπιά και για τους δύο παίκτες ακόμα και σε αυτή τη περίπτωση." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Κλίμακα Στοιχείου Χειρισμού Δράσεων", + "actionsText": "Δράσεις", + "buttonsText": "κουμπιά", + "dragControlsText": "< σύρετε τους χειρισμούς για επανατοποθέτηση >", + "joystickText": "μοχλός", + "movementControlScaleText": "Κλίμακα Στοιχείου Χειρισμού Κινήσεων", + "movementText": "Κίνηση", + "resetText": "Επαναφορά", + "swipeControlsHiddenText": "Απόκρυψη Εικονιδίων Swipe", + "swipeInfoText": "Ο χειρισμός 'Swipe' παίρνει λίγο χρόνο μέχρι να τον συνηθίσετε αλλά\nτο κάνει ευκολότερο να παίζετε χωρίς να κοιτάτε τους χειρισμούς.", + "swipeText": "swipe", + "titleText": "Οριστικοποίηση Οθόνης Αφής" + }, + "configureItNowText": "Οριστικοποίηση τώρα;", + "configureText": "Οριστικοποίηση", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsScale": 0.6, + "bestResultsText": "Για καλύτερα αποτελέσματα θα πρέπει να έχετε wifi δίκτυο χωρίς\nκαθυστερήσεις. Μπορείτε να τις μειώσετε κλείνοντας άλλες ασύρματες\nσυσκευές, παίζοντας κοντά στον δρομολογητή, και συνδέοντας τον\nοικοδεσπότη του παιχνιδιου απευθείας στο δίκτυο μέσω ethernet.", + "explanationText": "Για χρήση smart-phone ή tablet ως ασύρματο χειριστήριο,\nεγκαταστήστε το \"${REMOTE_APP_NAME}\". Κάθε αριθμός μπορεί\nνα συνδεθεί σε ένα παιχνίδι ${APP_NAME} μέσω Wi-Fi, δωρεάν!", + "forAndroidText": "για Android:", + "forIOSText": "για iOS:", + "getItForText": "Αποκτήστε το ${REMOTE_APP_NAME} για iOS στο App Store της Apple\nή για Android στο Google Play Store ή στο Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Χρησιμοποιώντας Φορητές Συσκευές ως Χειριστήρια:" + }, + "continuePurchaseText": "Συνέχιση για ${PRICE}?", + "continueText": "Συνέχιση", + "controlsText": "Χειρισμοί", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Αυτό δεν εφαρμόζεται για την διαχρονική κατάταξη.", + "activenessInfoText": "Αυτός ο πολλαπλασιαστής ανεβαίνει κατά τις μέρες\nπου παίζετε και πέφτει κατά τις μέρες που δεν παίζετε.", + "activityText": "Δραστηριότητα", + "campaignText": "Ιστορία", + "challengesInfoText": "Κερδίστε έπαθλα νικώντας μικροπαιχνίδια.\n\nΤα έπαθλα και ο βαθμός δυσκολίας αυξάνεται κάθε\nφορά που ολοκληρώνεται μία πρόκληση και μειώνεται\nκάθε φορά που κάποια λήξει ή εγκαταλειφθεί.", + "challengesText": "Προκλήσεις", + "currentBestText": "Τρέχουσα Υψηλότερη Βαθμολογία", + "customText": "Προσαρμοσμένο", + "entryFeeText": "Είσοδος", + "forfeitConfirmText": "Εγκατάλειψη της πρόκλησης?", + "forfeitNotAllowedYetText": "Δεν μπορείτε να εγκαταλείψετε ακόμα αυτή την πρόκληση.", + "forfeitText": "Εγκατάλειψη", + "multipliersText": "Πολλαπλασιαστές", + "nextChallengeText": "Επόμενη Πρόκληση", + "nextPlayText": "Επόμενο Παιχνίδι", + "ofTotalTimeText": "από ${TOTAL}", + "playNowText": "Παίξε Τώρα", + "pointsText": "Πόντοι", + "powerRankingFinishedSeasonUnrankedText": "(η σεζόν ολοκληρώθηκε δίχως να έχετε καταταχθεί)", + "powerRankingNotInTopText": "(όχι στους κορυφαίους ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} πόντοι", + "powerRankingPointsMultText": "(x ${NUMBER} πόντοι)", + "powerRankingPointsText": "${NUMBER} πόντοι", + "powerRankingPointsToRankedText": "(${CURRENT} από ${REMAINING} πόντοι)", + "powerRankingText": "Κατάταξη Δύναμης", + "prizesText": "Βραβεία", + "proMultInfoText": "Οι παίχτες με την ${PRO} αναβάθμιση\nλαμβάνουν επιπλέον ${PERCENT}% πόντους εδώ.", + "seeMoreText": "Περισσότερα...", + "skipWaitText": "Παράκαμψη Αναμονής", + "timeRemainingText": "Υπολοιπόμενος Χρόνος", + "toRankedText": "Για Κατάταξη", + "totalText": "σύνολο", + "tournamentInfoText": "Ανταγωνιστείτε για υψηλά σκορ με\nάλλους παίκτες της κατηγορίας σας.\n\nΟι παίκτες που κατέχουν τα κορυφαία σκορ όταν ο\nχρόνος του τουρνουά λήγει ανταμοίβονται με βραβεία.", + "welcome1Text": "Καλωσήρθατε στη κατηγορία ${LEAGUE}. Μπορείτε να ανεβάσετε\nτην κατάταξή σας κερδίζοντας βαθμολογίες αστεριών,\nολοκληρώνοντας επιτεύγματα, και κερδίζοντας βραβεία σε τουρνουά.", + "welcome2Text": "Μπορείτε ακόμα να κερδίσετε εισιτήρια με πολλές παρόμοιες δραστηριότητες.\nΤα εισιτήρια μπορούν να χρησιμοποιηθούν για να ξεκλειδώσετε νέους\nχαρακτήρες, χάρτες και μικροπαιχνίδια, να συμμετάσχετε σε τουρνουά, κ.α.", + "yourPowerRankingText": "Η Κατάταξη Δύναμής Σας:" + }, + "copyConfirmText": "Αντιγράφτηκε στο πρόχειρο.", + "copyOfText": "${NAME} Αντίγραφο", + "copyText": "αντίγραφο", + "createEditPlayerText": "<Δημιουργία/Επεξεργασία Παίκτη>", + "createText": "Δημιουργία", + "creditsWindow": { + "additionalAudioArtIdeasText": "Πρόσθετοι Ήχοι, Πρώιμη Καλλιτεχνική Επιμέλεια, και Ιδέες από ${NAME}", + "additionalMusicFromText": "Πρόσθετη μουσική από ${NAME}", + "allMyFamilyText": "Όλοι οι φίλοι και η οικογένειά μου που βοήθησαν στις δοκιμές του παιχνιδιού", + "codingGraphicsAudioText": "Κώδικας, Γραφικά, και Ήχοι από ${NAME}", + "languageTranslationsText": "Γλωσσικές Μεταφράσεις:", + "legalText": "Νομικά:", + "publicDomainMusicViaText": "Δημόσιος-τομέας μουσικής μέσω ${NAME}", + "softwareBasedOnText": "Αυτό το λογισμικό είναι βασισμένο σε μέρος του έργου των ${NAME}", + "songCreditText": "${TITLE} παίχτηκε από ${PERFORMER}\nΣυντέθηκε από ${COMPOSER}, Οργανώθηκε από ${ARRANGER}, Δημοσιεύτηκε από ${PUBLISHER},\nΠαραχωρήθηκε από ${SOURCE}", + "soundAndMusicText": "Ήχος & Μουσική:", + "soundsText": "Ήχοι (${SOURCE}):", + "specialThanksText": "Πολλά Ευχαριστώ:", + "thanksEspeciallyToText": "Ευχαριστώ ιδιαίτερα: ${NAME}", + "titleText": "Λίστα Συντελεστών ${APP_NAME}", + "whoeverInventedCoffeeText": "Οποιοσδήποτε επινόησε τον καφέ" + }, + "currentStandingText": "Η τρέχουσα κατάταξή σας είναι #${RANK}", + "customizeText": "Προσαρμογή...", + "deathsTallyText": "${COUNT} θάνατοι", + "deathsText": "Θάνατοι", + "debugText": "αποσφαλμάτωση", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Σημείωση: είναι προτεινόμενη η ρύθμιση Ρυθμίσεις->Γραφικά->Υφές στο 'Υψηλό' όταν το δοκιμάζετε αυτό.", + "runCPUBenchmarkText": "Εκτέλεση Αξιολόγησης Απόδοσης CPU", + "runGPUBenchmarkText": "Εκτέλεση Αξιολόγησης Απόδοσης GPU", + "runMediaReloadBenchmarkText": "Εκτέλεση Αξιολόγησης Απόδοσης Επαναφόρτωσης-Πολυμέσων", + "runStressTestText": "Εκτέλεση Ελέγχου Κόπωσης", + "stressTestPlayerCountText": "Αριθμός Παικτών", + "stressTestPlaylistDescriptionText": "Λίστα Παιχνιδιών Ελέγχου Κόπωσης", + "stressTestPlaylistNameText": "Όνομα Λίστας Παιχνιδιών", + "stressTestPlaylistTypeText": "Τύπος Λίστας Παιχνιδιών", + "stressTestRoundDurationText": "Διάρκεια Γύρου", + "stressTestTitleText": "Έλεγχος Κόπωσης", + "titleText": "Έλεγχος Αξιολόγησης & Κόπωσης", + "totalReloadTimeText": "Συνολικός χρόνος επαναφόρτωσης: ${TIME}" + }, + "defaultGameListNameText": "Προκαθορισμένη Λίστα ${PLAYMODE}", + "defaultNewGameListNameText": "Η Δική μου Λίστα ${PLAYMODE}", + "deleteText": "Διαγραφή", + "demoText": "Επίδειξη", + "denyText": "Απαγόρευση", + "deprecatedText": "Καταργήθηκε", + "desktopResText": "Ανάλυση Σταθερού Η/Υ", + "deviceAccountUpgradeText": "Προσοχή:\nΧρησιμοποιειτέ ένα λογαριασμό συσκευής(${NAME}).\nΟι λογαριασμοί συσκευών θα αφαιρεθούν σε μέλλουσα ενημέρωση.\nΑναβαθμίστε σε ένα λογαριασμό V2 αν θέλετε να διατηρήσετε την πρόοδο σας.", + "difficultyEasyText": "Εύκολο", + "difficultyHardOnlyText": "Αποκλειστικά Στο Δύσκολο", + "difficultyHardText": "Δύσκολο", + "difficultyHardUnlockOnlyText": "Αυτό το επίπεδο μπορεί να ξεκλειδωθεί μόνο στο\nΔύσκολο. Πιστεύετε ότι έχετε τα προσόντα!?!?!", + "directBrowserToURLText": "Παρακαλώ προβείτε στην παρακάτω ιστοσελίδα με τη χρήση διαδικτυακού περιηγητή:", + "disableRemoteAppConnectionsText": "Απενεργοποίηση Συνδέσεων Ασύρματης Εφαρμογής", + "disableXInputDescriptionText": "Επιτρέπει περισσότερα από 4 χειριστήρια αλλά μπορεί να μη λειτουργήσει.", + "disableXInputText": "Απενεργοποίηση XIinput", + "doneText": "Έγινε", + "drawText": "Ισοπαλία", + "duplicateText": "Διπλοτυπία", + "editGameListWindow": { + "addGameText": "Προσθήκη\nΠαιχνιδιού", + "cantOverwriteDefaultText": "Η προκαθορισμένη λίστα παιχνιδιών δεν μπορεί να αντικατασταθεί!", + "cantSaveAlreadyExistsText": "Μία λίστα παιχνιδιών με αυτό το όνομα υπάρχει ήδη!", + "cantSaveEmptyListText": "Μία άδεια λίστα παιχνιδιών δεν μπορεί να αποθηκευτεί!", + "editGameText": "Επεξεργασία\nΠαιχνιδιού", + "listNameText": "Όνομα λίστας", + "nameText": "Όνομα", + "removeGameText": "Αφαίρεση\nΠαιχνιδιού", + "saveText": "Αποθήκευση λίστας", + "titleText": "Επεξεργαστής Λίστας Παιχνιδιών" + }, + "editProfileWindow": { + "accountProfileInfoText": "Αυτό το ειδικό προφίλ έχει όνομα και\nεικονίδιο βασισμένο στον λογαριασμό σας.\n\n${ICONS}\n\nΔημιουργήστε προσαρμοσμένα προφίλ για τη\nχρήση διαφορετικών ονομάτων και εικονιδίων.", + "accountProfileText": "(προφίλ λογαριασμού)", + "availableText": "Το όνομα \"${NAME}\" είναι διαθέσιμο.", + "characterText": "χαρακτήρας", + "checkingAvailabilityText": "Έλεγχος διαθεσιμότητας για \"${NAME}\"...", + "colorText": "χρώμα", + "getMoreCharactersText": "Περισσότεροι Χαρακτήρες...", + "getMoreIconsText": "Περισσότερα εικονίδια...", + "globalProfileInfoText": "Τα παγκόσμια προφίλ παικτών εγγυώνται ότι εχουν μοναδικά\nονόματα παγκοσμίως. Επιπλέον, περιλαμβάνουν προσαρμοσμένα εικονίδια.", + "globalProfileText": "(παγκόσμιο προφίλ)", + "highlightText": "λεπτομέρεια", + "iconText": "εικονίδιο", + "localProfileInfoText": "Τα τοπικά προφίλ παικτών δεν έχουν εικονίδια και τα ονόματά\nτους δεν εγγυώνται ως μοναδικά. Αναβαθμίστε σε παγκόσμιο προφίλ\nγια την κατοχύρωση ενός ονόματος και την προσθήκη εικονιδίου.", + "localProfileText": "(τοπικό προφίλ)", + "nameDescriptionText": "Όνομα Παίκτη", + "nameText": "Όνομα", + "randomText": "τυχαίο", + "titleEditText": "Επεξεργασία Προφίλ", + "titleNewText": "Νέο Προφίλ", + "unavailableText": "Το \"${NAME}\" δεν είναι διαθέσιμο. Δοκιμάστε άλλο όνομα.", + "upgradeProfileInfoText": "Αυτό θα κατοχυρώσει το όνομά του παίκτη σας παγκοσμίως\nκαι θα σας επιτρέψει τη προσθήκη προσαρμοσμένου εικονιδίου.", + "upgradeToGlobalProfileText": "Προαγωγή σε Παγκόσμιο Προφίλ" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Δεν μπορείτε να διαγράψετε το προκαθορισμένο πακέτο.", + "cantEditDefaultText": "Δεν μπορείτε να επεξεργαστείτε το προκαθορισμένο πακέτο. Διπλοτυπίστε το ή δημιουργήστε καινούριο.", + "cantOverwriteDefaultText": "Το προκαθορισμένο πακέτο δεν μπορεί να αντικατασταθεί", + "cantSaveAlreadyExistsText": "Ένα πακέτο με το ίδιο όνομα υπάρχει ήδη!", + "defaultGameMusicText": "<προκαθορισμένη μουσική παιχνιδιού>", + "defaultSoundtrackNameText": "Προκαθορισμένο Πακέτο", + "deleteConfirmText": "Διαγραφή Πακέτου:\n\n'${NAME}';", + "deleteText": "Διαγραφή\nΠακέτου", + "duplicateText": "Διπλοτυπία\nΠακέτου", + "editSoundtrackText": "Επεξεργαστής Ηχητικής Υπόκρουσης", + "editText": "Επεξεργασία\nΠακέτου", + "fetchingITunesText": "μεταφορά λιστών μουσικής από εφαρμογή μουσικής...", + "musicVolumeZeroWarning": "Προειδοποίηση: η ένταση της μουσικής είναι ρυθμισμένη στο 0", + "nameText": "Όνομα", + "newSoundtrackNameText": "Η Ηχητική μου Υπόκρουση ${COUNT}", + "newSoundtrackText": "Νέο πακέτο:", + "newText": "Νέο\nΠακέτο", + "selectAPlaylistText": "Επιλέξτε μια Λίστα Μουσικής", + "selectASourceText": "Πηγή Μουσικής", + "testText": "έλεγχος", + "titleText": "Ηχητική Υπόκρουση", + "useDefaultGameMusicText": "Προκαθορισμένη Μουσική Παιχνιδιού", + "useITunesPlaylistText": "Λίστα μουσικής από εφαρμογή μουσικής", + "useMusicFileText": "Μουσικό Αρχείο (mp3, κλπ)", + "useMusicFolderText": "Φάκελος Αρχείων Μουσικής" + }, + "editText": "Επεξεργασία", + "endText": "Τέλος", + "enjoyText": "Απολαύστε!", + "epicDescriptionFilterText": "${DESCRIPTION} Σε επικά αργή κίνηση.", + "epicNameFilterText": "${NAME} Επικό", + "errorAccessDeniedText": "η πρόσβαση απορρίφθηκε", + "errorDeviceTimeIncorrectText": "Η ώρα της συσκευής σας είναι λάθος ${HOURS} ώρες.\nΑυτο είναι πιθανό να πεοκλέσει προβλήματα.\nΠαρακαλούμε ελέξτε τις ρυθμίσεις ώρας σας.", + "errorOutOfDiskSpaceText": "έλλειψη αποθηκευτικού χώρου", + "errorSecureConnectionFailText": "Αδύνατο να δημιουργηθεί ασφαλής σύνδεση cloud, η χρήση του διαδικτύου μπορεί να αποτύχει.", + "errorText": "Σφάλμα", + "errorUnknownText": "άγνωστο σφάλμα", + "exitGameText": "Έξοδος από το ${APP_NAME};", + "exportSuccessText": "Έγινε εξαγωγή του στοιχείου '${NAME}'.", + "externalStorageText": "Εξωτερικός Αποθηκευτικός Χώρος", + "failText": "Αποτυχία", + "fatalErrorText": "Ωχ; Κάτι λείπει ή έχει χαλάσει. Παρακαλώ,\nδοκιμάστε να επανεγκαταστήσετε την εφαρμογή\nή επικοινωνήστε στο ${EMAIL} για βοήθεια.", + "fileSelectorWindow": { + "titleFileFolderText": "Επιλέξτε Αρχείο ή Φάκελο", + "titleFileText": "Επιλέξτε Αρχείο", + "titleFolderText": "Επιλέξτε Φάκελο", + "useThisFolderButtonText": "Χρήση Αυτού Του Φακέλου" + }, + "filterText": "Φίλτρο", + "finalScoreText": "Τελική Βαθμολογία", + "finalScoresText": "Τελικές Βαθμολογίες", + "finalTimeText": "Τελικός χρόνος", + "finishingInstallText": "Ολοκλήρωση εγκατάστασης. Μια στιγμή...", + "fireTVRemoteWarningText": "* Για καλύτερη εμπειρία, χρησιμοποιήστε\nχειριστήρια Παιχνιδιών ή εγκαταστήστε την\nεφαρμογή '${REMOTE_APP_NAME}' στο κινητό\nτηλέφωνο ή το tablet σας.", + "firstToFinalText": "Πρώτος-Στα-${COUNT} Αποτέλεσμα", + "firstToSeriesText": "Σειρά πρώτος-στα-${COUNT}", + "fiveKillText": "ΠΕΝΤΑΠΛΟΣ ΦΟΝΟΣ!!!", + "flawlessWaveText": "Άψογο Κύμα!", + "fourKillText": "ΤΕΤΡΑΠΛΟΣ ΦΟΝΟΣ!!!", + "friendScoresUnavailableText": "Βαθμολογίες φίλων μη διαθέσιμες.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Πίνακας Κατάταξης ${COUNT}ου Παιχνιδιού", + "gameListWindow": { + "cantDeleteDefaultText": "Δεν μπορείτε να διαγράψετε την προκαθορισμένη λίστα παιχνιδιών.", + "cantEditDefaultText": "Δεν μπορείτε να επεξεργαστείτε την προκαθορισμένη λίστα παιχνιδιών! Διπλοτυπίστε την ή δημιουργήστε καινούρια.", + "cantShareDefaultText": "Δεν μπορειτε να μοιραστείτε την προκαθορισμένη λίστα παιχνιδιών.", + "deleteConfirmText": "Διαγραφή \"${LIST}\";", + "deleteText": "Διαγραφή\nΛίστας", + "duplicateText": "Διπλοτυπία\nΛίστας", + "editText": "Επεξεργασία\nΛίστας", + "newText": "Νέα\nΛίστα", + "showTutorialText": "Προβολή Εκπαιδευτικού Βίντεο", + "shuffleGameOrderText": "Ανακάτεμα Ουράς Παιχνιδιών", + "titleText": "Προσαρμογή Λίστων Παιχνιδιών ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Προσθήκη Παιχνιδιού" + }, + "gamesToText": "${WINCOUNT} - ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Θυμηθείτε: οποιαδήποτε συσκευή σε μια συγκέντρωση μπορεί να φιλοξενήσει\nπερισσότερους από έναν παίκτες, αρκεί να υπάρχουν αρκετά χειριστήρια.", + "aboutDescriptionText": "Χρησιμοποιήστε αυτές τις καρτέλες για να οργανώσετε μια συγκέντρωση.\n\nΟι συγκεντρώσεις σας επιτρέπουν να παίξετε παιχνίδια\nκαι τουρνουά με φίλους μεταξύ διαφόρων συσκευών.\n\nΠατήστε το κουμπί ${PARTY} στην κορυφή δεξιά για να συνομιλήσετε\nκαι να αλληλεπιδράσετε με τα μέλη της συγκέντρωσής σας.\n(με χειριστήριο, πατήστε το ${BUTTON} όταν βρίσκεστε σε μενού)", + "aboutText": "Σχετικά", + "addressFetchErrorText": "<σφάλμα κατά τη μεταφορά διευθύνσεων>", + "appInviteMessageText": "Ο χρήστης ${NAME} σας έστειλε ${COUNT} εισητήρια στο ${APP_NAME}", + "appInviteSendACodeText": "Στείλτε Τους Κωδικό", + "appInviteTitleText": "Πρόσκληση Στο ${APP_NAME}", + "bluetoothAndroidSupportText": "(λειτουργεί με οποιαδήποτε συσκευή Android που υποστηρίζει Bluetooth)", + "bluetoothDescriptionText": "Φιλοξενίστε/ενταχθείτε σε συγκέντρωση μέσω Bluetooth:", + "bluetoothHostText": "Φιλοξενίστε μέσω Bluetooth", + "bluetoothJoinText": "Ενταχθείτε μέσω Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "έλεγχος...", + "copyCodeConfirmText": "Ο κωδικός αντιγράφηκε στο πρόχειρο.", + "copyCodeText": "Αντιγράψτε τον κωδικό", + "dedicatedServerInfoText": "Για καλύτερα αποτελέσματα, οργανώστε έναν σταθερό διακομιστή. Βλέπε bombsquadgame.com/server.", + "disconnectClientsText": "Συνεχίζοντας θα αποσυνδεθούν ${COUNT} παίκης/ες\nαπο τη συγκέντρωσή σας. Είστε σίγουροι?", + "earnTicketsForRecommendingAmountText": "Οι φίλοι σας θα λάβουν ${COUNT} εισητήρια αν δοκιμάσουν το παιχνίδι\n(και εσείς θα λάβετε ${YOU_COUNT} για τον καθένα)", + "earnTicketsForRecommendingText": "Μοιραστείτε το παιχνίδι\nγια δωρεάν εισητήρια...", + "emailItText": "Στείλτε το σε Email", + "favoritesSaveText": "Αποθήκευση ως αγαπημένο", + "favoritesText": "Αγαπημένα", + "freeCloudServerAvailableMinutesText": "Ο επόμενος δωρεάν cloud διακομιστής διαθέσιμος σε ${MINUTES} λεπτά.", + "freeCloudServerAvailableNowText": "Ο δωρεάν cloud διακομιστής είναι διαθέσιμος!", + "freeCloudServerNotAvailableText": "Δεν υπάρχουν δωρεάν cloud διακομιστές διαθέσιμοι.", + "friendHasSentPromoCodeText": "${COUNT} εισητήρια ${APP_NAME} από ${NAME}", + "friendPromoCodeAwardText": "Θα λάμβάνετε από ${COUNT} εισητήρια για κάθε χρήση.", + "friendPromoCodeExpireText": "Αυτός ο κωδικός λήγει σε ${EXPIRE_HOURS} ώρες και λειτουργεί μόνο για νέα μέλη.", + "friendPromoCodeInstructionsText": "Για να το αξιοποιήσετε, ανοίξτε το ${APP_NAME} και ακολουθήστε το \"Ρυθμίσεις->Σύνθετες->Εισαγωγή Κωδικού\".\nΒλέπε bombsquadgame.com για συνδέσμους της εφαρμογής σε όλες τις υποστηριζόμενες πλατφόρμες.", + "friendPromoCodeRedeemLongText": "Μπορεί να εξαργυρωθεί για ${COUNT} δωρεάν εισητήρια από έως ${MAX_USES} άτομα.", + "friendPromoCodeRedeemShortText": "Μπορεί να εξαργυρωθεί για ${COUNT} εισητήρια στο παιχνίδι.", + "friendPromoCodeWhereToEnterText": "(στο \"Ρυθμίσεις->Σύνθετες->Εισαγωγή Κωδικού\")", + "getFriendInviteCodeText": "Αποκτήστε Κωδικό Πρόσκλησης Φίλων", + "googlePlayDescriptionText": "Προσκάλεσε Google Play παίκτες στη συγκέντρωσή σας:", + "googlePlayInviteText": "Πρόσκληση", + "googlePlayReInviteText": "Υπάρχουν ${COUNT} Google Play παίκτης/ες στη συγκέντρωσή\nσας οι οποίοι θα αποσυνδεθούν εάν στείλετε νέα πρόσκληση.\nΠεριελάβετέ τους σε αυτή για να τους φέρετε πίσω.", + "googlePlaySeeInvitesText": "Προβολή Προσκλήσεων", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play έκδοση)", + "hostPublicPartyDescriptionText": "Φιλοξενίστε Δημόσια Συγκέντρωση", + "hostingUnavailableText": "Η φιλοξενία δεν είναι διαθέσιμη.", + "inDevelopmentWarningText": "Σημείωση:\n\nΤο παιχνίδι μέσω ιστού είναι καινούριο και εξελισσόμενο\nχαρακτηριστηκό. Για την ώρα, είναι πολύ προτεινόμενο όλοι\nοι παίκτες να είναι συνδεδεμένοι στο ίδιο δίκτυο Wi-Fi.", + "internetText": "Διαδίκτυο", + "inviteAFriendText": "Οι φίλοι σας δεν έχουν το παιχνίδι? Προσκαλέστε τους\nνα το δοκιμάσουν και θα λάβουν ${COUNT} δωρεάν εισιτήρια.", + "inviteFriendsText": "Προσκαλέστε Φίλους", + "joinPublicPartyDescriptionText": "Ένταξη σε Δημόσια Συγκέντρωση", + "localNetworkDescriptionText": "Ένταξη σε συγκέντρωση στο δίκτυο σας (LAN, Bluetooth, κλπ.)", + "localNetworkText": "Τοπικό Δίκτυο", + "makePartyPrivateText": "Κάνε Την Συγκέντρωσή Μου Ιδιωτική", + "makePartyPublicText": "Κάνε Την Συγκέντρωσή Μου Δημόσια", + "manualAddressText": "Διεύθυνση", + "manualConnectText": "Σύνδεση", + "manualDescriptionText": "Ένταξη σε συγκέντρωση από διεύθυνση:", + "manualJoinSectionText": "Ένταξη Με Διεύθυνση", + "manualJoinableFromInternetText": "Μπορείτε να φιλοξενήσετε από το διαδίκτυο;:", + "manualJoinableNoWithAsteriskText": "ΟΧΙ*", + "manualJoinableYesText": "ΝΑΙ", + "manualRouterForwardingText": "*για να το διορθώσετε, δοκιμάστε να ρυθμίσετε τον δρομολογητή σας να στείλει τη UDP θύρα ${PORT} στην ιδιωτική σας διεύθυνση", + "manualText": "Χειροκίνητα", + "manualYourAddressFromInternetText": "Η διεύθυνση σας με βάση το διαδίκτυο:", + "manualYourLocalAddressText": "Η τοπική σας διεύθυνση:", + "nearbyText": "Κοντινά", + "noConnectionText": "<εκτός σύνδεσης>", + "otherVersionsText": "(άλλες εκδόσεις)", + "partyCodeText": "Κωδικός Party", + "partyInviteAcceptText": "Αποδοχή", + "partyInviteDeclineText": "Απόρριψη", + "partyInviteGooglePlayExtraText": "(δείτε την καρτέλα 'Google Play' στο παράθυρο 'Συγκέντρωση')", + "partyInviteIgnoreText": "Αγνόηση", + "partyInviteText": "Ο χρήστης ${NAME} σας προσκάλεσε\nνα συμμετάσχετε στη συγκέντρωσή του!", + "partyNameText": "Όνομα Συγκέντρωσης", + "partyServerRunningText": "Ο party διακομιστής σου τρέχει.", + "partySizeText": "μέγεθος συγκέντρωσης", + "partyStatusCheckingText": "έλεγχος κατάστασης...", + "partyStatusJoinableText": "η συγκέντρωσή σας μπορεί πλέον να φιλοξενήσει από το διαδίκτυο", + "partyStatusNoConnectionText": "αδυναμία σύνδεσης με τον διακομιστή", + "partyStatusNotJoinableText": "η συγκέντρωσή σας δεν μπορεί να φιλοξενήσει από το διαδίκτυο", + "partyStatusNotPublicText": "η συγκέντρωσή σας δεν είναι δημόσια", + "pingText": "ping", + "portText": "Θύρα", + "privatePartyCloudDescriptionText": "Τα ιδιωτικά party τρεχουν σε αφιερωμένους cloud διακομιστές, δεν χρειάζεται διαμόρφωση του ρουτερ.", + "privatePartyHostText": "Φιλοξενίστε ένα Ιδιωτικό Party", + "privatePartyJoinText": "Ένταξη σε Ιδιωτικό Party", + "privateText": "Ιδιωτικό", + "publicHostRouterConfigText": "Αυτό μπορεί να χρειαστεί διαμόρφωση του port-forwarding στο ρούτερ σου. Για μια ευκολότερη επιλογή, φιλοξενίστε ενα ιδιωτικό party.", + "publicText": "Δημόσιο", + "requestingAPromoCodeText": "Αίτημα κωδικού...", + "sendDirectInvitesText": "Αποστολή Άμεσων Προσκλήσεων", + "shareThisCodeWithFriendsText": "Μοιραστείτε αυτόν τον κωδικό με φίλους σας:", + "showMyAddressText": "Εμφάνισε τη Διεύθυνσή μου", + "startHostingPaidText": "Φιλοξενίστε Τώρα Για ${COST}", + "startHostingText": "Φιλοξενίστε", + "startStopHostingMinutesText": "Μπορείτε να ξεκινήσετε και να σταματήσετε να φιλοξενήσετε δωρεαν για τα επομενα ${MINUTES} λεπτά.", + "stopHostingText": "Σταματήσετε να φιλοξενήσετε", + "titleText": "Συγκέντρωση", + "wifiDirectDescriptionBottomText": "Εάν όλες οι συσκευές έχουν πίνακα 'Wi-Fi Direct', είναι να δυνατό μπορούν να τον χρησιμοποιήσουν \nγια να συνδεθούν μεταξύ τους. Όταν όλες οι συσκευές είναι συνδεδεμένες, μπορείτε να οργανώσετε\nσυγκεντρώσεις χρησιμοποιώντας τη καρτέλα 'Τοπικό Δίκτυο',όπως ακριβώς θα κάνατε και με το δίκτυο Wi-Fi.\n\nΓια καλύτερα αποτελέσματα, ο οικοδεσπότης Wi-Fi Direct θα πρέπει να είναι και ο οικοδεσπότης της ${APP_NAME} συγκέντρωσης.", + "wifiDirectDescriptionTopText": "Το Wi-Fi Direct μπορεί να χρησιμοποιηθεί για την άμεση σύνδεση Android συσκευών χωρίς\nτη χρήση Wi-Fi δικτύου. Αυτή η μέθοδος λειτουργεί καλύτερα με Android 4.2 ή νεότερο.\n\nΓια να το χρησιμοποιήσετε, ανοίξτε τις ρυθμίσεις Wi-Fi και ψάξτε γιά το μενού 'Wi-Fi Direct'.", + "wifiDirectOpenWiFiSettingsText": "Άνοιγμα Ρυθμίσεων Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(λειτουργεί μεταξύ κάθε πλατφόρμας)", + "worksWithGooglePlayDevicesText": "(λειτουργεί με συσκευές που τρέχουν τη Google Play (android) έκδοση του παιχνιδιού)", + "youHaveBeenSentAPromoCodeText": "Σας έχει σταλεί ένας κωδικός ${APP_NAME}:" + }, + "getTicketsWindow": { + "freeText": "ΔΩΡΕΑΝ!", + "freeTicketsText": "Δωρεάν Εισιτήρια", + "inProgressText": "Μια συναλλαγή σε εξέλιξη. Παρακαλώ ξαναπροσπαθήστε σε λίγο.", + "purchasesRestoredText": "Οι αγορές αποκαταστάθηκαν.", + "receivedTicketsText": "Αποκτήσατε ${COUNT} εισιτήρια!", + "restorePurchasesText": "Αποκατάσταση Αγορών", + "ticketPack1Text": "Μικρό Πακέτο Εισιτηρίων", + "ticketPack2Text": "Μέσαιο Πακέτο Εισιτηρίων", + "ticketPack3Text": "Μεγάλο Πακέτο Εισιτηρίων", + "ticketPack4Text": "Πακέτο Εισιτηρίων Jumbo", + "ticketPack5Text": "Πακέτο Εισιτηρίων Μαμούθ", + "ticketPack6Text": "Υπέρτατο Πακέτο Εισιτηρίων", + "ticketsFromASponsorText": "Παρακολουθήστε μια διαφήμηση\nγια ${COUNT} εισιτήρια", + "ticketsText": "${COUNT} Εισιτήρια", + "titleText": "Αποκτήστε Εισιτήρια", + "unavailableLinkAccountText": "Συγνώμη, οι αγορές δεν είναι διαθέσιμες σε αυτή την πλατφόρμα.\nΩς λύση, μπορείτε να δεσμεύσετε αυτόν τον λογαριασμό με έναν\nλογαριασμό από άλλη πλατφόρμα και να αγοράσετε από εκεί.", + "unavailableTemporarilyText": "Προς το παρόν μη διαθέσιμο. Παρακαλώ ξαναπροσπαθήστε αργότερα.", + "unavailableText": "Συγνώμη, το συγκεκριμένο δεν είναι διαθέσιμο.", + "versionTooOldText": "Συγνώμη, αυτή η έκδοση του παιχνιδιού είναι πολύ παλιά. Παρακαλώ αναβαθμίστε τη με μια πιο καινούρια.", + "youHaveShortText": "έχετε ${COUNT}", + "youHaveText": "έχετε ${COUNT} εισιτήρια" + }, + "googleMultiplayerDiscontinuedText": "Συγνώμη, φαίνεται πως η υπηρεσία πολλών παικτών της Google δεν είναι πλέον διαθέσιμη.\nΠροσπαθώ να βρω αντικατάσταση όσο πιο γρήγορα γίνεται.\nΜέχρι τότε, παρακαλώ δοκιμάστε άλλο τρόπο σύνδεσης.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Οι αγορές Google Play δεν είναι διαθέσιμες.\nΜπορεί να χρειάζεται να ενημερώσετε την εφαρμογή σας.", + "googlePlayServicesNotAvailableText": "Οι υπηρεσίες Google Play δεν είναι διαθέσιμες.\nΚάποιες λειτουργείες μπορεί να είναι απενεργοποιμένες.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Πάντα", + "fullScreenCmdText": "Πλήρης Οθόνη (Cmd-F)", + "fullScreenCtrlText": "Πλήρης Οθόνη (Ctrl-F)", + "gammaText": "Gamma", + "highText": "Υψηλό", + "higherText": "Υψηλότερο", + "lowText": "Χαμηλό", + "mediumText": "Μέτριο", + "neverText": "Ποτέ", + "resolutionText": "Ανάλυση", + "showFPSText": "Ένδειξη FPS", + "texturesText": "Υφές", + "titleText": "Γραφικά", + "tvBorderText": "Πλαίσιο TV", + "verticalSyncText": "Κατακόρυφος Συγχρονισμός", + "visualsText": "Οπτικά" + }, + "helpWindow": { + "bombInfoText": "- Βόμβα -\nΙσχυρότερη από τις γροθιές, αλλά μπορεί\nνα προκαλέσει δυστυχήματα. Για καλύτερα\nαποτελέσματα ρίξτε τις βόμβες στον εχθρό\nπρίν τελειώσει το φυτίλι.", + "bombInfoTextScale": 0.5, + "canHelpText": "Το ${APP_NAME} μπορεί να βοηθήσει.", + "controllersInfoText": "Μπορείτε να παίξετε ${APP_NAME} με φίλους μέσω ενός δικτύου ή μπορείτε\nόλοι να παίξετε στην ίδια συσκευή εάν έχετε αρκετά χειριστήρια. Το\n${APP_NAME} υποστηρίζει ποικιλία από αυτά. Μπορείτε ακόμα να\nχρησιμοποιήσετε κινητά τηλέφωνα ως χειριστήρια μέσω της δωρεάν εφαρμογής\n'${REMOTE_APP_NAME}'. Βλέπε Ρυθμίσεις->Χειριστήρια για περισσότερες πληροφορίες.", + "controllersInfoTextRemoteOnly": "Μπορείτε να παίξετε ${APP_NAME} με φιλους στο διαδίκτυο, ή μπορείτε\nνα παίξετε όλοι στην ίδια συσκευή χρησιμοποιώντας κινητά ως \nτηλεχειριστήρια μέσω της δωρεάν '${REMOTE_APP_NAME}'εφαρμογής.", + "controllersText": "Χειριστήρια", + "controlsSubtitleText": "Ο φιλικός σας ${APP_NAME} χαρακτήρας έχει μερικές βασικές κινήσεις:", + "controlsText": "Χειρισμοί", + "devicesInfoText": "Η έκδοση VR του ${APP_NAME} μπορεί να παίξει μέσω δικτύου\nμε την κανονική έκδοση, οπότε βγάλτε τα επιπλέον σας τηλέφωνα,\ntablet και υπολογιστές και ξεκινήστε το παιχνίδι. Θα μπορούσατε\nακόμα να συνδέσετε την έκδοση VR με την κανονική για να επιτρέψετε\nστους υπόλοιπους να παρακολουθούν.", + "devicesText": "Συσκευές", + "friendsGoodText": "Καλό θα ήταν να έχετε. Το ${APP_NAME} είναι πιό διασκεδαστικό με πολλούς\nπαίκτες και μπορεί να υποστηρίξει έως και 8 τη φορά, που μας οδηγεί σε:", + "friendsText": "Φίλοι", + "jumpInfoText": "- Άλμα -\nΠηδήξτε για να διασχίσετε μικρά κενά,\nνα πετάξετε αντικείμενα ψηλότερα\nκαι να εκφράσετε συναισθήματα χαράς.", + "orPunchingSomethingText": "Ή να γροθοκοπήσετε κάτι, να το πετάξετε από έναν γκρεμό, κάνοντας το να εκραγεί καθ' οδόν με μία κολλώδη βόμβα.", + "pickUpInfoText": "- Αρπαγή -\nΑρπάξτε σημαίες, εχθρούς ή οτιδήποτε\nάλλο δεν είναι βιδωμένο στο έδαφος.\nΞαναπατήστε για ρίψη.", + "powerupBombDescriptionText": "Σας επιτρέπει να ρίχνετε τρείς βόμβες\nμαζί με τη σειρά αντί για μία.", + "powerupBombNameText": "Τριπλές-Βόμβες", + "powerupCurseDescriptionText": "Ίσως θα προτιμούσατε να τα αποφύγετε.\n ...ή μήπως όχι;", + "powerupCurseNameText": "Κατάρα", + "powerupHealthDescriptionText": "Σας ανανεώνει όλη τη ζωή.\nΠοτέ δεν θα το μαντεύατε σωστά.", + "powerupHealthNameText": "Ιατρικό-Κουτί", + "powerupIceBombsDescriptionText": "Πιό αδύναμες από τις βασικές βόμβες\nαλλά αφήνουν τους εχθρούς σας\nπαγωμένους και εύθραυστους.", + "powerupIceBombsNameText": "Βόμβες-Πάγου", + "powerupImpactBombsDescriptionText": "Ελαφρώς πιό αδύναμες από τις βασικές\nβόμβες αλλά εκρήγνυνται με την επαφή.", + "powerupImpactBombsNameText": "Βόμβες-Ερεθίσματος", + "powerupLandMinesDescriptionText": "Έρχονται ανά τριάδες. Χρήσιμες\nγια τη προστασία μιάς περιοχής\nή για να σταματάνε γρήγορους εχθρούς.", + "powerupLandMinesNameText": "Νάρκες-Εδάφους", + "powerupPunchDescriptionText": "Κάνει τις γροθίες σας σκληρότερες,\nταχύτερες, καλύτερες, δυνατότερες.", + "powerupPunchNameText": "Γάντια-Πυγμαχίας", + "powerupShieldDescriptionText": "Απορροφά λίγες ζημιές που\nεναλλακτικά εσείς θα δεχόσασταν.", + "powerupShieldNameText": "Πεδίο-Ισχύος", + "powerupStickyBombsDescriptionText": "Κολλάνε σε ο,τι αγγίξουν.\nΑκολουθεί σαρκασμός.", + "powerupStickyBombsNameText": "Κολλώδεις-Βόμβες", + "powerupsSubtitleText": "Εννοείται πως κανένα παιχνίδι δεν είναι ολοκληρωμένο χωρίς ενισχυτικά:", + "powerupsSubtitleTextScale": 0.7, + "powerupsText": "Ενισχυτικά", + "punchInfoText": "- Γροθιά -\nΠροκαλούν περισσότερη ζημιά ανάλογα\nμε την ταχύτητα που κινούνται. Γι'\nαυτό τρέξτε και στρίψτε σαν μανιακός.", + "punchInfoTextScale": 0.55, + "runInfoText": "- Τρέξιμο -\nΚρατήστε πατημένο ΟΠΟΙΟΔΗΠΟΤΕ πλήκτρο για να τρέξετε. Πλαϊνά πλήκτρα ή διακόπτες λειτουργούν καλά αν διατίθενται.\nΤο τρέξιμο σας επιτρέπει να φτάνετε ταχύτερα στον προορισμό σας αλλά δυσκολεύει στο στρίψιμο, οπότε προσοχή στους γκρεμούς.", + "runInfoTextScale": 0.45, + "someDaysText": "Ορισμένες μέρες θέλετε να χτυπήσετε κάτι, ή να το ανατινάξετε.", + "titleText": "Βοήθεια ${APP_NAME}", + "toGetTheMostText": "Για καλύτερη εμπειρία από αυτό το παιχνίδι θα χρειαστείτε:", + "welcomeText": "Καλωσορίσατε στο ${APP_NAME}!" + }, + "holdAnyButtonText": "<κρατήστε πατημένο οποιδήποτε κουμπί>", + "holdAnyKeyText": "<κρατήστε πατημένο οποιοδήποτε πλήκτρο>", + "hostIsNavigatingMenusText": "- Ο χρήστης ${HOST} ελέγχει τα μενού σαν το αφεντικό -", + "importPlaylistCodeInstructionsText": "Χρησιμοποιήστε τον παρακάτω κωδικό για την εισαγωγή της λίστας κάπου αλλού:", + "importPlaylistSuccessText": "Έγινε εισαγωγή της λίστας '${NAME}' για ${TYPE}", + "importText": "Εισαγωγή", + "importingText": "Εισαγωγή...", + "inGameClippedNameText": "θα εμφανίζεται ως\n\"${NAME}\"", + "installDiskSpaceErrorText": "ΣΦΑΛΜΑ: Αδύνατη η ολοκλήρωση της εγκατάστασης.\nΕνδέχεται να ξεμείνατε από αποθηκευτικό χώρο στη\nσυσκεύη. Αδειάστε λίγο χώρο και ξαναπροσπαθήστε.", + "internal": { + "arrowsToExitListText": "πατήστε ${LEFT} ή ${RIGHT} για έξοδο από τη λίστα", + "buttonText": "κουμπί", + "cantKickHostError": "Δεν μπορείτε να διώξετε τον οικοδεσπότη.", + "chatBlockedText": "Ο παίκτης ${NAME} είναι αποκλεισμένος από τη συζήτηση γιά ${TIME} δευτ.", + "connectedToGameText": "Ενταχθήκατε σε: '${NAME}'", + "connectedToPartyText": "Ενταχθήκατε στη συγκέντρωση του χρήστη ${NAME}!", + "connectingToPartyText": "Σύνδεση...", + "connectionFailedHostAlreadyInPartyText": "Ανεπιτυχής σύνδεση. Ο οικοδεσπότης βρίσκεται σε άλλη συγκέντρωση.", + "connectionFailedPartyFullText": "Ανεπιτυχής σύνδεση. Η συγκέντρωση είναι γεμάτη.", + "connectionFailedText": "Ανεπιτυχής σύνδεση.", + "connectionFailedVersionMismatchText": "Ανεπιτυχής σύνδεση. Ο οικοδεσπότης τρέχει μιά διαφορετική έκδοση του παιχνιδιού.\nΣιγουρευτείτε ότι και οι δύο έχετε την πιο πρόσφατη έκδοση και ξαναπροσπαθήστε.", + "connectionRejectedText": "Η σύνδεση απορρίφθηκε.", + "controllerConnectedText": "Το χειριστήριο ${CONTROLLER} συνδέθηκε.", + "controllerDetectedText": "1 χειριστήριο εντοπίστηκε.", + "controllerDisconnectedText": "Το χειριστήριο ${CONTROLLER} αποσυνδέθηκε.", + "controllerDisconnectedTryAgainText": "Το χειριστήριο ${CONTROLLER} αποσυνδέθηκε. Παρακαλώ προσπαθήστε να το ξανασυνδέσετε.", + "controllerForMenusOnlyText": "Αυτό το χειριστήριο δεν μπορεί να χρησιμοποιηθεί στο παιχνίδι. Μονάχα για τη περιήγηση στα μενού.", + "controllerReconnectedText": "Το χειριστήριο ${CONTROLLER} ξανασυνδέθηκε.", + "controllersConnectedText": "Συνδέθηκαν ${COUNT} χειριστήρια.", + "controllersDetectedText": "Εντοπίστηκαν ${COUNT} χειριστήρια.", + "controllersDisconnectedText": "Αποσυνδέθηκαν ${COUNT} χειριστήρια.", + "corruptFileText": "Εντοπίστηκαν φθαρμένα αρχεία. Παρακαλώ επανεγκαταστήστε ή επικοινωνήστε με το email ${EMAIL}", + "errorPlayingMusicText": "Σφάλμα παίζοντας τη μουσική: ${MUSIC}", + "errorResettingAchievementsText": "Αδύνατη η επαναρύθμιση των online επιτευγμάτων. Παρακαλώ ξαναπροσπαθήστε αργότερα.", + "hasMenuControlText": "Ο παίκτης ${NAME} έχει τον έλεγχο στα μενού.", + "incompatibleNewerVersionHostText": "Ο οικοδεσπότης τρέχει μία νεότερη έκδοση το παιχνιδιού.\nΑναβαθμίστε στην πιο πρόσφατη έκδοση και ξαναπροσπαθήστε.", + "incompatibleVersionHostText": "Ο οικοδεσπότης τρέχει μιά διαφορετική έκδοση του παιχνιδιού.\nΣιγουρευτείτε ότι και οι δύο έχετε την πιο πρόσφατη έκδοση και ξαναπροσπαθήστε.", + "incompatibleVersionPlayerText": "Ο χρήστης ${NAME} τρέχει μιά διαφορετική έκδοση του παιχνιδιού.\nΣιγουρευτείτε ότι και οι δύο έχετε την πιο πρόσφατη έκδοση και ξαναπροσπαθήστε.", + "invalidAddressErrorText": "Σφάλμα: μη έγκυρη διεύθυνση.", + "invalidNameErrorText": "Σφάλμα: μη έγκυρο όνομα.", + "invalidPortErrorText": "Σφάλμα: μη έγκυρη θύρα.", + "invitationSentText": "Η πρόσκληση έχει σταλεί.", + "invitationsSentText": "${COUNT} προσκλήσεις έχουν σταλεί.", + "joinedPartyInstructionsText": "Κάποιος εντάχθηκε στη συγκέντρωσή σας.\nΠηγαίντε στο 'Παίξε' για να ξεκινήσετε παιχνίδι.", + "keyboardText": "Πληκτρολόγιο", + "kickIdlePlayersKickedText": "Αποβολή του παίκτη ${NAME} λόγω απραξίας.", + "kickIdlePlayersWarning1Text": "Ο παίκτης ${NAME} θα αποβληθεί σε ${COUNT} δευτ. αν παραμείνει άπραγος.", + "kickIdlePlayersWarning2Text": "(αυτό μπορείτε να το απενεργοποιήσετε στίς Ρυθμίσεις -> Σύνθετες)", + "leftGameText": "Αποχώρησατε από: '${NAME}'", + "leftPartyText": "Αποχωρήσατε από τη συγκέντρωση του παίκτη ${NAME}.", + "noMusicFilesInFolderText": "Ο φάκελος δεν περιέχει μουσικά αρχεία.", + "playerJoinedPartyText": "Ο παίκτης ${NAME} εντάχθηκε στη συγκέντρωση!", + "playerLeftPartyText": "Ο παίκτης ${NAME} αποχώρησε από τη συγκέντρωση.", + "rejectingInviteAlreadyInPartyText": "Η πρόσκληση απορρίπτεται (βρίσκεστε ήδη σε συγκέντρωση).", + "serverRestartingText": "Ο διακομιστής επανεκκινήτε. Παρακαλώ προσπαθήστε να επανενταχθείτε σε μία στιγμή...", + "serverShuttingDownText": "Ο διακομιστής κλείνει...", + "signInErrorText": "Σφάλμα κατά τη σύνδεση.", + "signInNoConnectionText": "Αδύνατη η σύνδεση. (χωρίς πρόσβαση στο διαδίκτυο;)", + "telnetAccessDeniedText": "ΣΦΑΛΜΑ: πρόσβαση telnet δεν έχει παραχωρηθεί στον χρήστη.", + "timeOutText": "(ο χρόνος λήγει σε ${TIME} δευτερόλεπτα)", + "touchScreenJoinWarningText": "Έχετε ενταχθεί με την οθόνη αφής.\nΑν συνέβη καταλάθος πατήστε με αυτή στο 'Μενού->Έξοδος Παιχνιδιού'.", + "touchScreenText": "Οθόνη Αφής", + "unableToResolveHostText": "Σφάλμα: αδύνατη η επίλυση του οικοδεσπότη.", + "unavailableNoConnectionText": "Αυτό είναι προς το παρόν μη διαθέσιμο (χωρίς πρόσβαση στο διαδίκτυο;)", + "vrOrientationResetCardboardText": "Χρησιμοποιήστε το για την επαναφορά το προσανατολισμού VR.\nΓια να παίξετε το παιχνίδι θα χρειαστείτε ένα εξωτερικό χειριστήριο.", + "vrOrientationResetText": "Έγινε επαναφορά του VR προσανατολισμού.", + "willTimeOutText": "(θα σταματήσει αν παραμείνει αδρανής)" + }, + "jumpBoldText": "ΑΛΜΑ", + "jumpText": "Άλμα", + "keepText": "Κράτησέ τες", + "keepTheseSettingsText": "Θέλετε να κρατήσετε έτσι τις ρυθμίσεις;", + "keyboardChangeInstructionsText": "Πατήστε δύο φορές το κουμπί κενό για να αλλάξετε πληκτρολόγιο.", + "keyboardNoOthersAvailableText": "Δεν υπάρχουν άλλα πληκτρολόγια διαθέσιμα.", + "keyboardSwitchText": "Αλλαγή πληκτρολογίου σε \"${NAME}\".", + "kickOccurredText": "Ο παίκτης ${NAME} αποβλήθηκε.", + "kickQuestionText": "Αποβολή του παίκτη ${NAME};", + "kickText": "Αποβολή", + "kickVoteCantKickAdminsText": "Οι διαχειριστές δεν μπορούν να διωχθούν.", + "kickVoteCantKickSelfText": "Δεν μπορείτε να διώξετε τον εαυτό σας.", + "kickVoteFailedNotEnoughVotersText": "Δεν υπάρχουν αρκετοί παίκτες για ψήφο.", + "kickVoteFailedText": "Η ψηφοφορία για αποβολή απέτυχε.", + "kickVoteStartedText": "Μια ψηφοφορία για την αποβολή του παίκτη ${NAME} ξεκίνησε.", + "kickVoteText": "Ψήφος προς Αποβολή", + "kickVotingDisabledText": "Το διώξημο μέσο ψήφου είναι απενεργοποιημένο.", + "kickWithChatText": "Γράψτε ${YES} στη συνομιλία για ναι ή ${NO} για όχι.", + "killsTallyText": "${COUNT} φόνοι", + "killsText": "Φόνοι", + "kioskWindow": { + "easyText": "Εύκολο", + "epicModeText": "Επική λειτουργία", + "fullMenuText": "Ολοκληρωμένο Μενού", + "hardText": "Δύσκολο", + "mediumText": "Μέτριο", + "singlePlayerExamplesText": "Μονός Παίκτης / Συνεργασία Παραδείγματα", + "versusExamplesText": "Παραδείγματα Εναντίον" + }, + "languageSetText": "Η γλώσσα είναι τώρα \"${LANGUAGE}\".", + "lapNumberText": "Γύρος ${CURRENT}/${TOTAL}", + "lastGamesText": "(τελευταία ${COUNT} παιχνίδια)", + "leaderboardsText": "Πίνακες Κατάταξης", + "league": { + "allTimeText": "Διαχρονικά", + "currentSeasonText": "Παρούσα Σεζόν (${NUMBER})", + "leagueFullText": "${NAME} Κατηγορία", + "leagueRankText": "Κατάταξη Κατηγορίας", + "leagueText": "Κατηγορία", + "rankInLeagueText": "#${RANK}, ${NAME} Κατηγορία${SUFFIX}", + "seasonEndedDaysAgoText": "Η σεζόν έληξε πριν από ${NUMBER} μέρες.", + "seasonEndsDaysText": "Η σεζόν λήγει σε ${NUMBER} μέρες.", + "seasonEndsHoursText": "Η σεζόν λήγει σε ${NUMBER} ώρες.", + "seasonEndsMinutesText": "Η σεζόν λήγει σε ${NUMBER} λεπτά.", + "seasonText": "Σεζόν ${NUMBER}", + "tournamentLeagueText": "Πρέπει να φτάσετε στην κατηγορία ${NAME} για να συμμετάσχετε σε αυτό το τουρνουά.", + "trophyCountsResetText": "Ο αριθμός των βραβείων θα υποστεί επαναφορά στην επόμενη σεζόν." + }, + "levelBestScoresText": "Οι υψηλότερες βαθμολογίες στο επίπεδο ${LEVEL}", + "levelBestTimesText": "Οι καλύτεροι χρόνοι στο επίπεδο ${LEVEL}", + "levelIsLockedText": "Το επίπεδο ${LEVEL} είναι κλειδωμένο.", + "levelMustBeCompletedFirstText": "Το επίπεδο ${LEVEL} πρέπει πρώτα να ολοκληρωθεί.", + "levelText": "Επίπεδο ${NUMBER}", + "levelUnlockedText": "Το Επίπεδο Ξεκλειδώθηκε!", + "livesBonusText": "Μπόνους Ζωών", + "loadingText": "Φόρτωση", + "loadingTryAgainText": "Φορτώνει. Παρακαλώ ξαναπροσπαθήστε αργότερα...", + "macControllerSubsystemBothText": "Και τα δύο (δεν προτείνεται)", + "macControllerSubsystemClassicText": "Κλασσικό", + "macControllerSubsystemDescriptionText": "(δοκιμάστε να το αλλάξετε αυτό αν τα χειριστήριά σας δεν λειτουργούν)", + "macControllerSubsystemMFiNoteText": "Εντοπίστηκε χειριστήριο φτιαγμένο-γιά-iOS/Mac.\nΊσως θα θέλατε να το ενεργοποιήσετε στις Ρυθμίσεις -> Χειριστήρια", + "macControllerSubsystemMFiText": "Φτιαγμένο-για-iOS/Mac", + "macControllerSubsystemTitleText": "Υποστήριξη Χειριστηρίων", + "mainMenu": { + "creditsText": "Εύσημα", + "demoMenuText": "Μενού Επίδειξης", + "endGameText": "Τέλος Παιχνιδιού", + "endTestText": "Τέλος τεστ", + "exitGameText": "Έξοδος Παιχνιδιού", + "exitToMenuText": "Έξοδος στο μενού;", + "howToPlayText": "Πως Παίζεται;", + "justPlayerText": "(Μονάχα ο Παίκτης ${NAME})", + "leaveGameText": "Αποχώρηση από το Παιχνίδι", + "leavePartyConfirmText": "Πραγματικά, αποχώρηση από τη συγκέντρωση;", + "leavePartyText": "Αποχώρηση από τη Συγκέντρωση", + "quitText": "Εγκατάλειψη", + "resumeText": "Συνέχιση", + "settingsText": "Ρυθμίσεις" + }, + "makeItSoText": "Κάν' το Έτσι", + "mapSelectGetMoreMapsText": "Περισσότεροι Χάρτες...", + "mapSelectText": "Επιλογή...", + "mapSelectTitleText": "Χάρτες ${GAME}", + "mapText": "Χάρτης", + "maxConnectionsText": "Μέγιστος Αριθμός Συνδέσεων", + "maxPartySizeText": "Μέγιστος Αριθμός Συγκέντρωσης", + "maxPlayersText": "Μέγιστος Αριθμός Παικτών", + "modeArcadeText": "Λειτουργία \"Arcade\"", + "modeClassicText": "Κλασσική λειτουργία", + "modeDemoText": "Δοκιμαστική λειτουργία", + "mostValuablePlayerText": "Πολυτιμότερος Παίκτης", + "mostViolatedPlayerText": "Πιο Ξυλοδαρμένος Παίκτης", + "mostViolentPlayerText": "Πιο Βίαιος Παίκτης", + "moveText": "Κίνηση", + "multiKillText": "${COUNT}-ΦΟΝΟΙ!!!", + "multiPlayerCountText": "${COUNT} παίκτες", + "mustInviteFriendsText": "Σημείωση: πρέπει να προσκαλέσετε φίλους από τον\nπίνακα \"${GATHER}\" ή να συνδέσετε χειριστήρια\nγια να παίξετε παιχνίδι για πολλαπλούς παίκτες.", + "nameBetrayedText": "Ο ${NAME} πρόδωσε τον ${VICTIM}.", + "nameDiedText": "Ο παίκτης ${NAME} πέθανε.", + "nameKilledText": "Ο ${NAME} σκότωσε τον ${VICTIM}.", + "nameNotEmptyText": "Το όνομα δεν μπορεί να είναι κενό!", + "nameScoresText": "Ο παίκτης ${NAME} Σκοράρει!", + "nameSuicideKidFriendlyText": "Ο παίκτης ${NAME} σκοτώθηκε καταλάθος.", + "nameSuicideText": "Ο παίκτης ${NAME} αυτοκτόνησε.", + "nameText": "Όνομα", + "nativeText": "Προσαρμόσιμο", + "newPersonalBestText": "Νέα προσωπικό ρεκόρ!", + "newTestBuildAvailableText": "Μια νεότερη δοκιμαστική έκδοση είναι διαθέσιμη! (κύρια ${VERSION}, δοκιμαστική ${BUILD}).\nΠαραλάβετέ την από ${ADDRESS}", + "newText": "Νέο", + "newVersionAvailableText": "Μιά νέα έκδοση ${APP_NAME} είναι διαθέσιμη! (${VERSION})", + "nextAchievementsText": "Επόμενα Επιτεύγματα:", + "nextLevelText": "Επόμενο Επίπεδο", + "noAchievementsRemainingText": "- κανένα", + "noContinuesText": "(χωρίς \"Συνέχιση\")", + "noExternalStorageErrorText": "Δεν βρέθηκε εξωτερικός αποθηκευτικός χώρος σε αυτή τη συσκευή", + "noGameCircleText": "Σφάλμα: δεν έχετε συνδεθεί στο GameCircle", + "noScoresYetText": "Δεν υπάρχουν βαθμολογίες ακόμη.", + "noThanksText": "Όχι Ευχαριστώ", + "noTournamentsInTestBuildText": "ΠΡΟΣΟΧΗ: Τα σκορ του τουρνουά από αυτή τη δοκιμαστική έκδοση θα αγνοηθούν.", + "noValidMapsErrorText": "Δεν βρέθηκαν έγκυροι χάρτες γι' αυτόν τον τύπο παιχνιδιού.", + "notEnoughPlayersRemainingText": "Οι παίκτες που παραμένουν δεν είναι αρκετοί. Αποχωρήστε και ξεκινήστε νέο παιχνίδι.", + "notEnoughPlayersText": "Χρειάζεστε τουλάχιστον ${COUNT} παίκτες για να ξεκινήσετε αυτό το παιχνίδι!", + "notNowText": "Όχι Τώρα", + "notSignedInErrorText": "Πρέπει να συνδεθείτε γι' αυτό.", + "notSignedInGooglePlayErrorText": "Πρέπει να συνδεθείτε με το Google Play γι' αυτό.", + "notSignedInText": "δεν έχετε συνδεθεί", + "notUsingAccountText": "Σημείωση: αγνοείται ο λογαριασμός ${SERVICE}.\nΠηγαίνετε στο'Λογαριασμός -> Σύνδεση με ${SERVICE}' αν θέλετε να τον χρησιμοποιήσετε.", + "nothingIsSelectedErrorText": "Τίποτα δεν επιλέχθηκε!", + "numberText": "#${NUMBER}", + "offText": "Κλειστό", + "okText": "Εντάξει", + "onText": "Ανοιχτό", + "oneMomentText": "Μια στιγμή...", + "onslaughtRespawnText": "Ο παίκτης ${PLAYER} θα ξαναδημιουργηθεί στο κύμα ${WAVE}", + "orText": "${A} ή ${B}", + "otherText": "Άλλο...", + "outOfText": "(#${RANK} από ${ALL})", + "ownFlagAtYourBaseWarning": "Η σημαία σας πρέπει να είναι\nστη βάση της για να σκοράρετε!", + "packageModsEnabledErrorText": "Το παιχνίδι σε δίκτυο δεν επιτρέπεται όσο υπάρχουν ενεργά τοπικά-πακέτα-τροποποίησης (βλέπε Ρυθμίσεις->Σύνθετες)", + "partyWindow": { + "chatMessageText": "Μύνημα Συζήτησης", + "emptyText": "Η συγκέντρωσή σας είναι άδεια", + "hostText": "(οικοδεσπότης)", + "sendText": "Αποστολή", + "titleText": "Η Συγκέντρωσή Σας" + }, + "pausedByHostText": "(παύση από τον οικοδεσπότη)", + "perfectWaveText": "Τέλειο Κύμα!", + "pickUpText": "Αρπαγή", + "playModes": { + "coopText": "Συνεργασία", + "freeForAllText": "Ελεύθερο-Για-Όλους", + "multiTeamText": "Πολλαπλές-Ομάδες", + "singlePlayerCoopText": "Μονός Παίκτης / Συνεργασία", + "teamsText": "Ομάδες" + }, + "playText": "Παίξε", + "playWindow": { + "oneToFourPlayersText": "1-4 παίκτες", + "titleText": "Παιχνίδι", + "twoToEightPlayersText": "2-8 παίκτες" + }, + "playerCountAbbreviatedText": "${COUNT}παίκ.", + "playerDelayedJoinText": "Ο παίκτης ${PLAYER} θα κάνει είσοδο στην εκκίνηση του επόμενου γύρου.", + "playerInfoText": "Πληροφορίες Παίκτη", + "playerLeftText": "Ο παίκτης ${PLAYER} αποχώρησε από το παιχνίδι.", + "playerLimitReachedText": "Το όριο των ${COUNT} επετεύχθη. Περεταίρω ένταξη δεν επιτρέπεται.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Δεν μπορείτε να διαγράψετε το προφίλ του λογαριασμού σας.", + "deleteButtonText": "Διαγραφή\nΠροφίλ", + "deleteConfirmText": "Διαγραφή '${PROFILE}';", + "editButtonText": "Επεξεργασία\nΠροφίλ", + "explanationText": "(προσαρμοσμένα ονόματα παικτών και εμφανίσεις γι' αυτόν τον λογαριασμό)", + "newButtonText": "Νέο\nΠροφίλ", + "titleText": "Προφίλ Παίκτη" + }, + "playerText": "Παίκτης", + "playlistNoValidGamesErrorText": "Αυτή η λίστα αποτελείται από μη έγκυρα ξεκλειδωμένα παιχνίδια.", + "playlistNotFoundText": "η λίστα δεν βρέθηκε", + "playlistText": "Λίστα αναπαραγωγής.", + "playlistsText": "Λίστες Παιχνιδιών", + "pleaseRateText": "Εάν απολαμβάνετε το ${APP_NAME}, παρακαλώ σκεφτείτε να αφιερώσετε μιά στιγμή\nγια να το βαθμολογήσετε ή να γράψετε μιά κριτική. Αυτό θα προσφέρει χρήσιμη\nανατροφοδότηση και θα βοηθήσει για την υποστήριξη της μέλλουσας ανάπτυξης.\n\nευχαριστώ!\n-eric", + "pleaseWaitText": "Παρακαλώ περιμένετε...", + "pluginClassLoadErrorText": "Σφάλμα φορτώνοντας πρόσθετο '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Σφάλμα επερξεγάζοντας πρόσθετο '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Νέα πρόσθετο/α εντοπίστηκαν. Επανεκκινήστε την εφαρμογή για να τα ενεργοποιήσετε, ή διαμορφώστε τα στις ρυθμίσεις.", + "pluginsRemovedText": "${NUM} πρόσθετο/α δεν εντοπίζονται πια.", + "pluginsText": "Πρόσθετα", + "practiceText": "Πρακτική", + "pressAnyButtonPlayAgainText": "Πατήστε οποιοδήποτε κουμπί για να ξαναπαίξετε...", + "pressAnyButtonText": "Πατήστε οποιοδήποτε κουμπί για να συνεχίσετε...", + "pressAnyButtonToJoinText": "πατήστε οποιοδήποτε κουμπί για να ενταχθείτε...", + "pressAnyKeyButtonPlayAgainText": "Πατήστε οποιοδήποτε πλήκτρο/κουμπί για να ξαναπαίξετε...", + "pressAnyKeyButtonText": "Πατήστε οποιοδήποτε πλήκτρο/κουμπί για να συνεχίσετε...", + "pressAnyKeyText": "Πατήστε οποιοδήποτε πλήκτρο...", + "pressJumpToFlyText": "** Πατήστε το άλμα συνεχόμενα για να πετάξετε **", + "pressPunchToJoinText": "πατήστε ΓΡΟΘΙΑ για να ενταχθείτε...", + "pressToOverrideCharacterText": "πιέστε ${BUTTONS} για να αναιρέσετε τον χαρακτήρα σας", + "pressToSelectProfileText": "πατήστε ${BUTTONS} για την επιλογή παίκτη", + "pressToSelectTeamText": "πατήστε ${BUTTONS} για την επιλογή ομάδας", + "promoCodeWindow": { + "codeText": "Κωδικός", + "enterText": "Εισαγωγή" + }, + "promoSubmitErrorText": "Σφάλμα κατά την υποβολή του κωδικού. Ελέγξτε την πρόσβασή σας στο διαδίκτυο", + "ps3ControllersWindow": { + "macInstructionsText": "Απενεργοποιήστε το PS3 σας, σιγουρευτείτε ότι το Bluetooth\nείναι ενεργοποιημένο στον Mac σας, έπειτα συνδέστε το χειριστήριό\nσας στον Mac μέσω καλωδίου USB για να τα ζευγαρώσετε. Από εκεί\nκαι στο εξής μπορείτε να χρησιμοποιήσετε το κουμπί \"home\" του \nχειριστηρίου για να το συνδέσετε στον Mac σας είτε με ενσύρματη\n(USB) ή ασύρματη (Bluetooth) λειτουργία.\n\nΣε μερικούς Mac μπορεί να σας ζητηθεί κωδικός πρόσβασης\nκατά το ζευγάρωμα. Αν συμβεί αυτό, δείτε το ακόλουθο\nεκπαιδευτικό ή κάντε αναζήτηση google για βοήθεια.\n\nΤα PS3 χειριστήρια που συνδέθηκαν ασύρματα πρέπει να εμφανίζονται\nστη λίστα με τις συσκευές στο Προτιμήσεις Συστήματος->Bluetooth.\nΜπορεί να χρειαστεί να τα αφαιρέσετε από αυτή τη λίστα όταν\nθα θελήσετε να τα χρησιμοποιήσετε πάλι για το PS3 σας.\n\nΕπίσης σιγουρευτείτε ότι θα αποσυνδέσετε από το Bluetooth για όσο δεν\nχρησιμοποιούνται, ειδάλλως οι μπαταρίες θα συνεχίσουν να ξοδεύονται.\n\nΤο Bluetooth μπορεί να υποστηρίξει έως και 7 συνδεδεμένες συσκευές,\nωστόσο η ισχύς μπορεί να διαφέρει.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "Για να χρησιμοποιήσετε ένα χειριστήριο PS3 με το OUYA σας, απλά συνδέστε το με ένα καλώδιο\nUSB για να τα ζευγαρώσετε. Κάνοντας αυτό μπορεί να αποσυνδεθούν τα υπόλοιπά σας χειριστήρια,\nγι' αυτό μετά πρέπει να επανεκκινήσετε το OUYA σας και να αποσυνδέσετε το καλώδιο USB.\n\nΑπό εκεί και στο εξής θα μπορείτε να χρησιμοποιείτε το κουμπί \"HOME\" για να τα\nσυνδέετε ασύρματα. Όταν τελειώσετε με το παιχνίδι, κρατήστε πατημένο το κουμπί\n\"HOME\" για 10 δευτερόλεπτα ώστε να απενεργοποιήσετε το χειριστήριο, ειδάλλως\nθα παραμείνει ανοιχτό ξοδεύοντας μπαταρία.", + "ouyaInstructionsTextScale": 0.6, + "pairingTutorialText": "εκπαιδευτικό βίντεο ζευγαρώματος", + "titleText": "Χρήση PS3 Χειριστηρίων με το ${APP_NAME}:" + }, + "punchBoldText": "ΓΡΟΘΙΑ", + "punchText": "Γροθιά", + "purchaseForText": "Αγορά για ${PRICE}", + "purchaseGameText": "Αγορά Παιχνιδιού", + "purchasingText": "Αγορά...", + "quitGameText": "Έξοδος από το ${APP_NAME};", + "quittingIn5SecondsText": "Έξοδος σε 5 δευτερόλεπτα...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Τυχαίο", + "rankText": "Κατάταξη", + "ratingText": "Βαθμολογία", + "reachWave2Text": "Φτάστε στο κύμα 2 για να καταταχθείτε.", + "readyText": "έτοιμος", + "recentText": "Πρόσφατα", + "remoteAppInfoShortText": "Το ${APP_NAME} είναι πιό διασκεδαστικό όταν παίζεται με φίλους και\nοικεγένεια. Συνδέστε ένα ή περισσότερα χειριστήρια ή εγκαταστήστε\nτην εφαρμογή ${REMOTE_APP_NAME} σε τηλέφωνα ή tablets για να τα\nχρησιμοποιήσετε ως χειριστήρια.", + "remote_app": { + "app_name": "Χειριστήριο BombSquad", + "app_name_short": "BSΧειριστήριο", + "button_position": "Θέση Κουμπιών", + "button_size": "Μέγεθος Κουμπιών", + "cant_resolve_host": "Αδύνατη η επίλυση του οικοδεσπότη.", + "capturing": "Σύλληψη...", + "connected": "Συνδέθηκε.", + "description": "Χρησιμοποίησε το τηλέφωνο ή το tablet σου ως χειριστήριο BombSquad!\nΈως και 8 συσκευές μπορούν να συνδεθούν ταυτόχρονα για ένα επικό παιχνίδι πολλαπλών παικτών (σε τοπικό δίκτυο) σε μία απλή TV ή tablet.", + "disconnected": "Ο διακομιστής σας αποσύνδεσε.", + "dpad_fixed": "σταθερό", + "dpad_floating": "ελεύθερο", + "dpad_position": "Θέση D-Pad", + "dpad_size": "Μέγεθος D-Pad", + "dpad_type": "Τύπος D-Pad", + "enter_an_address": "Εισάγετε Διεύθυνση", + "game_full": "Αυτό το παιχνίδι είναι γεμάτο ή δεν δέχεται συνδέσεις.", + "game_shut_down": "Το παιχνίδι έκλεισε.", + "hardware_buttons": "Κουμπιά Υλισμικού", + "join_by_address": "Ένταξη μέσω Διεύθυνσης...", + "lag": "Καθυστέρηση: ${SECONDS} δευτερόλεπτα", + "reset": "Επαναφορά στα Προκαθορισμένα", + "run1": "Τρέξιμο 1", + "run2": "Τρέξιμο 2", + "searching": "Αναζήτηση για παιχνίδια BombSquad...", + "searching_caption": "Πατήστε στο όνομα ένος παιχνδιού για να συνδεθείτε σε αυτό.\nΣιγουρευτείτε ότι βρίσκεστε στο ίδιο δίκτυο wifi με το παιχνίδι.", + "start": "Εκκίνηση", + "version_mismatch": "Οι εκδόσεις δεν ταιριάζουν.\nΣιγουρευτείτε ότι έχετε τις πιό πρόσφατες εκδόσεις για το\nBombSquad και για το Χειριστήριο BombSquad και ξαναπροσπαθήστε." + }, + "removeInGameAdsText": "Ξεκλειδώστε το \"${PRO}\" στο κατάστημα για να αφαιρέσετε τις διαφημήσεις κατα τη διάρκεια του παιχνιδιού.", + "renameText": "Μετονομασία", + "replayEndText": "Λήξη Επανάληψης", + "replayNameDefaultText": "Επανάληψη Τελευταίου Παιχνιδιού", + "replayReadErrorText": "Σφάλμα κατά την ανάγνωση του αρχείου επανάληψης.", + "replayRenameWarningText": "Μετονομάστε το \"${REPLAY}\" μετά από κάθε παιχνίδι άμα θέλετε να το κρατήσετε, ειδάλλως θα αντικαθίσταται.", + "replayVersionErrorText": "Συγνώμη, αυτή η επανάληψη δημιουργήθηκε σε μιά διαφορετική\nέκδοση του παιχνιδιού και δεν μπορεί να χρησιμοποιηθεί.", + "replayWatchText": "Προβολή Επανάληψης", + "replayWriteErrorText": "Σφάλμα κατά την εγγραφή του αρχείου επανάληψης.", + "replaysText": "Επαναλήψεις", + "reportPlayerExplanationText": "Χρησιμοποιήστε αυτό το email για να κάνετε αναφορά ζαβολιάς, απρεπούς λεξιλογίου ή άλλου είδους κακής συμπεριφοράς.\nΠαρακαλώ περιγράψτε παρακάτω:", + "reportThisPlayerCheatingText": "Ζαβολιά", + "reportThisPlayerLanguageText": "Απρεπές Λεξιλόγιο", + "reportThisPlayerReasonText": "Τι θα θέλατε να αναφέρετε;", + "reportThisPlayerText": "Αναφορά Αυτού του Παίκτη", + "requestingText": "Αίτηση...", + "restartText": "Επανεκκίνηση", + "retryText": "Εκ νέου απόπειρα", + "revertText": "Επαναφορά", + "runText": "Τρέξιμο", + "saveText": "Αποθήκευση", + "scanScriptsErrorText": "Σφάλματα σάρωσης σάρωσης; δείτε το αρχείο καταγραφής για λεπτομέρειες.", + "scoreChallengesText": "Προκλήσεις Βαθμολογίας", + "scoreListUnavailableText": "Λίστα βαθμολογίας μη διαθέσιμη.", + "scoreText": "Βαθμολογία", + "scoreUnits": { + "millisecondsText": "Χιλιοστά Δευτερολέπτου", + "pointsText": "Πόντοι", + "secondsText": "Δευτερόλεπτα" + }, + "scoreWasText": "(ήταν ${COUNT})", + "selectText": "Επιλογή", + "seriesWinLine1PlayerText": "ΚΕΡΔΙΣΕ ΤΗ", + "seriesWinLine1TeamText": "ΚΕΡΔΙΣΕ ΤΗ", + "seriesWinLine1Text": "ΚΕΡΔΙΣΕ ΤΗ", + "seriesWinLine2Text": "ΣΕΙΡΑ!", + "settingsWindow": { + "accountText": "Λογαριασμός", + "advancedText": "Σύνθετες", + "audioText": "Ήχος", + "controllersText": "Χειριστήρια", + "graphicsText": "Γραφικά", + "playerProfilesMovedText": "Σημείωση: η ενότητα \"Προφίλ Παίκτη\" μετακινήθηκε στο παράθυρο \"Λογαριασμός\" στο κύριο μενού.", + "titleText": "Ρυθμίσεις" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(ένα απλό, φιλικό με τα χειριστήρια πληκτρολόγιο οθόνης για επεξεργασία κειμένου)", + "alwaysUseInternalKeyboardText": "Πάντα να Χρησιμοποιείται το Εσωτερικό Πληκτρολόγιο", + "benchmarksText": "Έλεγχοι Απόδοσης & Κόπωσης", + "disableCameraGyroscopeMotionText": "Απενεργοποιήστε γυροσκοπική κίνηση της κάμερας", + "disableCameraShakeText": "Απενεργοποιήστε το κούνημα της κάμερας", + "disableThisNotice": "(μπορείτε να απενεργοποιήσετε αυτή τήν ειδοποίηση στις σύνθετες ρυθμίσεις)", + "enablePackageModsDescriptionText": "(επιτρέπει επιπλέον δυνατότητες τροποποίησης αλλά απενεργοποιεί το παιχνίδι σε δίκτυο)", + "enablePackageModsText": "Ενεργοποίηση Τοπικών Πακέτων Τροποποίησης", + "enterPromoCodeText": "Εισαγωγή Κωδικού", + "forTestingText": "Σημείωση: αυτές οι τιμές είναι μονάχα για έλεγχο και θα χαθούν όταν πραγματοποιηθεί έξοδος από την εφαρμογή.", + "helpTranslateText": "Οι μη Αγγλικές μεταφράσεις του ${APP_NAME} είναι υποστιριζόμενες\nαπό την κοινότητα. Αν θα θέλατε να συνεισφέρετε ή να διορθώσετε μια\nμετάφραση ακολουθήστε τον παρακάτω σύνδεσμο. Ευχαριστώ προκαταβολικά!", + "kickIdlePlayersText": "Αποβολή Άπραγων Παικτών", + "kidFriendlyModeText": "Λειτουργία για Παιδιά (μειωμένη βία, κτλ)", + "languageText": "Γλώσσα", + "moddingGuideText": "Οδηγός Τροποποίησης", + "mustRestartText": "Για να λειτουργήσει, πρέπει να επανεκκινήσετε το παιχνίδι.", + "netTestingText": "Έλεγχος Δικτύου", + "resetText": "Επαναφορά", + "showBombTrajectoriesText": "Εμφάνιση Πορείας Βόμβας", + "showPlayerNamesText": "Προβολή Ονομάτων Παικτών", + "showUserModsText": "Προβολή Φακέλου Πακέτων Τροποποίησης", + "titleText": "Σύνθετες", + "translationEditorButtonText": "Επεξεργαστής Γλωσσικών Μεταφράσεων ${APP_NAME}", + "translationFetchErrorText": "κατάσταση μεταφράσεων μη διαθέσιμη", + "translationFetchingStatusText": "έλεγχος κατάστασης μεταφράσεων...", + "translationInformMe": "Πληροφόρησέ με όταν η γλώσσα μου χρειάζεται ενημερώσεις", + "translationNoUpdateNeededText": "η συγγεκριμμένη γλώσσα είναι ενημερωμένη, γιούπι!", + "translationUpdateNeededText": "** η συγκεκριμένη γλώσσα χρειάζεται ενημερώσεις!! **", + "vrTestingText": "Έλεγχος VR" + }, + "shareText": "Κοινοποίηση", + "sharingText": "Κοινοποίηση...", + "showText": "Προβολή", + "signInForPromoCodeText": "Πρέπει να συνδεθείτε σε έναν λογαριασμό ώστε οι κωδικοί να πιάσουν τόπο.", + "signInWithGameCenterText": "Για να χρησιμοποιήσετε έναν λογαριασμό Game Center,\nσυνδεθείτε σε αυτόν με την εφαρμογή Game Center.", + "singleGamePlaylistNameText": "Μόνο ${GAME}", + "singlePlayerCountText": "1 παίκτης", + "soloNameFilterText": "Σόλο ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Επιλογή Χαρακτήρα", + "Chosen One": "Εκλεκτός", + "Epic": "Παιχνίδια Επικής Λειτουργίας", + "Epic Race": "Επικός Αγώνας Ταχύτητας", + "FlagCatcher": "Κατάκτηση Σημαίας", + "Flying": "Χαρούμενες Σκέψεις", + "Football": "Ποδόσφαιρο", + "ForwardMarch": "Έφοδος", + "GrandRomp": "Κυριαρχία", + "Hockey": "Χόκεϋ", + "Keep Away": "Απομάκρυνση", + "Marching": "Περίγυρος", + "Menu": "Κύριο Μενού", + "Onslaught": "Επίθεση", + "Race": "Αγώνας Ταχύτητας", + "Scary": "Βασιλιάς του Λόφου", + "Scores": "Οθόνη Βαθμολογίας", + "Survival": "Εξόντωση", + "ToTheDeath": "Μάχη Θανάτου", + "Victory": "Τελική Οθόνη Βαθμολογίας" + }, + "spaceKeyText": "κενό", + "statsText": "Στατιστικές", + "storagePermissionAccessText": "Αυτό απαιτεί πρόσβαση στον χώρο αποθήκευσης", + "store": { + "alreadyOwnText": "Το αντικείμενο \"${NAME}\" σας ανήκει ήδη!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Αφαιρεί τις διαφιμήσεις στο παιχνίδι και τις αναδυόμενες οθόνες\n• Ξεκλειδώνει περισσότερες ρυθμίσεις\n• Επιπλέον περιλαμβάνει:", + "buyText": "Αγορά", + "charactersText": "Χαρακτήρες", + "comingSoonText": "Προσεχώς...", + "extrasText": "Επιπλέον", + "freeBombSquadProText": "Το BombSquad είναι πλέον δωρεάν, αλλά αφού το έχετε αγοράσει εξ' αρχής\nθα λάβετε την BombSquad Pro αναβάθμιση και ${COUNT} εισιτήρια ως ευχαριστώ.\nΑπολαύστε τα νέα χαρακτηριστικά, και ευχαριστώ για την υποστήριξη!\n-Eric", + "holidaySpecialText": "Ειδικά Διακοπών/Αργίας", + "howToSwitchCharactersText": "(πηγαίντε στο \"${SETTINGS} -> ${PLAYER_PROFILES}\" για να αναθέσετε και να προσαρμόσετε χαρακτήρες)", + "howToUseIconsText": "(δημιουργήστε παγκόσμια προφίλ παίκτη (στο παράθυρο των λογαριασμών) για να μπορείτε να τα χρησιμοποιήσετε)", + "howToUseMapsText": "(χρησιμοποιήστε αυτούς τους χάρτες στις δικές σας λίστες Ομάδες/Ελεύθερο-Για-Όλους)", + "iconsText": "Εικονίδια", + "loadErrorText": "Αδύνατη η φόρτωση της σελίδας.\nΕλέγξτε την πρόσβασή σας στο διαδίκτυο.", + "loadingText": "Φόρτωση", + "mapsText": "Χάρτες", + "miniGamesText": "ΜικροΠαιχνίδια", + "oneTimeOnlyText": "(μια φορά μόνο)", + "purchaseAlreadyInProgressText": "Η αγορά αυτού του αντικειμένου βρίσκεται ήδη σε εξέλιξη.", + "purchaseConfirmText": "Αγορά του αντικειμένου ${ITEM};", + "purchaseNotValidError": "Η αγορά δεν είναι έγκυρη.\nΕπικοινωνήστε στο ${EMAIL} αν αυτό είναι σφάλμα.", + "purchaseText": "Αγορά", + "saleBundleText": "Προσφορά Πακέτου!", + "saleExclaimText": "Προσφορά!", + "salePercentText": "(${PERCENT}% προσφορά)", + "saleText": "ΠΡΟΣΦΟΡΑ", + "searchText": "Αναζήτηση", + "teamsFreeForAllGamesText": "Παιχνίδια για Ομάδες / Ελεύθερο-Για-Όλους", + "totalWorthText": "*** Αξίας ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Αναβάθμιση;", + "winterSpecialText": "Ειδικά Χειμερινά", + "youOwnThisText": "- σας ανήκει -" + }, + "storeDescriptionText": "Τρελό Παιχνίδι Για 8 Άτομα!\n\nΑνατινάξτε τους φίλους σας (ή τον υπολογιστή) σε ένα τουρνουά από εκρηκτικά mini-games όπως Κατακτηση-Σημαίας, Βόμβο-Χόκεϋ, και Επική-Μάχη-Μέχρι-Θανάτου-Σε-Αργή-Κίνηση!\n\nΟι απλοί χειρισμοί και η εκτενής υποστήριξη χειριστηρίων το κάνουν εύκολο μέχρι και για 8 άτομα να πάρουν μέρος στην δράση! Είναι δυνατή και η χρήση φορητών συσκευών ως χειριστήρια μέσω της εφαρμογής 'Χειριστήριο BombSquad'!\n\nΒόμβες! Φύγαμε!\n\nΒλέπε www.froemling.net/bombsquad για περισσότερες πληροφορίες.", + "storeDescriptions": { + "blowUpYourFriendsText": "Ανατινάξτε τους φίλους σας.", + "competeInMiniGamesText": "Ανταγωνιστείτε σε mini-games από αγώνες ταχύτητας έως και πέταγμα.", + "customize2Text": "Προσαρμόστε χαρακτήρες, mini-games, ακόμα και τη μουσική.", + "customizeText": "Προσαρμόστε χαρακτήρες και δημιουργήστε τις δικές σας λίστες mini-games.", + "sportsMoreFunText": "Τα αγωνίσματα είναι πιο διασκεδαστικά με εκρήξεις.", + "teamUpAgainstComputerText": "Συμμαχήστε εναντίον του υπολογιστή." + }, + "storeText": "Κατάστημα", + "submitText": "Υποβολή", + "submittingPromoCodeText": "Υποβολή Κωδικού...", + "teamNamesColorText": "Ονόματα/Χρώμματα Ομάδων...", + "telnetAccessGrantedText": "Πρόσβαση telnet ενεργοποιημένη.", + "telnetAccessText": "Πρόσβαση telnet εντοπίστηκε. Να επιτρέπεται;", + "testBuildErrorText": "Αυτή η δοκιμαστική έκδοση είναι πλέον ανενεργή. Παρακαλώ ελέγξτε για μια νεότερη έκδοση.", + "testBuildText": "Δοκιμαστική Έκδοση", + "testBuildValidateErrorText": "Αδύνατη η επικύρωση της δοκιμαστικής έκδοσης. (χωρίς πρόσβαση στο δίκτυο;)", + "testBuildValidatedText": "Η Δοκιμαστική Έκδοση Επικυρώθηκε. Απολαύστε!", + "thankYouText": "Ευχαριστώ για την υποστήριξή σας! Απολαύστε το παιχνίδι!!", + "threeKillText": "ΤΡΙΠΛΟΣ ΦΟΝΟΣ!!", + "timeBonusText": "Μπόνους Χρόνου", + "timeElapsedText": "Διάρκεια Χρόνου", + "timeExpiredText": "Ο Χρόνος Έληξε", + "timeSuffixDaysText": "${COUNT}μερ.", + "timeSuffixHoursText": "${COUNT}ωρ.", + "timeSuffixMinutesText": "${COUNT}λεπ.", + "timeSuffixSecondsText": "${COUNT}δευτ.", + "tipText": "Υπόδειξη", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Κορυφαίοι Φίλοι", + "tournamentCheckingStateText": "Έλεγχος κατάστασης τουρνουά. Παρακαλώ περιμένετε...", + "tournamentEndedText": "Αυτό το τουρνουά έχει λήξει. Ένα νέο θα ξεκινήσει σύντομα.", + "tournamentEntryText": "Είσοδος Τουρνουά", + "tournamentResultsRecentText": "Αποτελέσματα Πρόσφατων Τουρνουά", + "tournamentStandingsText": "Πίνακας Κατάταξης Τουρνουά", + "tournamentText": "Τουρνουά", + "tournamentTimeExpiredText": "Ο Χρόνος του Τουρνουά Έληξε", + "tournamentsDisabledWorkspaceText": "Τα τουρνουά είναι απενεργοποιημένα όταν χόροι εργασίας είναι ενεργοί.\nΓια να το ενεργοποιήσετε, κλείστε τον χώρο εργασίας σας και επανεκκινήστε την εφαρμογή.", + "tournamentsText": "Τουρνουά", + "translations": { + "characterNames": { + "Agent Johnson": "Πράκτορας Τζόνσον", + "B-9000": "Β-9000", + "Bernard": "Βερνάρδος", + "Bones": "Κοκαλάκιας", + "Butch": "Καουμπόι", + "Easter Bunny": "Πασχαλινός Λαγός", + "Flopsy": "Φλόπσυ", + "Frosty": "Φρόστυ", + "Gretel": "Γκρέτελ", + "Grumbledorf": "Γογγυδώρος", + "Jack Morgan": "Τζακ Μαυρογένης", + "Kronk": "Κρόνκ", + "Lee": "Λι", + "Lucky": "Τυχεράκιας", + "Mel": "Μελένιος", + "Middle-Man": "Σούπερ-Άσχετος", + "Minimus": "Μίνιμος", + "Pascal": "Πασκάλ", + "Pixel": "Πίξελ", + "Sammy Slam": "Σάμμυ Χαλκομανίας", + "Santa Claus": "Άγιος Βασίλης", + "Snake Shadow": "Σκιά Φιδιού", + "Spaz": "Σπάζ", + "Taobao Mascot": "Taobao Μασκότ", + "Todd McBurton": "Τοντ ΜακΜπάρτον", + "Zoe": "Ζωή", + "Zola": "Ζώλα" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Προπόνηση", + "Infinite ${GAME}": "${GAME} Ατελείωτο", + "Infinite Onslaught": "Επίθεση Ατελείωτο", + "Infinite Runaround": "Περίγυρος Ατελείωτο", + "Onslaught Training": "Επίθεση Προπόνηση", + "Pro ${GAME}": "${GAME} Επαγγελματικό", + "Pro Football": "Ποδόσφαιρο Επαγγελματικό", + "Pro Onslaught": "Επίθεση Επαγγελματικό", + "Pro Runaround": "Περίγυρος Επαγγελματικό", + "Rookie ${GAME}": "${GAME} Για Αρχάριους", + "Rookie Football": "Ποδόσφαιρο Για Αρχάριους", + "Rookie Onslaught": "Επίθεση Για Αρχάριους", + "The Last Stand": "Το Τελευταίο Ανάστημα", + "Uber ${GAME}": "${GAME} Ακραίο", + "Uber Football": "Ποδόσφαιρο Ακραίο", + "Uber Onslaught": "Επίθεση Ακραίο", + "Uber Runaround": "Περίγυρος Ακραίο" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Παραμείνετε εκλεκτός για ένα χρονικό διάστημα ώστε να νικήσετε.\nΣκοτώστε τον εκλεκτό για να πάρετε τη θέση του.", + "Bomb as many targets as you can.": "Βομβαρδίστε όσους στόχους μπορείτε.", + "Carry the flag for ${ARG1} seconds.": "Κουβαλήστε τη σημαία για ${ARG1} δευτερόλεπτα.", + "Carry the flag for a set length of time.": "Κουβαλήστε τη σημαία για ένα ορισμένο χρονικό διάστημα.", + "Crush ${ARG1} of your enemies.": "Συντρίψτε ${ARG1} από τους εχθρούς σας.", + "Defeat all enemies.": "Νικήστε όλους τους εχθρούς.", + "Dodge the falling bombs.": "Αποφύγετε τις βόμβες που πέφτουν.", + "Final glorious epic slow motion battle to the death.": "Τελική, δοξασμένη μάχη μέχρι θανάτου σε επικά αργή κίνηση.", + "Gather eggs!": "Μαζέψτε αυγά!", + "Get the flag to the enemy end zone.": "Μεταφέρετε τη σημαία στο εχθρικό τέρμα.", + "How fast can you defeat the ninjas?": "Πόσο γρήγορα μπορείτε να νικήσετε τους νίντζα;", + "Kill a set number of enemies to win.": "Σκοτώστε έναν ορισμένο αριθμό εχθρών για να νικήσετε.", + "Last one standing wins.": "Ο τελευταίος που θα σταθεί όρθιος κερδίζει.", + "Last remaining alive wins.": "Ο τελευταίος ζωντανός κερδίζει.", + "Last team standing wins.": "Η ομάδα που θα σταθεί τελευταία κερδίζει.", + "Prevent enemies from reaching the exit.": "Αποτρέψτε τους εχθρούς από το να φτάσουν στην έξοδο.", + "Reach the enemy flag to score.": "Αγγίξτε την εχθρική σημαία για να σκοράρετε.", + "Return the enemy flag to score.": "Επιστρέψτε την εχθρική σημαία για να σκοράρετε.", + "Run ${ARG1} laps.": "Τρέξτε ${ARG1} γύρους.", + "Run ${ARG1} laps. Your entire team has to finish.": "Τρέξτε ${ARG1} γύρους. Ολόκληρη η ομάδα σας πρέπει να τερματίσει.", + "Run 1 lap.": "Τρέξτε 1 γύρο.", + "Run 1 lap. Your entire team has to finish.": "Τρέξτε 1 γύρο. Ολόκληρη η ομάδα σας πρέπει να τερματίσει.", + "Run real fast!": "Τρέξτε πολύ γρήγορα!", + "Score ${ARG1} goals.": "Σκοράρετε ${ARG1} γκολ.", + "Score ${ARG1} touchdowns.": "Σκοράρετε ${ARG1} πόντους.", + "Score a goal.": "Σκοράρετε 1 γκολ.", + "Score a touchdown.": "Σκοράρετε 1 πόντο.", + "Score some goals.": "Σκοράρετε μερικά γκολ.", + "Secure all ${ARG1} flags.": "Προστατεύστε όλες τις ${ARG1} σημαίες.", + "Secure all flags on the map to win.": "Προστατεύστε όλες τις σημαίες στον χάρτη για να κερδίσετε.", + "Secure the flag for ${ARG1} seconds.": "Προστατεύστε τη σημαία για ${ARG1} δευτερόλεπτα.", + "Secure the flag for a set length of time.": "Προστατεύστε τη σημαία για ένα ορισμένο χρονικό διάστημα.", + "Steal the enemy flag ${ARG1} times.": "Κλέψτε την εχθρική σημαία ${ARG1} φορές.", + "Steal the enemy flag.": "Κλέψτε την εχθρική σημαία.", + "There can be only one.": "Μπορεί να υπάρξει μόνο ένας.", + "Touch the enemy flag ${ARG1} times.": "Αγγίξτε την εχθρική σημαία ${ARG1} φορές.", + "Touch the enemy flag.": "Αγγίξτε την εχθρική σημαία.", + "carry the flag for ${ARG1} seconds": "κουβαλήστε τη σημαία για ${ARG1} δευτερόλεπτα", + "kill ${ARG1} enemies": "σκοτώστε ${ARG1} εχθρούς", + "last one standing wins": "ο τελευταίος που θα σταθεί όρθιος κερδίζει", + "last team standing wins": "η ομάδα που θα σταθεί τελευταία κερδίζει", + "return ${ARG1} flags": "επιστρέψτε ${ARG1} σημαίες", + "return 1 flag": "επιστρέψτε 1 σημαία", + "run ${ARG1} laps": "τρέξτε ${ARG1} γύρους", + "run 1 lap": "τρέξτε 1 γύρο", + "score ${ARG1} goals": "σκοράρετε ${ARG1} γκολ", + "score ${ARG1} touchdowns": "σκοράρετε ${ARG1} πόντους", + "score a goal": "σκοράρετε 1 γκολ", + "score a touchdown": "σκοράρετε 1 πόντο", + "secure all ${ARG1} flags": "προστατεύστε όλες τις ${ARG1} σημαίες", + "secure the flag for ${ARG1} seconds": "προστατεύστε τη σημαία για ${ARG1} δευτερόλεπτα", + "touch ${ARG1} flags": "αγγίξτε ${ARG1} σημαίες", + "touch 1 flag": "αγγίξτε 1 σημαία" + }, + "gameNames": { + "Assault": "Έφοδος", + "Capture the Flag": "Κατάκτηση Σημαίας", + "Chosen One": "Εκλεκτός", + "Conquest": "Κυριαρχία", + "Death Match": "Μάχη Θανάτου", + "Easter Egg Hunt": "Κυνήγι Πασχαλινών Αυγών", + "Elimination": "Εξόντωση", + "Football": "Ποδόσφαιρο", + "Hockey": "Χόκεϋ", + "Keep Away": "Απομάκρυνση", + "King of the Hill": "Βασιλιάς του Λόφου", + "Meteor Shower": "Βροχή Μετεωριτών", + "Ninja Fight": "Μάχη Νίντζα", + "Onslaught": "Επίθεση", + "Race": "Αγώνας Ταχύτητας", + "Runaround": "Περίγυρος", + "Target Practice": "Εξάσκηση Στόχου", + "The Last Stand": "Το Τελευταίο Ανάστημα" + }, + "inputDeviceNames": { + "Keyboard": "Πληκτρολόγιο", + "Keyboard P2": "Πληκτρολόγιο Π2" + }, + "languages": { + "Arabic": "Αραβικά", + "Belarussian": "Λευκορώσικα", + "Chinese": "Απλοποιημένα κινέζικα", + "ChineseTraditional": "Παραδοσιακά κινέζικα", + "Croatian": "Κροάτικα", + "Czech": "Τσέχικα", + "Danish": "Δανικά", + "Dutch": "Ολλανδικά", + "English": "Αγγλικά", + "Esperanto": "Εσπαράντο", + "Filipino": "Φιλιπινέζικα", + "Finnish": "Φινλανδικά", + "French": "Γαλλικά", + "German": "Γερμανικά", + "Gibberish": "Ασυνάρτητα", + "Greek": "Ελληνικά", + "Hindi": "Ινδικά", + "Hungarian": "Ουγγρικά", + "Indonesian": "Ινδονησιακά", + "Italian": "Ιταλικά", + "Japanese": "Ιαπωνέζικα", + "Korean": "Κορεάτικα", + "Persian": "Πέρσικα", + "Polish": "Πολωνικά", + "Portuguese": "Πορτογαλικά", + "Romanian": "Ρουμάνικα", + "Russian": "Ρώσικα", + "Serbian": "Σέρβικα", + "Slovak": "Σλοβακικά", + "Spanish": "Ισπανικά", + "Swedish": "Σουηδικά", + "Tamil": "Ταμίλ", + "Thai": "ταϊλανδέζικο", + "Turkish": "Τούρκικα", + "Ukrainian": "Ουκρανικά", + "Venetian": "Ενετικά", + "Vietnamese": "Βιετναμέζικα" + }, + "leagueNames": { + "Bronze": "Χάλκινο", + "Diamond": "Διαμαντένιο", + "Gold": "Χρυσό", + "Silver": "Ασημένιο" + }, + "mapsNames": { + "Big G": "Μεγάλο G", + "Bridgit": "Ψηφιογέφυρα", + "Courtyard": "Αυλή", + "Crag Castle": "Βραχώδες Κάστρο", + "Doom Shroom": "Μανιτάρι του Χαμού", + "Football Stadium": "Στάδιο Ποδοσφαίρου", + "Happy Thoughts": "Χαρούμενες Σκέψεις", + "Hockey Stadium": "Στάδιο Χόκεϋ", + "Lake Frigid": "Καταψυγμένη Λίμνη", + "Monkey Face": "Φάτσα Μαϊμούς", + "Rampage": "Ράμπα", + "Roundabout": "Κυκλική Διασταύρωση", + "Step Right Up": "Σκαλοπάτια", + "The Pad": "Η Ταμπλέτα", + "Tip Top": "Κορυφή Υπόδειξης", + "Tower D": "Αμυντικός Πύργος", + "Zigzag": "ΖιγκΖαγκ" + }, + "playlistNames": { + "Just Epic": "Μόνο Επικό", + "Just Sports": "Μόνο Αγωνίσματα" + }, + "scoreNames": { + "Flags": "Σημαίες", + "Goals": "Γκολ", + "Score": "Βαθμοί", + "Survived": "Επιβίωση", + "Time": "Χρόνος", + "Time Held": "Χρόνος Κατοχής" + }, + "serverResponses": { + "A code has already been used on this account.": "Ένας κωδικός έχει ήδη χρησιμοποιηθεί σε αυτόν το λογαριασμό.", + "A reward has already been given for that address.": "Μια ανταμοιβή έχει ήδη δοθεί γι' αυτή την διεύθυνση.", + "Account linking successful!": "Δέσμευση Λογαριασμών Επιτυχής!", + "Account unlinking successful!": "Αποδέσμευση Λογαριασμών Επιτυχής!", + "Accounts are already linked.": "Οι λογαριασμοί είναι ήδη δεσμευμένοι.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Το Ad view δεν μπορούσε να επαληθευτεί.\nΠαρακαλώ σιγουρευτείτε ότι τρέχετε μια επίσημη και σύγχρονη έκδοση του παιχνιδιού.", + "An error has occurred; (${ERROR})": "Προέκυψε Σφάλμα. (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Προέκυψε Σφάλμα. Παρακαλώ επικοινωνήστε με την υποστήριξη. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Προέκυψε Σφάλμα. Παρακαλώ επικοινωνήστε με το support@froemling.net.", + "An error has occurred; please try again later.": "Προέκυψε Σφάλμα. Παρακαλώ ξαναπροσπαθήστε αργότερα.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Είστε σίγουροι πως θέλετε να δεσμεύσετε μεταξύ τους αυτούς τους λογαριασμούς;\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nΗ ενέργεια είναι μη αντιστρέψιμη!", + "BombSquad Pro unlocked!": "Το BombSquad Pro ξεκλειδώθηκε!", + "Can't link 2 accounts of this type.": "Αδύνατη η δέσμευση 2 λογαριασμών αυτού του τύπου.", + "Can't link 2 diamond league accounts.": "Αδύνατη η δέσμευση 2 λογαριασμών διαμαντένιας κατηγορίας.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Αδύνατη δέσμευση. Θα ξεπερνούσε το όριο των ${COUNT} δεσμευμένων λογαριασμών.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Εντοπίστηκε ζαβολιά. Οι βαθμολογίες και τα βραβεία θα ανασταλλούν για ${COUNT} μέρες.", + "Could not establish a secure connection.": "Δεν μπόρεσε να ιδρυθεί ασφαλής σύνδεση.", + "Daily maximum reached.": "Ημερήσιο μέγιστο επετεύχθη.", + "Entering tournament...": "Είσοδος στο τουρνουά...", + "Invalid code.": "Μη έγκυρος κωδικός.", + "Invalid payment; purchase canceled.": "Μη έγκυρη πληρωμή. Η αγορά ακυρώθηκε.", + "Invalid promo code.": "Μη έγκυρος κωδικός.", + "Invalid purchase.": "Μη έγκυρη αγορά.", + "Invalid tournament entry; score will be ignored.": "Μη έγκυρη είσοδος στο τουρνουά. Η βαθμολογία θα αγνοηθεί.", + "Item unlocked!": "Το αντικείμενο ξεκλειδώθηκε!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ΑΡΝΗΣΗ ΔΕΣΜΕΥΣΗΣ. Ο ${ACCOUNT} περιέχει\nσημαντικά δεδομένα τα οποία θα ΧΑΝΟΝΤΑΝ.\nΜπορείτε να δεσμεύσετε με την αντίστροφη σειρά αν θα θέλατε\n(έτσι θα χάσετε τα δεδομένα ΑΥΤΟΥ του λογαριασμού)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Δέσμευση του λογαριασμού ${ACCOUNT} σε αυτόν τον λογαριασμό;\nΌλα τα δεδομένα που υπάρχουν στον ${ACCOUNT} θα χαθούν.\nΕνέργεια μη αντιστρέψιμη. Είστε σίγουροι;", + "Max number of playlists reached.": "Μέγιστος αριθμός λιστών επετεύχθη.", + "Max number of profiles reached.": "Μέγιστος αριθμός προφίλ επετεύχθη.", + "Maximum friend code rewards reached.": "Μέγιστος αριθμός ανταμοιβών κωδικού φίλων επετεύχθη.", + "Message is too long.": "Το μήνυμα είναι πολύ μεγάλο.", + "No servers are available. Please try again soon.": "Καθόλου διακομιστές δεν ειναι διαθέσιμοι. Παρακαλώ δοκιμάστε ξανά αργότερα.", + "Profile \"${NAME}\" upgraded successfully.": "Το Προφίλ \"${NAME}\" αναβαθμίστηκε επιτυχώς.", + "Profile could not be upgraded.": "Το προφίλ δεν μπόρεσε να αναβαθμιστεί.", + "Purchase successful!": "Επιτυχής αγορά!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Παραλάβατε ${COUNT} εισιτήρια επειδή συνδεθήκατε.\nΕλάτε πάλι αύριο για να παραλάβετε ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Η λειτουργικότητα των διακομιστών δεν υποστηρίζεται πλέον σε αυτή την έκδοση του παιχνιδιού.\nΠαρακαλώ ενημερώστε σε μια νεότερη έκδοση.", + "Sorry, there are no uses remaining on this code.": "Συγνώμμη, δεν απομένουν άλλες χρήσεις αυτού του κωδικού.", + "Sorry, this code has already been used.": "Συγνώμη, αυτός ο κωδικός έχει ήδη χρησιμοποιηθεί.", + "Sorry, this code has expired.": "Συγνώμη, αυτός ο κωδικός έχει λήξει.", + "Sorry, this code only works for new accounts.": "Συγνώμη, αυτός ο κωδικός λειτουργεί μονάχα για νέους λογαριασμούς.", + "Still searching for nearby servers; please try again soon.": "Ψάχνοντας για κοντινούς διακομιστές, παρακαλώ δοκιμάστε αργότερα.", + "Temporarily unavailable; please try again later.": "Προς το παρόν μη διαθέσιμο. Παρακαλώ ξαναπροσπαθήστε αργότερα.", + "The tournament ended before you finished.": "Το τουρνουά έληξε πριν τερματίσετε.", + "This account cannot be unlinked for ${NUM} days.": "Αυτός ο λογαριασμός δεν μπορεί να αποδεσμευτεί για ${NUM} μέρες.", + "This code cannot be used on the account that created it.": "Αυτός ο κωδικός δεν μπορεί να χρησιμοποιηθεί από τον λογαριασμό που τον δημιούργησε.", + "This is currently unavailable; please try again later.": "Αυτό δεν είναι διαθέσιμο, παρακαλώ δοκιμάστε ξανά αργότερα.", + "This requires version ${VERSION} or newer.": "Αυτό απαιτεί έκδοση ${VERSION} ή νεότερη.", + "Tournaments disabled due to rooted device.": "Τα τουρνουά απενεργοποιήθηκαν λόγω rooted συσκευής.", + "Tournaments require ${VERSION} or newer": "Τα τουρνουά απαιτούν έκδοση ${VERSION} ή νεότερη", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Αποδέσμευση του ${ACCOUNT} από αυτόν τον λογαριασμό;\nΌλα τα δεδομένα στον ${ACCOUNT} θα υποστούν επαναφορά.\n(εκτός από τα επιτεύγματα σε ορισμένες περιπτώσεις)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Παράπονα παραβίασης (hacking) σημειώθηκαν εναντίον αυτού του λογαριασμού.\nΛογαριασμοί που παραβιάζουν το παιχνίδι θα αποκλείονται. Παρακαλώ παίξτε δίκαια.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Θα θέλατε να δεσμεύσετε τον λογαριασμό της συσκεύης σας με αυτόν εδώ;\n\nΟ λογαριασμός της συσκευής σας είναι ο ${ACCOUNT1}\nΑυτός ο λογαριασμός είναι ο ${ACCOUNT2}\n\nΑυτό θα σας επιτρέψει να κρατήσετε την υπάρχουσα πρόοδό σας.\nΠροσοχή: Ενέργεια μη αντιστρέψιμη!", + "You already own this!": "Αυτό σας ανήκει ήδη!", + "You can join in ${COUNT} seconds.": "Μπορείτε να ενταχθείτε σε ${COUNT} δευτ.", + "You don't have enough tickets for this!": "Δεν έχετε αρκετά εισιτήρια για να αγοράσετε αυτό το αντικείμενο!", + "You don't own that.": "Αυτό το αντικείμενο δεν σας ανήκει.", + "You got ${COUNT} tickets!": "Παραλάβατε ${COUNT} εισιτήρια!", + "You got a ${ITEM}!": "Παραλάβατε ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Έχετε προαχθεί σε μια νέα κατηγορία. Συγχαρητήρια!", + "You must update to a newer version of the app to do this.": "Πρέπει να ενημερώσετε σε μια νεότερη έκδοση της εφαρμογής γι' αυτή την ενέργεια.", + "You must update to the newest version of the game to do this.": "Πρέπει να ενημερώσετε στη νεότερη έκδοση του παιχνιδιού γι' αυτή την ενέργεια.", + "You must wait a few seconds before entering a new code.": "Πρέπει να περιμένετε μερικά δευτερόλεπτα πριν εισάγετε έναν νέο κωδικό.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Καταταχθήκατε #${RANK} στο τελευταίο τουρνουά. Ευχαριστώ για τη συμμετοχή!", + "Your account was rejected. Are you signed in?": "Ο λογαριασμός σας απορρίφθηκε. Έχετε συνδεθεί;", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Το αντίγραφο του παιχνιδιού σας έχει τροποποιηθεί.\nΠαρακαλώ κάντε επαναφορά όλων των αλλαγών και ξαναπροσπαθήστε.", + "Your friend code was used by ${ACCOUNT}": "Ο κωδικός φίλων σας χρησιμοποιήθηκε από τον λογαριασμό ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Λεπτό", + "1 Second": "1 Δευτερόλεπτο", + "10 Minutes": "10 Λεπτά", + "2 Minutes": "2 Λεπτά", + "2 Seconds": "2 Δευτερόλεπτα", + "20 Minutes": "20 Λεπτά", + "4 Seconds": "4 Δευτερόλεπτα", + "5 Minutes": "5 Λεπτά", + "8 Seconds": "8 Δευτερόλεπτα", + "Allow Negative Scores": "Να Επιτρέπονται Αρνητικές Βαθμολογίες", + "Balance Total Lives": "Να Εξισορροπούνται οι Συνολικές Ζωές", + "Bomb Spawning": "Δημιουργία Βομβών", + "Chosen One Gets Gloves": "Ο Εκλεκτός Παίρνει Γάντια", + "Chosen One Gets Shield": "Ο Εκλεκτός Παίρνει Ασπίδα", + "Chosen One Time": "Χρόνος Εκλεκτού", + "Enable Impact Bombs": "Ενεργοποίηση Βομβών Ερεθίσματος", + "Enable Triple Bombs": "Ενεργοποίηση Τριπλών Βομβών", + "Entire Team Must Finish": "Ολόκληρη Η Ομάδα Πρέπει να Τερματίσει", + "Epic Mode": "Επική Λειτουργία", + "Flag Idle Return Time": "Χρόνος Επιστροφής Αφημένης Σημαίας", + "Flag Touch Return Time": "Χρόνος Εξ'επαφούς Επιστροφής Σημαίας", + "Hold Time": "Χρόνος Κατοχής", + "Kills to Win Per Player": "Φόνοι Ανά Παίκτη για τη Νίκη", + "Laps": "Γύροι", + "Lives Per Player": "Ζωές Ανά Παίκτη", + "Long": "Διαρκές", + "Longer": "Εκτεταμένο", + "Mine Spawning": "Δημιουργία Ναρκών", + "No Mines": "Χωρίς Νάρκες", + "None": "Καθόλου", + "Normal": "Κανονικό", + "Pro Mode": "Επαγγελματική Λειτουργία", + "Respawn Times": "Χρόνος Επαναδημιουργίας", + "Score to Win": "Βαθμολογία για τη Νίκη", + "Short": "Βραχύ", + "Shorter": "Σύντομο", + "Solo Mode": "Λειτουργία Σόλο", + "Target Count": "Αριθμός Στόχων", + "Time Limit": "Χρονικό Όριο" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "Η ομάδα ${TEAM} αποκλείστηκε επειδή ο παίκτης ${PLAYER} εγκατέλλειψε", + "Killing ${NAME} for skipping part of the track!": "Θάνατος στον παίκτη ${NAME} επειδή παρέλειψε ένα μέρος της πίστας!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Προειδοποίηση στον παίκτη ${NAME}: το turbo / κατάχρηση κουμπιού σας τιμωρεί." + }, + "teamNames": { + "Bad Guys": "Κακοί Τύποι", + "Blue": "Μπλε", + "Good Guys": "Καλοί Τύποι", + "Red": "Κόκκινο" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Μια τέλεια συγχρονισμένη γροθιά τρεξίματος-άλματος-στροφής μπορεί να σκοτώσει\nμε ένα χτύπημα και να σας διασφαλίσει σεβασμό ευ' φόρου ζωής από τους φίλους σας.", + "Always remember to floss.": "Πάντα να θυμάστε το οδοντικό νήμα.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Δημιουργήστε προφίλ παικτών για εσάς και τους φίλους σας με τα\nονόματα και τις εμφανίσεις που προτιμάτε αντί να χρησιμοποιείτε τυχαία.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Τα κουτιά κατάρας σας μετατρέπουν σε ορολογιακή βόμβα.\nΗ μόνη θεραπεία είναι η άμεση χρήση ιατρικού.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Παρά την εμφάνισή τους, οι ιδιότητες όλων των χαρακτήρων είναι ίδιες,\nοπότε επιλέξτε αυτόν που σας αντιπροσοπεύει καλύτερα.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Μην παίρνετε πολύ θάρρος με το πεδίο ισχύος. Μπορείτε ακόμα να πέσετε από γκρεμό.", + "Don't run all the time. Really. You will fall off cliffs.": "Μην τρέχετε όλη την ώρα. Σοβαρά. Θα πέσετε από κανά γκρεμό.", + "Don't spin for too long; you'll become dizzy and fall.": "Μην περιστρέφεστε για πολλή ώρα. Θα ζαλιστείτε και θα πέσετε.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Κρατήστε πατημένο οποιοδήποτε κουμπί για να τρέξετε. (Το κουμπιά διακόπτες λειτουργούν πολύ καλά αν τα διαθέτετε)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Πατήστε κρατημένο οποιδήποτε κουμπί για να τρέξετε. Θα φτάνετε στον προορισμό σας\nταχύτερα αλλά θα είναι δύσκολο να στρίψετε, γι' αυτό λοιπόν προσοχή στους γκρεμούς.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Οι βόμβες πάγου δεν είναι και τόσο ισχυρές, αλλά παγώνουν\nοποιονδήποτε πετυχαίνουν, αφήνοντάς τον ευάλωτο στο θραύσιμο.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Αν κάποιος σας σηκώσει, χτυπήστε τον και θα σας\nαφήσει.Αυτό λειτουργεί και στην πραγματικότητα.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Αν ξεμείνατε από χειριστήρια, εγκαταστήστε την εφαρμογή '${REMOTE_APP_NAME}'\nστις φορητές σας συσκευές για να τις χρησιμοποιήσετε ως χειριστήρια.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Αν μια κολλώδη βόμβα κολλήσει πάνω σας, αρχίστε να πηδάτε και να τρέχετε σε κύκλους.\nΕνδέχεται να την ξεκολλήσετε, αλλιώς οι τελευταίες σας στιγμές θα είναι ψυχαγωγικές.", + "If you kill an enemy in one hit you get double points for it.": "Άμα σκοτώσετε έναν εχθρό με ένα χτύπημα κερδίζετε διπλάσιους πόντους.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Άμα μαζέψετε κατάρα, η μόνη ελπίδα σας για επιβίωση είναι\nνα βρείτε ιατρικό κουτί στα ακόλουθα δευτερόλεπτα.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Αν στέκεστε σε ένα σημείο, θα γίνετε ψητός. Τρέξτε και αποφύγετε για να επιβιώσετε..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Αν έχετε πολλούς παίκτες να εισέρχονται και να εξέρχονται, ενεργοποιήστε την 'αυτόματη-\nαποβολή-άπραγων-παικτών' στις ρυθμίσεις σε περίπτωση που κάποιος ξεχάσει να αποχωρήσει", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Αν η συσκευή σας ζεσταίνεται υπερβολικά ή θα θέλατε να διατηρήσετε την ενέργεια\nτης μπαταρίας, μειώστε τα \"Οπτικά\" ή την \"Ανάλυση\" στις Ρυθμίσεις->Γραφικά", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Αν το framerate σας είναι ασταθές, δοκιμάστε να μειώσετε την\nανάλυση ή τα οπτικά στις ρυθμίσεις γραφικών του παιχνιδιού.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Στην Κατάκτηση-Σημαίας, η δική σας σημαία πρέπει να είναι στη βάση της για να σκοράρετε. Αν η άλλη\nομάδα πάει να σκοράρει, κλέβοντας την σημαία της είναι ένας αποτελεσματικός τρόπος για να τη σταματήσετε.", + "In hockey, you'll maintain more speed if you turn gradually.": "Στο χόκεϋ, θα διατηρήσετε περισσότερη ταχύτητα αν στρίβετε σταδιακά.", + "It's easier to win with a friend or two helping.": "Είναι ευκολότερο να νικήσετε με τη βοήθεια κάνα-δυο φίλων.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Πηδήξτε για να πετάξετε βόμβες ψηλότερα.", + "Land-mines are a good way to stop speedy enemies.": "Οι νάρκες εδάφους είναι ένας αποτελεσματικός τρόπος για να σταματήσετε γρήγορους εχθρούς.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Μπορείτε να σηκώσετε και να πετάξετε διάφορα, συμπεριλαμβανομένου και άλλους παίκτες. Ρίχνοντας τους εχθρούς σας\nαπό το χείλος του γκρεμού μπορεί να είναι μια αποτελεσματική και συγχρόνως συναισθηματικά φορτισμένη στρατηγική.", + "No, you can't get up on the ledge. You have to throw bombs.": "Όχι, δεν μπορείτε να ανεβείτε από το περβάζι. Πρέπει να ρίξετε βόμβες.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Οι παίκτες μπορούν να ενταχθούν και να αποχωρήσουν στην μέση των περισσότερων παιχνιδιών,\nκαι μπορείτε ακόμα να συνδέσετε και να αποσυνδέσετε χειριστήρια καθ' όλη τη διάρκειά τους.", + "Practice using your momentum to throw bombs more accurately.": "Εξασκηθείτε χρησιμοποιώντας την ορμή σας για να ρίξετε βόμβες με περισσότερη ακρίβεια.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Οι γροθιές προκαλούν περισσότερη ζημιά με βάση την ταχύτητα με τη\nοποία κινούνται, γι' αυτό τρέξτε, πηδήξτε και στρίψτε σαν τρελός.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Κινηθείτε μπρος και πίσω πριν ρίξετε μια\nβόμβα για να την εκσφενδονήσετε μακρύτερα.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Εξοντώστε πολλαπλούς εχθρούς\nρίχνοντας βόμβα δίπλα σε κουτί TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Το κεφάλι είναι η πιο ευαίσθητη περιοχή, οπότε, μια\nκολλώδη βόμβα πάνω του συνήθως σημαίνει τέλος-παιχνιδιού.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Αυτό το επίπεδο δεν τελειώνει ποτέ, αλλά μία υψηλή βαθμολογία\nεδώ θα σας αποκαταστήσει την υστεροφημία σας παγκοσμίως.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Η δύναμη ριπής είναι βασισμένη στην κατεύθυνση που έχετε κρατημένη.\nΓια να ρίξετε κάτι απαλά μπροστά σας, μην στοχεύετε κατεύθυνση.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Βαρεθήκατε την ηχητική υπόκρουση; Αντικαταστήστε την με\nμια δικιά σας! Βλέπε Ρυθμίσεις->Ήχος->Ηχητική Υπόκρουση", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Δοκιμάστε να \"Μαγειρέψετε\" τις βόμβες για κάνα-δυο δευτερόλεπτα πριν τις πετάξετε.", + "Try tricking enemies into killing eachother or running off cliffs.": "Δοκιμάστε να ξεγελάσετε τους εχθρούς κάνοντάς τους να αλληλοσκοτωθούν ή να πέσουν από τον γκρεμό.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Χρησιμοποιήστε το κουμπί αρπαγής για να σηκώσετε τη σημαία < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Κινηθείτε μπρος και πίσω για να κερδίσετε απόσταση στις ρίψεις σας..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Μπορείτε να \"στοχεύσετε\" τις γροθιές σας στρίβοντας αριστερά ή δεξιά. Αυτό είναι\nχρήσιμο για να πετάτε τους κακούς από τις άκρες ή να σκοράρετε στο χόκεϋ.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Μπορείτε να μαντέψετε πότε μια βόμβα θα εκραγεί με βάση το χρώμα\nτων σπινθήρων στο φυτίλι: κίτρινο..πορτοκαλί..κόκκινο..ΜΠΟΥΜ.", + "You can throw bombs higher if you jump just before throwing.": "Μπορείτε να ρίξετε τις βόμβες ψηλότερα αν πηδήξετε ακριβώς πριν τη ρίψη.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Δέχεστε ζημιές όταν κουτουλάτε το κεφάλι σας οπουδήποτε, οπότε\nπροσπαθήστε να μην κουτουλάτε το κεφάλι σας οπουδήποτε.", + "Your punches do much more damage if you are running or spinning.": "Οι γροθιές σας προκαλούν περισσότερη ζημιά όταν τρέχετε ή περιστρέφεστε." + } + }, + "trophiesRequiredText": "Αυτό απαιτεί τουλάχιστον ${NUMBER} βραβεία.", + "trophiesText": "Βραβεία", + "trophiesThisSeasonText": "Βραβεία Αυτής Της Σεζόν", + "tutorial": { + "cpuBenchmarkText": "Εκτέλεση του εκπαιδευτικού βίντεο σε γελοίες ταχύτητες (έλεγχος κυρίως της ταχύτητας του CPU)", + "phrase01Text": "Γειά σας!", + "phrase02Text": "Καλωσήρθατε στο ${APP_NAME}!", + "phrase03Text": "Ορίστε μερικές συμβουλές για τον χειρισμό του χαρακτήρα σας:", + "phrase04Text": "Πολλά πράγματα στο ${APP_NAME} είναι βασισμένα στους ΝΟΜΟΥΣ της ΦΥΣΙΚΗΣ.", + "phrase05Text": "Για παράδειγμα, όταν βαράτε,..", + "phrase06Text": "..η ζημιά είναι βασισμένη στην ορμή των γροθιών σας.", + "phrase07Text": "Είδατε; Είμασταν ακίνητοι, οπότε αυτό ίσα που πλήγωσε τον ${NAME}.", + "phrase08Text": "Τώρα ας πηδήξουμε και ας στρίψουμε για να δώσουμε περισσότερη ταχύτητα.", + "phrase09Text": "Αχ, καλύτερα έτσι.", + "phrase10Text": "Το τρέξιμο επίσης βοηθάει.", + "phrase11Text": "Κρατήστε πατημένο ΟΠΟΙΟΔΗΠΟΤΕ κουμπί για να τρέξετε.", + "phrase12Text": "Για καλύτερες γροθιές, δοκιμάστε να τρέξετε ΚΑΙ να πηδήξετε.", + "phrase13Text": "Ουπς. Συγνώμη γι' αυτό ${NAME}.", + "phrase14Text": "Μπορείτε να σηκώσετε διάφορα, όπως σημαίες.. ή τον ${NAME}.", + "phrase15Text": "Τέλος, έχουμε τις βόμβες.", + "phrase16Text": "Η σωστή ρίψη βόμβας χρειάζεται εξάσκηση.", + "phrase17Text": "Άουτς! Όχι και πολύ καλή ρίψη.", + "phrase18Text": "Η κίνηση σας επιτρέπει να ρίχνετε μακρύτερα.", + "phrase19Text": "Το άλμα σας επιτρέπει να ρίχνετε ψηλότερα.", + "phrase20Text": "Τινάξτε τις βόμβες σας με ώθηση για ακόμα καλύτερες βολές.", + "phrase21Text": "Ο σωστός συγχρονισμός με την βόμβα μπορεί να είναι δύσκολος.", + "phrase22Text": "Συμφορά.", + "phrase23Text": "Δοκιμάστε να \"Μαγειρέψετε\" το φυτίλι για κάνα-δυο δευτερόλεπτα.", + "phrase24Text": "Ζήτω! Καλόμαγειρεμένο.", + "phrase25Text": "Λοιπόν, με αυτό ολοκληρώνουμε.", + "phrase26Text": "Όρμα τους, τίγρη!", + "phrase27Text": "Θυμηθείτε την εκπαίδευσή σας, και ΘΑ επιστρέψετε ζωντανοί!", + "phrase28Text": "...πιθανόν δηλαδή...", + "phrase29Text": "Καλή τύχη!", + "randomName1Text": "Φρεντ", + "randomName2Text": "Χάρρυ", + "randomName3Text": "Μπίλι", + "randomName4Text": "Τσακ", + "randomName5Text": "Φιλ", + "skipConfirmText": "Παράλειψη του εκπαιδευτικού βίντεο; Πατήστε ή πιέστε για επιβεβαίωση.", + "skipVoteCountText": "${COUNT}/${TOTAL} ψήφοι παράλειψης", + "skippingText": "παράλειψη εκπαιδευτικού βίντεο...", + "toSkipPressAnythingText": "(πατήστε ή πιέστε οτιδήποτε για να παραλείψετε το εκπαιδευτικό βίντεο)" + }, + "twoKillText": "ΔΙΠΛΟΣ ΦΟΝΟΣ!", + "unavailableText": "μη διαθέσιμο", + "unconfiguredControllerDetectedText": "Εντοπίστηκε μη διαμορφωμένο χειριστήριο:", + "unlockThisInTheStoreText": "Αυτό πρέπει να ξεκλειδωθεί στο κατάστημα.", + "unlockThisProfilesText": "Για να δημιουργήσετε περισσότερα από ${NUM} προφίλ, χρειάζεστε:", + "unlockThisText": "Για να το ξεκλειδώσετε, χρειάζεστε:", + "unsupportedHardwareText": "Συγνώμη, αυτό το υλισμικό δεν υποστηρίζεται από αυτή την έκδοση του παιχνιδιού.", + "upFirstText": "Για αρχή:", + "upNextText": "Στη συνέχεια, παιχνίδι ${COUNT}:", + "updatingAccountText": "Ενημέρωση του λογαριασμού σας...", + "upgradeText": "Αναβάθμιση", + "upgradeToPlayText": "Ξεκλειδώστε το \"${PRO}\" στο κατάστημα του παιχνιδιού για να μπορείτε να το παίξετε.", + "useDefaultText": "Χρήση Προκαθορισμένων", + "usesExternalControllerText": "Αυτό το παιχνίδι χρησιμοποιεί ένα εξωτερικό χειριστήριο για είσοδο.", + "usingItunesText": "Χρήση εφαρμογής μουσικής για ηχητική υπόκρουση...", + "v2AccountLinkingInfoText": "Για να δεσμεύσετε λογαριασμούς V2, χρησιμοιποιήστε το κουμπί 'Διαχείριση Λογαριασμού'.", + "validatingTestBuildText": "Επικύρωση Δοκιμαστικής Έκδοσης...", + "victoryText": "Νίκη!", + "voteDelayText": "Δεν μπορείτε να ξαναξεκινήσετε ψηφοφορία για ${NUMBER} δευτ.", + "voteInProgressText": "Μια ψηφοφορία βρίσκεται ήδη σε εξέλιξη.", + "votedAlreadyText": "Ψηφίσατε ήδη", + "votesNeededText": "Χρειάζονται ${NUMBER} ψήφοι", + "vsText": "εναντίον", + "waitingForHostText": "(αναμονή συνέχισης από τον χρήστη ${HOST})", + "waitingForPlayersText": "αναμονή για ένταξη παικτών...", + "waitingInLineText": "Αναμονή στην ουρά (η συγκέντρωση είναι πλήρης)...", + "watchAVideoText": "Παρακολουθήστε ένα Βίντεο", + "watchAnAdText": "Παρακολουθήστε μια Διαφήμιση", + "watchWindow": { + "deleteConfirmText": "Διαγραφή \"${REPLAY}\";", + "deleteReplayButtonText": "Διαγραφή\nΕπανάληψης", + "myReplaysText": "Οι Επαναλήψεις Μου", + "noReplaySelectedErrorText": "Δεν Επιλέχθηκε Επανάληψη", + "playbackSpeedText": "Ταχύτητα Αναπαραγωγής: ${SPEED}", + "renameReplayButtonText": "Μετονομασία\nΕπανάληψης", + "renameReplayText": "Μετονομασία \"${REPLAY}\" σε:", + "renameText": "Μετονομασία", + "replayDeleteErrorText": "Σφάλμα κατά τη διαγραφή της επανάληψης.", + "replayNameText": "Όνομα Επανάληψης", + "replayRenameErrorAlreadyExistsText": "Μια επανάληψη με το ίδιο όνομα υπάρχει ήδη.", + "replayRenameErrorInvalidName": "Αδύνατη η μετονομασία. Μη έγκυρο όνομα.", + "replayRenameErrorText": "Σφάλμα κατά την μετονομασία της επανάληψης.", + "sharedReplaysText": "Κοινόχρηστες Επαναλήψεις", + "titleText": "Προβολή", + "watchReplayButtonText": "Προβολή\nΕπανάληψης" + }, + "waveText": "Κύμα", + "wellSureText": "Βεβαίως!", + "whatIsThisText": "Τι είναι αυτό;", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Ακρόαση Για Wiimotes...", + "pressText": "Πιέστε τα κουμπιά 1 και 2 στο Wiimote ταυτοχρόνως.", + "pressText2": "Σε νεότερα Wiimotes με ενσωματωμένο Motion Plus, πατήστε αντίθετα το κόκκινο κουμπί 'sync' στο πίσω μέρος." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "listenText": "Ακρόαση", + "macInstructionsText": "Σιγουρευτείτε ότι το Wii είναι κλειστό και το Bluetooth ενεργοποιημένο\nστον Mac σας, τότε πατήστε 'Ακρόαση'. Η υποστήριξη Wiimote μπορεί\nνα είναι λίγο προβληματική, άρα μπορεί να χρειαστεί\nνα προσπαθήσετε μερικές φορές πριν να γίνει σύνδεση.\n\nΤο Bluetooth θα μπορεί να αντέξει έως 7 συνδεδεμένες συσκευές,\nαν και η απόσταση μπορεί να διαφέρει.\n\nΤο BombSquad υποστηρίζει τα αυθεντικά Wiimotes, Nunchuks\nκαι το κλασσικό χειριστήριο.\nΤο νεότερο Wii Remote Plus τώρα επίσης δουλεύει\nαλλά όχι με επιπρόσθετα εξαρτήματα.", + "thanksText": "Ευχαριστούμε την ομάδα DarwiinRemote\nπου έκανε αυτό εφικτό.", + "titleText": "Εγκατάσταση Wiimote" + }, + "winsPlayerText": "Ο Παίκτης ${NAME} Νίκησε!", + "winsTeamText": "Η Ομάδα ${NAME} Νίκησε!", + "winsText": "${NAME} Νίκησε!", + "workspaceSyncErrorText": "Σφάλμα συνγχρονήζοντας ${WORKSPACE}. Δείτε την καταγραφή για λεπτομέρειες.", + "workspaceSyncReuseText": "Ο χώρος εργασίας ${WORKSPACE} δεν μπορεί να συγχρονιστεί. Η προηγούμενη συγχρονισμένη έκδοση θα χρησιμοποιηθεί.", + "worldScoresUnavailableText": "Παγκόσμιες βαθμολογίες μη διαθέσιμες.", + "worldsBestScoresText": "Καλύτερες Βαθμολογίες Παγκοσμίως", + "worldsBestTimesText": "Καλύτεροι Χρόνοι Παγκοσμίως", + "xbox360ControllersWindow": { + "getDriverText": "Αποκτήστε Οδηγό", + "macInstructions2Text": "Για να χρησιμοποιήσετε χειριστήρια ασύρματα, θα χρειαστείτε επίσης\nέναν δέκτη που έρχεται μαζί με το 'Xbox 360 Ασύρματο Χειριστήριο για\nWindows'. Ένας δέκτης σας επιτρέπει να συνδέσετε έως και 4 χειριστήρια.\n\nΣημαντικό: οι δέκτες 3ου-μέλους δεν θα λειτουργήσουν με αυτόν τον οδηγό.\nΣιγουρευτείτε πως ο δέκτης αναγράφει 'Microsoft' και όχι 'XBOX 360'.\nΗ Microsoft δεν τους πωλεί πλέον ξεχωριστά, οπότε θα χρειαστεί να λάβετε\nέναν ως πακέτο μαζί με το χειριστήριο ή αλλιώς να κάνετε αναζήτηση στο ebay.\n\nΑν αυτό το βρήκατε χρήσιμο, παρακαλώ σκεφτείτε να κάνετε\nδωρεά στον προγραμματιστή οδηγών σε αυτή τη σελίδα.", + "macInstructionsText": "Για να χρησιμοποιήσετε χειριστήρια Xbox 360, θα χρειαστεί\nνα εγκαταστήσετε τον οδηγό Mac διαθέσιμο στον παρακάτω σύνδεσμο.\nΛειτουργεί και με ενσύρματα και ασύρματα χειριστήρια.", + "macInstructionsTextScale": 0.7, + "ouyaInstructionsText": "Για να χρησιμοποιήσετε ενσύρματα Xbox 360 χειριστήρια με το BombSquad,\nαπλούστατα συνδέστε τα στη θύρα USB της συσκευής σας. Μπορείτε να\nχρησιμοποιήσετε έναν κόμβο USB για να συνδέσετε πολλαπλά χειριστήρια.\n\nΓια να χρησιμοποιήσετε ασύρματα χειριστήρια θα χρειαστείτε έναν ασύρματο\nδέκτη, διαθέσιμο ως μέρος του πακέτου \"Xbox 360 ασύρματο Χειριστήριο για\nWindows\" ή πωλούμενο ξεχωριστά. Κάθε δέκτης συνδέεται μέσα σε μια θύρα USB\nκαι σας επιτρέπει να συνδέσετε έως και 4 ασύρματα χειριστήρια.", + "titleText": "Χρήση Xbox 360 Χειριστηρίων με το ${APP_NAME}:" + }, + "yesAllowText": "Ναι, Να Επιτρέπεται!", + "yourBestScoresText": "Οι Καλύτερές σας Βαθμολογίες", + "yourBestTimesText": "Οι Καλύτεροί σας Χρόνοι" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/hindi.json b/dist/ba_data/data/languages/hindi.json new file mode 100644 index 0000000..1fdbcf8 --- /dev/null +++ b/dist/ba_data/data/languages/hindi.json @@ -0,0 +1,1888 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "खाता नाम में इमोजी अथवा अन्य विशेष अक्षर नहीं हो सकते।", + "accountProfileText": "(खाते प्रोफाइल )", + "accountsText": "खातें", + "achievementProgressText": "उपलब्धियां: ${TOTAL} में से ${COUNT}", + "campaignProgressText": "अभियान प्रगति [कठिन]: ${PROGRESS}", + "changeOncePerSeason": "आप केवल प्रति सीजन इसे एक बार बदल सकते हैं।", + "changeOncePerSeasonError": "आपको इसे फिर से बदलने के लिए अगले सीज़न तक इंतजार करना होगा (${NUM} दिन)", + "customName": "अनुकूल नाम", + "googlePlayGamesAccountSwitchText": "अगर आप किसी भिन्न Google खाते का उपयोग करना चाहते हैं,\n स्विच करने के लिए Google Play गेम्स ऐप का उपयोग करें।", + "linkAccountsEnterCodeText": "कोड डालीए", + "linkAccountsGenerateCodeText": "काेड उत्पन्न करे", + "linkAccountsInfoText": "(प्रगति को अलग अलग यंत्रो पर बाटिए)", + "linkAccountsInstructionsNewText": "दो खातों को लिंक करने के लिए, पहले खाते पर एक कोड उत्पन्न करें \nऔर उस कोड को दूसरे पर दर्ज करें. \nदूसरा खाता डेटा तब दोनों के बीच साझा किया जाएगा. \n(पहले खाते से डेटा खो जाएगा) \n\nआप ${COUNT} खाते तक लिंक कर सकते हैं \n\nमहत्वपूर्ण: केवल आपके खाते लिंक करें; \nयदि आप दोस्तों के खातों के साथ लिंक करते हैं \nतो आप एक ही समय में ऑनलाइन खेलने में सक्षम नहीं हो पाएंगे.", + "linkAccountsInstructionsText": "दो खातों को जोड़ने के लिए एक में कोड उत्पन्न\nकरें एयर दुसरे खाते में दर्ज करें | प्रगति और\nवस्तुसूची जोड़ दी जायेगी | आप अधिकतम\n${COUNT} खातों को जोड़ सकते हैं |\n\nध्यान रखिये, इसे वापस नहीं लिया जा सकता !", + "linkAccountsText": "खाते को जोडिए", + "linkedAccountsText": "जुड़े हुए खाते:", + "manageAccountText": "खाता प्रबंधन", + "nameChangeConfirm": "अपने खाता का नाम इस नाम ${NAME} से बदले?", + "resetProgressConfirmNoAchievementsText": "यह आपकी को-ऑप प्रगति और \nस्थानीय उच्च स्कोर रीसेट कर देगा (आपके टिकट रीसेट नहीं होंगे) | \nइसे पूर्ववत नहीं किया जा सकता | इस बात की पुष्टि करें कि आप यह करना चाहते हैं |", + "resetProgressConfirmText": "यह आपकी को-ऑप प्रगति और\n स्थानीय उच्च स्कोर रीसेट कर देगा\n (आपके टिकट रीसेट नहीं होंगे) | \nइसे पूर्ववत नहीं किया जा सकता | इस बात की पुष्टि करें कि आप यह करना चाहते हैं |", + "resetProgressText": "प्रगति रीसेट करें", + "setAccountName": "खाता नाम रखे", + "setAccountNameDesc": "अपने खाते के लिए प्रदर्शित करने के लिए नाम चुनें। \nआप अपने लिंक किए गए किसी एक से नाम का उपयोग कर सकते हैं \nखातों या अनन्य कस्टम नाम बनाएं", + "signInInfoText": "सभी यंत्रों पर अपनी प्रगति को संग्रहीत करने के लिए, \nटिकट कमाने, टूर्नामेंट में प्रतिस्पर्धा करने के लिए साइन इन करें |", + "signInText": "साइन इन", + "signInWithDeviceInfoText": "(एक स्वचालित खता जिसका सिर्फ इस यंत्र से प्रयोग किया जा सकता है)", + "signInWithDeviceText": "इस डिवाइस के साथ साइन इन करें", + "signInWithGameCircleText": "Game circle के साथ प्रवेश करे", + "signInWithGooglePlayText": "गूगल प्ले से साईन ईन करे", + "signInWithTestAccountInfoText": "(पुराना खाते का प्ररूप; आगे के लिए यंत्र खाते का प्रयोग करें)", + "signInWithTestAccountText": "परीक्षण के खाते से साइन इन करें", + "signInWithV2InfoText": "(एक खाता जो सभी प्लेटफार्मों पर काम करता है)", + "signInWithV2Text": "BombSquad खाते से साइन इन करें", + "signOutText": "साइन आउट", + "signingInText": "साइन इन हो रहा है...", + "signingOutText": "साइन आउट हो रहा है...", + "testAccountWarningCardboardText": "चेतावनी: आप एक \"परीक्षा\" खाते से साइन इन कर रहे हैं |\nयह आपके खाते से बदल दिया जायेगा एक बार कार्डबोर्ड एप्प समर्थित हो जाये |\n\nअभी के लिए आपको टिकेट गेम के अन्दर से ही कमाने होंगे |\n(आपको बम स्क्वाड प्रो का उन्नयन मुफ्त में दिया जाएगा |)", + "testAccountWarningOculusText": "चेतावनी: आप एक \"परीक्षा\" खाते से साइन इन कर रहे हैं |\nयह आपके औक्युलस खाते से बदल दिया जायेगा इस साल के अंत तक जब टिकेट खरीदने व आदि विशेषताएं इस गेम में जोड़ दी जायेंगी |\n\nअभी के लिए आपको टिकेट गेम के अन्दर से ही कमाने होंगे |\n(आपको बम स्क्वाड प्रो का उन्नयन मुफ्त में दिया जाएगा |)", + "testAccountWarningText": "चेतावनी: आप एक \"परीक्षा\" खाते से साइन इन कर रहे हैं |\nयह खाता इस विशिष्ट यंत्र से जुड़ा हुआ है और\nसमय-समय पर रीसेट हो सकता है. (तथा इसी लिए ज्यादा समय सामन खोलने/ खरीदने व इकट्ठा करने में न लगायें ) |\n\nएक खुदरा संस्करण का प्रयोग करें एक 'सम्पूर्ण' खाते ( गेम सेण्टर, गूगल प्लस, आदि) के लिए | इससे आप अपनी प्रगति को बचा कर रख सकते हैं क्लाउड में तथा दुसरे यंत्रों पे भी अपनी प्रगति वहीँ से जारी रख सकते हैं | ", + "ticketsText": "टिकट: ${COUNT}", + "titleText": "खाता", + "unlinkAccountsInstructionsText": "अनलिंक करने के लिए एक खाता चुनें", + "unlinkAccountsText": "खाते अनलिंक करें", + "v2LinkInstructionsText": "खाता बनाने या साइन इन करने के लिए इस लिंक का उपयोग करें।", + "viaAccount": "(खाता ${NAME} के माध्यम से)", + "youAreSignedInAsText": "आप इस खाते से साइनड इन हो: " + }, + "achievementChallengesText": "उपलब्धि की चुनौतियां", + "achievementText": "उपलब्धि", + "achievements": { + "Boom Goes the Dynamite": { + "description": "टी•न•टी से ३ बुरे लोगों को मार डालो |", + "descriptionComplete": "टी•न•टी से ३ बुरे लोगों को मार डाला |", + "descriptionFull": "टी•न•टी से ३ बुरे लोगों को मार डालो स्तर ${LEVEL} पर |", + "descriptionFullComplete": "टी•न•टी से ३ बुरे लोगों को मार डाला स्तर ${LEVEL}  पर |", + "name": "बूम !! डायनामाइट फटा !" + }, + "Boxer": { + "description": "बिना बम इस्तेमाल करे जीतें |", + "descriptionComplete": "बिना बम इसतमाल करे जीते |", + "descriptionFull": "बिना बम इस्तेमाल करे स्तर ${LEVEL} पार करें |", + "descriptionFullComplete": "बिना बम इस्तेमाल करे स्तर ${LEVEL} पार किया |", + "name": "मुक्केबाज़" + }, + "Dual Wielding": { + "descriptionFull": "दो कंट्रोलर (हार्डवेयर या ऍप) जोड़िये", + "descriptionFullComplete": "नियंतरण से जुणा", + "name": "दो हथियार" + }, + "Flawless Victory": { + "description": "एक भी बार चोट लगे बिना जीतें |", + "descriptionComplete": "एक भी बार चोट लगे बिना जीते |", + "descriptionFull": "एक भी बार चोट लगे बिना स्तर ${LEVEL} जीतें |", + "descriptionFullComplete": "एक भी बार चोट लगे बिना स्तर ${LEVEL} जीते |", + "name": "निष्कलंक विजय" + }, + "Free Loader": { + "descriptionFull": "फ्री-फॉर-ऑल गेम दो से ज्यादा खिलाड़ियोंके साथ शुरू कीजिए", + "descriptionFullComplete": "दो से जयादा खिलाडी़यों के साथ सबके-लिये-फृी खेल की शुरुआत हो चुकी है", + "name": "मुफत लोडर" + }, + "Gold Miner": { + "description": "विस्फोटक थल बम से ६ बुरे लोगों को मारें |", + "descriptionComplete": "विस्फोटक थल बम से ६ बुरे लोगों को मारा |", + "descriptionFull": "विस्फोटक थल बम से ६ बुरे लोगों को मारें स्तर ${LEVEL} पर |", + "descriptionFullComplete": "विस्फोटक थल बम से ६ बुरे लोगों को मार दिया स्तर ${LEVEL} पर |", + "name": "सोने का खनिक" + }, + "Got the Moves": { + "description": "घूंसे या बमों का इस्तेमाल बिना किये जीतें |", + "descriptionComplete": "घूंसे या बमों का इस्तेमाल बिना किये जीत गए |", + "descriptionFull": "घूंसे या बमों का इस्तेमाल बिना किये स्तर ${LEVEL} जीतें |", + "descriptionFullComplete": "घूंसे या बमों का इस्तेमाल बिना किये स्तर ${LEVEL} जीत गए |", + "name": "चालें में निपुण" + }, + "In Control": { + "descriptionFull": "एक नियंत्रक कनेक्ट करें (हार्डवेयर या ऐप)", + "descriptionFullComplete": "एक नियंत्रक जोड़ा गया(हार्डवेयर या ऐप)", + "name": "नियंत्रण मे" + }, + "Last Stand God": { + "description": "१००० अंक स्कोर करे |", + "descriptionComplete": "१००० स्कोर कर लिया |", + "descriptionFull": "${LEVEL} स्तर पर १००० अंक स्कोर करे |", + "descriptionFullComplete": "${LEVEL} स्तर पर १००० अंक स्कोर किया |", + "name": "${LEVEL} भगवान" + }, + "Last Stand Master": { + "description": "२५० स्कोर करें |", + "descriptionComplete": "२५० स्कोर कर लिया |", + "descriptionFull": "${LEVEL} स्तर पर २५० अंक स्कोर करें |", + "descriptionFullComplete": "${LEVEL} स्तर पर २५० अंक स्कोर किया |", + "name": "${LEVEL} गुरु" + }, + "Last Stand Wizard": { + "description": "५०० अंक स्कोर करें |", + "descriptionComplete": "५०० स्कोर कर लिया |", + "descriptionFull": "${LEVEL} स्तर पर ५०० अंक स्कोर करें |", + "descriptionFullComplete": "${LEVEL} स्तर पर ५०० अंक स्कोर किया |", + "name": "${LEVEL} जादूगर" + }, + "Mine Games": { + "description": "विस्फोटक थल बम से ३ बुरे लोगों को मारें |", + "descriptionComplete": "विस्फोटक थल बम से ३ बुरे लोगों को मारा |", + "descriptionFull": "विस्फोटक थल बम से स्तर ${LEVEL} पे ३ बुरे लोगों को मारें |", + "descriptionFullComplete": "विस्फोटक थल बम से स्तर ${LEVEL} पे ३ बुरे लोगों को मारा |", + "name": "विस्फोटक थल बम के खेल" + }, + "Off You Go Then": { + "description": "३ बुरे लोगों को नक्शे के बाहर फेंकें |", + "descriptionComplete": "३ बुरे लोगों को नक्शे के बाहर फेंका |", + "descriptionFull": "३ बुरे लोगों को नक्शे के बाहर स्तर ${LEVEL} पर फेंकें |", + "descriptionFullComplete": "३ बुरे लोगों को नक्शे के बाहर स्तर ${LEVEL} पर फेंका |", + "name": "जाओ यहाँ से तुम" + }, + "Onslaught God": { + "description": "५००० अंक स्कोर करें |", + "descriptionComplete": "५००० स्कोर कर लिया |", + "descriptionFull": "${LEVEL} स्तर पर ५००० अंक स्कोर करें |", + "descriptionFullComplete": "${LEVEL} स्तर पर ५००० अंक स्कोर किया |", + "name": "${LEVEL} भगवान" + }, + "Onslaught Master": { + "description": "५०० अंक स्कोर करें |", + "descriptionComplete": "५०० स्कोर कर लिया |", + "descriptionFull": "${LEVEL} स्तर पर ५०० अंक स्कोर करें |", + "descriptionFullComplete": "${LEVEL} स्तर पर ५०० अंक स्कोर किया |", + "name": "${LEVEL} गुरु" + }, + "Onslaught Training Victory": { + "description": "सारी लहरों को पार करें |", + "descriptionComplete": "सारी लहरों को पार किया |", + "descriptionFull": "साड़ी लहरों को पार करें स्तर ${LEVEL} में |", + "descriptionFullComplete": "साड़ी लहरों को पार किया स्तर ${LEVEL} में |", + "name": "${LEVEL} पर विजय" + }, + "Onslaught Wizard": { + "description": "१००० अंक स्कोर करें |", + "descriptionComplete": "१००० स्कोर कर लिया |", + "descriptionFull": "${LEVEL} स्तर पर १००० अंक स्कोर करें |", + "descriptionFullComplete": "${LEVEL} स्तर पर १००० अंक स्कोर किया |", + "name": "${LEVEL} जादूगर" + }, + "Precision Bombing": { + "description": "किसी भी शक्तिप्रापक का इस्तेमाल किये बिना जीतें |", + "descriptionComplete": "किसी भी शक्तिप्रापक का इस्तेमाल किये बिना जीते |", + "descriptionFull": "किसी भी शक्तिप्रापक का इस्तेमाल किये बिना स्तर ${LEVEL} जीतें |", + "descriptionFullComplete": "किसी भी शक्तिप्रापक का इस्तेमाल किये बिना स्तर ${LEVEL} जीते |", + "name": "सटीक बमबारी" + }, + "Pro Boxer": { + "description": "बिना बम का प्रयोग करे जीतें |", + "descriptionComplete": "बिना बम का प्रयोग करे जीते |", + "descriptionFull": "बिना बम का प्रयोग करे स्तर ${LEVEL} पार करें |", + "descriptionFullComplete": "बिना बम का प्रयोग करे स्तर ${LEVEL} पार किया |", + "name": "पेशेवर बॉक्सर" + }, + "Pro Football Shutout": { + "description": "बिना बुरे लोगों के अंक लिए हुए जीतें |", + "descriptionComplete": "बिना बुरे लोगों के अंक लिए हुए जीते |", + "descriptionFull": "बिना बुरे लोगों के अंक लिए हुए स्तर ${LEVEL} जीतें |", + "descriptionFullComplete": "बिना बुरे लोगों के अंक लिए हुए स्तर ${LEVEL} जीते |", + "name": "${LEVEL} शट आउट" + }, + "Pro Football Victory": { + "description": "गेम जीतें |", + "descriptionComplete": "गेम जीत गए |", + "descriptionFull": "गेम जीतें स्तर ${LEVEL} पर |", + "descriptionFullComplete": "गेम जीत गए स्तर ${LEVEL} पर |", + "name": "${LEVEL} पर विजय" + }, + "Pro Onslaught Victory": { + "description": "सारी लहरों को पार करें |", + "descriptionComplete": "सारी लहरों को पार किया |", + "descriptionFull": "साड़ी लहरों को पार करें स्तर ${LEVEL} में |", + "descriptionFullComplete": "साड़ी लहरों को पार किया स्तर ${LEVEL} में |", + "name": "${LEVEL} पर विजय" + }, + "Pro Runaround Victory": { + "description": "सारी लहरों को पार करें |", + "descriptionComplete": "सारी लहरों को पार किया |", + "descriptionFull": "साड़ी लहरों को पार करें स्तर ${LEVEL} में |", + "descriptionFullComplete": "साड़ी लहरों को पार किया स्तर ${LEVEL} में |", + "name": "${LEVEL} पर विजय" + }, + "Rookie Football Shutout": { + "description": "बिना बुरे लोगों के अंक लिए हुए जीतें |", + "descriptionComplete": "बिना बुरे लोगों के अंक लिए हुए जीते |", + "descriptionFull": "बिना बुरे लोगों के अंक लिए हुए स्तर ${LEVEL} जीतें |", + "descriptionFullComplete": "बिना बुरे लोगों के अंक लिए हुए स्तर ${LEVEL} जीते |", + "name": "${LEVEL} शट आउट" + }, + "Rookie Football Victory": { + "description": "गेम जीतें |", + "descriptionComplete": "गेम जीत गए |", + "descriptionFull": "गेम जीतें स्तर ${LEVEL} पर |", + "descriptionFullComplete": "गेम जीत गए स्तर ${LEVEL} पर |", + "name": "${LEVEL} पर विजय" + }, + "Rookie Onslaught Victory": { + "description": "सारी लहरों को पार करें |", + "descriptionComplete": "सारी लहरों को पार किया |", + "descriptionFull": "सारी लहरों को पार करें स्तर ${LEVEL} में |", + "descriptionFullComplete": "सारी लहरों को पार किया स्तर ${LEVEL} में |", + "name": "${LEVEL} पर विजय" + }, + "Runaround God": { + "description": "२०० अंक स्कोर करें |", + "descriptionComplete": "२०० स्कोर कर लिया |", + "descriptionFull": "${LEVEL} स्तर पर २०० अंक स्कोर करें |", + "descriptionFullComplete": "${LEVEL} स्तर पर २०० अंक स्कोर किया |", + "name": "${LEVEL} भगवान" + }, + "Runaround Master": { + "description": "५०० अंक स्कोर करें |", + "descriptionComplete": "५०० स्कोर कर लिया |", + "descriptionFull": "${LEVEL} स्तर पर ५०० अंक स्कोर करें |", + "descriptionFullComplete": "${LEVEL} स्तर पर ५०० अंक स्कोर किया |", + "name": "${LEVEL} गुरु" + }, + "Runaround Wizard": { + "description": "१००० अंक स्कोर करें |", + "descriptionComplete": "१००० स्कोर कर लिया |", + "descriptionFull": "${LEVEL} स्तर पर १००० अंक स्कोर करें |", + "descriptionFullComplete": "${LEVEL} स्तर पर १००० अंक स्कोर किया |", + "name": "${LEVEL} जादूगर" + }, + "Sharing is Caring": { + "descriptionFull": "सफलतापूवृक शेयर", + "descriptionFullComplete": "मित्र के साथ खेल को सफलतापूर्वक साझा किया गया", + "name": "साझा करना ही देखभाल है" + }, + "Stayin' Alive": { + "description": "बिना मरे जीतें |", + "descriptionComplete": "बिना मरे जीते |", + "descriptionFull": "बिना मरे स्तर ${LEVEL} जीतें |", + "descriptionFullComplete": "बिना मरे स्तर ${LEVEL} जीते |", + "name": "जिन्दा हूँ मैं !" + }, + "Super Mega Punch": { + "description": "एक घूँसा में १००% नुक्सान दें दुश्मन को |", + "descriptionComplete": "एक घूँसा में १००% नुक्सान दिया दुश्मन को |", + "descriptionFull": "एक घूँसा में १००% नुक्सान दें दुश्मन को स्तर ${LEVEL} पर |", + "descriptionFullComplete": "एक घूँसा में १००% नुक्सान दें दुश्मन को स्तर ${LEVEL} पर |", + "name": "धमाकेदार घूँसा !" + }, + "Super Punch": { + "description": "एक घूँसा में ५०% नुक्सान दें दुश्मन को |", + "descriptionComplete": "एक घूँसा में ५०% नुक्सान दिया दुश्मन को |", + "descriptionFull": "एक घूँसा में ५०% नुक्सान दें दुश्मन को स्तर ${LEVEL} पर |", + "descriptionFullComplete": "एक घूँसा में ५०% नुक्सान दें दुश्मन को स्तर ${LEVEL} पर |", + "name": "धुआँधार घूँसा !" + }, + "TNT Terror": { + "description": "टी•न•टी से ६ बुरे लोगों को मार डालो |", + "descriptionComplete": "टी•न•टी से ६ बुरे लोगों को मार डाला |", + "descriptionFull": "टी•न•टी से ६ बुरे लोगों को मार डालो स्तर ${LEVEL} पर |", + "descriptionFullComplete": "टी•न•टी से ६ बुरे लोगों को मार डाला स्तर ${LEVEL} पर |", + "name": "टी•न•टी का आतंक !" + }, + "Team Player": { + "descriptionFull": "4+ खिलाड़ियों के साथ एक टीम गेम शुरू करें", + "descriptionFullComplete": "4+ खिलाड़ियों के साथ एक टीम गेम शुरू किया", + "name": "टीम के खिलाड़ी" + }, + "The Great Wall": { + "description": "हर एक बुरे व्यक्ति को रोकें |", + "descriptionComplete": "हर एक बुरे व्यक्ति को रोका |", + "descriptionFull": "हर एक बुरे व्यक्ति को रोकें स्तर ${LEVEL} पर |", + "descriptionFullComplete": "हर एक बुरे व्यक्ति को रोका स्तर ${LEVEL} पर |", + "name": "अटूट दीवार !" + }, + "The Wall": { + "description": "हर एक बुरे व्यक्ति को रोकें |", + "descriptionComplete": "हर एक बुरे व्यक्ति को रोका |", + "descriptionFull": "हर एक बुरे व्यक्ति को रोकें स्तर ${LEVEL} पर |", + "descriptionFullComplete": "हर एक बुरे व्यक्ति को रोका स्तर ${LEVEL} पर |", + "name": "दीवार !" + }, + "Uber Football Shutout": { + "description": "बिना बुरे लोगों के अंक लिए हुए जीतें |", + "descriptionComplete": "बिना बुरे लोगों के अंक लिए हुए जीते |", + "descriptionFull": "बिना बुरे लोगों के अंक लिए हुए स्तर ${LEVEL} जीतें |", + "descriptionFullComplete": "बिना बुरे लोगों के अंक लिए हुए स्तर ${LEVEL} जीते |", + "name": "${LEVEL} शट आउट" + }, + "Uber Football Victory": { + "description": "गेम जीतें |", + "descriptionComplete": "गेम जीत गए |", + "descriptionFull": "गेम जीतें स्तर ${LEVEL} पर |", + "descriptionFullComplete": "गेम जीत गए स्तर ${LEVEL} पर |", + "name": "${LEVEL} पर विजय" + }, + "Uber Onslaught Victory": { + "description": "सारी लहरों को पार करें |", + "descriptionComplete": "सारी लहरों को पार किया |", + "descriptionFull": "सारी लहरों को पार करें स्तर ${LEVEL} पर |", + "descriptionFullComplete": "सारी लहरों को पार किया स्तर ${LEVEL} पर |", + "name": "${LEVEL} पर विजय" + }, + "Uber Runaround Victory": { + "description": "सारी लहरों को पार करें |", + "descriptionComplete": "सारी लहरों को पार किया |", + "descriptionFull": "सारी लहरों को पार करें स्तर ${LEVEL} पर |", + "descriptionFullComplete": "सारी लहरों को पार किया स्तर ${LEVEL} पर |", + "name": "${LEVEL} पर विजय" + } + }, + "achievementsRemainingText": "उप्लाब्धियाँ बाकी:", + "achievementsText": "उप्लाब्धियाँ", + "achievementsUnavailableForOldSeasonsText": "माफ़ करें उपलब्धियों कि जानकारी पुराने सीजन से नहीं है", + "activatedText": "${THING} सक्रिय", + "addGameWindow": { + "getMoreGamesText": "और गेम्स कि जानकारी पायें", + "titleText": "गेम जोड़ें" + }, + "allowText": "अनुमति दें", + "alreadySignedInText": "आपका खाता किसी अन्य डिवाइस से साइन किया गया है; \nकृपया खातों को स्विच करें या अपने गेम को अन्य डिवाइस \nपर बंद करें और फिर से प्रयास करें", + "apiVersionErrorText": "${NAME} मौड्यूल लोड नहीं हो पाया ; यह एपीआई - संस्करण ${VERSION_USED} पे काम करने का प्रयास कर रहा है ; हमें संस्करण ${VERSION_REQUIRED} चाहिए |", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"स्वयं\" इसे तभी शुरू करेगा जब हैडफ़ोन लगें हों)", + "headRelativeVRAudioText": "सर के सापेक्ष वीआर ध्वनि", + "musicVolumeText": "गाने की आवाज़", + "soundVolumeText": "गाने कि ध्वनि का स्तर", + "soundtrackButtonText": "गाने", + "soundtrackDescriptionText": "(गेम के दौरान चलने के लिए अपना गाना निर्दिष्ट करें)", + "titleText": "ध्वनि" + }, + "autoText": "अपने आप उत्तम चुने", + "backText": "वापस", + "banThisPlayerText": "इस खिलाड़ी को प्रतिबंधित करें", + "bestOfFinalText": "${COUNT}-का-सबसे-अच्छा आखिरी", + "bestOfSeriesText": "${COUNT} सीरीज़ का सर्वोच्च", + "bestRankText": "आपका सबसे अच्छा पद है #${RANK}", + "bestRatingText": "आपका सबसे अच्छा मूल्यांकन है ${RATING}", + "bombBoldText": "बम", + "bombText": "बम", + "boostText": "प्रोत्साहन", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} को एप्लीकेशन के अन्दर से ही कॉन्फ़िगर करें |", + "buttonText": "बटन", + "canWeDebugText": "क्या आप बोम्ब-स्क्वाड को अपने आप खराबियों व \nआधारभूत उपयोग कि जानकारी भेजना चाहते हैं ? \n\nइस जानकारी में कुछ भी व्यक्तिगत नहीं होता है व \nयह गेम को सुचारू रूप से बिना खराबियों के चलने में सहायता करता है |", + "cancelText": "रद्द करें", + "cantConfigureDeviceText": "माफ़ करें  ${DEVICE} कांफिग्युरेब्ल नहीं है |", + "challengeEndedText": "यह चुनौती समाप्त हो चूकि हैं", + "chatMuteText": "बातचीत मौन करें", + "chatMutedText": "बातचीत मौन हो गई है", + "chatUnMuteText": "बातचीत दोबारा शुरू करें", + "choosingPlayerText": "<खिलाड़ी चुना जा रहा है>", + "completeThisLevelToProceedText": "आपको यह पड़ाव पार करना पड़ेगा आगे बढ़ने के लिए !", + "completionBonusText": "पूर्णता पुरस्कार", + "configControllersWindow": { + "configureControllersText": "नियंत्रक को कॉन्फ़िगर करें", + "configureKeyboard2Text": "कीबोर्ड पी २ को कॉन्फ़िगर करें", + "configureKeyboardText": "कीबोर्ड को कॉन्फ़िगर करें", + "configureMobileText": "मोबाइल यंत्रों को नियंत्रक के रूप में", + "configureTouchText": "टच स्क्रीन को कॉन्फ़िगर करें", + "ps3Text": "पी-एस-३ नियंत्रक", + "titleText": "नियंत्रक", + "wiimotesText": "वाईमोत्स", + "xbox360Text": "एक्स्बोक्स ३६० नियंत्रक" + }, + "configGamepadSelectWindow": { + "androidNoteText": "टिप्पणी- नियंत्रक के लिए सहारा यंत्र से यंत्र व एंड्राइड के संस्करणों से अलग अलग होता है |", + "pressAnyButtonText": "जिस भी नियंत्रक को आप कॉन्फ़िगर करना चाहते हैं उस पर कोई भी बटन दबाएँ ...", + "titleText": "नियंक्त्रकों को कॉन्फ़िगर करें" + }, + "configGamepadWindow": { + "advancedText": "उन्नत सेटिंग्स", + "advancedTitleText": "उन्नत सेटिंग्स नियंत्रक सेटअप", + "analogStickDeadZoneDescriptionText": "(इसको बढ़ाएं अगर आपकी प्रकृति नियंत्रण छोड़ने पर भी हिलती है )", + "analogStickDeadZoneText": "अनुरूप छड़ी का मृत क्षेत्र", + "appliesToAllText": "(इस प्रकार के सभी नियंत्रकों को प्रभावित करता है)", + "autoRecalibrateDescriptionText": "(इसे सक्षम करें यदि आपकी प्रकृति पूरी गति से नहीं चलती है )", + "autoRecalibrateText": "अनुरूप छड़ी का पुनः व्यास मापन करें", + "axisText": "धुरी", + "clearText": "खाली करें", + "dpadText": "डी-पैड", + "extraStartButtonText": "अतिरिक्त प्रारंभ करने का बटन", + "ifNothingHappensTryAnalogText": "अगर कुछ नहीं होता है तो अनुरूप छड़ी को निर्दिष्ट करने का प्रयास करें", + "ifNothingHappensTryDpadText": "अगर कुछ नहीं होता है तो डी-पैड को निर्दिष्ट करने का प्रयास करें", + "ignoreCompletelyDescriptionText": "(इस नियंत्रक को खेल या मेनू को प्रभावित करने से रोकें)", + "ignoreCompletelyText": "पूरी तरह से अनदेखा करें", + "ignoredButton1Text": "उपेक्षित बटन १", + "ignoredButton2Text": "उपेक्षित बटन २", + "ignoredButton3Text": "उपेक्षित बटन ३", + "ignoredButton4Text": "उपेक्षित बटन 4", + "ignoredButtonDescriptionText": "(होम व सम्न्यवित के बटन के प्रभाव से बचने के लिए इसका प्रयोग करें)", + "pressAnyAnalogTriggerText": "किसी भी अनुरुप संकेत को दबाएँ..", + "pressAnyButtonOrDpadText": "किसी भी बटन या डी-पैड को दबाएँ..", + "pressAnyButtonText": "कोई बटन दबाये..", + "pressLeftRightText": "दायें या बाएं दबाएँ..", + "pressUpDownText": "ऊपर या नीचे दबाएँ..", + "runButton1Text": "दोड़ने का पहला बटन", + "runButton2Text": "दोड़ने का दूसरा बटन", + "runTrigger1Text": "दोड़ने का पहला संकेत", + "runTrigger2Text": "दोड़ने का दूसरा संकेत", + "runTriggerDescriptionText": "(अनुरूप संकेत आपको परिवर्तनशील गति से दोड़ने दे सकता है)", + "secondHalfText": "इसका प्रयोग करके एक में दो वाले \nयंत्र को कॉन्फ़िगर करें जो एक यंत्र \nकि तरह भांपा जा रहा हो |", + "secondaryEnableText": "सक्षम करें", + "secondaryText": "द्वितीय नियंत्रक", + "startButtonActivatesDefaultDescriptionText": "(इसे बंद कर दें यदि आपका प्रारंभ करने का बटन मेन्यू बटन ज्यादा है)", + "startButtonActivatesDefaultText": "प्रारंभ करने का बटन, पहले से प्रस्थापित विजेट को सक्रिय कर देता है", + "titleText": "नियंत्रक का सेटअप", + "twoInOneSetupText": "एक में दो कंट्रोलर का सेटअप", + "uiOnlyDescriptionText": "(इस नियंत्रक को वास्तव में एक गेम में शामिल होने से रोकें)", + "uiOnlyText": "मेनू उपयोग की सीमा", + "unassignedButtonsRunText": "सरे निर्दिष्ट न किये हुए बटन को चलाना", + "unsetText": "<नियत न किये हुए>", + "vrReorientButtonText": "वीआर पुनर्योजी बटन" + }, + "configKeyboardWindow": { + "configuringText": "${DEVICE} को कॉन्फ़िगर किया जा रहा है", + "keyboard2NoteText": "टिपण्णी: अधिकतर कीबोर्ड एक बार में कुछ ही \nबटन के दबने को पह्चान सकता है, \nइसलिए दूसरा कीबोर्ड होना बेहतर रह सकता है |0\nपण्णी: आपको दुसरे खिलाड़ी के लिए \nफिर भी अलग बटन निर्दिष्ट करने पड़ेंगे |" + }, + "configTouchscreenWindow": { + "actionControlScaleText": "कार्य करने के बटनों का माप", + "actionsText": "कार्य", + "buttonsText": "बटन", + "dragControlsText": "< नियंत्रण बटन को पुनः स्थापित करने के लिए पकड़ के हिलाएं >", + "joystickText": "जोस्टिक", + "movementControlScaleText": "संचालन के बटनों का माप", + "movementText": "संचालन", + "resetText": "रीसेट", + "swipeControlsHiddenText": "स्वाइप आइकन को छुपा दें", + "swipeInfoText": "स्वाइप से खेलना सिखने में थोडा टाइम लगता है परन्तु\n उसके बाद बिना नियंत्रण बटन देखे खेलना बहुत आसन होता है", + "swipeText": "स्वाइप", + "titleText": "टच स्क्रीन को कॉन्फ़िगर करें" + }, + "configureItNowText": "अभी कॉन्फ़िगर करें ?", + "configureText": "कॉन्फ़िगर", + "connectMobileDevicesWindow": { + "amazonText": "अमेज़न का एप्लीकेशन भंडार", + "appStoreText": "गूगल का एप्लीकेशन हंदर", + "bestResultsText": "सबसे अच्छे परिणामों के लये आपको विलंबन रहित नेटवर्क चाहिए होगा | \nआप विलंबन कम कर सकते हैं बाकी वायरलेस यंत्रों को बंद कर के, \nराऊटर के पास खेल के, \nव गेम मेज़बान को नेटवर्क से ईथरनेट से सीधे जोड़ के |", + "explanationText": "किसी स्मार्ट फ़ोन या टेबलेट का वायरलेस नयन्त्रक के रूप में प्रयोग करने के लिए \nउसपे \"${REMOTE_APP_NAME}\" एप्लीकेशन डालें | \nकितने भी यंत्र ${APP_NAME} गेम से वाई-फी से जुड़ सकते हैं, और यह मुफ्त है !", + "forAndroidText": "एंड्राइड के लिए:", + "forIOSText": "आई-ओ-एस के लिए:", + "getItForText": "${REMOTE_APP_NAME} पायें आई-ओ-एस के लिए एप्पल एप्लीकेशन भंडार से \nव एंड्राइड के लिए गूगल प्ले भंडार या अमेज़न एप्लीकेशन भंडार से |", + "googlePlayText": "गूगल प्ले स्टोर", + "titleText": "मोबाइल यंत्र का नियंत्रक के रूप में प्रयोग करते हुए: " + }, + "continuePurchaseText": "${PRICE} के खर्चे पर जारी रखें ?", + "continueText": "जारी रखें", + "controlsText": "नियंत्रण", + "coopSelectWindow": { + "activenessAllTimeInfoText": "यह सम्पूर्ण काल के पद पे लागू नहीं होता है", + "activenessInfoText": "यह गुणक उन दिनों बढ़ता है जब आप खेलते हैं \nऔर उन दिनों घटता है जिन दिन आप नहीं खेलते", + "activityText": "सक्रियता", + "campaignText": "अभियान", + "challengesInfoText": "छोटे गेम खेल के पुरस्कार जीतें | \n\nकिसी स्तर को पार करने पर पुरस्कार \nव कठिनाई बढती है | \nकिसी स्तर पर हारने पर कठिनाई व पुरस्कार कम होता है |", + "challengesText": "चुनौतियाँ", + "currentBestText": "अभी तक का सबसे अच्छा", + "customText": "अपने हिसाब से", + "entryFeeText": "भाग लेने कि कीमत", + "forfeitConfirmText": "यह चुनौती छोड़ दें ?", + "forfeitNotAllowedYetText": "यह चुनौती इस वक्त समाप्त नहीं हो सकती", + "forfeitText": "हार मानें", + "multipliersText": "गुणक", + "nextChallengeText": "अगली चुनौती", + "nextPlayText": "अगली बार खेलने का अवसर", + "ofTotalTimeText": "${TOTAL} में से", + "playNowText": "अभी खेलें", + "pointsText": "अंक", + "powerRankingFinishedSeasonUnrankedText": "(ख़तम किया बिना पद के)", + "powerRankingNotInTopText": "(सर्वोच्च ${NUMBER} में से नहीं)", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} अंक)", + "powerRankingPointsText": "${NUMBER} अंक", + "powerRankingPointsToRankedText": "(${REMAINING} में से ${CURRENT} अंक बाकी)", + "powerRankingText": "सत्ता पद", + "prizesText": "पुरस्कार", + "proMultInfoText": "${PRO} उन्नयन वाले खिलाड़ियों को \n${PERCENT}% अंकों का बढ़ावा मिलता है", + "seeMoreText": "और..", + "skipWaitText": "प्रतीक्षा ख़तम करें", + "timeRemainingText": "समय बाकी", + "toRankedText": "अभी पद मिलना है", + "totalText": "सम्पूर्ण", + "tournamentInfoText": "सम्पूर्ण अंकों में अपने संघ के बाकी \nखिलाड़ियों के साथ प्रतिस्पर्धा करें | \n\nप्रतियोगिता के ख़तम होने पर सबसे ज्यादा अंकों वाले \nखिलाड़ियों को पुरस्कार दिया जायेगा |", + "welcome1Text": "${LEAGUE} में आपका स्वागत है | \nआप आपनी संघ में पैड को स्टार रेटिंग कमाने से, \nउप्लाब्धियाँ पार करने से व  ट्रॉफी जीतने से बढ़ा सकते हैं |", + "welcome2Text": "आप टिकेट उन्ही गतिविधियाओं से भी कमा सकते हैं | \nटिकेट नए रूप, नक़्शे व छोटे गेम खोलने तथा \nप्रतियोगिता में भाग लेने आदि में काम आ सकते हैं |", + "yourPowerRankingText": "आपका सत्ता पद :" + }, + "copyConfirmText": "क्लिपबोर्ड पर कॉपी हुआ।", + "copyOfText": "${NAME} दूसरा", + "copyText": "नकल किजिए", + "createEditPlayerText": "<प्लेयर बनाएँ / संपादित करें>", + "createText": "बनायें", + "creditsWindow": { + "additionalAudioArtIdeasText": "${NAME} कि अतिरिक्त ध्वनि, अकालघटित कलाकृति, और विचार", + "additionalMusicFromText": "${NAME} कि अतिरिक्त ध्वनि", + "allMyFamilyText": "मेरे सारे परिवार के सदस्य व दोस्त जिन्होंने गेम खेला", + "codingGraphicsAudioText": "कोडिंग, ग्राफ़िक्स और ध्वनि ${NAME} के द्वारा", + "languageTranslationsText": "भाषा के अनुवाद:", + "legalText": "क़ानूनी:", + "publicDomainMusicViaText": "सार्वजनिक-डोमेन संगीत ${NAME} के द्वारा", + "softwareBasedOnText": "यह सॉफ्टवेयर ${NAME} के कुछ अंश के काम पर आधारित है", + "songCreditText": "${TITLE} ${PERFORMER} के द्वारा, ${COMPOSER} के द्वारा रचा हुआ,\n ${ARRANGER} के द्वारा सहेजा हुआ, \n ${PUBLISHER} द्वारा प्रकाशित, ${SOURCE} का सौजन्य |", + "soundAndMusicText": "ध्वनि व गाने:", + "soundsText": "गाने (${SOURCE}):", + "specialThanksText": "विशेष धन्यवाद:", + "thanksEspeciallyToText": "खासकर धन्यवाद ${NAME}", + "titleText": "${APP_NAME} कि आभार सूचि", + "whoeverInventedCoffeeText": "जिसने भी कॉफ़ी ढूंढी!" + }, + "currentStandingText": "आपका वर्तमान पैड है #${RANK}", + "customizeText": "अपने हिसाब से समायोजित करें...", + "deathsTallyText": "${COUNT} बार मौत", + "deathsText": "मौत", + "debugText": "डीबग", + "debugWindow": { + "reloadBenchmarkBestResultsText": "टिप्पणी: इसकी जांच करते समय सेटिंग->ग्राफ़िक्स->तेक्स्चर्स को 'उच्च' पे रखें", + "runCPUBenchmarkText": "सीपीयू बेंचमार्क चलायें", + "runGPUBenchmarkText": "जीपीयु बेंचमार्क चलायें", + "runMediaReloadBenchmarkText": "मीडिया लादने का बेंचमार्क चलायें", + "runStressTestText": "तनाव परीक्षा करें", + "stressTestPlayerCountText": "खिलाड़ियों कि संख्या", + "stressTestPlaylistDescriptionText": "तनाव परीक्षा कि प्लेलिस्ट", + "stressTestPlaylistNameText": "प्लेलिस्ट का नाम", + "stressTestPlaylistTypeText": "प्लेलिस्ट का प्ररूप", + "stressTestRoundDurationText": "दौर कि अवधि", + "stressTestTitleText": "तनाव परीक्षा", + "titleText": "बेंचमार्क व तनाव परीक्षाएं", + "totalReloadTimeText": "पूरा पुनः लादने का समय: ${TIME} (अधिक जानकारी के लिए लॅाग देखें)" + }, + "defaultGameListNameText": "पहले से प्रस्थापित ${PLAYMODE} प्लेलिस्ट", + "defaultNewGameListNameText": "मेरी ${PLAYMODE} प्लेलिस्ट", + "deleteText": "हटाना", + "demoText": "डेमो", + "denyText": "अस्वीकृत करें", + "deprecatedText": "पदावनत", + "desktopResText": "डेस्कटॉप रेज़ोल्यूशन", + "deviceAccountUpgradeText": "चेतावनी:\n आप डिवाइस खाते (${NAME}) से साइन इन हैं।\n डिवाइस खातों को भविष्य के अपडेट में हटा दिया जाएगा।\n यदि आप अपनी प्रगति को बनाए रखना चाहते हैं तो V2 खाते में अपग्रेड करें।", + "difficultyEasyText": "आसन", + "difficultyHardOnlyText": "केवल कठिन", + "difficultyHardText": "कठिन", + "difficultyHardUnlockOnlyText": "इस स्तर को सिर्फ कठिन में खोला जा सकता है | \nक्या आपमें वोह है इसे पार करने के लिए !", + "directBrowserToURLText": "कृपया अपने वेब ब्राउज़र को इस यूआरएल पे भेजें", + "disableRemoteAppConnectionsText": "रिमोट के ऐप्प कनेक्शन्स को बंद करे", + "disableXInputDescriptionText": "4 नियंत्रकों से अधिक की अनुमति देता है लेकिन साथ ही साथ काम नहीं कर सकते", + "disableXInputText": "Xinput अक्षम करें", + "doneText": "हो गया", + "drawText": "बराबर", + "duplicateText": "प्रतिलिपि", + "editGameListWindow": { + "addGameText": "गेम जोड़ें", + "cantOverwriteDefaultText": "पहले से प्रस्थापित किया गया प्लेलिस्ट ओवरराईट नहीं कर सकते !", + "cantSaveAlreadyExistsText": "इस नाम कि प्लेलिस्ट पहले से ही मौजूद है |", + "cantSaveEmptyListText": "खली प्लेलिस्ट को सेव नहीं किया जा सकता है", + "editGameText": "गेम को संपादित करें", + "listNameText": "प्लेलिस्ट का नाम", + "nameText": "नाम", + "removeGameText": "गेम को हटायें", + "saveText": "सूचि को सेव करें", + "titleText": "प्लेलिस्ट संपादक" + }, + "editProfileWindow": { + "accountProfileInfoText": "यह एक ख़ास पार्श्वचित्र ( एक नाम और आइकॉन के साथ) है \nआपके साइन इन करे हुए खाते के आधार पर | \n\n${ICONS} \n\nअपना पार्श्वचित्र बनायें अगर आपको अलग नाम \nअपने आइकॉन का प्रयोग करना है |", + "accountProfileText": "(खाते का पार्श्वचित्र)", + "availableText": "नाम \"${NAME}\" उपलब्ध है", + "changesNotAffectText": "टिपण्णी: गेम के अन्दर पहले से जो पात्र है उनपे परिवर्तन का असर नहीं होगा", + "characterText": "पात्र", + "checkingAvailabilityText": "${NAME} कि उपलब्धि जाँची जा रही है...", + "colorText": "रंग", + "getMoreCharactersText": "और पात्र पायें...", + "getMoreIconsText": "और आइकॉन पायें...", + "globalProfileInfoText": "खिलाड़ियों के वैश्विक पार्श्वचित्र का अनोखा नाम होगा | \nवैश्विक पार्श्वचित्र वाले खिलाड़ी अपना आइकॉन भी लगा सकते हैं |", + "globalProfileText": "(वैश्विक पार्श्वचित्र)", + "highlightText": "उभार", + "iconText": "आइकॉन", + "localProfileInfoText": "स्थानिक खिलाड़ी पार्श्वचित्र का कोई आइकॉन नहीं होता है \nव यह भी ज़रूरी नहीं है कि उनका नाम अनोखा हो | \nवैश्विक पार्श्वचित्र में उन्नयन करें अनोखे नाम व आइकॉन के लिए |", + "localProfileText": "(स्थानिक पार्श्वचित्र)", + "nameDescriptionText": "खिलाड़ी का नाम", + "nameText": "नाम", + "randomText": "यादृच्छिक", + "titleEditText": "पार्श्वचित्र को संपादित करें", + "titleNewText": "नया पार्श्वचित्र बनायें", + "unavailableText": "\"${NAME}\" उपलब्ध नहीं है; कृपया दूसरा नाम चुनें |", + "upgradeProfileInfoText": "यह आपके नाम को विश्व भर में निग्रह कर देगा \nव आप अपना आइकॉन चुन सकते हैं |", + "upgradeToGlobalProfileText": "वैश्विक पार्श्वचित्र में उन्नयन करें" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "पहले से प्रस्थापित गाने को डिलीट नहीं कर सकते |", + "cantEditDefaultText": "पहले से प्रस्थापित गाने को संपादित नहीं किया जा सकता है | इसकी छवि बनायें या नया बनायें |", + "cantOverwriteDefaultText": "पहले से प्रस्थापित गाने को अधिलेखित नहीं किया जा सकता है", + "cantSaveAlreadyExistsText": "इस नाम का गाना पहले से है !", + "defaultGameMusicText": "<पहले से प्रस्थापित गाना>", + "defaultSoundtrackNameText": "पहले से प्रस्थापित गाना", + "deleteConfirmText": "गाने को हटायें ?\n\n${NAME}", + "deleteText": "गाना \nहटायें", + "duplicateText": "गाने कि \nछवि बनायें", + "editSoundtrackText": "गाना संपादक", + "editText": "गाने को \nसंपादित करें", + "fetchingITunesText": "आपके गाने वाले एप्लिकेशन कि प्लेलिस्ट ली जा रही है...", + "musicVolumeZeroWarning": "चेतावनी: गाने कि ध्वनि का स्तर ० पर है", + "nameText": "नाम", + "newSoundtrackNameText": "मेरा गाना ${COUNT}", + "newSoundtrackText": "नया गाना:", + "newText": "नया \nगाना:", + "selectAPlaylistText": "पल्य्लिस्ट चुनें:", + "selectASourceText": "गाने का स्रोत", + "testText": "परीक्षा करें", + "titleText": "गानें", + "useDefaultGameMusicText": "पहले से प्रस्थापित गेम का गाना", + "useITunesPlaylistText": "गाने एप्लिकेशन कि प्लेलिस्ट", + "useMusicFileText": "गाने कि फाइल (एम्-पी-३, आदि)", + "useMusicFolderText": "गाने कि फाइल्स का फोल्डर" + }, + "editText": "संपादित करें", + "endText": "समाप्त", + "enjoyText": "मज़ा लें !", + "epicDescriptionFilterText": "${DESCRIPTION} उत्कृष्ट धीमे गति में।", + "epicNameFilterText": "उत्कृष्ट ${NAME}", + "errorAccessDeniedText": "अभिगम वर्जित", + "errorDeviceTimeIncorrectText": "आपके उपकरण का समय ${HOURS} घंटे गलत है।\nइससे समस्याएं होने की संभावना है।\nकृपया अपना समय और समय-क्षेत्र सेटिंग की जाँच करें", + "errorOutOfDiskSpaceText": "डिस्क पे जगह ख़तम", + "errorSecureConnectionFailText": "सुरक्षित क्लाउड कनेक्शन स्थापित करने में असमर्थ; नेटवर्क कार्यक्षमता विफल हो सकती है", + "errorText": "त्रुटी", + "errorUnknownText": "अज्ञात त्रुटी", + "exitGameText": "${APP_NAME} से निकास करें ?", + "exportSuccessText": "'${NAME}' निर्यात हुआ", + "externalStorageText": "बाहरी संचयन", + "failText": "असफल", + "fatalErrorText": "माफ़ करें कुछ लुप्त है या गड़बड़ है | \nकृपया फिर से इनस्टॉल करने का प्रयास करें या \n${EMAIL} पर सहयता के लिए संपर्क करें |", + "fileSelectorWindow": { + "titleFileFolderText": "कोई फाइल या फोल्डर चुनें", + "titleFileText": "फाइल चुनें", + "titleFolderText": "फोल्डर चुनें", + "useThisFolderButtonText": "इस फोल्डर को चुनें" + }, + "filterText": "निस्पंदन", + "finalScoreText": "समापक अंक", + "finalScoresText": "समापक अंक", + "finalTimeText": "समापक समय", + "finishingInstallText": "इनस्टॉल ख़तम हो रहा है, सब्र रखें...", + "fireTVRemoteWarningText": "और बेहतर अनुभव के लिए \nगेम नियंत्रक का प्रयोग करें, \nया '${REMOTE_APP_NAME}' \nएप्लीकेशन इन्स्टाल करें अपने फ़ोन या टेबलेट पे |", + "firstToFinalText": "${COUNT} तक पहले पहुँचने कि प्रतियोगिता का आखिरी दौर", + "firstToSeriesText": "${COUNT} तक पहले पहुँचने कि प्रतियोगिता", + "fiveKillText": "पांच हत्या !!!", + "flawlessWaveText": "त्रुटिरहित लहर !", + "fourKillText": "चार हत्या !!!", + "friendScoresUnavailableText": "दोस्तों के अंक उनुप्लाब्ध हैं ", + "gameCenterText": "गेम-सेण्टर", + "gameCircleText": "गेम-सर्किल", + "gameLeadersText": "गेम ${COUNT} के सरदार", + "gameListWindow": { + "cantDeleteDefaultText": "पहले से प्रस्थापित प्लेलिस्ट को डिलीट नहीं कर सकते |", + "cantEditDefaultText": "पहले से प्रस्थापित प्लेलिस्ट को संपादित नहीं किया जा सकता है | इसकी छवि बनायें या नया बनायें |", + "cantShareDefaultText": "आप डिफ़ॉल्ट प्लेलिस्ट साझा नहीं कर सकते", + "deleteConfirmText": "${LIST} को हटायें ?", + "deleteText": "प्लेलिस्ट \nको हटायें", + "duplicateText": "प्लेलिस्ट कि \nछवि बनायें", + "editText": "प्लेलिस्ट को \nसंपादित करें", + "newText": "नयी \nप्लेलिस्ट", + "showTutorialText": "ट्युटोरियल दिखाएँ", + "shuffleGameOrderText": "गेम के क्रमांक को मिलाएं", + "titleText": "${TYPE} प्लेलिस्ट को अपने हिसाब से बदलें" + }, + "gameSettingsWindow": { + "addGameText": "गेम जोड़ें" + }, + "gamesToText": "${WINCOUNT} जीते और ${LOSECOUNT} हारे", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "ध्यान रखें: किसी भी यंत्र पे एक से ज्यादा खिलाड़ी हो सकते हैं \nअगर आपके पास पर्याप्त नियंत्रक हैं", + "aboutDescriptionText": "पार्टी इकट्ठा करने के लिए इन टैब्स का प्रयोग करें | \n\nपार्टी में आप गेम व \nप्रतियोगिता अपने दोस्तों के साथ \nअलग यंत्रो पे भी खेल सकते हैं | \n\nऊपरी-दायें हाथ कोने में उपस्थित ${PARTY} बटन का प्रयोग करके \nआप अपनी पार्टी से बात कर सकते हैं | (नियंत्रक पे ${BUTTON} दबाएँ मेनू में) ", + "aboutText": "इसके बारे में", + "addressFetchErrorText": "<पता पाने में त्रुटी>", + "appInviteInfoText": "दोस्तों को बोम्ब-स्क्वाड खेलने के लिए आमंत्रित करें\nऔर आपको ${COUNT} टिकेट मुफ्त मिलेंगे | हर\nदोस्त के आपको ${YOU_COUNT} टिकेट मिलेंगे |", + "appInviteMessageText": "${NAME} ने आपको ${COUNT} टिकेट ${APP_NAME} में भेजे हैं", + "appInviteSendACodeText": "एक कोड भेजें", + "appInviteTitleText": "${APP_NAME} एप्लीकेशन का आमंत्रण", + "bluetoothAndroidSupportText": "(किसी भी ब्लूटूथ वाले एंड्राइड यंत्र पे चलता है)", + "bluetoothDescriptionText": "किसी पार्टी के मेज़बान बनें या किसी पार्टी में जुडें ब्लूटूथ से", + "bluetoothHostText": "मेज़बान बनें ब्लूटूथ पर", + "bluetoothJoinText": "ब्लूटूथ से जुडें", + "bluetoothText": "ब्लूटूथ", + "checkingText": "जांचा जा रहा है...", + "copyCodeConfirmText": "कोड को क्लिपबोर्ड पर कॉपी किया गया है", + "copyCodeText": "कोड को कॉपी करें", + "dedicatedServerInfoText": "श्रेष्ठ परिणामों के लिए, एक समर्पित सर्वर सेट करें. कैसे जानने के लिए bombsquadgame.com/server देखें.", + "disconnectClientsText": "यह आपके पार्टी में ${COUNT} \nखिलाड़ियों का सम्बन्ध तोड़ देगा", + "earnTicketsForRecommendingAmountText": "यदि वे गेम को आज़माते हैं तो दोस्तों को ${COUNT} \nटिकट मिलेंगे (और आप प्रत्येक के लिए ${YOU_COUNT} प्राप्त करेंगे)", + "earnTicketsForRecommendingText": "मुफ्त के टिकेट \nके लिए गेम को बाटें...", + "emailItText": "मेल करें", + "favoritesSaveText": "पसंदीदा के रूप में सहेजें", + "favoritesText": "पसंदीदा", + "freeCloudServerAvailableMinutesText": "अगला मुफ्त क्लाउड सर्वर ${MINUTES} मिनट में उपलब्ध है", + "freeCloudServerAvailableNowText": "फ्री क्लाउड सर्वर उपलब्ध है", + "freeCloudServerNotAvailableText": "कोई निःशुल्क क्लाउड सर्वर उपलब्ध नहीं है।", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} टिकेट मिले ${NAME} से", + "friendPromoCodeAwardText": "आपको ${COUNT} टिकेट मिलेंगे हर बार इसका प्रयोग किया जाता है", + "friendPromoCodeExpireText": "आपका कोड सिर्क नयें खिलाड़ियों के लिए चलेगा और ${EXPIRE_HOURS} घंटों के बाद काम करना बंद कर देगा", + "friendPromoCodeInstructionsText": "इसका प्रयोग करने के लिए, ${APP_NAME} खोले और फिर \"सेटिंग->उन्नत सेटिंग->कोड डालें\" में जाएँ \nअधिक जानकारी के लिए bombsquadgame.com व डाउनलोड करने के लिए पे जाएँ |", + "friendPromoCodeRedeemLongText": "यह ${COUNT} मुफ्त के टिकेट के लिए प्रयोग किया जा सकता है अधकतम  ${MAX_USES} लोगों के द्वारा |", + "friendPromoCodeRedeemShortText": "यह ${COUNT} मुफ्त के टिकेट के लिए प्रयोग किया जा सकता है गेम के अन्दर |", + "friendPromoCodeWhereToEnterText": "(\"सेटिंग->उन्नत सेटिंग->कोड डालें\" में जाएँ )", + "getFriendInviteCodeText": "दोस्त आमंत्रण कोड पायें", + "googlePlayDescriptionText": "गूगल प्ले के खिलाड़ियों को अपनी पार्टी में आमंत्रण दें:", + "googlePlayInviteText": "आमंत्रण दें", + "googlePlayReInviteText": "आपकी पार्टी में ${COUNT} गूगल प्ले के खिलाड़ी हैं \nजिनका सम्बन्ध टूट जाएगा अगर आप नया आमंत्रण शुरू करते हैं |\n उनको नए आमंत्रण में जोड़ें फिर से पार्टी में जोड़ने के लिए |", + "googlePlaySeeInvitesText": "आमंत्रण देखें", + "googlePlayText": "गूगल प्ले", + "googlePlayVersionOnlyText": "(एंड्राइड / गूगल प्ले का संस्करण)", + "hostPublicPartyDescriptionText": "अपनी सार्वजनिक पार्टी की मेजबानी करें", + "hostingUnavailableText": "होस्टिंग अनुपलब्ध", + "inDevelopmentWarningText": "टिपण्णी: \n\nनेटवर्क पे खेल अभी नया है और अभी भी इसका विकास हो रहा है | \nअभी के लिए यह सलाह डी जाती है\n कि सभी खिलाड़ी एक ही वाई-फाई नेटवर्क पे हों |", + "internetText": "इंटरनेट", + "inviteAFriendText": "दोस्तों के पास यह गेम नहीं है ? उन्हें आमंत्रित करें खेलने के लिए | \nउन्हें ${COUNT} टिकेट मुफ्त मिलेंगे |", + "inviteFriendsText": "आमंत्रित करें", + "joinPublicPartyDescriptionText": "एक सार्वजनिक पार्टी में शामिल हों", + "localNetworkDescriptionText": "अपने आस पास के दल से जुड़े (लैन , ब्यूटूथ , आदि)", + "localNetworkText": "स्थानिक नेटवर्क", + "makePartyPrivateText": "मेरा दल निजी करें", + "makePartyPublicText": "मेरा दल सार्वजनिक करें", + "manualAddressText": "पता", + "manualConnectText": "जुड़ें", + "manualDescriptionText": "पते के द्वारा किसी दल से जुडें", + "manualJoinSectionText": "पते से जुड़े", + "manualJoinableFromInternetText": "क्या आप इन्टरनेट से जुड़ सकते हैं ?:", + "manualJoinableNoWithAsteriskText": "नहीं*", + "manualJoinableYesText": "हाँ", + "manualRouterForwardingText": "*इसे ठीक करने के लिए अपने राऊटर के यु-डी-पी पोर्ट ${PORT} को अपने स्थानिक पते पर भेजने के अनुकूल करें", + "manualText": "खुद से", + "manualYourAddressFromInternetText": "आपका पता इन्टरनेट से:", + "manualYourLocalAddressText": "आपका स्थानीय पता:", + "nearbyText": "आस/पास", + "noConnectionText": "<कोई कनेक्शन नहीं है>", + "otherVersionsText": "(कोई और संस्करण)", + "partyCodeText": "दल कोड", + "partyInviteAcceptText": "स्वीकार करें", + "partyInviteDeclineText": "अस्वीकार करें", + "partyInviteGooglePlayExtraText": "('गूगल-प्ले' टैब 'इकट्ठा' विंडो में देखें)", + "partyInviteIgnoreText": "नज़रंदाज़ करें", + "partyInviteText": "${NAME} ने आपको अपनी पार्टी में \nजुड़ने के लिए आमंत्रित करा है !", + "partyNameText": "दल का नाम", + "partyServerRunningText": "आपका पार्टी सर्वर चल रहा है", + "partySizeText": "पार्टी साइज", + "partyStatusCheckingText": "स्थिति की जांच ...", + "partyStatusJoinableText": "आपकी पार्टी इंटरनेट से अब जुड़ने योग्य है", + "partyStatusNoConnectionText": "सर्वर से संपर्क करने में असमर्थ", + "partyStatusNotJoinableText": "आपकी पार्टी इंटरनेट से जुड़ने योग्य नहीं है", + "partyStatusNotPublicText": "आपकी पार्टी सार्वजनिक नहीं है", + "pingText": "पिंग", + "portText": "पॉर्ट", + "privatePartyCloudDescriptionText": "सभी निजी पार्टीयां उनके लिये समर्पित सरवर पर ही चलती है|कोई राऊटर कौ कॉन्फीगर करने की जरुरत नही |", + "privatePartyHostText": "निजी पार्टी बनाये", + "privatePartyJoinText": "एक निजी पार्टी में शामिल हों", + "privateText": "निजी", + "publicHostRouterConfigText": "यह आपके राउटर पर पोर्ट-फॉरवक्रिंग को कॉन्फ़िगर करने की आवश्यकता हो सकती है। एक आसान विकल्प के लिए, एक निजी पार्टी की मेजबानी करें", + "publicText": "सार्वजनिक", + "requestingAPromoCodeText": "एक कोड के लिए अनुरोध किया जा रहा है...", + "sendDirectInvitesText": "सीधे आमंत्रण भेजें", + "shareThisCodeWithFriendsText": "इस कोड को अपने दोस्तों के साथ बाटें:", + "showMyAddressText": "मेरा पता दिखाएं", + "startHostingPaidText": "अभी होस्ट करे ${COST}", + "startHostingText": "मेज़बान", + "startStopHostingMinutesText": "आप अगले ${MINUTES} के लिए मुफ्त में होस्टिंग शुरू और बंद कर सकते हैं।", + "stopHostingText": "होस्टिंग बंद करो", + "titleText": "इकट्ठा", + "wifiDirectDescriptionBottomText": "यदि सारे यंत्रों में 'वाई-फाई डायरेक्ट' का पैनल है \nतो यंत्र उससे आराम से एक दुसरे से जुड़ सकते हैं |\nजुड़ने के बाद आप 'स्थानीय नेटवर्क' टैब से पार्टी बना सकते है, सामान्य 'वाई-फाई' कि तरह | \n\n सबसे अच्छे परिणामों के लिए 'वाई-फाई डायरेक्ट' के मेज़बान को ही ${APP_NAME} पार्टी का मेज़बान होना चाहिए |", + "wifiDirectDescriptionTopText": "वाई-फाई डायरेक्ट' से एंड्राइड यंत्रों को बिना वाई-फाई नेटवर्क के भी जोड़ा जा सकता है | \nयह एंड्राइड ४.२ और ओसके बाद के सभी संस्करणों के साथ सबसे अच्छा चलता है | \n\nइसका प्रयोग करने के लिए वाई-फाई सेटिंग खोलें और फिर 'वाई-फाई डायरेक्ट' मेनू में ढूंढे |", + "wifiDirectOpenWiFiSettingsText": "वाई-फाई सेटिंग खोलें", + "wifiDirectText": "वाई-फाई डायरेक्ट", + "worksBetweenAllPlatformsText": "(हर प्लेटफार्म के बीच काम करता है)", + "worksWithGooglePlayDevicesText": "(गूगल प्ले का गेम का संस्करण चलने वाले यंत्रों पे चलता है)", + "youHaveBeenSentAPromoCodeText": "आपको बोम्बस्क्वॉड का प्रोत्साहक सन्देश भेजा गया है:" + }, + "getTicketsWindow": { + "freeText": "मुफ्त !!", + "freeTicketsText": "मुफ्त टिकेट", + "inProgressText": "एक सौदा अभी चल रहा है; कृपया थोड़ी देर बाद प्रयास करें", + "purchasesRestoredText": "खरीदारी वापस ला दी गयी है", + "receivedTicketsText": "${COUNT} टिकेट मिले !!", + "restorePurchasesText": "खरीदारी वापस लायें", + "ticketDoublerText": "टिकेट को दुगना करें", + "ticketPack1Text": "छोटा टिकेट का संग्रह", + "ticketPack2Text": "ठीक-ठाक टिकेट का संग्रह", + "ticketPack3Text": "बड़ा टिकेट का संग्रह", + "ticketPack4Text": "बहुत बड़ा टिकेट का संग्रह", + "ticketPack5Text": "महान टिकेट संग्रह", + "ticketPack6Text": "महाकाय टिकेट संग्रह", + "ticketsFromASponsorText": "एक विज्ञापन देख के \n${COUNT} टिकट प्राप्त करें", + "ticketsText": "${COUNT} टिकेट", + "titleText": "टिकेट पायें", + "unavailableLinkAccountText": "माफ़ करें इस प्लेटफार्म पर खरीदारी नहीं कि जा सकती है |\nएक वैकल्पिक हल के रूप में आप इस खाते को किसी \nऔर प्लेटफार्म के खाते से जोड़ कर खरीदारी कर सकते हैं |", + "unavailableTemporarilyText": "यह अभी उपलब्ध नहीं है; कृपया थोड़ी देर बाद पुनः प्रयास करें |", + "unavailableText": "मांफ करें, यह अभी उपलब्ध नहीं है |", + "versionTooOldText": "माफ़ कारें यह गेम का संस्करण बहुत ही पुराना है; कृपया नया संस्करण डालें", + "youHaveShortText": "आपके पास ${COUNT} हैं", + "youHaveText": "आपके पास ${COUNT} टिकेट हैं" + }, + "googleMultiplayerDiscontinuedText": "क्षमा करें, गूगल की एक साथ खेलने की सेवा अब उपलब्ध नहीं है। \nमैं जितनी जल्दी हो सके एक प्रतिस्थापन पर काम कर रहा हूं।\nतब तक, कृपया दूसरी जुडने की विधि आज़माएँ। \n-Eric", + "googlePlayPurchasesNotAvailableText": "गूगल प्ले से ख़रीदारी उपलब्ध नहीं हैं।\nआपको अपना स्टोर ऐप अपडेट करना पड़ सकता है।", + "googlePlayServicesNotAvailableText": "गूगल प्ले सर्विसेज उपलब्ध नहीं है।\nऐप की कुछ कार्यक्षमता अक्षम हो सकती है।", + "googlePlayText": "गूगल प्ले", + "graphicsSettingsWindow": { + "alwaysText": "हमेशा", + "fullScreenCmdText": "संपूर्ण स्क्रीन में चलायें (सी-एम्-डी + ऍफ़)", + "fullScreenCtrlText": "संपूर्ण स्क्रीन में चलायें (सी-टी-आर-एल + ऍफ़)", + "gammaText": "चमक", + "highText": "ज्यादा", + "higherText": "और ज्यादा", + "lowText": "कम", + "mediumText": "ठीक ठाक", + "neverText": "कभी नहीं", + "resolutionText": "रेज़ोल्यूशन", + "showFPSText": "ऍफ़-पी-एस दिखाएँ", + "texturesText": "बनावटें", + "titleText": "ग्राफ़िक्स", + "tvBorderText": "टी-वि कि सीमा", + "verticalSyncText": "लंबरूप समकालीकरण", + "visualsText": "दृश्य" + }, + "helpWindow": { + "bombInfoText": "- बम - \nमुक्कों से ज्यादा शक्तिशाली परंतू \nखुद को भी नुक्सान पहुंचा सकते हैं | \nसबसे अच्छे परिणामों के लिए दुश्मन \nकि तरफ फूटने से पहले फेंके |", + "canHelpText": "${APP_NAME} मदद कर सकता है |", + "controllersInfoText": "आप नेटवर्क पे दोस्तों के साथ ${APP_NAME} खेल सकते हैं, या आप एक ही यंत्र पे भी खेल सकते हैं \nअगर आपके पास पर्याप्त नियंत्रक हैं | \n${APP_NAME} विविध नियंत्रकों को चला सकता है; \nआप फ़ोन का भी नियंत्रक के रूप में प्रयोग कर सकते है मुफ्त कि \n'${REMOTE_APP_NAME}' एप्लीकेशन द्वारा | अधिक जानकारी के लिए सेटिंग->नियंत्रक देखें |", + "controllersInfoTextRemoteOnly": "आप एक नेटवर्क पर दोस्तों के साथ ${APP_NAME} खेल सकते हैं, या आप \nसभी एक ही डिवाइस पर मुफ्त '${REMOTE_APP_NAME}' ऐप के \nमाध्यम से कंट्रोलर के रूप में फोन का उपयोग कर सकते हैं।", + "controllersText": "नियंत्रक", + "controlsSubtitleText": "आपका ${APP_NAME} पात्र कुछ बुनियादी कार्य कर सकता है", + "controlsText": "नियंत्रण", + "devicesInfoText": "${APP_NAME} गेम का वी-आर संस्करण आम संस्करण के \nसाथ नेटवर्क पे खेला जा सकता है, \nतो निकलित्ये अपने फ़ोन और टेबलेट और खेलने लग जाइए !\nएक आम संस्करण को वी-आर संस्करण से भी जोड़ सकते हैं \nताकि आपके दुसरे दोस्त भी देखके मज़ा ले सकें |", + "devicesText": "यंत्र", + "friendsGoodText": "इनका होना नहुत अच्छा है | ${APP_NAME} को कई खिलाड़ियों (अधिकतम ८ खिलाड़ी) \nके साथ खेलने में मज़ा आता है |यह हमें पहुंचाता है:", + "friendsText": "दोस्त", + "jumpInfoText": "- कूदें - \nछोटे फासलें पार करने के लिए कूदें, \nचीजों को ऊँचा फेकने के लिए कूदें, \nऔर ख़ुशी ज़ाहिर करने के लिये कूदें !", + "orPunchingSomethingText": "या मुक्केबाजी के लिए, बहार फेकने के लिए और चिपकू बम्ब से उसे रास्ते में फोड़ने के लिए", + "pickUpInfoText": "- उठाना - \nझंडे, दुश्मन या कुछ भी उठायें \nजो जमीन से न जुड़ा हो फेकने \nके लिए फिर से दबाएँ", + "powerupBombDescriptionText": "एक बार में एक कि जगह तीन \nबम फेकने कि क्षमता दे देता है |", + "powerupBombNameText": "तीगुना बम", + "powerupCurseDescriptionText": "आप इनसे शायद बचना चाहेंगे,.. \n......या नहीं ??", + "powerupCurseNameText": "श्राप", + "powerupHealthDescriptionText": "आपके स्वास्थ्य को पूरा कर देती है | \nयह आपने सोचा भी न होगा |", + "powerupHealthNameText": "स्वास्थ्य का संकुल", + "powerupIceBombsDescriptionText": "साधारण बम से कमज़ोर \nमगर दुश्मन को जमा के \nबहुत नाज़ुक कर देते हैं |", + "powerupIceBombsNameText": "बर्फ़-बम", + "powerupImpactBombsDescriptionText": "साधारण बम से कमज़ोर \nमगर छुते ही फुट जाते हैं |", + "powerupImpactBombsNameText": "ट्रिगर-बम", + "powerupLandMinesDescriptionText": "यह एक साथ तिन मिलती हैं; \nइसका प्रयोग अपने अड्डे \nकि सुरक्षा के लिए व तेज़ दुश्मनों को रोकने के लिए करें |", + "powerupLandMinesNameText": "विस्फोटक थल बम", + "powerupPunchDescriptionText": "आपके मुक्कों को और दमदार, \nतेज़ और बेहतर करता है |", + "powerupPunchNameText": "मुक्केबाज़ी के दस्ताने", + "powerupShieldDescriptionText": "थोडा सा नुक्सान \nअपने में ले लेता है |", + "powerupShieldNameText": "सुरक्षा कवच", + "powerupStickyBombsDescriptionText": "जिस भी चीज़ को छुएँगे उससे चिपक जायेंगे .. \nइसका मज़ा लें !", + "powerupStickyBombsNameText": "चिपकू-बम", + "powerupsSubtitleText": "बेशक कोई भी गेम शक्तिप्रापकों के बिना पूरा नहीं है;", + "powerupsText": "शक्तिप्रापक", + "punchInfoText": "- मुक्के - \nमुक्के ज्यादा नुक्सान करते हैं। \nजितनी तेजी से मुक्के चलेंगे उतने ज़्यादा नुकसान होंगे। \nअतः पागल जैसे दौड़ो और घूमो।", + "runInfoText": "- दोडें - \nदोड़ने के लिए किसी भी बटन को दबाये रखें | \nदोड़ने से आप जल्दी पहुँच सकते हैं लेकिन मुड़ने में दिक्कत हो सकती है, इसलिए किनारों पे सावधान रहें |", + "someDaysText": "कुछ दिन आपका सिर्फ मुक्के मारने का या कुछ फोड़ने का मन करता है", + "titleText": "${APP_NAME} सहायता", + "toGetTheMostText": "इस गेम से सबसे ज्यादा पाने के लिए आपको इनकी आवश्यकता होगी:", + "welcomeText": "${APP_NAME} में आपका स्वागत है !" + }, + "holdAnyButtonText": "<कोई भी बटन दबाएँ रखें>", + "holdAnyKeyText": "<कोई भी की दबाएँ रखें>", + "hostIsNavigatingMenusText": "- ${HOST} मेनू में सरदार कि तरह घूम रहा है -", + "importPlaylistCodeInstructionsText": "इस प्लेलिस्ट को कहीं और आयात करने के लिए निम्न कोड का उपयोग करें:", + "importPlaylistSuccessText": "आयातित ${TYPE} प्लेलिस्ट '${NAME}'", + "importText": "आयात करें", + "importingText": "आयात कर रहा है...", + "inGameClippedNameText": "खेल में होगा \n\"${NAME}\"", + "installDiskSpaceErrorText": "त्रुटी: इनस्टॉल ख़तम नहीं कर पाया | \nआपके यंत्र पे जगह ख़तम हो सकती है | \nजगह खली कर के फिर से प्रयास करें |", + "internal": { + "arrowsToExitListText": "सूचि से बाहर निकलने केलिए ${LEFT} या ${RIGHT} दबाएँ", + "buttonText": "बुतों", + "cantKickHostError": "आप होस्ट को किक नहीं कर सकते।", + "chatBlockedText": "${NAME} ${TIME} सेकंड के लिए अवरुद्ध चैट है।", + "connectedToGameText": "${NAME}' में शामिल हो गए", + "connectedToPartyText": "${NAME} कि पार्टी में जुड़ गए हैं !", + "connectingToPartyText": "जुड़ रहे हैं ...", + "connectionFailedHostAlreadyInPartyText": "जुड़ना असफल रहा; मेज़बान किसी और पार्टी में है |", + "connectionFailedPartyFullText": "कनेक्शन विफल; पार्टी भरी हुई है।", + "connectionFailedText": "जुड़ना असफल रहा |", + "connectionFailedVersionMismatchText": "जुड़ना असफल रहा; मेज़बान गेम का अलग संस्करण चला रहा है | \nयह सुनिश्चित करें कि आप दोनों के पास एक ही संस्करण है और फिर प्रयास करें |", + "connectionRejectedText": "जुड़ने के अनुरोध को अस्वीकार कर दिया गया |", + "controllerConnectedText": "${CONTROLLER} जुड़ गया है |", + "controllerDetectedText": "1 नियंत्रक का पता चला है |", + "controllerDisconnectedText": "${CONTROLLER} अब जुदा नहीं है |", + "controllerDisconnectedTryAgainText": "${CONTROLLER} अब जुदा नहीं है | पुनः जोड़ने का प्रयास करें |", + "controllerForMenusOnlyText": "इस नियंत्रक को खेलने के लिए इस्तेमाल नहीं किया जा सकता है; केवल मेनू नेविगेट करने के लिए।", + "controllerReconnectedText": "${CONTROLLER} पुनः जुड़ गया है |", + "controllersConnectedText": "${COUNT} नियंत्रक जुड़े हैं |", + "controllersDetectedText": "${COUNT} नियंत्रक का पता चला है |", + "controllersDisconnectedText": "${COUNT} नियंत्रक अब जुड़े नहीं है |", + "corruptFileText": "फाइलों में कुछ गड़बड़ी है | पुनः इनस्टॉल करने का प्रयास करें या ${EMAIL} पे मेल करें", + "errorPlayingMusicText": "${MUSIC} गाना चलने में दिक्कत", + "errorResettingAchievementsText": "ऑनलाइन उपलब्धियों को रिसेट करने में दिक्कत; कृपया थोड़ी देर बाद पुनः प्रयास करें |", + "hasMenuControlText": "${NAME} के पास मेनू का नियंत्रण है|", + "incompatibleNewerVersionHostText": "होस्ट खेल का एक नया संस्करण चल रहा है। \nनवीनतम संस्करण में अपडेट करें और पुनः प्रयास करें।", + "incompatibleVersionHostText": "मेज़बान गेम का अलग संस्करण चला रहा है | \nयह सुनिश्चित करें कि आप दोनों के पास एक ही संस्करण है और फिर प्रयास करें |", + "incompatibleVersionPlayerText": "${NAME} गेम का अलग संस्करण चला रहा है | \nयह सुनिश्चित करें कि आप दोनों के पास एक ही संस्करण है और फिर प्रयास करें |", + "invalidAddressErrorText": "त्रुटी: आमान्य पता |", + "invalidNameErrorText": "त्रुटि: गलत नाम", + "invalidPortErrorText": "त्रुटि: गलत पोर्ट।", + "invitationSentText": "आमंत्रण भेज दिया गया है |", + "invitationsSentText": "${COUNT} आमंत्रण भेज दिए गए हैं |", + "joinedPartyInstructionsText": "कोई आपकी पार्टी में जुड़ गया है | \nगेम शुरू करने के लिए 'खेलें' पे जाएँ |", + "keyboardText": "कीबोर्ड", + "kickIdlePlayersKickedText": "आलसी होने के कारण ${NAME} को बहार निकाल जा रहा है", + "kickIdlePlayersWarning1Text": "${NAME} को ${COUNT} सेकंड में निकल दिया जाएगा अगर अआलसी ही रहता है |", + "kickIdlePlayersWarning2Text": "(आप इसे सेटिंग -> उन्नत सेटिंग में जा के बंद कर सकते हैं)", + "leftGameText": "${NAME}' ने छोड़ दिया।", + "leftPartyText": "${NAME} कि पार्टी को छोड़ दिया है |", + "noMusicFilesInFolderText": "इस फोल्डर में कोई भी गाना नहीं है |", + "playerJoinedPartyText": "${NAME} पार्टी में जुड़ गया है !", + "playerLeftPartyText": "${NAME} ने पार्टी छोड़ दी है |", + "rejectingInviteAlreadyInPartyText": "आमंत्रण को अस्वीकार किया जा रहा है (पहले से ही पार्टी में हैं) |", + "serverRestartingText": "परिसेवक पुन: प्रारंभ हो रहा है। कृपया एक पल में फिर से जुड़ें...", + "serverShuttingDownText": "परिसेवक बंद हो रहा है...", + "signInErrorText": "साइन इन करने में त्रुटी", + "signInNoConnectionText": "साइन इन नहीं कर पा रहे | (इन्टरनेट कनेक्शन है ना ?)", + "telnetAccessDeniedText": "त्रुटी: उपयोगकर्ता ने टेलनेट कि अनुमति नहीं डी है |", + "timeOutText": "(समय ख़तम होने में ${TIME} सेकंड)", + "touchScreenJoinWarningText": "आपने टच स्क्रीन से जोड़ा है | \nअगर यह गलती से हुआ है तो 'मेनू -> गेम छोड़ें' से बाहर निकल जाएँ |", + "touchScreenText": "टच स्क्रीन", + "unableToResolveHostText": "त्रुटि: होस्ट को हल करने में असमर्थ हैं।", + "unavailableNoConnectionText": "यह अभी उपलब्ध नहीं है | (इन्टरनेट कनेक्शन है ना ?)", + "vrOrientationResetCardboardText": "वी-आर अनुस्थापन रिसेट करने के लिए इसका प्रयोग करें | \nगेम खेलने के लिए आपको एक बाहरी नियंत्रक चाहिए होगा |", + "vrOrientationResetText": "वी-आर अनुस्थापन रिसेट", + "willTimeOutText": "(समय ख़तम हो जायेगा अगर आलसी रहेंगे)" + }, + "jumpBoldText": "कूदें", + "jumpText": "कूदें", + "keepText": "रखें", + "keepTheseSettingsText": "इन सेटिंग को रखें ?", + "keyboardChangeInstructionsText": "कीबोर्ड को बदलने के लिए दो बार अन्तरक दबाएँ।", + "keyboardNoOthersAvailableText": "ओर कीबोर्ड उपलब्ध नहीं हैं।", + "keyboardSwitchText": "\"${NAME}\" से कीबोर्ड बदला जा रहा है।", + "kickOccurredText": "${NAME} को बाहर निकाल दिया गया।", + "kickQuestionText": "${NAME} को बाहर निकाल दें?", + "kickText": "बाहर निकाल दें", + "kickVoteCantKickAdminsText": "परिसेवक मालिक को निकाल नहीं सकते।", + "kickVoteCantKickSelfText": "खुद को निकाल नहीं कर सकते।", + "kickVoteFailedNotEnoughVotersText": "वोट के लिए पर्याप्त खिलाड़ी नहीं हैं।", + "kickVoteFailedText": "बाहर निकालने का वोट असफल रहा।", + "kickVoteStartedText": "${NAME} के लिए एक बाहर निकलने का वोट शुरू किया गया है।", + "kickVoteText": "बाहर निकालने के लिए वोट करें", + "kickVotingDisabledText": "निकालने का चुनाव बंद है।", + "kickWithChatText": "हां के लिए चैट में ${YES} टाइप करें और ना के लिए ${NO}।", + "killsTallyText": "${COUNT} हत्याएं", + "killsText": "हत्याएं", + "kioskWindow": { + "easyText": "आसान", + "epicModeText": "अद्भुत मोड", + "fullMenuText": "पूरा मेनू", + "hardText": "कठिन", + "mediumText": "मध्यम", + "singlePlayerExamplesText": "अकेले/दुकेले के अदाहरण", + "versusExamplesText": "विरुद्ध के उदहारण" + }, + "languageSetText": "भाषा अब \"${LANGUAGE}\" है |", + "lapNumberText": "${TOTAL} में से ${CURRENT} चक्कर", + "lastGamesText": "(आखिरी ${COUNT} गेम)", + "leaderboardsText": "लीडरबोर्ड", + "league": { + "allTimeText": "सबसे अच्छे शुरुआत से", + "currentSeasonText": "वर्तमान सीज़न (${NUMBER})", + "leagueFullText": "${NAME} संघ", + "leagueRankText": "संघ में पद", + "leagueText": "संघ", + "rankInLeagueText": "#${RANK}, ${NAME} संघ ${SUFFIX}", + "seasonEndedDaysAgoText": "सीज़न ख़तम हो गया ${NUMBER} दिन पहले |", + "seasonEndsDaysText": "सीज़न ख़तम होगा ${NUMBER} दिनों में |", + "seasonEndsHoursText": "सीज़न ख़तम होगा ${NUMBER} घंटों में |", + "seasonEndsMinutesText": "सीज़न ख़तम होगा ${NUMBER} मिनटों में |", + "seasonText": "सीज़न संख्या ${NUMBER}", + "tournamentLeagueText": "इस प्रतियोगिता में हिस्सा लेने के लिए आपको ${NAME} संघ तक पहले पहुंचना होगा", + "trophyCountsResetText": "ट्रॉफी कि संख्या अगले सीज़न में रिसेट हो जायेगी" + }, + "levelBestScoresText": "${LEVEL} पर सर्वश्रेष्ठ स्कोर", + "levelBestTimesText": "${LEVEL} पर सबसे अच्छे समय", + "levelFastestTimesText": "सबसे तेज़ ${LEVEL} स्तर पे", + "levelHighestScoresText": "सबसे जादा अंक ${LEVEL} स्तर पे", + "levelIsLockedText": "${LEVEL} अभी नहीं खेल सकते |", + "levelMustBeCompletedFirstText": "${LEVEL} को पहले पार करना होगा |", + "levelText": "स्तर ${NUMBER}", + "levelUnlockedText": "स्तर खुल गया है", + "livesBonusText": "प्राण का अधिलाभ", + "loadingText": "लोड हो रहा है", + "loadingTryAgainText": "लोड हो रहा है; एक क्षण में फिर से प्रयास करें...", + "macControllerSubsystemBothText": "दोनों (सिफारिश नहीं की गई)", + "macControllerSubsystemClassicText": "क्लासिक", + "macControllerSubsystemDescriptionText": "(यदि आपका नियंत्रक काम नहीं कर रहे हैं तो इसे बदलने का प्रयास करें)", + "macControllerSubsystemMFiNoteText": "आईओएस/मैक के लिए बना हुआ नियंत्रक का पता चला; \nआप सेटिंग -> नियंत्रकों में इन्हें सक्षम करना चाह सकते हैं", + "macControllerSubsystemMFiText": "आईओएस/मैक के लिए बना हुआ", + "macControllerSubsystemTitleText": "नियंत्रक समर्थन", + "mainMenu": { + "creditsText": "आभार सूचि", + "demoMenuText": "डेमो मेनू", + "endGameText": "गेम ख़तम करें", + "endTestText": "परीक्षण अंत", + "exitGameText": "गेम से बहार जाएँ", + "exitToMenuText": "ख़तम कर के मेनू में जाएं ?", + "howToPlayText": "कैसे खेलें", + "justPlayerText": "(केवल ${NAME})", + "leaveGameText": "गेम छोड़ें", + "leavePartyConfirmText": "सही में पार्टी छोड़ें ?", + "leavePartyText": "पार्टी छोड़ें", + "quitText": "बंद कर दें", + "resumeText": "पुनः शुरू करें", + "settingsText": "सेटिंग" + }, + "makeItSoText": "लागू करें", + "mapSelectGetMoreMapsText": "और नक़्शे पायें....", + "mapSelectText": "चुनें....", + "mapSelectTitleText": "${GAME} नक़्शे", + "mapText": "नक्शा", + "maxConnectionsText": "अधिकतम कनेक्शन", + "maxPartySizeText": "अधिकतम पार्टी का आकार", + "maxPlayersText": "अधिकतम खिलाड़ी", + "modeArcadeText": "आर्केड मोड", + "modeClassicText": "क्लासिक मोड", + "modeDemoText": "डेमो मोड", + "mostValuablePlayerText": "सबसे ज्यादा कीमती खिलाड़ी", + "mostViolatedPlayerText": "सबसे ज्यादा उल्लंघित खिलाड़ी", + "mostViolentPlayerText": "सबसे ज्यादा हिंसात्मक खिलाड़ी", + "moveText": "हिलें", + "multiKillText": "${COUNT}-हत्याएं!!!", + "multiPlayerCountText": "${COUNT} खिलाड़ी", + "mustInviteFriendsText": "टिपण्णी: आपको अपने दोस्तों को आमंत्रण \nभेजना होगा \"${GATHER}\" पैनल में, \nया दोस्तों के साथ खेलने के लिए नियंत्रक जोड़ें |", + "nameBetrayedText": "${NAME} ने ${VICTIM} को धोखा दिया |", + "nameDiedText": "${NAME} मर गया |", + "nameKilledText": "${NAME} ने ${VICTIM} को मार डाला |", + "nameNotEmptyText": "नाम खाली नहीं हो सकता है !", + "nameScoresText": "${NAME} को अंक मिला !", + "nameSuicideKidFriendlyText": "${NAME} गलती से मर गया |", + "nameSuicideText": "${NAME} ने आत्म-हत्या कर ली |", + "nameText": "नाम", + "nativeText": "मूलभूत", + "newPersonalBestText": "नया निजी उत्तम अंक !", + "newTestBuildAvailableText": "एक नया परीक्षा का संस्करण उपलब्ध है ! \n(${VERSION} बिल्ड ${BUILD}). इसे ${ADDRESS} से पायें |", + "newText": "नया", + "newVersionAvailableText": "${APP_NAME} का एक नया संस्करण उपलब्ध है ! (${VERSION})", + "nextAchievementsText": "अगली उपलब्धियां:", + "nextLevelText": "अगला स्तर", + "noAchievementsRemainingText": "- कुछ नहीं", + "noContinuesText": "(कोई जारी रखना नहीं)", + "noExternalStorageErrorText": "कोई बाहरी संचयन करने कि जगह नहीं मिली", + "noGameCircleText": "त्रुटी: गेम-सर्किल में लॉग-इन नहीं हैं |", + "noProfilesErrorText": "आपकी कोई खिलाड़ी पार्श्वचित्र नहीं है, इसलिए आप '${NAME}' नाम के साथ फंसे हैं |\nसेटिंग -> खिलाड़ी पार्श्वचित्र में जाके अपने लिए पार्श्वचित्र बनायें |", + "noScoresYetText": "अभी तक कोई स्कोर नहीं है |", + "noThanksText": "नहीं धन्यवाद", + "noTournamentsInTestBuildText": "चेतावनी: इस टेस्ट बिल्ड से खेलकूद-प्रतियोगिता के खेल के अंकों को नजरअंदाज कर दिया जाएगा।", + "noValidMapsErrorText": "इस गेम ढंग के लिए कोई नक्शा नहीं मिला", + "notEnoughPlayersRemainingText": "पर्याप्त खिलाड़ी बाकी नहीं हैं; बंद कर के नया गेम शुरू करें |", + "notEnoughPlayersText": "आपको कम से कम ${COUNT} खिलाड़ी चाहिए गेम शुरू करने के लिए !", + "notNowText": "अभी नहीं", + "notSignedInErrorText": "यह करने के लिए आपको अपने खाते में साइन इन करना पड़ेगा", + "notSignedInGooglePlayErrorText": "आपको गूगल प्ले से साइन इन करना पड़ेगा यह करने के लिए |", + "notSignedInText": "साइन इन नहीं हैं", + "notUsingAccountText": "नोट: ${SERVICE} खाते को अनदेखा करना।\n यदि आप इसका उपयोग करना चाहते हैं तो 'खाता -> ${SERVICE}' के साथ साइन इन करें।", + "nothingIsSelectedErrorText": "कुछ चुना नहीं है !", + "numberText": "#${NUMBER}", + "offText": "बंद करें", + "okText": "ठीक है", + "onText": "चालू करें", + "oneMomentText": "एक क्षण...", + "onslaughtRespawnText": "${PLAYER} फिर से जिन्दा होगा लहर ${WAVE} में", + "orText": "${A} या ${B}", + "otherText": "अन्य", + "outOfText": "(${ALL} में से #${RANK})", + "ownFlagAtYourBaseWarning": "आपका अपना झंडा अंक पाने के लिए आपके अड्डे पर होना चाहिए", + "packageModsEnabledErrorText": "स्थानिक मोड्स के साथ नेटवर्क पे खेलना वर्जित है (सेटिंग->उन्नत सेटिंग देखें)", + "partyWindow": { + "chatMessageText": "गपशप ख़त", + "emptyText": "आपकी पार्टी खाली है", + "hostText": "(मेज़बान)", + "sendText": "भेजें", + "titleText": "आपकी पार्टी" + }, + "pausedByHostText": "(मेज़बान ने रोका है)", + "perfectWaveText": "निष्कलंक लहर !", + "pickUpText": "उठायें", + "playModes": { + "coopText": "एक साथ", + "freeForAllText": "सभी अकेले-अकेले", + "multiTeamText": "कई समूह", + "singlePlayerCoopText": "अकेले/ एक साथ", + "teamsText": "समूह" + }, + "playText": "खेलें", + "playWindow": { + "oneToFourPlayersText": "१-४ खिलाड़ी", + "titleText": "खेलें", + "twoToEightPlayersText": "२-८ खिलाड़ी" + }, + "playerCountAbbreviatedText": "${COUNT} व्यक्ति", + "playerDelayedJoinText": "${PLAYER} अगले दौर कि शुरुआत में आएगा।", + "playerInfoText": "खिलाड़ी कि जानकारी", + "playerLeftText": "${PLAYER} ने गेम छोड़ दिया है", + "playerLimitReachedText": "खिलाड़ी कि अधिकतम संख्या ${COUNT} तक पहुँच गयी है; कोई और अब नहीं जुड़ सकता है |", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "आप अपने खाते के पार्श्वचित्र को हटा नहीं सकते |", + "deleteButtonText": "पार्श्वचित्र \nहटायें", + "deleteConfirmText": "${PROFILE}' हटायें?", + "editButtonText": "पार्श्वचित्र को \nसंपादित करें", + "explanationText": "(इस खाते के लिए कस्टम प्लेयर नाम और वेश-भूषा)", + "newButtonText": "नया \nपार्श्वचित्र", + "titleText": "खिलाड़ी के पार्श्वचित्र" + }, + "playerText": "खिलाड़ी", + "playlistNoValidGamesErrorText": "इस प्लेलिस्ट में कोई खुला हुआ गेम नहीं है |", + "playlistNotFoundText": "प्लेलिस्ट नहीं मिली", + "playlistText": "प्लेलिस्ट", + "playlistsText": "प्लेलिस्ट", + "pleaseRateText": "अगर आपको ${APP_NAME} में मज़ा आ रहा है, \nतो एक क्षण ले कर इसका मूल्यांकन करें | \nयह इस गेम के आगे के विकास का एक बहुत अहम् अंश है | \n\nधन्यवाद !\n-एरिक", + "pleaseWaitText": "कृपया प्रतीक्षा करें...", + "pluginClassLoadErrorText": "प्लगइन क्लास '${PLUGIN}' लोड करने में त्रुटि: ${ERROR}", + "pluginInitErrorText": "प्लगइन '${PLUGIN}' शुरुआत करने में त्रुटि: ${ERROR}", + "pluginsDetectedText": "नए प्लगइन्स पता चले। उन्हें सक्रिय करने के लिए पुनरारंभ करें, या उन्हें सेटिंग्स में कॉन्फ़िगर करें।", + "pluginsRemovedText": "${NUM} प्लगइन्स अब नहीं मिले।", + "pluginsText": "प्लगइन्स", + "practiceText": "अभ्यास", + "pressAnyButtonPlayAgainText": "दोबारा खेलने के लिए कोई भी बटन दबाएँ...", + "pressAnyButtonText": "जारी रखने के लिए कोई भी बटन दबाएँ...", + "pressAnyButtonToJoinText": "भाग लेने के लिए कोई भी बटन दबाएँ...", + "pressAnyKeyButtonPlayAgainText": "दोबारा खेलने के लिए कोई भी की / बटन दबाएँ...", + "pressAnyKeyButtonText": "जारी रखने के लिए कोई भी की / बटन दबाएँ...", + "pressAnyKeyText": "कोई भी की दबाएँ...", + "pressJumpToFlyText": "** उड़ने के लिए कूदने वाला बटन बार बार दबाएँ **", + "pressPunchToJoinText": "जुड़ने के लिए मुक्के वाला बटन दबाएँ...", + "pressToOverrideCharacterText": "${BUTTONS} दबाएँ अपना चरित्र बदलने के लिए", + "pressToSelectProfileText": "खिलाड़ी चुनने के लिए ${BUTTONS} दबाएं", + "pressToSelectTeamText": "एक समूह चुनने के लिए ${BUTTONS} दबाएं", + "promoCodeWindow": { + "codeText": "कोड", + "codeTextDescription": "प्रोमो कोड", + "enterText": "घुसें" + }, + "promoSubmitErrorText": "कोड जमा करने में त्रुटि: अपना इंटरनेट कनेक्शन जांच लें।", + "ps3ControllersWindow": { + "macInstructionsText": "अपने पी.एस.३ के पीछे कि बिजली को काटें, \nयह सुनिश्चित करें कि ब्लूटूथ खुला है आपके मैक पे और \nफिर अपने नियंत्रक को अपने मैक से जोड़ें एक यु.एस.बी तार से | \nइसके बाद से आप अपने नियंत्रक के होम बटन से मैक से जुड़ सकते है दोनों तार के साथ और \nबिना तार के साथ भी | कुछ मैक पे आपको पास्कोद के लिए अनुरोध किया जा सकता है | \n\n\n\nअगर यह होता है तो सहायता के \nलिए टुटोरिअल देखें या गूगल करें | \n\n\nपी.एस.३ के नियंत्रक जो बिना तार के जुड़े हैं वोह यंत्रों कि सूचि में दिखने चाहिए | \nआपको उन्हें हटाना पड़ सकता है उस सूचि से जब \nआपको उनका पुनः पी.एस.३ के साथ प्रयोग करना हो | \n\nऔर यह भी ध्यान रखें कि जब वोह प्रयोग में ना हों तो \nवोह जुड़े ना हों अन्यथा उनकी बैटरी ख़तम होती रहेगी | \n\nब्लूटूथ पे अधिकतम ७ यंत्र चल जाने चाहिए, \nहालाकि उनमें थोड़ी देरी आ सकती है |", + "ouyaInstructionsText": "पी.एस.३ नियंत्रक को ऊया के सस्थ चलने के लिए सिर्फ उसे एक बार यु.एस.बी तार से जोड़ दें |\nयह करने पे आपके बाकी नियंत्रकों का जोड़ टूट सकता है इसलिए आपको अपने ऊया को पुनः शुरू\nकर के यु.एस.बी तार निकाल देना चाहिए | \n\nइसके बाद से आप नियंत्रक का 'होम' बटन दबा के बिना तार के जुड़ सकते हैं | \nजब आपका खेलना ख़तम हो जाए तो \n'होम' बटन १० सेकंड तक दबा के \nनियंत्रक को बंद कर दें अन्यथा वोह बैटरी ख़तम कर सकता है |", + "pairingTutorialText": "शैक्षणिक वीडियो जोड़ा जा रहा है", + "titleText": "${APP_NAME} के साथ पी.एस.३ नियंत्रक का प्रयोग किया जा रहा है:" + }, + "punchBoldText": "मुक्का", + "punchText": "मुक्का", + "purchaseForText": "${PRICE} के भाव पे खरीदें", + "purchaseGameText": "गेम खरीदें", + "purchasingText": "खरीद रहे हैं...", + "quitGameText": "${APP_NAME} को बंद कर दें ?", + "quittingIn5SecondsText": "५ सेकंड में बंद कर रहे हैं...", + "randomPlayerNamesText": "किशोर, यश, ख्याति, शालिनी, आदित्य, उमेस, निश्चिंत, भाविक, रिशव, तुषार, राहुल, अमोल, मिशेल, प्रियंका, कल्याण, रियान, दिविज, हरी, आदर्श, कौस्तुभ, ज़ोया, सीनू, प्रतीक, ज़ारा, रुक्सार, शकील, पूजा, शबनम, शेरा, चेतन, समीर, टोनी, अजय, आकाश, पंकज, आरती, शबाना, मुमताज़, शुभम, शिवम्, लकेव, सचिन, दीपक, अक्षय, अर्जुन, किशन, राधा, विश्वनाथ, शालू, विमल, शिवा, पप्पू, नरेंद्र, आज़म, अनमोल, काजल, संध्या, दिनेश, प्रिंस, आनंद, अज़हर, पवन, अभिषेक, विवेक", + "randomText": "अनियमित", + "rankText": "पद", + "ratingText": "मूल्यांकन", + "reachWave2Text": "पद पाने के लिए पेहली लहर को पार करें", + "readyText": "तैयार", + "recentText": "नए", + "remoteAppInfoShortText": "${APP_NAME} सबसे मजेदार है जब परिवार और दोस्तों के साथ खेला जाता है। \nएक या अधिक हार्डवेयर नियंत्रक से कनेक्ट करें \nया स्थापित करें ${REMOTE_APP_NAME} एप्लिकेशन उन्हें फोन या \nटेबलेट पर उपयोग करने के लिए नियंत्रकों के रूप में।", + "remote_app": { + "app_name": "बोम्ब-स्क्वाड दूरस्थ", + "app_name_short": "बी.एस दूरस्थ", + "button_position": "बटन कि जगह", + "button_size": "बटन का माप", + "cant_resolve_host": "मेज़बान से जुड़ नहीं पा रहे...", + "capturing": "पकड़ा जा रहा है...", + "connected": "जुड़ गए हैं", + "description": "अपने फ़ोन या टेबलेट का नियंत्रिक के रूप में बोम्ब-स्क्वाड के लिए प्रयोग करें | \nअधिकतम ८ यंत्र जुड़ सकते है एक साथ एक ही टेबलेट या दूरदर्शन में अपना अलग अलग खेलने के लिए |", + "disconnected": "परिसेवक से संपर्क टूट गया है", + "dpad_fixed": "स्थायी", + "dpad_floating": "हिलता हुआ", + "dpad_position": "हिलने के बटन कि जगह", + "dpad_size": "हिलने के बटन का माप", + "dpad_type": "हिलने के बटन का प्ररूप", + "enter_an_address": "पता डालें", + "game_full": "यह गेम भरा हुआ है और संपर्क नहीं स्वीकार कर रहा है |", + "game_shut_down": "गेम बंद हो गया है |", + "hardware_buttons": "हार्डवेयर बटन", + "join_by_address": "पते से जुडें...", + "lag": "देरी: ${SECONDS} सेकंड", + "reset": "पहले से प्रस्थापित सेटिंग्स को लागू करें", + "run1": "दोडें १", + "run2": "दोडें २", + "searching": "बोम्ब-स्क्वाड के गेम को ढूँढा जा रहा है", + "searching_caption": "जुड़ने के लिए किसी गेम के नाम को दबाएँ | \nये ध्यान रखे कि आप भी उसी नेटवर्क पे हों जिस पे गेम चल रहा है |", + "start": "शुरू करें", + "version_mismatch": "संस्करण मेल नहीं खा रहे हैं | \nयह सुनिश्चित कर लें कि बोम्ब-स्क्वाड गेम और \nरिमोट पर नवीनतम संस्करण है और पुनः प्रयास करें |" + }, + "removeInGameAdsText": "${PRO} को भंडार में खरीदें गेम के बीच आने वाले एड्स को हटाने के लिए |", + "renameText": "नाम बदलें", + "replayEndText": "रीप्ले बंद करें", + "replayNameDefaultText": "आखिरी गेम का रीप्ले", + "replayReadErrorText": "रीप्ले फाइल को पढने में त्रुटी", + "replayRenameWarningText": "अगर आप \"${REPLAY}\" को रखना चाहते हैं तो उसका नाम बदल दें वरना उसे अगली बार मिटा दिया जाएगा |", + "replayVersionErrorText": "माफ़ करें, यह रीप्ले किसी और संस्करण में बना था \nइसलिए इसका प्रयोग नहीं किया जा सकता है", + "replayWatchText": "रीप्ले देखें", + "replayWriteErrorText": "रीप्ले को फाइल में लिखने में त्रुटी |", + "replaysText": "रीप्ले", + "reportPlayerExplanationText": "इस ईमेल का प्रयोग करके धोकाधड़ी या अनुचित शब्दों के प्रयोग या \nकिसी और चीज़ कि आख्या दें | कृपया निचे विवरण दीजिये :", + "reportThisPlayerCheatingText": "धोकाधड़ी", + "reportThisPlayerLanguageText": "अनुचित शब्दों का प्रयोग", + "reportThisPlayerReasonText": "आप इस खिलाडी कि आख्या करना चाहते हैं ?", + "reportThisPlayerText": "खिलाडी कि आख्या करें", + "requestingText": "अनुरोध किया जा रहा है...", + "restartText": "पुनः शुरू करें", + "retryText": "पुनः प्रयास करें", + "revertText": "पूर्व स्तिथि में लायें", + "runText": "दोडें", + "saveText": "सुरक्षित करें", + "scanScriptsErrorText": "स्क्रिप्ट्स को स्कैन करने में त्रुटि; विवरण के लिए लॉग देखें।", + "scoreChallengesText": "अंकों कि चुनौतियाँ", + "scoreListUnavailableText": "अंकों कि सूचि अभी उपस्थित नहीं है", + "scoreText": "अंक", + "scoreUnits": { + "millisecondsText": "मिलीसेकेंड", + "pointsText": "अंक", + "secondsText": "सेकंड" + }, + "scoreWasText": "(${COUNT} था)", + "selectText": "चुनें", + "seriesWinLine1PlayerText": "विजयी", + "seriesWinLine1TeamText": "विजयी", + "seriesWinLine1Text": "विजयी", + "seriesWinLine2Text": "शृंखला !", + "settingsWindow": { + "accountText": "खाता", + "advancedText": "उन्नत", + "audioText": "ध्वनि", + "controllersText": "नियंत्रक", + "graphicsText": "ग्राफिक्स", + "playerProfilesMovedText": "टिपण्णी: खिलाडी के पार्श्वचित्र को मुख्या मेनू में खिसका दिया गया है |", + "titleText": "सेटिंग" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(एक साधारण, नियंत्रक से आसानी इ प्रयोग हो जाने वाला कीबोर्ड)", + "alwaysUseInternalKeyboardText": "हमेशा गेम के कीबोर्ड का प्रयोग करें", + "benchmarksText": "बेंचमार्क व तनाव परीक्षण", + "disableCameraGyroscopeMotionText": "कैमरा गायरोस्कोप गतिवान बंद करे", + "disableCameraShakeText": "कैमरा की हलचल बंद करे", + "disableThisNotice": "(आप उन्नत सेटिंग में इस नोटिस को अक्षम कर सकते हैं)", + "enablePackageModsDescriptionText": "(अतिरिक्त परिवर्तन करने कि क्षमताएं देता है, लेकिन फिर आप नेट पर नहीं खेल सकते हैं)", + "enablePackageModsText": "स्थानीय परिवर्तनों को लागू करें", + "enterPromoCodeText": "कोड डालें", + "forTestingText": "टिपण्णी: यह संख्याएं सिर्फ परीक्षण के लिए हैं, और एप्लीकेशन के बंद होने पर खो जायेंगी |", + "helpTranslateText": "${APP_NAME} के अनुवाद एक सामुदायिक प्रयास का परिणाम हैं | \nअगर आप इसमें अपना योगदान देना चाहते हैं \nया कुछ ठीक करना चाहते हैं तो निचे दी गयी लिंक को देखें | धन्यवाद !", + "kickIdlePlayersText": "निष्क्रिय खिलाडियों को बाहर निकाल दें", + "kidFriendlyModeText": "बच्चों के अनुकूल करें (कम हिंसा, आदि)", + "languageText": "भाषा", + "moddingGuideText": "परिवर्तन करने कि गाइड", + "mustRestartText": "इसके लागू होने के लिए आपको गेम को पुनः शुरू करना पड़ेगा |", + "netTestingText": "नेटवर्क पर परीक्षण", + "resetText": "रीसेट", + "showBombTrajectoriesText": "बोम्ब का पथ दिखाएँ", + "showPlayerNamesText": "खिलाड़ी का नाम दिखाएँ", + "showUserModsText": "परिवर्तनों का फोल्डर दिखाएँ", + "titleText": "उन्नत", + "translationEditorButtonText": "${APP_NAME} अनुवाद संपादक", + "translationFetchErrorText": "अनुवाद कि स्तिथि अभी उपलब्ध नहीं है", + "translationFetchingStatusText": "अनुवाद कि स्तिथि का पता करा जा रहा है...", + "translationInformMe": "मुझे सूचित करें जब मेरी भाषा में अपडेट की आवश्यकता होती है", + "translationNoUpdateNeededText": "यह भाषा अद्यतन है !!", + "translationUpdateNeededText": "** इस भाषा का अद्यतन करने कि जरूरत है !! **", + "vrTestingText": "वी-आर परीक्षण" + }, + "shareText": "शेयर", + "sharingText": "शेयर कर रहे हैं...", + "showText": "दिखाएँ", + "signInForPromoCodeText": "कोड प्रभावी होने के लिए आपको किसी खाते में साइन इन करना होगा।", + "signInWithGameCenterText": "गेम केंद्र खाते का उपयोग करने के लिए, \nगेम सेंटर एप के साथ साइन इन करें।", + "singleGamePlaylistNameText": "केवल ${GAME}", + "singlePlayerCountText": "1 खिलाड़ी", + "soloNameFilterText": "अकेले ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "कैरेक्टर का चयन", + "Chosen One": "चुना हुआ", + "Epic": "उत्कृष्ट प्रकार के खेल", + "Epic Race": "उत्कृष्ट दौड़", + "FlagCatcher": "झंडे पर कब्जा", + "Flying": "सुखद कल्पना", + "Football": "फ़ुटबॉल", + "ForwardMarch": "आक्रमण", + "GrandRomp": "जय", + "Hockey": "हॉकी", + "Keep Away": "दूर रहो", + "Marching": "रनअराउंड़", + "Menu": "मुख्य मेनू", + "Onslaught": "हमला", + "Race": "दौड़", + "Scary": "पहाड़ी का राजा", + "Scores": "स्कोर स्क्रीन", + "Survival": "निकाल देना", + "ToTheDeath": "मौत का खेल", + "Victory": "अंतिम स्कोर स्क्रीन" + }, + "spaceKeyText": "स्पेस", + "statsText": "स्टैट्‍स", + "storagePermissionAccessText": "इसमें संग्रहण एक्सेस की आवश्यकता है", + "store": { + "alreadyOwnText": "आपके पास ${NAME} पहले से ही है!", + "bombSquadProNameText": "${APP_NAME} प्रो", + "bombSquadProNewDescriptionText": "• इन-गेम विज्ञापनों और नैग-स्क्रीन को निकाल देता है \n• अधिक गेम सेटिंग्स को खोलता है \n• यें भी शामिल है:", + "buyText": "खरीदें", + "charactersText": "पात्र", + "comingSoonText": "जल्द आ रहा है...", + "extrasText": "अतिरिक्त", + "freeBombSquadProText": "बम्ब्सक्वाड अब नि:शुल्क है, लेकिन जब से आपने मूल रूप से इसे खरीदा था \nतब आप हैं बम्ब्सक्वाड प्रो उन्नयन और ${COUNT} टिकट आपको धन्यवाद के रूप में दिए जा रहे हैं। \nनई सुविधाओं का आनंद लें, और अपने समर्थन के लिए धन्यवाद! \n-एरिक", + "holidaySpecialText": "छुट्टी विशेष", + "howToSwitchCharactersText": "(पात्र असाइन और कस्टमाइज़ करने के लिए जाएं \"${SETTINGS} -> ${PLAYER_PROFILES}\" पर)", + "howToUseIconsText": "(इन का उपयोग करने के लिए वैश्विक खिलाड़ी प्रोफाइल (खाता विंडो में) बनाएं)", + "howToUseMapsText": "(इन नक्शों का उपयोग अपनी खुद की टीमों/फ्री-फाॅर-आॅल प्लेलिस्टों में करें)", + "iconsText": "आइकनस", + "loadErrorText": "पृष्ठ लोड करने में असमर्थ। \nअपना इंटरनेट संपर्क जांचे।", + "loadingText": "लोड हो रहा है", + "mapsText": "नक्शे", + "miniGamesText": "छोटे खेल", + "oneTimeOnlyText": "(सिर्फ़ एक बार)", + "purchaseAlreadyInProgressText": "इस आइटम की खरीद पहले से ही प्रगति पर है।", + "purchaseConfirmText": "${ITEM} खरीदें?", + "purchaseNotValidError": "खरीद मान्य नहीं है। \nअगर यह एक त्रुटि है तो ${EMAIL} से संपर्क करें।", + "purchaseText": "खरीदें", + "saleBundleText": "बंडल बिक्री!", + "saleExclaimText": "छूट!", + "salePercentText": "(${PERCENT}% छूट)", + "saleText": "छूट", + "searchText": "खोजें", + "teamsFreeForAllGamesText": "टीमों / फ्री-फाॅर-आॅल खेल", + "totalWorthText": "*** ${TOTAL_WORTH} मूल्य! ***", + "upgradeQuestionText": "उन्नयन करें?", + "winterSpecialText": "शीतकालीन विशेष", + "youOwnThisText": "- आप इसके मालिक हो -" + }, + "storeDescriptionText": "8 खिलाड़ी पार्टी खेल पागलपन! \n\nकैप्चर-द-फ्लैग, बॉम्बर-हॉकी, और एपिक-स्लो-मोशन-डेथ-मैच जैसे विस्फोटक मिनी-गेम्स के टूर्नामेंट में अपने दोस्तों (या कंप्यूटर) को उड़ाएं! \n\nसरल नियंत्रण और व्यापक नियंत्रक समर्थन कार्रवाई पर 8 लोगों तक पहुंचना आसान बनाता है; आप अपने मोबाइल उपकरणों को मुफ्त 'BombSquad Remote' ऐप के माध्यम से नियंत्रकों के रूप में भी उपयोग कर सकते हैं! \n\nबॉम्ब्स अवे! \n\nअधिक जानकारी के लिए www.froemling.net/bombsquad देखें।", + "storeDescriptions": { + "blowUpYourFriendsText": "अपने दोस्तों को उड़ाएं।", + "competeInMiniGamesText": "रेसिंग से उड़ान तक लेकर मिनी-गेम में प्रतिस्पर्धा करें।", + "customize2Text": "पात्र, मिनी-गेम्स और ध्वनि तक को अपने अनुकूल करें।", + "customizeText": "पात्र को अनुकूल करें और अपनी खुद की मिनी-गेम प्लेलिस्ट बनाएं।", + "sportsMoreFunText": "विस्फोटकों के साथ खेल अधिक मज़ेदार हैं।", + "teamUpAgainstComputerText": "कंप्यूटर के खिलाफ टीम" + }, + "storeText": "दुकान", + "submitText": "जमा करें", + "submittingPromoCodeText": "संहिता जमा कर रहा है ...", + "teamNamesColorText": "टीम के नाम / रंग ...", + "telnetAccessGrantedText": "टेलनेट एक्सेस सक्षम है", + "telnetAccessText": "टेलनेट पहुंच का पता चला; अनुमति देते हैं?", + "testBuildErrorText": "यह परीक्षण बिल्ड अब सक्रिय नहीं है; कृपया एक नए संस्करण की जांच करें", + "testBuildText": "टेस्ट बिल्ड", + "testBuildValidateErrorText": "परीक्षण निर्माण मान्य करने में असमर्थ। (कोई शुद्ध कनेक्शन नहीं है?)", + "testBuildValidatedText": "परीक्षण निर्माण मान्य; आनंद लें!", + "thankYouText": "आपके सहयोग के लिए धन्यवाद! खेल का लुफ्त उठाओ!!", + "threeKillText": "तिहरा हत्या!!", + "timeBonusText": "समय बोनस", + "timeElapsedText": "समय बीता", + "timeExpiredText": "समय समाप्त", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "टिप", + "titleText": "बमस्क्वाड", + "titleVRText": "बमस्क्वाड व.र.", + "topFriendsText": "अच्छे दोस्त", + "tournamentCheckingStateText": "प्रतियोगिता की जांच हो रही है; कृपया प्रतीक्षा करें...", + "tournamentEndedText": "यह प्रतियोगिता समाप्त हो गया है। एक नया जल्द ही शुरू होगा।", + "tournamentEntryText": "प्रतियोगिता प्रवेश", + "tournamentResultsRecentText": "हालिया प्रतियोगिता परिणाम", + "tournamentStandingsText": "प्रतियोगिता स्टैंडिंग्स", + "tournamentText": "प्रतियोगिता", + "tournamentTimeExpiredText": "प्रतियोगिता समय समाप्त", + "tournamentsDisabledWorkspaceText": "कार्यस्थान सक्रिय होने पर टूर्नामेंट अक्षम हो जाते हैं।\nटूर्नामेंट को पुन: सक्षम करने के लिए, अपने कार्यक्षेत्र को अक्षम करें और पुनः आरंभ करें।", + "tournamentsText": "प्रतियोगिता", + "translations": { + "characterNames": { + "Agent Johnson": "एजेंट जॉनसन", + "B-9000": "बी-9000", + "Bernard": "बर्नार्ड", + "Bones": "हड्डि", + "Butch": "बुच", + "Easter Bunny": "ईस्टर बनी", + "Flopsy": "फ्लॉप्सी", + "Frosty": "फ्रॉस्टी", + "Gretel": "ग्रेटेल", + "Grumbledorf": "ग्रुम्बलडोर्फ़", + "Jack Morgan": "जैक मॉर्गन", + "Kronk": "क्रोंक", + "Lee": "ली", + "Lucky": "सौभाग्यशाली", + "Mel": "मेल", + "Middle-Man": "मध्य-व्यक्ति", + "Minimus": "कनिष्ठा", + "Pascal": "पास्कल", + "Pixel": "पिक्सेल", + "Sammy Slam": "सैमी स्लैम", + "Santa Claus": "सांता क्लॉज़", + "Snake Shadow": "सांप छाया", + "Spaz": "स्पॅज", + "Taobao Mascot": "ताओबाओ मास्कॉट", + "Todd McBurton": "टोड मैकबर्टन", + "Zoe": "झो", + "Zola": "ज़ोला" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} प्रशिक्षण", + "Infinite ${GAME}": "अनंत ${GAME}", + "Infinite Onslaught": "अनंत आक्रमण", + "Infinite Runaround": "अनंत भागम-भाग", + "Onslaught Training": "आक्रमण प्रशिक्षण", + "Pro ${GAME}": "उत्तम ${GAME}", + "Pro Football": "उत्तम फुटबॉल", + "Pro Onslaught": "उत्तम हमला", + "Pro Runaround": "उत्तम भागम-भाग", + "Rookie ${GAME}": "प्रथम ${GAME}", + "Rookie Football": "प्रथम फुटबॉल", + "Rookie Onslaught": "प्रथम हमला", + "The Last Stand": "एक अंतिम मोर्चा", + "Uber ${GAME}": "महा ${GAME}", + "Uber Football": "महा फुटबॉल", + "Uber Onslaught": "महा हमला", + "Uber Runaround": "महा रनराउंड" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "जीतने के लिए लंबे समय तक चुने गए व्यक्ति बनें। \nइसे चुनने के लिए चुने हुए को मार डालो।", + "Bomb as many targets as you can.": "जितना संभव हो उतने लक्ष्य पर बम मारें ।", + "Carry the flag for ${ARG1} seconds.": "${ARG1} सेकंड के लिए ध्वज पकड़ें", + "Carry the flag for a set length of time.": "समय की एक निश्चित लंबाई के लिए झंडा ले लो।", + "Crush ${ARG1} of your enemies.": "अपने ${ARG1} दुश्मनों को क्रश करें।", + "Defeat all enemies.": "सभी दुश्मनों को हराएं।", + "Dodge the falling bombs.": "गिरने वाले बम चकमा दें।", + "Final glorious epic slow motion battle to the death.": "मृत्यु के लिए अंतिम गौरवशाली महाकाव्य धीमी गति लड़ाई।", + "Gather eggs!": "अंडे इकट्ठा करो!", + "Get the flag to the enemy end zone.": "दुश्मन अंत क्षेत्र में ध्वज प्राप्त करें।", + "How fast can you defeat the ninjas?": "आप निंजा को कितनी तेजी से पराजित कर सकते हैं?", + "Kill a set number of enemies to win.": "जीतने के लिए दुश्मनों की एक निश्चित संख्या को मार डालो।", + "Last one standing wins.": "आखिरी खड़े की जीत", + "Last remaining alive wins.": "आखिरी शेष जीवित की जीत।", + "Last team standing wins.": "आखिरी टीम विजयी", + "Prevent enemies from reaching the exit.": "दुश्मनों को बाहर निकलने से रोकें।", + "Reach the enemy flag to score.": "स्कोर करने के लिए दुश्मन ध्वज तक पहुंचें।", + "Return the enemy flag to score.": "स्कोर करने के लिए दुश्मन ध्वज लौटें।", + "Run ${ARG1} laps.": "${ARG1} अंतराल दौड़ेँ", + "Run ${ARG1} laps. Your entire team has to finish.": "${ARG1} अंतराल दौड़ेँ। आपकी पूरी टीम को खत्म करना है।", + "Run 1 lap.": "1 अंतराल दौड़ो।", + "Run 1 lap. Your entire team has to finish.": "१ अंतराल दौड़ेँ। आपकी पूरी टीम को भी दौड़ना है।", + "Run real fast!": "असली तेजी से भागो!", + "Score ${ARG1} goals.": "${ARG1} गोल्स स्कोर करें।", + "Score ${ARG1} touchdowns.": "${ARG1} टचडाउन्स स्कोर करें।", + "Score a goal.": "एक गोल करो", + "Score a touchdown.": "एक टचडाउन स्कोर करें", + "Score some goals.": "कुछ स्कोर करें।", + "Secure all ${ARG1} flags.": "सभी ${ARG1} झंडे सुरक्षित करें।", + "Secure all flags on the map to win.": "जीतने के लिए मानचित्र पर सभी झंडे सुरक्षित करें।", + "Secure the flag for ${ARG1} seconds.": "${ARG1} सेकंड के लिए ध्वज सुरक्षित करें।", + "Secure the flag for a set length of time.": "समय की एक निश्चित लंबाई के लिए ध्वज सुरक्षित करें।", + "Steal the enemy flag ${ARG1} times.": "दुश्मन ध्वज ${ARG1} बार चुराओ।", + "Steal the enemy flag.": "दुश्मन का झंडा चोरी करो।", + "There can be only one.": "वहां केवल एक हो सकता है।", + "Touch the enemy flag ${ARG1} times.": "${ARG1} बार दुश्मन ध्वज स्पर्श करें।", + "Touch the enemy flag.": "दुश्मन का झंडा स्पर्श करें।", + "carry the flag for ${ARG1} seconds": "${ARG1} सेकंड के लिए ध्वज पकड़ें", + "kill ${ARG1} enemies": "${ARG1} दुश्मनों को मार डालो", + "last one standing wins": "आखिरी खड़े जीत", + "last team standing wins": "आखिरी टीम विजयी", + "return ${ARG1} flags": "${ARG1} झंडे वापस करें", + "return 1 flag": "1 झंडा वापस करें", + "run ${ARG1} laps": "${ARG1} अंतराल दौड़ेँ", + "run 1 lap": "1 अंतराल दौड़ो", + "score ${ARG1} goals": "${ARG1} गोल्स स्कोर करे।", + "score ${ARG1} touchdowns": "${ARG1} गोल्स स्कोर करें।", + "score a goal": "एक गोल करो", + "score a touchdown": "एक टचडाउन स्कोर करें", + "secure all ${ARG1} flags": "सभी ${ARG1} झंडे सुरक्षित करें", + "secure the flag for ${ARG1} seconds": "${ARG1} सेकंड के लिए ध्वज सुरक्षित करें", + "touch ${ARG1} flags": "${ARG1} झंडे स्पर्श करें", + "touch 1 flag": "1 ध्वज स्पर्श करें" + }, + "gameNames": { + "Assault": "आक्रमण", + "Capture the Flag": "झंडा कब्जा", + "Chosen One": "एक चुना हुआ", + "Conquest": "विजय", + "Death Match": "मौत का खेल", + "Easter Egg Hunt": "ईस्टर अंडा खोजना", + "Elimination": "निकाल देना", + "Football": "फ़ुटबॉल", + "Hockey": "हॉकी", + "Keep Away": "दूर रखना", + "King of the Hill": "पहाड़ी के राजा", + "Meteor Shower": "उल्का बौछार", + "Ninja Fight": "निंजा लड़ाई", + "Onslaught": "हमला", + "Race": "दौड़", + "Runaround": "चारो और दौड़ें", + "Target Practice": "लक्ष्य अभ्यास", + "The Last Stand": "अंतिम स्टैंड" + }, + "inputDeviceNames": { + "Keyboard": "कीबोर्ड", + "Keyboard P2": "कीबोर्ड प.२" + }, + "languages": { + "Arabic": "अरबी", + "Belarussian": "बेलारूसी", + "Chinese": "सरलीकृत चीनी", + "ChineseTraditional": "चीनी पारंपरिक", + "Croatian": "क्रोएशियाई", + "Czech": "चेक", + "Danish": "डेनिश", + "Dutch": "डच", + "English": "अंग्रेजी", + "Esperanto": "एस्पेरांतो", + "Filipino": "फिलिनो", + "Finnish": "फिनिश", + "French": "फ्रेंच", + "German": "जर्मन", + "Gibberish": "जिबरिश", + "Greek": "ग्रीक", + "Hindi": "हिंदी", + "Hungarian": "हंगेरी", + "Indonesian": "इन्डोनेशियाई", + "Italian": "इतालवी", + "Japanese": "जापानी", + "Korean": "कोरियाई", + "Persian": "फ़ारसी", + "Polish": "पोलिश", + "Portuguese": "पुर्तगाली", + "Romanian": "रोमानियाई", + "Russian": "रूसी", + "Serbian": "सर्बियाई", + "Slovak": "स्लोवाक", + "Spanish": "स्पेनिश", + "Swedish": "स्वीडिश", + "Tamil": "तामिल", + "Thai": "थाई", + "Turkish": "तुर्की", + "Ukrainian": "यूक्रेनी", + "Venetian": "वेनेशियन", + "Vietnamese": "वियतनामी" + }, + "leagueNames": { + "Bronze": "कांस्य", + "Diamond": "हीरक", + "Gold": "स्वर्ण", + "Silver": "रजत" + }, + "mapsNames": { + "Big G": "बड़ा जी", + "Bridgit": "ब्रिजिट", + "Courtyard": "आंगन", + "Crag Castle": "क्रैग कैसल", + "Doom Shroom": "डूम शोरूम", + "Football Stadium": "फ़ुटबॉल स्टेडियम", + "Happy Thoughts": "सुखद ख़याल", + "Hockey Stadium": "हॉकी स्टेडियम", + "Lake Frigid": "उदासीन झील", + "Monkey Face": "वानर मुख", + "Rampage": "हंगामा", + "Roundabout": "फेरदार", + "Step Right Up": "वर्धक सीढी", + "The Pad": "तकती", + "Tip Top": "सर्वोच्चता", + "Tower D": "डी मीनार", + "Zigzag": "टेढ़ा-मेढ़ा" + }, + "playlistNames": { + "Just Epic": "सिर्फ उत्कृष्ट", + "Just Sports": "सिर्फ्र खेल" + }, + "scoreNames": { + "Flags": "झण्डें", + "Goals": "लक्ष्य", + "Score": "स्कोर", + "Survived": "जीवित रह गए", + "Time": "समय", + "Time Held": "आयोजित समय" + }, + "serverResponses": { + "A code has already been used on this account.": "इस खाते पर एक कोड पहले से ही इस्तेमाल किया जा चुका है।", + "A reward has already been given for that address.": "उस पते के लिए एक इनाम पहले ही दिया जा चुका है।", + "Account linking successful!": "खाता का जुड़ाव सफल!", + "Account unlinking successful!": "खाता अलगाव सफल!", + "Accounts are already linked.": "खाते पहले ही जुड़े हुए हैं।", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "विज्ञापन दृश्य सत्यापित नहीं किया जा सका.\nकृपया सुनिश्चित करें कि आप गेम का आधिकारिक और अप-टू-डेट संस्करण चला रहे हैं।", + "An error has occurred; (${ERROR})": "एक गलती हुई है; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "एक गलती हुई है; कृपया समर्थन से संपर्क करें। (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "एक गलती हुई है; कृपया support@froemling.net से संपर्क करें।", + "An error has occurred; please try again later.": "एक गलती हुई है; बाद में पुन: प्रयास करें।", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "क्या आप वाकई इन खातों को जोड़ना चाहते हैं? \n\n${ACCOUNT1} \n${ACCOUNT2} \n\nइसे असंपादित नहीं किया जा सकता है!", + "BombSquad Pro unlocked!": "बमस्क्वाड प्रो खुला है!", + "Can't link 2 accounts of this type.": "इस प्रकार के २ खातों को लिंक नहीं कर सकता।", + "Can't link 2 diamond league accounts.": "२ डायमंड लीग खातों को लिंक नहीं कर सकता।", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "लिंक नहीं किआ जा सकता; अधिकतम ${COUNT} खातों का जुड़ाव पार होने की सम्भावना है।", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "धोखाधड़ी का पता चला; स्कोर और पुरस्कार ${COUNT} दिनों के लिए निलंबित कर दिए गए हैं।", + "Could not establish a secure connection.": "एक सुरक्षित कनेक्शन स्थापित नहीं कर सका।", + "Daily maximum reached.": "दैनिक अधिकतम पहुंच गया।", + "Entering tournament...": "टूर्नामेंट में प्रवेश ...", + "Invalid code.": "अमान्य कोड।", + "Invalid payment; purchase canceled.": "अमान्य भुगतान; खरीद रद्द।", + "Invalid promo code.": "अमान्य प्रोमो कोड।", + "Invalid purchase.": "अवैध खरीदी", + "Invalid tournament entry; score will be ignored.": "अवैध टूर्नामेंट प्रविष्टि; स्कोर को नजरअंदाज कर दिया जाएगा।", + "Item unlocked!": "सामग्री अनलॉक!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "जुड़ाव अस्वीकृत। ${ACCOUNT} में महत्वपूर्ण डेटा शामिल है \nजो सभी खो जाएंगे। यदि आप चाहते हैं \nतो आप विपरीत क्रम में लिंक कर सकते हैं \n(और इसके बजाय इस खाते का डेटा खो दें)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "इस खाते में ${ACCOUNT} खाता लिंक करें? \n${ACCOUNT} पर मौजूद सभी डेटा खो जाएंगे। \nइसे असंपादित नहीं किया जा सकता है। क्या आपको यकीन है?", + "Max number of playlists reached.": "प्लेलिस्ट की अधिकतम संख्या तक पहुंच गई।", + "Max number of profiles reached.": "प्रोफाइल की अधिकतम संख्या तक पहुंच गया।", + "Maximum friend code rewards reached.": "अधिकतम मित्र कोड पुरस्कार पहुंचे।", + "Message is too long.": "संदेश बहुत लंबा है।", + "No servers are available. Please try again soon.": "कोई सर्वर उपलब्ध नहीं हैं। कृपया शीघ्र ही पुन: प्रयास करें।", + "Profile \"${NAME}\" upgraded successfully.": "प्रोफाइल \"${NAME}\" सफलतापूर्वक अपग्रेड किया गया।", + "Profile could not be upgraded.": "प्रोफ़ाइल को अपग्रेड नहीं किया जा सका।", + "Purchase successful!": "खरीद सफल!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "साइन इन करने के लिए ${COUNT} टिकट प्राप्त हुए। \n${TOMORROW_COUNT} प्राप्त करने के लिए कल वापस आएं।", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "सर्वर कार्यक्षमता अब खेल के इस संस्करण में समर्थित नहीं है; \nकृपया एक नए संस्करण में अपडेट करें।", + "Sorry, there are no uses remaining on this code.": "क्षमा करें, इस कोड पर कोई उपयोग शेष नहीं है।", + "Sorry, this code has already been used.": "क्षमा करें, यह कोड पहले ही इस्तेमाल हो चुका है।", + "Sorry, this code has expired.": "क्षमा करें, यह कोड समाप्त हो गया है।", + "Sorry, this code only works for new accounts.": "क्षमा करें, यह कोड केवल नए खातों के लिए काम करता है।", + "Still searching for nearby servers; please try again soon.": "अभी भी आस-पास के सर्वर खोज रहे हैं; कृपया जल्द ही पुन: प्रयास करें।", + "Temporarily unavailable; please try again later.": "अस्थाई रूप से अनुपलब्ध; बाद में पुन: प्रयास करें।", + "The tournament ended before you finished.": "टूर्नामेंट समाप्त होने से पहले समाप्त हो गया।", + "This account cannot be unlinked for ${NUM} days.": "यह खाता ${NUM} दिनों के लिए अनलिंक नहीं किया जा सकता है।", + "This code cannot be used on the account that created it.": "इस कोड का उपयोग उस खाते पर नहीं किया जा सकता है जिसने इसे बनाया है।", + "This is currently unavailable; please try again later.": "यह अभी अनुपलब्ध है; कृपया बाद में पुन: प्रयास करें।", + "This requires version ${VERSION} or newer.": "इसके लिए संस्करण ${VERSION} या नए की आवश्यकता है।", + "Tournaments disabled due to rooted device.": "रूट डिवाइस के कारण टूर्नामेंट अक्षम", + "Tournaments require ${VERSION} or newer": "टूर्नामेंटों को ${VERSION} या नए की आवश्यकता होती है", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "इस खाते से ${ACCOUNT} अनलिंक करें? ${ACCOUNT} \nपर मौजूद सभी डेटा रीसेट हो जाएंगे। \n(कुछ मामलों में उपलब्धियों को छोड़कर)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "चेतावनी: आपके खाते के खिलाफ हैकिंग की शिकायतें जारी की गई हैं। \nहैकिंग के लिए पाए गए खातों पर प्रतिबंध लगा दिया जाएगा। कृपया ईमानदार से खेलें।", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "क्या आप अपने डिवाइस खाते को इस से लिंक करना चाहते हैं? \n\nआपका डिवाइस खाता ${ACCOUNT1} है \nयह खाता ${ACCOUNT2} है \n\nयह आपको अपनी मौजूदा प्रगति को रखने की अनुमति देगा। \nचेतावनी: इसे पूर्ववत नहीं किया जा सकता है", + "You already own this!": "आप पहले से ही इसे खरीद चुके है!", + "You can join in ${COUNT} seconds.": "आप ${COUNT} सेकंड में शामिल हो सकते हैं।", + "You don't have enough tickets for this!": "आपके पास इसके लिए पर्याप्त टिकट नहीं हैं!", + "You don't own that.": "आप उसका स्वामित्व नहीं रखते हैं।", + "You got ${COUNT} tickets!": "आपको ${COUNT} टिकट मिल गए हैं!", + "You got a ${ITEM}!": "आपको ${ITEM} मिला है!", + "You have been promoted to a new league; congratulations!": "आपको एक नए लीग में पदोन्नत किया गया है; बधाई!", + "You must update to a newer version of the app to do this.": "ऐसा करने के लिए आपको ऐप के एक नए संस्करण में अपडेट करना होगा।", + "You must update to the newest version of the game to do this.": "ऐसा करने के लिए आपको गेम के नवीनतम संस्करण में अपडेट करना होगा।", + "You must wait a few seconds before entering a new code.": "नया कोड दर्ज करने से पहले आपको कुछ सेकंड इंतजार करना होगा।", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "आपने पिछले टूर्नामेंट में #${RANK} रैंक किया था। खेलने के लिए शुक्रिया!", + "Your account was rejected. Are you signed in?": "आपका खाता अस्वीकृत कर दिया गया है। क्या आप हस्ताक्षरित हैं?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "खेल की आपकी प्रति संशोधित कर दी गई है। \nकृपया किसी भी बदलाव को वापस करें और पुनः प्रयास करें।", + "Your friend code was used by ${ACCOUNT}": "आपका मित्र कोड ${ACCOUNT} द्वारा उपयोग किया गया था" + }, + "settingNames": { + "1 Minute": "१ मिनट", + "1 Second": "१ सेकंड", + "10 Minutes": "१० मिनट", + "2 Minutes": "२ मिनट", + "2 Seconds": "२ सेकंड", + "20 Minutes": "२० मिनट", + "4 Seconds": "४ सेकंड", + "5 Minutes": "५ मिनटें", + "8 Seconds": "८ सेकंड", + "Allow Negative Scores": "नकारात्मक स्कोर की अनुमति दें", + "Balance Total Lives": "कुल जीवनों का संतुलन करें", + "Bomb Spawning": "बम की पैदावार", + "Chosen One Gets Gloves": "चुनिंदा को दस्ताना प्राप्त", + "Chosen One Gets Shield": "चुनिंदा को कवच प्राप्त", + "Chosen One Time": "एक चुनिंदा का समय", + "Enable Impact Bombs": "प्रभाव बम सक्षम करें", + "Enable Triple Bombs": "तिहरा बम सक्षम करें", + "Entire Team Must Finish": "पूरी टीम द्वारा पूर्ण होनी चाहिए", + "Epic Mode": "उत्कृष्ट प्रकार", + "Flag Idle Return Time": "झंडा निष्क्रिय का वापसी समय", + "Flag Touch Return Time": "फ्लैग स्पर्श का वापसी समय", + "Hold Time": "पकड़ रहने का समय", + "Kills to Win Per Player": "प्रति खिलाड़ी जीतने के लिए हत्या", + "Laps": "चक्कर", + "Lives Per Player": "प्रति खिलाड़ी जीवन", + "Long": "लम्बा", + "Longer": "अधिक लम्बा", + "Mine Spawning": "भूमिगत बम का अंतर", + "No Mines": "कोई भूमिगत बम नहीं", + "None": "कोई नहीं", + "Normal": "साधारण", + "Pro Mode": "प्रो प्रकार", + "Respawn Times": "पैदावार की अवधि", + "Score to Win": "जितने का अंक", + "Short": "लघु", + "Shorter": "अधिक लघु", + "Solo Mode": "एकल प्रकार", + "Target Count": "लक्ष्य संख्या", + "Time Limit": "समय अवधि" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} अयोग्य है क्योंकि ${PLAYER} ने छोड़ दिया।", + "Killing ${NAME} for skipping part of the track!": "रास्ते के कुछ भाग छोड़ने के लिए ${NAME} को मृत्यु दंड !", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "${NAME} को चेतावनी: टर्बो / बटन-अवांछनीयता आपको बाहर निकलता है।" + }, + "teamNames": { + "Bad Guys": "बुरे लोग", + "Blue": "नीला", + "Good Guys": "अच्छे लोग", + "Red": "लाल" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "एक परिपूर्ण समय से किआ गया दौड़-कूद-स्पिन-पंच एक ही बार में मार सकता है\nऔर आपको आपके दोस्तों से वह-वाही भी मिलती है।", + "Always remember to floss.": "हमेशा फ्लॉस करना याद रखें।", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "यादृच्छिक के बजाये अपने पसंदीदा नाम और भेष का उपयोग करके \nअपने और अपने दोस्तों के लिए प्लेयर प्रोफाइल बनाएं।", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "अभिशाप बक्से आपको एक टिकिंग टाइम बम में बदल देते हैं।\nइसका एकमात्र इलाज स्वास्थ्य पैक को जल्दी से पकड़ना है।", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "उनके दिक्खावट के अलावा, सभी पात्रों की क्षमता समान हैं,\nतो बस जो भी आप सबसे करीब मिलते हैं उसे चुनें।", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "उस ऊर्जा ढाल को पाकर खुदको एकदम से सुरक्षित मत समझो ; आप अभी भी एक चट्टान से फेंक जा सकते हैं।", + "Don't run all the time. Really. You will fall off cliffs.": "हर समय मत भागो। सचमे। आप चट्टानों से गिर जाओगे।", + "Don't spin for too long; you'll become dizzy and fall.": "बहुत लंबे समय तक स्पिन मत करो; आप चक्कर खाकर गिर जाओगे।", + "Hold any button to run. (Trigger buttons work well if you have them)": "दौड़ने के लिए कोई भी बटन दबाए रखें। (यदि आपके पास है तो ट्रिगर बटन अच्छी तरह से काम करते हैं)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "दौड़ने के लिए किसी भी बटन को दबाए रखें। आप स्थानों को तेजी से प्राप्त करेंगे\nलेकिन बहुत अच्छी तरह से नहीं मुड़ पाएंगे, तो चट्टानों ज़रा संभल कर ।", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "बर्फ बम बहुत शक्तिशाली नहीं हैं, लेकिन जो भी उसके चपेट में अत है जम जाता है, \nऔर मरने की स्तिथि में रह जाता है ।", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "अगर कोई आपको उठाता है, तो उन्हें मुक्का मारें और वे जाने देंगे।\nयह वास्तविक जीवन में भी काम करता है।", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "यदि आपके पास नियंत्रकों की कमी है, तो अपने मोबाइल उपकरणों पर '${REMOTE_APP_NAME}' ऐप ​​इंस्टॉल करें\nऔर उन्हें नियंत्रकों के रूप में उपयोग करने के लिए।", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "यदि आप चिपचिपा-बम के शिकार हो गए , तो चारों ओर कूदें और गोल-गोल घूमे। आप शायद\nबम को हिलाकर हटा सकेंगे, या यदि कुछ और नहीं तो आपके आखिरी क्षण मनोरंजन होंगे।", + "If you kill an enemy in one hit you get double points for it.": "यदि आप एक बार में दुश्मन को मार देते हैं तो आपको इसके लिए डबल अंक मिलते हैं।", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "यदि आप एक अभिशाप उठाते हैं, तो अस्तित्व के लिए आपकी एकमात्र आशा है\nअगले कुछ सेकंड में एक स्वास्थ्य पावरअप पाएं।", + "If you stay in one place, you're toast. Run and dodge to survive..": "यदि आप एक ही स्थान पर रहते हैं, तो आप एक टोस्ट की तरह जल जायेंगे। जीवित रहने के लिए भागो और चकमा दो..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "यदि आपके पास बहुत से खिलाड़ी आ रहे हैं और जा रहे हैं, तो सेटिंग्स के तहत 'ऑटो-किक-निष्क्रिय-प्लेयर्स' चालू करें\nयदि कोई भी गेम छोड़ना भूल जाता है।", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "यदि आपका डिवाइस बहुत गर्म हो जाता है या आप बैटरी पावर को संरक्षित करना चाहते हैं,\nसेटिंग-> ग्राफिक्स में \"विजुअल\" या \"रेज़ोल्यूशन\" को बंद करें", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "यदि आपका फ्रेमरेट चकाचौंध है, \nतो रेसोलुशन या खेल की ग्राफिक्स सेटिंग्स में दृश्य को बंद करने का प्रयास करें।", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "कैप्चर-द-फ्लैग में, आपका खुद का झंडा स्कोर करने के लिए आपके आधार पर होना चाहिए, यदि दूसरा\nटीम स्कोर करने वाली है, अपने ध्वज चोरी करना उन्हें रोकने का एक अच्छा तरीका हो सकता है।", + "In hockey, you'll maintain more speed if you turn gradually.": "हॉकी में, यदि आप धीरे-धीरे मुड़ते हैं तो आप अधिक गति बनाए रखेंगे।", + "It's easier to win with a friend or two helping.": "एक दोस्त या दो मदद के साथ जीतना आसान है।", + "Jump just as you're throwing to get bombs up to the highest levels.": "जैसे ही आप उच्चतम स्तर तक बम प्राप्त करने के लिए फेंक रहे हैं, कूदो।", + "Land-mines are a good way to stop speedy enemies.": "तेजी से दुश्मनों को रोकने के लिए भूमि-खान एक अच्छा तरीका है।", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "अन्य खिलाड़ियों सहित कई चीजों को उठाया और फेंक दिया जा सकता है। पटकना\nचट्टानों से आपके दुश्मन एक प्रभावी और भावनात्मक रूप से पूरा करने वाली रणनीति हो सकते हैं।", + "No, you can't get up on the ledge. You have to throw bombs.": "नहीं, आप किनारे पर नहीं उठ सकते हैं। आपको बम फेंकना है।", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "खिलाड़ी अधिकांश खेलों के बीच में शामिल हो सकते हैं और छोड़ सकते हैं,\nऔर आप फ्लाई पर नियंत्रकों को प्लग और अनप्लग भी कर सकते हैं", + "Practice using your momentum to throw bombs more accurately.": "बम फेंकने के लिए अपनी गति का उपयोग करके अधिक सटीक रूप से अभ्यास करें।", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "पंच आपके मुट्ठी तेजी से बढ़ रहे हैं, और अधिक नुकसान पहुंचाते हैं,\nइसलिए craz की तरह दौड़ना, कूदना और कताई करने का प्रयास करें", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "एक बम फेंकने से पहले आगे और पीछे भागो\nइसे 'whiplash' करने के लिए और इसे आगे फेंक दें।", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "दुश्मनों का एक समूह बाहर ले लो\nएक टीएनटी बॉक्स के पास एक बम की स्थापना।", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "सिर सबसे कमजोर क्षेत्र है, इसलिए एक चिपचिपा-बम\nनोगिन के लिए आम तौर पर गेम-ओवर का मतलब है", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "यह स्तर कभी खत्म नहीं होता है, लेकिन यहां एक उच्च स्कोर है\nआपको दुनिया भर में अनन्त सम्मान अर्जित करेगा।", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "फेंक ताकत आपके द्वारा धारित दिशा पर आधारित है।\nआप के सामने धीरे-धीरे कुछ टॉस करने के लिए, कोई दिशा न रखें।", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "साउंडट्रैक से थक गए? अपनी स्वयं की वस्तु से इसे प्रतिस्थापित करें!\nसेटिंग्स-> ऑडियो-> साउंडट्रैक देखें", + "Try 'Cooking off' bombs for a second or two before throwing them.": "उन्हें फेंकने से पहले एक या दो के लिए 'पाक कला बंद' बम आज़माएं।", + "Try tricking enemies into killing eachother or running off cliffs.": "एक दूसरे को मारने या चट्टानों से भागने में दुश्मनों को धोखा देने का प्रयास करें।", + "Use the pick-up button to grab the flag < ${PICKUP} >": "ध्वज <${PICKUP}> को पकड़ने के लिए पिक-अप बटन का उपयोग करें", + "Whip back and forth to get more distance on your throws..": "अपने फेंकने पर अधिक दूरी पाने के लिए आगे और पीछे चाबुक करें ..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "आप बाएं या दाएं कताई करके अपने पेंच 'लक्ष्य' कर सकते हैं।\nबुजुर्गों को किनारों से बाहर करने या हॉकी में स्कोर करने के लिए यह उपयोगी है।", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "जब आप एक बम विस्फोट करने जा रहे हैं तो आप न्याय कर सकते हैं\nअपने फ्यूज से स्पार्क्स का रंग: पीला..रेंज..रेड..बॉम।", + "You can throw bombs higher if you jump just before throwing.": "यदि आप फेंकने से पहले कूदते हैं तो आप बम को अधिक फेंक सकते हैं।", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "जब आप चीजों पर अपना सिर फटकारते हैं तो आप नुकसान लेते हैं,\nतो चीजों पर अपने सिर को मारने की कोशिश मत करो।", + "Your punches do much more damage if you are running or spinning.": "यदि आप दौड़ रहे हैं या चक्रण कर रहे हैं तो आपके मुक्के अधिक नुकसान करते हैं।" + } + }, + "trophiesRequiredText": "इसके लिए कम से कम ${NUMBER} वैजयन्तीयों की आवश्यकता होती है।", + "trophiesText": "वैजयन्तीयां", + "trophiesThisSeasonText": "इस सीज़न की वैजयन्तीयां", + "tutorial": { + "cpuBenchmarkText": "ऊटपटांग-गति पर शिक्षण चलाना (मुख्य रूप से सीपीयू की गति का परीक्षण करता है)", + "phrase01Text": "नमस्ते!", + "phrase02Text": "${APP_NAME} में आपका स्वागत है!", + "phrase03Text": "अपने पात्र को नियंत्रित करने के लिए यहां कुछ युक्तियां दी गई हैं:", + "phrase04Text": "${APP_NAME} में कई चीजें भौतिक विज्ञान पर आधारित हैं।", + "phrase05Text": "उदाहरण के लिए, जब आप मुक्के मारते हैं,..", + "phrase06Text": "..क्षति आपके मुट्ठी की गति पर आधारित है।", + "phrase07Text": "देखा? हम एक ही जगह पर थे, जिससे मुश्किल से ${NAME} को चोट पहुंची।", + "phrase08Text": "अब कूदो और अधिक गति पाने के लिए घूमो ।", + "phrase09Text": "वाह! यह बेहतर है।", + "phrase10Text": "दौड़ना से भी मदद मिलती है।", + "phrase11Text": "दौड़ने के लिए किसी भी को बटन दबाए रखें।", + "phrase12Text": "अतिरिक्त-विस्मयकारी मुक्के के लिए, दौड़कर घूमने का प्रयास करें।", + "phrase13Text": "ओह, इसके लिए क्षमा करें '${NAME}।", + "phrase14Text": "झंडे जैसे चीजों को आप उठा सकते हैं और फेंक सकते हैं .. और ${NAME} को भी ।", + "phrase15Text": "अंत में, बम।", + "phrase16Text": "बम फेंकने के लिए अभ्यास की आवश्यकता है।", + "phrase17Text": "आउच! बहुत अच्छा फेंक नहीं है।", + "phrase18Text": "विचलन से आपको आगे फेंकने में मदद मिलती है।", + "phrase19Text": "कूदकर आप बम को ऊँचा फेंक सकते हैं।", + "phrase20Text": "ज़्यादा दूर फेकने के लिए बम को \"घुमा\" कर फेकें।", + "phrase21Text": "अपने बमों का समय निर्धारित करना मुश्किल हो सकता है।", + "phrase22Text": "फुस्स...!", + "phrase23Text": "एक या दो सेकंड के लिए सुतली को \"जलने\" देने का प्रयास करें।", + "phrase24Text": "हुर्रे! अच्छी तरह से जला है।", + "phrase25Text": "खैर, इसके बारे में बस इतना ही ।", + "phrase26Text": "अब जाओ शेर, उसका शिकार करलो ।", + "phrase27Text": "अपना प्रशिक्षण याद रखें, और आप जीवित वापस आ जाएंगे!", + "phrase28Text": "...शायद, नहीं भी...", + "phrase29Text": "शुभकामनाएँ", + "randomName1Text": "किशोर", + "randomName2Text": "हरी", + "randomName3Text": "यश", + "randomName4Text": "ख्याति", + "randomName5Text": "कल्याण", + "skipConfirmText": "सच में ट्यूटोरियल छोड़ना चाहते हैं? पुष्टि करने के लिए स्पर्श करें या दबाएं।", + "skipVoteCountText": "${COUNT}/${TOTAL} मतदान छोड़ना", + "skippingText": "शिक्षण छोड़ा जा रहा है...", + "toSkipPressAnythingText": "(शिक्षण छोड़ने के लिए कुछ भी स्पर्श करे या दबाएं)" + }, + "twoKillText": "दोहरी हत्या", + "unavailableText": "उपलब्ध नहीं", + "unconfiguredControllerDetectedText": "बिना विन्यास वाले नियंत्रक का पता चला:", + "unlockThisInTheStoreText": "यह स्टोर में अनलॉक होना चाहिए।", + "unlockThisProfilesText": "${NUM} प्रोफ़ाइल बनाने के लिए, आपको इसकी आवश्यकता है:", + "unlockThisText": "इसे अनलॉक करने के लिए, आपको इसकी आवश्यकता है:", + "unsupportedHardwareText": "क्षमा करें, यह हार्डवेयर गेम के इस निर्माण द्वारा समर्थित नहीं है।", + "upFirstText": "सर्व प्रथम", + "upNextText": "गेम ${COUNT} में अगला:", + "updatingAccountText": "आपका खाता \nअद्यतन हो रहा है ...", + "upgradeText": "अभ्युत्थान", + "upgradeToPlayText": "इन-गेम स्टोर में इसे चलाने के लिए \"${PRO}\" अनलॉक करें।", + "useDefaultText": "पूर्व निर्धारित उपयोग करें", + "usesExternalControllerText": "यह गेम इनपुट के लिए बाहरी नियंत्रक का उपयोग करता है।", + "usingItunesText": "गाने के लिए संगीत ऐप का उपयोग कर रहे है ...", + "v2AccountLinkingInfoText": "V2 खातों को लिंक करने के लिए, 'खाता प्रबंधित करें' बटन का उपयोग करें।", + "validatingTestBuildText": "परीक्षण निर्माण मान्य ...", + "victoryText": "विजय!", + "voteDelayText": "आप ${NUMBER} सेकंड के लिए एक और वोट शुरू नहीं कर सकते हैं", + "voteInProgressText": "एक वोट पहले ही प्रगति पर है।", + "votedAlreadyText": "तुमने पहले ही मतदान कर दिया", + "votesNeededText": "${NUMBER} वोटों की आवश्यकता है", + "vsText": "बनाम", + "waitingForHostText": "(जारी रखने के लिए ${HOST} की प्रतीक्षा कर रहा है)", + "waitingForPlayersText": "प्लेयर्स के जुड़ने की प्रतीक्षा करे।", + "waitingInLineText": "लाइन में प्रतीक्षा (पार्टी पूर्ण है) ...", + "watchAVideoText": "वीडियो देखो", + "watchAnAdText": "एक विज्ञापन देखें", + "watchWindow": { + "deleteConfirmText": "\"${REPLAY}\" हटाएं?", + "deleteReplayButtonText": "रीप्ले \nहटाएं", + "myReplaysText": "मेरा रीप्ले", + "noReplaySelectedErrorText": "कोई रीप्ले चयनित नहीं है", + "playbackSpeedText": "रीप्ले की गति", + "renameReplayButtonText": "रीप्ले का \nपुनः नामकारन", + "renameReplayText": "\"${REPLAY}\" का नाम बदलें।", + "renameText": "नाम बदलूँ", + "replayDeleteErrorText": "रीप्ले हटाने में त्रुटि", + "replayNameText": "रीप्ले का नाम", + "replayRenameErrorAlreadyExistsText": "उस नाम के साथ एक रीप्ले पहले से मौजूद है।", + "replayRenameErrorInvalidName": "रीप्ले का नाम बदल नहीं सकते; गलत नाम।", + "replayRenameErrorText": "रीप्ले का नाम बदलने में त्रुटि।", + "sharedReplaysText": "साझा रीप्ले", + "titleText": "देखें", + "watchReplayButtonText": "रीप्ले \nदेखें" + }, + "waveText": "लहर", + "wellSureText": "हाँ ज़रूर !", + "whatIsThisText": "यह क्या है?", + "wiimoteLicenseWindow": { + "titleText": "डार्विन रिमोट कॉपीराइट" + }, + "wiimoteListenWindow": { + "listeningText": "Wiimotes के लिए सुन रहा है ...", + "pressText": "एक साथ Wiimote बटन 1 और 2 दबाएं।", + "pressText2": "मोशन प्लस के साथ निर्मित नए वाईमोट्स पर, इसके बजाय लाल 'सिंक' बटन दबाएं।" + }, + "wiimoteSetupWindow": { + "copyrightText": "डार्विनरिमोट कॉपीराइट", + "listenText": "सुनें", + "macInstructionsText": "सुनिश्चित करें कि आपके मैक पर वाईआई बंद है और ब्लूटूथ सक्षम है, \nफिर 'Listen' दबाएं। विमोट सम्रथन थोड़ा सा चंचल हो सकता है, \nतो कनेक्शन मिलने से पहले आपको कुछ \nबार कोशिश करनी पड़ सकती है। \n\nब्लूटूथ ७ कनेक्टेड डिवाइसों को संभालना चाहिए, \nहालांकि आपका माइलेज भिन्न हो सकता है। \n\nबमस्क्वाड मूल विमोट, ननचक्स और पारम्परिक \nनियंत्रक का समर्थन करता है। \nनया वाईआई रिमोट प्लस अब भी काम करता है \nलेकिन संलग्नक के साथ नहीं।", + "thanksText": "इसे संभव बनाने के लिए \nDarwiinRemote को धन्यवाद।", + "titleText": "विमोट सेटअप" + }, + "winsPlayerText": "${NAME} विजयी!", + "winsTeamText": "${NAME} विजयी!", + "winsText": "${NAME} विजयी!", + "workspaceSyncErrorText": "${WORKSPACE} सिंक में त्रुटि। विवरण के लिए लॉग देखें।", + "workspaceSyncReuseText": "${WORKSPACE} सिंक करने में असमर्थ। पिछले समन्वयित संस्करण का पुन: उपयोग होगा।", + "worldScoresUnavailableText": "वैश्विक अंक उपलब्ध नहीं", + "worldsBestScoresText": "जागतिक सर्वोत्तम स्कोर्स", + "worldsBestTimesText": "विश्व का सबसे अधिक समय", + "xbox360ControllersWindow": { + "getDriverText": "ड्राइवर प्राप्त करें।", + "macInstructions2Text": "", + "macInstructionsText": "Xbox 360 नियंत्रकों का उपयोग करने के लिए, \nआपको इंस्टॉल करने की आवश्यकता होगी मैक ड्राइवर नीचे दिए गए लिंक पर उपलब्ध है। \nयह वायर्ड और वायरलेस नियंत्रकों दोनों के साथ काम करता है।", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "BombSquad के साथ वायर्ड Xbox 360 नियंत्रकों का उपयोग करने के लिए, \nबस उन्हें अपने डिवाइस के यूएसबी पोर्ट में प्लग करें। \nएकाधिक नियंत्रकों को जोड़ने के लिए आप एक यूएसबी हब का उपयोग कर सकते हैं । \n\nवायरलेस नियंत्रकों का उपयोग करने के लिए आपको एक वायरलेस रिसीवर की आवश्यकता होगी, \n\"विंडोज़ के लिए Xbox 360 वायरलेस नियंत्रक\" के हिस्से के रूप में उपलब्ध पैकेज या अलग से बेचा गया। \nप्रत्येक रिसीवर यूएसबी पोर्ट में प्लग करता है \nऔर आपको 4 वायरलेस नियंत्रकों तक कनेक्ट करने की अनुमति देता है।", + "titleText": "${APP_NAME}:के साथ Xbox 360 नियंत्रकों का उपयोग करना" + }, + "yesAllowText": "हाँ, आज्ञा दें", + "yourBestScoresText": "आपका बेस्ट स्कोर।", + "yourBestTimesText": "आपका सर्वोत्तम समय" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/hungarian.json b/dist/ba_data/data/languages/hungarian.json new file mode 100644 index 0000000..769c7ed --- /dev/null +++ b/dist/ba_data/data/languages/hungarian.json @@ -0,0 +1,1892 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "A fiók neve nem tartalmazhat emojikat és más speciális karaktereket", + "accountProfileText": "(Felhasználó profilok)", + "accountsText": "Fiókok", + "achievementProgressText": "Eredmènyek: ${COUNT} a(z) ${TOTAL}-ból/ből.", + "campaignProgressText": "Kampány haladás(nehéz mód): ${PROGRESS}", + "changeOncePerSeason": "Ebben a szezonban ezt csak egyszer változtathatod meg.", + "changeOncePerSeasonError": "Várj a következő szezonig, hogy ezt megint megváltoztasd (${NUM} nap)", + "customName": "Egyedi név", + "deviceSpecificAccountText": "Csak erről az eszközről lehet elérni ezt a profilt: ${NAME}", + "linkAccountsEnterCodeText": "Írd Be A Kódot", + "linkAccountsGenerateCodeText": "Kód Generálása", + "linkAccountsInfoText": "(vidd át előrehaladásodat akár több eszközre is)", + "linkAccountsInstructionsNewText": "Két fiók összekapcsolásához először hozzon létre egy kódot\nés írja be a második kódot. Adatok a\na második számlát majd megosztják egymással.\n(Az első fiókból származó adatok elveszhetnek)\n\nÖsszesen akár ${COUNT} fiókot is összekapcsolhat.\n\nFONTOS: csak az Ön tulajdonában lévő fiókokat kapcsolja össze;\nHa kapcsolatba lépsz a barátok fiókjaival, akkor nem fogsz\negyszerre tud online játszani.", + "linkAccountsInstructionsText": "Hogy párosíts két profilt, generálj egy kódot\naz egyiken majd írd be a kapott kódot a másikon.\nAz előrehaladás és a megvásárolt dolgok is párosításra kerülnek .\nÖsszesen ${COUNT} profilt tudsz összehangolni.\n\nFONTOS:Csak olyan profilt csatlakoztass ami a tiéd!\nHogyha profilt csatlakoztatsz a barátaiddal\nakkor nem fogsz tudni játszani azonos időben!\n\nLégy óvatos!Ezt a lépést nem lehet visszavonni!", + "linkAccountsText": "Profilok Párosítása", + "linkedAccountsText": "Párosított Profilok:", + "manageAccountText": "Fiók szerkesztése", + "nameChangeConfirm": "Megváltoztatod a fiókod nevét erre: ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Ez visszaállítja a co-op haladásodat és \nhelyi legmagasabb pontszámaidat (de a jegyeidet nem). \nEz nem vissza vonható. Biztos vagy benne?", + "resetProgressConfirmText": "Ez visszaállítja a co-op haladásodat,\nteljesítményeidet és helyi legmagasabb pontszámaidat\n(de a jegyeidet nem). Ez nem vissza vonható.\nBiztos vagy benne?", + "resetProgressText": "Haladás visszaállítása", + "setAccountName": "Állítsa be a fiók nevét", + "setAccountNameDesc": "Válassza ki a megjeleníteni kívánt fiók nevét.\nHasználhatja a nevét az egyik kapcsoltól\nfiókokat, vagy egyedi egyedi nevet hozhat létre.", + "signInInfoText": "Lépj be, hogy tudj jegyeket gyűjteni, online versenyezni\nés elérni az eredményeidet akár több eszközről is.", + "signInText": "Bejelentkezés", + "signInWithDeviceInfoText": "(Autómatikus fiók csak ezen az eszközön elérhető)", + "signInWithDeviceText": "Bejelentkezés az eszköz felhasználójával.", + "signInWithGameCircleText": "Lépj be a Game Circle fiókodba", + "signInWithGooglePlayText": "Belépés Google fiókkal", + "signInWithTestAccountInfoText": "(Egy régi típusú felhasználó; Mostantól a készülék felhasználóját használd.)", + "signInWithTestAccountText": "Bejelentkezés teszt felhasználóval", + "signInWithV2InfoText": "(egy fiók, amely minden platformon működik)", + "signInWithV2Text": "Jelentkezzen be BombSquad fiókkal", + "signOutText": "Kijelentkezés", + "signingInText": "Bejelentkezés...", + "signingOutText": "Kijelentkezés...", + "testAccountWarningCardboardText": "Vigyázat:egy \"teszt\" fiókkal lépsz be.\nEzek helyettesítve lesznek egy Google\nfiókkal, amint támogatottá válnak.\n\nMost minden jegyet meg kell szerezned a játékban.\n(viszont megkapod a BombSquad Pro-t ingyen)", + "testAccountWarningOculusText": "Figyelmeztetés: egy \"teszt\" felhasználóval jelentkezel be.\nEz \"valós\" felhasználókkal lesz helyettesítve később\nidén ami jegyek és egyéb jellemzők vásárlását fogja ajánlani.\n\nEgyenlőre minden jegyet játékon belül kell megszerezned.\n(Viszont, ha megteszed, ingyen megkaphatod a BombSquad Pro frissítést)", + "testAccountWarningText": "Figyelmeztetés: egy \"teszt\" felhasználóval jelentkezel be.\nEz a felhasználó ehez az egy telefonhoz van kötve és\nlehet időnként visszaáll. (Tehát kérjük ne tölts\nsok időt a cuccok gyüjtésével/felnyitásával)\n\nFuss egy kereskedelmi verziót a játékból, hogy egy \"valós\" \nfelhasználót használj (Game-Center, Google Plus, stb.)\nEz engedi a haladások tárolását a felhőben és megosztását\nmás eszközök közt is.\n", + "ticketsText": "Jegyek: ${COUNT}", + "titleText": "Felhasználó", + "unlinkAccountsInstructionsText": "Válassz ki egy fiókot a leválasztáshoz", + "unlinkAccountsText": "Fiókok leválasztása", + "v2LinkInstructionsText": "Használja ezt a linket fiók létrehozásához vagy bejelentkezéshez.", + "viaAccount": "(számlán keresztül ${NAME})", + "youAreSignedInAsText": "Be vagy jelentkezve, mint:" + }, + "achievementChallengesText": "Teljesítmény kihívások", + "achievementText": "Teljesítmény", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Ölj meg 3 rosszfiút TNT-vel", + "descriptionComplete": "Megöltél 3 rosszfiút TNT-vel", + "descriptionFull": "Ölj meg 3 rosszfiút TNT-vel a(z) ${LEVEL}-n", + "descriptionFullComplete": "Megöltél 3 rosszfiút TNT-vel a(z) ${LEVEL}-n", + "name": "Bumm Megy a Dinamit" + }, + "Boxer": { + "description": "Nyerj bombák használata nélkül", + "descriptionComplete": "Bombák használata nélkül nyertél", + "descriptionFull": "Teljesítsd a(z) ${LEVEL} szintet bombák használata nélkül", + "descriptionFullComplete": "Teljesítetteda a(z) ${LEVEL} szintet bombák használata nélkül", + "name": "Boxoló" + }, + "Dual Wielding": { + "descriptionFull": "Csatlakoztass 2 kontrollert(hardvert vagy applikáció)", + "descriptionFullComplete": "2 kontroller csatlakoztatva (hardver vagy applikáció)", + "name": "Dupla Hadonászás" + }, + "Flawless Victory": { + "description": "Nyerj anélkül hogy megütnének", + "descriptionComplete": "Nyertél anélkül hogy megütöttek volna", + "descriptionFull": "Nyerj a(z) ${LEVEL} pályán anélkül, hogy megütnének", + "descriptionFullComplete": "Nyertél a(z) ${LEVEL} pályán anélkül hogy megütöttek volna", + "name": "Csodálatos győzelem" + }, + "Free Loader": { + "descriptionFull": "Kezdj el egy mindenki mindenki ellen meccset több mint 2 játékossal", + "descriptionFullComplete": "Egy mindenki mindenki ellen meccs elkezdve több mint 2 játékossal", + "name": "A Vezető" + }, + "Gold Miner": { + "description": "Ölj meg 6 rosszfiút taposóaknákkal", + "descriptionComplete": "Megöltél 6 rosszfiút taposóaknákkal", + "descriptionFull": "Ölj meg 6 rosszfiút taposóaknákkal a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Megöltél 6 rosszfiút taposóaknákkal a(z) ${LEVEL} pályán", + "name": "Aranyásó" + }, + "Got the Moves": { + "description": "Nyerj anélkül, hogy ütéseket vagy bombákat alkalmaznál", + "descriptionComplete": "Nyertél anélkül, hogy ütéseket vagy bombákat alkalmaztál volna", + "descriptionFull": "Nyerj a(z) ${LEVEL} pályán anélkül, hogy ütéseket vagy bombákat alkalmaznál", + "descriptionFullComplete": "Nyertél a(z) ${LEVEL}-n anélkül, hogy ütéseket vagy bombákat alkalmaztál volna", + "name": "Megvan a mozgás" + }, + "In Control": { + "descriptionFull": "Csatlakoztass egy kontrollert (hardver vagy applikáció)", + "descriptionFullComplete": "Egy kontrollert csatlakoztatva (hardver vagy applikáció)", + "name": "Kontrollálva" + }, + "Last Stand God": { + "description": "Szerezz 1000 pontot", + "descriptionComplete": "Szereztél 1000 pontot", + "descriptionFull": "Szerezz 1000 pontot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Szereztél 1000 pontot a(z) ${LEVEL}-n", + "name": "${LEVEL} Isten" + }, + "Last Stand Master": { + "description": "Szerezz 250 pontot", + "descriptionComplete": "Szereztél 250 pontot", + "descriptionFull": "Szerezz 250 pontot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Szereztél 250 pontot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Mester" + }, + "Last Stand Wizard": { + "description": "Szerezz 500 pontot", + "descriptionComplete": "Szereztél 500 pontot", + "descriptionFull": "Szerezz 500 pontot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Szereztél 500 pontot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Varázsló" + }, + "Mine Games": { + "description": "Ölj meg 3 rosszfiút taposóaknákkal", + "descriptionComplete": "Megöltél 3 rosszfiút taposóaknákkal", + "descriptionFull": "Ölj meg 3 rosszfiút taposóaknákkal a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Megöltél 3 rosszfiút taposóaknákkal a(z) ${LEVEL} pályán", + "name": "Akna Játékok" + }, + "Off You Go Then": { + "description": "Lökj ki 3 rosszfiút a pályáról", + "descriptionComplete": "Kilöktél 3 rosszfiút a pályáról", + "descriptionFull": "Lökj ki 3 rosszfiút a pályáról a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Kilöktél 3 rosszfiút a pályáról a(z) ${LEVEL} pályán", + "name": "Kifele mész majd" + }, + "Onslaught God": { + "description": "Szerezz 5000 pontot", + "descriptionComplete": "Szereztél 5000 pontot", + "descriptionFull": "Szerezz 5000 pontot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Szereztél 5000 pontot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Isten" + }, + "Onslaught Master": { + "description": "Szerezz 500 pontot", + "descriptionComplete": "Szereztél 500 pontot", + "descriptionFull": "Szerezz 500 pontot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Szereztél 500 pontot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Mester" + }, + "Onslaught Training Victory": { + "description": "Győzz le minden hullámot", + "descriptionComplete": "Minden hullámot legyőztél", + "descriptionFull": "Győzz le minden hullámot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Legyőztél minden hullámot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Győzelem" + }, + "Onslaught Wizard": { + "description": "Szerezz 1000 pontot", + "descriptionComplete": "Szereztél 1000 pontot", + "descriptionFull": "Szerezz 1000 pontot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Szereztél 1000 pontot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Varázsló" + }, + "Precision Bombing": { + "description": "Nyerj mindenféle erőnövelő nélkül", + "descriptionComplete": "Nyertél mindenféle erőnövelő nélkül", + "descriptionFull": "Nyerj a(z) ${LEVEL}-n mindenféle erőnövelő nélkül", + "descriptionFullComplete": "Nyertél a(z) ${LEVEL}-n mindenféle erőnövelő nélkül", + "name": "Precíziós Bombák" + }, + "Pro Boxer": { + "description": "Nyerj bombák használata nélkül", + "descriptionComplete": "Bombák használata nélkül nyertél", + "descriptionFull": "Teljesítsd a(z) ${LEVEL} pályát bombák használata nélkül", + "descriptionFullComplete": "Teljesítetted a(z) ${LEVEL}-t bombák használata nélkül", + "name": "Profi Boxoló" + }, + "Pro Football Shutout": { + "description": "Nyerj anélkül hogy a rosszfiúk pontot szerezzenek.", + "descriptionComplete": "Nyertél anélkül hogy a rosszfiúk pontot szereztek volna", + "descriptionFull": "Nyerd meg a(z) ${LEVEL} pályát anélkül, hogy a rosszfiúk pontot szereznének", + "descriptionFullComplete": "Megnyerted a(z) ${LEVEL} pályát anélkül, hogy a rosszfiúk pontot szereztek volna", + "name": "${LEVEL} Kirekesztve" + }, + "Pro Football Victory": { + "description": "Nyerd meg a játékot", + "descriptionComplete": "Megnyerted a játékot", + "descriptionFull": "Nyerdmeg a játékot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Megnyerted a játékot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Győzelem" + }, + "Pro Onslaught Victory": { + "description": "Győzz le minden hullámot", + "descriptionComplete": "Minden hullámot túléltél!", + "descriptionFull": "Győzz le minden hullámot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Legyőztél minden hullámot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Győzelem" + }, + "Pro Runaround Victory": { + "description": "Teljesítsd az összes hullámot", + "descriptionComplete": "Összes hullám teljesítve", + "descriptionFull": "Teljesítsd az összes hullámot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Teljesítetted az összes hullámot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Győzelem" + }, + "Rookie Football Shutout": { + "description": "Nyerj anélkül, hogy hagynád a rosszfiúkat pontot szerezni", + "descriptionComplete": "Nyertél anélkül, hogy a rosszfiúk pontot szereztek volna", + "descriptionFull": "Nyerj a(z) ${LEVEL}-n anélkül, hogy hagynád a rosszfiúkat pontot szerezni", + "descriptionFullComplete": "Megnyerted a ${LEVEL} pályát, anélkül, hogy a rosszfiúk pontot szereztek volna", + "name": "${LEVEL} Kirekesztve" + }, + "Rookie Football Victory": { + "description": "Nyerd meg a játékot", + "descriptionComplete": "Játék megnyerve", + "descriptionFull": "Nyerd meg a ${LEVEL} pályát", + "descriptionFullComplete": "${LEVEL} pálya megnyerve", + "name": "${LEVEL} Győzelem" + }, + "Rookie Onslaught Victory": { + "description": "Győzz le minden hullámot", + "descriptionComplete": "Minden hullámot túléltél!", + "descriptionFull": "Győzz le minden hullámot a(z) ${LEVEL}-ban/ben", + "descriptionFullComplete": "Legyőztél minden hullámot a(z) ${LEVEL}-ban/ben", + "name": "${LEVEL} Győzelem" + }, + "Runaround God": { + "description": "Szerezz 2000 pontot", + "descriptionComplete": "Szereztél 2000 pontot", + "descriptionFull": "Szerezz 2000 pontot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Szereztél 2000 pontot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Isten" + }, + "Runaround Master": { + "description": "Szerezz 500 pontot", + "descriptionComplete": "Szereztél 500 pontot", + "descriptionFull": "Szerezz 500 pontot a ${LEVEL} pályán", + "descriptionFullComplete": "Szereztél 500 pontot a ${LEVEL} pályán", + "name": "${LEVEL} Mester" + }, + "Runaround Wizard": { + "description": "Szerezz 1000 pontot", + "descriptionComplete": "Szereztél 1000 pontot", + "descriptionFull": "Szerezz 1000 pontot a(z) ${LEVEL} pályán", + "descriptionFullComplete": "Szereztél 1000 pontot a(z) ${LEVEL} pályán", + "name": "${LEVEL} Varázsló" + }, + "Sharing is Caring": { + "descriptionFull": "Oszd meg a játékot egy barátoddal", + "descriptionFullComplete": "A játék sikeresen megosztva egy baráttal", + "name": "Oszd meg és Uralkodj" + }, + "Stayin' Alive": { + "description": "Nyerj halál nélkül", + "descriptionComplete": "Nyerj anélkül hogy meghalnál.", + "descriptionFull": "Nyerd meg a ${LEVEL} pályát halál nélkül", + "descriptionFullComplete": "${LEVEL} pálya megnyerve halál nélkül", + "name": "Maradj életben!" + }, + "Super Mega Punch": { + "description": "Okozz 100%-os sebzést egyetlen ütéssel", + "descriptionComplete": "100%-os sebzés kiosztva", + "descriptionFull": "Okozz 100%-os sebzést egyetlen ütéssel a ${LEVEL} pályán", + "descriptionFullComplete": "100%-os sebzés kiosztva a ${LEVEL} pályán", + "name": "Szuper Mega Ütés" + }, + "Super Punch": { + "description": "Okozz 50%-os sebzést egyetlen ütéssel", + "descriptionComplete": "50%-os sebzés kiosztva", + "descriptionFull": "Okozz 50%-os sebzést egyetlen ütéssel a ${LEVEL} pályán", + "descriptionFullComplete": "50%-os sebzés kiosztva a ${LEVEL} pályán", + "name": "Szuper ütés" + }, + "TNT Terror": { + "description": "Ölj meg 6 rossz fiút TNT-vel", + "descriptionComplete": "6 rossz fiú megölve TNT-vel", + "descriptionFull": "Ölj meg 6 rossz fiút TNT-vel itt:${LEVEL}", + "descriptionFullComplete": "6 rossz fiú megölve TNT-vel itt:${LEVEL}", + "name": "TNT Terror" + }, + "Team Player": { + "descriptionFull": "Indíts el egy Csapatos mérkőzést több mint 4 játékossal", + "descriptionFullComplete": "Csapatos mérkőzés sikeresen elkezdve több mint 4 játékossal", + "name": "Csapatjátékos" + }, + "The Great Wall": { + "description": "Állítsd meg as összes rosszfiút", + "descriptionComplete": "Összes rosszfiú megállítva", + "descriptionFull": "Állítsd meg az összes rossz fiút itt:${LEVEL}", + "descriptionFullComplete": "Az összes rossz fiú megállítva itt:${LEVEL}", + "name": "A Nagy Fal" + }, + "The Wall": { + "description": "Állítsd meg as összes rosszfiút", + "descriptionComplete": "Megállítittad az összes rosszfiút", + "descriptionFull": "Állítsd meg az összes rossz fiút itt:${LEVEL}", + "descriptionFullComplete": "Az összes rossz fiú megállítva itt:${LEVEL}", + "name": "A Fal" + }, + "Uber Football Shutout": { + "description": "Nyerj, anélkül, hogy a rosszfiúk pontot szereznének", + "descriptionComplete": "Nyertél ,anélkül ,hogy a rossz fiúk pontot szereztek volna", + "descriptionFull": "Nyerj, anélkül, hogy a rossz fiúk pontot szereznének itt:${LEVEL}", + "descriptionFullComplete": "Nyertél ,anélkül ,hogy a rossz fiúk pontot szereztek volna itt:${LEVEL}", + "name": "${LEVEL} Kiütés" + }, + "Uber Football Victory": { + "description": "Nyerd meg a játékot", + "descriptionComplete": "Megnyerted a játékot", + "descriptionFull": "Nyerd meg a játékot a(z) ${LEVEL} pályán.", + "descriptionFullComplete": "Játék megnyerve a ${LEVEL} pályán", + "name": "${LEVEL} Győzelem" + }, + "Uber Onslaught Victory": { + "description": "Győzz le minden hullámot", + "descriptionComplete": "Minden hullámot legyőztél", + "descriptionFull": "Győzz le minden hullámot a(z) ${LEVEL}-ban/ben", + "descriptionFullComplete": "Legyőztél minden hullámot a(z) ${LEVEL}-ban/ben", + "name": "${LEVEL} Győzelem" + }, + "Uber Runaround Victory": { + "description": "Győzd le az összes hullámot", + "descriptionComplete": "Az összes hullám legyőzve", + "descriptionFull": "Győzd le az összes hullámot itt:${LEVEL}", + "descriptionFullComplete": "Az összes hullám legyőzve itt:${LEVEL}", + "name": "${LEVEL} Győzelem" + } + }, + "achievementsRemainingText": "Hátralévő Teljesítmények:", + "achievementsText": "Teljesítmények", + "achievementsUnavailableForOldSeasonsText": "Bocsi, de a teljesítmények nem elérhetőek a régi szezonban.", + "activatedText": "${THING} aktiválva", + "addGameWindow": { + "getMoreGamesText": "Több Játékmód...", + "titleText": "Játék Hozzáadása" + }, + "allowText": "Engedélyezés", + "alreadySignedInText": "A fiókoddal be vagy jelentkezve egy másik eszközről;\nkérlek cserélj fiókot vagy zárd be a játékot \na másik eszközön és próbáld újra", + "apiVersionErrorText": "Nem lehet betölteni a ${NAME} modult jelenlegi verzió:${VERSION_USED}; szükséges verió:${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Automatikus\" csak akkor érhető el ha csatlakoztatva van egy fejhallgató)", + "headRelativeVRAudioText": "Head-Relative hangzás", + "musicVolumeText": "Zene Hangereje", + "soundVolumeText": "Játék Hangereje", + "soundtrackButtonText": "Zenék", + "soundtrackDescriptionText": "(hallgasd a kedvenc zenéidet a játék betétdalaként)", + "titleText": "Hang" + }, + "autoText": "Automatikus", + "backText": "Vissza", + "banThisPlayerText": "Kitagadod ezt a játékost", + "bestOfFinalText": "A ${COUNT} Finálé legjobbja", + "bestOfSeriesText": "A ${COUNT} sorozat legjobbja:", + "bestRankText": "Legjobb helyezésed:#${RANK}", + "bestRatingText": "Legjobb értékelésed:${RATING}", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Boost", + "bsRemoteConfigureInAppText": "A(z) ${REMOTE_APP_NAME} a saját alkalmazásában konfigurálódik.", + "buttonText": "Gomb", + "canWeDebugText": "Szeretnéd, ha a BombSquad automatikusan jelentené a hibákat, \ncrash-eléseket, és általános használati infókat a fejlesztőknek?\n\nEz az adat nem tartalmaz személyes információkat és segít\na játék sima és hibamentes futásának megtartásában.", + "cancelText": "Mégse", + "cantConfigureDeviceText": "Bocs, ${DEVICE} nem beállítható.", + "challengeEndedText": "Ez a kihívás már végét ért.", + "chatMuteText": "Chat némítása", + "chatMutedText": "Chat némítva", + "chatUnMuteText": "Chat némítás feloldása", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Teljesítened kell ezt\na szintet a folytatáshoz!", + "completionBonusText": "Befejezési Bónusz", + "configControllersWindow": { + "configureControllersText": "Vezérlők beállítása", + "configureKeyboard2Text": "2. játékos billentyűzetének beállítása", + "configureKeyboardText": "Billentyűzet beállítása", + "configureMobileText": "Mobil eszközök, mint vezérlők", + "configureTouchText": "Érintőkijelző beállítása", + "ps3Text": "PS3 Vezérlők", + "titleText": "Kontrollerek", + "wiimotesText": "Wiimote-ok", + "xbox360Text": "Xbox 360 Vezérlők" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Megjegyzés: a vezérlő támogatás függ az eszköztől és Android verziójától.", + "pressAnyButtonText": "Nyomj akármilyen gombot a vezérlőn\namit be akarsz állítani...", + "titleText": "Vezérlők Beállítása" + }, + "configGamepadWindow": { + "advancedText": "Haladó", + "advancedTitleText": "Haladó Vezérlő Felépítések", + "analogStickDeadZoneDescriptionText": "(kapcsold ezt fel, ha a karaktered 'kifarol' amikor elengeded a joystick-et)", + "analogStickDeadZoneText": "Analóg Joystick Holtpont", + "appliesToAllText": "(alkalmazza minden ilyen típusú vezérlőnek)", + "autoRecalibrateDescriptionText": "(engedélyezze ezt, ha karaktere nem fut teljes sebességen)", + "autoRecalibrateText": "Automatikus Analóg kar Újrakaribrálás", + "axisText": "tengely", + "clearText": "tiszta", + "dpadText": "dpad", + "extraStartButtonText": "Extra Start Gomb", + "ifNothingHappensTryAnalogText": "Ha semmi sem történt,próbál meg az analóg kart használni helyette.", + "ifNothingHappensTryDpadText": "Ha semmi sem történt,próbáld meg a d-padot használni helyette.", + "ignoreCompletelyDescriptionText": "(megelőzi hogy ez a kontroller befolyásolja a játékot vagy a menüket)", + "ignoreCompletelyText": "Teljes Letiltás", + "ignoredButton1Text": "Letiltott gomb 1", + "ignoredButton2Text": "Letiltott gomb 2", + "ignoredButton3Text": "Letiltott gomb 3", + "ignoredButton4Text": "Letiltott Gomb 4", + "ignoredButtonDescriptionText": "(használd ezeket a gombokat,hogy megelőzd ,hogy a 'home' és a 'sync' gombok befolyásolják az UI-t)", + "pressAnyAnalogTriggerText": "Érintsd meg az analógot...", + "pressAnyButtonOrDpadText": "Nyomj meg egy gombot vagy a D-padot...", + "pressAnyButtonText": "Nyomj meg egy gombot...", + "pressLeftRightText": "Érintsd meg a jobb oldalt vagy a balt...", + "pressUpDownText": "Nyomd meg a felfelét vagy a lefelét...", + "runButton1Text": "Futás gomb 1", + "runButton2Text": "Futás gomb 2", + "runTrigger1Text": "Futás ravasz 1", + "runTrigger2Text": "Futás ravasz 2", + "runTriggerDescriptionText": "(az analóg ravaszok lehetővé teszik a variálható futási sebességet)", + "secondHalfText": "Használd ezt ,hogy beállítsd a második felét \na 2 az 1-ben kontrollernek \n,így a játék egy kontrollert fog mutatni.", + "secondaryEnableText": "Engedélyezés", + "secondaryText": "Másodlagos Vezérlő", + "startButtonActivatesDefaultDescriptionText": "(kapcsold ezt ki ha a start gombod több mint egy 'menü' gomb)", + "startButtonActivatesDefaultText": "A Start gomb létrehoz egy widgetet", + "titleText": "Kontroller Beállítása", + "twoInOneSetupText": "2 az 1-ben Kontroller Beállítása", + "uiOnlyDescriptionText": "(Akadályozd meg, hogy ez a vezérlő csatlakozzon a játszmába)", + "uiOnlyText": "Menü használatra korlátozás", + "unassignedButtonsRunText": "Minden nem használt gomb fut", + "unsetText": "", + "vrReorientButtonText": "VR Nézet Visszaállítás Gomb" + }, + "configKeyboardWindow": { + "configuringText": "Konfigurálás: ${DEVICE}", + "keyboard2NoteText": "A legtöbb billentyűzet csak pár gombnyomást érzékel egyszerre,\nszóval jobb ha használtok két játékos esetén jobb, \nhogy ha egy második billentyűzetet is használtok.\nFontos, hogy ebben az esetben is be kell állítani \naz egyéni vezérlést." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Akció Panel Átmérőja", + "actionsText": "Akciók", + "buttonsText": "gombok", + "dragControlsText": "", + "joystickText": "joystick", + "movementControlScaleText": "Mozgás Panel Átmérője", + "movementText": "Mozgás", + "resetText": "Visszaállítás", + "swipeControlsHiddenText": "Nyilak elrejtése", + "swipeInfoText": "A 'Nyilak' stílushoz hozzá kell szokni \n,viszont játék közben nem kell folyamatosan az ikonokat nézni.", + "swipeText": "nyilak", + "titleText": "Érintőképernyő Konfigurálása" + }, + "configureItNowText": "Most Konfigurálod?", + "configureText": "Konfigurálás", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "A legjobb eredményért szükséged lesz egy lag-mentes Wi-fi hálózatra.\nCsökkentheted a wi-fi lag esélyét azzal, hogy kikapcsolsz más vezeték nélküli\neszközt, hogy közel játszol a router-hez, és hogy egyszerűen\ncsatlakoztatod a kiszolgálót ethernet segitségével.", + "explanationText": "Hogy az okos telefonodat vagy a tableted használni tudd mint vezeték nélküli kontroller,\nnem kell mást tenned csak telepíteni a \"${REMOTE_APP_NAME}\" alkalmazást.\nBármennyi eszköz csatlakozhat a ${APP_NAME}-hoz Wi-Fi-n keresztül méghozzá teljesen ingyen!", + "forAndroidText": "Androidhoz:", + "forIOSText": "iOS-hez:", + "getItForText": "Töltsd le a ${REMOTE_APP_NAME} alkalmazást iOS-hez, az Apple\nApp Store-ból, Androidhoz a Google Play Áruházból, vagy az Amazon Appstore-ból", + "googlePlayText": "Google Play", + "titleText": "Mobil eszközök használata vezérlőként" + }, + "continuePurchaseText": "Folytatod ${PRICE}-t?", + "continueText": "Folytatás", + "controlsText": "Irányítás", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Ez nem vonatkozik a minden idők rangsorra.", + "activenessInfoText": "Ez a szorzó növekszik mikor naponta játszol,\nde kihagyott napok után viszont csökkenni fog.", + "activityText": "Aktivitás", + "campaignText": "Kampány", + "challengesInfoText": "Nyerj nyereményeket mini-játékok megcsinálásával.\n\nA nyeremény és a nehézségi szint\nmindig nő, amikor egy játékot teljesítesz\nés csökken ha egy nem sikerül.", + "challengesText": "Kihívások", + "currentBestText": "Jelenlegi Legjobb", + "customText": "Egyediség", + "entryFeeText": "Belépő", + "forfeitConfirmText": "Felhagysz ezzel a kihívással?", + "forfeitNotAllowedYetText": "Ezt a kihívást most még nem adhatod fel.", + "forfeitText": "Feladás", + "multipliersText": "Szorzók", + "nextChallengeText": "Következő kihívás", + "nextPlayText": "Következő játék", + "ofTotalTimeText": "${TOTAL}-ból/ből", + "playNowText": "Játssz most", + "pointsText": "Pontok", + "powerRankingFinishedSeasonUnrankedText": "(szezon befejezve rang nélkül)", + "powerRankingNotInTopText": "(Nincs benne a top ${NUMBER} -ban/-ben)", + "powerRankingPointsEqualsText": "= ${NUMBER} pont", + "powerRankingPointsMultText": "(x ${NUMBER} pont)", + "powerRankingPointsText": "${NUMBER} pont", + "powerRankingPointsToRankedText": "(${CURRENT} a ${REMAINING} pontból)", + "powerRankingText": "Értékelés", + "prizesText": "Nyeremények", + "proMultInfoText": "Játékosok a ${PRO} verzióval\n${PERCENT}%-kal több pontot kapnak.", + "seeMoreText": "További...", + "skipWaitText": "Kihagyás", + "timeRemainingText": "Hátralévő idő", + "toRankedText": "A helyezésig", + "totalText": "végeredmény", + "tournamentInfoText": "Versenyez a legjobb eredményeiddel\nmás játékosokkal a ligádban.\n\nA legjobb eredményeket elérő játékosok\na torna végén nyereményt kapnak.", + "welcome1Text": "Üdv a ${LEAGUE} Ligában. Fejlesztheted a liga \nhelyezésedet azzal, hogy csillagokat, teljesítményeket \nszerzel vagy akár megnyered a mérkőzéseket.", + "welcome2Text": "Jegyeket is szerezhetsz. A jegyekkel beléphetsz mérkőzésekbe,\nilletve betudod váltani új karakterekre, pályákra, mini-játékokra\nés még sok másra.", + "yourPowerRankingText": "Helyezésed:" + }, + "copyConfirmText": "Másolva", + "copyOfText": "${NAME} másolata", + "copyText": "Másolat", + "createEditPlayerText": "", + "createText": "Készíts", + "creditsWindow": { + "additionalAudioArtIdeasText": "További Audio, Korai Művek, és Ötletek ${NAME} által", + "additionalMusicFromText": "További zenék ${NAME}-tól/től", + "allMyFamilyText": "Minden barátomnak és a családomnak akik segítettek a tesztelésben", + "codingGraphicsAudioText": "Kódolás, Grafika, és Audio ${NAME} által", + "languageTranslationsText": "Nyelvi fordítások:", + "legalText": "Jog:", + "publicDomainMusicViaText": "Nyilvános-domain zene ${NAME} által", + "softwareBasedOnText": "Ez a szoftver részben ${NAME} munkáján alapszik", + "songCreditText": "${PERFORMER} előadásával a(z) ${TITLE}\nKomponálta ${COMPOSER}, Rendezte ${ARRANGER}, Kiadta ${PUBLISHER},\n${SOURCE} Udvariasságából", + "soundAndMusicText": "Hang és Zene:", + "soundsText": "Hangok (${SOURCE}):", + "specialThanksText": "Külön Köszönet:", + "thanksEspeciallyToText": "Kűlönösképpen köszönet ${NAME}-nak/nek", + "titleText": "${APP_NAME} Közreműködők", + "whoeverInventedCoffeeText": "Akárki, aki meghívott egy kávéra" + }, + "currentStandingText": "A jelenlegi álláspontod: #${RANK}", + "customizeText": "Személyre szabás...", + "deathsTallyText": "${COUNT} halál", + "deathsText": "Halál", + "debugText": "Hibajavítás", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Megjegyzés: ajánlott a Beállítások->Grafika->Textúrákat 'Eros'-re állítani ennek leteszteléséhez.", + "runCPUBenchmarkText": "CPU Benchmark futtatása", + "runGPUBenchmarkText": "GPU Benchmark futtatása", + "runMediaReloadBenchmarkText": "Média-Újratöltési Benchmark futtatása", + "runStressTestText": "Feszültség teszt futtatása", + "stressTestPlayerCountText": "Játékos szám", + "stressTestPlaylistDescriptionText": "Stressz Teszt lista", + "stressTestPlaylistNameText": "Lista neve", + "stressTestPlaylistTypeText": "Lista típusa", + "stressTestRoundDurationText": "Kör időtartama", + "stressTestTitleText": "Stressz Teszt", + "titleText": "Tesztfeladat és Stressz Teszt", + "totalReloadTimeText": "Újratöltési idő: ${TIME} (lásd a naplót)" + }, + "defaultGameListNameText": "Alapértelmezett ${PLAYMODE} lista", + "defaultNewGameListNameText": "Saját ${PLAYMODE} listám", + "deleteText": "Törlés", + "demoText": "Demo", + "denyText": "Megtagad", + "desktopResText": "Asztali Felbontás", + "difficultyEasyText": "Könnyű", + "difficultyHardOnlyText": "Csak Nehéz Mód", + "difficultyHardText": "Nehéz", + "difficultyHardUnlockOnlyText": "Ezt a szintet csak nehéz módban lehet feloldani.\nSzerinted megvan benned ami kell!?!?!", + "directBrowserToURLText": "Kérlek irányíts egy web-böngészőt a következő URL-re:", + "disableRemoteAppConnectionsText": "Irányító Alkalmazások Letiltása", + "disableXInputDescriptionText": "Engedélyezi ,hogy 4-nél több kontroller is csatlakozhasson ,viszont nem biztos a hibátlan működés.", + "disableXInputText": "XInput kikapcsolása", + "doneText": "Elvégezve", + "drawText": "Döntetlen", + "duplicateText": "Másolás", + "editGameListWindow": { + "addGameText": "Játék\nHozzáadása", + "cantOverwriteDefaultText": "Nem lehet felülírni az alap lejátszási listát!", + "cantSaveAlreadyExistsText": "Egy lejátszási lista már létezik ilyen néven!", + "cantSaveEmptyListText": "Egy üres lejátszási listát nem lehet elmenteni!", + "editGameText": "Játék\nSzerkesztése", + "listNameText": "Lejátszási lista név", + "nameText": "Név", + "removeGameText": "Játék\nEltávolítása", + "saveText": "Lista Mentése", + "titleText": "Lejátszási lista szerkesztő" + }, + "editProfileWindow": { + "accountProfileInfoText": "Ez a különleges profil rendelkezik névvel,\nés ikonnal a fiókod alapján.\n\n${ICONS}\n\nKészíts egyéni profilt, hogy használhass\nkülönböző neveket vagy egyéni ikonokat.", + "accountProfileText": "(fiók profil)", + "availableText": "A \"${NAME}\" név elérhető.", + "changesNotAffectText": "Megjegyzés: a változások nem érintik a játékban lévő karaktereket", + "characterText": "karakter", + "checkingAvailabilityText": "\"${NAME}\" név ellenőrzése...", + "colorText": "szín", + "getMoreCharactersText": "Több Karakter Szerzése...", + "getMoreIconsText": "Szerezz több ikont...", + "globalProfileInfoText": "A teljes körű játékos profilok garantálják az egyedi \nnevet a játékban, és feloldják az ikonokat is.", + "globalProfileText": "(teljes körű profil)", + "highlightText": "fénypont", + "iconText": "ikon", + "localProfileInfoText": "Alkalmi játékos profilok nem rendelkeznek ikonokkal és lehet,\nhogy a nevüket már használja más a játékban.Fejleszd a profilodat\n teljes körű profilra, hogy egyedülálló neved legyen és, hogy felold az ikonokat.", + "localProfileText": "(alkalmi profil)", + "nameDescriptionText": "Játékos Név", + "nameText": "Név", + "randomText": "véletlen", + "titleEditText": "Profil Szerkesztése", + "titleNewText": "Új Profil", + "unavailableText": "A \"${NAME}\" név nem elérhető;próbálj ki egy másikat.", + "upgradeProfileInfoText": "Ezzel a frissítéssel egyedülálló neved lesz\n és engedélyezi az ikonok használatát is.", + "upgradeToGlobalProfileText": "Frissítés teljes körű profillá" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Nem törölheted az alap betétdalt.", + "cantEditDefaultText": "Nem lehet szerkeszteni az alap betétdalt. Duplázd meg vagy csinálj egy újat.", + "cantOverwriteDefaultText": "Nem lehet felülírni az alap betétdalt", + "cantSaveAlreadyExistsText": "Egy betétdal már létezik ilyen névvel!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Alapértelmezett Betétdal", + "deleteConfirmText": "Betétdal Törlése:\n\n'${NAME}'?", + "deleteText": "Betétdal\nTörlése", + "duplicateText": "Betétdal\nDuplázása", + "editSoundtrackText": "Betétdal Szerkesztő", + "editText": "Betétdal\nSzerkesztése", + "fetchingITunesText": "A(z) iTunes lejátszási listák megszerzése...", + "musicVolumeZeroWarning": "Figyelem: a zene hangerő 0-ra van állítva", + "nameText": "Név", + "newSoundtrackNameText": "Saját Betétdal ${COUNT}", + "newSoundtrackText": "Új Betétdal:", + "newText": "Új\nBetétdal", + "selectAPlaylistText": "Válassz Egy Lejátszási Listát", + "selectASourceText": "Zene Forrás", + "testText": "Teszt", + "titleText": "Betétdalok", + "useDefaultGameMusicText": "Alapértelmezett Játék Zene", + "useITunesPlaylistText": "Zene App Lejátszási Lista", + "useMusicFileText": "Zene Fájl (mp3, stb)", + "useMusicFolderText": "Zene Fájlok Mappája" + }, + "editText": "Szerkesztés", + "endText": "Befejezés", + "enjoyText": "Jó Játékot!", + "epicDescriptionFilterText": "${DESCRIPTION} A hatalmas lassú mozgásban", + "epicNameFilterText": "Hatalmas ${NAME}", + "errorAccessDeniedText": "hozzáférés megtagadva", + "errorDeviceTimeIncorrectText": "Az eszközöd rossz időt mutat ennyi órával:${HOURS}.\nEz okozhat problémákat is.\nKérjük ellenőrizze az időt és idő-zónát a beállításokban.", + "errorOutOfDiskSpaceText": "Kifogyott a szabadhelyből", + "errorSecureConnectionFailText": "Nem lehet kapcsolatot létrehozni a biztonságos felhővel;Az internet funkcionálása talán elbukik.", + "errorText": "Hiba", + "errorUnknownText": "ismeretlen hiba", + "exitGameText": "Kilépsz a ${APP_NAME}-ból?", + "exportSuccessText": "'${NAME}' áthelyezve.", + "externalStorageText": "Külső Tárhely", + "failText": "Bukta", + "fatalErrorText": "Ajajj; valami hiányzik vagy megsérült.\nPróbáld meg újratelepíteni a játékot vagy,\nírj az alábbi e-mail címünkre: ${EMAIL}.", + "fileSelectorWindow": { + "titleFileFolderText": "Válaszd ki a fájlt vagy a mappát", + "titleFileText": "Válasz ki egy fájlt", + "titleFolderText": "Válasz ki egy mappát", + "useThisFolderButtonText": "Használd ezt a mappát" + }, + "filterText": "Szűrő", + "finalScoreText": "Végeredmény", + "finalScoresText": "Végeredmények", + "finalTimeText": "Végső idő", + "finishingInstallText": "Telepítés befejezése...", + "fireTVRemoteWarningText": "A jobb játékélményért, használj\nkontrollert, vagy telepítsd fel a\n'${REMOTE_APP_NAME}' alkalmazást az\nokostelefonodra vagy táblagépedre.", + "firstToFinalText": "Első ${COUNT} végleges", + "firstToSeriesText": "Első ${COUNT} sorozat", + "fiveKillText": "SOROZAT GYILKOS!!!", + "flawlessWaveText": "Hibátlan Hullám!", + "fourKillText": "CSOPORT GYILKOS!!!", + "friendScoresUnavailableText": "A barátok eredményei elérhetetlenek.", + "gameCenterText": "Játék Központ", + "gameCircleText": "GameCircle", + "gameLeadersText": "${COUNT}. játék vezetői", + "gameListWindow": { + "cantDeleteDefaultText": "Az alapértelmezett listát nem lehet törölni.", + "cantEditDefaultText": "Az alapértelmezett listát nem lehet szerkezteni.Másold vagy csinálj egy újat.", + "cantShareDefaultText": "Nem oszthatod meg az alap lejátszási listát.", + "deleteConfirmText": "Törli ezt: \"${LIST}\"?", + "deleteText": "Lista\nTörlése", + "duplicateText": "Lista\nMásolása", + "editText": "Lista\nSzerkesztése", + "newText": "Új\nLista", + "showTutorialText": "Oktató végignézése", + "shuffleGameOrderText": "Játék Rendelés Megkeverése", + "titleText": "Szabd személyre a ${TYPE} Lejátszási listát" + }, + "gameSettingsWindow": { + "addGameText": "Játék Hozzáadása" + }, + "gamesToText": "${WINCOUNT} játék a ${LOSECOUNT}-hez/hoz/höz", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Emlékezz: néhány eszköz a társaságban, több mint\negy játékost is kezelhet, ha van elég vezérlő hozzá.", + "aboutDescriptionText": "Használd ezeket a füleket, hogy összegyűjts egy társaságot.\n\nTársaságokban játszhatsz játékokat, mérkőzéseket\nbarátaiddal különböző eszközökön keresztül.\n\nHasználd a ${PARTY} gombot a felső jobb sarokban, hogy\ncsevegj és közölj valamit társaságoddal.\n(a vezérlőn, nyomd meg a ${BUTTON}-t amikor a menübe vagy)", + "aboutText": "Információ", + "addressFetchErrorText": "", + "appInviteInfoText": "Hívj meg barátokat hogy kipróbálják a BombSquad-ot és ők\nkapnak ${COUNT} ingyen jegyeket. Te kapsz\n${YOU_COUNT} minden barátért aki játszik.", + "appInviteMessageText": "${NAME} küldött neked ${COUNT} jegyeket a ${APP_NAME}-ban", + "appInviteSendACodeText": "Küldj neki egy Kódot", + "appInviteTitleText": "${APP_NAME} Játékba Meghívás", + "bluetoothAndroidSupportText": "(működik néhány Android eszközzel Bluetooth támogatással)", + "bluetoothDescriptionText": "Szolgálj ki/csatlakozz egy társasághoz Bluetooth-on keresztül:", + "bluetoothHostText": "Kiszolgálás Bluetooth-on keresztül", + "bluetoothJoinText": "Csatlakozás Bluetooth-on keresztül", + "bluetoothText": "Bluetooth", + "checkingText": "ellenőrzés...", + "copyCodeConfirmText": "Vágólapra másolva.", + "copyCodeText": "Kód másolása", + "dedicatedServerInfoText": "A legjobb eredményért, csinálj dedikált szerver.Útmutató:bombsquadgame.com/server", + "disconnectClientsText": "Ez le fogja csatlakoztatni a ${COUNT} játékost\na társaságodból. Biztos vagy benne?", + "earnTicketsForRecommendingAmountText": "A barátaid kapni fognak ${COUNT} jegyet ha kipróbálják a játékot\n(és te is kapni fogsz ${YOU_COUNT} jegyet minden barátok általi kipróbálás után)", + "earnTicketsForRecommendingText": "Terjeszd a játékot\ningyenes jegyekért...", + "emailItText": "Küldés", + "favoritesSaveText": "Mentés a kedvencekhez", + "favoritesText": "Kedvencek", + "freeCloudServerAvailableMinutesText": "A következő szerver elérhető ${MINUTES} percen belül.", + "freeCloudServerAvailableNowText": "Szerver elérhető!", + "freeCloudServerNotAvailableText": "Nincsenek elérhető szerverek.", + "friendHasSentPromoCodeText": "${COUNT} db ${APP_NAME} jegyet kaptál ${NAME}-tól", + "friendPromoCodeAwardText": "${COUNT} jegyet fogsz kapni minden egyes használásnál.", + "friendPromoCodeExpireText": "Ez a kód ${EXPIRE_HOURS} óra múlva lejár és csak új játékosok használhatják.", + "friendPromoCodeInfoText": "Ez a kód ${COUNT} jegyet ér.\n\nMenj a \"Beállítások->Haladó->Promóciós Kód Beírása\" a játékban, hogy aktiváld.\nLátogasd meg a bombsquadgame.com nevű weboldalt, a letöltési linkek eléréséhez.\nEz a kód csak ${EXPIRE_HOURS} óráig érvényes és csak új játékosok számára elérhető.", + "friendPromoCodeInstructionsText": "Hogy használhasd, nyisd meg a ${APP_NAME}-ot, menj a \"Beállítások->Haladó>Promóciós Kód Beírása\" menüpontba.\nÍrd be a kódod majd kattints a \"Küldés\" gombra. Látogasd meg a bombsquadgame.com weboldalt letöltési linkekért, és a támogatott eszközök listájáért.", + "friendPromoCodeRedeemLongText": "${COUNT} jegyet ér és maximum ${MAX_USES} ember használhatja.", + "friendPromoCodeRedeemShortText": "${COUNT} jegyet ér a játékon belül.", + "friendPromoCodeWhereToEnterText": "(itt \"Beállítások->Haladó->Promóciós Kód Beírása\")", + "getFriendInviteCodeText": "Promóciós Kód Lekérése", + "googlePlayDescriptionText": "Hívj meg Google Play játékosokat a társaságodba:", + "googlePlayInviteText": "Meghívás", + "googlePlayReInviteText": "Van ${COUNT} Google Play játékos a társaságodban\naki le lesz csatlakoztatva, ha egy másik meghívást kezdeményezel.\nVedd be őket is az új meghívásba, hogy visszakapd őket.", + "googlePlaySeeInvitesText": "Lásd a Meghívásokat", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play-es verzió)", + "hostPublicPartyDescriptionText": "Nyilvános játék indítása:", + "hostingUnavailableText": "Hosztolás elérhetetlen", + "inDevelopmentWarningText": "Megjegyzés:\n\nHálózati játszás egy új és még mindig-fejlődő részleg.\nEgyenlőre, erősen ajánlott, hogy az összes játékos\nlegyen egy Wi-Fi hálózaton.", + "internetText": "Internet", + "inviteAFriendText": "Nincs meg a barátoknak a játék? Hívd meg őket,\nhogy játszanak és ${COUNT} jegy ütheti a markukat.", + "inviteFriendsText": "Barát Meghívása", + "joinPublicPartyDescriptionText": "Belépés nyilvános játékba:", + "localNetworkDescriptionText": "Csatlakozz egy társasághoz, a hálózatodon:", + "localNetworkText": "Helyi Hálózat", + "makePartyPrivateText": "Privát Parti", + "makePartyPublicText": "Nyilvános Parti", + "manualAddressText": "Cím", + "manualConnectText": "Csatlakozás", + "manualDescriptionText": "Csatlakozz egy társasághoz cím alapján:", + "manualJoinSectionText": "Csatlakozás cím alapján", + "manualJoinableFromInternetText": "Tudnak más játékosok csatlakozni hozzád?", + "manualJoinableNoWithAsteriskText": "NEM*", + "manualJoinableYesText": "IGEN", + "manualRouterForwardingText": "*hogy ezt kijávítsd, próbáld meg beállítani a router-edet UDP port átengedése szempontjából a helyi hálózatra ezen: ${PORT}", + "manualText": "Kézi", + "manualYourAddressFromInternetText": "Publikus IP címed:", + "manualYourLocalAddressText": "Lokális IP címed:", + "nearbyText": "Közeli játékok", + "noConnectionText": "", + "otherVersionsText": "(másik verziók)", + "partyCodeText": "Party kód", + "partyInviteAcceptText": "Elfogad", + "partyInviteDeclineText": "Elutasít", + "partyInviteGooglePlayExtraText": "(lásd a 'Google Play' fület a 'Toborzás' ablakban)", + "partyInviteIgnoreText": "Figyelmen kívül hagy", + "partyInviteText": "${NAME} meg lett hívva hogy \ncsatlakozzon a te társaságodba!", + "partyNameText": "Parti Neve:", + "partyServerRunningText": "A party szervered fut.", + "partySizeText": "parti mérete", + "partyStatusCheckingText": "Ellenőrzés...", + "partyStatusJoinableText": "a partidba most már mások is csatlakozhatnak az internetről", + "partyStatusNoConnectionText": "a szerver nem elérhető", + "partyStatusNotJoinableText": "a partidba nem tudnak mások csatlakozni az internetről", + "partyStatusNotPublicText": "a partid nem nyilvános", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Privát szerverek felhőkön futnak.", + "privatePartyHostText": "Privát party hosztolása", + "privatePartyJoinText": "Csatlakozás privát partyhoz", + "privateText": "Privát", + "publicHostRouterConfigText": "Ezt beállítani nehéz. Inkább csinálj egy privát partyt", + "publicText": "Nyilvános", + "requestingAPromoCodeText": "Kód lekérése....", + "sendDirectInvitesText": "Meghívás Küldése", + "sendThisToAFriendText": "Küld el ezt a kódot egy barátodnak:", + "shareThisCodeWithFriendsText": "Küld el ezt a kódot barátaidnak:", + "showMyAddressText": "Címem", + "startAdvertisingText": "Parti Indítása", + "startHostingPaidText": "Hosztolj akár ${COST} -ért", + "startHostingText": "Hoszt", + "startStopHostingMinutesText": "Ingyen hostolhatsz az elköventezendő ${MINUTES} percben.", + "stopAdvertisingText": "Parti Leállítása", + "stopHostingText": "Hosztolás abbahagyása", + "titleText": "Toborzás", + "wifiDirectDescriptionBottomText": "Ha minden eszköznek van 'Wi-Fi Direct' panelje, akkor meg kellene találniuk és \ncsatlakozniuk egymáshoz. Ha mindegyik eszköz csatlakoztatva van, akkor tudtok alkotni\na társaságot a 'Helyi Hálózatok' fülnél, csak úgy mint a sima Wi-Fi hálózattal.\n\nA legjobb eredményért, a Wi-Fi Direkt hálózat készítőjének kellene lennie a ${APP_NAME} társaság készítőjének is.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct-t arra is lehet használni, hogy Android eszközön közvetlenül, Wi-Fi hálózat\nigénye nélkül is csatlakozhassanak. A legjobban Android 4.2-n és újabbon működik.\n\nHogy ezt használd, nyisd meg a Wi-Fi beállításokat és keress 'Wi-Fi Direct'-et a menüben.", + "wifiDirectOpenWiFiSettingsText": "Wi-Fi Beállítások Megnyitása", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(minden platform közt működik)", + "worksWithGooglePlayDevicesText": "(Google Play-t futtató (android) verziós játékkal működik)", + "youHaveBeenSentAPromoCodeText": "Küldtek neked egy ${APP_NAME} promóciós kódot:" + }, + "getTicketsWindow": { + "freeText": "INGYENES!", + "freeTicketsText": "Ingyen Jegyek", + "inProgressText": "Egy tranzakció már folyamatban van; kérlek próbáld ismét egy pillanat múlva.", + "purchasesRestoredText": "Vásárlások helyreállítva.", + "receivedTicketsText": "${COUNT} jegy megkapva!", + "restorePurchasesText": "Vásárlások Helyreállítása", + "ticketDoublerText": "Jegy Duplázó", + "ticketPack1Text": "Kis Jegy Csomag", + "ticketPack2Text": "Közepes Jegy Csomag", + "ticketPack3Text": "Nagy Jegy Csomag", + "ticketPack4Text": "Jumbo Jegy Csomag", + "ticketPack5Text": "Mammoth Jegy Csomag", + "ticketPack6Text": "Végső Jegy Csomag", + "ticketsFromASponsorText": "Nézz egy reklámot \n${COUNT} jegyekért", + "ticketsText": "${COUNT} Jegy", + "titleText": "Szerezz Jegyeket", + "unavailableLinkAccountText": "Sajnálom, a vásárlások ezen az eszközön nem elérhetőek.\nHa szeretnéd, ezt a felhasználót csatlakoztathatod egy másik\neszközre és ott vásárolhatsz.", + "unavailableTemporarilyText": "Ez jelenleg elérhetetlen; kérlek próbáld meg később ismét.", + "unavailableText": "Bocs, ez nem elérhetó.", + "versionTooOldText": "Bocs, a játék ezen verziója túl régi; kérlek frissítsd fel egy újabbra.", + "youHaveShortText": "${COUNT} jegyed van", + "youHaveText": "Neked ${COUNT} jegyed van." + }, + "googleMultiplayerDiscontinuedText": "Bocsánat, A Google-nek a többjátékos szervisze többé nem elérhető.\nÉn most egy cserén dolgozok.\nAddig, Kérlek Válasz egy Másik Kapcsolódási lehetőséget.\n-Eric", + "googlePlayPurchasesNotAvailableText": "A Google Play vásárlások nem elérhetőek.\nTalán frissíteni kell a vásárló alakalmazásod", + "googlePlayServicesNotAvailableText": "A Google Play Szolgáltatások nem elérhetőek.\nNéhány része a játéknak talán le vannak tiltva", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Mindig", + "fullScreenCmdText": "Teljes képernyő (Cmd-F)", + "fullScreenCtrlText": "Teljes képernyő (Ctrl-F)", + "gammaText": "Gamma", + "highText": "Magas", + "higherText": "Magasabb", + "lowText": "Alacsony", + "mediumText": "Közepes", + "neverText": "Soha", + "resolutionText": "Felbontás", + "showFPSText": "FPS Mutatása", + "texturesText": "Textúrák", + "titleText": "Grafika", + "tvBorderText": "TV Keret", + "verticalSyncText": "Vertikális Szinkron", + "visualsText": "Látvány" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nErősebb, mint az ütés, de\neredményezhet komoly ön-sértést.\nA legjobb eredményért, dobj közel\naz elenség elé, mielőtt a kanóc kiég.", + "canHelpText": "A ${APP_NAME} tud segíteni.", + "controllersInfoText": "Játszhatsz ${APP_NAME}-ot a barátaiddal egy hálózaton keresztül, vagy\nmind tudtok játszani ugyanazon az eszközön, ha van elég kontrolleretek.\nA ${APP_NAME} támogat különböző fajtákat is; használhatod akár telefonod is\nmint kontroller az ingyenes '${REMOTE_APP_NAME}' alkalmazás által.\nLásd \"Beállítások->Vezérlők\" menüpontot további infókért.", + "controllersInfoTextRemoteOnly": "A (z) ${APP_NAME} játékot játszhatja barátaival a hálózaton keresztül, vagy veled\nmindannyian játszhatnak ugyanazon az eszközön a (z) telefonok használatával\nvezérlőket az ingyenes „${REMOTE_APP_NAME}” alkalmazáson keresztül.", + "controllersText": "Vezérlők", + "controlsSubtitleText": "A barátságos ${APP_NAME} karakterednek van pár alap képessége:", + "controlsText": "Irányítás", + "devicesInfoText": "A VR verziós ${APP_NAME} játszható hálózaton keresztül a sima verzióval,\ntehát nincs szükséged az extra telefonjaidra, tabletedre, és számítógépedre és \nszállj be a játékba. Ez még hasznos is lehet, hogy csatlakozhatsz a\nsima verziós játékkal a VR verzióshoz hogy lehetőséget adj\na nem játszó embereknek, hogy kívülről nézhessék az eseményeket.", + "devicesText": "Eszközök", + "friendsGoodText": "Jó ha vannak. A ${APP_NAME} akkor a legszórakoztatóbb, hogy ha másokkal játszol,\na játék 8 játékost támogat egyszerre, ami ide vezet:", + "friendsText": "Barátok", + "jumpInfoText": "- Ugrás -\nUgorj keresztül kis hasadásokon,\nhogy távolabbra dobj dolgokat, és\nhogy sürgesd az öröm érzetét.", + "orPunchingSomethingText": "Vagy megütni valamit, ledobni egy hegyről, és felrobbantani a lefele úton egy ragadós bombával.", + "pickUpInfoText": "- Felvétel -\nRagadd meg a zászlót, ellenfelet,\nvagy akármi mást ami nincs rögzítve.\nNyomd meg még egyszer az eldobáshoz.", + "powerupBombDescriptionText": "Hagyja, hogy egyszerre három\nbombát is el tudj dobni.", + "powerupBombNameText": "Tripla-Bomba", + "powerupCurseDescriptionText": "Talán ezeket elakarod kerülni.\n...vagy nem?", + "powerupCurseNameText": "Átok", + "powerupHealthDescriptionText": "Helyreállítja a teljes egészségedet.\nSose gondoltad volna.", + "powerupHealthNameText": "Gyógyító-Csomag", + "powerupIceBombsDescriptionText": "Gyengébb mint a normál bombák,\nde hülten hagyja ellenfeleidet\nés különösen törékenyen.", + "powerupIceBombsNameText": "Jég-Bombák", + "powerupImpactBombsDescriptionText": "Némileg gyengébb, mint az eredeti\nbombák, de becsapódásra robannak.", + "powerupImpactBombsNameText": "Ravasz-Bombák", + "powerupLandMinesDescriptionText": "Ezek 3-asával jönnek egy csomagba;\nHasznos a bázis védelemre vagy\na gyors ellenfelek megállítására.", + "powerupLandMinesNameText": "Taposó-akna", + "powerupPunchDescriptionText": "Felerősíti, gyorsítja, jobbá,\nés keményebbé teszi ütéseidet.", + "powerupPunchNameText": "Box-Kesztyűk", + "powerupShieldDescriptionText": "Elnyeli a sérülés egy részét,\nszóval neked nem kell.", + "powerupShieldNameText": "Energia-Pajzs", + "powerupStickyBombsDescriptionText": "Ragadnak mindenhez amit megütnek.\nVidámság következik.", + "powerupStickyBombsNameText": "Ragadós-Bombák", + "powerupsSubtitleText": "Természetesen, nincs is játék erőfokozók nélkül:", + "powerupsText": "Erőfokozók", + "punchInfoText": "- Ütés -\nÜtések nagyobb sérülést okoznak az\nöklöd mozgási sebességével, tehát\nfuss és pörgj mint egy őrült.", + "runInfoText": "- Futás -\nTarts lenyomva AKÁRMILYEN gombot a futáshoz. Adagolós gombok jól működnek, már ha van olyanod (vezérlők tetején \nLT,LB,RT,RB vagy L1,L2,R1,R2) A futás gyorsabban juttat el helyekre, de megnehezíti a fordulást, szóval vigyázz hova lépsz.", + "someDaysText": "Néha úgy érzed, hogy bele vernél valamibe. Vagy csak felrobbantanál valamit.", + "titleText": "${APP_NAME} Segítség", + "toGetTheMostText": "Hogy mindent kihozz ebből a játékből, szükséged lesz:", + "welcomeText": "Üdvözlet a ${APP_NAME}-ban!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} navigálja most a menüt -", + "importPlaylistCodeInstructionsText": "Használd ezt a kódot, hogy áthelyezd ezt a lejátszási listát:", + "importPlaylistSuccessText": "A ${TYPE} típusú '${NAME}' nevű lejátszási lista sikeresen áthelyezve", + "importText": "Importálás", + "importingText": "Bemásolás...", + "inGameClippedNameText": "játékbeli alak:\n\"${NAME}\"", + "installDiskSpaceErrorText": "Hiba: Nem lehet teljesíteni a telepítést.\nTalán kifogytál a szabadhelyből az eszközödön.\nTakaríts egy kis helyet, és próbáld újra.", + "internal": { + "arrowsToExitListText": "nyomj ${LEFT}-t vagy ${RIGHT}-t a lista bezárásához", + "buttonText": "gomb", + "cantKickHostError": "Nem rúghatod ki a host-ot.", + "chatBlockedText": "${NAME} ki lett tiltva a chatből ${TIME} mp.-re.", + "connectedToGameText": "Beléptél ide: ${NAME}", + "connectedToPartyText": "Csatlakoztál ${NAME} társaságába!", + "connectingToPartyText": "Csatlakozás...", + "connectionFailedHostAlreadyInPartyText": "Csatlakozás nem sikerült; a kiszolgáló másik társaságban van.", + "connectionFailedPartyFullText": "Sikertelen csatlakozás;a parti tele van.", + "connectionFailedText": "Csatlakozás nem sikerült.", + "connectionFailedVersionMismatchText": "Csatlakozás nem sikerült; a kiszolgáló a játék másik verzióját futtatja.\nBizonyosodj meg róla, mindkettőtöknek naprakész és próbáljátok meg újra.", + "connectionRejectedText": "Csatlakozás elutasítva.", + "controllerConnectedText": "${CONTROLLER} csatlakoztatva.", + "controllerDetectedText": "1 vezérlő észlelve.", + "controllerDisconnectedText": "${CONTROLLER} lecsatlakoztatva.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} lecsatlakoztatva. Kérlek próbáld meg újra csatlakoztatni.", + "controllerForMenusOnlyText": "Ezt a típusú kontrollert nem használhatod játékra; csak navigálásra a menüpontokon.", + "controllerReconnectedText": "${CONTROLLER} újracsatlakoztatva.", + "controllersConnectedText": "${COUNT} vezérlő csatlakoztatva.", + "controllersDetectedText": "${COUNT} vezérlő észlelve", + "controllersDisconnectedText": "${COUNT} vezérlő lecsatlakoztatva.", + "corruptFileText": "Korrupt fájl(ok) észlelve. Kérlek próbáld meg újra telepíteni, vagy küld el a ${EMAIL}-ra", + "errorPlayingMusicText": "Hiba a zene lejátszása közben: ${MUSIC}", + "errorResettingAchievementsText": "Nem lehet visszaállítani az achievementeket, próbálkozz később.", + "hasMenuControlText": "${NAME} vezérli a menüt.", + "incompatibleNewerVersionHostText": "A hosztoló a játék újabb verzióját használja.\nFrissítsd az appot, malyd próbáld újra.", + "incompatibleVersionHostText": "A kiszolgáló más virzió számú játékot futtat.\nBizonyosodj megróla hogy mimdkettőtöké naprakész és próbáld újra.", + "incompatibleVersionPlayerText": "${NAME} más BombSquad verziót használ. Győződjetek meg\nróla, hogy mindkettőtöknek a legfrissebb verzió van meg.", + "invalidAddressErrorText": "Hiba: érvénytelen cím.", + "invalidNameErrorText": "Hiba: helytelen név.", + "invalidPortErrorText": "Hiba:érvénytelen port.", + "invitationSentText": "Meghívó elküldve.", + "invitationsSentText": "${COUNT} db meghívó elküldve.", + "joinedPartyInstructionsText": "Valaki csatlakozott a partidhoz.\nMenj a 'Játék'-ra hogy elkezd a játékot.", + "keyboardText": "Billentyűzet", + "kickIdlePlayersKickedText": "${NAME} kirúgva tétlenség miatt.", + "kickIdlePlayersWarning1Text": "${NAME} ki lesz rúgva ${COUNT} másodpercen beül ha továbbra is tétlen marad.", + "kickIdlePlayersWarning2Text": "(ezt ki tudod kapcsolni itt: Beállítások->Haladó)", + "leftGameText": "Kiléptél innen: ${NAME}", + "leftPartyText": "Elhagytad ${NAME} társaságát.", + "noMusicFilesInFolderText": "A mappa nem tartalmaz zenei fájlokat.", + "playerJoinedPartyText": "${NAME} csatlakozott a partihoz!", + "playerLeftPartyText": "${NAME} kilépett a partiból.", + "rejectingInviteAlreadyInPartyText": "Meghívó elutasítva (már benne van a partiban).", + "serverRestartingText": "A szerver Ujraindul. Kérlek csatlakozz vissza egy pillanat után...", + "serverShuttingDownText": "A Szerver lekapcsol...", + "signInErrorText": "Hiba a bejelentkezésnél.", + "signInNoConnectionText": "Nem lehet bejelentkezni. (nincs internet kapcsolat?)", + "telnetAccessDeniedText": "HIBA: a felhasználónak nincs telnet hozzáférése", + "timeOutText": "(Kifagyás ${TIME} másodpercen belül)", + "touchScreenJoinWarningText": "Az érintőképernyővel csatlakoztál.\nHa ez egy hiba, akkor menj ide: Menü->Játék Elhagyása.", + "touchScreenText": "Érintőképernyő", + "unableToResolveHostText": "Hiba: a host nem elérhető.", + "unavailableNoConnectionText": "Ez a funkció nem elérhető (Nincs internet kapcsolat?).", + "vrOrientationResetCardboardText": "Használd ezt, hogy visszaállíts a VR orientációkat.\nHogy játszhass csatlakoztatnod kell egy kontrollert.", + "vrOrientationResetText": "VR orientáció újraindítása.", + "willTimeOutText": "(lejár az idő, ha tétlen)" + }, + "jumpBoldText": "UGORJ", + "jumpText": "Ugorj", + "keepText": "Tartsd", + "keepTheseSettingsText": "Megtartja ezeket a beállításokat?", + "keyboardChangeInstructionsText": "Nyomd meg kétszer a SPACE gombot a billentyűzetváltáshoz.", + "keyboardNoOthersAvailableText": "Nem elérhető másik billentyűzet.", + "keyboardSwitchText": "Átvástás ${NAME} nevű billentyűzetre.", + "kickOccurredText": "${NAME} ki lett rúgva.", + "kickQuestionText": "Kirúgod őt:${NAME}?", + "kickText": "Kirúgás", + "kickVoteCantKickAdminsText": "Adminokat Nem lehet Kidobni.", + "kickVoteCantKickSelfText": "Nem tudod magadat kirugni.", + "kickVoteFailedNotEnoughVotersText": "Nincs elég játékos a szavazáshoz.", + "kickVoteFailedText": "Kirúgási-indítvány sikertelen.", + "kickVoteStartedText": "Kirúgási-szavazás indult ${NAME} ellen.", + "kickVoteText": "Kirúgási indítvány", + "kickVotingDisabledText": "Kirugási szavazás ki van kapcsolva.", + "kickWithChatText": "Írd be a chatbe, hogy:${YES},ha igennel szavazol vagy azt, hogy:${NO}, ha nemmel.", + "killsTallyText": "${COUNT} ölés", + "killsText": "Ölések", + "kioskWindow": { + "easyText": "Könnyű", + "epicModeText": "Hatalmas mód", + "fullMenuText": "Teljes menü", + "hardText": "Nehéz", + "mediumText": "Közepes", + "singlePlayerExamplesText": "Egyszemélyes / Co-op példák", + "versusExamplesText": "Egymás elleni példák" + }, + "languageSetText": "A most használt nyelv:\"${LANGUAGE}\".", + "lapNumberText": "Kör ${CURRENT}/${TOTAL}", + "lastGamesText": "(utolsó ${COUNT} játék)", + "leaderboardsText": "Ranglisták", + "league": { + "allTimeText": "Minden Idő", + "currentSeasonText": "Jelenlegi szezon (${NUMBER})", + "leagueFullText": "${NAME} Liga", + "leagueRankText": "Liga Helyezés", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "A liga befejeződött ${NUMBER} napja.", + "seasonEndsDaysText": "A Szezonból hátra van még:${NUMBER} nap.", + "seasonEndsHoursText": "Szezonból hátralévő idő:${NUMBER} óra.", + "seasonEndsMinutesText": "Szezonból hátralévő idő:${NUMBER} perc.", + "seasonText": "Szezon ${NUMBER}", + "tournamentLeagueText": "Hogy ebbe a tornába be tudj nevezni,el kell érned ezt a ligát:${NAME}", + "trophyCountsResetText": "A trófeák a következő szezonban lenullázódnak." + }, + "levelBestScoresText": "Legjobb eredmények a ${LEVEL}-es szinten.", + "levelBestTimesText": "Legjobb időeredmények a ${LEVEL}-es szinten", + "levelFastestTimesText": "Legjobb idők a ${LEVEL}-n", + "levelHighestScoresText": "Legmagasabb pontszám a ${LEVEL}-n", + "levelIsLockedText": "${LEVEL} le van zárva.", + "levelMustBeCompletedFirstText": "Előszőr a ${LEVEL}-t kell teljesítened.", + "levelText": "Szint:${NUMBER}", + "levelUnlockedText": "Szint Feloldva!", + "livesBonusText": "Élet Bónusz", + "loadingText": "betöltés", + "loadingTryAgainText": "Próbáld újra később...", + "macControllerSubsystemBothText": "Mindkettő(nem ajánlott)", + "macControllerSubsystemClassicText": "Klasszikus", + "macControllerSubsystemDescriptionText": "(Próbáld megváltoztatni ezt, ha a kontroller nem működik)", + "macControllerSubsystemMFiNoteText": "iOS/Mac kontroller észlelve;\nEngedélyezd őket itt: Beállítások->Kontrollerek", + "macControllerSubsystemMFiText": "iOS/Mac", + "macControllerSubsystemTitleText": "Kontroller Támogatás", + "mainMenu": { + "creditsText": "Közreműködők", + "demoMenuText": "Demo Menü", + "endGameText": "Játék Vége", + "endTestText": "Teszt vége", + "exitGameText": "Kilépés a Játékból", + "exitToMenuText": "Kilépés a menübe?", + "howToPlayText": "Tippek", + "justPlayerText": "(Csak ${NAME})", + "leaveGameText": "Játék Elhagyása", + "leavePartyConfirmText": "Tényleg elhagyod a társaságot?", + "leavePartyText": "Társaság Elhagyása", + "quitText": "Kilépés", + "resumeText": "Folytatás", + "settingsText": "Beállítások" + }, + "makeItSoText": "Tedd meg annak", + "mapSelectGetMoreMapsText": "Szerezz Több Pályát", + "mapSelectText": "Válassz...", + "mapSelectTitleText": "${GAME} Pályák", + "mapText": "Pálya", + "maxConnectionsText": "Max. Eszközök", + "maxPartySizeText": "Maximum Parti Méret", + "maxPlayersText": "Max. Játékosok", + "modeArcadeText": "Árkád mód", + "modeClassicText": "Klasszikus mód", + "modeDemoText": "Demó mód", + "mostValuablePlayerText": "Legértékesebb Játékos", + "mostViolatedPlayerText": "Legtöbbször Megölt Játékos", + "mostViolentPlayerText": "Legerőszakosabb Játékos", + "moveText": "Mozgás", + "multiKillText": "${COUNT}-ÖLÉS!!!", + "multiPlayerCountText": "${COUNT} játékos", + "mustInviteFriendsText": "Jegyezd meg: meg kell hívnod a barátaidat \na \"${GATHER}\" panelbenvagy csatlakoztatni\negy vezérlőt a többjátékos mód játszásához.", + "nameBetrayedText": "${NAME} elárulta ${VICTIM}-t.", + "nameDiedText": "${NAME} meghalt.", + "nameKilledText": "${NAME} megölte ${VICTIM}-t.", + "nameNotEmptyText": "A név nem lehet üres!", + "nameScoresText": "${NAME} Pontot Szerzett!", + "nameSuicideKidFriendlyText": "${NAME} véletlenül meghalt", + "nameSuicideText": "${NAME} öngyilkosságot követett el.", + "nameText": "Név", + "nativeText": "Eredeti", + "newPersonalBestText": "Új személyi rekord!", + "newTestBuildAvailableText": "Egy újabb teszt szerkezet elérhető! (${VERSION} build ${BUILD}).\nSzerezd meg a ${ADDRESS}-n", + "newText": "Új", + "newVersionAvailableText": "A ${APP_NAME} újabb verziója elérhető! (${VERSION})", + "nextAchievementsText": "Következő Teljesítmények:", + "nextLevelText": "Következő Szint", + "noAchievementsRemainingText": "- semmi", + "noContinuesText": "(újraéledés nélkül)", + "noExternalStorageErrorText": "Nincs megtalálható külső tárhely ezen az eszközön", + "noGameCircleText": "Hiba: nincs bejelentkezve egy JátékKörbe", + "noProfilesErrorText": "Nincs játékos profilod, tehát te most '${NAME}'-val nyomulsz.\nMenj a Beállítások->Játékos Profilok-ba hogy csinálj magadnak egy profilt-", + "noScoresYetText": "Nincs még pontod.", + "noThanksText": "Nem Köszönöm", + "noTournamentsInTestBuildText": "FIGYELEM: A tournament pontok ebből a teszt épitésből ki lesznek hagyva.", + "noValidMapsErrorText": "Nem található pálya ehhez a játéktípushoz.", + "notEnoughPlayersRemainingText": "Nincs elég játékos. Lépj ki és kezdj egy új játékot.", + "notEnoughPlayersText": "A játék elindításához, minimum ${COUNT} játékos szükséges!", + "notNowText": "Most Nem", + "notSignedInErrorText": "Be kell jelentkezned a művelethez.", + "notSignedInGooglePlayErrorText": "Be kell jelentkezned Google Play-el a művelethez.", + "notSignedInText": "nem vagy bejelentkezve", + "nothingIsSelectedErrorText": "Nem választottál ki semmit!", + "numberText": "#${NUMBER}", + "offText": "Ki", + "okText": "Ok", + "onText": "Be", + "oneMomentText": "Egy pillanat...", + "onslaughtRespawnText": "${PLAYER} újraéled a következő körben (${WAVE})", + "orText": "${A} vagy ${B}", + "otherText": "Egyéb...", + "outOfText": "(#${RANK} a ${ALL}-ból/-ből)", + "ownFlagAtYourBaseWarning": "A saját zászlódnak a bázisodon\nkell tartózkodnia, a pontszerzéshez.", + "packageModsEnabledErrorText": "A hálózati játék nem engedélyezett amíg a Helyi modok be vannak kapcsolva (lásd Beállítások->Haladó)", + "partyWindow": { + "chatMessageText": "Üzenet:", + "emptyText": "Senki sincs a partiban", + "hostText": "(házigazda)", + "sendText": "Küld", + "titleText": "A Partid" + }, + "pausedByHostText": "(szüneteltetve a házigazda által)", + "perfectWaveText": "Tökéletes Hullám!", + "pickUpText": "Felvétel", + "playModes": { + "coopText": "Co-op", + "freeForAllText": "Mindenki mindenki ellen", + "multiTeamText": "Multi-csapat", + "singlePlayerCoopText": "Egy Játékos / Co-op", + "teamsText": "Csapat" + }, + "playText": "Játék", + "playWindow": { + "oneToFourPlayersText": "1-4 játékos", + "titleText": "Játék", + "twoToEightPlayersText": "2-8 játékos" + }, + "playerCountAbbreviatedText": "${COUNT}játékos", + "playerDelayedJoinText": "${PLAYER} a következő körben fog csatlakozni a játékhoz.", + "playerInfoText": "Játékos Információ", + "playerLeftText": "${PLAYER} elhagyta a játékot.", + "playerLimitReachedText": "A játékos limit elérte a határt: ${COUNT}. Többen nem csatlakozhatnak.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Nem lehet törölni a főprofilt.", + "deleteButtonText": "Profil\nTörlése", + "deleteConfirmText": "Törlöd a '${PROFILE}' profilt?", + "editButtonText": "Profil\nSzerkesztése", + "explanationText": "(egyedi karakter nevek és kinézetek ezen a fiókon)", + "newButtonText": "Új \nProfil", + "titleText": "Profilok" + }, + "playerText": "Játékos", + "playlistNoValidGamesErrorText": "Ez a lista tartalmaz még nem feloldott játékokat.", + "playlistNotFoundText": "A lista nem található", + "playlistText": "Játszólista", + "playlistsText": "Listák", + "pleaseRateText": "Ha élvezed a játékot, kérlek értékeld, vagy írj egy\nvéleményt a ${APP_NAME}-ról. Ez mások számára hasznos \nlehet, vagy akár segítheti a játék fejlődését is a jövőben.\n\nKöszi!\n-eric", + "pleaseWaitText": "Kérljek várj...", + "pluginClassLoadErrorText": "Nem sikerült egy hoozáadást betölteni '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Nem sikerült elkezdeni az egyik hozzáadást '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Új hozzáadások érzékelve. Indítsa újra az alkalmazást az aktiváláshoz, vagy szerkesztés őket a beállításokban", + "pluginsRemovedText": "${NUM} hozzáadás(ok) mostmár nem találhatóak", + "pluginsText": "Pluginok", + "practiceText": "Gyakorlás", + "pressAnyButtonPlayAgainText": "Nyomj meg egy gombot, az újrakezdéshez...", + "pressAnyButtonText": "Nyomj meg egy gombot a folytatáshoz...", + "pressAnyButtonToJoinText": "nyomj meg egy gombot a csatlakozáshoz...", + "pressAnyKeyButtonPlayAgainText": "Nyomj meg bármilyen billenyűt/gombot az újrajátszáshoz...", + "pressAnyKeyButtonText": "Nyomj meg bármilyen gombot a folytatáshoz...", + "pressAnyKeyText": "Nyomj meg bármilyen gombot....", + "pressJumpToFlyText": "**Nyomd az ugrást ismételten a repüléshez**", + "pressPunchToJoinText": "Nyomd meg az ütést a csatlakozáshoz...", + "pressToOverrideCharacterText": "Nyomd meg a ${BUTTONS} gombot hogy megváltoztasd a karaktered", + "pressToSelectProfileText": "Nyomd meg a ${BUTTONS}-ot karakterválasztáshoz", + "pressToSelectTeamText": "Nyomd meg a ${BUTTONS}-ot csapatválasztáshoz", + "promoCodeWindow": { + "codeText": "Kód", + "codeTextDescription": "Promóciós Kód", + "enterText": "Küldés" + }, + "promoSubmitErrorText": "Hiba a promóciós kód aktiválásánál; ellenőrizd az internetkapcsolatodat", + "ps3ControllersWindow": { + "macInstructionsText": "Kapcsold ki a PS3-dat majd ellenőrizd ,hogy a MAC-eden \nbiztosan be van-e kapcsolva a Bluetooth, majd \ncsatlakoztasd a kontrollert egy USB kábellel a MAC-hez.\nMost már használhatod a kontroller 'home' gombját hogy \npárosítsd a MAC-et USB-n vagy Bluetooth-on.\n\nNéhány MAC-en meg kell adni a párosítási kódot.\nHa ez történt próbáld meg követni a leírást \nvagy használd a google-t.\n\nHa a PS3 kontrollert vezeték nélkül párosítod akkor meg kell jelennie a\nlistában itt:Preferenciák->Bluetooth.El kell a listából távolítanod \n,hogyha a PS3-dal szeretnéd újra használni a kontrollert.\n\nGyőződj meg róla ,hogy leválasztottad a \nbluetooth-ról ha nem használod mivel \nha ezt nem teszed meg az \nakkumulátor tovább fog merülni.\n\nA bluetooth 7 eszközt tud kezelni,\nde ez a szám változhat.", + "ouyaInstructionsText": "Ha PS3 kontrollert szeretnél használni az OUYA-hoz egyszerűen \ncsak csatlakoztasd a kontrollert egy USB kábellel.\nMiközben ezt csinálod lehet ,hogy a többi kontrollered lecsatlakozik \nígy majd újra kell indítanod az OUYA-át és kihúzni az USB-t.\n\nHogy ha vezeték nélkül szeretnél játszani használd a kontrollert \n'home' gombját.Ha már nem játszol tartsd lenyomva 10 másodpercig a \n'home' gombot ,hogy kikapcsold azt.", + "pairingTutorialText": "párosítást bemutató videó", + "titleText": "PS3 kontroller használata a ${APP_NAME}-ban:" + }, + "punchBoldText": "ÜTÉS", + "punchText": "Ütés", + "purchaseForText": "Megvétel ennyiért:${PRICE}", + "purchaseGameText": "Játék megvásárlása", + "purchasingText": "Vásárlás folyamatban...", + "quitGameText": "Kilépsz a ${APP_NAME}-ból?", + "quittingIn5SecondsText": "Kilépés 5 másodpercen belül...", + "randomPlayerNamesText": "ALAP_NEVEK András, Béla, Csaba, Dániel, Elemér, Ferenc, Gábor, Herold, Imre, János, Károly, László, Márkó, Nándor, Ottó, Péter, Roland, Simon, Tamás, Ubul, Vajk, Walter, Zoltán", + "randomText": "Véletlenszerű", + "rankText": "Helyezés", + "ratingText": "Értékelés", + "reachWave2Text": "Érd el a 2. hullámot a helyezésért.", + "readyText": "kész", + "recentText": "Legutóbbi", + "remoteAppInfoShortText": "A ${APP_NAME} akkor a legjobb hogyha a barátaiddal játszod.\nCsatlakoztass kontrollereket vagy telepítsd a ${REMOTE_APP_NAME}\nnevű alkalmazást a telefonodra vagy tabletedre és használd ezeket\nkontrollerként.", + "remote_app": { + "app_name": "BombSquad Irányító", + "app_name_short": "BsIrányító", + "button_position": "Gomb helye", + "button_size": "Gomb mérete", + "cant_resolve_host": "Nem elemezhető hálózat.", + "capturing": "Foglalás...", + "connected": "Kapcsolódva.", + "description": "Használd a telefonod vagy tableted egy irányítóként a BombSqaud-hez.\nAkár 8 eszköz tud kapcsolódni egyszerre egy epikus többjátékos őrülethez TV-n vagy Tableten.", + "disconnected": "Lecsatlakozva a szerver miatt.", + "dpad_fixed": "megoldva", + "dpad_floating": "repülés", + "dpad_position": "D-Pad Helye", + "dpad_size": "D-pad Mérete", + "dpad_type": "D-Pad Típusa", + "enter_an_address": "Belépés címről.", + "game_full": "Ez a játék tele van vagy nem fogad kapcsolatokat.", + "game_shut_down": "Ez a játék leállt.", + "hardware_buttons": "Hardver Gombok.", + "join_by_address": "Cím alapján való csatlakozás...", + "lag": "Lagg: ${SECONDS} másodpercig.", + "reset": "Visszaállítás alap értelmezettre.", + "run1": "1 Futtatása", + "run2": "2 Futtatása", + "searching": "Keresés BombSquad játékra...", + "searching_caption": "Nyomj annak a játéknak a nevére amelynez csatlakozni akarsz.\nLegyél biztos abba hogy ugyan azon a wifi hálozaton van a játék.", + "start": "Kezdés", + "version_mismatch": "Verzió hiba.\nLégy biztos abban hogy a BombSqad Irányító\na legújabb verzióval rendelkezik, és próbáld újra." + }, + "removeInGameAdsText": "Old fel a \"${PRO}\"-t az áruházból hogy eltávolítsd a játékbeli reklámokat.", + "renameText": "Átnevezés", + "replayEndText": "Visszajátszás Befejezése", + "replayNameDefaultText": "Utolsó Játék visszajátszás", + "replayReadErrorText": "Hiba a visszajátszási fájlok olvasásában.", + "replayRenameWarningText": "Nevezd át \"${REPLAY}\"-t egy játék után ha megakarod tartani; máskülönben felül lesz írva.", + "replayVersionErrorText": "Hiba: Ez a visszajátszás még a régebbi verzióval\nkészült, tehát nem használható.", + "replayWatchText": "Visszajátszás visszanézése", + "replayWriteErrorText": "Hiba a fájl írása során.", + "replaysText": "Visszajátszások", + "reportPlayerExplanationText": "Használd ezt az emailt hogy feljelents csalást, trágár nyelhasználatot , vagy más szabálysért.\nKérlek ide írd:", + "reportThisPlayerCheatingText": "Csalás", + "reportThisPlayerLanguageText": "Trágár Nyelvhasználat", + "reportThisPlayerReasonText": "Miért akarsz feljelentést tenni?", + "reportThisPlayerText": "Játékos Jelentése", + "requestingText": "Lekérés...", + "restartText": "Újraindítás", + "retryText": "Újrapróbálás", + "revertText": "Visszateker", + "runText": "Futás", + "saveText": "Mentés", + "scanScriptsErrorText": "Hiba a szkriptek szkennelésében; részletek a naplóban.", + "scoreChallengesText": "Pontszám Kihívások", + "scoreListUnavailableText": "A pontszám lista nem elérhető.", + "scoreText": "Pont", + "scoreUnits": { + "millisecondsText": "Milliszekundum", + "pointsText": "Pontok", + "secondsText": "Másodperc" + }, + "scoreWasText": "(${COUNT} volt)", + "selectText": "Válassz", + "seriesWinLine1PlayerText": "NYERTE MEG A", + "seriesWinLine1TeamText": "NYERTE MEG A", + "seriesWinLine1Text": "NYERTE MEG A", + "seriesWinLine2Text": "SOROZATOT", + "settingsWindow": { + "accountText": "Felhasználó", + "advancedText": "Haladó", + "audioText": "Hang", + "controllersText": "Vezérlők", + "graphicsText": "Grafika", + "playerProfilesMovedText": "Megjegyzés: A felhasználói profilok át lettek helyezve a fiókok ablakhoz a főmenübe.", + "playerProfilesText": "Játékos Profil", + "titleText": "Beállítások" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(kontroller barát billentyűzet a szöveg szerkesztéséhez)", + "alwaysUseInternalKeyboardText": "Használjon Belső Billentyűzetet", + "benchmarksText": "Teljesítmény és Stressz Teszt", + "disableCameraGyroscopeMotionText": "Kamera Gyroscope kikapcsolása", + "disableCameraShakeText": "Kamera rázást Kikapcsolni", + "disableThisNotice": "(kikapcsolhatod ezt a beállítások menüben)", + "enablePackageModsDescriptionText": "(engedélyez a plusz helyeket a modoknak, viszont letiltja a hálózati játékot)", + "enablePackageModsText": "Helyi Modok Engedélyezése ", + "enterPromoCodeText": "Kód beírása", + "forTestingText": "Megj.:ezek az értékek csak tesztek és az alkalmazás bezárásával együtt törlődnek.", + "helpTranslateText": "A ${APP_NAME} nem Angol fordításait a közösség végzi.\nHa szeretnél fordítani vagy hibát javítani akkor \nhasználd ezt a linket. Előre is köszönöm!", + "kickIdlePlayersText": "Tétlen Játékosok Kirúgása", + "kidFriendlyModeText": "Gyerekbarát Mód (erőszak csökkentése,stb.)", + "languageText": "Nyelv", + "moddingGuideText": "Modolási Útmutató", + "mustRestartText": "Újra kell indítanod a játékot a módosítások érvénybe lépéséhez.", + "netTestingText": "Hálózat Tesztelése", + "resetText": "Visszaállítás", + "showBombTrajectoriesText": "Bomba Pályájának Mutatása", + "showPlayerNamesText": "Játékos Név Mutatása", + "showUserModsText": "Mod Mappák Mutatása", + "titleText": "Haladó", + "translationEditorButtonText": "${APP_NAME} Fordítás Szerkesztő", + "translationFetchErrorText": "fordítási státusz elérhetetlen", + "translationFetchingStatusText": "Fordítási státusz ellenőrzése...", + "translationInformMe": "Értesítsen, ha a nyelvem fordítását frissíteni kell", + "translationNoUpdateNeededText": "A jelenlegi nyelv naprakész; woohoo!", + "translationUpdateNeededText": "**a jelenlegi nyelv frissítésre szorul!!**", + "vrTestingText": "VR Tesztelése" + }, + "shareText": "Megosztás", + "sharingText": "Megosztás...", + "showText": "Mutatott Liga:", + "signInForPromoCodeText": "A promóciós kódok csak akkor érvényesíthetőek, hogy ha be vagy lépve egy profilba.", + "signInWithGameCenterText": "Hogy használd a Játék Központ felhasználódat\njelentkezz be a Játék Központban.", + "singleGamePlaylistNameText": "Csak ${GAME}", + "singlePlayerCountText": "1 játékos", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Karakter Választás", + "Chosen One": "A kiválasztott", + "Epic": "Hatalmas Módú Játékok", + "Epic Race": "Hatalmas Verseny", + "FlagCatcher": "Szerezd meg a Zászlót", + "Flying": "Boldog Gondolatok", + "Football": "Football", + "ForwardMarch": "Roham", + "GrandRomp": "Hóditás", + "Hockey": "Hoki", + "Keep Away": "Tartsd Távol", + "Marching": "Szaladgálás", + "Menu": "Főmenü", + "Onslaught": "Támadás", + "Race": "Verseny", + "Scary": "A Hegy Királya", + "Scores": "Ponttáblázat", + "Survival": "Kirekesztés", + "ToTheDeath": "Death Match", + "Victory": "Végső Ponttáblázat" + }, + "spaceKeyText": "space", + "statsText": "Statisztikák", + "storagePermissionAccessText": "Ehhez tárhelyhozzáférés szükséges", + "store": { + "alreadyOwnText": "Már birtoklod ezt:${NAME}", + "bombSquadProDescriptionText": "-Megduplázza a jegyek szerzését az eredményekért\n-Eltávolítja a hírdetéseket\n-Tartalmaz ${COUNT} ajándék jegyet\n-+${PERCENT}% liga pont bónusz\n-Feloldja a '${INF_ONSLAUGHT}' és\na '${INF_RUNAROUND}' co-op pályákat", + "bombSquadProFeaturesText": "Jellemzők:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "Eltávolítja a reklámokat.\nTöbb játék beállítást nyit meg.\nÉs tartalmaz még:", + "buyText": "Megvesz", + "charactersText": "Karakterek", + "comingSoonText": "Hamarosan...", + "extrasText": "Extrák", + "freeBombSquadProText": "A BombSquad most ingyenes, de mivel te eredetileg megvetted, ezért \nmegkapod a BombSquad Pro frissítést és ${COUNT} jegyet hála jeléül.\nÉlvezd az új jellemzőket, és kösz a támogatást!\n-Eric", + "gameUpgradesText": "Játék Frissítések", + "holidaySpecialText": "Ünnepi Különlegességek", + "howToSwitchCharactersText": "(menj a \"${SETTINGS} -> ${PLAYER_PROFILES}\"-ba, hogy kijelölj és testre szabj karaktereket)", + "howToUseIconsText": "(készíts egy teljes körű profilt (a fiók ablakban) hogy használhasd ezeket)", + "howToUseMapsText": "(használd ezeket a pályákat a saját játék listáidban)", + "iconsText": "Ikonok", + "loadErrorText": "Nem lehet betölteni az oldalt.\nEllenőrizd internet kapcsolatodat.", + "loadingText": "betöltés", + "mapsText": "Pályák", + "miniGamesText": "MiniJátékok", + "oneTimeOnlyText": "(csak egyszer)", + "purchaseAlreadyInProgressText": "Egy vásárlása ezen tárgynak, már folyamatban van.", + "purchaseConfirmText": "Megveszed ${ITEM}?", + "purchaseNotValidError": "Vásárlás nem érvényes\nLépj kapcsolatba a ${EMAIL} címmel, ha ez egy hiba", + "purchaseText": "Vásárlás", + "saleBundleText": "Csomag Akció!", + "saleExclaimText": "Akció!", + "salePercentText": "(${PERCENT}%-os leárazás)", + "saleText": "AKCIÓ", + "searchText": "Keresés", + "teamsFreeForAllGamesText": "Csapatok / Mindenki-Mindenki-ellen Játékok", + "totalWorthText": "*** ${TOTAL_WORTH} Érték! ***", + "upgradeQuestionText": "Fejelszti?", + "winterSpecialText": "Téli Különlegesség", + "youOwnThisText": "- rendelkezel ezzel -" + }, + "storeDescriptionText": "8 Játékos Parti Játék Őrület!\n\nRobbantsd fel a barátaidat (vagy a gépet) a kirobbanó jó mini-játékokkal rendelkező tornákon mint pl: Szerezd meg a Zászlót,Bombázó Jéghoki és Látványos Lassított Death Match!\n\nEgyszerű irányítás és csatlakoztatható kontrollerek teszik lehetővé akár 8-an is csatlakozhassatok a játékhoz.Akár a telefonodat is használhatod mint kontroller a BomSquad Remote ingyenes alkalmazással.\n\nBombára Fel!\n\nA további információkért látogass el ide-> www.froemling.net/bombsquad", + "storeDescriptions": { + "blowUpYourFriendsText": "Robbantsd fel barátaidat.", + "competeInMiniGamesText": "Teljesíts a mini-játékokban a versenyzéstől a repülésig.", + "customize2Text": "Szabd testre a karaktereket, mini-játékokat, és még a betétdalokat is.", + "customizeText": "Szabj testre karaktereket és alkosd meg saját mini-játék lejátszási listádat.", + "sportsMoreFunText": "A sportok még mókásabbak robbanószerekkel.", + "teamUpAgainstComputerText": "Alkoss csapatot a számítógép ellen." + }, + "storeText": "Bolt", + "submitText": "Érvényesítsd", + "submittingPromoCodeText": "Promóciós Kód Érvényesítése...", + "teamNamesColorText": "Csapatnevek/csapatszínek...", + "telnetAccessGrantedText": "Telnet hozzáférés engedélyezve.", + "telnetAccessText": "Telnet hozzáférés észlelve. Engedélyezed?", + "testBuildErrorText": "Ez a teszt verzió többé nem elérhető;kérlek nézz utána egy újabb verziónak.", + "testBuildText": "Teszt Verzió", + "testBuildValidateErrorText": "A Teszt Verzió nem lehet ellenőrizni.(nincs internet?)", + "testBuildValidatedText": "A Teszt Verzió Naprakész;Élvezd!", + "thankYouText": "Köszi a támogatást. Jó játékot!", + "threeKillText": "TRIPLA ÖLÉS!", + "timeBonusText": "Idő Bónusz", + "timeElapsedText": "Eltelt Idő", + "timeExpiredText": "Lejárt az idő", + "timeSuffixDaysText": "${COUNT}n", + "timeSuffixHoursText": "${COUNT}ó", + "timeSuffixMinutesText": "${COUNT}p", + "timeSuffixSecondsText": "${COUNT}mp", + "tipText": "Tipp", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Top Barátok", + "tournamentCheckingStateText": "Torna állapotának ellenőrzése;Kérlek várj...", + "tournamentEndedText": "Ez a torna befejeződött.Az új torna hamarosan kezdődik.", + "tournamentEntryText": "Belépés a Tornába", + "tournamentResultsRecentText": "Legutóbbi Tornában elért helyezésed", + "tournamentStandingsText": "Torna Állása", + "tournamentText": "Bajnokság", + "tournamentTimeExpiredText": "Mérkőzési Idő Lejárt", + "tournamentsDisabledWorkspaceText": "A versenyek ki vannak kapcsolva amíg a munkaterületek aktiválva vannak.\nA versenyek aktiválásához, kapcsold ki a munkaterületeket, és indítsd újra az alkalmazást.", + "tournamentsText": "Bajnokságok", + "translations": { + "characterNames": { + "Agent Johnson": "Johnson Ügynök", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Csonti", + "Butch": "Billy", + "Easter Bunny": "Húsvéti Nyúl", + "Flopsy": "Bolyhos", + "Frosty": "Fagyos", + "Gretel": "Gréta", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Morgan Jack", + "Kronk": "Kronk", + "Lee": "Boróka", + "Lucky": "Manó", + "Mel": "Mel", + "Middle-Man": "Pannónia Kapitány", + "Minimus": "Minimusz", + "Pascal": "Pingu", + "Pixel": "Pixi", + "Sammy Slam": "Sam", + "Santa Claus": "Mikulás", + "Snake Shadow": "Kígyó Árny", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao Mascot", + "Todd McBurton": "Termi Nándor", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Edzés", + "Infinite ${GAME}": "Végtelen ${GAME}", + "Infinite Onslaught": "Végtelen Támadás", + "Infinite Runaround": "Végtelen Szaladgálás", + "Onslaught Training": "Támadás edzés", + "Pro ${GAME}": "Profi ${GAME}", + "Pro Football": "Profi Football", + "Pro Onslaught": "Profi Támadás", + "Pro Runaround": "Profi Szaladgálás", + "Rookie ${GAME}": "Újonc ${GAME}", + "Rookie Football": "Újonc Football", + "Rookie Onslaught": "Újonc Támadás", + "The Last Stand": "Az Utolsó Kiállás", + "Uber ${GAME}": "Über ${GAME}", + "Uber Football": "Über Football", + "Uber Onslaught": "Über Támadás", + "Uber Runaround": "Über Szaladgálás" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Légy a kiválasztott egy ideig hogy nyerj.\nÖld meg a kiválasztottat, hogy te légy az.", + "Bomb as many targets as you can.": "Bombázz annyi célpontot, amennyit csak tudsz.", + "Carry the flag for ${ARG1} seconds.": "Cipeld a zászlót ${ARG1} másodpercig.", + "Carry the flag for a set length of time.": "Cipeld a zászlót egy adott ideig.", + "Crush ${ARG1} of your enemies.": "Zúzz szét ${ARG1}-t az ellenségeidből.", + "Defeat all enemies.": "Győzz le minden ellenséget.", + "Dodge the falling bombs.": "Térj ki minden hulló bomba elől.", + "Final glorious epic slow motion battle to the death.": "A végső dicső hatalmas lassú mozgásos csata a halálig.", + "Gather eggs!": "Gyűjts tojásokat!", + "Get the flag to the enemy end zone.": "Juttasd el a zászlót az ellenséges zóna végére.", + "How fast can you defeat the ninjas?": "Milyen gyorsan győzöd le a ninja-kat?", + "Kill a set number of enemies to win.": "Öllj meg fix mennyiségű ellenséget a nyeréshez.", + "Last one standing wins.": "Utolsó ember nyer.", + "Last remaining alive wins.": "Az utolsó életben lévő nyer.", + "Last team standing wins.": "Utolsó csapat nyer.", + "Prevent enemies from reaching the exit.": "Ne engedd át az ellenséget a kijáraton.", + "Reach the enemy flag to score.": "Érd el az ellenfél zászlóját ,hogy pontot szerezz.", + "Return the enemy flag to score.": "Vidd haza az ellenség zászlóját, hogy pontot szerezz.", + "Run ${ARG1} laps.": "Fuss ${ARG1} kört.", + "Run ${ARG1} laps. Your entire team has to finish.": "Fuss ${ARG1} kört. A csapatod összes tagjának végeznie kell.", + "Run 1 lap.": "Fuss 1 kört.", + "Run 1 lap. Your entire team has to finish.": "Fuss 1 kört. A csapatod összes tagjának végeznie kell.", + "Run real fast!": "Fuss nagyon gyorsan!", + "Score ${ARG1} goals.": "szerezz ${ARG1} gólt.", + "Score ${ARG1} touchdowns.": "Szerezz touchdowns-t.", + "Score a goal.": "Szerezz egy gólt.", + "Score a touchdown.": "Szerezz egy touchdown-t.", + "Score some goals.": "Szerezz pár gólt.", + "Secure all ${ARG1} flags.": "Védd meg mid a ${ARG1} zászlót.", + "Secure all flags on the map to win.": "Védd meg az összes zászlót a pályán ,hogy nyerj.", + "Secure the flag for ${ARG1} seconds.": "Védd a zászlót ${ARG1} másodpercig.", + "Secure the flag for a set length of time.": "Őrizd a zászlót egy adott ideig.", + "Steal the enemy flag ${ARG1} times.": "Lopd el az ellenség zászlóját ${ARG1} alkalommal.", + "Steal the enemy flag.": "Lopd el az ellenség zászlóját.", + "There can be only one.": "Csak egy lehet.", + "Touch the enemy flag ${ARG1} times.": "Érintsd meg az ellenség zászlóját ${ARG1} alkalommal.", + "Touch the enemy flag.": "Érintsd meg az ellenség zászlóját.", + "carry the flag for ${ARG1} seconds": "Cipeld a zászlót ${ARG1} másodpercig", + "kill ${ARG1} enemies": "Ölj meg ${ARG1} ellenséget", + "last one standing wins": "Utolsó ember nyer", + "last team standing wins": "utolsó csapat nyer", + "return ${ARG1} flags": "juttasd vissza a zászlót ${ARG1} alkalommal.", + "return 1 flag": "juttasd vissza a zászlót 1 alkalommal", + "run ${ARG1} laps": "fuss ${ARG1} kört", + "run 1 lap": "fuss 1 kört", + "score ${ARG1} goals": "szerezz ${ARG1} gólt", + "score ${ARG1} touchdowns": "szerezz ${ARG1} touchdowns-t", + "score a goal": "szerezz egy gólt", + "score a touchdown": "szerezz egy touchdown-t", + "secure all ${ARG1} flags": "véd meg mind a ${ARG1} zászlót", + "secure the flag for ${ARG1} seconds": "védd a zászlót ${ARG1} másodpercig", + "touch ${ARG1} flags": "Érints meg ${ARG1} zászlót", + "touch 1 flag": "Érints meg 1 zászlót" + }, + "gameNames": { + "Assault": "Támadás", + "Capture the Flag": "Szerezd meg a zászlót", + "Chosen One": "Kiválasztott", + "Conquest": "Hódítás", + "Death Match": "Death Match", + "Easter Egg Hunt": "Húsvéti tojásvadászat", + "Elimination": "Kiesés", + "Football": "Football", + "Hockey": "Hockey", + "Keep Away": "Tartsd Távol", + "King of the Hill": "A Hegyek Ura", + "Meteor Shower": "Meteor Zuhany", + "Ninja Fight": "Ninja Harc", + "Onslaught": "Támadás", + "Race": "Verseny", + "Runaround": "Szaladgálás", + "Target Practice": "Célzás gyakorlás", + "The Last Stand": "Az utolsó kiállás" + }, + "inputDeviceNames": { + "Keyboard": "Billentyűzet", + "Keyboard P2": "Billentyűzet P2" + }, + "languages": { + "Arabic": "Arab", + "Belarussian": "Fehér Orosz", + "Chinese": "Kínai Simplább", + "ChineseTraditional": "Kínai Tradicionális", + "Croatian": "Horvát", + "Czech": "Cseh", + "Danish": "Dán", + "Dutch": "Holland", + "English": "Angol", + "Esperanto": "Eszperanto", + "Filipino": "Filippínó", + "Finnish": "Finn", + "French": "Francia", + "German": "Német", + "Gibberish": "Értelmetlen beszéd", + "Greek": "Görög", + "Hindi": "Hindi", + "Hungarian": "Magyar", + "Indonesian": "Indonéz", + "Italian": "Olasz", + "Japanese": "Japán", + "Korean": "Koreai", + "Persian": "Perzsa", + "Polish": "Lengyel", + "Portuguese": "Portugál", + "Romanian": "Román", + "Russian": "Orosz", + "Serbian": "Szerb", + "Slovak": "Szlovák", + "Spanish": "Spanyol", + "Swedish": "Svéd", + "Tamil": "Tamil", + "Thai": "Thai, Thai ember", + "Turkish": "Török", + "Ukrainian": "Ukrán", + "Venetian": "Velencei", + "Vietnamese": "Vietnám" + }, + "leagueNames": { + "Bronze": "Bronz", + "Diamond": "Gyémánt", + "Gold": "Arany", + "Silver": "Ezüst" + }, + "mapsNames": { + "Big G": "Nagy G", + "Bridgit": "Bridgit", + "Courtyard": "Udvar", + "Crag Castle": "Szikla Vár", + "Doom Shroom": "A Végzet Gombája", + "Football Stadium": "Football Stadion", + "Happy Thoughts": "Vidám Gondolatok", + "Hockey Stadium": "Hockey Stadion", + "Lake Frigid": "Fagyos Tó", + "Monkey Face": "Majom Arc", + "Rampage": "Rámpa", + "Roundabout": "Kerülő", + "Step Right Up": "Fél Piramis", + "The Pad": "A Pad", + "Tip Top": "Tip Top", + "Tower D": "D Torony", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Csak Hatalmas", + "Just Sports": "Csak Sportok" + }, + "scoreNames": { + "Flags": "Zászlók", + "Goals": "Gólok", + "Score": "Pontok", + "Survived": "Túlélve", + "Time": "Idő", + "Time Held": "Megmaradt Idő" + }, + "serverResponses": { + "A code has already been used on this account.": "Ez a kód már fel volt használva ezen a profilon.", + "A reward has already been given for that address.": "Ez a kód egyszer már használva volt.", + "Account linking successful!": "A fiók összekötése sikeres!", + "Account unlinking successful!": "A fiók leválasztása sikeres", + "Accounts are already linked.": "A fiókok már össze vannak kötve.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "A hirdetés megtekintését nem sikerült ellenőrizni.\nKérjük, győződjön meg róla, hogy a játék hivatalos és naprakész verzióját futtatja.", + "An error has occurred; (${ERROR})": "Egy valamiféle hiba történt; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Hiba történt; kérlek vedd fel a kapcsolatot az ügyfélszolgálattal. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Valamiféle hiba történt; kérlek lépj kapcsolatba velünk: support@froemling.net.", + "An error has occurred; please try again later.": "Egy hiba lépett; kérlek próbáld újra később.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Össze akarod kötni ezt a két fiókot?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nEzt nem lehet visszavonni!", + "BombSquad Pro unlocked!": "BombSquad Pro feloldva!", + "Can't link 2 accounts of this type.": "Nem lehet 2 ilyen típusú fiókot összekötni.", + "Can't link 2 diamond league accounts.": "Nem lehet összekötni 2 gyémánt ligabeli fiókot.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Nem lehet összekötni; túllépné a maximum ${COUNT} összeköthető fiókok mennyiségét.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Csalás észlelve; a pontok és nyeremények felfüggesztve ${COUNT} napig.", + "Could not establish a secure connection.": "Nem lehet megbízható kapcsolatot létesíteni.", + "Daily maximum reached.": "Napi maximum elérve.", + "Entering tournament...": "Belépés a tornába...", + "Invalid code.": "Hibás kód.", + "Invalid payment; purchase canceled.": "Érvénytelen fizetési mód; fizetés visszavonva.", + "Invalid promo code.": "Érvénytelen promóciós kód.", + "Invalid purchase.": "Érvénytelen vásárlás.", + "Invalid tournament entry; score will be ignored.": "Érvénytelen verseny belépés; az eredményeid figyelmen kívül lesznek hagyva.", + "Item unlocked!": "Elem feloldva!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "KAPCSOLAT FENNTARTVA. ${ACCOUNT} tartalmaz\njelentős adatok, amelyek MINDEN elvesznének.\nÖsszekapcsolhatja az ellenkező sorrendben, ha szeretné\n(és ehelyett elveszíti a fiók adatait)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Összekötöd a/az ${ACCOUNT} fiókot ehhez a fiókhoz?\nMinden létező adat a/az ${ACCOUNT} fiókon elveszik.\nEzt nem tudod majd visszavonni. Biztos vagy benne?", + "Max number of playlists reached.": "Maximum listaszám elérve.", + "Max number of profiles reached.": "Maximum profilszám elérve.", + "Maximum friend code rewards reached.": "Maximum barát kód elérve.", + "Message is too long.": "Az üzenet túl hosszú.", + "No servers are available. Please try again soon.": "A szerverek nem elérhetőek. Kérlek próbáld újra később.", + "Profile \"${NAME}\" upgraded successfully.": "A \"${NAME}\" profil teljes körűvé fejlesztve.", + "Profile could not be upgraded.": "A profilt nem lehet frissíteni.", + "Purchase successful!": "Vásárlás sikeres!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "${COUNT} jegy megkapva a bejelentkezés miatt.\nTérj vissza holnap és kapsz újabb${TOMORROW_COUNT} jegyet.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "A szerver nem működik a játék jelenlegi verziójával; \nKérlek frissítsd egy új verzióra.", + "Sorry, there are no uses remaining on this code.": "Ez a kód már elérte a használati limitet.", + "Sorry, this code has already been used.": "Ezt a kódot már használták.", + "Sorry, this code has expired.": "Ez a kód már lejárt.", + "Sorry, this code only works for new accounts.": "Ezt a kódot csak új játékosok használhatják.", + "Still searching for nearby servers; please try again soon.": "Keresés közeli szerverek iránt...", + "Temporarily unavailable; please try again later.": "Jelenleg elérhetetlen; kérlek próbáld újra később.", + "The tournament ended before you finished.": "A torna lezárult mielőtt te befejezted volna.", + "This account cannot be unlinked for ${NUM} days.": "Ezt a fiókot nem tudod leválasztani ${NUM} napig.", + "This code cannot be used on the account that created it.": "Ez a kód nem használható fel, mivel te alkottad.", + "This is currently unavailable; please try again later.": "Ez jelenleg elérhetetlen. Kérlek próbáld újra később.", + "This requires version ${VERSION} or newer.": "Ehhez szükséges verzió:${VERSION} vagy újabb.", + "Tournaments disabled due to rooted device.": "A versenyek tiltva vannak rootolt eszköz miatt.", + "Tournaments require ${VERSION} or newer": "A versenyhez ${VERSION} verzió vagy újabb szükséges.", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Leválasztod ${ACCOUNT} erről a fiókról?\nAz összes adat innen: ${ACCOUNT} törölve lesz. \n(Kivéve a mérföldkövek egyes esetekben)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "FIGYELMEZTETÉS: fiókod ellen panaszok érkeztek csalásért.\nA csaláson kapott fiókok tiltva lesznek. Kérlek játsz tisztességesen.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Szeretnéd hogy a készülék felhasználója ez legyen?\n\nA készülék mostani felhasználója: ${ACCOUNT1}\nEz a felhasználó: ${ACCOUNT2}\n\nEz megtartja a mostani teljesítményed.\nVigyázat: ez nem visszavonható!", + "You already own this!": "Már birtoklod ezt!", + "You can join in ${COUNT} seconds.": "Beléphetsz ${COUNT} másodperc múlva.", + "You don't have enough tickets for this!": "Nincs elég jegyed a vásárláshoz!", + "You don't own that.": "Te nem rendelkezel ezzel.", + "You got ${COUNT} tickets!": "Kaptál ${COUNT} jegyet!", + "You got a ${ITEM}!": "Kaptál egy ${ITEM}-t!", + "You have been promoted to a new league; congratulations!": "Feljutottál egy új ligába; Gratulálunk!", + "You must update to a newer version of the app to do this.": "Frissítened kell a játékot az újabb verzióra, hogy megtehesd ezt.", + "You must update to the newest version of the game to do this.": "Frissítened kell a játék legújabb verziójára hogy ezt meg tudd tenni.", + "You must wait a few seconds before entering a new code.": "Várnod kell pár másodpercet egy új kód beírásához.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Az előző tornában elért helyezésed:#${RANK}.Köszönjük a játékot!", + "Your account was rejected. Are you signed in?": "Fiókod elutasítva. Be vagy jelentkezve?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "A játékod módosítva lett.\nÁllíts vissza minden módosítást és próbáld újra.", + "Your friend code was used by ${ACCOUNT}": "A promóciós kódod használva volt ${ACCOUNT} által" + }, + "settingNames": { + "1 Minute": "1 Perc", + "1 Second": "1 Másodperc", + "10 Minutes": "10 Perc", + "2 Minutes": "2 Perc", + "2 Seconds": "2 Másodperc", + "20 Minutes": "20 Perc", + "4 Seconds": "4 Másodperc", + "5 Minutes": "5 Perc", + "8 Seconds": "8 Másodperc", + "Allow Negative Scores": "Negatív Eredmények Engedélyezése", + "Balance Total Lives": "Teljes Életek Kiegyensúlyozása", + "Bomb Spawning": "Random Bomba", + "Chosen One Gets Gloves": "A Kiválasztott Kesztyűket Kap", + "Chosen One Gets Shield": "A Kiválaszott Pajzsot Kap", + "Chosen One Time": "Kiválasztott Idő", + "Enable Impact Bombs": "Ragadós Bomba engedélyezve", + "Enable Triple Bombs": "Háromszoros Bomba engedélyezve", + "Entire Team Must Finish": "Az Egész csapatnak be kell érnie", + "Epic Mode": "Hatalmas Mód", + "Flag Idle Return Time": "Zászló Tétlen Visszatérés Idő", + "Flag Touch Return Time": "Zászló Érintés Visszatérési Idő", + "Hold Time": "Kitartási Idő", + "Kills to Win Per Player": "Ölések a Győzelemhez Per Játékos", + "Laps": "Körök", + "Lives Per Player": "Életek Per Játékos", + "Long": "Hosszú", + "Longer": "Hosszabb", + "Mine Spawning": "Akna Lerakás", + "No Mines": "Nincsenek Aknák", + "None": "Semmi", + "Normal": "Normál", + "Pro Mode": "Profi mód", + "Respawn Times": "Újraéledési Idő", + "Score to Win": "Pontszám a Győzelemért", + "Short": "Rövid", + "Shorter": "Rövidebb", + "Solo Mode": "Solo Mód", + "Target Count": "Célpontok Száma", + "Time Limit": "Idő Korlát" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "A/az ${TEAM} csapat diszkvalifikálva mivel kilépett az alábbi játékos:${PLAYER}", + "Killing ${NAME} for skipping part of the track!": "${NAME} megölése pálya rész átugrás miatt!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Figyelem ${NAME} dollárnak: a turbó / gomb spammelés kiüti Önt." + }, + "teamNames": { + "Bad Guys": "Rosszfiúk", + "Blue": "Kék", + "Good Guys": "Jó Fiúk", + "Red": "Vörös" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Egy tökéletesen időzített futás-ugrás-pörgés-ütés kombináció azonnal képes ölni\nés emellett egy életen át tartó tisztelet is jár mellé ,talán.", + "Always remember to floss.": "Ne felejts el fogselymet használni!", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Csinálj játékos profilokat magadnak és a barátaidnak,\n hogy ne kelljen véletlenszerű neveket használnotok.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Az átok doboz visszaszámlálós bombává tesz téged.\nAz egyetlen gyógymód ha gyorsan felveszel egy gyógyító dobozt.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Annak ellenére ,hogy a karakterek másképp néznek ki a képességük azonosak,\ntehát válaszd ki a legszimpatikusabbat közölük.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Le legyél elszállva magadtól ha van egy energia pajzsod,ennek ellenére is ugyan úgy lehajíthatnak.", + "Don't run all the time. Really. You will fall off cliffs.": "Ne csak szaladgálj, még a végén leesel a pályáról.", + "Don't spin for too long; you'll become dizzy and fall.": "ne pörögj sokáig, mivel elfogsz esni.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Nyomj meg egy gombot a futáshoz. (A \"Ravasz\" gombok ugyanúgy működnek, ha vannak)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "A futáshoz, nyomj meg egy gombot. Gyorsabb leszel,\nde nehezebb lesz kanyarodnod. Figyelj oda, nehogy leess a pályáról.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Jégbombák nem a legerősebbek, de ha valakit eltalál\naz megfagy. Ilyenkor az illető sebezhető.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Ha valaki felvesz a hátára, csak üsd meg és elfog engedni.\nEz a való életben is így működik.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Ha nincs elég kontrollered, töltsd le a '${REMOTE_APP_NAME}' alkalmazást\na mobil eszközödre hogy kontrollerként használhasd őket.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "HA nincs kontrollered ,telepítsd a BombSquad Remote alkalmazást \na iOS vagy Android készülékedre és használd őket kontrollerként.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Ha egy ragadós bomba rád ragadna,ugrálj és forogj \nkörbe-körbe így talán sikerül lerázni magadról a bombát.", + "If you kill an enemy in one hit you get double points for it.": "Ha megölsz egy ellenséget egyetlen egy sebzéssel, akkor dupla pontot kapsz érte.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Ha felveszel egy átok dobozt csak egy esélyed van a túlélésre \nha felveszel egy gyógyító doboz pár másodpercen belül.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Ha egy helyben maradsz megpörkölnek a bombák. Szaladj, és kerüld ki őket.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Ha sok egy játékos csatlakozik le és fel kapcsold be a 'Tétlen Játékosok Kirúgása'-t\n a beállításokba így senki sem felejt el majd kilépni.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Ha a telefonod híján van az energiának és szeretnél több energiát megtartani \naz akkumulátorban akkor vedd lejjebb a 'Grafikát' a 'Beállításokban'.", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Ha az FPS-ed túl kicsi lenne próbáld meg lejjebb venni\n a felbontást vagy a grafikát a beállításokban.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "A Szerezd meg a Zászlót játékban, ahhoz, hogy pontot szerezz a zászlódnak a bázisodon kell lennie,\nígy egy jó módszer az ellenfél pontszerzésének megakadályozására a zászlójuk ellopása.", + "In hockey, you'll maintain more speed if you turn gradually.": "Hokiban több sebességet tudsz szerezni, ha fokozatosan elfordulsz.", + "It's easier to win with a friend or two helping.": "Sokkal könnyebb nyerni a barátok segítségével.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Ugorj fel, ha magasabb helyekre szeretnél feldobni bombát.", + "Land-mines are a good way to stop speedy enemies.": "A gyors ellenségek ellen a leghatásosabbak a taposóaknák.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Rengeteg dolog fogható meg és dobható el még a játékos.\nDobd le az ellenfeleidet ,hisz így biztosan meghal.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nem tudsz felmenni a létrát. A bombát kell használod.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "A játékosok a legtöbb játékmódban akár a meccs közepén \nis becsatlakozhat, és ez igaz a kontrollerekre is.", + "Practice using your momentum to throw bombs more accurately.": "Használd az időt is, ha egy kicsit vársz a bombával, hatásosabb lehet.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Az ütések hatékonyabbak ha az öklöd mozog,\nszóval próbálj keg futni,ugrani vagy pörögni közben.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Menj vissza és fuss neki a bomba dobásnak\n így a bomba sokkal messzebre repül majd.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Iktass egyszerre egy egész csapatnyi ellenfelet\n úgy ,hogy a TNT közelébe dobsz egy bombát.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "A fej a legsebezhetőbb rész, szóval egy fejre ragadt bomba \nlegtöbbször csak egyet jelenthet: GAME OVER.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Ennek a pályának nincs vége, viszont a \nlegmagasabb pontszám nagy tiszteletet adhat neked.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Az erős dobás egyik alapja az irány nyomva tartása.\nHa gyengén szeretnél eldobni valamit annak a legjobb módja, hogy nem nyomsz semmilyen mozgási gombot.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Unalmasak az alap zenék? Rakj be sajátot!\nBővebben: Beállítások->Hang->Zenék", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Próbáld meg megtartani a bombát olyan 1-2 másodpercig mielőtt eldobnád.", + "Try tricking enemies into killing eachother or running off cliffs.": "Próbáld meg kicselezni az ellenséget úgy ,hogy megöljék egymást vagy leszaladjanak a pályáról.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Használd a felemelő gombot, hogy felemeld a zászlót. < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Próbálj meg neki futni a bombadobásnak így az messzebbre repül...", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "'Becélozhatod' űtésed azzal, hogy forogsz balra vagy jobbra.\nHasznos hogy kiüsd a rosszfiúkat a pályaszélről, vagy a hokiban való pont szerzésre.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Megtudod állapítani, hogy a bomba mikor fog robbani, a kanócon lévő\nszikrák színére való tekintettel: sárga..narancs..piros..BUMM.", + "You can throw bombs higher if you jump just before throwing.": "Magasabbra is tudod dobni a bombát, ha épp a dobás előtt csak ugrassz egyet.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Sérülést szerzel, amikor beütöd a fejedet a dolgokba,\nszóval próbád nem megfejelni a dolgokat.", + "Your punches do much more damage if you are running or spinning.": "Az ütéseid nagyobb sérülést okoznak, ha futsz vagy pörögsz." + } + }, + "trophiesRequiredText": "Ehhez szükség van minimum ${NUMBER} kupára.", + "trophiesText": "Trófeák", + "trophiesThisSeasonText": "Trófeák ebben a ligában", + "tutorial": { + "cpuBenchmarkText": "Futó oktatás a nevetséges-sebességen (elsősorban CPU sebesség teszt)", + "phrase01Text": "Szevasz!", + "phrase02Text": "Üdvözöllek a ${APP_NAME}-ban!", + "phrase03Text": "Itt van pár tipp, hogy irányítsd a karaktered:", + "phrase04Text": "Sok tárgy a ${APP_NAME}-ban FIZIKÁRA alapszik.", + "phrase05Text": "Például, ha ütsz...", + "phrase06Text": "..a sérülés az őkleid gyorsaságán múlik.", + "phrase07Text": "Látod? Nem mozdultunk, szóval ez alig sebezte meg ${NAME}-t.", + "phrase08Text": "Most ugorjunk és pörögjünk hogy sebességre tegyünk szert.", + "phrase09Text": "Áh, így jobb.", + "phrase10Text": "A futás is segít.", + "phrase11Text": "Tartsd lenyomva AKÀRMELYIK gombot a futáshoz.", + "phrase12Text": "Extra-király ütésért, próbálj futni és pörögni.", + "phrase13Text": "Hopsz; bocs ezért ${NAME}", + "phrase14Text": "Feltudsz venni és eldobni dolgokat, csak úgy mint a zászlót... vagy ${NAME}-t.", + "phrase15Text": "Végül, van bomba.", + "phrase16Text": "A bomba dobás gyakorlatot vesz igénybe.", + "phrase17Text": "Áú! Nem nagyon jódobás!", + "phrase18Text": "Mozgás segít távolabbra dobni.", + "phrase19Text": "Az ugrás segít magasabbra dobni.", + "phrase20Text": "\"Ostorozz\" a bombáddal, hogy még messzebbre is dobd.", + "phrase21Text": "Beidőzíteni a bombádat, trükkös lehet.", + "phrase22Text": "Beng.", + "phrase23Text": "Próbáld meg \"kisütni\" a kanócot egy vagy két másodpercre.", + "phrase24Text": "Hurrá! Jól megsült.", + "phrase25Text": "Jólvan, ez csak erről szól.", + "phrase26Text": "Kapd el őket, tigris!", + "phrase27Text": "Emlékezz az edzésedre, és élve jössz vissza!", + "phrase28Text": "...jah, talán...", + "phrase29Text": "Sok szerencsét!", + "randomName1Text": "Fred", + "randomName2Text": "Harry", + "randomName3Text": "Bill", + "randomName4Text": "Chuck", + "randomName5Text": "Phil", + "skipConfirmText": "Tényleg átléped az oktatót? Tapints a belegyezéshez.", + "skipVoteCountText": "${COUNT}/${TOTAL} szavazat az átlépésre", + "skippingText": "Oktató átlépése...", + "toSkipPressAnythingText": "(tapints vagy nyomj meg akármit az oktató átlépéséhez)" + }, + "twoKillText": "DUPLA ÖLÉS!", + "unavailableText": "elérhetetlen", + "unconfiguredControllerDetectedText": "Konfigurált vezérlő felismerve:", + "unlockThisInTheStoreText": "Ennek feloldva kell lennie az áruházban.", + "unlockThisProfilesText": "Hogy készíts több mint ${NUM} profilt, kelleni fog:", + "unlockThisText": "Hogy ezt felold, szükséged van ezekre:", + "unsupportedHardwareText": "Bocs, ez a hárdver nem támogatott a játék ezen szerkezete által.", + "upFirstText": "Elsőként:", + "upNextText": "A következő a ${COUNT}. játékban:", + "updatingAccountText": "Felhasználó frissítése...", + "upgradeText": "Frissítés", + "upgradeToPlayText": "Old fel a \"${PRO}\"-t az áruházba, hogy játszhass ezzel.", + "useDefaultText": "Alapértelmezett Használata", + "usesExternalControllerText": "Ez a játék egy külső vezérlőt használ bemenet gyanánt.", + "usingItunesText": "Itunes használása a zenéhez...", + "usingItunesTurnRepeatAndShuffleOnText": "Kérlek bizonyosodj meg arról, hogy a keverés BE van kapcsolva és az ismétlés MINDEN-re van állítva az iTunes-on.", + "validatingTestBuildText": "Teszt Szerkezet Érvényesítése...", + "victoryText": "Győzelem!", + "voteDelayText": "Még nem indíthatsz szavazást újabb ${NUMBER} másodpercig", + "voteInProgressText": "Már egy szavazás folyamatban van...", + "votedAlreadyText": "Már szavaztál", + "votesNeededText": "${NUMBER} szavazatra van szükség", + "vsText": "ellen", + "waitingForHostText": "(várakozás ${HOST}-ra, hogy folytassuk)", + "waitingForPlayersText": "várakozás a csatlakozó játékosokra...", + "waitingInLineText": "Várakozás (a parti tele van)...", + "watchAVideoText": "Videó Nézése", + "watchAnAdText": "Reklám Nézése", + "watchWindow": { + "deleteConfirmText": "\"${REPLAY}\" Törlése?", + "deleteReplayButtonText": "Visszajátszás\nTörlése", + "myReplaysText": "Az én visszajátszásaim", + "noReplaySelectedErrorText": "Nincs Visszajátszás Kiválasztva", + "playbackSpeedText": "Lejátszási sebesség: ${SPEED}", + "renameReplayButtonText": "Visszajátszás\nÁtnevezése", + "renameReplayText": "\"${REPLAY}\" átnevezése erre:", + "renameText": "Átnevezés", + "replayDeleteErrorText": "Hiba a visszajátszás törlése során.", + "replayNameText": "Visszajátszási Név", + "replayRenameErrorAlreadyExistsText": "Egy visszajátszás már létezik ezzel a névvel.", + "replayRenameErrorInvalidName": "Nem lehet átnevezni a visszajátszást; érvénytelen név.", + "replayRenameErrorText": "Hiba a visszajátszás átnevezése során.", + "sharedReplaysText": "Megosztott Visszajátszások", + "titleText": "Visszajátszás", + "watchReplayButtonText": "Visszajátszás\nMegnézése" + }, + "waveText": "Hullám", + "wellSureText": "Rendben!", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Szerzői jog" + }, + "wiimoteListenWindow": { + "listeningText": "Wiimote-ra való figyelés...", + "pressText": "Nyomd meg a Wiimote 1-es és 2-es gombokat egyidejűleg.", + "pressText2": "Az újabb Wiimote-okon a Motion Plus beépítéssel, nyomd meg a piros 'sync' gombot a hátul lévő helyett." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Szerzői jog", + "listenText": "Figyelj", + "macInstructionsText": "Bizonyosodj meg arról, hogy a Wii-d ki van kapcsolva és a bluetooth engedélyezve van\na te Mac-eden, azután nyomd meg a 'Listen'-t. Wiimote támogatás lehet\nkicsit labilis, szóval lehet párszor próbálgatnod kell\nmielőtt csatlakoztathatnád.\n\nA Bluetooth-nak kezelnie kell felmenőleg 7 csatlakoztatott eszközt,\nbár a távolság változhat.\n\nBombSquad támogatja az eredeti Wiimote-okat, Nunchuk-okat,\nés a klasszikus vezérlőt.\nMost már az újabb Wii Remote Plus is működik\nde nem mellékletekkel.", + "thanksText": "Köszönet a DarwiinRemote csapatnak,\nhogy lehetővé tették.", + "titleText": "Wiimote beállítás" + }, + "winsPlayerText": "${NAME} nyert!", + "winsTeamText": "${NAME} nyert!", + "winsText": "${NAME} nyert!", + "workspaceSyncErrorText": "Nem sikerült szinkronizálni a következő munkaterületet: ${WORKSPACE}. Nézd a naplót további adatokért.", + "workspaceSyncReuseText": "Nem lehet szinkronizálni a következő munkaterületet: ${WORKSPACE}. Előző munkaterület lesz használatban.", + "worldScoresUnavailableText": "Világ eredmények elérhetetlenek", + "worldsBestScoresText": "Világ legjobb eredményei", + "worldsBestTimesText": "Világ legjobb idejei", + "xbox360ControllersWindow": { + "getDriverText": "Szerezz illesztőprogramot", + "macInstructions2Text": "Hogy használj vezérlőket vezetéknélkül, szükséged lesz egy vevőre (reciever),\nami a(z) 'Xbox 360 Wireless Controller for Windows'-hoz jár.\nEgy vevő 4 vezérlőnek engedélyezi a csatlakozást.\n\nFontos: 3rd-party vevők nem fognak működni ezzel az illesztőprogrammal;\nbizonyosodj meg róla, hogy a te vevődön van 'Microsoft' felirat, nem 'Xbox 360'.\nMicrosoft többé már nemadja ezeket külön, tehát szerezned kell\negy olyan csomagot a vezérlővel vagy keress mást ebay-en.\n\nHa hasznosnak találod ezt, kérlek fontolgasd meg az adományozást\naz illesztőprogram fejlesztőinek az ő oldalukon.", + "macInstructionsText": "Hogy használj xbox 360 vezérlőket, fel kell telepítened\na Mac illesztő programot, ami elérhető a fenti link-en.\nMűködik vezetékes, és vezetéknélküli vezérlőkkel is.", + "ouyaInstructionsText": "Hogy használj xbox 360 vezérlőket a BombSquad-dal, szimplán\ndugd őket be az eszköz USB port-jába. Használhatsz egy USB hub-ot\nhogy csatlakoztass több vezérlőket.\n\nHogy használj vezetéknélküli vezérlőket, szükséged lesz vezetéknélküli vevőre, (wireless receiver)\nelérhető, mint a(z) \"Xbox 360 wireless Controller for Windows\" csomag\nalkatrésze vagy külön eladva. Minden vevő egy USB port-ba megy és\nengedélyezi a felcsatlakozást 4 vezetéknélküli vezérlő számára.", + "titleText": "Xbox 360 kontroller használata a ${APP_NAME}-ban:" + }, + "yesAllowText": "Igen, Engedélyez!", + "yourBestScoresText": "Te legjobb pontjaid", + "yourBestTimesText": "Te legjobb időid" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/indonesian.json b/dist/ba_data/data/languages/indonesian.json new file mode 100644 index 0000000..2d18824 --- /dev/null +++ b/dist/ba_data/data/languages/indonesian.json @@ -0,0 +1,1893 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Emoji atau karakter spesial lainnya tidak dapat digunakan untuk nama akun", + "accountProfileText": "(profil akun)", + "accountsText": "Akun", + "achievementProgressText": "Penghargaan: ${COUNT} dari ${TOTAL}", + "campaignProgressText": "Kemajuan Ekspedisi [Sulit]: ${PROGRESS}", + "changeOncePerSeason": "Kamu hanya dapat mengganti ini sekali per musim.", + "changeOncePerSeasonError": "Kamu harus menunggu sampai musim berikutnya untuk menggantinya lagi (${NUM} hari)", + "customName": "Nama Khusus", + "googlePlayGamesAccountSwitchText": "Jika kamu ingin menggunakan akun Google yang lain,\ngunakan aplikasi Google Play Games untuk mengganti.", + "linkAccountsEnterCodeText": "Masukkan kode", + "linkAccountsGenerateCodeText": "Buat Kode", + "linkAccountsInfoText": "(bagikan kemajuan permainan dengan platform lain)", + "linkAccountsInstructionsNewText": "Untuk menghubungkan dua akun, buat kode pada \nperangkat pertama dan masukkan kode ke perangkat kedua.\nData dari kedua akun akan di bagi ke kedua perangkat.\n(Data dari akun pertama akan hilang)\n\nKamu dapat menghubungkan ke ${COUNT} akun.\n\nPENTING: hanya hubungkan akun milikmu sendiri;\nJika kamu menghubungkannya dengan temanmu, kamu tidak akan\ndapat bermain daring pada waktu yang bersamaan.", + "linkAccountsInstructionsText": "Untuk menghubungkan dua akun, buat kode di salah satu\ndari mereka dan masukkan kode itu di sisi lain.\nKemajuan dan persediaan akan digabungkan.\nAnda dapat menghubungkan hingga ${COUNT} akun.\n\nPENTING: Hanya hubungkan akun yang anda miliki!\nJika Anda menghubungkan akun dengan teman anda, anda\ntidak akan bisa bermain bersamaan!\n\nJuga: ini tidak dapat dibatalkan, jadi berhati-hatilah!", + "linkAccountsText": "Tautkan Akun", + "linkedAccountsText": "Akun yang Tertaut:", + "manageAccountText": "Manajemen Akun", + "nameChangeConfirm": "Ganti namamu menjadi ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Tindakan ini akan mengatur ulang kemajuan co-op dan\nskor tertinggi Kamu (kecuali tiket).\nTidak dapat dibatalkan. Apakah Kamu yakin?", + "resetProgressConfirmText": "Ini akan mengatur ulang kemajuan co-op,\npencapaian, dan skor tertinggi Kamu\n(kecuali tiket). Ini tidak dapat\ndibatalkan. Kamu yakin?", + "resetProgressText": "Atur Ulang kemajuan", + "setAccountName": "Pasang Nama Akun", + "setAccountNameDesc": "Pilih nama yang ditampilkan untuk akun Kamu.\nGunakan nama dari akun yang tersambung atau\nbuatlah nama khusus baru.", + "signInInfoText": "Masuk untuk mendapatkan tiket, bermain daring,\ndan membagikan kemajuan permaian antar perangkat.", + "signInText": "Masuk", + "signInWithDeviceInfoText": "(akun otomatis hanya tersedia untuk perangkat ini)", + "signInWithDeviceText": "Masuk menggunakan akun perangkat", + "signInWithGameCircleText": "Masuk dengan LingkarPermainan", + "signInWithGooglePlayText": "Masuk menggunakan Google Play", + "signInWithTestAccountInfoText": "(akun tipe lama; gunakan akun device untuk kedepannya)", + "signInWithTestAccountText": "Masuk menggunakan akun percobaan", + "signInWithV2InfoText": "(Akun yang berfungsi di semua akun)", + "signInWithV2Text": "Daftar dengan akun bombsquad", + "signOutText": "Keluar", + "signingInText": "Sedang masuk...", + "signingOutText": "Sedang keluar...", + "ticketsText": "Tiket:${COUNT}", + "titleText": "Akun", + "unlinkAccountsInstructionsText": "Pilih akun yang akan diputuskan.", + "unlinkAccountsText": "Memutus Akun.", + "unlinkLegacyV1AccountsText": "Putuskan tautan Akun lama (V1)", + "v2LinkInstructionsText": "Gunakan tautan ini untuk membuat akun atau masuk.", + "viaAccount": "(melalui akun ${NAME})", + "youAreSignedInAsText": "Kamu terdaftar sebagai:" + }, + "achievementChallengesText": "Tantangan Pencapaian", + "achievementText": "Pencapaian", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Bunuh 3 musuh menggunakan TNT", + "descriptionComplete": "Membunuh 3 musuh menggunakan TNT", + "descriptionFull": "Bunuh 3 musuh menggunakan TNT pada ${LEVEL}", + "descriptionFullComplete": "Membunuh 3 musuh menggunakan TNT pada ${LEVEL}", + "name": "Duar, Peledak Diledakkan" + }, + "Boxer": { + "description": "Menangkan pertandingan tanpa menggunakan bom", + "descriptionComplete": "Memenangkan pertandingan tanpa bom", + "descriptionFull": "Selesaikan ${LEVEL} tanpa menggunakan bom sama sekali", + "descriptionFullComplete": "Menyelesaikan ${LEVEL} tanpa menggunakan bom", + "name": "Petinju" + }, + "Dual Wielding": { + "descriptionFull": "hubungkan 2 pengontrol (perangkat keras atau aplikasi)", + "descriptionFullComplete": "2 pengontrol terhubung (perangkat keras atau aplikasi)", + "name": "Dua Tangan" + }, + "Flawless Victory": { + "description": "Menangkan pertandingan tanpa terkena serangan", + "descriptionComplete": "Menang Tanpa terkena Serangan", + "descriptionFull": "Menangkan ${LEVEL} tanpa terkena serangan", + "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa terkena serangan", + "name": "Kemenangan Mutlak" + }, + "Free Loader": { + "descriptionFull": "Mulai permainan Bebas-Untuk-Semua dengan 2+ pemain", + "descriptionFullComplete": "Memulai Bebas-Untuk-Semua permainan dengan 2 + pemain", + "name": "Tukang Angkut" + }, + "Gold Miner": { + "description": "Bunuh 6 musuh dengan menggunakan ranjau", + "descriptionComplete": "Membunuh 6 musuh menggunakan ranjau", + "descriptionFull": "Bunuh 6 musuh menggunakan ranjau pada ${LEVEL}", + "descriptionFullComplete": "Membunuh 6 musuh dengan ranjau pada ${LEVEL}", + "name": "Penambang Emas" + }, + "Got the Moves": { + "description": "Menang tanpa memukul atau menggunakan bom", + "descriptionComplete": "Memenangkan pertandingan tanpa memukul dan bom", + "descriptionFull": "Menangkan ${LEVEL} tanpa memukul dan tanpa menggunakan bom", + "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa memukul dan tanpa bom", + "name": "Got the Moves" + }, + "In Control": { + "descriptionFull": "hubungkan pengontrol (perangkat keras atau aplikasi)", + "descriptionFullComplete": "pengontrol terhubung (perangkat keras atau aplikasi)", + "name": "Terkendali" + }, + "Last Stand God": { + "description": "Cetak skor 1000 poin", + "descriptionComplete": "Mencetak skor 1000 poin", + "descriptionFull": "Cetak skor 1000 poin pada ${LEVEL}", + "descriptionFullComplete": "Mencetak skor 1000 poin pada ${LEVEL}", + "name": "Rajanya ${LEVEL}" + }, + "Last Stand Master": { + "description": "Cetak skor 250 poin", + "descriptionComplete": "Mencetak skor 250 poin", + "descriptionFull": "Cetak skor 250 poin pada ${LEVEL}", + "descriptionFullComplete": "Mencetak skor 250 poin pada ${LEVEL}", + "name": "Masternya ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Cetak skor 500 poin", + "descriptionComplete": "Mencetak skor 500 poin", + "descriptionFull": "Cetak skor 500 poin pada ${LEVEL}", + "descriptionFullComplete": "Mencetak skor 500 poin pada ${LEVEL}", + "name": "Penyihir ${LEVEL}" + }, + "Mine Games": { + "description": "Bunuh 3 musuh menggunakan ranjau", + "descriptionComplete": "Membunuh 3 musuh menggunakan ranjau", + "descriptionFull": "Bunuh 3 musuh menggunakan ranjau pada ${LEVEL}", + "descriptionFullComplete": "Membunuh 3 musuh menggunakan ranjau pada ${LEVEL}", + "name": "Permainan Ranjau" + }, + "Off You Go Then": { + "description": "Lempar 3 musuh keluar arena", + "descriptionComplete": "Melempar 3 musuh keluar arena", + "descriptionFull": "Lempar 3 musuh keluar arena pada ${LEVEL}", + "descriptionFullComplete": "Melempar 3 musuh keluar arena pada ${LEVEL}", + "name": "Oke, Maju!" + }, + "Onslaught God": { + "description": "Cetak skor 5000 poin", + "descriptionComplete": "Mencetak skor 5000 poin", + "descriptionFull": "Cetak skor 5000 poin pada ${LEVEL}", + "descriptionFullComplete": "Mencetak skor 5000 poin pada ${LEVEL}", + "name": "Rajanya ${LEVEL}" + }, + "Onslaught Master": { + "description": "Cetak skor 500 poin", + "descriptionComplete": "Mencetak skor 500 poin", + "descriptionFull": "Cetak skor 500 poin pada ${LEVEL}", + "descriptionFullComplete": "Mencetak skor 500 poin pada ${LEVEL}", + "name": "Masternya ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Kalahkan semua gelombang", + "descriptionComplete": "Mengalahkan semua gelombang", + "descriptionFull": "Kalahkan semua gelombang pada ${LEVEL}", + "descriptionFullComplete": "Mengalahkan semua gelombang pada ${LEVEL}", + "name": "Juara ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Cetak skor 1000 poin", + "descriptionComplete": "Mencetak skor 1000 poin", + "descriptionFull": "Cetak skor 1000 poin pada ${LEVEL}", + "descriptionFullComplete": "Mencetak skor 1000 poin pada ${LEVEL}", + "name": "Penyihir ${LEVEL}" + }, + "Precision Bombing": { + "description": "Menang tanpa mengambil kekuatan tambahan", + "descriptionComplete": "Memenangkan permainan tanpa mengambil kekuatan tambahan", + "descriptionFull": "Menangkan ${LEVEL} tanpa mengambil power-up", + "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa mengambil power-up", + "name": "Pengebom Jitu" + }, + "Pro Boxer": { + "description": "Menang tanpa menggunakan bom", + "descriptionComplete": "Menang tanpa menggunakan bom", + "descriptionFull": "Menangkan ${LEVEL} tanpa menggunakan bom", + "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa menggunakan bom", + "name": "Petinju Handal" + }, + "Pro Football Shutout": { + "description": "Menang tanpa memperbolehkan musuh mencetak skor", + "descriptionComplete": "Menang tanpa memperbolehkan musuh mencetak skor", + "descriptionFull": "Menangkan ${LEVEL} tanpa memperbolehkan musuh mencetak skor", + "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa memperbolehkan musuh mencetak skor", + "name": "${LEVEL} Beres" + }, + "Pro Football Victory": { + "description": "Menangkan permainan", + "descriptionComplete": "Memenangkan permainan", + "descriptionFull": "Menangkan permainan pada ${LEVEL}", + "descriptionFullComplete": "Memenangkan permainan pada ${LEVEL}", + "name": "Juara ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Kalahkan semua gelombang", + "descriptionComplete": "Mengalahkan semua gelombang", + "descriptionFull": "Kalahkan semua gelombang pada ${LEVEL}", + "descriptionFullComplete": "Mengalahkan semua gelombang pada ${LEVEL}", + "name": "Juara ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Selesaikan semua gelombang", + "descriptionComplete": "Menyelesaikan semua gelombang", + "descriptionFull": "Selesaikan semua gelombang pada ${LEVEL}", + "descriptionFullComplete": "Menyelesaikan semua gelombang pada ${LEVEL}", + "name": "Juara ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Menang tanpa memperbolehkan musuh mencetak skor", + "descriptionComplete": "Menang tanpa memperbolehkan musuh mencetak skor", + "descriptionFull": "Menangkan ${LEVEL} tanpa memperbolehkan musuh mencetak skor", + "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa memperbolehkan musuh mencetak skor", + "name": "${LEVEL} Beres" + }, + "Rookie Football Victory": { + "description": "Menangkan permainan", + "descriptionComplete": "Memenangkan permainan", + "descriptionFull": "Menangkan permainan pada ${LEVEL}", + "descriptionFullComplete": "Memenangkan permainan pada ${LEVEL}", + "name": "Juara ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Kalahkan semua gelombang", + "descriptionComplete": "Mengalahkan semua gelombang", + "descriptionFull": "Kalahkan semua gelombang pada ${LEVEL}", + "descriptionFullComplete": "Mengalahkan semua gelombang pada ${LEVEL}", + "name": "Juara ${LEVEL}" + }, + "Runaround God": { + "description": "Cetak skor 2000 poin", + "descriptionComplete": "Mencetak skor 2000 poin", + "descriptionFull": "Cetak skor 2000 poin pada ${LEVEL}", + "descriptionFullComplete": "Mencetak skor 2000 poin pada ${LEVEL}", + "name": "Rajanya ${LEVEL}" + }, + "Runaround Master": { + "description": "Cetak skor 500 poin", + "descriptionComplete": "Mencetak skor 500 poin", + "descriptionFull": "Cetak skor 500 poin pada ${LEVEL}", + "descriptionFullComplete": "Mencetak skor 500 poin pada ${LEVEL}", + "name": "Masternya ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Cetak skor 1000 poin", + "descriptionComplete": "Mencetak skor 1000 poin", + "descriptionFull": "Cetak skor 1000 poin pada ${LEVEL}", + "descriptionFullComplete": "Mencetak skor 1000 poin pada ${LEVEL}", + "name": "Penyihir ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Berhasil berbagi permainan dengan teman", + "descriptionFullComplete": "Berhasil berbagi permainan dengan teman", + "name": "Berbagi adalah Peduli" + }, + "Stayin' Alive": { + "description": "Menangkan permainan tanpa mati", + "descriptionComplete": "Memenangkan permainan tanpa mati", + "descriptionFull": "Menangkan ${LEVEL} tanpa mati", + "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa mati", + "name": "Bertahan Hidup" + }, + "Super Mega Punch": { + "description": "Buat 100% damage dengan satu pukulan", + "descriptionComplete": "Membuat 100% damage dengan satu pukulan", + "descriptionFull": "Buat 100% damage dengan satu pukulan pada ${LEVEL}", + "descriptionFullComplete": "Membuat 100% damage dengan satu pukulan pada ${LEVEL}", + "name": "Tinjuan Mega Super" + }, + "Super Punch": { + "description": "Buat 50% damage dengan satu pukulan", + "descriptionComplete": "Membuat 50% damage dengan satu pukulan", + "descriptionFull": "Buat 50% damage dengan satu pukulan pada ${LEVEL}", + "descriptionFullComplete": "Membuat 50% damage dengan satu pukulan pada ${LEVEL}", + "name": "Tinjuan Super" + }, + "TNT Terror": { + "description": "Bunuh 6 musuh menggunakan TNT", + "descriptionComplete": "Membunuh 6 musuh menggunakan TNT", + "descriptionFull": "Bunuh 6 musuh menggunakan TNT pada ${LEVEL}", + "descriptionFullComplete": "Membunuh 6 musuh menggunakan TNT pada ${LEVEL}", + "name": "Teror TNT" + }, + "Team Player": { + "descriptionFull": "Mulai permainan tim dengan 4+ pemain", + "descriptionFullComplete": "Memulai permainan tim dengan 4+ pemain", + "name": "Pemain tim" + }, + "The Great Wall": { + "description": "Hentikan semua musuh", + "descriptionComplete": "Menghentikan semua musuh", + "descriptionFull": "Hentikan semua musuh pada ${LEVEL}", + "descriptionFullComplete": "Menghentikan semua musuh pada ${LEVEL}", + "name": "Si Tembok Baja" + }, + "The Wall": { + "description": "Hentikan semua musuh", + "descriptionComplete": "Menghentikan semua musuh", + "descriptionFull": "Hentikan semua musuh pada ${LEVEL}", + "descriptionFullComplete": "Menghentikan semua musuh pada ${LEVEL}", + "name": "Si Tembok" + }, + "Uber Football Shutout": { + "description": "Menang tanpa memperbolehkan musuh mencetak skor", + "descriptionComplete": "Menang tanpa memperbolehkan musuh mencetak skor", + "descriptionFull": "Menangkan ${LEVEL} tanpa memperbolehkan musuh mencetak skor", + "descriptionFullComplete": "Memenangkan ${LEVEL} tanpa memperbolehkan musuh mencetak skor", + "name": "${LEVEL} Beres" + }, + "Uber Football Victory": { + "description": "Menangkan permainan", + "descriptionComplete": "Memenangkan permainan", + "descriptionFull": "Menangkan permainan pada ${LEVEL}", + "descriptionFullComplete": "Memenangkan permainan pada ${LEVEL}", + "name": "Juara ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Kalahkan semua gelombang", + "descriptionComplete": "Mengalahkan semua gelombang", + "descriptionFull": "Kalahkan semua gelombang pada ${LEVEL}", + "descriptionFullComplete": "Mengalahkan semua gelombang pada ${LEVEL}", + "name": "Juara ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Selesaikan semua gelombang", + "descriptionComplete": "Menyelesaikan semua gelombang", + "descriptionFull": "Selesaikan semua gelombang pada ${LEVEL}", + "descriptionFullComplete": "Menyelesaikan semua gelombang pada ${LEVEL}", + "name": "Juara ${LEVEL}" + } + }, + "achievementsRemainingText": "Achievement Tersisa:", + "achievementsText": "Achievement", + "achievementsUnavailableForOldSeasonsText": "Maaf, spesifik achievement tidak tersedia untuk musim lama.", + "activatedText": "${THING} telah aktif", + "addGameWindow": { + "getMoreGamesText": "Game Lain...", + "titleText": "Tambah Game" + }, + "allowText": "Izinkan", + "alreadySignedInText": "Akunmu telah masuk di perangkat lain;\nSilakan beralih akun atau menutup permainanmu \ndi perangkat lain dan coba lagi.", + "apiVersionErrorText": "Modul ${NAME} gagal dimuat; Menarget api-version ${VERSION_USED}; kami membutuhkan ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" nyalakan ini hanya jika menggunakan headphone)", + "headRelativeVRAudioText": "VR Audio Head-Relative", + "musicVolumeText": "Volume Musik", + "soundVolumeText": "Volume Suara", + "soundtrackButtonText": "Pengiring lagu", + "soundtrackDescriptionText": "(masukkan musik Kamu untuk diputar saat permainan)", + "titleText": "Audio" + }, + "autoText": "Otomatis", + "backText": "Kembali", + "banThisPlayerText": "Melarang Pemain Ini", + "bestOfFinalText": "Terbaik dari ${COUNT} Final", + "bestOfSeriesText": "Terbaik dari ${COUNT}:", + "bestRankText": "Urutan terbaikmu #${RANK}", + "bestRatingText": "Rating terbaikmu ${RATING}", + "bombBoldText": "BOM", + "bombText": "Bom", + "boostText": "Dorongan", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} dikonfigurasi di aplikasinya sendiri.", + "buttonText": "tombol", + "canWeDebugText": "Bolehkah BombSquad mengirim informasi kerusakan\ndan info penggunaan ke pengembang secara otomatis? \n\nData pribadi tidak akan dikirim dan\nmembantu game berjalan lebih baik.", + "cancelText": "Batal", + "cantConfigureDeviceText": "Maaf, ${DEVICE} tidak dapat dikonfigurasi.", + "challengeEndedText": "Tantangan selesai", + "chatMuteText": "Abaikan Percakapan", + "chatMutedText": "Percakapan Diabaikan", + "chatUnMuteText": "Menampilkan kembali percakapan", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Kamu harus menyelesaikan\nlevel ini untuk dapat lanjut!", + "completionBonusText": "Bonus Kelengkapan", + "configControllersWindow": { + "configureControllersText": "Atur Pengontrol", + "configureKeyboard2Text": "Atur Keyboard Player 2", + "configureKeyboardText": "Atur Keyboard", + "configureMobileText": "Perangkat ponsel sebagai pengontrol", + "configureTouchText": "Atur Kontrol Layar", + "ps3Text": "Pengontrol PS3", + "titleText": "Pengontrol", + "wiimotesText": "Wiimote", + "xbox360Text": "Pengontrol Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Catatan: pengontrol dapat digunakan berdasarkan versi Android Kamu.", + "pressAnyButtonText": "Tekan tombol kontroller yang\n ingin Kamu atur,,,", + "titleText": "Konfigurasi Pengontrol" + }, + "configGamepadWindow": { + "advancedText": "Lanjutan", + "advancedTitleText": "Pengaturan Pengontrol Lanjutan", + "analogStickDeadZoneDescriptionText": "(nyalakan ini jika karaktermu ngedrift saat kamu melepaskan analog stik)", + "analogStickDeadZoneText": "Analog Stick Zona Mati", + "appliesToAllText": "(Berlakukan ke semua kontrol tipe ini)", + "autoRecalibrateDescriptionText": "(nyalakan ini jika karaktermu tidak bergerak dengan kecepatan penuh)", + "autoRecalibrateText": "Otomatis kalibrasi kembali stik analog", + "axisText": "axis", + "clearText": "hapus", + "dpadText": "dpad", + "extraStartButtonText": "Tambahan tombol start", + "ifNothingHappensTryAnalogText": "Jika tidak terjadi apa-apa,coba berlakukan stik analog langsung", + "ifNothingHappensTryDpadText": "Jika tidak terjadi apa-apa,coba berlakukan ke d-pad langsung", + "ignoreCompletelyDescriptionText": "Cegah pengontrol ini untuk mempengaruhi game atau menu", + "ignoreCompletelyText": "Abaikan Sepenuhnya", + "ignoredButton1Text": "Abaikan tombol 1", + "ignoredButton2Text": "Abaikan tombol 2", + "ignoredButton3Text": "Abaikan tombol 3", + "ignoredButton4Text": "Abaikan tombol 4", + "ignoredButtonDescriptionText": "(Gunakan ini untuk mencegah tombol 'home' atau 'sync' yang mempengaruhi UI)", + "pressAnyAnalogTriggerText": "Tekan Tombol analog....", + "pressAnyButtonOrDpadText": "Tekan Tombol dpad", + "pressAnyButtonText": "Tekan tombol", + "pressLeftRightText": "Tekan Tombol kiri atau kanan", + "pressUpDownText": "Tekan tombol atas atau bawah..", + "runButton1Text": "Jalankan tombol 1", + "runButton2Text": "Jalankan tombol 2", + "runTrigger1Text": "Jalankan pelatuk 1", + "runTrigger2Text": "Jalankan pelatuk 2", + "runTriggerDescriptionText": "(Analog memungkinkan kamu untuk lari pada berbagai kecepatan)", + "secondHalfText": "Gunakan ini untuk pengontrol kedua dari\n2-pengontrol-dalam-1 alat yang\nditunjukan sebagai pengontrol tunggal", + "secondaryEnableText": "Aktifkan", + "secondaryText": "Pengontrol kedua", + "startButtonActivatesDefaultDescriptionText": "(Matikan jika tombol start Kamu lebih dari tombol 'menu')", + "startButtonActivatesDefaultText": "Tombol start mengaktifkan widget biasanya", + "titleText": "Pengaturan Pengontrol", + "twoInOneSetupText": "Pengaturan Pengontrol 2-dalam-1", + "uiOnlyDescriptionText": "(Cegah kontrol ini dari mengikuti permainan yang asli)", + "uiOnlyText": "Batas untuk menu guna", + "unassignedButtonsRunText": "Tidak berlakukan semua tombol lari", + "unsetText": "", + "vrReorientButtonText": "Tombol reorientasi VR" + }, + "configKeyboardWindow": { + "configuringText": "Mengaturi ${DEVICE}", + "keyboard2NoteText": "Catatan: beberapa keyboard hanya dapat memasukan beberapa tombol yang ditekan pada satu waktu,\njadi memiliki keyboard pemain kedua mungkin bekerja lebih baik\njika ada pemisah keyboard yang terpasang untuk digunakan\nPerlu dicatat bahwa Kamu masih butuh memasukan tombol unik untuk\nkedua pemain di kasus ini" + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Ukuran kontrol aksi", + "actionsText": "Aksi", + "buttonsText": "tombol", + "dragControlsText": "< geser kontrol untuk memposisikannya >", + "joystickText": "joystick", + "movementControlScaleText": "Skala kontrol penggerak", + "movementText": "Pergerakan", + "resetText": "Kembalikan ke awal", + "swipeControlsHiddenText": "Sembunyikan ikon geser", + "swipeInfoText": "Model kontrol 'geser' membutuhkan penggunaan sedikit \nnamun membuat mudah untuk bermain tanpa melihat pengontrol", + "swipeText": "geser", + "titleText": "Atur layar sentuh" + }, + "configureItNowText": "Atur sekarang?", + "configureText": "Konfigurasi", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App store", + "bestResultsText": "Untuk hasil yang lebih baik, Kamu membutuhkan jaringan Wi-Fi yang bebas lag.\nKamu dapat menurunkan lag Wi-Fi dengan cara mematikan alat wireless lainnya,\ndengan bermain dekat dengan router Wi-Fi dan dengan menyambungkan ke host\ngame langsung ke jaringan via ethernet", + "explanationText": "Untuk menggunakan smartphone atau tablet sebagai pengontrol,\npasang \"${REMOTE_APP_NAME}\" app. Alat apapun dapat tersambung ke\n${APP_NAME} game melalui Wi-Fi, dan ini gratis!", + "forAndroidText": "Untuk Android:", + "forIOSText": "Untuk iOS:", + "getItForText": "Dapatkan ${REMOTE_APP_NAME} untuk iOS di Apple App Store\natau untuk Android di Google Play Store atau Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Gunakan Perangkat untuk kontroler:" + }, + "continuePurchaseText": "Lanjutkan untuk ${PRICE}?", + "continueText": "Lanjutkan", + "controlsText": "Kontrol", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Ini akan tidak berlaku ke ranking semua waktu.", + "activenessInfoText": "Kelipatan ini naik di hari ketika Kamu bermain\ndan turun di haru ketika Kamu tidak bermain", + "activityText": "Aktivitas", + "campaignText": "Ekspedisi", + "challengesInfoText": "Dapatkan hadiah dengan menyelesaikan mini games\n\nHadiah dan tingkat kesulitan level bertambah\nsaat tantangan terselesaikan \ndan berkurang jika waktu habis atau menyerah", + "challengesText": "Tantangan", + "currentBestText": "Terbaik saat ini", + "customText": "Kustom", + "entryFeeText": "Masuk", + "forfeitConfirmText": "Kehilangan tantangan ini??", + "forfeitNotAllowedYetText": "Tantangan ini belum dapat hiang", + "forfeitText": "Kehilangan", + "multipliersText": "Kelipatan", + "nextChallengeText": "Tantangan berikutnya", + "nextPlayText": "Permainan berikutnya", + "ofTotalTimeText": "Dari ${TOTAL}", + "playNowText": "Main sekarang", + "pointsText": "Poin", + "powerRankingFinishedSeasonUnrankedText": "(Sesi berakhir tidak terangking)", + "powerRankingNotInTopText": "(tidak di atas ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} poin", + "powerRankingPointsMultText": "(x ${NUMBER} poin)", + "powerRankingPointsText": "${NUMBER} poin", + "powerRankingPointsToRankedText": "(${CURRENT} dari ${REMAINING} poin)", + "powerRankingText": "Rangking power", + "prizesText": "Hadiah", + "proMultInfoText": "Pemain dengan peningkatan ${PRO}\nmendapatkan sebuah ${PERCENT}% poin tambahan disini.", + "seeMoreText": "Lebih...", + "skipWaitText": "Lewati Tunggu", + "timeRemainingText": "Waktu tersisa", + "toRankedText": "untuk Peringkat", + "totalText": "Total", + "tournamentInfoText": "Bersaing untuk skor tinggi dengan\npemain lain di liga Kamu.\n\nHadiah diberikan ke atas\npapan skor", + "welcome1Text": "Selamat datang di ${LEAGUE}.Kamu dapat tingkatkan \nranking liga dengan dapatkan peringkat berlian, selesaikan \npenghargaan dan menenangkan piala di turnamen", + "welcome2Text": "Kamu juga dapat mendapatkan tiket dari aktivitas yang sama.\nTiket dapat digunakan untuk membuka karakter baru, peta, dan\nmini games,untuk masuk liga, dan lainnya", + "yourPowerRankingText": "Peringkat Kekuatan Kamu:" + }, + "copyConfirmText": "Tersalin ke papan klip.", + "copyOfText": "Salinan ${NAME}", + "copyText": "Salin", + "createEditPlayerText": "", + "createText": "Buat", + "creditsWindow": { + "additionalAudioArtIdeasText": "Audio tambahan,Early Artwork, dan ide dari ${NAME}", + "additionalMusicFromText": "Musik Tambahan Dari ${NAME}", + "allMyFamilyText": "Semua teman saya dan keluarga saya yang menolong untuk memainkan test", + "codingGraphicsAudioText": "Koding, Grafik, Dan audio dari ${NAME}", + "languageTranslationsText": "Penerjemah bahasa:", + "legalText": "Legal:", + "publicDomainMusicViaText": "Musik publik dominan via ${NAME}", + "softwareBasedOnText": "Software ini berasal dari bagian kerja dari ${NAME}", + "songCreditText": "${TITLE} Dimainkan oleh ${PERFORMER}\nKomposisi oleh ${COMPOSER}, Aransemen oleh ${ARRANGER}, Publikasi oleh ${PUBLISHER},\nSumber dari ${SOURCE}", + "soundAndMusicText": "Suara & Musik:", + "soundsText": "Suara (${SOURCE}):", + "specialThanksText": "Terima Kasih Khusus:", + "thanksEspeciallyToText": "dan Terima Kasih juga kepada ${NAME}", + "titleText": "${APP_NAME} Kredit", + "whoeverInventedCoffeeText": "Siapapun itu yang menyajikan Kopi" + }, + "currentStandingText": "Posisimu sekarang: #${RANK}", + "customizeText": "Ubah...", + "deathsTallyText": "${COUNT} kematian", + "deathsText": "Kematian", + "debugText": "debug", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Penting!: disarankan untuk mengatur Pengaturan->Grafis->Tekstur ke 'Tinggi' saat mencoba ini.", + "runCPUBenchmarkText": "Menjalankan CPU Benchmark", + "runGPUBenchmarkText": "Jalankan GPU Benchmark", + "runMediaReloadBenchmarkText": "Menjalankan Media-Reload Benchmark", + "runStressTestText": "Menjalankan test stress", + "stressTestPlayerCountText": "Jumlah Pemain", + "stressTestPlaylistDescriptionText": "Daftar Putar Stres Tes", + "stressTestPlaylistNameText": "Nama Daftar Putar", + "stressTestPlaylistTypeText": "Tipe Daftar Putar", + "stressTestRoundDurationText": "Durasi Permainan", + "stressTestTitleText": "Uji Stres", + "titleText": "Uji Tolak Ukur % Stres", + "totalReloadTimeText": "Total waktu memuat: ${TIME} (lihat log untuk selengkapnya)" + }, + "defaultGameListNameText": "Daftar Putar ${PLAYMODE} Semula", + "defaultNewGameListNameText": "Daftar Putar ${PLAYMODE} Ku", + "deleteText": "Hapus", + "demoText": "Demo", + "denyText": "Tolak", + "deprecatedText": "Usang", + "desktopResText": "Resolusi Desktop", + "deviceAccountUpgradeText": "Peringatan:\nKamu masuk dengan akun perangkat (${NAME}).\nAkun perangkat akan dihilangkan pada pembaharuan yg akan datang.\nTingkatkan ke akun V2 jika kamu ingin pertahankan kemajuanmu.", + "difficultyEasyText": "Mudah", + "difficultyHardOnlyText": "Khusus Mode Sulit", + "difficultyHardText": "Sulit", + "difficultyHardUnlockOnlyText": "Level ekspedisi ini khusus untuk mode sulit. \nKamu pikir kamu bisa!?!?!", + "directBrowserToURLText": "dimohon langsung ke web-browser untuk URL:", + "disableRemoteAppConnectionsText": "Matikan Koneksi App-Remot", + "disableXInputDescriptionText": "Izinkan lebih dari 4 pengontrol tapi mungkin agak lemot.", + "disableXInputText": "Blokir XInput", + "doneText": "Selesai", + "drawText": "Seri", + "duplicateText": "Duplikat", + "editGameListWindow": { + "addGameText": "Tambah\nPermainan", + "cantOverwriteDefaultText": "Tidak dapat mengubah daftar putar asal!", + "cantSaveAlreadyExistsText": "Daftar Putar dengan nama ini sudah ada!", + "cantSaveEmptyListText": "Tidak dapat menyimpan daftar putar kosong!", + "editGameText": "Ubah\nPermainan", + "listNameText": "Nama Daftar Putar", + "nameText": "Nama", + "removeGameText": "Hapus\nPermainan", + "saveText": "Simpan Daftar", + "titleText": "Penyusun Daftar Putar" + }, + "editProfileWindow": { + "accountProfileInfoText": "Profil spesial ini mengikuti nama\ndan ikon sesuai akun Kamu.\n\n${ICONS}\n\nBuat profil lain untuk menggunakan\nnama dan ikon yang berbeda.", + "accountProfileText": "(Profil Akun)", + "availableText": "Nama ini \"${NAME}\" tersedia.", + "characterText": "Karakter", + "checkingAvailabilityText": "Memeriksa Ketersediaan \"${NAME}\"...", + "colorText": "warna", + "getMoreCharactersText": "Dapatkan karakter lain...", + "getMoreIconsText": "Dapatkan ikon lain...", + "globalProfileInfoText": "Profil pemain global dijamin untuk memiliki nama unik\ndi seluruh dunia. Termasuk juga ikon lain.", + "globalProfileText": "(Profil Global)", + "highlightText": "highlight", + "iconText": "ikon", + "localProfileInfoText": "Profile lokal tidak mempunyai ikon dan nama \ntidak terjamin unik. Tingkatkan ke profil global \nuntuk mendapatkan nama unik dan dapat menambahkan ikon kustom.", + "localProfileText": "(Profil lokal)", + "nameDescriptionText": "Nama Pemain", + "nameText": "Nama", + "randomText": "Acak", + "titleEditText": "Ubah Profil", + "titleNewText": "Profil Baru", + "unavailableText": "\"${NAME}\" tidak tersedia; coba nama lain.", + "upgradeProfileInfoText": "Ini akan jadi nama Kamu dalam game ini\ndan memungkinkan Kamu untuk menetapkan ikon kustom.", + "upgradeToGlobalProfileText": "Tingkatkan ke Profil Global" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Kamu tidak dapat menghapus soundtrack asal.", + "cantEditDefaultText": "Tidak dapat mengubah soundtrack asal. Gandakan atau buat soundtrack baru.", + "cantOverwriteDefaultText": "tidak dapat menimpa soundtrack asal", + "cantSaveAlreadyExistsText": "Soundtrack dengan nama ini telah digunakan!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Soundtrack Asal", + "deleteConfirmText": "Hapus Soundtrack:\n\n'${NAME}'?", + "deleteText": "Hapus\nSoundtrack", + "duplicateText": "Gandakan\nSoundtrack", + "editSoundtrackText": "Pengaturan Soundtrack", + "editText": "Ubah\nSoundtrack", + "fetchingITunesText": "Mengambil playlist Music App...", + "musicVolumeZeroWarning": "Perhatian: suara musik menjadi 0", + "nameText": "Nama", + "newSoundtrackNameText": "Soundtrack saya ${COUNT}", + "newSoundtrackText": "Soundtrack Baru:", + "newText": "Buat\nSoundtrack", + "selectAPlaylistText": "Pilih Daftar Putar", + "selectASourceText": "Sumber Musik", + "testText": "Tes", + "titleText": "Soundtrack", + "useDefaultGameMusicText": "Musik Game Asal", + "useITunesPlaylistText": "Daftar Putar Apl. Musik", + "useMusicFileText": "Data Musik (mp3, dll)", + "useMusicFolderText": "berkas dari Data Musik" + }, + "editText": "Edit", + "endText": "Akhiri", + "enjoyText": "Nikmati!", + "epicDescriptionFilterText": "${DESCRIPTION} dalam slow-motion yang epik.", + "epicNameFilterText": "${NAME} Epik", + "errorAccessDeniedText": "akses ditolak", + "errorDeviceTimeIncorrectText": "Waktu di perangkatmu berbeda ${HOURS} jam.\nIni akan menyebabkan masalah.\nSilahkan cek pengaturan jam dan zona waktu anda.", + "errorOutOfDiskSpaceText": "media penyimpanan tidak cukup", + "errorSecureConnectionFailText": "Tidak bisa mendirikan koneksi aman; fungsi jaringan mungkin gagal.", + "errorText": "Kesalahan!", + "errorUnknownText": "kesalahan tak teridentifikasi", + "exitGameText": "Keluar dari ${APP_NAME}?", + "exportSuccessText": "'${NAME}' TEREXPORT", + "externalStorageText": "Penyimpanan Eksternal", + "failText": "Gagal", + "fatalErrorText": "O-ow, sesuatu hilang atau rusak. \nCoba install ulang BombSquad atau kontak\n${EMAIL} untuk bantuan.", + "fileSelectorWindow": { + "titleFileFolderText": "Pilih File atau Folder", + "titleFileText": "Ambil File", + "titleFolderText": "Pilih Folder", + "useThisFolderButtonText": "Gunakan Folder" + }, + "filterText": "Filter", + "finalScoreText": "Skor Final", + "finalScoresText": "Skor Final", + "finalTimeText": "Waktu Final", + "finishingInstallText": "Selesai menginstall, tunggu sebentar...", + "fireTVRemoteWarningText": "* Untuk mempermudah, gunakan\npengontrol permainan atau pasang\naplikasi '${REMOTE_APP_NAME}'\ndi HP atau tabletmu.", + "firstToFinalText": "Final Pertama Mencapai ${COUNT}", + "firstToSeriesText": "Pertama Mencapai ${COUNT}", + "fiveKillText": "MATI LIMA!!", + "flawlessWaveText": "Gelombang Mulus!", + "fourKillText": "MATI EMPAT!!", + "friendScoresUnavailableText": "Skor teman tidak tersedia.", + "gameCenterText": "PusatGame", + "gameCircleText": "LingkaranGame", + "gameLeadersText": "Pemimpin Game ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "Kamu tidak dapat menghapus daftar putar asal.", + "cantEditDefaultText": "Tidak dapat mengubah Daftar Putar asal! Gandakan atau buat baru.", + "cantShareDefaultText": "Kamu tidak dapat bagikan playlist semula", + "deleteConfirmText": "Hapus \"${LIST}\"?", + "deleteText": "Hapus\nDaftar Putar", + "duplicateText": "Gandakan\nDaftar Putar", + "editText": "Ubah\nDaftar Putar", + "newText": "Buat\nDaftar Putar", + "showTutorialText": "Lihat Panduan", + "shuffleGameOrderText": "Acak Urutan Game", + "titleText": "Ubah ${TYPE} Daftar Putar" + }, + "gameSettingsWindow": { + "addGameText": "Tambah Game" + }, + "gamesToText": "${WINCOUNT} menang lawan ${LOSECOUNT} menang", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Catatan: tiap perangkat dapat punya lebih dari\nsatu pemain jika memang ada pengontrol yang cukup.", + "aboutDescriptionText": "Gunakan tab ini untuk mengadakan acara.\n\nDengan adanya acara, Kamu dapat bermain\ndengan teman di perangkat yang berbeda.\n\nGunakan tombol ${PARTY} di kanan atas\nuntuk chat dan berinteraksi di acara. \n(pada pengontrol, tekan ${BUTTON} saat di menu)", + "aboutText": "Perihal", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} mengirim ${COUNT} tiket ke ${APP_NAME}", + "appInviteSendACodeText": "Kirimkan Kode", + "appInviteTitleText": "Undangan Aplikasi ${APP_NAME}", + "bluetoothAndroidSupportText": "(bekerja dengan semua Android yang punya Bluetooth)", + "bluetoothDescriptionText": "Buat/ikut acara lewat Bluetooth:", + "bluetoothHostText": "Adakan acara!", + "bluetoothJoinText": "Ikut acara!", + "bluetoothText": "Bluetooth", + "checkingText": "memeriksa...", + "copyCodeConfirmText": "Kode disalin ke papan klip.", + "copyCodeText": "Salin Kode", + "dedicatedServerInfoText": "Untuk hasil terbaik, buatlah server yang bagus. Lihat bombsquadgame.com/server untuk membuatnya", + "disconnectClientsText": "Ini akan memutuskan sambungan ${COUNT} pemain\ndi acaramu. Apa kamu yakin?", + "earnTicketsForRecommendingAmountText": "Teman Kamu akan mendapatkan ${COUNT} tiket jika mereka memainkan game ini\n(dan Kamu akan mendapatkan ${YOU_COUNT} untuk setiap mereka memainkan game ini)", + "earnTicketsForRecommendingText": "Bagikan permainan\nuntuk tiket gratis...", + "emailItText": "Lewat Surel", + "favoritesSaveText": "Simpan Sebagai Favorit", + "favoritesText": "Favorit", + "freeCloudServerAvailableMinutesText": "Server cloud gratis berikutnya tersedia dalam ${MINUTES} menit.", + "freeCloudServerAvailableNowText": "Server cloud gratis tersedia!", + "freeCloudServerNotAvailableText": "Tidak ada server cloud gratis yang tersedia.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} tiket dari ${NAME}", + "friendPromoCodeAwardText": "Kamu akan mendapatkan ${COUNT} tiket setiap kode ini digunakan.", + "friendPromoCodeExpireText": "kode ini akan berakhir dalam ${EXPIRE_HOURS} jam dan hanya berlaku untuk pemain baru.", + "friendPromoCodeInstructionsText": "Untuk menggunakannya, buka ${APP_NAME} dan buka \"Pengaturan-> Lanjutan-> Masukkan Kode\".\nLihat bombsquadgame.com untuk tautan unduhan untuk semua platform yang didukung.", + "friendPromoCodeRedeemLongText": "ini dapat digunakan untuk ${COUNT} tiket gratis hingga batas maksimal ${MAX_USES} orang.", + "friendPromoCodeRedeemShortText": "ini dapat digunkanan untuk mendapatkan ${COUNT} tiket.", + "friendPromoCodeWhereToEnterText": "(di \"Pengaturan-> Lanjutan-> Masukkan Kode\")", + "getFriendInviteCodeText": "Dapatkan Kode Undangan Teman", + "googlePlayDescriptionText": "Undang pemain Google Play ke acaramu:", + "googlePlayInviteText": "Undang", + "googlePlayReInviteText": "Ada ${COUNT} pemain Google Play di acaramu\nyang akan terputus jika Kamu undang ulang. \nJangan lupa masukan mereka ke undangan.", + "googlePlaySeeInvitesText": "Lihat Undangan", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(versi Android / Google Play)", + "hostPublicPartyDescriptionText": "Selenggarakan Acara Publik", + "hostingUnavailableText": "Hosting Tidak Tersedia", + "inDevelopmentWarningText": "Catatan:\n\nBermain dalam jaringan masih baru dan dalam\nperkembangan. Sementara, sangat disarankan para\npemain ada di jaringan Wi-Fi yang sama.", + "internetText": "Internet", + "inviteAFriendText": "Teman Kamu belum memainkan ini? undang mereka sekarang\ndan mereka akan mendapatkan ${COUNT} tiket gratis.", + "inviteFriendsText": "Undang Teman", + "joinPublicPartyDescriptionText": "Gabung dengan Acara Publik", + "localNetworkDescriptionText": "Bergabunglah dengan Acara Terdekat (LAN, Bluetooth, dll.)", + "localNetworkText": "Jaringan Lokal", + "makePartyPrivateText": "Buat acaraku pribadi", + "makePartyPublicText": "Buat acaraku publik", + "manualAddressText": "Alamat", + "manualConnectText": "Hubungkan", + "manualDescriptionText": "Ikut acara di alamat:", + "manualJoinSectionText": "Gabung Berdasarkan Alamat", + "manualJoinableFromInternetText": "Apakah Kamu dapat bergabung internet?:", + "manualJoinableNoWithAsteriskText": "TIDAK*", + "manualJoinableYesText": "YA", + "manualRouterForwardingText": "*untuk memperbaiki, coba dengan mengkonfigurasi router ke UDP port ${PORT} ke alamat lokal Kamu", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Alamat Kamu dari internet:", + "manualYourLocalAddressText": "Alamat lokal Kamu:", + "nearbyText": "Dekat", + "noConnectionText": "", + "otherVersionsText": "(Versi lain)", + "partyCodeText": "Kode Acara", + "partyInviteAcceptText": "Terima", + "partyInviteDeclineText": "Tolak", + "partyInviteGooglePlayExtraText": "(Lihat tab 'Google Play' di jendela 'Berkumpul')", + "partyInviteIgnoreText": "Abaikan", + "partyInviteText": "${NAME} mengundangmu\nke acaranya!", + "partyNameText": "Nama acara", + "partyServerRunningText": "Server acara Anda sedang berjalan.", + "partySizeText": "ukuran acara", + "partyStatusCheckingText": "memeriksa status...", + "partyStatusJoinableText": "sekarang orang lain dapat gabung ke acaramu dari internet", + "partyStatusNoConnectionText": "Tidak dapat terhubung ke server", + "partyStatusNotJoinableText": "orang lain gak dapat gabung ke acaramu lewat internet", + "partyStatusNotPublicText": "acaramu bukan acara publik", + "pingText": "Ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Acara pribadi dijalankan di server cloud khusus; tidak diperlukan konfigurasi router.", + "privatePartyHostText": "Adakan Acara Pribadi", + "privatePartyJoinText": "Gabung di Acara Pribadi", + "privateText": "Pribadi", + "publicHostRouterConfigText": "Ini mungkin memerlukan konfigurasi penerusan port di router Anda. Untuk opsi yang lebih mudah, adakan acara pribadi.", + "publicText": "Publik", + "requestingAPromoCodeText": "Memesan Kode...", + "sendDirectInvitesText": "Kirim Undangan", + "shareThisCodeWithFriendsText": "Bagikan kode ini ke teman-teman mu!", + "showMyAddressText": "Tunjukkan Alamatku", + "startHostingPaidText": "Host Sekarang Dengan ${COST}", + "startHostingText": "Host", + "startStopHostingMinutesText": "Anda dapat memulai dan menghentikan hosting gratis untuk ${MINUTES} menit berikutnya.", + "stopHostingText": "Hentikan Hosting", + "titleText": "Gabung", + "wifiDirectDescriptionBottomText": "Jika semua perangkat punya tab 'Wi-Fi Direct', maka seharusnya semua dapat saling\nkoneksi. Ketika sudah konek semua, buat team\ndi tab 'Jaringan Lokal', seperti Wi-Fi biasa.\n\nUntuk hasil maksimal, host Wi-Fi Direct juga harus sebagai host team di ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct dapat digunakan untuk koneksi Android tanpa hotspot.\nBekerja paling bagus pada Android 4.2 lebih.\n\nUntuk itu, buka Pengaturan Wi-Fi dan pilih 'Wi-Fi Direct' di menu.", + "wifiDirectOpenWiFiSettingsText": "Buka Pengaturan Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(bekerja antar platform)", + "worksWithGooglePlayDevicesText": "(bekerja antar perangkat yang menggunakan versi Android)", + "youHaveBeenSentAPromoCodeText": "Kamu telah mengirim sebuah kode promo ${APP_NAME}!" + }, + "getTicketsWindow": { + "freeText": "Gratis!", + "freeTicketsText": "Tiket Gratis", + "inProgressText": "Transaksi sedang dalam proses; mohon dicoba lagi nanti.", + "purchasesRestoredText": "Pembelian dipulihkan.", + "receivedTicketsText": "Mendapatkan ${COUNT} tiket!", + "restorePurchasesText": "Memulihkan Pembelian", + "ticketPack1Text": "Paket Tiket Kecil", + "ticketPack2Text": "Paket Tiket Sedang", + "ticketPack3Text": "Paket Tiket Besar", + "ticketPack4Text": "Paket Tiket Jumbo", + "ticketPack5Text": "Paket Tiket Raksasa", + "ticketPack6Text": "Paket Tiket Berlimpah", + "ticketsFromASponsorText": "Tonton iklan\nuntuk ${COUNT} tiket", + "ticketsText": "${COUNT} tiket", + "titleText": "Dapatkan Tiket", + "unavailableLinkAccountText": "Maaf, pembelian tidak dapat dilakukan di perangkat ini.\nsebagai antisipasi, kamu dapat menautkan akun ini ke perangkat\nlain dan melakukan pembelian di sana.", + "unavailableTemporarilyText": "mohon maaf, saat ini layanan tidak tersedia; mohon dicoba lagi lain waktu.", + "unavailableText": "Maaf, tidak tersedia.", + "versionTooOldText": "Maaf, versi permainan ini terlalu usang; silahkan perbaharui dengan yang terbaru.", + "youHaveShortText": "kamu memiliki ${COUNT}", + "youHaveText": "kamu memiliki ${COUNT} tiket" + }, + "googleMultiplayerDiscontinuedText": "Maaf, Google's multiplayer service tidak lagi tersedia.\nSaya sedang bekerja pada penggantian secepat mungkin.\nHingga saat itu, silakan coba metode koneksi lainnya.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Pembayaran Google Play tidak tersedia.\nMungkin perlu memperbaharui Playstore anda.", + "googlePlayServicesNotAvailableText": "Layanan Google Play tidak tersedia.\nBeberapa fungsi dari aplikasi mungkin padam.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Selalu", + "fullScreenCmdText": "Layar Penuh (Cmd-F)", + "fullScreenCtrlText": "Layar Penuh (Ctrl+F)", + "gammaText": "Gamma", + "highText": "Tinggi", + "higherText": "Tertinggi", + "lowText": "Rendah", + "mediumText": "Sedang", + "neverText": "Tak Pernah", + "resolutionText": "Resolusi", + "showFPSText": "Tampilkan FPS", + "texturesText": "Tekstur", + "titleText": "Grafik", + "tvBorderText": "Perbatasan TV", + "verticalSyncText": "Vertical Sync", + "visualsText": "Visual" + }, + "helpWindow": { + "bombInfoText": "- Bomb -\nLebih kuat dari Tinju, tapi\ndapat menjadi bom bunuh diri.\nCoba untuk melempar sebelum\nsumbu akan habis.", + "canHelpText": "${APP_NAME} Solusinya!", + "controllersInfoText": "Kamu dapat bermain ${APP_NAME} dengan temanmu melalui sebuah\nJaringan, atau kamu dapat bermain dalam perangkat yang sama\njika kamu memiliki kontrol yang cukup. ${APP_NAME} menyediakan\npengontrol digital melalui aplikasi '${REMOTE_APP_NAME}'.\nlihat di Pengaturan -> Kontrol untuk info lebih lanjut.", + "controllersInfoTextRemoteOnly": "Anda bisa bermain ${APP_NAME} bersama dengan teman melalui jaringan, \natau kalian semua bisa bermain di perangkat yang sama dengan menggunakan ponsel sebagai pengontrol melalui aplikasi \n'${REMOTE_APP_NAME}' gratis.", + "controllersText": "Kontrol", + "controlsSubtitleText": "karakter ${APP_NAME} Memiliki beberapa gerakan dasar:", + "controlsText": "Kontrol", + "devicesInfoText": "Versi VR dari ${APP_NAME} dapat dimainkan lewat jaringan dengan\nversi reguler. Jadi siapkan ponsel, Tablet atau Komputermu\ndan Mainkan Game ini! Fitur ini juga dapat menjadi menyenangkan\ndengan cara mengizinkan orang lain melihat permainan Kamu saat\nmenggunakan VR!", + "devicesText": "Perangkat", + "friendsGoodText": "Sangat diperlukan. ${APP_NAME} Sangat menyenangkan dengan beberapa\npemain (maksimal 8 pemain) dalam sekali permainan.", + "friendsText": "Teman", + "jumpInfoText": "- Lompat -\nLompat untuk melewati gundukan,\nmelempar lebih jauh, dan\nmengekspresikan kebehagiaan Kamu.", + "orPunchingSomethingText": "Atau menghajar sesuatu, melemparnya ke Jurang, dan meledakannya dengan beberapa bom mematikan.", + "pickUpInfoText": "- Angkat -\nMengangkat Bendera, Musuh, atau\napapun yang tidak melekat di tanah.\nTekan sekali lagi untuk melempar.", + "powerupBombDescriptionText": "Memberikan Kamu 3 bom sekaligus.\nLebih baik dari pada 1.", + "powerupBombNameText": "Bomb Beruntun", + "powerupCurseDescriptionText": "Hindari ini segera jika kamu \ntidak ingin mati!", + "powerupCurseNameText": "Kutukan", + "powerupHealthDescriptionText": "Mengembalikan darah Kamu\nseperti semula.", + "powerupHealthNameText": "Kotak Medis", + "powerupIceBombsDescriptionText": "Lebih lemah dari bom biasa\ntapi membuat musuh Kamu beku,\npanik, gelisah, dan rapuh.", + "powerupIceBombsNameText": "Bom Beku", + "powerupImpactBombsDescriptionText": "Sedikit lebih lemah dari bom\nbiasa, tapi akan meledak saat terbentur.", + "powerupImpactBombsNameText": "Bom Pemicu", + "powerupLandMinesDescriptionText": "berisi 3 paket; berguna untuk\nbertahan atau menghentikan\nlangkah musuhmu.", + "powerupLandMinesNameText": "Ranjau", + "powerupPunchDescriptionText": "Membuat tinjumu lebih kuat,\nlebih cepat, bahkan lebih baik.", + "powerupPunchNameText": "Sarung Tinju", + "powerupShieldDescriptionText": "menahan beberapa serangan\nsehingga darah Kamu tidak berkurang.", + "powerupShieldNameText": "Energi Pelindung", + "powerupStickyBombsDescriptionText": "Lengket ke apapun yang tersentuh.\nSungguh Menjijikkan.", + "powerupStickyBombsNameText": "Bom Lengket", + "powerupsSubtitleText": "Jelas sekali, tidak ada game yang bakal seru tanpa Kekuatan Tambahan:", + "powerupsText": "Kekuatan Tambahan", + "punchInfoText": "- Tinju -\nTinju lebih merusak saat\nKamu bergerak cepat. Jadi lari\ndan berputarlah seperti orang gila.", + "runInfoText": "- Lari -\nSEMUA tombol dapat digunakan untuk lari. Kecuali tombol pusar Kamu, haha. Lari\ndapat membuat Kamu cepat tapi sulit untuk berbelok, jadi hati-hati dengan jurang.", + "someDaysText": "Terkadang, kamu ingin sekali menghajar sesuatu atau menghancurkan sesuatu.", + "titleText": "Bantuan ${APP_NAME}", + "toGetTheMostText": "Untuk menikmati game ini, kamu perlu menyiapkan:", + "welcomeText": "Selamat datang di ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} sedang merenung untuk memilih menu -", + "importPlaylistCodeInstructionsText": "Masukan kode untuk mengimpor playlist :", + "importPlaylistSuccessText": "Terimpor ${TYPE} daftar putar '${NAME}'", + "importText": "Impor", + "importingText": "Mengimpor...", + "inGameClippedNameText": "dalam game akan\n\"${NAME}\"", + "installDiskSpaceErrorText": "ERROR: Gagal menginstall. \nMungkin penyimpanan Kamu terlalu penuh. \nMohon hapus beberapa file dan coba lagi.", + "internal": { + "arrowsToExitListText": "tekan ${LEFT} atau ${RIGHT} untuk keluar", + "buttonText": "Tombol", + "cantKickHostError": "Kamu tak dapat mengeluarkan host", + "chatBlockedText": "${NAME} di blokir chatnya selama ${TIME} detik.", + "connectedToGameText": "'${NAME}' Bergabung", + "connectedToPartyText": "Bergabung ke team ${NAME}!", + "connectingToPartyText": "Menyambung...", + "connectionFailedHostAlreadyInPartyText": "Sambungan Gagal, Host sedang dalam team lain.", + "connectionFailedPartyFullText": "Koneksi gagal; acara sudah penuh", + "connectionFailedText": "Gagal Menghubungkan.", + "connectionFailedVersionMismatchText": "Gagal menghubungkan; Host sedang menjalankan versi lain dari game ini.\nPastikan kamu memperbarui game lalu coba lagi.", + "connectionRejectedText": "Sambungan ditolak.", + "controllerConnectedText": "${CONTROLLER} tersambung.", + "controllerDetectedText": "1 pengontrol terdeteksi.", + "controllerDisconnectedText": "${CONTROLLER} terputus.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} terputus. Silahkan menghubungkan kembali.", + "controllerForMenusOnlyText": "Pengontrol ini tidak dapat digunakan untuk bermain, hanya untuk memilih menu.", + "controllerReconnectedText": "${CONTROLLER} terhubung kembali.", + "controllersConnectedText": "${COUNT} pengontrol terhubung.", + "controllersDetectedText": "${COUNT} pengontrol terdeteksi.", + "controllersDisconnectedText": "${COUNT} pengontrol terputus.", + "corruptFileText": "Data rusak terdeteksi. dimohon untuk pasang ulang, atau kirimkan surel ke ${EMAIL}", + "errorPlayingMusicText": "Gagal memutar musik: ${MUSIC}", + "errorResettingAchievementsText": "Tidak dapat mengulang Online Achievments; dimohon coba lagi.", + "hasMenuControlText": "${NAME} mempunyai kendali menu.", + "incompatibleNewerVersionHostText": "Host menggunakan versi baru dari game ini\nSilakan perbarui dan coba lagi", + "incompatibleVersionHostText": "Host berjalan dengan versi yang berbeda dengan game.\nPastikan Kamu up-to-date dan coba lagi", + "incompatibleVersionPlayerText": "${NAME} menjalankan versi game yang berbeda.\nPastikan versi game kalian sama dan coba lagi.", + "invalidAddressErrorText": "Error: alamat tidak jelas.", + "invalidNameErrorText": "Error: nama tidak jelas.", + "invalidPortErrorText": "Error: port tidak jelas.", + "invitationSentText": "Undangan terkirim.", + "invitationsSentText": "${COUNT} undangan terkirim.", + "joinedPartyInstructionsText": "Seseorang bergabung di acaramu.\nTekan 'Main' untuk mulai permainan.", + "keyboardText": "Keyboard", + "kickIdlePlayersKickedText": "Mengeluarkan ${NAME} karena diam.", + "kickIdlePlayersWarning1Text": "${NAME} akan dikeluarkan dalam ${COUNT} detik jika masih diam.", + "kickIdlePlayersWarning2Text": "(Kamu dapat mematikan ini di Pengaturan -> Lanjutan)", + "leftGameText": "Keluar '${NAME}'.", + "leftPartyText": "Keluar dari acara ${NAME}'", + "noMusicFilesInFolderText": "Folder tidak memiliki file musik.", + "playerJoinedPartyText": "${NAME} bergabung ke acara!", + "playerLeftPartyText": "${NAME} keluar dari acara.", + "rejectingInviteAlreadyInPartyText": "Membatalkan undangan (sudah ada di acara).", + "serverRestartingText": "Memulai ulang. Silakan masuk dalam beberapa saat lagi", + "serverShuttingDownText": "Server sedang menutup...", + "signInErrorText": "Gagal masuk", + "signInNoConnectionText": "Gagal masuk. (apa jaringanmu tidak terkoneksi internet?)", + "telnetAccessDeniedText": "ERROR: pengguna tidak mengizinkan akses telnet.", + "timeOutText": "(waktu akan habis dalam ${TIME} detik lagi)", + "touchScreenJoinWarningText": "Kamu telah bergabung dengan layar sentuh.\nJika ini kesalahan. tekan 'Menu->Mode Penonton' saja", + "touchScreenText": "Layar Sentuh", + "unableToResolveHostText": "Error:Tidak dapat menyambung pada server", + "unavailableNoConnectionText": "Maaf, layanan tidak tersedia (apa jaringanmu tidak terkoneksi internet?)", + "vrOrientationResetCardboardText": "Gunakan ini untuk mengulang orientasi VR.\nUntuk memainkan game ini Kamu harus mempunyai kontroller eksternal.", + "vrOrientationResetText": "Atur ulang orientasi VR", + "willTimeOutText": "(waktu habis jika diam)" + }, + "jumpBoldText": "LOMPAT", + "jumpText": "Lompat", + "keepText": "Simpan", + "keepTheseSettingsText": "Simpan pengaturan ini?", + "keyboardChangeInstructionsText": "Tekan spasi dua kali untuk mengubah keyboard.", + "keyboardNoOthersAvailableText": "Tidak ada keyboard lain tersedia.", + "keyboardSwitchText": "Mengalihkan keyboard ke \"${NAME}\".", + "kickOccurredText": "${NAME} dikeluarkan.", + "kickQuestionText": "Keluarkan ${NAME}?", + "kickText": "Keluarkan", + "kickVoteCantKickAdminsText": "Admin tidak dapat dikeluarkan", + "kickVoteCantKickSelfText": "Kamu tidak dapat mengeluarkan dirimu sendiri", + "kickVoteFailedNotEnoughVotersText": "Tidak cukup pemain untuk pengambilan suara.", + "kickVoteFailedText": "Pengambilan suara untuk mengeluarkan pemain gagal", + "kickVoteStartedText": "Pengambilan suara untuk mengeluarkan ${NAME} sudah dimulai.", + "kickVoteText": "Tentukan suara untuk mengeluarkan", + "kickVotingDisabledText": "Pengambilan suara untuk mengeluarkan pemain di nonaktifkan", + "kickWithChatText": "Ketik ${YES} di kolom obrolan jika setuju dan ${NO} jika tidak setuju.", + "killsTallyText": "${COUNT} pembunuhan", + "killsText": "Pembunuhan", + "kioskWindow": { + "easyText": "Mudah", + "epicModeText": "Mode Epik", + "fullMenuText": "Semua Menu", + "hardText": "Sulit", + "mediumText": "Sedang", + "singlePlayerExamplesText": "Coontoh Main Sendiri / Berteman", + "versusExamplesText": "Contoh Versus" + }, + "languageSetText": "Bahasa yang sedang digunakan adalah \"${LANGUAGE}\".", + "lapNumberText": "Putaran ${CURRENT}/${TOTAL}", + "lastGamesText": "(${COUNT} game terakhir)", + "leaderboardsText": "Papan Juara", + "league": { + "allTimeText": "Keseluruhan", + "currentSeasonText": "Musim Sekarang (${NUMBER})", + "leagueFullText": "Liga ${NAME}", + "leagueRankText": "Peringkat Liga", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "Musim berakhir ${NUMBER} hari yang lalu", + "seasonEndsDaysText": "Musim berakhir ${NUMBER} hari lagi", + "seasonEndsHoursText": "Musim berakhir ${NUMBER} jam lagi", + "seasonEndsMinutesText": "Musim berakhir ${NUMBER} menit lagi", + "seasonText": "Musim ${NUMBER}", + "tournamentLeagueText": "Kamu harus berada di liga ${NAME} untuk memasukinya", + "trophyCountsResetText": "Hitungan trofimu akan diulang di musim berikutnya" + }, + "levelBestScoresText": "Skor terbaik di ${LEVEL}", + "levelBestTimesText": "Waktu terbaik di ${LEVEL}", + "levelFastestTimesText": "Waktu tercepat pada ${LEVEL}", + "levelHighestScoresText": "Skor tertinggi pada ${LEVEL}", + "levelIsLockedText": "${LEVEL} terbuka.", + "levelMustBeCompletedFirstText": "Selesaikan ${LEVEL} dulu.", + "levelText": "Level ${NUMBER}", + "levelUnlockedText": "Level Terbuka!", + "livesBonusText": "Nyawa Tambahan", + "loadingText": "memuat", + "loadingTryAgainText": "Memuat; Coba lagi nanti.. sabar ya..", + "macControllerSubsystemBothText": "Keduanya (Tidak direkomendasikan)", + "macControllerSubsystemClassicText": "Klasik", + "macControllerSubsystemDescriptionText": "Coba ubah ini jika pengontrol Kamu tidak bekerja", + "macControllerSubsystemMFiNoteText": "Pengontrol yang dibuat-untuk-ios/Mac terdeteksi;\nKamu mungkin ingin mengaktifkanya melalui Pengaturan -> Pengontrol", + "macControllerSubsystemMFiText": "Dibuat-untuk-iOS/Mac", + "macControllerSubsystemTitleText": "Dukungan pengontrol", + "mainMenu": { + "creditsText": "Kredit", + "demoMenuText": "Menu Demo", + "endGameText": "Akhiri Permainan", + "endTestText": "Akhiri Pengetesan", + "exitGameText": "Keluar dari Permainan", + "exitToMenuText": "Ke Menu?", + "howToPlayText": "Cara bermain", + "justPlayerText": "(Hanya ${NAME})", + "leaveGameText": "Mode Penonton", + "leavePartyConfirmText": "Yakin Ingin Keluar?", + "leavePartyText": "Keluar", + "quitText": "Berhenti", + "resumeText": "Lanjutkan", + "settingsText": "Pengaturan" + }, + "makeItSoText": "Jadilah Demikian", + "mapSelectGetMoreMapsText": "Arena Lainnya", + "mapSelectText": "Pilih", + "mapSelectTitleText": "Arena ${GAME}", + "mapText": "Arena", + "maxConnectionsText": "Koneksi maksimal", + "maxPartySizeText": "Besar Ukuran Maksimal", + "maxPlayersText": "Jumlah Pemain Maksimal", + "merchText": "Merchandise!", + "modeArcadeText": "Mode Arcade", + "modeClassicText": "Mode Klasik", + "modeDemoText": "Mode Demo", + "mostValuablePlayerText": "Pemain Terunggul", + "mostViolatedPlayerText": "Pemain Teraniaya", + "mostViolentPlayerText": "Pemain Terkejam", + "moveText": "Gerak", + "multiKillText": "${COUNT} MATI!!", + "multiPlayerCountText": "${COUNT} pemain", + "mustInviteFriendsText": "CATATAN: kamu harus mengundang teman di\nopsi \"${GATHER}\" atau pasang\npengontrol untuk bermain di mode multi-pemain", + "nameBetrayedText": "${NAME} membunuh rekannya ${VICTIM}", + "nameDiedText": "${NAME} meninggal.", + "nameKilledText": "${NAME} membunuh ${VICTIM}", + "nameNotEmptyText": "Nama harus diisi!", + "nameScoresText": "${NAME} mencetak poin!", + "nameSuicideKidFriendlyText": "${NAME} meninggal tiba-tiba.", + "nameSuicideText": "${NAME} bunuh diri.", + "nameText": "Nama", + "nativeText": "Asli", + "newPersonalBestText": "Rekor Pribadi Baru!", + "newTestBuildAvailableText": "Uji coba baru tersedia! (${VERSION} bangun ${BUILD}).\nDapatkan di ${ADDRESS}", + "newText": "Baru", + "newVersionAvailableText": "Versi ${APP_NAME} terbaru tersedia", + "nextAchievementsText": "Pencapaian berikutnya:", + "nextLevelText": "Level Berikutnya", + "noAchievementsRemainingText": "- tidak ada", + "noContinuesText": "(tidak dapat melanjutkan)", + "noExternalStorageErrorText": "Tidak ada penyimpanan eksternal", + "noGameCircleText": "Kesalahan: tidak masuk ke LingkaranGame", + "noProfilesErrorText": "Kamu tidak punya profil pemain, jadi '${NAME}' dipakai. \nMasuk Pengaturan->Profil Pemain untuk membuat profil. ", + "noScoresYetText": "Belum ada skor.", + "noThanksText": "Tidak, Terima kasih", + "noTournamentsInTestBuildText": "PERHATIAN: Skor turnamen dari build tes ini akan di abaikan", + "noValidMapsErrorText": "Tidak ada arena valid untuk game ini.", + "notEnoughPlayersRemainingText": "Tidak ada pemain tersisa; keluar dan main ulang.", + "notEnoughPlayersText": "Kamu butuh sedikitnya ${COUNT} pemain untuk memulai permainan!", + "notNowText": "Jangan Sekarang", + "notSignedInErrorText": "Kamu harus masuk untuk lakukan ini.", + "notSignedInGooglePlayErrorText": "Kamu harus masuk pakai Google Play untuk lakukan ini.", + "notSignedInText": "belum masuk", + "notUsingAccountText": "Catatan: mengabaikan akun ${SERVICE}.\nPergi ke 'Akun -> Masuk dengan ${SERVICE}' jika kamu ingin gunakan.", + "nothingIsSelectedErrorText": "Tidak ada yang dipilih!", + "numberText": "#${NUMBER}", + "offText": "Mati", + "okText": "Baik", + "onText": "Nyala", + "oneMomentText": "Sebentar...", + "onslaughtRespawnText": "${PLAYER} akan bangkit pada gelombang ${WAVE}", + "orText": "${A} atau ${B}", + "otherText": "Lainnya...", + "outOfText": "(#${RANK} dari ${ALL})", + "ownFlagAtYourBaseWarning": "Benderamu harus\nberada di basismu!", + "packageModsEnabledErrorText": "Game yang melalui jaringan tidak diperbolehkan ketika mod-paket-lokal diaktifkan (lihat Pengaturan->Lanjutan) ", + "partyWindow": { + "chatMessageText": "Pesan Obrolan", + "emptyText": "acaramu kosong", + "hostText": "(pembuat)", + "sendText": "Kirim", + "titleText": "acaramu" + }, + "pausedByHostText": "(terhenti oleh pemilik)", + "perfectWaveText": "Gelombang Sempurna!", + "pickUpText": "Ambil", + "playModes": { + "coopText": "Koloni", + "freeForAllText": "Saling bunuh", + "multiTeamText": "Multi-Tim", + "singlePlayerCoopText": "Pemain Tunggal / Lawan komputer", + "teamsText": "Tim" + }, + "playText": "Main", + "playWindow": { + "oneToFourPlayersText": "1-4 pemain", + "titleText": "Main", + "twoToEightPlayersText": "2-8 pemain" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} akan masuk pada ronde berikutnya.", + "playerInfoText": "Info Pemain", + "playerLeftText": "${PLAYER} meninggalkan game.", + "playerLimitReachedText": "Batas pemain ${COUNT} tercapai; tidak dapat bergabung lagi.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Kamu tidak dapat menghapus akun profilmu.", + "deleteButtonText": "Hapus\nProfil", + "deleteConfirmText": "Hapus '${PROFILE}'?", + "editButtonText": "Ubah\nProfil", + "explanationText": "(setiap nama pemain dan penampilan kustom untuk akun ini)", + "newButtonText": "Profil\nBaru", + "titleText": "Profil Pemain" + }, + "playerText": "Pemain", + "playlistNoValidGamesErrorText": "Playlist ini mempunyai game terbuka yang tidak valid.", + "playlistNotFoundText": "Daftar Putar tidak ditemukan", + "playlistText": "Daftar Putar", + "playlistsText": "Daftar Putar", + "pleaseRateText": "Jika Kamu menyukai ${APP_NAME}, yuk luangkan waktu sejenak untuk menilai dan membubuhkan komentar. Ini akan membantu kami untuk menyempurnakan permainan yang akan datang.\n\nterima kasih!\n-eric", + "pleaseWaitText": "Mohon tunggu...", + "pluginClassLoadErrorText": "Error saat memuat class plugin '${PLUGIN}':${ERROR}", + "pluginInitErrorText": "Error saat menjalankan plugin '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Pengaturan Plugin", + "pluginsAutoEnableNewText": "Otomatis nyalakan Plugin", + "pluginsDetectedText": "Plugin baru terdeteksi. Mulai ulang game untuk mengaktifkan pluginnya, atau mengaturnya di pengaturan.", + "pluginsDisableAllText": "Matikan semua Plugin", + "pluginsEnableAllText": "Nyalakan semua Plugin", + "pluginsRemovedText": "${NUM} plugin tidak lagi ditemukan.", + "pluginsText": "Plugin", + "practiceText": "Latihan", + "pressAnyButtonPlayAgainText": "Tekan tombol apa saja untuk kembali bermain...", + "pressAnyButtonText": "Tekan tombol apa saja untuk lanjut...", + "pressAnyButtonToJoinText": "tekan apa saja untuk bergabung...", + "pressAnyKeyButtonPlayAgainText": "Tekan apa saja untuk kembali bermain...", + "pressAnyKeyButtonText": "Tekan apa saja untuk lanjut...", + "pressAnyKeyText": "Tekan apa saja...", + "pressJumpToFlyText": "** Tekan tombol lompat terus menerus untuk terbang **", + "pressPunchToJoinText": "tekan PUKUL untuk bergabung..", + "pressToOverrideCharacterText": "tekan ${BUTTONS} untuk menimpa karaktermu.", + "pressToSelectProfileText": "tekan ${BUTTONS} untuk memilih pemain", + "pressToSelectTeamText": "tekan ${BUTTONS} untuk memilih tim", + "promoCodeWindow": { + "codeText": "Kode", + "enterText": "Masuk" + }, + "promoSubmitErrorText": "Kesalahan saat mengirim kode; periksa koneksi internet Kamu", + "ps3ControllersWindow": { + "macInstructionsText": "Matikan daya pada bagian belakang PS3-mu, pastikan\nBluetooth aktif pada Mac-mu, lalu hubungkan kontrollermu\nke Mac-mu dengan kabel USB untuk memasangkannya. Sekarang, Kamu\ndapat menggunakan kontrollermu dengan kabel USB atau Bluetooth.\n\nPada beberapa perangkat Mac, Kamu mungkin akan dimintai kata sandi ketika memasangkannya.\nJika ini terjadi, lihat beberapa petunjuk atau gunakan google untuk meminta bantuan.\n\n\n\n\n\nKontroller PS3 yang terhubung dengan jaringan akan terlihat pada daftar perangkat\ndalam System Preferences->Bluetooth. Kamu mungkin harus menghapusnya\ndalam daftar tersebut ketika Kamu ingin menggunakan kontroller PS3mu kembali.\n\nDan pastikan untuk memutuskannya dari Bluetooth ketika sedang tidak\ndigunakan atau baterainya akan secara otomatis terkuras.\n\nBluetooth biasanya menangani sampai 7 perangkat yang terhubung,\nmeski jarak tempuhmu berbeda.", + "ouyaInstructionsText": "Untuk menggunakan kontroller PS3mu dengan OUYA, hubungkan saja dengan kabel USB\nsekali untuk memasangkannya. Melakukan ini akan memutuskan kontrollermu yang lain, jadi\nKamu harus mengulang OUYA-mu dan cabut kabel USB.\n\nSekarang Kamu seharusnya dapat menggunakan kontrollermu untuk\nmenghubungkannya dengan jaringan. Ketika Kamu sudah selesai bermain, tekan tombol HOME\nselama 10 detik untuk mematikan kontroller; jika itu tetap menyala\nmaka bateraimu akan terkuras habis.", + "pairingTutorialText": "memasangkan video petunjuk", + "titleText": "Menggunakan Kontroller PS3 dengan ${APP_NAME}:" + }, + "punchBoldText": "PUKUL", + "punchText": "Pukul", + "purchaseForText": "Membeli dengan ${PRICE}", + "purchaseGameText": "Membeli Game", + "purchasingText": "Membeli...", + "quitGameText": "Keluar ${APP_NAME}?", + "quittingIn5SecondsText": "Keluar dalam 5 detik...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Acak", + "rankText": "Peringkat", + "ratingText": "Nilai", + "reachWave2Text": "Raih gelombang 2 untuk dapat peringkat", + "readyText": "Siap", + "recentText": "Terbaru", + "remoteAppInfoShortText": "${APP_NAME} akan menyenangkan ketika dimainkan dengan keluarga & teman.\nHubungkan satu atau lebih kontroller atau install app\n${REMOTE_APP_NAME} pada ponsel atau tablet untuk menggunakannya\nsebagai kontroller.", + "remote_app": { + "app_name": "Remot BombSquad", + "app_name_short": "RemotBS", + "button_position": "Posisi Tombol", + "button_size": "Ukuran Tombol", + "cant_resolve_host": "Tidak dapat menemukan pemilik.", + "capturing": "Menangkap…", + "connected": "Terhubung.", + "description": "Gunakan ponsel atau tabletmu sebagai pengontrol BombSquad.\nLebih dari 8 perangkat dapat terhubung sekaligus untuk keseruan multipemain lokal yang epik di sebuah TV atau tablet", + "disconnected": "Diputus server", + "dpad_fixed": "tetap", + "dpad_floating": "mengambang", + "dpad_position": "Posisi D-Pad", + "dpad_size": "Ukuran D-Pad", + "dpad_type": "Tipe D-Pad", + "enter_an_address": "Masukkan Alamat", + "game_full": "Permainan sudah penuh atau tidak menerima koneksi.", + "game_shut_down": "Permainan sudah berakhir", + "hardware_buttons": "Tombol Perangkat keras", + "join_by_address": "Masuk pakai Alamat...", + "lag": "Lag: ${SECONDS} detik", + "reset": "Ubah ke awal", + "run1": "Lari 1", + "run2": "Lari 2", + "searching": "Mencari BombSquad...", + "searching_caption": "Ketuk nama permainan yang kamu inginkan.\nPastikan Kamu berada di jaringan wifi yang sama dengan permainan tersebut.", + "start": "Mulai", + "version_mismatch": "Versi tidak sama.\nPastikan kamu menggunakan BombSquad dan Remot BombSquad\ndengan versi terbaru dan coba lagi." + }, + "removeInGameAdsText": "Buka \"${PRO}\" di toko untuk menghilangkan iklan game", + "renameText": "Mengubah Nama", + "replayEndText": "Akhiri Replay", + "replayNameDefaultText": "Replay Game Terakhir", + "replayReadErrorText": "Error membaca file replay.", + "replayRenameWarningText": "Ubah nama \"${REPLAY}\" setelah game jika Kamu ingin menyimpannya; jika tidak itu akan ditimpa.", + "replayVersionErrorText": "Maaf, replay ini dibuat dalam\nversi game yang berbeda dan tidak dapat digunakan", + "replayWatchText": "Nonton Replay", + "replayWriteErrorText": "Error menulis file replay", + "replaysText": "Replay", + "reportPlayerExplanationText": "Gunakan alamat surel ini untuk melaporkan tindakan curang, kata-kata yang tidak pantas, atau kelakuan buruk lainnya.\nTolong jelaskan dibawah ini:", + "reportThisPlayerCheatingText": "Curang", + "reportThisPlayerLanguageText": "Bahasa Yang Tidak Pantas", + "reportThisPlayerReasonText": "Apa yang ingin Kamu laporkan?", + "reportThisPlayerText": "Laporkan pemain ini", + "requestingText": "Meminta...", + "restartText": "Ulangi", + "retryText": "Ulangi", + "revertText": "Kembali", + "runText": "Lari", + "saveText": "Simpan", + "scanScriptsErrorText": "Galat saat memindai skrip; lihat log untuk detailnya.", + "scoreChallengesText": "Tantangan Skor", + "scoreListUnavailableText": "Daftar skor tidak ada", + "scoreText": "Skor", + "scoreUnits": { + "millisecondsText": "Milidetik", + "pointsText": "Poin", + "secondsText": "Detik" + }, + "scoreWasText": "(adalah ${COUNT})", + "selectText": "Pilih", + "seriesWinLine1PlayerText": "MEMENANGKAN", + "seriesWinLine1TeamText": "MEMENANGKAN", + "seriesWinLine1Text": "MEMENANGKAN", + "seriesWinLine2Text": "SERINYA!", + "settingsWindow": { + "accountText": "Akun", + "advancedText": "Lanjutan", + "audioText": "Suara", + "controllersText": "Pengontrol", + "graphicsText": "Grafik", + "playerProfilesMovedText": "NB: Profil-Profil Pemain sudah dipindahkan di jendela Akun di menu utama.", + "playerProfilesText": "Profil Pemain", + "titleText": "Pengaturan" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(keyboard dari BombSquad)", + "alwaysUseInternalKeyboardText": "Gunakan Keyboard Internal", + "benchmarksText": "Tes Stres dan Benchmark", + "disableCameraGyroscopeMotionText": "Nonaktikan Gerakkan Kamera Giroskop", + "disableCameraShakeText": "Nonaktifkan Gerakkan Kamera", + "disableThisNotice": "(Kamu dapat matikan peringatan ini di pengaturan tambahan)", + "enablePackageModsDescriptionText": "(menyalakan kapabilitas modding ekstra menyebabkan kamu tidak dapat bermain di internet)", + "enablePackageModsText": "Izinkan Paket Mod Lokal", + "enterPromoCodeText": "Masukkan Kode", + "forTestingText": "NB: jumlah ini hanya untuk tes dan akan hilang saat keluar", + "helpTranslateText": "Terjemahan ${APP_NAME} selain Bahasa Inggris adalah bantuan \nkomunitas. Jika Kamu ingin membantu atau mengoreksi berkas\nterjemahan, silahkan masuk ke situs berikut. Terima kasih!", + "kickIdlePlayersText": "Keluarkan Pemain Diam", + "kidFriendlyModeText": "Mode Dibawah Umur (kekerasan rendah, dll)", + "languageText": "Bahasa", + "moddingGuideText": "Cara Me-Modding", + "mustRestartText": "Kamu harus memulai ulang permainan untuk menerapkan perubahan.", + "netTestingText": "Tes Jaringan", + "resetText": "Atur ulang", + "showBombTrajectoriesText": "Lihat Lintasan Bom", + "showInGamePingText": "Tampilkan Ping dalam permainan", + "showPlayerNamesText": "Tunjukkan Nama Pemain", + "showUserModsText": "Lihat Folder Mod", + "titleText": "Lanjutan", + "translationEditorButtonText": "Penyunting Translasi ${APP_NAME}", + "translationFetchErrorText": "status translasi tidak tersedia.", + "translationFetchingStatusText": "memeriksa status terjemahan...", + "translationInformMe": "Beritahu saya jika bahasa yang saya gunakan harus diperbarui", + "translationNoUpdateNeededText": "Bahasa saat ini sudah yang terbaru; woohoo!", + "translationUpdateNeededText": "** bahasa ini perlu diperbaharui! **", + "vrTestingText": "Percobaan VR" + }, + "shareText": "Bagikan", + "sharingText": "Membagikan...", + "showText": "Tampilkan", + "signInForPromoCodeText": "Kamu harus masuk ke akun agar kode berlaku.", + "signInWithGameCenterText": "Untuk menggunakan akun Game Center,\nmasuk ke Game Center dahulu.", + "singleGamePlaylistNameText": "Hanya ${GAME}", + "singlePlayerCountText": "1 pemain", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Pemilihan Karakter", + "Chosen One": "Yang Terpilih", + "Epic": "Game Mode Epik", + "Epic Race": "Balap Epik", + "FlagCatcher": "Tangkap Bendera", + "Flying": "Pikiran Bahagia", + "Football": "Rugby", + "ForwardMarch": "Penyerbuan", + "GrandRomp": "Penaklukan", + "Hockey": "Hoki", + "Keep Away": "Menjauh", + "Marching": "Bolak-Balik", + "Menu": "Menu Utama", + "Onslaught": "Pembantaian", + "Race": "Balapan", + "Scary": "Raja Bukit", + "Scores": "Layar Skor", + "Survival": "Eliminasi", + "ToTheDeath": "Pertarungan Mematikan", + "Victory": "Layar Skor Akhir" + }, + "spaceKeyText": "spasi", + "statsText": "Statistik", + "storagePermissionAccessText": "Ini membutuhkan akses penyimpanan", + "store": { + "alreadyOwnText": "Kamu sudah punya ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Menghapus iklan dalam permainan dan omelan-layar\n• Membuka lebih banyak pengaturan permainan\n• Juga termasuk:", + "buyText": "Beli", + "charactersText": "Karakter", + "comingSoonText": "Segera Hadir...", + "extrasText": "Extra", + "freeBombSquadProText": "BombSquad sekarang gratis, karena dulu Kamu membelinya\nKamu mendapat tingkatan BombSquad Pro dan ${COUNT} tiket sebagai ucapan terima kasih.\nNikmati fitur barunya, dan terima kasih atas dukungannya!\n-Eric", + "holidaySpecialText": "Spesial Liburan", + "howToSwitchCharactersText": "pergi ke \"${SETTINGS} -> ${PLAYER_PROFILES}\" untuk mengubah karakter", + "howToUseIconsText": "(Buatlah profil pemain global (dalam jendela akun) untuk menggunakan ini)", + "howToUseMapsText": "(gunakan peta ini di tim/daftar putar bebasmu)", + "iconsText": "Simbol", + "loadErrorText": "Tidak dapat memuat halaman.\nCek koneksi internetmu.", + "loadingText": "memuat", + "mapsText": "Peta", + "miniGamesText": "Mini Game", + "oneTimeOnlyText": "(sekali saja)", + "purchaseAlreadyInProgressText": "Pembelian barang ini sedang dalam proses.", + "purchaseConfirmText": "Beli ${ITEM}?", + "purchaseNotValidError": "Pembelian tidak valid.\nHubungi ${EMAIL} jika ini adalah error.", + "purchaseText": "Membeli", + "saleBundleText": "Paket Promo!", + "saleExclaimText": "Dijual!", + "salePercentText": "(Diskon ${PERCENT}%)", + "saleText": "DIJUAL", + "searchText": "Cari", + "teamsFreeForAllGamesText": "Permainan Tim / Bebas-untuk-Semua", + "totalWorthText": "*** ${TOTAL_WORTH} nilai! ***", + "upgradeQuestionText": "Tingkatkan?", + "winterSpecialText": "Spesial Musim Dingin", + "youOwnThisText": "- Kamu sudah memiliki ini -" + }, + "storeDescriptionText": "Permainan dengan 8 pemain!\n\nLedakkan temanmu (atau komputer) dalam turnamen ledakkan seperti Ambil-Bendera, Bom-Hoki, dan Pertarungan-Mematikan-Epik-Gerakkan-Lambat\n\nDukungan pengontrol Sederhana dan pengontrol luas membuatnya mudah untuk 8 orang untuk beraksi; Kamu juga dapat menggunakan perangkat ponselmu sebagai pengontrol dengan aplikasi ‘BombSquad Remote’!\n\nAwas Bom!\n\nKunjungi www.froemling.net/bombsquad untuk informasi lebih lanjut.", + "storeDescriptions": { + "blowUpYourFriendsText": "Meledakkan temanmu.", + "competeInMiniGamesText": "Bersaing dalam mini-game mulai dari balapan sampai terbang.", + "customize2Text": "Sesuaikan karakter, mini-game, dan juga soundtrack.", + "customizeText": "Sesaikan karakter dan buat daftar mini-gamemu sendiri.", + "sportsMoreFunText": "Olahraga lebih menyenangkan dengan peledak.", + "teamUpAgainstComputerText": "Satu tim melawan komputer." + }, + "storeText": "Toko", + "submitText": "Serahkan", + "submittingPromoCodeText": "Menyerahkan Kode ...", + "teamNamesColorText": "Nama Tim / Warna ...", + "telnetAccessGrantedText": "Akses telnet aktif.", + "telnetAccessText": "Akses telnet terdekteksi; izinkan?", + "testBuildErrorText": "Percobaan ini tidak aktif lagi; tolong cek versi barunya.", + "testBuildText": "Percobaan", + "testBuildValidateErrorText": "Tidak dapat mengesahkan percobaan. (Tidak tersedia koneksi internet?)", + "testBuildValidatedText": "Percobaan Sah; Nikmati!", + "thankYouText": "Terima kasih atas dukungan mu! Nikmati gamenya!!", + "threeKillText": "KEJAM ! 3 TERBUNUH", + "timeBonusText": "Bonus Waktu", + "timeElapsedText": "Waktu Berlalu", + "timeExpiredText": "Berakhir", + "timeSuffixDaysText": "${COUNT}h", + "timeSuffixHoursText": "${COUNT}j", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}d", + "tipText": "Petunjuk", + "titleText": "BomSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Teman Terbaik", + "tournamentCheckingStateText": "Memeriksa keadaan turnamen; harap tunggu...", + "tournamentEndedText": "Turnamen sudah berakhir. Turnamen yang baru akan mulai segera.", + "tournamentEntryText": "Biaya Masuk Turnamen", + "tournamentResultsRecentText": "Hasil Turnamen Terbaru", + "tournamentStandingsText": "Hasil Terbaik Turnamen", + "tournamentText": "Turnamen", + "tournamentTimeExpiredText": "Waktu Turnamen Berakhir", + "tournamentsDisabledWorkspaceText": "Turnamen telah dinonaktifkan saat workspace(plugin/mod) aktif.\nUntuk mengaktifkan turnamen kembali, nonaktifkan dulu workspace anda dan mulai ulang gamenya.", + "tournamentsText": "Turnamen", + "translations": { + "characterNames": { + "Agent Johnson": "Agen Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Jerangkong", + "Butch": "Butch", + "Easter Bunny": "Kelinci Paskah", + "Flopsy": "Kelinci", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Manusia Super", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Peri", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Santa Klaus", + "Snake Shadow": "Ninja", + "Spaz": "Spaz", + "Taobao Mascot": "Maskot Taobao", + "Todd": "Todd", + "Todd McBurton": "Rambo", + "Xara": "Xara", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "Latihan ${GAME}", + "Infinite ${GAME}": "${GAME} Tanpa Batas", + "Infinite Onslaught": "Pembantaian Tanpa Batas", + "Infinite Runaround": "Penjaga Tanpa Batas", + "Onslaught Training": "Latihan Pembantaian", + "Pro ${GAME}": "${GAME} Profesional", + "Pro Football": "Rugby Ahli", + "Pro Onslaught": "Pembantaian Ahli", + "Pro Runaround": "Penjaga Ahli", + "Rookie ${GAME}": "${GAME} Pemula", + "Rookie Football": "Rugby Pemula", + "Rookie Onslaught": "Pembantaian Pemula", + "The Last Stand": "Usaha Terakhir", + "Uber ${GAME}": "${GAME} Master", + "Uber Football": "Rugby Uber", + "Uber Onslaught": "Pembantaian Uber", + "Uber Runaround": "Master Penjaga" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Jadilah 'yang terpilih' dalam waktu yang ditentukan.\nBunuh 'yang terpilih' untuk menjadi 'yang terpilih'.", + "Bomb as many targets as you can.": "Bom target sebanyak mungkin yang kamu bisa.", + "Carry the flag for ${ARG1} seconds.": "Bawa bendera selama ${ARG1} detik.", + "Carry the flag for a set length of time.": "Bawa bendera dalam waktu yang ditentukan.", + "Crush ${ARG1} of your enemies.": "Hancurkan ${ARG1} musuh.", + "Defeat all enemies.": "Hancurkan semua musuh.", + "Dodge the falling bombs.": "Hindari bom-bom yang berjatuhan.", + "Final glorious epic slow motion battle to the death.": "Pertarungan slow motion epik hingga kematian menjemput.", + "Gather eggs!": "Kumpulkan telur!", + "Get the flag to the enemy end zone.": "Bawa bendera sampai ujung lapangan.", + "How fast can you defeat the ninjas?": "Secepat apa kamu bisa mengalahkan para ninja?", + "Kill a set number of enemies to win.": "Hancurkan sejumlah musuh.", + "Last one standing wins.": "Terakhir hidup menang.", + "Last remaining alive wins.": "Terakhir hidup menang.", + "Last team standing wins.": "Habisi tim lawan.", + "Prevent enemies from reaching the exit.": "Tahan musuh jangan sampai finish.", + "Reach the enemy flag to score.": "Sentuh bendera lawan untuk skor.", + "Return the enemy flag to score.": "Kembalikan bendera musuh untuk menskor.", + "Run ${ARG1} laps.": "Lari ${ARG1} putaran.", + "Run ${ARG1} laps. Your entire team has to finish.": "Lari ${ARG1} putaran. Seluruh tim harus mencapai finish.", + "Run 1 lap.": "Lari 1 putaran.", + "Run 1 lap. Your entire team has to finish.": "Lari 1 putaran. Seluruh tim harus mencapai finish.", + "Run real fast!": "Lari! Ada Anjing!", + "Score ${ARG1} goals.": "Masukan ${ARG1} gol.", + "Score ${ARG1} touchdowns.": "Cetak ${ARG1} touchdown.", + "Score a goal.": "Cetak 1 Gol.", + "Score a touchdown.": "Cetak 1 touchdown.", + "Score some goals.": "Cetak beberapa gol.", + "Secure all ${ARG1} flags.": "Amankan ${ARG1} bendera.", + "Secure all flags on the map to win.": "Amankan semua bendera di arena untuk menang.", + "Secure the flag for ${ARG1} seconds.": "Amankan bendera selama ${ARG1} detik.", + "Secure the flag for a set length of time.": "Amankan bendera selama waktu yang ditentukan.", + "Steal the enemy flag ${ARG1} times.": "Curi bendera musuh ${ARG1} kali.", + "Steal the enemy flag.": "Curi bendera musuh.", + "There can be only one.": "Dunia ini tidak cukup luas untuk kita.", + "Touch the enemy flag ${ARG1} times.": "Sentuh bendera musuh ${ARG1} kali.", + "Touch the enemy flag.": "Sentuh bendera musuh.", + "carry the flag for ${ARG1} seconds": "bawa bendera selama ${ARG1} detik", + "kill ${ARG1} enemies": "Bunuh ${ARG1} musuh.", + "last one standing wins": "terakhir hidup menang", + "last team standing wins": "habisi tim lawan", + "return ${ARG1} flags": "kembalikan ${ARG1} bendera", + "return 1 flag": "kembalikan 1 bendera", + "run ${ARG1} laps": "lari ${ARG1} putaran", + "run 1 lap": "lari 1 putaran", + "score ${ARG1} goals": "masukan ${ARG1} gol", + "score ${ARG1} touchdowns": "Cetak ${ARG1} touchdown", + "score a goal": "cetak 1 gol", + "score a touchdown": "cetak 1 touchdown", + "secure all ${ARG1} flags": "amankan ${ARG1} bendera", + "secure the flag for ${ARG1} seconds": "amankan bendera selama ${ARG1} detik", + "touch ${ARG1} flags": "sentuh ${ARG1} bendera", + "touch 1 flag": "sentuh 1 bendera" + }, + "gameNames": { + "Assault": "Penyerbuan", + "Capture the Flag": "Curi Bendera", + "Chosen One": "Yang Terpilih", + "Conquest": "Penguasaan", + "Death Match": "Pertarungan Kematian", + "Easter Egg Hunt": "Memburu Easter Egg", + "Elimination": "Eliminasi", + "Football": "Rugby", + "Hockey": "Hoki", + "Keep Away": "Kejar-kejaran", + "King of the Hill": "Penguasa Bendera", + "Meteor Shower": "Hujan Meteor", + "Ninja Fight": "Perang Ninja", + "Onslaught": "Pembantaian", + "Race": "Balap Liar", + "Runaround": "Jangan Kabur", + "Target Practice": "Sasaran Tembak", + "The Last Stand": "Penyintas Terakhir" + }, + "inputDeviceNames": { + "Keyboard": "Keyboard", + "Keyboard P2": "Keyboard P2" + }, + "languages": { + "Arabic": "Arab", + "Belarussian": "Belarusia", + "Chinese": "Mandarin (disederhanakan)", + "ChineseTraditional": "Cina tradisional", + "Croatian": "Kroasia", + "Czech": "Ceko", + "Danish": "Denmark", + "Dutch": "Belanda", + "English": "Inggris", + "Esperanto": "Esperanto", + "Filipino": "Filipina", + "Finnish": "Finlandia", + "French": "Prancis", + "German": "Jerman", + "Gibberish": "Rahasia", + "Greek": "Yunani", + "Hindi": "Hindi", + "Hungarian": "Hongaria", + "Indonesian": "Bahasa Indonesia", + "Italian": "Italia", + "Japanese": "Jepang", + "Korean": "Korea", + "Malay": "Bahasa Malaysia", + "Persian": "Persia", + "Polish": "Polandia", + "Portuguese": "Portugis", + "Romanian": "Romania", + "Russian": "Rusia", + "Serbian": "Serbia", + "Slovak": "Slovakia", + "Spanish": "Spanyol", + "Swedish": "Swedia", + "Tamil": "Tamil", + "Thai": "Thai", + "Turkish": "Turki", + "Ukrainian": "Ukraina", + "Venetian": "Venesia", + "Vietnamese": "Vietnam" + }, + "leagueNames": { + "Bronze": "Perunggu", + "Diamond": "Berlian", + "Gold": "Emas", + "Silver": "Perak" + }, + "mapsNames": { + "Big G": "G Besar", + "Bridgit": "Jembatan", + "Courtyard": "Tempat Pengadilan", + "Crag Castle": "Kastil karang", + "Doom Shroom": "Jamur Gelap", + "Football Stadium": "Stadion Rugby", + "Happy Thoughts": "Pikiran Bahagia", + "Hockey Stadium": "Stadion Hoki", + "Lake Frigid": "Danau Beku", + "Monkey Face": "Wajah Monyet", + "Rampage": "Timbangan", + "Roundabout": "Luncuran", + "Step Right Up": "Tangga Penentuan", + "The Pad": "Tablet", + "Tip Top": "Bukit Bayangan", + "Tower D": "Menara D", + "Zigzag": "Lika Liku" + }, + "playlistNames": { + "Just Epic": "Hanya Epik", + "Just Sports": "Hanya Olahraga" + }, + "scoreNames": { + "Flags": "Bendera", + "Goals": "Gol", + "Score": "Skor", + "Survived": "Bertahan Hidup", + "Time": "Waktu", + "Time Held": "Lama Kuasa" + }, + "serverResponses": { + "A code has already been used on this account.": "Sebuah kode sudah digunakan pada aku ini.", + "A reward has already been given for that address.": "Hadiah telah diberikan ke alamat tersebut.", + "Account linking successful!": "Berhasil menghubungkan akun!", + "Account unlinking successful!": "Pemutusan akun berhasil!", + "Accounts are already linked.": "Akun sudah dihubungkan.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Menonton iklan tidak dapat diverifikasi.\nPastikan Anda menjalankan versi game yang resmi dan terbaru.", + "An error has occurred; (${ERROR})": "Sebuah kesalahan telah terjadi; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Sebuah kesalahan telah terjadi; tolong hubungi dukungan. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Sebuah error telah terjadi; tolong hubungi support@froemling.net.", + "An error has occurred; please try again later.": "Sebuah error telah terjadi; mohon coba lagi nanti.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Kamu yakin ingin menghubungkan akun ini?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nIni tidak dapat ditunda!", + "BombSquad Pro unlocked!": "BombSquad Pro terbuka!", + "Can't link 2 accounts of this type.": "Tidak dapat menghubungkan 2 tipe akun ini.", + "Can't link 2 diamond league accounts.": "Tidak dapat menghubungkan 2 akun liga berlian.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Tidak dapat menghubungkan; akan melampaui batas maksimum ${COUNT} akun yang dihubungkan.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Kecurangan terdeteksi; skor dan hadiah ditahan selama ${COUNT} hari", + "Could not establish a secure connection.": "Tidak dapat menyeimbangkan koneksi yang aman.", + "Daily maximum reached.": "Batas maksimal tercapai.", + "Entering tournament...": "Memasuki turnamen...", + "Invalid code.": "Kode Salah", + "Invalid payment; purchase canceled.": "Pembayaran tidak valid; pembelian dibatalkan.", + "Invalid promo code.": "Promo kode salah.", + "Invalid purchase.": "Pembelian tidak valid.", + "Invalid tournament entry; score will be ignored.": "Masukkan turnamen tidak valid; skor akan diabaikan.", + "Item unlocked!": "Item dibuka!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "PENAUTAN DITOLAK. ${ACCOUNT} berisi\ndata penting yang SEMUANYA AKAN HILANG.\nKamu dapat menautkannya dalam urutan yang berlawanan jika Kamu mau\n(dan kehilangan data akun INI sebagai gantinya)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Menghubungkan akun ${ACCOUNT} ke akun ini?\nSemua data yang ada di ${ACCOUNT} akan hilang.\nIni tidak dapat dibatalkan. Apa kamu yakin?", + "Max number of playlists reached.": "Batas maksimum daftar putar tercapai.", + "Max number of profiles reached.": "Batas maksimum profil tercapai.", + "Maximum friend code rewards reached.": "Batas maksimum hadiah kode teman tercapai.", + "Message is too long.": "Pesan terlalu panjang.", + "No servers are available. Please try again soon.": "Tidak ada server yang Tersedia. silakan coba lagi nanti", + "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" berhasil ditingkatkan.", + "Profile could not be upgraded.": "Profile tidak dapat di tingkatkan.", + "Purchase successful!": "Pembelian sukses!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Menerima ${COUNT} tiket untuk masuk.\nSilahkan kembali besok untuk menerima ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Server tidak lagi mendukung permainan dengan versi ini;\nSilahkan perbarui ke versi yang lebih baru.", + "Sorry, there are no uses remaining on this code.": "Maaf, kode ini tidak dapat dipakai lagi", + "Sorry, this code has already been used.": "Maaf,kode ini sudah digunakan", + "Sorry, this code has expired.": "Maaf, kode ini sudah kadaluarsa.", + "Sorry, this code only works for new accounts.": "Maaf, kode ini hanya berlaku untuk akun baru.", + "Still searching for nearby servers; please try again soon.": "Masih mencari server terdekat; silahkan coba lagi nanti", + "Temporarily unavailable; please try again later.": "Sedang tidak ada; mohon coba lagi nanti.", + "The tournament ended before you finished.": "Turnamen berakhir sebelum Kamu selesai.", + "This account cannot be unlinked for ${NUM} days.": "Akun ini tidak dapat diputuskan untuk ${NUM} hari.", + "This code cannot be used on the account that created it.": "Kode ini tidak dapat dipakai di akun yang membuatnya.", + "This is currently unavailable; please try again later.": "Ini saat ini tidak tersedia; silahkan coba lagi nanti.", + "This requires version ${VERSION} or newer.": "Ini membutuhkan versi ${VERSION} atau versi yang baru.", + "Tournaments disabled due to rooted device.": "Turnamen dinonaktifkan karena perangkat yang di-rooting.", + "Tournaments require ${VERSION} or newer": "Turnamen membutuhkan ${VERSION} atau lebih baru", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Memutus ${ACCOUNT} dari akun ini?\nSemua data dari ${ACCOUNT} akan disetel ulang.\n(kecuali penghargaan di beberapa kasus)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "PERINGATAN: keluhan tentang kecurangan telah diajukan terhadap akun Kamu.\nAkun yang ditemukan curang akan dilarang. Silakan bermain adil.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Apakah Kamu mau menghubungkan akun perangkatmu dengan yang ini>\n\nAkun perangkatmu adalah ${ACCOUNT1}\nAkun ini adalah ${ACCOUNT2}\n\nIni akan mengizinkanmu untuk menyimpan datamu.\nPeringatan: ini tidak dapat dibatalkan!", + "You already own this!": "Kamu sudah mempunyai ini!", + "You can join in ${COUNT} seconds.": "Kamu dapat bergabung lagi pada ${COUNT} detik", + "You don't have enough tickets for this!": "Kamu tidak mempunyai cukup tiket untuk ini!", + "You don't own that.": "Kamu tidak memiliki itu.", + "You got ${COUNT} tickets!": "Kamu dapat ${COUNT} tiket!", + "You got a ${ITEM}!": "Kamu dapat ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Kamu dipromosikan ke liga yang baru; selamat!", + "You must update to a newer version of the app to do this.": "Kamu harus perbarui app ke versi yang baru untuk melakukan ini.", + "You must update to the newest version of the game to do this.": "Kamu harus memperbaharui ke versi permainan yang lebih baru untuk melakukan ini.", + "You must wait a few seconds before entering a new code.": "Kamu harus menunggu beberapa detik sebelum memasukkan kode yang baru.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Kamu peringkat ke #${RANK} pada turnament terakhir. Terima kasih sudah bermain!", + "Your account was rejected. Are you signed in?": "Akunmu ditolak. Apakah Kamu terdaftar?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Salinan gamemu telah dimodifikasi.\nMohon kembalikan perubahan apapun dan coba lagi.", + "Your friend code was used by ${ACCOUNT}": "Kode temanmu digunakan oleh ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Menit", + "1 Second": "1 Detik", + "10 Minutes": "10 Menit", + "2 Minutes": "2 Menit", + "2 Seconds": "2 Detik", + "20 Minutes": "20 Menit", + "4 Seconds": "4 Detik", + "5 Minutes": "5 Menit", + "8 Seconds": "8 detik", + "Allow Negative Scores": "Izinkan Skor Bernilai Negatif", + "Balance Total Lives": "Total Nyawa Seimbang", + "Bomb Spawning": "Bom Muncul", + "Chosen One Gets Gloves": "Yang Terpilih Mendapat Sarung Tinju", + "Chosen One Gets Shield": "Terpilih akan mendapatkan perisai", + "Chosen One Time": "Waktu Yang Terpilih", + "Enable Impact Bombs": "Izinkan Dampak Bom", + "Enable Triple Bombs": "Izinkan Bom Beruntun", + "Entire Team Must Finish": "Seluruh Tim Harus Melewati Finish", + "Epic Mode": "Mode Epik", + "Flag Idle Return Time": "Waktu Bendera Diam Kembali", + "Flag Touch Return Time": "Waktu Bendera Sentuh Kembali", + "Hold Time": "Waktu Tunggu", + "Kills to Win Per Player": "Pembunuhan untuk Para Pemain", + "Laps": "Lap", + "Lives Per Player": "Nyawa Tiap Pemain", + "Long": "Lama", + "Longer": "Lama Sekali", + "Mine Spawning": "Ranjau Muncul", + "No Mines": "Tidak Ada Ranjau", + "None": "Tak Satupun", + "Normal": "Sedang", + "Pro Mode": "Mode Ahli", + "Respawn Times": "Jeda Hingga Kembali", + "Score to Win": "Skor menang", + "Short": "Pendek", + "Shorter": "Pendek sekali", + "Solo Mode": "Mode Solo", + "Target Count": "Jumlah Target", + "Time Limit": "Batas waktu" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} didiskualifikasi karena ${PLAYER} meninggalkan permainan", + "Killing ${NAME} for skipping part of the track!": "Membunuh ${NAME} Karena melewati bagian permainan ini!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Peringatan ke ${NAME}: turbo / tombol-spamming menjatuhkan Kamu." + }, + "teamNames": { + "Bad Guys": "Si Jahat", + "Blue": "Biru", + "Good Guys": "Si Baik", + "Red": "Merah" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Lari-lompat-putar-dan pukul yang sempurna dan pada waktu yang tepat dapat\nmembunuh hanya dengan sekali serangan dan dapatkan penghargaan dari temanmu.", + "Always remember to floss.": "Selalu ingat untuk buang air.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Buat profil pemain untuk teman dan dirimu sendiri dengan\nnama dan penampilan yang kamu sukai daripada menggunakan yang acak.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Kotak Terkutuk membuatmu menjadi bom waktu.\nSatu-satunya obat adalah mencari kotak medis.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Selain penampilannya, semua kemampuan karakter sama,\npilih saja yang cocok untukmu.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Jangan terlalu sombong dengan perisai energi; Kamu masih dapat dibuang ke dalam jurang.", + "Don't run all the time. Really. You will fall off cliffs.": "Jangan selalu berlari atau Kamu akan jatuh ke jurang.", + "Don't spin for too long; you'll become dizzy and fall.": "Jangan putar terlalu lama; kamu akan pusing dan jatuh.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Tahan tombol apa saja untuk lari.", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Tahan tombol apa saja untuk lari. Kamu akan menjadi lebih cepat\ntapi tidak dapat berbelok dengan lancar, hati-hati dengan jurang.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Bom es tidak cukup kuat, tetapi mereka membekukan\napapun yang mereka kena dan membuat orang mudah dihancurkan.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Jika seseorang mengangkatmu, pukul dia dan dia akan melepaskanmu.\nIni bekerja didunia nyata juga.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Jika Kamu tidak mempunyai kontroller, pasang app '${REMOTE_APP_NAME}\npada perangkat handphonemu untuk menggunakannya sebagai kontroller.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "", + "If you kill an enemy in one hit you get double points for it.": "Jika Kamu membunuh musuh dengan sekali serangan maka Kamu akan mendapat poin ganda.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Jika Kamu mengambil kutukan, satu-satunya harapanmu untuk hidup adalah\nmenemukan kotak medis dalam 5 detik.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Jika Kamu berdiam diri saja, maka Kamu akan tamat. Lari dan menghindar untuk tetap hidup..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jika Kamu mendapatkan banyak pemain yang masuk dan bergabung dalam permainan, aktifkan 'keluarkan pemain diam'\npada pengaturan untuk jaga-jaga jika seseorang lupa meninggalkan permainan.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Jika perangkatmu mulai panas atau Kamu mau menghemat baterai,\nturunkan \"Visual\" atau \"Resolusi\" pada Pengaturan->Grafis", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Jika framerate-mu lemah, coba turunkan resolusi\natau visual dalam pengaturan grafis permainan.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Dalam Ambil-Benderanya, benderamu sendiri harus ada pada bentengmu untuk mencetak skor, jika tim lain\nakan mencetak skor, mengambil benderanya adalah cara yang bagus untuk menghentikannnya.", + "In hockey, you'll maintain more speed if you turn gradually.": "Dalam hoki, Kamu dapat mempertahankan kecepatanmu jika Kamu berbelok secara bertahap.", + "It's easier to win with a friend or two helping.": "Lebih mudah menang jika dibantu teman.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Lompat sambil melempar bom untuk membuat bom melambung tinggi.", + "Land-mines are a good way to stop speedy enemies.": "Ranjau adalah cara yang bagus untuk menghentikan musuh yang cepat.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Banyak hal yang dapat diambil dan dilempar, termasuk pemain lain. Membuang\nmusuhmu ke jurang akan lebih efektif.", + "No, you can't get up on the ledge. You have to throw bombs.": "Tidak, Kamu tidak dapat melewati pembatas. Kamu harus melempar bom.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Pemain dapat masuk dan keluar ditengah-tengah permainan,\ndan Kamu juga dapat menyambung dan memutuskan kontroller.", + "Practice using your momentum to throw bombs more accurately.": "Latihan menggunakan momentum-mu untuk melempar bom lebih akurat.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Pukulan mendapatkan lebih banyak serangan ketika Kamu\nberlari, melompat, dan berputar.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Lari maju mundur untuk melempar bom\nsangat jauh.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Hancurkan sekumpulan musuh dengan\nmemasang TNT dan meledakkannya dengan bom.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Kepala adalah tempat yang paling rapuh, jadi menempelkannya dengan bom-lengket\nakan membuat musuhmu \"GAME OVER\".", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Level ini tidak akan pernah berakhir, tetapi skor\nakan membuat semua takjub didunia ini.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Kekuatan lemparan tergantung dimana Kamu melempar.\nJika Kamu ingin melempar lebih lembut, jangan terlalu banyak bergerak.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Bosan dengan soundtrack lama? Ganti dengan milikmu sendiri!\nLihat Pengaturan->Suara->Soundtrack", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Cobalah menunggu sumbu bom-mu mati lalu lempar.", + "Try tricking enemies into killing eachother or running off cliffs.": "Cobalah menipu musuhmu dengan membuatnya saling membunuh atau lari ke jurang.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Gunakkan tombol ambil untuk mengambil bendera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Jalan maju mundur untuk melempar lebih jauh..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Kamu dapat 'mengarahkan' tinjuanmu dengan memutar ke kiri atau ke kanan.\nIni berguna untuk memukul musuh di tepian atau membuat gol di permainan hoki.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Kamu dapat memperkirakan bom yang akan meledak dengan melihat warna percikan bom itu sendiri:\nKuning..Jingga..Merah..DUARRR.", + "You can throw bombs higher if you jump just before throwing.": "Kamu dapat melempar bom lebih tinggi jika kamu melompat sebelum melemparnya.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Kamu akan kesakitan jika kamu menabrakan kepalamu ke benda lain,\nJadi,Jangan tabrakan kepalamu ke benda lain.", + "Your punches do much more damage if you are running or spinning.": "Pukulanmu akan lebih sakit jika kamu lari atau berputar-putar." + } + }, + "trophiesRequiredText": "Ini membutuhkan setidaknya ${NUMBER} piala.", + "trophiesText": "Piala", + "trophiesThisSeasonText": "Piala Musim Ini", + "tutorial": { + "cpuBenchmarkText": "Proses tutorial dengan kecepatan super cepat(CPU test)", + "phrase01Text": "Hai, apa kabar?", + "phrase02Text": "Selamat Datang di ${APP_NAME}", + "phrase03Text": "Ada sedikit tips untuk mengontrol karaktermu:", + "phrase04Text": "Banyak hal di ${APP_NAME} yang didasarkan pada FISIKA", + "phrase05Text": "Misalnya, ketika kamu meninju....", + "phrase06Text": "... kecepatan lenganmu memengaruhi tinjuanmu.", + "phrase07Text": "Lihat? Kamu hanya diam, jadi ${NAME} hanya kegelian", + "phrase08Text": "Sekarang, cobalah lompat sembari berputar supaya lebih cepat.", + "phrase09Text": "Hmm, lebih baik", + "phrase10Text": "Berlari juga membantu", + "phrase11Text": "Tahan tombol APA SAJA untuk berlari.", + "phrase12Text": "Untuk tinjuan super maut, cobalah lari dan berputar.", + "phrase13Text": "Ups, maaf ya ${NAME}!", + "phrase14Text": "Kamu dapat mengangkat lalu melempar barang, bendera, atau mungkin.... ${NAME}", + "phrase15Text": "Yang terakhir, BOM.", + "phrase16Text": "Melempar bom butuh latihan.", + "phrase17Text": "Eh! Lemparanmu sangat buruk!", + "phrase18Text": "Lempar bom sambil lari juga membantu.", + "phrase19Text": "Lompat membuat lemparanmu makin tinggi.", + "phrase20Text": "Lempar sambil berputar untuk lemparan terjauh.", + "phrase21Text": "Mengatur waktu bom dapat jadi sulit.", + "phrase22Text": "Yah, meleset", + "phrase23Text": "Tunggu bom hingga matang, lalu lempar.", + "phrase24Text": "Horee! Kerja Bagus.", + "phrase25Text": "Yap, sepertinya itu saja.", + "phrase26Text": "Hantam mereka, Joe!", + "phrase27Text": "Ingat latihanmu, agar kamu dapat kembali hidup-hidup!", + "phrase28Text": "... em, mungkin sih...", + "phrase29Text": "Semoga beruntung kawan !", + "randomName1Text": "Ucup", + "randomName2Text": "Asep", + "randomName3Text": "Galang", + "randomName4Text": "Suci", + "randomName5Text": "Aldi", + "skipConfirmText": "Yakin ingin melompati pembelajaran? Tekan apa saja untuk konfirmasi.", + "skipVoteCountText": "${COUNT} dari ${TOTAL} suara untuk melewati pembelajaran", + "skippingText": "Melewati pembelajaran...", + "toSkipPressAnythingText": "(tekan apa saja untuk melompati pembelajaran)" + }, + "twoKillText": "PEMBUNUHAN GANDA!", + "unavailableText": "tidak tersedia", + "unconfiguredControllerDetectedText": "Pengontrol belum terkonfigurasi terdeteksi:", + "unlockThisInTheStoreText": "Tersedia di toko terdekat.", + "unlockThisProfilesText": "Untuk membuat lebih dari ${NUM} profil, Kamu memerlukan:", + "unlockThisText": "Untuk buka ini,kamu membutuhkan:", + "unsupportedHardwareText": "Maaf, perangkat ini tidak mendukung build permainan ini.", + "upFirstText": "Game pertama:", + "upNextText": "${COUNT} game berikutnya:", + "updatingAccountText": "Memperbaharui akun...", + "upgradeText": "Tingkatkan", + "upgradeToPlayText": "Buka \"${PRO}\" di toko game untuk bermain.", + "useDefaultText": "Gunakan Default", + "usesExternalControllerText": "Game ini menggunakan pengontrol external untuk input.", + "usingItunesText": "Menggunakan soundtrack dari aplikasi Musik", + "usingItunesTurnRepeatAndShuffleOnText": "Tolong pastikan lagu diacak dan diulang di iTunes. ", + "v2AccountLinkingInfoText": "Untuk menautkan akun V2, gunakan tombol 'Manajemen Akun'.", + "validatingTestBuildText": "Memvalidasi Bangunan Tes...", + "victoryText": "Menang!", + "voteDelayText": "Kamu tidak dapat memulai pemilihan suara dalam ${NUMBER} detik", + "voteInProgressText": "Pemilihan suara sedang dalam proses.", + "votedAlreadyText": "Kamu sudah memilih suara", + "votesNeededText": "${NUMBER} suara dibutuhkan", + "vsText": "lw.", + "waitingForHostText": "(menunggu ${HOST} untuk lanjut)", + "waitingForPlayersText": "menunggu pemain untuk bergabung...", + "waitingInLineText": "Menunggu antrian (acara penuh)...", + "watchAVideoText": "Tonton Video", + "watchAnAdText": "Tonton Iklan", + "watchWindow": { + "deleteConfirmText": "Hapus \"${REPLAY}\"?", + "deleteReplayButtonText": "Hapus\nReplay", + "myReplaysText": "Replayku", + "noReplaySelectedErrorText": "Tidak Ada Replay Terpilih", + "playbackSpeedText": "Kecepatan Putar Ulang: ${SPEED}", + "renameReplayButtonText": "Ganti\nNama", + "renameReplayText": "Mengubah nama\"${REPLAY}\" ke", + "renameText": "Ganti Nama", + "replayDeleteErrorText": "Galat menghapus replay", + "replayNameText": "Nama Replay", + "replayRenameErrorAlreadyExistsText": "Replay dengan nama yang sudah ada", + "replayRenameErrorInvalidName": "Tidak dapat menganti nama replay; nama invailid", + "replayRenameErrorText": "Error mengganti nama replay", + "sharedReplaysText": "Replay dibagikan", + "titleText": "Nonton", + "watchReplayButtonText": "Lihat\nReplay" + }, + "waveText": "Gelombang", + "wellSureText": "Sip!", + "whatIsThisText": "Apa ini?", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Mencari Wiimotes....", + "pressText": "Tekan tombol Wilmote 1 dan 2 secara bersamaan", + "pressText2": "Pada Wiimotes baru dengan Motion Plus built in, tekan tombol merah 'sync' pada belakang sebagai gantinya." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "listenText": "Mendengarkan", + "macInstructionsText": "Pastika Wii-mu mati dan Bluetooth hidup\npada Macmu, lalu tekan 'Dengar'. Dukungan Wiimote\ndapat sedikit sulit, jadi Kamu harus mencoba beberapa kali\nsebelum Kamu mempunyai koneksi.\n\nBluetooth seharusnya dapat mengatasi sampai 7 perangkat yang terhubung\nmeski jaraknya bervariasi.\n\nBombSquad mendukung Wiimotes, Nunchuks,\ndan kontroller klasik.\nWii Remote yang baru sekarang bekerja juga\ntapi tanpa penghubung.", + "thanksText": "Terimakasih kepada DarwiinRemote team\nUntuk dukungan wiimote", + "titleText": "Pengaturan Wiimote" + }, + "winsPlayerText": "${NAME} Menang!", + "winsTeamText": "${NAME} Menang!", + "winsText": "${NAME} Menang!", + "workspaceSyncErrorText": "Menyinkronkan ke ${WORKSPACE} error. Lihat log untuk lebih detailnya.", + "workspaceSyncReuseText": "Tidak bisa menyinkronkan ${WORKSPACE}. Menggunakan kembali versi sinkronan sebelumnya.", + "worldScoresUnavailableText": "Skor Dunia tidak tersedia.", + "worldsBestScoresText": "Nilai Terbaik Dunia", + "worldsBestTimesText": "Waktu Terbaik Dunia", + "xbox360ControllersWindow": { + "getDriverText": "Dapatkan Driver", + "macInstructions2Text": "Untuk menggunakan stik nirkabel, Kamu juga memerlukan penerima jaringan nirkabel\natau wireless receiver yang termasuk bagian dari 'Xbox 360 Wireless Controller for Windows'.\nSatu receiver dapat digunakan untuk hingga 4 stik/pengontrol.\n\nPenting: receiver pihak ketiga biasanya tidak dapat digunakan dengan driver ini;\npastikan pada receiver Kamu tertulis logo 'Microsoft', bukan logo 'XBOX360'.\nMicrosoft tidak menjual receiver secara terpisah lagi, jadi Kamu harus\nmembeli stik yang termasuk receiver, atau cari di ebay/kaskus.\n\nJika Kamu berpikir ini berguna, tolong pertimbangkan untuk donasi kepada\npengembang/developer driver tersebut pada situsnya.", + "macInstructionsText": "Untuk menggunakan stik Xbox 360, Kamu perlu menginstall\ndriver untuk Mac, dapat didownload pada link di bawah.\nDapat digunakan untuk stik kabel maupun wireless.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Untuk menggunakan stik Xbox 360 kabel, tancapkan\nkabel USB ke komputer Kamu. Kamu dapat menggunakan USB hub\nuntuk menancapkan banyak stik/pengontrol\n\nUntuk menggunakan stik wireless Kamu perlu wireless reciever,\ntersedia sebagai bagian dari \"Xbox 360 wireless Controller for Windows\"\ntermasuk ataupun dijual terpisah. Setiap reciever yang ditancapkan dapat\nmenyambunggkan sampai 4 buah stik/pengontrol.", + "titleText": "Menggunakan pengontrol Xbox 360 dengan ${APP_NAME}:" + }, + "yesAllowText": "Ya, Izinkan!", + "yourBestScoresText": "Skor terbaikmu", + "yourBestTimesText": "Waktu Terbaikmu" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/italian.json b/dist/ba_data/data/languages/italian.json new file mode 100644 index 0000000..0361c7f --- /dev/null +++ b/dist/ba_data/data/languages/italian.json @@ -0,0 +1,1985 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "I nomi degli account non possono contenere emoji o altri caratteri speciali.", + "accountProfileText": "(profilo account)", + "accountsText": "Account", + "achievementProgressText": "Trofei: ${COUNT} su ${TOTAL}", + "campaignProgressText": "Progresso Campagna [Difficile]: ${PROGRESS}", + "changeOncePerSeason": "Puoi cambiare questa cosa solo una volta a stagione.", + "changeOncePerSeasonError": "Devi aspettare la prossima stagione per apportare delle modifiche (${NUM} days)", + "customName": "Nome Personalizzato", + "deviceSpecificAccountText": "Stai usando un account automaticamente generato: ${NAME}", + "googlePlayGamesAccountSwitchText": "Se desideri utilizzare un'altro account Google,\nutilizza l'app Google Play Games.", + "linkAccountsEnterCodeText": "Inserisci il codice", + "linkAccountsGenerateCodeText": "Genera codice", + "linkAccountsInfoText": "(condividi i progressi sui vari dispositivi)", + "linkAccountsInstructionsNewText": "Per collegare due account, genera un codice nel primo dispositivo\ned inserisci il codice nel secondo. I dati del secondo account\nverranno condivisi in entrambi gli account.\n(I dati del primo account andranno persi)\n\nPuoi collegare fino a ${COUNT} account.\n\nIMPORTANTE: collega solo account che ti appartengono;\nSe colleghi account di amici non sarete in grado di\ngiocare online allo stesso momento.", + "linkAccountsInstructionsText": "Per collegare due account, crea un codice su uno\ndei dispositivi e inserisci quel codice negli altri. \nProgressi e inventario verranno combinati.\nPuoi collegare fino a ${COUNT} account.\n\nIMPORTANTE: Collega solo account che possiedi!\nSe colleghi un account con un tuo amico non potrete\ngiocare allo stesso momento!\n \nInoltre: questa operazione non può essere annullata, quindi stai attento!", + "linkAccountsText": "Collega account", + "linkedAccountsText": "Account Collegati:", + "manageAccountText": "Gestisci account", + "nameChangeConfirm": "Confermi di voler modificare il tuo nome in ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Stai per cancellare i tuoi progressi in\nmodalità cooperativa, i tuoi obbiettivi, i tuoi punteggi\nlocali (ma non i tuoi biglietti). \n\nL'operazione è irreversibile: continuare?", + "resetProgressConfirmText": "Stai per cancellare i tuoi progressi in\nmodalità cooperativa, i tuoi punteggi\nlocali e i tuoi obiettivi (ma non i tuoi biglietti).\nL'operazione è irreversibile: continuare?", + "resetProgressText": "Cancella Progressi", + "setAccountName": "Inserisci un nome utente", + "setAccountNameDesc": "Seleziona quale nome visualizzare per il tuo account.\nPuoi usare quel nome per uno dei tuoi account collegati,\noppure creare un unico nome personalizzato.", + "signInInfoText": "Accedi per raccogliere biglietti, competere online,\ne condividere i progressi tra i vari dispositivi.", + "signInText": "Accedi", + "signInWithDeviceInfoText": "(Un solo account automatico è disponibile per questo dispositivo)", + "signInWithDeviceText": "Accedi con l'account del dispositivo", + "signInWithGameCircleText": "Accedi con Game Circle", + "signInWithGooglePlayText": "Accedi con Google Play", + "signInWithTestAccountInfoText": "(tipo di account obsoleto; usa gli account dispositivo d'ora in poi)", + "signInWithTestAccountText": "Accedi con un account di prova", + "signInWithV2InfoText": "(un account che funziona su tutte le piattaforme)", + "signInWithV2Text": "Effettua l'accesso con un account di BombSquad", + "signOutText": "Esci", + "signingInText": "Accesso in corso...", + "signingOutText": "Uscita in corso...", + "testAccountWarningCardboardText": "Attenzione: stai accedendo con un account di test.\n\nQuesto sarà sostituito con l'account Google quando diventeremo supportati nelle app per cardboard.\n\nPer ora puoi raccogliere tutti i biglietti in-game.\n(Però puoi prendere l'aggiornamento BombSquad Pro gratis)", + "testAccountWarningOculusText": "Attenzione. Stai eseguendo l'accesso con un account \"di prova\".\nQuesto sarà sostituito da un account Oculus l'anno prossimo \ne offrirà acquisti di biglietti e altre opzioni.\n\nAl momento, tutti i biglietti vanno guadagnati nel gioco.\n(Devi, comunque, prendere l'upgrade di BombSquad Pro gratuito)", + "testAccountWarningText": "Attenzione: stai per accedere usando un account \"di prova\".\nQuesto account è legato a questo specifico apparecchio e\npotrebbe essere resettato in alcune occasioni (perciò non\nperderci troppo tempo a raccogliere/sbloccare oggetti).\n\nUsa una versione completa del gioco per usare un profilo\n\"vero\" (Game-Center, Google Plus, ecc.). Questo ti permet-\nterà di salvare i tuoi progressi online e condividerlo fra\npiù apparecchi.", + "ticketsText": "Ticket: ${COUNT}", + "titleText": "Account", + "unlinkAccountsInstructionsText": "Seleziona un account da scollegare", + "unlinkAccountsText": "Scollega Account", + "unlinkLegacyV1AccountsText": "Desvincular cuentas heredadas (V1)", + "v2LinkInstructionsText": "Usa questo link per creare un account o accedere.", + "viaAccount": "(tramite ${NAME})", + "youAreLoggedInAsText": "Accesso effettuato come:", + "youAreSignedInAsText": "Hai effettuato l'accesso con:" + }, + "achievementChallengesText": "Sfide trofeo", + "achievementText": "Obiettivo", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Uccidi 3 cattivoni con la TNT", + "descriptionComplete": "Hai Ucciso 3 cattivoni con la TNT", + "descriptionFull": "Uccidi 3 cattivoni con la TNT in ${LEVEL}", + "descriptionFullComplete": "Hai Ucciso 3 cattivoni con la TNT in ${LEVEL}", + "name": "E la dinamite fa Boom!" + }, + "Boxer": { + "description": "Vinci senza lanciare bombe", + "descriptionComplete": "Hai vinto senza lanciare bombe", + "descriptionFull": "Completa ${LEVEL} senza lanciare bombe", + "descriptionFullComplete": "Hai completato ${LEVEL} senza lanciare bombe", + "name": "Pugile" + }, + "Dual Wielding": { + "descriptionFull": "Connetti 2 controller (hardware o app)", + "descriptionFullComplete": "2 controller connessi (hardware o app)", + "name": "Doppio maneggiamento" + }, + "Flawless Victory": { + "description": "Vinci senza essere colpito", + "descriptionComplete": "Hai vinto senza essere colpito", + "descriptionFull": "Vinci ${LEVEL} senza essere colpito", + "descriptionFullComplete": "Hai vinto ${LEVEL} senza essere colpito", + "name": "Vittoria Impeccabile" + }, + "Free Loader": { + "descriptionFull": "Avvia una partita Tutti Contro Tutti con 2 o più giocatori", + "descriptionFullComplete": "Hai avviato una partita Tutti Contro Tutti con 2 o più giocatori", + "name": "Caricatore gratuito" + }, + "Gold Miner": { + "description": "Uccidi 6 cattivoni con le mine antiuomo", + "descriptionComplete": "Hai ucciso 6 cattivoni con le mine antiuomo", + "descriptionFull": "Uccidi 6 cattivoni con le mine in ${LEVEL}", + "descriptionFullComplete": "Hai ucciso 6 cattivoni con le mine antiuomo in ${LEVEL}", + "name": "Minatore D'Oro" + }, + "Got the Moves": { + "description": "Vinci senza tirare pugni né bombe", + "descriptionComplete": "Hai vinto senza tirare pugni né bombe", + "descriptionFull": "Vinci ${LEVEL} senza tirare pugni né bombe", + "descriptionFullComplete": "Hai vinto il livello ${LEVEL} senza tirare pugni né bombe", + "name": "Ci sai fare!" + }, + "In Control": { + "descriptionFull": "Connetti un controller (hardware o app)", + "descriptionFullComplete": "Controller connesso (hardware o app)", + "name": "In controllo" + }, + "Last Stand God": { + "description": "Totalizza 1000 punti", + "descriptionComplete": "Hai totalizzato 1000 punti", + "descriptionFull": "Totalizza 1000 punti in ${LEVEL}", + "descriptionFullComplete": "Hai totalizzato 1000 punti in ${LEVEL}", + "name": "Dio di ${LEVEL}" + }, + "Last Stand Master": { + "description": "Totalizza 250 punti", + "descriptionComplete": "Hai totalizzato 250 punti", + "descriptionFull": "Totalizza 250 punti in ${LEVEL}", + "descriptionFullComplete": "Hai totalizzato 250 punti in ${LEVEL}", + "name": "Maestro di ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Fai 500 punti", + "descriptionComplete": "Hai totalizzato 500 punti", + "descriptionFull": "Totalizza 500 punti in ${LEVEL}", + "descriptionFullComplete": "Hai totalizzato 500 punti in ${LEVEL}", + "name": "Mago di ${LEVEL}" + }, + "Mine Games": { + "description": "Uccidi 3 cattivoni con le mine antiuomo", + "descriptionComplete": "Hai ucciso 3 cattivoni con le mine antiuomo", + "descriptionFull": "Uccidi 3 cattivoni con le mine antiuomo in ${LEVEL}", + "descriptionFullComplete": "Hai ucciso 3 cattivoni con le mine antiuomo in ${LEVEL}", + "name": "Campo minato" + }, + "Off You Go Then": { + "description": "Scaraventa 3 cattivoni fuori dalla mappa", + "descriptionComplete": "Hai scaraventato 3 cattivoni fuori dalla mappa", + "descriptionFull": "Scaraventa 3 cattivoni fuori dalla mappa in ${LEVEL}", + "descriptionFullComplete": "Hai scaraventato 3 cattivoni fuori dalla mappa in ${LEVEL}", + "name": "Cado dalle nubi" + }, + "Onslaught God": { + "description": "Totalizza 5000 punti", + "descriptionComplete": "Hai totalizzato 5000 punti", + "descriptionFull": "Totalizza 5000 punti in ${LEVEL}", + "descriptionFullComplete": "Hai totalizzato 5000 punti in ${LEVEL}", + "name": "Dio di ${LEVEL}" + }, + "Onslaught Master": { + "description": "Totalizza 500 punti", + "descriptionComplete": "Hai totalizzato 500 punti", + "descriptionFull": "Totalizza 500 punti in ${LEVEL}", + "descriptionFullComplete": "Hai totalizzato 500 punti in ${LEVEL}", + "name": "Maestro di ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Sconfiggi tutte le ondate", + "descriptionComplete": "Hai sconfitto tutte le ondate", + "descriptionFull": "Sconfiggi tutte le ondate in ${LEVEL}", + "descriptionFullComplete": "Hai sconfitto tutte le ondate in ${LEVEL}", + "name": "Vittoria in ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Totalizza 1000 punti", + "descriptionComplete": "Hai totalizzato 1000 punti", + "descriptionFull": "Totalizza 1000 punti in ${LEVEL}", + "descriptionFullComplete": "Hai totalizzato 1000 punti in ${LEVEL}", + "name": "Mago di ${LEVEL}" + }, + "Precision Bombing": { + "description": "Vinci senza usare potenziamenti", + "descriptionComplete": "Hai vinto senza usare potenziamenti", + "descriptionFull": "Vinci ${LEVEL} senza usare potenziamenti", + "descriptionFullComplete": "Hai vinto ${LEVEL} senza usare potenziamenti", + "name": "Bombardamento di precisione" + }, + "Pro Boxer": { + "description": "Vinci senza lanciare bombe", + "descriptionComplete": "Hai vinto senza lanciare bombe", + "descriptionFull": "Completa ${LEVEL} senza lanciare bombe", + "descriptionFullComplete": "Hai completato ${LEVEL} senza lanciare bombe", + "name": "Pugile Esperto" + }, + "Pro Football Shutout": { + "description": "Vinci senza che i cattivoni facciano gol", + "descriptionComplete": "Hai vinto senza che i cattivoni facessero gol", + "descriptionFull": "Vinci ${LEVEL} senza che i cattivoni facciano gol", + "descriptionFullComplete": "Hai vinto ${LEVEL} senza che i cattivoni facessero gol", + "name": "Saracinesca in ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Vinci la partita", + "descriptionComplete": "Hai vinto la partita", + "descriptionFull": "Vinci la partita in ${LEVEL}", + "descriptionFullComplete": "Hai vinto la partita in ${LEVEL}", + "name": "Vittoria in ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Sconfiggi tutte le ondate", + "descriptionComplete": "Hai sconfitto tutte le ondate", + "descriptionFull": "Sconfiggi tutte le ondate di ${LEVEL}", + "descriptionFullComplete": "Hai sconfitto tutte le ondate di ${LEVEL}", + "name": "Vittoria in ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Completa tutte le ondate", + "descriptionComplete": "Hai completato tutte le ondate", + "descriptionFull": "Completa tutte le ondate su ${LEVEL}", + "descriptionFullComplete": "Hai completato tutte le ondate su ${LEVEL}", + "name": "Vittoria in ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Vinci senza che i cattivoni facciano gol", + "descriptionComplete": "Hai vinto senza che i cattivoni facessero gol", + "descriptionFull": "Vinci ${LEVEL} senza che i cattivoni segnino", + "descriptionFullComplete": "Hai vinto ${LEVEL} senza che i cattivoni segnassero", + "name": "Saracinesca in ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Vinci la partita", + "descriptionComplete": "Hai vinto la partita", + "descriptionFull": "Vinci la partita in ${LEVEL}", + "descriptionFullComplete": "Hai vinto la partita in ${LEVEL}", + "name": "Vittoria in ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Sconfiggi tutte le ondate", + "descriptionComplete": "Hai sconfitto tutte le ondate", + "descriptionFull": "Sconfiggi tutte le ondate in ${LEVEL}", + "descriptionFullComplete": "Hai sconfitto tutte le ondate in ${LEVEL}", + "name": "Vittoria in ${LEVEL}" + }, + "Runaround God": { + "description": "Totalizza 2000 punti", + "descriptionComplete": "Hai totalizzato 2000 punti", + "descriptionFull": "Totalizza 2000 punti in ${LEVEL}", + "descriptionFullComplete": "Hai totalizzato 2000 punti in ${LEVEL}", + "name": "Dio di ${LEVEL}" + }, + "Runaround Master": { + "description": "Totalizza 500 punti", + "descriptionComplete": "Hai totalizzato 500 punti", + "descriptionFull": "Totalizza 500 punti in ${LEVEL}", + "descriptionFullComplete": "Hai totalizzato 500 punti in ${LEVEL}", + "name": "Maestro di ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Totalizza 1000 punti", + "descriptionComplete": "Hai totalizzato 1000 punti", + "descriptionFull": "Totalizza 1000 punti in ${LEVEL}", + "descriptionFullComplete": "Hai totalizzato 1000 punti in ${LEVEL}", + "name": "Mago di ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Condividi con successo il gioco con un amico", + "descriptionFullComplete": "Gioco condiviso con successo con un amico", + "name": "La Condivisione E' La Cura" + }, + "Stayin' Alive": { + "description": "Vinci senza morire", + "descriptionComplete": "Hai vinto senza morire", + "descriptionFull": "Vinci ${LEVEL} senza morire", + "descriptionFullComplete": "Hai vinto ${LEVEL} senza morire", + "name": "Stayin' alive" + }, + "Super Mega Punch": { + "description": "Infliggi una percentuale del 100% di danno con un solo pugno", + "descriptionComplete": "Hai inflitto una percentuale del 100% di danno con un solo pugno", + "descriptionFull": "Infliggi il 100% di danno con un solo pugno in ${LEVEL}", + "descriptionFullComplete": "Hai inflitto il 100% di danno con un solo pugno in ${LEVEL}", + "name": "Super mega pugno" + }, + "Super Punch": { + "description": "Infliggi una percentuale del 50% di danno con un solo pugno", + "descriptionComplete": "Hai inflitto una percentuale del 50% di danno con un solo pugno", + "descriptionFull": "Infliggi il 50% di danno con un solo pugno in ${LEVEL}", + "descriptionFullComplete": "Hai inflitto il 50% di danno con un solo pugno in ${LEVEL}", + "name": "Super Pugno" + }, + "TNT Terror": { + "description": "Uccidi 6 cattivoni con la TNT", + "descriptionComplete": "Hai ucciso 6 cattivoni con la TNT", + "descriptionFull": "Uccidi 6 cattivoni con la TNT su ${LEVEL}", + "descriptionFullComplete": "Hai ucciso 6 cattivoni con la TNT su ${LEVEL}", + "name": "Terrore Del Tritolo" + }, + "Team Player": { + "descriptionFull": "Avvia una partita Squadre con 4+ giocatori", + "descriptionFullComplete": "Avviato una partita Squadre con 4+ giocatori", + "name": "Giocatore di Squadra" + }, + "The Great Wall": { + "description": "Ferma ogni singolo cattivone", + "descriptionComplete": "Hai fermato ogni singolo cattivone", + "descriptionFull": "Ferma ogni singolo cattivone in ${LEVEL}", + "descriptionFullComplete": "Hai fermato ogni singolo cattivone in ${LEVEL}", + "name": "La grande muraglia" + }, + "The Wall": { + "description": "Ferma ogni singolo cattivone", + "descriptionComplete": "Hai fermato ogni singolo cattivone", + "descriptionFull": "Ferma ogni singolo cattivone in ${LEVEL}", + "descriptionFullComplete": "Hai fermato ogni singolo cattivone in ${LEVEL}", + "name": "Il muro" + }, + "Uber Football Shutout": { + "description": "Vinci senza che i cattivoni facciano gol", + "descriptionComplete": "Hai vinto senza che i cattivoni facessero gol", + "descriptionFull": "Vinci ${LEVEL} senza che i cattivoni segnino", + "descriptionFullComplete": "Hai vinto ${LEVEL} senza che i cattivoni segnassero", + "name": "Saracinesca in ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Vinci la partita", + "descriptionComplete": "Hai vinto la partita", + "descriptionFull": "Vini la partita in ${LEVEL}", + "descriptionFullComplete": "Hai vinto la partita in ${LEVEL}", + "name": "Vittoria in ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Sconfiggi tutte le ondate", + "descriptionComplete": "Hai sconfitto tutte le ondate", + "descriptionFull": "Sconfiggi tutte le ondate in ${LEVEL}", + "descriptionFullComplete": "Hai sconfitto tutte le ondate in ${LEVEL}", + "name": "Vittoria in ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Completa tutte le ondate", + "descriptionComplete": "Hai completato tutte le ondate", + "descriptionFull": "Completa tutte le ondate in ${LEVEL}", + "descriptionFullComplete": "Completa tutte le ondate in ${LEVEL}", + "name": "Vittoria in ${LEVEL}" + } + }, + "achievementsRemainingText": "Trofei rimasti:", + "achievementsText": "Trofei", + "achievementsUnavailableForOldSeasonsText": "Mi dispiace, ma gli obbiettivi non sono disponibili per le stagioni vecchie.", + "activatedText": "${THING} attivato.", + "addGameWindow": { + "getMoreGamesText": "Ottieni Giochi...", + "titleText": "Aggiungi Partita" + }, + "allowText": "Consenti", + "alreadySignedInText": "Il tuo account è collegato da un altro dispositivo;\ncambia account o chiudi il gioco nel tuo altro\ndispositivo e riprova.", + "apiVersionErrorText": "Impossibile caricare il modulo ${NAME}; sono installate le API versione ${VERSION_USED}; è richiesta la ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" abilitalo solo quando sono connesse delle cuffie)", + "headRelativeVRAudioText": "Audio VR Head-Relative", + "musicVolumeText": "Volume delle musica", + "soundVolumeText": "Volume dei suoni", + "soundtrackButtonText": "Colonna sonora", + "soundtrackDescriptionText": "(scegli la musica da ascoltare durante le partite)", + "titleText": "Audio" + }, + "autoText": "Automatico", + "backText": "Indietro", + "banThisPlayerText": "Banna questo giocatore", + "bestOfFinalText": "Finale Al-meglio-di-${COUNT}", + "bestOfSeriesText": "Serie al meglio di ${COUNT}:", + "bestRankText": "Il tuo miglior piazzamento: N.${RANK}", + "bestRatingText": "La tua valutazione migliore è ${RATING}", + "betaErrorText": "Questa versione non è più attiva; per favore, cercane una più recente.", + "betaValidateErrorText": "Impossibile convalidare la beta. (nessuna connessione internet?)", + "betaValidatedText": "Versione beta convalidata; Divertiti!", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Potenziamento", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} è configurato nell'app stessa.", + "buttonText": "pulsante", + "canWeDebugText": "Vorresti che BombSquad segnalasse automaticamente bug, errori\ne informazioni sull'utilizzo direttamente allo sviluppatore?\n\nQuesti dati non contengono informazioni personali e aiutano a \nmantenere il gioco privo di bug e rallentamenti.", + "cancelText": "Annulla", + "cantConfigureDeviceText": "Spiacente, ${DEVICE} non è configurabile.", + "challengeEndedText": "Questa sfida è finita.", + "chatMuteText": "Silenzia Chat", + "chatMutedText": "Chat Silenziata", + "chatUnMuteText": "Smuta Chat", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Devi completare questo\nlivello per procedere!", + "completionBonusText": "Competizione bonus", + "configControllersWindow": { + "configureControllersText": "Configura Controller", + "configureGamepadsText": "Configura i gamepad", + "configureKeyboard2Text": "Configura la tastiera P2", + "configureKeyboardText": "Configura la tastiera", + "configureMobileText": "Smartphone/tablet come Controller", + "configureTouchText": "Configura il touchscreen", + "ps3Text": "Controller PS3", + "titleText": "Controller", + "wiimotesText": "Wiimotes", + "xbox360Text": "Controller Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Nota: il supporto ai gamepad varia a seconda del dispositivo e la versione di Android.", + "pressAnyButtonText": "Premi un pulsante qualsiasi sul\nController che vuoi configurare...", + "titleText": "Configura i Controller" + }, + "configGamepadWindow": { + "advancedText": "Avanzato", + "advancedTitleText": "Impostazioni Avanzate Controller", + "analogStickDeadZoneDescriptionText": "(aumentalo se il personaggio continua a camminare anche quando non tocchi nulla)", + "analogStickDeadZoneText": "Zona Neutrale Levetta Analogica", + "appliesToAllText": "(si applica a tutti i Controller di questo tipo)", + "autoRecalibrateDescriptionText": "(abilita se il tuo personaggio non si muove alla massima velocità)", + "autoRecalibrateText": "Autocalibra le levette analogiche", + "axisText": "Asse", + "clearText": "reimposta", + "dpadText": "dpad", + "extraStartButtonText": "Tasto Start Extra", + "ifNothingHappensTryAnalogText": "Se non succede nulla, prova invece ad assegnarlo alla levetta analogica", + "ifNothingHappensTryDpadText": "Se non succede nulla, prova invece ad assegnarlo al d-pad.", + "ignoreCompletelyDescriptionText": "(impedisci a questo controller di modificare il gioco o i menu)", + "ignoreCompletelyText": "Ignora Completamente", + "ignoredButton1Text": "Tasto Ignorato 1", + "ignoredButton2Text": "Tasto Ignorato 2", + "ignoredButton3Text": "Tasto Ignorato 3", + "ignoredButton4Text": "Pulsante sconosciuto 4", + "ignoredButtonDescriptionText": "(usa questo per prevenire che i pulsanti 'home' o 'sync' influenzino il gioco)", + "ignoredButtonText": "Pulsante ignorato", + "pressAnyAnalogTriggerText": "Premi un qualunque grilletto analogico...", + "pressAnyButtonOrDpadText": "Premi un qualsiasi pulsante o d-pad...", + "pressAnyButtonText": "Premi un pulsante qualsiasi...", + "pressLeftRightText": "Premi il pulsante destra o sinistra...", + "pressUpDownText": "Premi il pulsante su o giù...", + "runButton1Text": "Pulsante per Correre 1", + "runButton2Text": "Pulsante per Correre 2", + "runTrigger1Text": "Grilletto per Correre 1", + "runTrigger2Text": "Grilletto per Correre 2", + "runTriggerDescriptionText": "(i grilletti analogici ti permettono di variare la velocità di corsa)", + "secondHalfText": "Usa questo per configurare la seconda metà\ndi un dispositivo 2-controller-in-1 che\nviene mostrato come controller singolo.", + "secondaryEnableText": "Abilita", + "secondaryText": "Controller secondario", + "startButtonActivatesDefaultDescriptionText": "(disattivalo se il tuo pulsante Start è più che altro un pulsante \"menu/pausa\")", + "startButtonActivatesDefaultText": "Non usare il pulsante Start/Menu del controller (se presente) per correre", + "titleText": "Configurazione Controller", + "twoInOneSetupText": "Installazione controller 2-in-1", + "uiOnlyDescriptionText": "(non permettere a questo controller di essere usato durante il gioco)", + "uiOnlyText": "Limita l'uso al Menu", + "unassignedButtonsRunText": "Corri tenendo premuto qualsiasi pulsante", + "unsetText": "", + "vrReorientButtonText": "Pulsante Reset VR" + }, + "configKeyboardWindow": { + "configuringText": "Configurando ${DEVICE}", + "keyboard2NoteText": "Nota: la maggior parte delle tastiere può registrare solo un numero\nridotto di pulsanti premuti alla volta, quindi se c'è un secondo\ngiocatore alla tastiera potrebbe risultare meglio farlo giocare\nsu una tastiera a parte. Nota che dovrai assegnare tasti diversi\nai due giocatori anche in quel caso." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Dimensione controlli azioni", + "actionsText": "Azioni", + "buttonsText": "Pulsanti", + "dragControlsText": "< Trascina i comandi in modo da riposizionarli >", + "joystickText": "Joystick", + "movementControlScaleText": "Dimensione controlli movimento", + "movementText": "Movimento", + "resetText": "Reset", + "swipeControlsHiddenText": "Nascondi icone a scivolo", + "swipeInfoText": "Ci vuole un po' per abituarsi ai comandi a scivolo,\nma rendono più facile giocare senza guardare i tasti o lo stick.", + "swipeText": "Scivolo", + "titleText": "Configura il Touchscreen", + "touchControlsScaleText": "Scala dei Comandi Touch" + }, + "configureItNowText": "Configurarlo adesso?", + "configureText": "Configura", + "connectMobileDevicesWindow": { + "amazonText": "Appstore di Amazon", + "appStoreText": "App store", + "bestResultsText": "Le prestazioni del gamepad dipendono dalla tua rete wifi.\nPuoi ridurre il ritardo (lag) avvicinandoti al router,\ncollegandoti tramite cavo di rete (dove possibile)\no disattivando altri dispositivi WiFi che non usi.", + "explanationText": "Per usare uno smartphone o un tablet come controller wireless,\ninstallaci l'app \"${REMOTE_APP_NAME}\". Puoi connettere quanti\ndispositivi vuoi a ${APP_NAME} tramite WiFi, ed è gratis!", + "forAndroidText": "Per Android:", + "forIOSText": "Per iOS:", + "getItForText": "Scarica ${REMOTE_APP_NAME} per iOS dall'AppStore Apple o\nper Android dal GooglePlay Store o dall'Appstore Amazon", + "googlePlayText": "Google Play", + "titleText": "Smartphone/Tablet come Controller:" + }, + "continuePurchaseText": "Proseguire per ${PRICE}?", + "continueText": "Proseguire", + "controlsText": "Comandi", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Questo non viene applicato al punteggio totale", + "activenessInfoText": "Questo moltiplicatore aumenta i giorni che giochi\n e diminuisce quando non giochi", + "activityText": "Attività", + "campaignText": "Campagna", + "challengesInfoText": "Ottieni premi completando mini-giochi.\n\nI premi e la difficoltà aumentano ogni volta\nche una sfida è completata e diminuiscono\nquando queste scadono o vengono abbandonate.", + "challengesText": "Sfide", + "currentBestText": "Attuale Migliore", + "customText": "Personalizzati", + "entryFeeText": "Ingresso", + "forfeitConfirmText": "Abbandonare questa sfida?", + "forfeitNotAllowedYetText": "Questa sfida non puó essere abbandonata.", + "forfeitText": "Abbandona", + "multipliersText": "Moltiplicatori", + "nextChallengeText": "Sfida successiva", + "nextPlayText": "Prossima partita", + "ofTotalTimeText": "su ${TOTAL}", + "playNowText": "Gioca ora", + "pointsText": "Punti", + "powerRankingFinishedSeasonUnrankedText": "(stagione finita senza essere classificato)", + "powerRankingNotInTopText": "(non nella top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} punti", + "powerRankingPointsMultText": "(x ${NUMBER} punti)", + "powerRankingPointsText": "${NUMBER} punti", + "powerRankingPointsToRankedText": "(${CURRENT} di ${REMAINING} punti)", + "powerRankingText": "Punteggi", + "prizesText": "Premi", + "proMultInfoText": "I giocatori con il ${PRO} upgrade\nricevono il ${PERCENT}% di punti in più.", + "seeMoreText": "Altri...", + "skipWaitText": "Salta attesa", + "timeRemainingText": "Tempo Rimanente", + "titleText": "Cooperativi", + "toRankedText": "Al prossimo livello", + "totalText": "Totale", + "tournamentInfoText": "Competi per punteggi alti con\naltri giocatori della tua lega.\n\nI premi sono assegnati ai giocatori con\ni punteggi più alti quando il tempo del torneo scade.", + "welcome1Text": "Benvenuto in ${LEAGUE}. Puoi migliorare il tuo\n livello lega guadagnando stelle, completando\n obbiettivi, e vincendo i trofei.", + "welcome2Text": "Puoi anche guadagnare biglietti con molte attività simili.\nI biglietti possono essere usato per sbloccare nuovi capitoli, mappe e\nmini-giochi, per entrare nei tornei ed altro.", + "yourPowerRankingText": "La tua posizione assoluta" + }, + "copyConfirmText": "Copiato negli appunti.", + "copyOfText": "${NAME} - Copia", + "copyText": "Copia", + "copyrightText": "© 2013 Eric Froemling", + "createAPlayerProfileText": "Creare un profilo giocatore?", + "createEditPlayerText": "", + "createText": "Crea", + "creditsWindow": { + "additionalAudioArtIdeasText": "Effetti sonori addizionali, disegni iniziali e idee di ${NAME}", + "additionalMusicFromText": "Musiche extra: ${NAME}", + "allMyFamilyText": "Tutti i miei amici e familiari che hanno aiutato a testare il gioco", + "codingGraphicsAudioText": "Programmazione, Grafica e Audio di ${NAME}", + "languageTranslationsText": "Traduzioni:", + "legalText": "Note legali:", + "publicDomainMusicViaText": "Musica di pubblico dominio via ${NAME}", + "softwareBasedOnText": "Questo software è basato in parte sul lavoro di ${NAME}", + "songCreditText": "${TITLE} Eseguita da ${PERFORMER}\nComposta da ${COMPOSER}, arrangiata da ${ARRANGER}, pubblicata da ${PUBLISHER},\nPer concessione di ${SOURCE}", + "soundAndMusicText": "Effetti sonori & Musica:", + "soundsText": "Effetti sonori (${SOURCE}):", + "specialThanksText": "Ringraziamenti Speciali:", + "thanksEspeciallyToText": "Grazie specialmente a ${NAME}", + "titleText": "Riconoscimenti per ${APP_NAME}", + "whoeverInventedCoffeeText": "Chiunque abbia inventato il caffè" + }, + "currentStandingText": "La tua attuale posizione è #${RANK}", + "customizeText": "Personalizza...", + "deathsTallyText": "${COUNT} morti", + "deathsText": "Morti", + "debugText": "Debug", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Nota: si raccomanda di impostare le texture 'Alte' in Impostazioni->Grafiche->Texture per questa prova.", + "runCPUBenchmarkText": "Esegui Benchmark CPU", + "runGPUBenchmarkText": "Esegui Benchmark GPU", + "runMediaReloadBenchmarkText": "Esegui Benchmark Media-Reload", + "runStressTestText": "Testa il gioco", + "stressTestPlayerCountText": "Numero Giocatori", + "stressTestPlaylistDescriptionText": "Stress Test Playlist", + "stressTestPlaylistNameText": "Nome Playlist", + "stressTestPlaylistTypeText": "Tipo Playlist", + "stressTestRoundDurationText": "Durata Round", + "stressTestTitleText": "Prova di Carico", + "titleText": "Benchmark e Stress Test", + "totalReloadTimeText": "Tempo totale di ricarica: ${TIME} (vedi log per i dettagli)", + "unlockCoopText": "Sblocca i livelli cooperativi" + }, + "defaultFreeForAllGameListNameText": "Partite Tutti Contro Tutti predefinite", + "defaultGameListNameText": "Scaletta ${PLAYMODE} predefinita", + "defaultNewFreeForAllGameListNameText": "Le mie partite Tutti Contro Tutti", + "defaultNewGameListNameText": "Le mie scalette ${PLAYMODE}", + "defaultNewTeamGameListNameText": "I miei giochi a squadre", + "defaultTeamGameListNameText": "Giochi a squadre predefiniti", + "deleteText": "Cancella", + "demoText": "Demo", + "denyText": "Nega", + "deprecatedText": "Deprecato", + "desktopResText": "Risoluzione Nativa", + "deviceAccountUpgradeText": "Attenzione:\nHai effettuato l'accesso con un profilo dispositivo (${NAME}$).\nI profili dispositivi verranno rimossi in un aggiornamento futuro.\nAggiornati ad un profilo V2 se desideri mantenere i tuoi progressi.", + "difficultyEasyText": "Facile", + "difficultyHardOnlyText": "Solo Modalità Difficile", + "difficultyHardText": "Difficile", + "difficultyHardUnlockOnlyText": "Questo livello può essere sbloccato solo in modalità difficile.\nPensi di avere la stoffa per farlo?!", + "directBrowserToURLText": "Visita quest'indirizzo sul tuo computer:", + "disableRemoteAppConnectionsText": "Disattiva connessione remota all'app", + "disableXInputDescriptionText": "Permette l'uso di più di 4 pulsantiere, ma potrebbe anche non funzionare.", + "disableXInputText": "Disabilita XInput", + "doneText": "Fatto", + "drawText": "Pareggio", + "duplicateText": "Duplicato", + "editGameListWindow": { + "addGameText": "Aggiungi\nGioco", + "cantOverwriteDefaultText": "Non puoi sovrascrivere la scaletta predefinita!", + "cantSaveAlreadyExistsText": "Una scaletta con quel nome esiste già!", + "cantSaveEmptyListText": "Non puoi salvare una scaletta vuota!", + "editGameText": "Modifica\nGioco", + "gameListText": "Serie di Partite", + "listNameText": "Nome Scaletta", + "nameText": "Nome", + "removeGameText": "Rimuovi\nGioco", + "saveText": "Salva la serie", + "titleText": "Editor della Scaletta" + }, + "editProfileWindow": { + "accountProfileInfoText": "Questo è uno speciale profilo giocatore con un\nnome e icona basati sul tuo account attualmente connesso.\n\n${ICONS}\n\nCrea profili personalizzati se vuoi usare\nnomi o icone differenti.", + "accountProfileText": "(profilo account)", + "availableText": "Il nome \"${NAME}\" è disponibile.", + "changesNotAffectText": "Nota: i cambiamenti non influiranno sui personaggi già in gioco", + "characterText": "personaggio", + "checkingAvailabilityText": "Controllo disponibilità per \"${NAME}\"...", + "colorText": "colore", + "getMoreCharactersText": "Ottieni altri personaggi...", + "getMoreIconsText": "Ottieni più icone...", + "globalProfileInfoText": "I profili globali del giocatore garantiscono di avere nomi\nunici in tutto il mondo. Includono anche delle icone personalizzate.", + "globalProfileText": "(profilo globale)", + "highlightText": "colore principale", + "iconText": "icona", + "localProfileInfoText": "I profili giocatori locali non hanno icone e non è\n garantito che siano unici. Aggiorna a un profilo\nglobale per riservare un nome unico e per aggiungere un'icona personalizzata", + "localProfileText": "(profilo locale)", + "nameDescriptionText": "Nome del giocatore", + "nameText": "Nome", + "randomText": "casuale", + "titleEditText": "Modifica Profilo", + "titleNewText": "Nuovo Profilo", + "unavailableText": "\"${NAME}\" non è disponibile; prova un altro nome.", + "upgradeProfileInfoText": "Questo riserverà il tuo nome in tutto il mondo\nè ti permetterà di assegnare un'icona personalizzata ad esso.", + "upgradeToGlobalProfileText": "Aggiorna al Profilo Globale" + }, + "editProfilesAnyTimeText": "(puoi creare profili in qualiasi momento sotto la voce 'impostazioni')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Impossibile cancellare la colonna sonora predefinita.", + "cantEditDefaultText": "Impossibile modificare la colonna sonora predefinita. Duplicala o creane una nuova.", + "cantEditWhileConnectedOrInReplayText": "Impossibile modificare la colonna sonora mentre connesso ad un gruppo o in un replay. ", + "cantOverwriteDefaultText": "Impossibile sovrascrivere la colona sonora predefinita", + "cantSaveAlreadyExistsText": "Esiste già una colonna sonora con quel nome!", + "copyText": "Copia", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Colonna sonora predefinita", + "deleteConfirmText": "Cancellare la colonna sonora:\n\n'${NAME}'?", + "deleteText": "Elimina", + "duplicateText": "Duplica", + "editSoundtrackText": "Editor Colonna Sonora", + "editText": "Modifica", + "fetchingITunesText": "Recupero playlist musicale dall'app", + "musicVolumeZeroWarning": "Attenzione: il volume della musica è impostato a 0", + "nameText": "Nome", + "newSoundtrackNameText": "La mia Colonna Sonora ${COUNT}", + "newSoundtrackText": "Nuova colonna sonora:", + "newText": "Nuova", + "selectAPlaylistText": "Seleziona una playlist", + "selectASourceText": "Fonte Musica", + "soundtrackText": "Colonna sonora", + "testText": "test", + "titleText": "Colonne Sonore", + "useDefaultGameMusicText": "Musica Predefinita", + "useITunesPlaylistText": "Playlist di colonne sonore da app musicale", + "useMusicFileText": "File Musicale (mp3, ecc)", + "useMusicFolderText": "Cartella di Musica" + }, + "editText": "Modifica", + "endText": "Fine", + "enjoyText": "Buon Divertimento!", + "epicDescriptionFilterText": "${DESCRIPTION} a rallentatore leggendario.", + "epicNameFilterText": "${NAME} Leggendario", + "errorAccessDeniedText": "accesso negato", + "errorDeviceTimeIncorrectText": "L'orario del tuo dispositivo è incorretto di ${HOURS} ore.\nCiò può causare problemi.\nControlla il tuo orario e fuso orario impostato.", + "errorOutOfDiskSpaceText": "spazio su disco esaurito", + "errorSecureConnectionFailText": "Impossibile stabilire una connessione sicura con il cloud; le funzionalità online possono interrompersi.", + "errorText": "Errore", + "errorUnknownText": "errore sconosciuto", + "exitGameText": "Uscire da ${APP_NAME}?", + "exportSuccessText": "'${NAME}' esportato", + "externalStorageText": "Memoria Esterna", + "failText": "Perso", + "fatalErrorText": "Ops! qualcosa non va.\nPer favore provate a reinstallare l'app o\ncontattate ${EMAIL} per ricevere aiuto.", + "fileSelectorWindow": { + "titleFileFolderText": "Scegli un File o Cartella", + "titleFileText": "Scegli un File", + "titleFolderText": "Scegli una Cartella", + "useThisFolderButtonText": "Usa Questa Cartella" + }, + "filterText": "Filtro", + "finalScoreText": "Punteggio finale", + "finalScoresText": "Punteggi finali", + "finalTimeText": "Tempo finale", + "finishingInstallText": "Completamento installazione; un istante...", + "fireTVRemoteWarningText": "* Per una migliore esperienza,\nusa dei Controller o installa\nl'app '${REMOTE_APP_NAME}' sui\ntuoi telefoni o tablet.", + "firstToFinalText": "Finale First-to-${COUNT}", + "firstToSeriesText": "Serie First-to-${COUNT}", + "fiveKillText": "CINQUE UCCISIONI!!!", + "flawlessWaveText": "Ondata Impeccabile!", + "fourKillText": "QUATTRO UCCISIONI!!!", + "freeForAllText": "Tutti Contro Tutti", + "friendScoresUnavailableText": "Punteggi degli amici non disponibili.", + "gameCenterText": "Game Center", + "gameCircleText": "GameCircle", + "gameLeadersText": "Leader della partita ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "Non puoi eliminare la scaletta predefinita!", + "cantEditDefaultText": "Non puoi modificare la scaletta predefinita! Duplicala o creane una nuova.", + "cantShareDefaultText": "Non puoi condividere la scaletta predefinita", + "deleteConfirmText": "Eliminare \"${LIST}\"?", + "deleteText": "Elimina", + "duplicateText": "Duplica\nScaletta", + "editText": "Modifica\nScaletta", + "gameListText": "Lista delle serie di partite", + "newText": "Nuova\nScaletta", + "showTutorialText": "Mostra Guida", + "shuffleGameOrderText": "Ordine Partite Casuale", + "titleText": "Personalizza Scalette ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Aggiungi Partita" + }, + "gamepadDetectedText": "Un gamepad rilevato.", + "gamepadsDetectedText": "${COUNT} gamepad rilevati.", + "gamesToText": "${WINCOUNT} - ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Ricorda: qualunque dispositivo in un gruppo può ospitare \npiù di un giocatore se si hanno abbastanza controller.", + "aboutDescriptionText": "Usa queste schede per assemblare un party.\n\nI party ti permettono di partecipare a giochi e\ntornei con i tuoi amici usando diversi dispositivi.\n\nUsa il tasto ${PARTY} in alto a destra per chattare\ne interagire con il tuo gruppo.\n(su un controller, premi ${BUTTON} in un menu)", + "aboutText": "Informazioni", + "addressFetchErrorText": "", + "appInviteInfoText": "Invita i tuoi amici a provare BonvSquad e loro \nriceveranno ${COUNT} biglietti gratis. Tu guadagnerai\n${YOU_COUNT} per ogni amico che lo farà.", + "appInviteMessageText": "${NAME} ti ha mandato ${COUNT} biglietti per ${APP_NAME}", + "appInviteSendACodeText": "Inviagli un codice", + "appInviteTitleText": "Invito per l'app di ${APP_NAME}", + "bluetoothAndroidSupportText": "(funziona su dispositivi Android dotati di Bluetooth)", + "bluetoothDescriptionText": "Ospita/unisciti a un party via Bluetooth:", + "bluetoothHostText": "Ospita via Bluetooth", + "bluetoothJoinText": "Unisciti via Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "controllo in corso...", + "copyCodeConfirmText": "Codice copiato negli appunti!", + "copyCodeText": "Copia il codice", + "dedicatedServerInfoText": "Per risultati migliori, crea un server dedicato. Vedi bombsquadgame.com/server per scoprire come.", + "disconnectClientsText": "Questo disconnetterà ${COUNT} giocatore/i\nnel tuo gruppo. Sei sicuro?", + "earnTicketsForRecommendingAmountText": "I tuoi amici riceveranno ${COUNT} biglietti se proveranno il gioco\n(anche tu riceverai ${YOU_COUNT} biglietti per ogni amico che lo farà)", + "earnTicketsForRecommendingText": "Condividi il gioco\nper biglietti gratis...", + "emailItText": "Manda Email", + "favoritesSaveText": "Salva nei preferiti", + "favoritesText": "Preferiti", + "freeCloudServerAvailableMinutesText": "Il prossimo server gratuito sarà disponibile tra ${MINUTES} minuti!", + "freeCloudServerAvailableNowText": "Server gratuito disponibile!", + "freeCloudServerNotAvailableText": "Nessun server gratuito disponibile", + "friendHasSentPromoCodeText": "${COUNT} biglietti di ${APP_NAME} da ${NAME}", + "friendPromoCodeAwardText": "Riceverai ${COUNT} biglietti ogni volta che viene usato.", + "friendPromoCodeExpireText": "Questo codice scadrà in ${EXPIRE_HOURS} ore e funziona soltanto per nuovi giocatori.", + "friendPromoCodeInstructionsText": "Per usarlo, apri ${APP_NAME} e vai su \"Impostazioni->Avanzate->Inserisci Codice\".\nVisita bombsquadgame.com per i link di download per tutte le versioni supportate.", + "friendPromoCodeRedeemLongText": "Puó essere utilizzato per ${COUNT} biglietti gratis per un massimo di ${MAX_USES} persone.", + "friendPromoCodeRedeemShortText": "Puó essere utilizzato per ${COUNT} biglietti nel gioco.", + "friendPromoCodeWhereToEnterText": "(in \"Impostazioni->Avanzate->Inserisci Codice\")", + "getFriendInviteCodeText": "Ottieni un Codice di Invito", + "googlePlayDescriptionText": "Invita giocatori Google Play nel tuo gruppo:", + "googlePlayInviteText": "Invita", + "googlePlayReInviteText": "Ci sono ${COUNT} giocatori di Google Play nel tuo gruppo\nche saranno disconnessi se mandi un nuovo invito.\nIncludili nel nuovo invito per farli tornare.", + "googlePlaySeeInvitesText": "Visualizza inviti", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(solo nella versione Android / Google Play)", + "hostPublicPartyDescriptionText": "Ospita un Party pubblico:", + "hostingUnavailableText": "Hosting non disponibile", + "inDevelopmentWarningText": "Note:\n\nIl gioco in rete è una funzione ancora in fase di sviluppo. \nPer adesso, è altamente raccomandato che tutti\ni giocatori siano sulla stessa rete WiFi.", + "internetText": "Internet", + "inviteAFriendText": "I tuoi amici non hanno il gioco? Invitati a\nprovarlo e riceveranno ${COUNT} biglietti gratis.", + "inviteFriendsText": "Invita Amici", + "joinPublicPartyDescriptionText": "Unisciti a un party pubblico", + "localNetworkDescriptionText": "Unisciti ad un Party vicino (LAN, Bluetooth, etc.)", + "localNetworkText": "Rete locale", + "makePartyPrivateText": "Rendi privato il mio party", + "makePartyPublicText": "Rendi pubblico il mio party", + "manualAddressText": "Indirizzi", + "manualConnectText": "Connettiti", + "manualDescriptionText": "Unisciti a un gruppo all'indirizzo:", + "manualJoinSectionText": "Unisciti con l'indirizzo", + "manualJoinableFromInternetText": "Sei raggiungibile da internet?", + "manualJoinableNoWithAsteriskText": "NO*", + "manualJoinableYesText": "SÌ", + "manualRouterForwardingText": "*come rimedio, prova a far inoltrare al router la porta UDP ${PORT} verso l'indirizzo locale", + "manualText": "Manuale", + "manualYourAddressFromInternetText": "Il tuo indirizzo da internet:", + "manualYourLocalAddressText": "Indirizzo locale:", + "nearbyText": "Locale", + "noConnectionText": "", + "otherVersionsText": "(altre versioni)", + "partyCodeText": "Codice del Party", + "partyInviteAcceptText": "Accetta", + "partyInviteDeclineText": "Rifiuta", + "partyInviteGooglePlayExtraText": "(vedi la scheda 'Google Play' nella finestra 'Raduna')", + "partyInviteIgnoreText": "Ignora", + "partyInviteText": "${NAME} ti ha invitato\nad unirsi al suo party!", + "partyNameText": "Nome Party", + "partyServerRunningText": "Il tuo party è in esecuzione.", + "partySizeText": "dimensione party", + "partyStatusCheckingText": "controllo status in corso...", + "partyStatusJoinableText": "il tuo party è ora raggiungibile da internet", + "partyStatusNoConnectionText": "impossibile connettersi al server", + "partyStatusNotJoinableText": "il tuo party non è raggiungibile da internet", + "partyStatusNotPublicText": "il tuo party non è pubblico", + "pingText": "ping", + "portText": "Porta", + "privatePartyCloudDescriptionText": "I party privati prendono posto su dei cloud server fatti apposta; non c'è bisogno di una configurazione del router.", + "privatePartyHostText": "Ospita un Party privato", + "privatePartyJoinText": "Entra in un Party privato", + "privateText": "Privato", + "publicHostRouterConfigText": "Questa opzione richiede la configurazione di port-forwarding sul tuo router. Per comodità, utilizza la funzionalità di hosting su server", + "publicText": "Pubblico", + "requestingAPromoCodeText": "Richiesta codice in corso...", + "sendDirectInvitesText": "Invia Inviti Diretti", + "shareThisCodeWithFriendsText": "Condividi questo codice con i tuoi amici:", + "showMyAddressText": "Mostra il mio IP", + "startHostingPaidText": "Hosting disponibile per ${COST}", + "startHostingText": "Ospita il party!", + "startStopHostingMinutesText": "Puoi avviare o terminare il tuo server gratuitamente entro ${MINUTES} minuti", + "stopHostingText": "Termina l'Hosting", + "titleText": "Raduna", + "wifiDirectDescriptionBottomText": "Se tutti i dispositivi hanno un pannello 'WiFi direct', dovrebbero poterlo usare\nper trovarsi e connettersi l'un l'altro. Una volta connessi, potrai formare gruppi\nqui utilizzando la scheda \"Rete Locale\", come fosse una rete WiFi.\n\nPer risultati migliori, l'host WiFi Direct dovrebbe essere anche l'host ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct può essere usato per connettere dispositivi Android direttamente\nsenza l'uso di una rete Wi-Fi. Funziona meglio con Android 4.2 o superiore.\n\nPer usarlo, apri le impostazioni Wi-Fi e cerca la voce 'Wi-Fi Direct' nel menu.", + "wifiDirectOpenWiFiSettingsText": "Apri Impostazioni Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(funziona fra tutte le piattaforme)", + "worksWithGooglePlayDevicesText": "(funziona con dispositivi che usano la versione Google Play (Android) del gioco)", + "youHaveBeenSentAPromoCodeText": "Ti è stato spedito un codice promozionale di ${APP_NAME}:" + }, + "getCoinsWindow": { + "coinDoublerText": "Raddoppia Monete", + "coinsText": "${COUNT} Monete", + "freeCoinsText": "Monete Gratuite", + "restorePurchasesText": "Ripristina Acquisti", + "titleText": "Ottieni Monete" + }, + "getTicketsWindow": { + "freeText": "GRATIS!", + "freeTicketsText": "Biglietti Gratuiti", + "inProgressText": "Una transazione è in corso; prova di nuovo in un secondo momento.", + "purchasesRestoredText": "Acquisti ripristinati.", + "receivedTicketsText": "Ricevuti ${COUNT} biglietti!", + "restorePurchasesText": "Ripristina Acquisti", + "ticketDoublerText": "Raddoppia Biglietti", + "ticketPack1Text": "Pacchetto Biglietti Piccolo", + "ticketPack2Text": "Pacchetto Biglietti Medio", + "ticketPack3Text": "Pacchetto Biglietti Grande", + "ticketPack4Text": "Pacchetto Biglietti Jumbo", + "ticketPack5Text": "Pacchetto Biglietti Mammuth", + "ticketPack6Text": "Pacchetto Biglietti Ultimate", + "ticketsFromASponsorText": "Guarda una pubblicità\nper ${COUNT} biglietti", + "ticketsText": "${COUNT} Biglietti", + "titleText": "Ottieni Biglietti", + "unavailableLinkAccountText": "Scusa, gli acquisti non sono disponibili su questa piattaforma.\nCome soluzione, puoi collegare questo account ad un'altra \npiattaforma e fare l'acquisto lì.", + "unavailableTemporarilyText": "Non disponibile al momento: riprova più tardi.", + "unavailableText": "Spiacenti, non disponibile.", + "versionTooOldText": "Mi dispiace, questa versione del gioco è troppo vecchia; ti preghiamo di aggiornare.", + "youHaveShortText": "Hai ${COUNT}", + "youHaveText": "Hai ${COUNT} biglietti" + }, + "googleMultiplayerDiscontinuedText": "Mi dispiace, il servizio multiplayer di Google non è più disponibile.\nSto lavorando per sostituirlo il più velocemente possibile.\nFino a quando non troverò una soluzione, prova un altro metodo per connetterti.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Gli acquisti Google Play non sono disponibili.\nPotresti dover aggiornare lo store.", + "googlePlayServicesNotAvailableText": "Google Play Services non è disponibile.\nAlcune funzionalità dell'app saranno disattivate.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Sempre", + "autoText": "Automatico", + "fullScreenCmdText": "Schermo intero (Cmd-F)", + "fullScreenCtrlText": "Schermo intero (Ctrl-F)", + "gammaText": "Gamma", + "highText": "Alto", + "higherText": "Più alto", + "lowText": "Basso", + "mediumText": "Medio", + "neverText": "Mai", + "resolutionText": "Risoluzione", + "showFPSText": "Mostra FPS", + "texturesText": "Textures", + "titleText": "Grafiche", + "tvBorderText": "Bordo della TV", + "verticalSyncText": "Sincronizzazione verticale", + "visualsText": "Visuali" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nPiù forte dei pugni, ma \npuò risultare autolesionistica.\nPer un risultato migliore, lanciala\nin direzione del nemico prima\nche la miccia si esaurisca.", + "canHelpText": "${APP_NAME} può aiutarti.", + "controllersInfoText": "Puoi giocare a ${APP_NAME} con gli amici attraverso la rete,\no mediante lo stesso dispositivo se hai abbastanza controller.\n${APP_NAME} ne supporta diversi; puoi usare perfino smartphones\ncome controller grazie all'app gratuita '${REMOTE_APP_NAME}'.\nVedi Impostazioni->Controller per ulteriori informazioni.", + "controllersInfoTextFantasia": "Puoi usare il telecomando per giocare, ma suggerisco\nvivamente di usare i gamepad. Puoi anche usare i tuoi cellulari e\ntablet come controller usando l'app gratuita \"BombSquad Remote\".\nVai su \"Impostazioni\" e poi \"Controller\" per più informazioni.", + "controllersInfoTextMac": "Uno o due giocatori possono usare la tastiera, ma BombSquad dà il meglio usando i Gamepad.\nPuoi controllare i personaggi usando Gamepad USB, controller PS3 o Xbox 360, Wiimote e \ndispositivi iOS/Android. Si spera che tu abbia alcuni di questi sotto mano. \nPer ulteriori informazioni vai su Impostazioni > Controller", + "controllersInfoTextOuya": "Con BombSquad puoi utilizzare controller OUYA, PS3 e Xbox 360, e tanti\naltri Gamepad USB e Bluetooth. Puoi anche utilizzare dispositivi iOS e\nAndroid come controller tramite l'app gratuita 'BombSquad Remote'.\nPer ulteriori informazioni vai su Impostazioni > Controller.", + "controllersInfoTextRemoteOnly": "Tu puoi giocare a ${APP_NAME} con i tuoi amici su una connessione,\no puoi\nanche giocare sullo stesso dispositivo usando dei telefoni come controllers gratuitamente con l'app '${REMOTE_APP_NAME}'", + "controllersText": "Controller", + "controlsSubtitleText": "Il tuo amichevole personaggio di ${APP_NAME} ha poche azioni di base:", + "controlsText": "Comandi", + "devicesInfoText": "Si può giocare online con la versione VR di ${APP_NAME} con la versione\ncompleta, perciò tirate fuori i telefonini, tablet, e computer e comin-\nciate a giocare. Può essere anche utile connettere una versione completa\ndel gioco con una VR solo per permettere alla gente fuori di seguire \nl'azione.", + "devicesText": "Dispositivi", + "friendsGoodText": "È sempre meglio averne. ${APP_NAME} è molto più divertente con tanti giocatori,\nfino ad un massimo di 8 per volta, che ci porta a poter usare:", + "friendsText": "Amici", + "jumpInfoText": "- Salto -\nSalta per aggirare piccoli ostacoli,\nlanciare oggetti più in alto, e\nesprimere la tua gioia.", + "orPunchingSomethingText": "O per prenderla a pugni, buttarla giù da un precipizio e farla saltare giù con una bomba appiccicosa..", + "pickUpInfoText": "- Raccogliere -\nRaccogli bandiere, nemici, o qualsiasi\naltra cosa non fissata sul terreno.\nPremi di nuovo per lanciare.", + "powerupBombDescriptionText": "Permette di lanciare tre bombe\ndi seguito anziché una sola.", + "powerupBombNameText": "Tripla bomba", + "powerupCurseDescriptionText": "Non credo che tu voglia prenderle.\n...o forse sì?", + "powerupCurseNameText": "Maledizione", + "powerupHealthDescriptionText": "Rigenera completamente la tua salute.\nNon l'avresti mai detto, eh?", + "powerupHealthNameText": "Pronto soccorso", + "powerupIceBombsDescriptionText": "Più deboli rispetto alle bombe normali\nma congelano i tuoi nemici\ne li rendono particolarmente fragili.", + "powerupIceBombsNameText": "Bombe ghiaccio", + "powerupImpactBombsDescriptionText": "Leggermente più deboli rispetto alle bombe\nnormali, ma esplodono all'impatto.", + "powerupImpactBombsNameText": "Bombe ad impatto", + "powerupLandMinesDescriptionText": "Sono disponibili in pratiche confezioni da 3;\nUtili per piazzare una difesa di base o\nper fermare nemici rapidi.", + "powerupLandMinesNameText": "Mine antiuomo", + "powerupPunchDescriptionText": "Rendono i tuoi pugni più tosti,\nveloci, migliori e forti.", + "powerupPunchNameText": "Guantoni da boxe", + "powerupShieldDescriptionText": "Assorbono un po' di danno\nal posto tuo.", + "powerupShieldNameText": "Scudo energetico", + "powerupStickyBombsDescriptionText": "Si appiccicano a qualunque cosa colpiscono.\nNe consegue una massiccia dose di ilarità.", + "powerupStickyBombsNameText": "Bombe caccola", + "powerupsSubtitleText": "Ovviamente, nessun gioco è davvero completo se non vi sono potenziamenti:", + "powerupsText": "Potenziamenti", + "punchInfoText": "- Pugno -\nI pugni infliggono molti\npiù danni quanto più velocemente ti muovi,\nquindi corri e scazzotta come un pazzo.", + "runInfoText": "- Corsa -\nTieni premuto un QUALSIASI tasto. Pulsanti dorsali e grilletti funzionano bene se ne hai.\nCorrere ti permette di arrivare prima ma rende difficile girare, perciò attento ai precipizi.", + "someDaysText": "Certi giorni vorresti prendere tutto a pugni. O far esplodere qualcosa.", + "titleText": "Manuale di ${APP_NAME}", + "toGetTheMostText": "Per divertirti al meglio in questo gioco avrai bisogno di:", + "welcomeText": "Benvenuti in ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} sta navigando fra i menu come un vero lupo di mare.", + "importPlaylistCodeInstructionsText": "Usa il codice seguente per importare questa scaletta da un'altra parte:", + "importPlaylistSuccessText": "Importata ${TYPE} la playlist '${NAME}'", + "importText": "Importa", + "importingText": "Importando...", + "inGameClippedNameText": "Nel gioco ci sarà\n\"${NAME}\"", + "installDiskSpaceErrorText": "ERRORE: Impossibile completare l'installazione. \nPotresti aver esaurito lo spazio sul tuo dispositivo. \nLibera un po' di spazio e prova di nuovo.", + "internal": { + "arrowsToExitListText": "Premi ${LEFT} o ${RIGHT} per uscire dalla serie", + "buttonText": "pulsante", + "cantKickHostError": "Non è possibile cacciare l'host.", + "chatBlockedText": "${NAME} è escluso dalla chat per ${TIME} secondi.", + "connectedToGameText": "Unito alla partita '${NAME}'", + "connectedToPartyText": "Unito al gruppo di ${NAME}!", + "connectingToPartyText": "Connessione in corso...", + "connectionFailedHostAlreadyInPartyText": "Connessione fallita; l'host è in un altro gruppo.", + "connectionFailedPartyFullText": "Connessione fallita; il gruppo è pieno.", + "connectionFailedText": "Connessione fallita.", + "connectionFailedVersionMismatchText": "Connessione fallita; l'host usa una versione diversa del gioco.\nAssicuratevi che BombSquad sia aggiornato e riprovate.", + "connectionRejectedText": "Connessione rifiutata.", + "controllerConnectedText": "${CONTROLLER} connesso.", + "controllerDetectedText": "Trovato 1 controller.", + "controllerDisconnectedText": "${CONTROLLER} disconnesso.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} si è disconnesso. Prova a riconnetterlo.", + "controllerForMenusOnlyText": "Questo controller non può essere usato per giocare; solo per la navigazione tra i menu.", + "controllerReconnectedText": "${CONTROLLER} riconnesso.", + "controllersConnectedText": "Trovati ${COUNT} controller.", + "controllersDetectedText": "Trovati ${COUNT} controller.", + "controllersDisconnectedText": "${COUNT} controller disconnessi.", + "corruptFileText": "Ci sono alcuni file corrotti. Si prega di reinstallare il gioco, o di inviare un email ${EMAIL}", + "errorPlayingMusicText": "Errore nel riprodurre la musica: ${MUSIC}", + "errorResettingAchievementsText": "Impossibile ripristinare i trofei online: riprova più tardi.", + "hasMenuControlText": "${NAME} ha il comando del menù.", + "incompatibleNewerVersionHostText": "L'host già giocando una versione più nuova del gioco\nAggiorna il gioco alla versione più recente e riprova", + "incompatibleVersionHostText": "L'host sta usando una versione diversa del gioco.\nAssicuratevi che BombSquad sia aggiornato e riprovate.", + "incompatibleVersionPlayerText": "${NAME} sta usando una versione diversa del gioco.\nAssicuratevi che BombSquad sia aggiornato e riprovate.", + "invalidAddressErrorText": "Errore: indirizzo non valido.", + "invalidNameErrorText": "Errore: nome non valido.", + "invalidPortErrorText": "Errore: porta non valida.", + "invitationSentText": "Invito spedito.", + "invitationsSentText": "${COUNT} inviti spediti.", + "joinedPartyInstructionsText": "Qualcuno si è unito al tuo gruppo.\nVai a 'Gioca' per cominciare una partita.", + "keyboardText": "Tastiera", + "kickIdlePlayersKickedText": "${NAME} cacciato per inattività.", + "kickIdlePlayersWarning1Text": "${NAME} sarà cacciato in ${COUNT} secondi se rimarrà inattivo.", + "kickIdlePlayersWarning2Text": "(puoi disattivarlo in Impostazioni -> Avanzate)", + "leftGameText": "Hai abbandonato '${NAME}'.", + "leftPartyText": "Gruppo di ${NAME} abbandonato.", + "noMusicFilesInFolderText": "La cartella non contiene file musicali.", + "playerJoinedPartyText": "${NAME} si è unito al gruppo!", + "playerLeftPartyText": "${NAME} è uscito dal gruppo.", + "rejectingInviteAlreadyInPartyText": "Rifiuta invito (già in un gruppo).", + "serverRestartingText": "Il server si sta riavviando. Per favore ricollegati tra poco...", + "serverShuttingDownText": "Il server si sta chiudendo...", + "signInErrorText": "Errore nell'accesso.", + "signInNoConnectionText": "Impossibile accedere. (nessuna connessione internet?)", + "teamNameText": "Team ${NAME}", + "telnetAccessDeniedText": "ERRORE: l'utente non ha concesso l'accesso a telnet.", + "timeOutText": "(prenderai il controllo tra ${TIME} secondi)", + "touchScreenJoinWarningText": "Ti sei unito al gioco con il touchscreen.\nSe è stato un errore, premi 'Menu->Lascia Gioco'.", + "touchScreenText": "TouchScreen", + "trialText": "prova", + "unableToResolveHostText": "Errore: impossibile connettersi all'host", + "unavailableNoConnectionText": "Non è al momento disponibile (dipende dalla tua connessione?)", + "vrOrientationResetCardboardText": "Usa questo per ripristinare l'orientamento del VR.\nPer giocare avrai bisogno di un controller esterno.", + "vrOrientationResetText": "Ripristina orientamento VR.", + "willTimeOutText": "(se inattivo potrai riprendere il controllo)" + }, + "jumpBoldText": "SALTO", + "jumpText": "Salta", + "keepText": "Mantieni", + "keepTheseSettingsText": "Mantenere queste impostazioni?", + "keyboardChangeInstructionsText": "Premi due volte Spazio per cambiare la tastiera.", + "keyboardNoOthersAvailableText": "Non sono disponibili altre tastiere.", + "keyboardSwitchText": "Cambiando la tastiera a \"${NAME}\".", + "kickOccurredText": "${NAME} è stato cacciato.", + "kickQuestionText": "Cacciare ${NAME}?", + "kickText": "Caccia", + "kickVoteCantKickAdminsText": "Gli amministratori non possono essere cacciati.", + "kickVoteCantKickSelfText": "Non puoi cacciare te stesso.", + "kickVoteFailedNotEnoughVotersText": "Non ci sono abbastanza giocatori per una votazione", + "kickVoteFailedText": "Voto di caccia fallito.", + "kickVoteStartedText": "Una votazione per l'espulsione di ${NAME} è già in corso", + "kickVoteText": "Vota per cacciare", + "kickVotingDisabledText": "Il voto di caccia è disabilitato.", + "kickWithChatText": "Scrivi ${YES} in chat per sì e ${NO} per no.", + "killsTallyText": "${COUNT} uccisioni", + "killsText": "Uccisioni", + "kioskWindow": { + "easyText": "Facile", + "epicModeText": "Modalità Epica", + "fullMenuText": "Menu completo", + "hardText": "Difficile", + "mediumText": "Medio", + "singlePlayerExamplesText": "Esempi Giocatore Singolo / Co-op", + "versusExamplesText": "Esempi Versus" + }, + "languageSetText": "Lingua impostata: \"${LANGUAGE}\".", + "lapNumberText": "Giro ${CURRENT} di ${TOTAL}", + "lastGamesText": "(ultime ${COUNT} partite)", + "leaderboardsText": "Classifiche", + "league": { + "allTimeText": "Di sempre", + "currentSeasonText": "Stagione corrente (${NUMBER})", + "leagueFullText": "${NAME} Lega", + "leagueRankText": "Punteggio Lega", + "leagueText": "Lega", + "rankInLeagueText": "#${RANK}, ${NAME} Lega${SUFFIX}", + "seasonEndedDaysAgoText": "La stagione è finita da ${NUMBER} giorni.", + "seasonEndsDaysText": "La stagione finirà tra ${NUMBER} giorni.", + "seasonEndsHoursText": "La stagione finisce tra ${NUMBER} ore.", + "seasonEndsMinutesText": "La stagione finisce tra ${NUMBER} minuti.", + "seasonText": "Stagione ${NUMBER}", + "tournamentLeagueText": "Devi raggiungere la lega ${NAME} per partecipare a questo torneo.", + "trophyCountsResetText": "Il numero dei trofei verra azzerato la prossima stagione." + }, + "levelBestScoresText": "Miglior punteggio in ${LEVEL}", + "levelBestTimesText": "Miglior tempo in ${LEVEL}", + "levelFastestTimesText": "Tempo migliore su ${LEVEL}", + "levelHighestScoresText": "Punteggio migliore su ${LEVEL}", + "levelIsLockedText": "${LEVEL} è bloccato.", + "levelMustBeCompletedFirstText": "Devi completare prima il livello ${LEVEL}.", + "levelText": "Livello ${NUMBER}", + "levelUnlockedText": "Livello Sbloccato!", + "livesBonusText": "Vite bonus", + "loadingText": "caricamento", + "loadingTryAgainText": "Caricamento; riprova tra un momento", + "macControllerSubsystemBothText": "Entrambi (non consigliato)", + "macControllerSubsystemClassicText": "Classica", + "macControllerSubsystemDescriptionText": "(Prova a modificare questo se il controller non funziona)", + "macControllerSubsystemMFiNoteText": "Rilevato iOS/Mac Controller\nPotresti voler attivare questi in Impostazioni -> Controller", + "macControllerSubsystemMFiText": "iOS/Mac controller", + "macControllerSubsystemTitleText": "Supporto controller", + "mainMenu": { + "creditsText": "Riconoscimenti", + "demoMenuText": "Menu Demo", + "endGameText": "Chiudi partita", + "endTestText": "Termina Test", + "exitGameText": "Esci dal gioco", + "exitToMenuText": "Tornare al menu?", + "howToPlayText": "Come Giocare", + "justPlayerText": "(solo ${NAME})", + "leaveGameText": "Lascia Gioco", + "leavePartyConfirmText": "Lasciare davvero il gruppo?", + "leavePartyText": "Lascia Gruppo", + "leaveText": "Espelli giocatore", + "quitText": "Esci", + "resumeText": "Riprendi", + "settingsText": "Impostazioni" + }, + "makeItSoText": "Va Bene Così", + "mapSelectGetMoreMapsText": "Ottieni altre Mappe...", + "mapSelectText": "Cambia...", + "mapSelectTitleText": "Mappe per ${GAME}", + "mapText": "Mappa", + "maxConnectionsText": "Connessioni massime", + "maxPartySizeText": "Dimensione massima gruppo", + "maxPlayersText": "Giocatori massimi", + "merchText": "Mercancía!", + "modeArcadeText": "Modalità Arcade", + "modeClassicText": "Modalità Classica", + "modeDemoText": "Modalità Demo", + "mostValuablePlayerText": "Giocatore Più Bravo", + "mostViolatedPlayerText": "Giocatore Più Ucciso", + "mostViolentPlayerText": "Giocatore Più Violento", + "moveText": "Muovi", + "multiKillText": "${COUNT} UCCISIONI!!!", + "multiPlayerCountText": "${COUNT} giocatori", + "mustInviteFriendsText": "Nota: dovete invitare degli amici nel\npannello \"${GATHER}\" o collegare\ndei controller per giocare in multiplayer.", + "nameBetrayedText": "${NAME} ha tradito ${VICTIM}.", + "nameDiedText": "${NAME} è morto.", + "nameKilledText": "${NAME} ha ucciso ${VICTIM}.", + "nameNotEmptyText": "Il nome non può essere vuoto!", + "nameScoresText": "${NAME} ha segnato!", + "nameSuicideKidFriendlyText": "${NAME} è morto accidentalmente.", + "nameSuicideText": "${NAME} si è suicidato.", + "nameText": "Nome", + "nativeText": "Nativa", + "newPersonalBestText": "Nuovo record personale!", + "newTestBuildAvailableText": "Una nuova versione beta è disponibile (${VERSION} build ${BUILD}).\nScaricala da ${ADDRESS}", + "newText": "Nuovo", + "newVersionAvailableText": "Una nuova versione di ${APP_NAME} è disponibile! (${VERSION})", + "nextAchievementsText": "Prossimi Trofei:", + "nextLevelText": "Prossimo Livello", + "noAchievementsRemainingText": "- nessuno", + "noContinuesText": "(non continua)", + "noExternalStorageErrorText": "Nessun archiviatore esterno trovato su questo dispositivo", + "noGameCircleText": "Errore: non hai effettuato il login su GameCircle", + "noJoinCoopMidwayText": "Non puoi entrare in una partita cooperativa già iniziata.", + "noProfilesErrorText": "Non hai un profilo giocatore, quindi sei bloccato con '${NAME}'.\nVai su Impostazioni > Profili giocatore per creare un profilo personale.", + "noScoresYetText": "Ancora nessun punteggio.", + "noThanksText": "No Grazie", + "noTournamentsInTestBuildText": "I punteggi del torneo di questo test build verranno ignorati", + "noValidMapsErrorText": "Non sono state trovate mappe valide per questo tipo di gioco.", + "notEnoughPlayersRemainingText": "Non ci sono più abbastanza giocatori: esci e inizia un'altra partita.", + "notEnoughPlayersText": "Hai bisogno di almeno ${COUNT} giocatori per iniziare questa partita!", + "notNowText": "Non ora", + "notSignedInErrorText": "Per fare questo, devi accedere.", + "notSignedInGooglePlayErrorText": "Per fare questo devi accedere a Google Play.", + "notSignedInText": "non hai effettuato l'accesso", + "notUsingAccountText": "Nota: ignorando ${SERVICE} account.\nVai su 'Account -> Accedi con ${SERVICE}' se desideri utilizzarlo.", + "nothingIsSelectedErrorText": "Non hai selezionato nulla!", + "numberText": "N°${NUMBER}", + "offText": "Disattiva", + "okText": "Ok", + "onText": "Attiva", + "oneMomentText": "Un Momento...", + "onslaughtRespawnText": "${PLAYER} ritornerà all'ondata ${WAVE}", + "orText": "${A} o ${B}", + "otherText": "Altro", + "outOfText": "(#${RANK} su ${ALL})", + "ownFlagAtYourBaseWarning": "Per segnare un punto la tua bandiera\ndev'essere nella tua base!", + "packageModsEnabledErrorText": "Il gioco in rete non è consentito con i mod dei pacchetti locali abilitati (vedi Impostazioni->Avanzate)", + "partyWindow": { + "chatMessageText": "Messaggio Chat", + "emptyText": "Il tuo gruppo è vuoto", + "hostText": "(host)", + "sendText": "Invia", + "titleText": "Il tuo Gruppo" + }, + "pausedByHostText": "(in pausa da host)", + "perfectWaveText": "Ondata Perfetta!", + "pickUpBoldText": "RACCOGLI", + "pickUpText": "Raccogli", + "playModes": { + "coopText": "Cooperativa", + "freeForAllText": "Tutti Contro Tutti", + "multiTeamText": "Multi-Squadra", + "singlePlayerCoopText": "Giocatore singolo / Cooperativa", + "teamsText": "Squadre" + }, + "playText": "Gioca", + "playWindow": { + "coopText": "Cooperativi", + "freeForAllText": "Tutti Contro Tutti", + "oneToFourPlayersText": "1-4 giocatori", + "teamsText": "A Squadre", + "titleText": "Gioca", + "twoToEightPlayersText": "2-8 giocatori" + }, + "playerCountAbbreviatedText": "${COUNT}g", + "playerDelayedJoinText": "${PLAYER} si unirà al prossimo round.", + "playerInfoText": "Info Giocatore", + "playerLeftText": "${PLAYER} ha lasciato il gioco.", + "playerLimitReachedText": "Limite di ${COUNT} giocatori raggiunto; non può aggiungersi nessuno.", + "playerLimitReachedUnlockProText": "Aggiorna alla \"${PRO}\" sul negozio per giocare con più di ${COUNT} giocatori.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Non puoi eliminare il tuo profilo account.", + "deleteButtonText": "Elimina\nProfilo", + "deleteConfirmText": "Cancellare '${PROFILE}'?", + "editButtonText": "Modifica\nProfilo", + "explanationText": "(nomi e aspetti personalizzati per questo account)", + "newButtonText": "Nuovo\nProfilo", + "titleText": "Profili Giocatore" + }, + "playerText": "Giocatore", + "playlistNoValidGamesErrorText": "Questa scaletta non contiene giochi sbloccati validi.", + "playlistNotFoundText": "playlist non trovata", + "playlistText": "Lista", + "playlistsText": "Scalette", + "pleaseRateText": "Se ti sta piacendo ${APP_NAME}, prenditi\nun momento per valutarlo o scriverci su una recensione.\nQuesto aiuterà a supportare futuri sviluppi.\n\nGrazie!\n-eric", + "pleaseWaitText": "Attendi...", + "pluginClassLoadErrorText": "Errore nel caricamento di plugin classe '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Errore inizializzazione plugin '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "nuovo/i plugin rilevato. Riavvia per attivarli, o configurali nelle impostazioni.", + "pluginsRemovedText": "${NUM} plugin non trovati.", + "pluginsText": "Plugin", + "practiceText": "Allenamento", + "pressAnyButtonPlayAgainText": "Premi un pulsante qualunque per rigiocare...", + "pressAnyButtonText": "Premi un pulsante qualunque per continuare...", + "pressAnyButtonToJoinText": "Premi un pulsante qualunque per partecipare...", + "pressAnyKeyButtonPlayAgainText": "Premi un tasto/pulsante qualunque per giocare ancora...", + "pressAnyKeyButtonText": "Premi un tasto/pulsante qualunque per continuare...", + "pressAnyKeyText": "Premi un tasto qualunque...", + "pressJumpToFlyText": "** Premi ripetutamente 'salto' per volare **", + "pressPunchToJoinText": "premi PUGNO per partecipare...", + "pressToOverrideCharacterText": "premi ${BUTTONS} per sovrascrivere il tuo personaggio", + "pressToSelectProfileText": "premi ${BUTTONS} per selezionare il giocatore", + "pressToSelectTeamText": "premi ${BUTTONS} per selezionare una squadra", + "profileInfoText": "Crea profili per te e i tuoi amici\nper personalizzare nomi, personaggi e colori.", + "promoCodeWindow": { + "codeText": "Codice", + "codeTextDescription": "Codice Promozionale", + "enterText": "Usa" + }, + "promoSubmitErrorText": "Errore nell' immissione del codice; controlla la tua connessione internet", + "ps3ControllersWindow": { + "macInstructionsText": "Spegni l'alimentazione sul retro della tua PS3, assicurati\nche il Bluetooth sia abilitato sul tuo Mac, poi connetti i tuoi controller\nal tuo Mac tramite un cavo USB per appaiarli. Da qui in poi, puoi usare\nil tasto home del tuo controller per connetterlo al tuo Mac\nsia in modalità cavo (USB) o senza fili (Bluetooth).\n\nSu alcuni Mac potrebbe esserci la richiesta di una password per l'appaiamento.\nSe dovesse succedere, da' un occhiata al seguente tutorial o cerca su google.\n\n\n\n\nI controller PS3 connessi senza filo dovrebbero essere mostrati \nnella lista dispositivi su Preferenze di Sistema > Bluetooth. Potrebbe essere\nnecessario rimuoverli dalla lista quando vorrai usarli di nuovo sulla tua PS3.\n\nAssicurati inoltre di disconnetterli dal Bluetooth quando \nnon sono in uso altrimenti la loro batteria continuerà a scaricarsi.\n\nIl Bluetooth dovrebbe riuscire a gestire fino a 7 dispositivi,\nanche se il numero potrebbe variare.", + "ouyaInstructionsText": "Per usare un controller PS3 con la tua OUYA, semplicemente collegalo con un\ncavo USB in modo da accoppiarlo. Fare questo potrebbe disconnettere gli\naltri controller, quindi dovresti riavviare la OUYA e scollegare il cavo USB.\n\nDa qui in poi dovresti essere capace di usare il tasto HOME per connetterlo \nsenza fili. Una volta finito di giocare, tieni premuto il tasto HOME per 10\nsecondi per spegnere il controller; in caso contrario rimarrà acceso e \nsprecherà le batterie.", + "pairingTutorialText": "Video-tutorial per l'accoppiamento", + "titleText": "Come usare i controller PS3 con ${APP_NAME}:" + }, + "publicBetaText": "BETA PUBBLICA", + "punchBoldText": "PUGNO", + "punchText": "Pugno", + "purchaseForText": "Acquista per ${PRICE}", + "purchaseGameText": "Acquista il gioco", + "purchasingText": "Acquisto in corso...", + "quitGameText": "Uscire da ${APP_NAME}?", + "quittingIn5SecondsText": "Uscendo in 5 secondi...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Casuale", + "rankText": "Grado", + "ratingText": "Valutazione", + "reachWave2Text": "Raggiungi la seconda ondata per entrare in classifica.", + "readyText": "pronto", + "recentText": "Recenti", + "remainingInTrialText": "Rimani in prova", + "remoteAppInfoShortText": "${APP_NAME} è più divertente se giocato in famiglia o tra amici.\nConnetti uno o più controller hardware oppure installa la app \n${REMOTE_APP_NAME} su telefoni o tablet, per usarli\na mo' di controller.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Posizione del Tasto", + "button_size": "Dimensione del Tasto", + "cant_resolve_host": "Impossibile trovare l'host.", + "capturing": "Attesa Giocatori...", + "connected": "Connesso.", + "description": "Usa il tuo cellulare o tablet come controller per BombSquad.\nMassimo 8 dispositivi possono connettersi alla volta su una singola Tv o tablet.", + "disconnected": "Disconnesso dal Server.", + "dpad_fixed": "Fisso", + "dpad_floating": "Mobile", + "dpad_position": "Posizione del D-Pad", + "dpad_size": "Dimensione del D-Pad", + "dpad_type": "Modalità del D-Pad", + "enter_an_address": "Inserire un Indirizzo", + "game_full": "Il gioco è al completo o non accetta connessioni.", + "game_shut_down": "Il gioco si è spento.", + "hardware_buttons": "Tasto Hardware", + "join_by_address": "Accedi per Indirizzo...", + "lag": "Lag: ${SECONDS} secondi", + "reset": "Resetta", + "run1": "Corsa 1", + "run2": "Corsa 2", + "searching": "In cerca di partite...", + "searching_caption": "Tocca il nome della partita per aggiungertici.\nAssicurati di utilizzare la stessa rete wifi della partita.", + "start": "Start", + "version_mismatch": "Incompatibilità di versione.\nAssicurati che BombSquad e BombSquad Remote\nsiano alla stessa versione e riprova." + }, + "removeInGameAdsText": "Sblocca \"${PRO}\" nel negozio per rimuovere le pubblicità.", + "renameText": "Rinomina", + "replayEndText": "Fine Replay", + "replayNameDefaultText": "Replay Ultima Partita", + "replayReadErrorText": "Errore durante la lettura del replay.", + "replayRenameWarningText": "Rinomina ${REPLAY} dopo una partita per conservarlo, altrimenti verrà sovrascritto.", + "replayVersionErrorText": "Questo replay è stato creato con una versione\nnon compatibile del gioco e non può essere usato.", + "replayWatchText": "Guarda Replay", + "replayWriteErrorText": "Errore durante il salvataggio del replay.", + "replaysText": "Replay", + "reportPlayerExplanationText": "Usa questa email per segnalare imbrogli, linguaggio inappropriato o altri cattivi comportamenti.\nAggiungere una descrizione nello spazio sottostante:", + "reportThisPlayerCheatingText": "Scorrettezze", + "reportThisPlayerLanguageText": "Linguaggio inappropriato", + "reportThisPlayerReasonText": "Cosa vorresti segnalare?", + "reportThisPlayerText": "Segnala Questo Giocatore", + "requestingText": "Richiesta in corso...", + "restartText": "Ricomincia", + "retryText": "Riprova", + "revertText": "Ritorna", + "runText": "Corri", + "saveText": "Salva", + "scanScriptsErrorText": "Errore/i nella lettura degli script, guardare il log per i dettagli.", + "scoreChallengesText": "Punteggi sfida", + "scoreListUnavailableText": "Lista punteggi non disponibile.", + "scoreText": "Punteggio", + "scoreUnits": { + "millisecondsText": "Millisecondi", + "pointsText": "Punti", + "secondsText": "Secondi" + }, + "scoreWasText": "(era ${COUNT})", + "selectText": "Seleziona", + "seriesWinLine1PlayerText": "VINCE LA", + "seriesWinLine1TeamText": "VINCE LA", + "seriesWinLine1Text": "VINCE LA", + "seriesWinLine2Text": "SERIE!", + "settingsWindow": { + "accountText": "Account", + "advancedText": "Avanzate", + "audioText": "Audio", + "controllersText": "Controller", + "graphicsText": "Grafiche", + "playerProfilesMovedText": "Nota: Il profilo del giocatore è stato spostato nella finestra \"Account\" nella schermata principale.", + "playerProfilesText": "Profili giocatore", + "titleText": "Impostazioni" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(una semplice tastiera sullo schermo per editare testi)", + "alwaysUseInternalKeyboardText": "Usa Sempre La Tastiera Interna", + "benchmarksText": "Benchmarks & Prove Di Stress", + "disableCameraGyroscopeMotionText": "Disabilita il movimento della visuale tramite giroscopio", + "disableCameraShakeText": "Disabilita il tremolio della visuale", + "disableThisNotice": "(puoi disattivare questo messaggio su Impostazioni>Avanzate)", + "enablePackageModsDescriptionText": "(abilita la possibilità di modding aggiuntivo ma disabilita il gioco in rete)", + "enablePackageModsText": "Abilita Mod Dei Pacchetti Locali", + "enterPromoCodeText": "Inserisci il Codice", + "forTestingText": "Note: questi valori sono solo di prova e saranno cancellati uscendo dalla app.", + "helpTranslateText": "Le traduzioni di ${APP_NAME} sono un contributo\ndella comunità. Se vuoi contribuire o correggere una\ntraduzione, segui il link qui sotto. Grazie in anticipo!", + "kickIdlePlayersText": "Caccia i giocatori inattivi", + "kidFriendlyModeText": "Modalità per bambini (violenza ridotta e altro)", + "languageText": "Lingua", + "moddingGuideText": "Manuale di personalizzazione", + "mustRestartText": "Devi riavviare il gioco per apportare questa modifica.", + "netTestingText": "Collaudo Rete", + "resetText": "Reset", + "showBombTrajectoriesText": "Mostra le traiettorie delle bombe", + "showPlayerNamesText": "Mostra i nomi dei giocatori", + "showUserModsText": "Apri cartella personalizzazioni", + "titleText": "Avanzato", + "translationEditorButtonText": "Modifica la traduzione di ${APP_NAME}", + "translationFetchErrorText": "stato traduzione non disponibile", + "translationFetchingStatusText": "controllo stato traduzione...", + "translationInformMe": "Informami quando la mia lingua ha bisogno di aggiornamenti", + "translationNoUpdateNeededText": "la traduzione italiana è completa; woohoo!", + "translationUpdateNeededText": "** ci sono testi da tradurre!! **", + "vrTestingText": "Collaudo VR" + }, + "shareText": "Condividi", + "sharingText": "Condividendo...", + "showText": "Mostra", + "signInForPromoCodeText": "Devi accedere ad un account, per poter far funzionare i codici.", + "signInWithGameCenterText": "Per utilizzare un account Game Center,\naccedi utilizzando l'app Game Center.", + "singleGamePlaylistNameText": "Solo ${GAME}", + "singlePlayerCountText": "Un giocatore", + "soloNameFilterText": "${NAME} Testa a Testa", + "soundtrackTypeNames": { + "CharSelect": "Selezione del personaggio", + "Chosen One": "Il prescelto", + "Epic": "Giochi in Modalità Leggendaria", + "Epic Race": "Corsa Leggendaria", + "FlagCatcher": "Cattura la bandiera", + "Flying": "Pensieri beati", + "Football": "Football", + "ForwardMarch": "Attacco", + "GrandRomp": "Conquista", + "Hockey": "Hockey", + "Keep Away": "Tieni lontano", + "Marching": "Girotondo", + "Menu": "Menu principale", + "Onslaught": "Assalto", + "Race": "Corsa", + "Scary": "Re della collina", + "Scores": "Schermata punteggi", + "Survival": "Eliminazione", + "ToTheDeath": "Death match", + "Victory": "Schermata punteggi finali" + }, + "spaceKeyText": "spazio", + "statsText": "statistiche", + "storagePermissionAccessText": "Richiede l'accesso alla memoria locale", + "store": { + "alreadyOwnText": "Hai già acquistato ${NAME}!", + "bombSquadProDescriptionText": "• Guadagni doppi per gli obiettivi\n• Rimuovi la pubblicità nel gioco\n• Include ${COUNT} biglietti bonus\n• +${PERCENT}% di bonus sul punteggio di lega\n• Sblocca '${INF_ONSLAUGHT}' e\n '${INF_RUNAROUND}' livelli co-op", + "bombSquadProFeaturesText": "Caratteristiche:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Rimuove la pubblicità e nag screens\n• Sblocca più impostazioni del gioco\n• Include inoltre:", + "buyText": "Acquista", + "charactersText": "Personaggi", + "comingSoonText": "In Arrivo...", + "extrasText": "Extra", + "freeBombSquadProText": "BombSquad adesso è gratuito, ma dato che lo avevi già comprato\nriceverai l'aggiornamento a BombSquad Pro e ${COUNT} biglietti come ringraziamento.\nGustati le novità, e grazie per il supporto!\n-Eric", + "gameUpgradesText": "Aggiornamenti Gioco", + "getCoinsText": "Ottieni monete", + "holidaySpecialText": "Speciale Vacanze", + "howToSwitchCharactersText": "(vai a \"${SETTINGS} -> ${PLAYER_PROFILES}\" per assegnare o cambiare i personaggi.)", + "howToUseIconsText": "(crea profili giocatori globali (nella finestra \"Account\") per poterle usare)", + "howToUseMapsText": "(usa queste mappe nelle tue playlist a squadre/tutti contro tutti)", + "iconsText": "Icone", + "loadErrorText": "Impossibile caricare la pagina.\nControlla la tua connessione a internet.", + "loadingText": "caricamento", + "mapsText": "Mappe", + "miniGamesText": "MiniGiochi", + "oneTimeOnlyText": "(solo una volta)", + "purchaseAlreadyInProgressText": "Un acquisto per questo oggetto è già in corso.", + "purchaseConfirmText": "Vuoi comprare ${ITEM}?", + "purchaseNotValidError": "Acquisto non valido.\nContatta ${EMAIL} se questo è un errore.", + "purchaseText": "Compra", + "saleBundleText": "Pacchetto in sconto!", + "saleExclaimText": "Saldi!", + "salePercentText": "(${PERCENT}% di meno)", + "saleText": "SALDI", + "searchText": "Cerca", + "teamsFreeForAllGamesText": "Giochi a Squadre e/o Tutti Contro Tutti", + "totalWorthText": "*** Valore di ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Aggiornare?", + "winterSpecialText": "Speciale Inverno", + "youOwnThisText": "- è già tuo -" + }, + "storeDescriptionText": "Festa Caotica a 8 Giocatori\n\nFai saltare in aria i tuoi amici (o il computer) in un torneo di mini-giochi esplosivi come Cattura la bandiera, Hockeybomba, e l'Epic-Slow-Motion-Death-Match!\n\nI comandi semplici e l'ampio supporto di controller rendono più facile e divertente il gioco fino a 8 persone; puoi anche usare il tuo cellulare o tablet come controller tramite l'App gratuita 'BombSquad Remote'!\n\nBombardali tutti!\n\nVai su www.froemling.net/bombsquad per più informazioni.", + "storeDescriptions": { + "blowUpYourFriendsText": "Fai saltare in aria i tuoi amici.", + "competeInMiniGamesText": "Competi in mini-giochi che vanno dalla corsa al volo.", + "customize2Text": "Personalizza personaggi, mini-giochi, e persino la colonna sonora.", + "customizeText": "Personalizza i personaggi e crea la tua playlist personale di mini-giochi.", + "sportsMoreFunText": "Gli sport sono più divertenti con gli esplosivi.", + "teamUpAgainstComputerText": "Alleati contro il computer." + }, + "storeText": "Negozio", + "submitText": "Inoltra", + "submittingPromoCodeText": "Inoltrando il Codice...", + "teamNamesColorText": "Colore/Nome Team", + "teamsText": "Squadre", + "telnetAccessGrantedText": "Accesso a telnet abilitato", + "telnetAccessText": "Rilevato accesso a telnet; consentirlo?", + "testBuildErrorText": "Questa build di prova non è più attiva; per favore controlla se c'è una nuova versione.", + "testBuildText": "Build Di Prova", + "testBuildValidateErrorText": "Incapace di validare la build di prova. (sei connesso alla rete?)", + "testBuildValidatedText": "Build Di Prova Validata; Divertiti!", + "thankYouText": "Grazie per il supporto! Goditi il gioco!!", + "threeKillText": "TRIPLA UCCISIONE!!", + "timeBonusText": "Bonus Tempo", + "timeElapsedText": "Tempo trascorso", + "timeExpiredText": "Tempo Scaduto", + "timeSuffixDaysText": "${COUNT}gg", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Consiglio", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Gli amici migliori", + "tournamentCheckingStateText": "Controllo stato torneo in corso; attendere...", + "tournamentEndedText": "Questo torneo è finito. Ne partirà un altro a breve.", + "tournamentEntryText": "Partecipa al Torneo", + "tournamentResultsRecentText": "Risultati recenti del torneo", + "tournamentStandingsText": "Classifica del torneo", + "tournamentText": "Torneo", + "tournamentTimeExpiredText": "Tempo del torneo esaurito", + "tournamentsDisabledWorkspaceText": "I tornei sono disabilitati quando una o più mod sono attive.\nPer riattivare i tornei, disabilita tutte le mod e riavvia il gioco.", + "tournamentsText": "Tornei", + "translations": { + "characterNames": { + "Agent Johnson": "Agente Johnson", + "B-9000": "B-9000", + "Bernard": "Bernardo", + "Bones": "Ossicino", + "Butch": "Butch", + "Easter Bunny": "Coniglio Pasquale", + "Flopsy": "Flopsy", + "Frosty": "Gelido", + "Gretel": "Gretel", + "Grumbledorf": "Brontolone", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Middle-Man", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Babbo Natale", + "Snake Shadow": "Snake Shadow", + "Spaz": "Spaz", + "Taobao Mascot": "Mascotte Tabao", + "Todd": "Todd", + "Todd McBurton": "Todd McBurton", + "Xara": "Xara", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Assalto\nInfinito", + "Infinite\nRunaround": "Girotondo\nInfinito", + "Onslaught\nTraining": "Assalto\nAllenamento", + "Pro\nFootball": "Football\nEsperto", + "Pro\nOnslaught": "Assalto\nEsperto", + "Pro\nRunaround": "Girotondo\nEsperto", + "Rookie\nFootball": "Football\nNovellino", + "Rookie\nOnslaught": "Assalto\nNovellino", + "The\nLast Stand": "L'ultimo\nSopravvissuto", + "Uber\nFootball": "Football\nUltra", + "Uber\nOnslaught": "Assalto\nUltra", + "Uber\nRunaround": "Girotondo\nUltra" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Allenamento", + "Infinite ${GAME}": "${GAME} Infinito", + "Infinite Onslaught": "Assalto Infinito", + "Infinite Runaround": "Girotondo Infinito", + "Onslaught": "Assalto - Infinito", + "Onslaught Training": "Allenamento Assalto", + "Pro ${GAME}": "${GAME} Pro", + "Pro Football": "Football Esperto", + "Pro Onslaught": "Assalto Esperto", + "Pro Runaround": "Girotondo Esperto", + "Rookie ${GAME}": "${GAME} Principiante", + "Rookie Football": "Football Facile", + "Rookie Onslaught": "Assalto Facile", + "Runaround": "Girotondo - Infinito", + "The Last Stand": "L'ultimo sopravvissuto", + "Uber ${GAME}": "${GAME} Impossibile", + "Uber Football": "Football Ultra", + "Uber Onslaught": "Assalto Ultra", + "Uber Runaround": "Girotondo Ultra" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Per vincere, sii il prescelto per un determinato tempo.\nUccidi il prescelto per diventarlo.", + "Bomb as many targets as you can.": "Bombarda più bersagli che puoi.", + "Carry the flag for ${ARG1} seconds.": "Tieni la bandiera per ${ARG1} secondi.", + "Carry the flag for a set length of time.": "Tieni la bandiera per una determinata quantità di tempo.", + "Crush ${ARG1} of your enemies.": "Distruggi ${ARG1} dei tuoi nemici.", + "Defeat all enemies.": "Sconfiggi tutti i nemici.", + "Dodge the falling bombs.": "Evita le bombe cadenti.", + "Final glorious epic slow motion battle to the death.": "Gloriosa battaglia finale fino alla morte a rallentatore leggendario.", + "Gather eggs!": "Raccogli le uova!", + "Get the flag to the enemy end zone.": "Prendi la bandiera dalla zona del nemico.", + "How fast can you defeat the ninjas?": "Quanto velocemente riuscirete a sconfiggere i ninja?", + "Kill a set number of enemies to win.": "Uccidi un determinato numero di nemici per vincere.", + "Last one standing wins.": "L'ultimo giocatore a rimanere in piedi vince.", + "Last remaining alive wins.": "L'ultimo giocatore a rimanere vivo vince.", + "Last team standing wins.": "L'ultima squadra a rimanere in piedi vince.", + "Prevent enemies from reaching the exit.": "Non lasciare che i nemici raggiungano l'uscita.", + "Reach the enemy flag to score.": "Raggiungi la bandiera nemica per vincere.", + "Return the enemy flag to score.": "Riporta la bandiera nemica per vincere.", + "Run ${ARG1} laps.": "Corri per ${ARG1} giri.", + "Run ${ARG1} laps. Your entire team has to finish.": "Corri per ${ARG1} giri. Tutta la tua squadra deve completarli.", + "Run 1 lap.": "Corri per un giro.", + "Run 1 lap. Your entire team has to finish.": "Corri per un giro. Tutta la tua squadra deve completarlo.", + "Run real fast!": "Corri velocissimo!", + "Score ${ARG1} goals.": "Segna ${ARG1} gol.", + "Score ${ARG1} touchdowns.": "Segna ${ARG1} touchdown.", + "Score a goal": "Segna un gol", + "Score a goal.": "Segna un gol.", + "Score a touchdown.": "Segna un touchdown.", + "Score some goals.": "Segna alcuni gol.", + "Secure all ${ARG1} flags.": "Assicurati tutte e ${ARG1} le bandiere.", + "Secure all flags on the map to win.": "Assicurati tutte le bandiere sulla mappa per vincere.", + "Secure the flag for ${ARG1} seconds.": "Difendi la bandiera per ${ARG1} secondi.", + "Secure the flag for a set length of time.": "Difendi la bandiera per un determinato periodo di tempo.", + "Steal the enemy flag ${ARG1} times.": "Ruba la bandiera nemica ${ARG1} volte.", + "Steal the enemy flag.": "Ruba la bandiera nemica.", + "There can be only one.": "Ne resterà soltanto uno.", + "Touch the enemy flag ${ARG1} times.": "Tocca la bandiera nemica ${ARG1} volte.", + "Touch the enemy flag.": "Tocca la bandiera nemica.", + "carry the flag for ${ARG1} seconds": "tieni la bandiera per ${ARG1} secondi", + "kill ${ARG1} enemies": "Uccidi ${ARG1} nemici", + "last one standing wins": "L'ultimo a rimanere in piedi vince", + "last team standing wins": "L'ultima squadra a rimanere in piedi vince", + "return ${ARG1} flags": "Riporta ${ARG1} bandiere", + "return 1 flag": "Riporta 1 bandiera", + "run ${ARG1} laps": "corri per ${ARG1} giri", + "run 1 lap": "corri per un giro", + "score ${ARG1} goals": "Segna ${ARG1} gol", + "score ${ARG1} touchdowns": "Segna ${ARG1} touchdowns", + "score a goal": "Segna un gol", + "score a touchdown": "segna un touchdown", + "secure all ${ARG1} flags": "Assicurati tutte e ${ARG1} bandiere", + "secure the flag for ${ARG1} seconds": "Difendi la bandiera per ${ARG1} secondi", + "touch ${ARG1} flags": "tocca ${ARG1} bandiere", + "touch 1 flag": "tocca 1 bandiera" + }, + "gameNames": { + "Assault": "Attacco", + "Capture the Flag": "Cattura la bandiera", + "Chosen One": "Il Prescelto", + "Conquest": "Conquista", + "Death Match": "Death Match", + "Easter Egg Hunt": "Caccia alle Uova", + "Elimination": "Eliminazione", + "Football": "Football", + "Hockey": "Hockey", + "Keep Away": "Tieni lontano", + "King of the Hill": "Re della collina", + "Meteor Shower": "Tempesta di meteoriti", + "Ninja Fight": "Ninja Fight", + "Onslaught": "Assalto", + "Race": "Corsa", + "Runaround": "Girotondo", + "Target Practice": "Tiro al Bersaglio", + "The Last Stand": "L'ultimo sopravvissuto" + }, + "inputDeviceNames": { + "Keyboard": "Tastiera", + "Keyboard P2": "Tastiera G2" + }, + "languages": { + "Arabic": "Arabo", + "Belarussian": "Bielorusso", + "Chinese": "Cinese Semplificato", + "ChineseTraditional": "Cinese Tradizionale", + "Croatian": "Croato", + "Czech": "Ceco", + "Danish": "Danese", + "Dutch": "Olandese", + "English": "Inglese", + "Esperanto": "Esperanto", + "Filipino": "Filippino", + "Finnish": "Finlandese", + "French": "Francese", + "German": "Tedesco", + "Gibberish": "Insensato", + "Greek": "Greco", + "Hindi": "Hindi", + "Hungarian": "Ungherese", + "Indonesian": "Indonesiano", + "Italian": "Italiano", + "Japanese": "Giapponese", + "Korean": "Koreano", + "Malay": "Malese", + "Persian": "Persiano", + "Polish": "Polacco", + "Portuguese": "Portoghese", + "Romanian": "Rumeno", + "Russian": "Russo", + "Serbian": "Serbo", + "Slovak": "Slovacco", + "Spanish": "Spagnolo", + "Swedish": "Svedese", + "Tamil": "Tamil", + "Thai": "Tailandese", + "Turkish": "Turco", + "Ukrainian": "Ucraino", + "Venetian": "Veneto", + "Vietnamese": "Vietnamita" + }, + "leagueNames": { + "Bronze": "Bronzo", + "Diamond": "Diamante", + "Gold": "Oro", + "Silver": "Argento" + }, + "mapsNames": { + "Big G": "La grande G", + "Bridgit": "Pontile", + "Courtyard": "Cortile", + "Crag Castle": "Castello arroccato", + "Doom Shroom": "Il fungo del destino", + "Football Stadium": "Campo da football", + "Happy Thoughts": "Pensieri beati", + "Hockey Stadium": "Campo da Hockey", + "Lake Frigid": "Lago Ghiacciato", + "Monkey Face": "Faccia da scimmia", + "Rampage": "La furia", + "Roundabout": "Trampolini", + "Step Right Up": "Su e giù per le scale", + "The Pad": "L'altura", + "Tip Top": "Tip Top", + "Tower D": "Torre D", + "Zigzag": "Zig Zag" + }, + "playlistNames": { + "Just Epic": "Epico!", + "Just Sports": "Facciamo Sport!" + }, + "promoCodeResponses": { + "invalid promo code": "codice promozionale non valido" + }, + "scoreNames": { + "Flags": "Bandiere", + "Goals": "Gol", + "Score": "Punteggio", + "Survived": "Sopravvissuto", + "Time": "Tempo", + "Time Held": "Tempo di possesso" + }, + "serverResponses": { + "A code has already been used on this account.": "Un codice è già stato usato su questo account.", + "A reward has already been given for that address.": "Una ricompensa è già stata data a quell'indirizzo", + "Account linking successful!": "Account collegato correttamente!", + "Account unlinking successful!": "Account scollegato con successo!", + "Accounts are already linked.": "Questi account sono già collegati.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "La visione della pubblicità non può essere verificata.\nper favore controlla di star usando una versione aggiornata del gioco.", + "An error has occurred; (${ERROR})": "C'è stato un errore; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "C'è stato un errore; contatta il supporto. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Si è verificato un errore; per favore contattare support@froemling.net.", + "An error has occurred; please try again later.": "Qualcosa non va; per favore riprova più tardi.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Sei sicuro di voler collegare questi account?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nL'operazione non può essere annullata!", + "BombSquad Pro unlocked!": "BombSquad Pro sbloccato!", + "Can't link 2 accounts of this type.": "Impossibile collegare 2 account di questo tipo.", + "Can't link 2 diamond league accounts.": "Impossibile collegare 2 account lega diamante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Impossibile collegare; supererebbe il massimo di ${COUNT} account collegabili.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Individuato imbroglio: punteggi e premi sospesi per ${COUNT} giorni.", + "Could not establish a secure connection.": "Impossibile stabilire una connessione sicura.", + "Daily maximum reached.": "Limite massimo giornaliero raggiunto.", + "Entering tournament...": "Entrando nel torneo...", + "Invalid code.": "Codice non valido.", + "Invalid payment; purchase canceled.": "Pagamento non valido; acquisto annullato.", + "Invalid promo code.": "Codice promozionale non valido.", + "Invalid purchase.": "Acquisto non valido.", + "Invalid tournament entry; score will be ignored.": "Entrata in gioco non valida; il punteggio sarà ignorato.", + "Item unlocked!": "Oggetto sbloccato!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "Collegamento rifiutato. ${ACCOUNT} contiene\ndati importanti che verranno TUTTI PERSI.\nPuoi collegarlo nell'ordine opposto se preferisci\n(e perdere i dati di QUESTO account)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Vuoi davvero collegare l'account ${ACCOUNT} a questo account?\nTutti i dati presenti in ${ACCOUNT} andranno persi.\nLa procedura non può essere annullata. Sei sicuro?", + "Max number of playlists reached.": "Numero massimo di playlist raggiunto.", + "Max number of profiles reached.": "Numero massimo di profili raggiunto.", + "Maximum friend code rewards reached.": "Numero massimo di richieste d'amicizia inviate", + "Message is too long.": "Il messaggio è troppo lungo.", + "No servers are available. Please try again soon.": "Nessun server disponibile,prova più tardi.", + "Profile \"${NAME}\" upgraded successfully.": "Il profilo \"${NAME}\" è stato aggiornato con successo.", + "Profile could not be upgraded.": "Il profilo non è potuto essere aggiornato.", + "Purchase successful!": "Acquistato con successo!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Ricevi ${COUNT} biglietti accedendo.\nTorna domani per ricevere ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funzionalità server non è più supportata in questa versione del gioco;\nAggiornalo ad una nuova versione.", + "Sorry, there are no uses remaining on this code.": "Spiacente, non ci sono altri utilizzi rimasti su questo codice.", + "Sorry, this code has already been used.": "Spiacente, questo codice è già stato usato.", + "Sorry, this code has expired.": "Spiacente, questo codice è scaduto.", + "Sorry, this code only works for new accounts.": "Spiacente, questo codice funziona solo per nuovi account.", + "Still searching for nearby servers; please try again soon.": "Continuo a cercare dei server.Per favore prova più tardi.", + "Temporarily unavailable; please try again later.": "Al momento non disponibile; prova più tardi.", + "The tournament ended before you finished.": "Il torneo è terminato prima che tu abbia finito.", + "This account cannot be unlinked for ${NUM} days.": "Questo account non può essere scollegato per ${NUM} giorni.", + "This code cannot be used on the account that created it.": "Questo codice non può essere usato sull'account che l'ha creato.", + "This is currently unavailable; please try again later.": "Al momento non è disponibile. Riprova più tardi!", + "This requires version ${VERSION} or newer.": "Richiede la versione ${VERSION} o più recente.", + "Tournaments disabled due to rooted device.": "Tornei disabilitati a causa del dispositivo rooted.", + "Tournaments require ${VERSION} or newer": "I tornei richiedono ${VERSION} o superiore", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Scollegare l'account ${ACCOUNT} da questo account?\nTutti i dati su ${ACCOUNT} andranno cancellati.\n(eccetto per i trofei in alcuni casi)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ATTENZIONE: tentativi di hacking sono stati segnalati per il tuo account.\nGli account scoperti in tentativi di hacking saranno bannati. Gioca pulito.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Vuoi collegare il tuo account di dispositivo a questo?\n\nIl tuo account di dispositivo è ${ACCOUNT1}\nQuesto account è ${ACCOUNT2}\n\nQuesta operazione ti permetterà di conservare i tuoi progressi esistenti.\nAttenzione: l'operazione non può essere annullata!", + "You already own this!": "È già tuo!", + "You can join in ${COUNT} seconds.": "Potrai entrare in ${COUNT} secondi", + "You don't have enough tickets for this!": "Non hai abbastanza biglietti per questo!", + "You don't own that.": "Non lo possiedi", + "You got ${COUNT} tickets!": "Hai ${COUNT} biglietti!", + "You got a ${ITEM}!": "Hai ricevuto un ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Sei stato promosso a una nuova lega, Congratulazioni!", + "You must update to a newer version of the app to do this.": "Devi aggiornare a una versione nuova dell'app per poter fare questo.", + "You must update to the newest version of the game to do this.": "Devi aggiornare ad una nuova versione del gioco per fare ciò.", + "You must wait a few seconds before entering a new code.": "Devi aspettare qualche secondo prima di inserire un nuovo codice.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Sei il numero ${RANK} dell'ultimo torneo. Grazie per aver giocato!", + "Your account was rejected. Are you signed in?": "Il tuo account è stato rifiutato. Sei già iscritto?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "La tua copia del gioco è stata modificata.\nPer favore, annulla le modifiche e riprova.", + "Your friend code was used by ${ACCOUNT}": "Il tuo codice amico è stato usato da ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 minuto", + "1 Second": "1 Secondo", + "10 Minutes": "10 minuti", + "2 Minutes": "2 minuti", + "2 Seconds": "2 Secondi", + "20 Minutes": "20 minuti", + "4 Seconds": "4 Secondi", + "5 Minutes": "5 minuti", + "8 Seconds": "8 Secondi", + "Allow Negative Scores": "Abilita Punteggio Negativo", + "Balance Total Lives": "Bilancia le vite totali", + "Bomb Spawning": "Apparizione bombe", + "Chosen One Gets Gloves": "Il prescelto ottiene i guantoni", + "Chosen One Gets Shield": "Il prescelto ottiene lo scudo", + "Chosen One Time": "Tempo del prescelto", + "Enable Impact Bombs": "Abilita bombe ad impatto", + "Enable Triple Bombs": "Abilita bombe triple", + "Entire Team Must Finish": "Tutta la squadra deve finire", + "Epic Mode": "Modalità Leggendaria", + "Flag Idle Return Time": "Tempo di ritorno della bandiera inattiva", + "Flag Touch Return Time": "Tempo di ritorno della bandiera toccata", + "Hold Time": "Tempo di possesso", + "Kills to Win Per Player": "Uccisioni per giocatore per vincere", + "Laps": "Giri", + "Lives Per Player": "Vite per giocatore", + "Long": "Lunga", + "Longer": "Più lunga", + "Mine Spawning": "Apparizione Mine", + "No Mines": "Nessuna mina", + "None": "No", + "Normal": "Normale", + "Pro Mode": "Modalità Pro", + "Respawn Times": "Attesa per riapparire", + "Score to Win": "Punteggio per vincere", + "Short": "Breve", + "Shorter": "Più breve", + "Solo Mode": "Modalità Testa a Testa", + "Target Count": "Numero dì obbiettivi", + "Time Limit": "Tempo limite" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} è squalificato perché ${PLAYER} ha abbandonato", + "Killing ${NAME} for skipping part of the track!": "${NAME} è stato ucciso per aver saltato parte del tracciato!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Avviso per ${NAME}: turbo / turbo-spam ti ha espulso." + }, + "teamNames": { + "Bad Guys": "Cattivoni", + "Blue": "Blu", + "Good Guys": "Buoni", + "Red": "Rossa" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Un pugno dato in perfetta sincronia di corsa, salto e rotazione può uccidere\nin un colpo solo e farti guadagnare la stima e il rispetto dei tuoi amici.", + "Always remember to floss.": "Ricorda sempre di usare il filo interdentale.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crea profili giocatore per te e i tuoi amici con i vostri\nnomi e aspetti preferiti invece di usarne uno casuale.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Le scatole maledizione ti trasformano in una bomba ad orologeria.\nL'unico antidoto è di prendere velocemente un kit di pronto soccorso.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Malgrado il loro aspetto, le abilità di ogni personaggio sono identiche, \nquindi scegline uno qualunque nel quale ti ci rivedi.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Non darti troppe arie con quello scudo di energia; puoi sempre essere scaraventato giù da un dirupo.", + "Don't run all the time. Really. You will fall off cliffs.": "Non correre sempre. Davvero. Cadrai sicuramente.", + "Don't spin for too long; you'll become dizzy and fall.": "Non girare troppo a lungo altrimenti diverrai pazzo e cadrai", + "Hold any button to run. (Trigger buttons work well if you have them)": "Tieni premuto un pulsante qualsiasi per correre. (I grilletti sono ideali, se li hai)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Tieni premuto un pulsante qualsiasi. Andrai più veloce\nma sarà più difficile fare manovre, quindi attento a non cadere.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Le bombe ghiaccio non sono molto potenti, ma congelano\nchiunque colpiscono, rendendoli vulnerabili alla frantumazione.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Se qualcuno ti afferra, colpiscilo e ti lascerà andare.\nQuesto funziona anche nella vita di tutti i giorni.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Se non hai nessun controller, installa l'app ${REMOTE_APP_NAME}'\nsul tuo dispositivo mobile per usarlo come controller.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Se sei a corto di controller, installa l'app 'BombSquad Remote' \nsul tuo dispositivo iOS o Android per usarli come controller. ", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Se vieni colpito da una bomba caccola, salta, corri in cerchi e dimenati come un matto.\nDovresti riuscire a staccartene, o almeno a rendere più divertente i tuoi ultimi istanti di vita.", + "If you kill an enemy in one hit you get double points for it.": "Se uccidi un nemico in un colpo solo riceverai il doppio dei punti.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Se acchiappi una maledizione, la tua unica speranza di salvezza \nè quella di prendere un kit di pronto soccorso nei pochi secondi successivi.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Se resti fermo, sei fritto. Corri e schiva per sopravvivere.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Se hai diversi giocatori che vanno e vengono, seleziona 'Caccia i giocatori inattivi'\nnel menù Impostazioni nel caso qualcuno dimentichi di lasciare il gioco.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Se il tuo dispositivo si scaldasse eccessivamente e tu volessi conservare batteria,\ncala le impostazioni \"Visuali\" o \"Risoluzione\" in Impostazioni->Grafiche", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Se i frame sono discontinui, prova ad abbassare la risoluzione\no la visuale del gioco nel menu Impostazioni grafiche", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "In Cattura la bandiera, per segnare un punto la tua bandiera dev'essere nella tua base;\nse il team avversario sta per segnare, rubare la loro bandiera può essere un modo per fermarli.", + "In hockey, you'll maintain more speed if you turn gradually.": "Nell'hockey, per manterere più velocità, ti conviene girare gradualmente.", + "It's easier to win with a friend or two helping.": "È più facile vincere con uno o più amici che ti aiutano.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Salta nel momento in cui lanci le bombe per farle arrivare più in alto possibile.", + "Land-mines are a good way to stop speedy enemies.": "Le mine antiuomo sono un'ottimo modo di fermare nemici veloci.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Molte cose possono essere raccolte e lanciate, compresi altri giocatori. Scaraventare\ni tuoi nemici giù dai precipizi può essere un efficiente ed appagante strategia.", + "No, you can't get up on the ledge. You have to throw bombs.": "No, non puoi salire sulla sporgenza. Devi lanciare le bombe.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "I giocatori possono entrare ed uscire durante la maggior parte delle partite,\ne puoi anche collegare e scollegare le periferiche al volo.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "I giocatori possono entrare e uscire nel mezzo della maggior parte dei giochi,\ne inoltre puoi collegare e scollegare i gamepad al volo.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "I potenziamenti sono a tempo solo nei giochi cooperativi.\nNei giochi a squadre e nei Tutti Contro Tutti sono tuoi finché non muori.", + "Practice using your momentum to throw bombs more accurately.": "Fai pratica usando la spinta per lanciare le bombe con più precisione.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "I pugni infliggono molti più danni quanto più velocemente ti muovi,\nquindi prova a correre, saltare e girare come un pazzo.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Prendi la rincorsa prima di lanciare una bomba\ncosì da farla andare più lontano.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Fai fuori un gruppo di nemici\nlanciando una bomba vicino a una scatola di TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "La testa è l'area più vulnerabile, quindi una bomba caccola\nsulla zucca di solito vuol dire game over.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Questo livello non finisce mai, ma un punteggio elevato qui\nti farà guadagnare eterno rispetto in tutto il mondo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "La potenza di lanci è basata sulla direzione che stai premendo.\nPer lanciare delicatamente qualcosa davanti a te, non premere nessun pulsante direzionale.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Stanco della colonna sonora? Sostituiscila con una tua!\nVai in Settings->Audio->Soundtrack", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Prova a 'lasciar cuocere' le bombe per un secondo o due prima di lanciarle.", + "Try tricking enemies into killing eachother or running off cliffs.": "Prova ad ingannare i nemici in modo da farli uccidere l'un l'altro o di farli cadere dalle sporgenze.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Usa il pulsante raccogli per afferrare la bandiera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Prendi la rincorsa per lanciare più lontano.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Puoi 'direzionare' i tuoi pugni girando a destra o a sinistra.\nQuesto è utile per far cadere giù i nemici dalle sporgenze o segnare un gol nell'hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Puoi capire quando una bomba sta per esplodere basandoti\nsul colore della miccia: giallo... arancione... rosso... BOOOM.", + "You can throw bombs higher if you jump just before throwing.": "Se salti appena prima di lanciarle, le bombe arrivano più in alto.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Non c'è bisogno di creare un profilo per cambiare personaggio; basta premere \nil pulsante superiore (afferra) quando prendi parte ad un gioco.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Subisci danno quando sbatti la testa contro le cose,\nquindi cerca di non farlo.", + "Your punches do much more damage if you are running or spinning.": "I pugni fanno molti più danni se stai correndo o roteando." + } + }, + "trialPeriodEndedText": "Il periodo di prova è finito. Ti andrebbe di\ncomprare BombSquad e continuare a giocare?", + "trophiesRequiredText": "Questo richiede almeno ${NUMBER} trofei.", + "trophiesText": "Trofei", + "trophiesThisSeasonText": "Trofei Questa Stagione", + "tutorial": { + "cpuBenchmarkText": "Esecuzione tutorial a velocità assurda (principalmente analizza velocità CPU)", + "phrase01Text": "Ciao!", + "phrase02Text": "Benvenuto in ${APP_NAME}!", + "phrase03Text": "Ecco alcuni consigli su come muovere il tuo personaggio:", + "phrase04Text": "Molte cose in ${APP_NAME} sono basate sulla FISICA.", + "phrase05Text": "Ad esempio, quando tiri un pugno...", + "phrase06Text": "...il danno è calcolato in base alla velocità dei tuoi pugni.", + "phrase07Text": "Visto? Non ci stavamo muovendo, perciò ${NAME} lo ha a malapena sentito.", + "phrase08Text": "Ora saltiamo e roteiamo per ottenere più velocità.", + "phrase09Text": "Eh sì, così va meglio.", + "phrase10Text": "Anche correre aiuta.", + "phrase11Text": "Tieni premuto un tasto QUALUNQUE per correre.", + "phrase12Text": "Per pugni ancora più tosti, prova a correre E roteare.", + "phrase13Text": "Ooops! Non volevo, ${NAME}.", + "phrase14Text": "Puoi raccogliere e lanciare oggetti come le bandiere... o ${NAME}", + "phrase15Text": "Infine, ci sono le bombe.", + "phrase16Text": "Ci vuole pratica per lanciare le bombe.", + "phrase17Text": "Ahia. Non era granché come lancio.", + "phrase18Text": "Muoversi aiuta a lanciare più lontano.", + "phrase19Text": "Saltare aiuta a lanciare più in alto.", + "phrase20Text": "Fai girare la tua bomba per lanci ancora più lunghi.", + "phrase21Text": "Capire quando lanciare può essere difficile.", + "phrase22Text": "Accipicchia.", + "phrase23Text": "Prova a far consumare la miccia per un secondo o due.", + "phrase24Text": "Così si fa! Cotto a puntino.", + "phrase25Text": "Be', questo è tutto.", + "phrase26Text": "Ora va' e colpisci, campione!", + "phrase27Text": "Ricorda il tuo addestramento, e tornerai indietro vivo!", + "phrase28Text": "...be', forse...", + "phrase29Text": "Buona fortuna!", + "randomName1Text": "Fred", + "randomName2Text": "Harry", + "randomName3Text": "Bill", + "randomName4Text": "Chuck", + "randomName5Text": "Phil", + "skipConfirmText": "Sicuro di voler saltare il tutorial? Tocca o premi per confermare.", + "skipVoteCountText": "${COUNT} su ${TOTAL} vogliono saltare la guida", + "skippingText": "guida saltata", + "toSkipPressAnythingText": "(tocca o premi qualsiasi pulsante per saltare la guida)" + }, + "twoKillText": "DOPPIA UCCISIONE!", + "unavailableText": "non disponibile", + "unconfiguredControllerDetectedText": "Rilevato controller non configurato:", + "unlockThisInTheStoreText": "Deve essere sbloccato nel negozio", + "unlockThisProfilesText": "Per creare più di ${NUM} profili, ti serve:", + "unlockThisText": "Per sbloccare questo, hai bisogno di:", + "unsupportedHardwareText": "Purtroppo, questo hardware non è supportato da questa versione del gioco.", + "upFirstText": "Per primo:", + "upNextText": "Fra poco nel ${COUNT}:", + "updatingAccountText": "Sto aggiornando il tuo account...", + "upgradeText": "Aggiorna", + "upgradeToPlayText": "Sblocca \"${PRO}\" nel negozio in-game per poter giocare a questo.", + "useDefaultText": "Usa Predefinito", + "usesExternalControllerText": "Questo gioco utilizza un controller esterno come input.", + "usingItunesText": "Sto usando una app musicale per la colonna sonora...", + "usingItunesTurnRepeatAndShuffleOnText": "Per favore, assicurati che la riproduzione casuale sia ATTIVA e che la ripetizione sia su TUTTO su iTunes.", + "v2AccountLinkingInfoText": "Per collegare degli account V2, usa il tasto 'Gestisci Account'.", + "validatingBetaText": "Sto convalidando la beta...", + "validatingTestBuildText": "Convalida Build Di Prova...", + "victoryText": "Vittoria!", + "voteDelayText": "Non puoi cominciare un'altra votazione per ${NUMBER} secondi", + "voteInProgressText": "C'è già una votazione in corso.", + "votedAlreadyText": "Hai già votato", + "votesNeededText": "Servono ${NUMBER} voti", + "vsText": "vs.", + "waitingForHostText": "(in attesa di ${HOST} per continuare)", + "waitingForLocalPlayersText": "in attesa di giocatori...", + "waitingForPlayersText": "in attesa di giocatori...", + "waitingInLineText": "Aspettando in coda (il party è pieno)..", + "watchAVideoText": "Guarda un video", + "watchAnAdText": "Guarda una pubblicità", + "watchWindow": { + "deleteConfirmText": "Vuoi cancellare \"${REPLAY}\"?", + "deleteReplayButtonText": "Cancella\nReplay", + "myReplaysText": "I Miei Replay", + "noReplaySelectedErrorText": "Nessun Replay Selezionato", + "playbackSpeedText": "Velocità Replay: ${SPEED}", + "renameReplayButtonText": "Rinomina\nReplay", + "renameReplayText": "Rinomina \"${REPLAY}\" in:", + "renameText": "Rinomina", + "replayDeleteErrorText": "Errore cancellazione replay.", + "replayNameText": "Nome Replay", + "replayRenameErrorAlreadyExistsText": "Esiste già un replay con questo nome.", + "replayRenameErrorInvalidName": "Impossibile rinominare replay; nome invalido.", + "replayRenameErrorText": "Errore rinominazione replay", + "sharedReplaysText": "Replays Condivisi", + "titleText": "Guarda", + "watchReplayButtonText": "Guarda\nReplay" + }, + "waveText": "Ondata", + "wellSureText": "Beh, certo!", + "whatIsThisText": "Che cos'è questo?", + "wiimoteLicenseWindow": { + "licenseText": "Copyright (c) 2007, DarwiinRemote Team\nAll rights reserved.\n\n Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n3. Neither the name of this project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", + "licenseTextScale": 0.62, + "titleText": "Copyright DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "In attesa dei Wiimote...", + "pressText": "Premi contemporaneamente i tasti 1 e 2 sul Wiimote.", + "pressText2": "Nei nuovi Wiimote con il Motion Plus integrato, premi invece il tasto rosso 'sync' sul retro.", + "pressText2Scale": 0.55, + "pressTextScale": 1.0 + }, + "wiimoteSetupWindow": { + "copyrightText": "Copyright DarwiinRemote", + "copyrightTextScale": 0.6, + "listenText": "Ascolta", + "macInstructionsText": "Assicurati che la tua Wii sia spenta e il Bluetooth acceso\nsul tuo Mac, poi premi 'Ascolta'. Il supporto a Wiimote può\nessere un po' traballante, quindi prova ad aspettare qualche\nminuto prima di ottenere una connessione.\n\nVia Bluetooth dovresti riuscire a gestire fino a 7 dispositivi connessi,\nanche se le prestazioni potrebbero variare.\n\nBombSquad supporta i controller originali Wiimote, Nunchuk,\ne il Controller Classico.\nAnche i nuovi controller Wii Remote Plus funzionano, ma\nnon con gli accessori.", + "macInstructionsTextScale": 0.7, + "thanksText": "Grazie al team DarwiiRemote\nper aver reso possibile tutto questo.", + "thanksTextScale": 0.8, + "titleText": "Configurazione Wiimote" + }, + "winsPlayerText": "${NAME} Ha Vinto!", + "winsTeamText": "${NAME} Ha Vinto!", + "winsText": "${NAME} vince!", + "workspaceSyncErrorText": "Errore nella sincronizzazione di ${WORKSPACE}. Controlla il registro per dettagli.", + "workspaceSyncReuseText": "Impossibile sincronizzare ${WORKSPACE}. Riutilizzo della versione sincronizzata precedente.", + "worldScoresUnavailableText": "Punteggi mondiali non disponibili.", + "worldsBestScoresText": "I punteggi migliori del mondo", + "worldsBestTimesText": "I tempi migliori del mondo", + "xbox360ControllersWindow": { + "getDriverText": "Scarica il driver", + "macInstructions2Text": "Per usare i controller in modalità wireless, avrai anche bisogno del\nricevitore contenuto nel pacchetto 'Xbox 360 controller wireless per\nWindows'. Un ricevitore permette di collegare fino a 4 controller.\n\nImportante: i ricevitori di terze parti non funzioneranno con questo driver;\nassicurati di avere un ricevitore 'Microsoft', non 'XBOX 360'.\nMicrosoft non li vende più separatamente, quindi avrai bisogno di quello\nfornito con il controller, oppure cerca su ebay.\n\nSe lo hai trovato utile, considera una donazione allo sviluppatore del\ndriver al suo sito.", + "macInstructions2TextScale": 0.76, + "macInstructionsText": "Per usare il controller dell'Xbox 360, avrai bisogno di installare\ni driver per MAC disponibili cliccando sul link qui sotto.\nFunziona sia con i controller senza fili che con i via cavo.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Per usare i controller dell'Xbox 360 con Bombsquad, semplicemente\ncollegali alla porta USB. Puoi usare un hub USB per connettere\npiù controller.\n\nPer usare i controller wireless hai bisogno di un ricevitore\nwireless, disponibile come parte del pacchetto \"Xbox 360 controller\nwireless per Windows\", venduto separatamente. Ogni ricevitore va\ninserito nella porta USB e permette di connettere fino a 4 controller.", + "ouyaInstructionsTextScale": 0.8, + "titleText": "Come usare i controller dell'Xbox 360 con ${APP_NAME}:" + }, + "yesAllowText": "Sì, permetti!", + "yourBestScoresText": "I tuoi punteggi migliori", + "yourBestTimesText": "I tuoi tempi migliori" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/korean.json b/dist/ba_data/data/languages/korean.json new file mode 100644 index 0000000..81b7c5a --- /dev/null +++ b/dist/ba_data/data/languages/korean.json @@ -0,0 +1,1883 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "계정 이름은 이모티콘이나 특수문자를 포함할수 없습니다.", + "accountProfileText": "계정 프로파일", + "accountsText": "계정", + "achievementProgressText": "업적: ${TOTAL} 중 ${COUNT}", + "campaignProgressText": "캠페인 진행 상황 [어려움]: ${PROGRESS}", + "changeOncePerSeason": "한 시즌마다 바꿀수 있습니다.", + "changeOncePerSeasonError": "다음 시즌으로 바뀔때까지 (${NUM} 일)기다려야 계정 이름을 바꿀수 있습니다.", + "customName": "이름 맞춤설정", + "googlePlayGamesAccountSwitchText": "다른 Google 계정을 전환하려면,\nGoogle Play 앱을 사용하세요", + "linkAccountsEnterCodeText": "코드 입력", + "linkAccountsGenerateCodeText": "코드 생성", + "linkAccountsInfoText": "(여러 플랫폼에서 진행 상황을 공유합니다)", + "linkAccountsInstructionsNewText": "두 계정을 연동하시려면, 첫번째 계정에 코드를 생성하고 \n두번째 계정에 코드를 입력하십시오. \n이후 두번째 계정의 데이터는 서로 공유됩니다.\n(첫번째 계정의 데이터는 삭제됩니다.)\n\n최대 ${COUNT}의 계정까지 연동할수 있습니다..\n\n중요: 당신이 소유하고 있는 계정만 연동하십시오;\n만약 친구 계정과 연동 시' \n동시 온라인 접속이 불가능해집니다.", + "linkAccountsInstructionsText": "두 개의 계정을 연동하려면 한 곳에서 코드를\n생성한 후 다른 곳에서 해당 코드를 입력합니다.\n진행 상황 및 소지품은 결합됩니다.\n최대 ${COUNT}개의 계정을 연동할 수 있습니다.\n\n중요:당신의 계정만 연동하십시오!\n만약에 당신이 친구의 계정과 연동하면 친구가 게임\n하는 동안 당신은 게임 할수 없게 됩니다!\n\n이 작업은 취소할 수 없으므로 주의하세요!", + "linkAccountsText": "계정 연동", + "linkedAccountsText": "연동된 계정", + "manageAccountText": "계정 관리", + "nameChangeConfirm": "계정이름을 ${NAME}으로 바꾸시겠습니까?", + "resetProgressConfirmNoAchievementsText": "이 옵션은 협동 모드 진행 상황 및 로컬\n최고 점수를 초기화합니다 (티켓 제외).\n이 작업은 취소할 수 없습니다. 괜찮습니까?", + "resetProgressConfirmText": "이 옵션은 협동 모드 진행 상황, 업적 및\n로컬 최고 점수를 초기화합니다\n(티켓 제외). 이 작업은 취소할 수 없습니다.\n괜찮습니까?", + "resetProgressText": "진행 상황 초기화", + "setAccountName": "계정 이름 설정", + "setAccountNameDesc": "당신 계정에 보여질 이름을 선택해주시오.\n연동된 계정 중 하나에서 이름을 사용하거나,\n또는 자기만의 독창적인 이름을 만들어서 사용할 수 있습니다.", + "signInInfoText": "로그인해서 티켓을 수집하고 온라인으로 겨루며\n여러 기기에서 진행 상황을 공유하세요.", + "signInText": "로그인", + "signInWithDeviceInfoText": "(자동 계정은 이 기기에서만 이용할 수 있습니다)", + "signInWithDeviceText": "기기 계정으로 로그인", + "signInWithGameCircleText": "Game Circle로 로그인", + "signInWithGooglePlayText": "Google Play로 로그인", + "signInWithTestAccountInfoText": "(이전 계정 유형, 앞의 기기 계정을 이용하세요)", + "signInWithTestAccountText": "테스트 계정으로 로그인", + "signInWithV2InfoText": "(모든 플랫폼에서 작동하는 계정입니다)", + "signInWithV2Text": "BombSquad 계정으로 로그인", + "signOutText": "로그아웃", + "signingInText": "로그인 중...", + "signingOutText": "로그아웃 중...", + "testAccountWarningText": "테스트 계정은 초기화될 염려가 있습니다.\n(이 계정을 쓸때는 제발 많은 시간이나 상품을 구입하지 말아주세요).\n\n진짜 계정을 쓰시면( Game-Center, 구글 플러스 Google Plus, 기타등등)\n계정을 다른 기기에서 불러올 수 있습니다).", + "ticketsText": "티켓: ${COUNT}", + "titleText": "계정", + "unlinkAccountsInstructionsText": "계정 연동을 해제할 계정을 선택하세요", + "unlinkAccountsText": "계정 연동해제", + "unlinkLegacyV1AccountsText": "레거시(V1) 계정 연결 해제", + "v2LinkInstructionsText": "이 링크를 사용해서 계정을 만들거나, 로그인을 하세요.", + "viaAccount": "(계정 종류 ${NAME})", + "youAreSignedInAsText": "현재 로그인된 사용자 이름:" + }, + "achievementChallengesText": "업적 챌린지", + "achievementText": "업적", + "achievements": { + "Boom Goes the Dynamite": { + "description": "TNT로 악당 3명을 처치합니다", + "descriptionComplete": "TNT로 악당 3명을 처치했습니다", + "descriptionFull": "${LEVEL}에서 TNT로 악당 3명을 처치합니다", + "descriptionFullComplete": "${LEVEL}에서 TNT로 악당 3명을 처치했습니다", + "name": "다이너마이트 대폭발" + }, + "Boxer": { + "description": "폭탄을 사용하지 않고 승리합니다", + "descriptionComplete": "폭탄을 사용하지 않고 승리했습니다", + "descriptionFull": "폭탄을 사용하지 않고 ${LEVEL} 레벨을 완료합니다", + "descriptionFullComplete": "폭탄을 사용하지 않고 ${LEVEL} 레벨을 완료했습니다", + "name": "권투 선수" + }, + "Dual Wielding": { + "descriptionFull": "컨트롤러를 두개 연결합니다. (하드웨어 밎 앱)", + "descriptionFullComplete": "컨트롤러를 두개 연결했습니다. (하드웨어 밎 앱)", + "name": "콩까는 컨트롤러" + }, + "Flawless Victory": { + "description": "피해를 입지 않고 승리합니다", + "descriptionComplete": "피해를 입지 않고 승리했습니다", + "descriptionFull": "${LEVEL}에서 피해를 입지 않고 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 피해를 입지 않고 승리했습니다", + "name": "완벽한 승리" + }, + "Free Loader": { + "descriptionFull": "개인전을 두명 이상으로 시작합니다.", + "descriptionFullComplete": "개인전을 두명 이상으로 시작했습니다.", + "name": "격투가" + }, + "Gold Miner": { + "description": "지뢰로 악당 6명을 처치합니다", + "descriptionComplete": "지뢰로 악당 6명을 처치했습니다", + "descriptionFull": "${LEVEL}에서 지뢰로 악당 6명을 처치합니다", + "descriptionFullComplete": "${LEVEL}에서 지뢰로 악당 6명을 처치했습니다", + "name": "금광 광부" + }, + "Got the Moves": { + "description": "펀치 또는 폭탄을 사용하지 않고 승리합니다", + "descriptionComplete": "펀치 또는 폭탄을 사용하지 않고 승리했습니다", + "descriptionFull": "${LEVEL}에서 펀치 또는 폭탄을 사용하지 않고 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 펀치 또는 폭탄을 사용하지 않고 승리했습니다", + "name": "뛰어난 움직임" + }, + "In Control": { + "descriptionFull": "컨트롤러를 연결합니다. (하드웨어 밎 앱)", + "descriptionFullComplete": "컨트롤러를 연결했습니다. (하드웨어 밎 앱)", + "name": "에네미 컨트롤러!" + }, + "Last Stand God": { + "description": "1000점을 기록합니다", + "descriptionComplete": "1000점을 기록했습니다", + "descriptionFull": "${LEVEL}에서 1000점을 기록합니다", + "descriptionFullComplete": "${LEVEL}에서 1000점을 기록했습니다", + "name": "${LEVEL}의 신" + }, + "Last Stand Master": { + "description": "250점을 기록합니다", + "descriptionComplete": "250점을 기록했습니다", + "descriptionFull": "${LEVEL}에서 250점을 기록합니다", + "descriptionFullComplete": "${LEVEL}에서 250점을 기록했습니다", + "name": "${LEVEL}의 달인" + }, + "Last Stand Wizard": { + "description": "500점을 기록합니다", + "descriptionComplete": "500점을 기록했습니다", + "descriptionFull": "${LEVEL}에서 500점을 기록합니다", + "descriptionFullComplete": "${LEVEL}에서 500점을 기록했습니다", + "name": "${LEVEL}의 현인" + }, + "Mine Games": { + "description": "지뢰로 악당 3명을 처치합니다", + "descriptionComplete": "지뢰로 악당 3명을 처치했습니다", + "descriptionFull": "${LEVEL}에서 지뢰로 악당 3명을 처치합니다", + "descriptionFullComplete": "${LEVEL}에서 지뢰로 악당 3명을 처치했습니다", + "name": "지뢰 유희" + }, + "Off You Go Then": { + "description": "지도 밖으로 악당 3명을 내던집니다", + "descriptionComplete": "지도 밖으로 악당 3명을 내던졌습니다", + "descriptionFull": "${LEVEL}에서 지도 밖으로 악당 3명을 내던집니다", + "descriptionFullComplete": "${LEVEL}에서 지도 밖으로 악당 3명을 내던졌습니다", + "name": "먼저 나가" + }, + "Onslaught God": { + "description": "5000점을 기록합니다", + "descriptionComplete": "5000점을 기록했습니다", + "descriptionFull": "${LEVEL}에서 5000점을 기록합니다", + "descriptionFullComplete": "${LEVEL}에서 5000점을 기록했습니다", + "name": "${LEVEL}의 신" + }, + "Onslaught Master": { + "description": "500점을 기록합니다", + "descriptionComplete": "500점을 기록했습니다", + "descriptionFull": "${LEVEL}에서 500점을 기록합니다", + "descriptionFullComplete": "${LEVEL}에서 500점을 기록했습니다", + "name": "${LEVEL}의 달인" + }, + "Onslaught Training Victory": { + "description": "모든 웨이브를 물리칩니다", + "descriptionComplete": "모든 웨이브를 물리쳤습니다", + "descriptionFull": "${LEVEL}에서 모든 웨이브를 물리칩니다", + "descriptionFullComplete": "${LEVEL}에서 모든 웨이브를 물리쳤습니다", + "name": "${LEVEL} 승리" + }, + "Onslaught Wizard": { + "description": "1000점을 기록합니다", + "descriptionComplete": "1000점을 기록했습니다", + "descriptionFull": "${LEVEL}에서 1000점을 기록합니다", + "descriptionFullComplete": "${LEVEL}에서 1000점을 기록했습니다", + "name": "${LEVEL}의 현인" + }, + "Precision Bombing": { + "description": "파워업을 사용하지 않고 승리합니다", + "descriptionComplete": "파워업을 사용하지 않고 승리했습니다", + "descriptionFull": "${LEVEL}에서 파워업을 사용하지 않고 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 파워업을 사용하지 않고 승리했습니다", + "name": "정밀 폭격" + }, + "Pro Boxer": { + "description": "폭탄을 사용하지 않고 승리합니다", + "descriptionComplete": "폭탄을 사용하지 않고 승리했습니다", + "descriptionFull": "폭탄을 사용하지 않고 ${LEVEL} 레벨을 완료합니다", + "descriptionFullComplete": "폭탄을 사용하지 않고 ${LEVEL} 레벨을 완료했습니다", + "name": "프로 권투 선수" + }, + "Pro Football Shutout": { + "description": "악당들에게 점수를 주지 않고 승리합니다", + "descriptionComplete": "악당들에게 점수를 주지 않고 승리했습니다", + "descriptionFull": "${LEVEL}에서 악당들에게 점수를 주지 않고 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 악당들에게 점수를 주지 않고 승리했습니다", + "name": "${LEVEL} 완봉승" + }, + "Pro Football Victory": { + "description": "게임을 승리합니다", + "descriptionComplete": "게임을 승리했습니다", + "descriptionFull": "${LEVEL}에서 게임을 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 게임을 승리했습니다", + "name": "${LEVEL} 승리" + }, + "Pro Onslaught Victory": { + "description": "모든 웨이브를 물리칩니다", + "descriptionComplete": "모든 웨이브를 물리쳤습니다", + "descriptionFull": "${LEVEL}의 모든 웨이브를 물리칩니다", + "descriptionFullComplete": "${LEVEL}의 모든 웨이브를 물리쳤습니다", + "name": "${LEVEL} 승리" + }, + "Pro Runaround Victory": { + "description": "모든 웨이브를 완료합니다", + "descriptionComplete": "모든 웨이브를 완료했습니다", + "descriptionFull": "${LEVEL}에서 모든 웨이브를 완료합니다", + "descriptionFullComplete": "${LEVEL}에서 모든 웨이브를 완료했습니다", + "name": "${LEVEL} 승리" + }, + "Rookie Football Shutout": { + "description": "악당들에게 점수를 주지 않고 승리합니다", + "descriptionComplete": "악당들에게 점수를 주지 않고 승리했습니다", + "descriptionFull": "${LEVEL}에서 악당들에게 점수를 주지 않고 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 악당들에게 점수를 주지 않고 승리했습니다", + "name": "${LEVEL} 완봉승" + }, + "Rookie Football Victory": { + "description": "게임을 승리합니다", + "descriptionComplete": "게임을 승리했습니다", + "descriptionFull": "${LEVEL}에서 게임을 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 게임을 승리했습니다", + "name": "${LEVEL} 승리" + }, + "Rookie Onslaught Victory": { + "description": "모든 웨이브를 물리칩니다", + "descriptionComplete": "모든 웨이브를 물리쳤습니다", + "descriptionFull": "${LEVEL}에서 모든 웨이브를 물리칩니다", + "descriptionFullComplete": "${LEVEL}에서 모든 웨이브를 물리쳤습니다", + "name": "${LEVEL} 승리" + }, + "Runaround God": { + "description": "2000점을 기록합니다", + "descriptionComplete": "2000점을 기록했습니다", + "descriptionFull": "${LEVEL}에서 2000점을 기록합니다", + "descriptionFullComplete": "${LEVEL}에서 2000점을 기록했습니다", + "name": "${LEVEL}의 신" + }, + "Runaround Master": { + "description": "500점을 기록합니다", + "descriptionComplete": "500점을 기록했습니다", + "descriptionFull": "${LEVEL}에서 500점을 기록합니다", + "descriptionFullComplete": "${LEVEL}에서 500점을 기록했습니다", + "name": "${LEVEL}의 달인" + }, + "Runaround Wizard": { + "description": "1000점을 기록합니다", + "descriptionComplete": "1000점을 기록했습니다", + "descriptionFull": "${LEVEL}에서 1000점을 기록합니다", + "descriptionFullComplete": "${LEVEL}에서 1000점을 기록했습니다", + "name": "${LEVEL}의 현인" + }, + "Sharing is Caring": { + "descriptionFull": "게임을 친구와 성공적으로 공유합니다", + "descriptionFullComplete": "게임을 친구와 성공적으로 공유했습니다", + "name": "백지장도 맞들면 낫다" + }, + "Stayin' Alive": { + "description": "죽지 않고 승리합니다", + "descriptionComplete": "죽지 않고 승리했습니다", + "descriptionFull": "${LEVEL}에서 죽지 않고 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 죽지 않고 승리했습니다", + "name": "생존 본능" + }, + "Super Mega Punch": { + "description": "한 번의 펀치로 100% 대미지를 가합니다", + "descriptionComplete": "한 번의 펀치로 100% 대미지를 가했습니다", + "descriptionFull": "${LEVEL}에서 한 번의 펀치로 100% 대미지를 가합니다", + "descriptionFullComplete": "${LEVEL}에서 한 번의 펀치로 100% 대미지를 가했습니다", + "name": "슈퍼 메가 펀치" + }, + "Super Punch": { + "description": "한 번의 펀치로 50% 대미지를 가합니다", + "descriptionComplete": "한 번의 펀치로 50% 대미지를 가했습니다", + "descriptionFull": "${LEVEL}에서 한 번의 펀치로 50% 대미지를 가합니다", + "descriptionFullComplete": "${LEVEL}에서 한 번의 펀치로 50% 대미지를 가했습니다", + "name": "슈퍼 펀치" + }, + "TNT Terror": { + "description": "TNT로 악당 6명을 처치합니다", + "descriptionComplete": "TNT로 악당 6명을 처치했습니다", + "descriptionFull": "${LEVEL}에서 TNT로 악당 6명을 처치합니다", + "descriptionFullComplete": "${LEVEL}에서 TNT로 악당 6명을 처치했습니다", + "name": "TNT 테러" + }, + "Team Player": { + "descriptionFull": "4명 이상과 같이 팀전을 합니다", + "descriptionFullComplete": "4명 이상과 같이 팀전을 하였습니다.", + "name": "팀전 플레이어" + }, + "The Great Wall": { + "description": "모든 악당을 저지합니다", + "descriptionComplete": "모든 악당을 저지했습니다", + "descriptionFull": "${LEVEL}에서 모든 악당을 저지합니다", + "descriptionFullComplete": "${LEVEL}에서 모든 악당을 저지했습니다", + "name": "만리장성" + }, + "The Wall": { + "description": "모든 악당을 저지합니다", + "descriptionComplete": "모든 악당을 저지했습니다", + "descriptionFull": "${LEVEL}에서 모든 악당을 저지합니다", + "descriptionFullComplete": "${LEVEL}에서 모든 악당을 저지했습니다", + "name": "벽" + }, + "Uber Football Shutout": { + "description": "악당들에게 점수를 주지 않고 승리합니다", + "descriptionComplete": "악당들에게 점수를 주지 않고 승리했습니다", + "descriptionFull": "${LEVEL}에서 악당들에게 점수를 주지 않고 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 악당들에게 점수를 주지 않고 승리했습니다", + "name": "${LEVEL} 완봉승" + }, + "Uber Football Victory": { + "description": "게임을 승리합니다", + "descriptionComplete": "게임을 승리했습니다", + "descriptionFull": "${LEVEL}에서 게임을 승리합니다", + "descriptionFullComplete": "${LEVEL}에서 게임을 승리했습니다", + "name": "${LEVEL} 승리" + }, + "Uber Onslaught Victory": { + "description": "모든 웨이브를 물리칩니다", + "descriptionComplete": "모든 웨이브를 물리쳤습니다", + "descriptionFull": "${LEVEL}에서 모든 웨이브를 물리칩니다", + "descriptionFullComplete": "${LEVEL}에서 모든 웨이브를 물리쳤습니다", + "name": "${LEVEL} 승리" + }, + "Uber Runaround Victory": { + "description": "모든 웨이브를 완료합니다", + "descriptionComplete": "모든 웨이브를 완료했습니다", + "descriptionFull": "${LEVEL}에서 모든 웨이브를 완료합니다", + "descriptionFullComplete": "${LEVEL}에서 모든 웨이브를 완료했습니다", + "name": "${LEVEL} 승리" + } + }, + "achievementsRemainingText": "남은 업적:", + "achievementsText": "업적", + "achievementsUnavailableForOldSeasonsText": "죄송합니다만 이전 시즌에 대해서는 업적 정보가 제공되지 않습니다.", + "activatedText": "${THING}가 작동을 시작했습니다.", + "addGameWindow": { + "getMoreGamesText": "다른 게임 보기...", + "titleText": "게임 추가" + }, + "allowText": "허용", + "alreadySignedInText": "귀하의 계정은 다른 기기에서 로그인되었습니다. \n계정을 전환하거나 다른 기기에서 게임을 종료하고 \n다시 시도하십시오.", + "apiVersionErrorText": "${NAME} 모듈을 불러올 수 없습니다; ${VERSION_USED} api 버전입니다; ${VERSION_REQUIRED} 버전이 필요합니다.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(헤드폰이 연결된 때에만 '자동'이 이 옵션을 활성화합니다)", + "headRelativeVRAudioText": "머리 비례 VR 오디오", + "musicVolumeText": "음악 볼륨", + "soundVolumeText": "사운드 볼륨", + "soundtrackButtonText": "사운드트랙", + "soundtrackDescriptionText": "(게임 중 재생할 사용자의 음악을 배정합니다)", + "titleText": "오디오" + }, + "autoText": "자동", + "backText": "뒤로", + "banThisPlayerText": "이 플레이어를 밴한다", + "bestOfFinalText": "베스트 ${COUNT} 최종 점수", + "bestOfSeriesText": "Best of ${COUNT} series:", + "bestRankText": "귀하의 최고 순위: #${RANK}", + "bestRatingText": "귀하의 최고 등급: ${RATING}", + "bombBoldText": "폭탄", + "bombText": "폭탄", + "boostText": "증가", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME}(은)는 앱 자체에 구성되어 있습니다.", + "buttonText": "버튼", + "canWeDebugText": "BombSquad가 버그, 충돌 및 기본 사용 정보를\n자동으로 개발자에게 신고하도록 하시겠습니까?\n\n이 데이터에 개인 정보는 포함되지 않으며 게임이\n버그 없이 원활하게 실행되도록 하는 데 도움이 됩니다.", + "cancelText": "취소", + "cantConfigureDeviceText": "죄송합니다만 ${DEVICE}(은)는 구성할 수 없습니다.", + "challengeEndedText": "이 챌린지는 종료되었습니다.", + "chatMuteText": "채팅 음소거", + "chatMutedText": "채팅 음소거됨.", + "chatUnMuteText": "채팅 음소거 해제", + "choosingPlayerText": "<플레이어 선택>", + "completeThisLevelToProceedText": "계속 진행하려면 이 레벨을\n완료해야 합니다!", + "completionBonusText": "완료 보너스", + "configControllersWindow": { + "configureControllersText": "컨트롤러 구성", + "configureKeyboard2Text": "키보드 P2 구성", + "configureKeyboardText": "키보드 구성", + "configureMobileText": "모바일 기기를 컨트롤러로 사용", + "configureTouchText": "터치스크린 구성", + "ps3Text": "플레이스테이션 3 컨트롤러", + "titleText": "컨트롤러", + "wiimotesText": "Wii 리모컨", + "xbox360Text": "Xbox 360 컨트롤러" + }, + "configGamepadSelectWindow": { + "androidNoteText": "참고: 기기 및 안드로이드 버전에 따라 컨트롤러 지원이 다릅니다.", + "pressAnyButtonText": "구성하고 싶은 컨트롤러의\n 버튼을 아무거나 누르세요...", + "titleText": "컨트롤러 구성" + }, + "configGamepadWindow": { + "advancedText": "고급", + "advancedTitleText": "고급 컨트롤러 설정", + "analogStickDeadZoneDescriptionText": "(스틱을 놓을 때 캐릭터가 '표류'할 경우 이 옵션을 켭니다)", + "analogStickDeadZoneText": "아날로그 스틱 데드 존", + "appliesToAllText": "(이 유형의 모든 컨트롤러에 적용됩니다)", + "autoRecalibrateDescriptionText": "(캐릭터가 전속력으로 움직이지 않으면 이 옵션을 사용합니다)", + "autoRecalibrateText": "아날로그 스틱 자동 재보정", + "axisText": "축", + "clearText": "지우기", + "dpadText": "D-패드", + "extraStartButtonText": "보조 시작 버튼", + "ifNothingHappensTryAnalogText": "아무 일도 발생하지 않으면 아날로그 스틱을 대신 배정해보세요.", + "ifNothingHappensTryDpadText": "아무 일도 발생하지 않으면 D-패드를 대신 배정해보세요.", + "ignoreCompletelyDescriptionText": "(이 컨트롤러를 게임 또는 메뉴에 영향을 주지 않게 함)", + "ignoreCompletelyText": "완전히 무시하기", + "ignoredButton1Text": "무시된 버튼 1", + "ignoredButton2Text": "무시된 버튼 2", + "ignoredButton3Text": "무시된 버튼 3", + "ignoredButton4Text": "4번 버튼을 무시함", + "ignoredButtonDescriptionText": "('홈' 또는 '동기화' 버튼이 사용자 인터페이스에 영향을 주지 않도록 하려면 이 옵션을 사용합니다)", + "pressAnyAnalogTriggerText": "아무 아날로그 트리거나 누르세요...", + "pressAnyButtonOrDpadText": "아무 버튼 또는 D-패드를 누르세요...", + "pressAnyButtonText": "아무 버튼이나 누르세요...", + "pressLeftRightText": "왼쪽 또는 오른쪽을 누르세요...", + "pressUpDownText": "위쪽 또는 아래쪽을 누르세요...", + "runButton1Text": "달리기 버튼 1", + "runButton2Text": "달리기 버튼 2", + "runTrigger1Text": "달리기 트리거 1", + "runTrigger2Text": "달리기 트리거 2", + "runTriggerDescriptionText": "(다양한 속도에서 달릴 수 있게 하는 아날로그 트리거)", + "secondHalfText": "이 옵션을 사용해서 단일 컨트롤러로\n표시되는 투-인-원 컨트롤러\n장치의 두 번째 설정을 구성합니다.", + "secondaryEnableText": "활성화", + "secondaryText": "보조 컨트롤러", + "startButtonActivatesDefaultDescriptionText": "(시작 버튼이 '메뉴' 버튼 기능 이상일 경우 이 옵션을 끕니다)", + "startButtonActivatesDefaultText": "시작 버튼은 기본 위젯을 활성화합니다", + "titleText": "컨트롤러 설정", + "twoInOneSetupText": "투-인-원 컨트롤러 설정", + "uiOnlyDescriptionText": "(이 컨트롤러를 게임에 참여하지 못하게 하기)", + "uiOnlyText": "메뉴에만 사용", + "unassignedButtonsRunText": "배정되지 않은 모든 버튼으로 달리기", + "unsetText": "<미설정>", + "vrReorientButtonText": "VR 방향 재설정 버튼" + }, + "configKeyboardWindow": { + "configuringText": "${DEVICE} 구성 중", + "keyboard2NoteText": "주의\n대부분의 키보드는 한번에 많은 양의 키를 인식하지 못하므로\n2인 플레이시 다른 키보드를 연결하여 플레이하는 것이 더 나을 수도 있습니다.\n단, 이 경우에도 각 플레이어에게 서로 다른 키배치를 배정해야\n게임이 정상적으로 됩니다." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "액션 컨트롤 눈금", + "actionsText": "액션", + "buttonsText": "버튼", + "dragControlsText": "< 재배치하려면 컨트롤을 드래그하세요 >", + "joystickText": "조이스틱", + "movementControlScaleText": "이동 컨트롤 눈금", + "movementText": "이동", + "resetText": "재설정", + "swipeControlsHiddenText": "스와이프 아이콘 숨기기", + "swipeInfoText": "'스와이프' 스타일 컨트롤은 익숙해지는 데 시간이 약간\n걸리지만 컨트롤을 보지 않고 플레이할 때 더 편합니다.", + "swipeText": "스와이프", + "titleText": "터치스크린 구성" + }, + "configureItNowText": "지금 구성하시겠습니까?", + "configureText": "구성", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "최선의 결과를 얻으려면 랙이 없는 Wi-Fi 네트워크가 필요합니다. \n다른 무선 장치들을 끄거나 Wi-Fi 라우터 근처에서 플레이하거나\n게임 호스트를 이더넷 네트워크에 직접 연결해서\nWi-Fi 랙을 줄일 수 있습니다.", + "explanationText": "스마트폰 또는 태블릿을 무선 컨트롤러로 사용하려면\n해당 기기에 \"${REMOTE_APP_NAME}\" 앱을 설치합니다. Wi-Fi를 통해서\n여러 기기를 ${APP_NAME} 게임에 무료로 연결할 수 있습니다!", + "forAndroidText": "안드로이드:", + "forIOSText": "iOS:", + "getItForText": "${REMOTE_APP_NAME} 앱의 iOS 버전은 Apple App Store에서, Android\n버전은 Google Play Store 또는 Amazon Appstore에서 다운로드할 수 있습니다", + "googlePlayText": "Google Play", + "titleText": "모바일 기기를 컨트롤러로 사용하기:" + }, + "continuePurchaseText": "${PRICE}에 계속하시겠습니까?", + "continueText": "계속", + "controlsText": "컨트롤", + "coopSelectWindow": { + "activenessAllTimeInfoText": "이 옵션은 역대 랭킹에는 적용되지 않습니다.", + "activenessInfoText": "이 증배율은 플레이할 때 올라가고\n플레이를 안 하면 내려갑니다.", + "activityText": "활동", + "campaignText": "캠페인", + "challengesInfoText": "미니 게임을 완료하고 상품을 받으세요.\n\n상품 및 난이도는 챌린지를 완료할 때마다 \n올라가고 만료되거나 포기하면\n내려갑니다.", + "challengesText": "챌린지", + "currentBestText": "현재 최고 점수", + "customText": "커스텀", + "entryFeeText": "참가", + "forfeitConfirmText": "이 챌린지를 포기하시겠습니까?", + "forfeitNotAllowedYetText": "이 챌린지는 아직 포기할 수 없습니다.", + "forfeitText": "포기", + "multipliersText": "증배율", + "nextChallengeText": "다음 챌린지", + "nextPlayText": "다음 플레이", + "ofTotalTimeText": "/ ${TOTAL}", + "playNowText": "지금 시작", + "pointsText": "점수", + "powerRankingFinishedSeasonUnrankedText": "(랭크 없이 완료된 시즌)", + "powerRankingNotInTopText": "(톱 ${NUMBER} 밖)", + "powerRankingPointsEqualsText": "= ${NUMBER}점", + "powerRankingPointsMultText": "(x ${NUMBER}점)", + "powerRankingPointsText": "${NUMBER}점", + "powerRankingPointsToRankedText": "(${CURRENT} / ${REMAINING}점)", + "powerRankingText": "파워 랭킹", + "prizesText": "상품", + "proMultInfoText": "${PRO} 업그레이드를 구입한 플레이어들은\n이곳에서 ${PERCENT}% 점수 보너스를 받습니다.", + "seeMoreText": "더 보기", + "skipWaitText": "대기 건너뛰기", + "timeRemainingText": "남은 시간", + "toRankedText": "랭킹까지", + "totalText": "합계", + "tournamentInfoText": "자신의 리그에서 다른 플레이어들과\n최고 점수를 겨루세요.\n\n토너먼트가 종료될 때 랭킹에 오른\n플레이어들에게 상품이 수여됩니다.", + "welcome1Text": "${LEAGUE}에 환영합니다. 별 등급을 획득하고\n업적을 완료하며 토너먼트에서 트로피를 획득해서\n리그 등급을 올릴 수 있습니다.", + "welcome2Text": "또한 많은 동일한 활동에서 티켓을 획득할 수 있습니다.\n티켓을 사용해서 새로운 캐릭터, 지도 및 미니 게임을\n잠금 해제하고 토너먼트에 참가할 수 있습니다.", + "yourPowerRankingText": "내 파워 랭킹:" + }, + "copyConfirmText": "클립 보드에 복사", + "copyOfText": "${NAME} 사본", + "copyText": "복사", + "createEditPlayerText": "<플레이어 생성/편집>", + "createText": "생성", + "creditsWindow": { + "additionalAudioArtIdeasText": "추가 오디오, 초기 아트워크 및 아이디어: ${NAME}", + "additionalMusicFromText": "추가 음악: ${NAME}", + "allMyFamilyText": "게임 테스트를 도와준 모든 친구 및 가족", + "codingGraphicsAudioText": "코딩, 그래픽 및 오디오: ${NAME}", + "languageTranslationsText": "언어 번역:", + "legalText": "법무:", + "publicDomainMusicViaText": "공개 음악: ${NAME}", + "softwareBasedOnText": "이 소프트웨어는 ${NAME}의 작품에 일부 기반하고 있습니다", + "songCreditText": "${TITLE} 연주: ${PERFORMER}\n작곡: ${COMPOSER}, 편곡: ${ARRANGER}, 발표: ${PUBLISHER},\n제공: ${SOURCE}", + "soundAndMusicText": "사운드 및 음악:", + "soundsText": "사운드 (${SOURCE}):", + "specialThanksText": "특히 감사드리는 분들:", + "thanksEspeciallyToText": "${NAME}에게 특히 감사를 드립니다", + "titleText": "${APP_NAME} 개발진", + "whoeverInventedCoffeeText": "커피를 발명하신 분" + }, + "currentStandingText": "귀하의 현재 순위: #${RANK}", + "customizeText": "커스터마이징...", + "deathsTallyText": "${COUNT}번 사망", + "deathsText": "사망", + "debugText": "디버그", + "debugWindow": { + "reloadBenchmarkBestResultsText": "참고: 테스트를 할 때에 설정->그래픽->텍스처에서 '높음'으로 설정할 것을 권장합니다.", + "runCPUBenchmarkText": "CPU 벤치마크 실행", + "runGPUBenchmarkText": "GPU 벤치마크 실행", + "runMediaReloadBenchmarkText": "미디어-리로드 벤치마크 실행", + "runStressTestText": "스트레스 테스트 실행", + "stressTestPlayerCountText": "플레이어 수", + "stressTestPlaylistDescriptionText": "플레이 목록 스트레스 테스트", + "stressTestPlaylistNameText": "플레이 목록 이름", + "stressTestPlaylistTypeText": "플레이 목록 유형", + "stressTestRoundDurationText": "라운드 지속 시간", + "stressTestTitleText": "스트레스 테스트", + "titleText": "벤치마크 및 스트레스 테스트", + "totalReloadTimeText": "총 리로드 시간: ${TIME} (로그에서 자세한 정보 참고)" + }, + "defaultGameListNameText": "기본 ${PLAYMODE} 플레이 목록", + "defaultNewGameListNameText": "내 ${PLAYMODE} 플레이 목록", + "deleteText": "삭제", + "demoText": "체험판", + "denyText": "거부", + "deprecatedText": "더 이상 사용되지 않음", + "desktopResText": "데스크톱 해상도", + "deviceAccountUpgradeText": "경고:\n 기기 계정(${NAME})으로 로그인하셨습니다.\n 기기 계정은 향후 업데이트에서 제거되기에\n 진행 상황을 유지하려면 V2 계정으로 업그레이드하세요.", + "difficultyEasyText": "쉬움", + "difficultyHardOnlyText": "어려움 모드만", + "difficultyHardText": "어려움", + "difficultyHardUnlockOnlyText": "이 레벨은 어려움 모드에서만 잠금 해제할 수 있습니다.\n준비가 되셨습니까?", + "directBrowserToURLText": "웹 브라우저에서 다음 URL을 방문하십시오:", + "disableRemoteAppConnectionsText": "리모트 앱 연결 비활성화", + "disableXInputDescriptionText": "4개 이상의 컨트롤러를 허용하지만 아마 잘 작동하지 않을 것입니다.", + "disableXInputText": "엑스인풋 컨트롤러 비활성화", + "doneText": "완료", + "drawText": "무승부", + "duplicateText": "복사", + "editGameListWindow": { + "addGameText": "게임\n추가", + "cantOverwriteDefaultText": "기본 플레이 목록은 덮어쓸 수 없습니다!", + "cantSaveAlreadyExistsText": "같은 이름의 플레이 목록이 이미 존재합니다!", + "cantSaveEmptyListText": "빈 플레이 목록을 저장할 수 없습니다!", + "editGameText": "게임\n편집", + "listNameText": "플레이 목록 이름", + "nameText": "이름", + "removeGameText": "게임\n제거", + "saveText": "목록 저장", + "titleText": "플레이 목록 편집기" + }, + "editProfileWindow": { + "accountProfileInfoText": "이 특별 프로필은 사용자의 계정에\n기반한 이름 및 아이콘을 보유합니다.\n\n${ICONS}\n\n다른 이름 또는 맞춤형 아이콘을 사용하려면\n맞춤형 프로필을 만드십시오.", + "accountProfileText": "(계정 프로필)", + "availableText": "이름 \"${NAME}\"(은)는 이용할 수 있습니다.", + "characterText": "캐릭터", + "checkingAvailabilityText": "\"${NAME}\"의 이용 가능성 확인 중...", + "colorText": "색", + "getMoreCharactersText": "캐릭터 더 보기...", + "getMoreIconsText": "아이콘 더 보기...", + "globalProfileInfoText": "글로벌 플레이어 프로필은 반드시 전 세계적으로 고유한\n이름을 갖습니다. 또한 맞춤형 아이콘이 포함됩니다.", + "globalProfileText": "(글로벌 프로필)", + "highlightText": "하이라이트", + "iconText": "아이콘", + "localProfileInfoText": "로컬 플레이어 프로필은 아이콘이 없으며 이름은 반드시\n고유하지 않습니다. 고유한 이름을 갖고 맞춤형 아이콘을\n추가하려면 글로벌 프로필로 업그레이드하세요.", + "localProfileText": "(로컬 프로필)", + "nameDescriptionText": "플레이어 이름", + "nameText": "이름", + "randomText": "무작위", + "titleEditText": "프로필 편집", + "titleNewText": "새 프로필", + "unavailableText": "\"${NAME}\"(은)는 사용할 수 없습니다. 다른 이름을 시도하세요.", + "upgradeProfileInfoText": "플레이어 이름을 전 세계적으로 유지하고\n맞춤형 아이콘을 추가할 수 있습니다.", + "upgradeToGlobalProfileText": "글로벌 프로필로 업그레이드" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "기본 사운드트랙을 삭제할 수 없습니다.", + "cantEditDefaultText": "기본 사운드트랙을 편집할 수 없습니다. 복사하거나 새로 만드세요.", + "cantOverwriteDefaultText": "기본 사운드트랙을 덮어쓸 수 없습니다", + "cantSaveAlreadyExistsText": "같은 이름의 사운드트랙이 이미 존재합니다!", + "defaultGameMusicText": "<기본 게임 음악>", + "defaultSoundtrackNameText": "기본 사운드트랙", + "deleteConfirmText": "사운드트랙 삭제:\n\n'${NAME}'?", + "deleteText": "사운드트랙\n삭제", + "duplicateText": "사운드트랙\n복사", + "editSoundtrackText": "사운드트랙 편집기", + "editText": "사운드트랙\n편집", + "fetchingITunesText": "음악 어플 재생 목록을 가져오는 중...", + "musicVolumeZeroWarning": "경고: 음악 볼륨은 0으로 설정됩니다", + "nameText": "이름", + "newSoundtrackNameText": "내 사운드트랙 ${COUNT}", + "newSoundtrackText": "새 사운드트랙:", + "newText": "새\n사운드트랙", + "selectAPlaylistText": "재생 목록 선택", + "selectASourceText": "음악 출처", + "testText": "테스트", + "titleText": "사운드트랙", + "useDefaultGameMusicText": "기본 게임 음악", + "useITunesPlaylistText": "음악 앱 재생 목록", + "useMusicFileText": "음악 파일 (mp3 등)", + "useMusicFolderText": "음악 파일 폴더" + }, + "editText": "편집", + "endText": "종료", + "enjoyText": "즐기세요!", + "epicDescriptionFilterText": "(에픽 슬로 모션) ${DESCRIPTION}.", + "epicNameFilterText": "에픽 ${NAME}", + "errorAccessDeniedText": "액세스가 거부됨", + "errorDeviceTimeIncorrectText": "당신의 디바이스 시간은 ${HOURS}시간이나 맞지 않습니다.\n이러면 아마 문제를 불러 이르킬 수 있습니다.\n디바이스의 시간을 현재 시각으로 바꿔 주십시오.", + "errorOutOfDiskSpaceText": "디스크 공간 부족", + "errorSecureConnectionFailText": "클라우드 연결 상황이 안전하지 않습니다. 네트워크가 종종 연결 해제 될 수 있습니다.", + "errorText": "오류", + "errorUnknownText": "알 수 없는 오류", + "exitGameText": "${APP_NAME}를 종료하시겠습니까?", + "exportSuccessText": "'${NAME}' 를 내보냈습니다.", + "externalStorageText": "외부 저장소", + "failText": "실패", + "fatalErrorText": "무언가 누락되거나 잘못되었습니다.\n앱을 다시 설치하거나 ${EMAIL}에\n문의해주십시오.", + "fileSelectorWindow": { + "titleFileFolderText": "파일 또는 폴더 선택", + "titleFileText": "파일 선택", + "titleFolderText": "폴더 선택", + "useThisFolderButtonText": "이 폴더 사용" + }, + "filterText": "필터", + "finalScoreText": "최종 점수", + "finalScoresText": "최종 점수", + "finalTimeText": "최종 시간", + "finishingInstallText": "설치 완료 중, 잠시만 기다려주십시오...", + "fireTVRemoteWarningText": "* 더 나은 경험을 위해 게임 컨트롤러를\n사용하거나 스마트폰 또는 태블릿에서\n'${REMOTE_APP_NAME}' 앱을\n설치해주십시오.", + "firstToFinalText": "시작 ~ ${COUNT} 최종 결과", + "firstToSeriesText": "시작 ~ ${COUNT} 시리즈", + "fiveKillText": "펜타킬!!!", + "flawlessWaveText": "완벽한 웨이브!", + "fourKillText": "쿼드라킬!!!", + "friendScoresUnavailableText": "친구 점수를 이용할 수 없습니다.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "게임 ${COUNT} 리더", + "gameListWindow": { + "cantDeleteDefaultText": "기본 플레이 목록을 삭제할 수 없습니다.", + "cantEditDefaultText": "기본 플레이 목록을 편집할 수 없습니다! 복사하거나 새로 만드세요.", + "cantShareDefaultText": "기본 목록은 공유할 수 없습니다.", + "deleteConfirmText": "\"${LIST}\"(을)를 삭제합니까?", + "deleteText": "플레이 목록\n삭제", + "duplicateText": "플레이 목록\n복사", + "editText": "플레이 목록\n편집", + "newText": "새\n플레이 목록", + "showTutorialText": "튜토리얼 보기", + "shuffleGameOrderText": "게임 순서 섞기", + "titleText": "${TYPE} 플레이 목록 커스터마이징" + }, + "gameSettingsWindow": { + "addGameText": "게임 추가" + }, + "gamesToText": "${WINCOUNT} 대 ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "참고: 컨트롤러가 충분하면 파티 내의 어떤 기기든\n한 명 이상의 플레이어를 보유할 수 있습니다.", + "aboutDescriptionText": "이 탭을 이용해 파티를 구성합니다.\n\n파티를 통해서 다양한 기기를 사용하는 친구들과\n게임 및 토너먼트를 즐길 수 있습니다.\n\n우측 상단의 ${PARTY} 버튼을 이용해서\n파티원과 채팅하고 교류하세요.\n(컨트롤러의 경우 메뉴에서 ${BUTTON}을 누릅니다)", + "aboutText": "정보", + "addressFetchErrorText": "<주소 가져오기 오류>", + "appInviteMessageText": "${NAME} 님이 ${APP_NAME}에서 티켓 ${COUNT}장을 보냈습니다", + "appInviteSendACodeText": "코드 보내기", + "appInviteTitleText": "${APP_NAME} 앱 초대", + "bluetoothAndroidSupportText": "(블루투스를 지원하는 안드로이드 기기에서 작동합니다)", + "bluetoothDescriptionText": "블루투스를 통해 파티 호스트/가입:", + "bluetoothHostText": "블루투스를 통해 호스트", + "bluetoothJoinText": "블루투스를 통해 가입", + "bluetoothText": "블루투스", + "checkingText": "확인 중...", + "copyCodeConfirmText": "코드가 클립보드에 복사되었습니다.", + "copyCodeText": "코드 복사", + "dedicatedServerInfoText": "최선의 결과를 위해 전용 서버를 구축하세요. 자세한 사항은 bombsquadgame.com/server를 참조해주십시오.", + "disconnectClientsText": "파티 내의 플레이어 ${COUNT}명의 연결이\n끊어집니다. 괜찮습니까?", + "earnTicketsForRecommendingAmountText": "친구들은 게임을 시도하면 티켓 ${COUNT}장을 받습니다\n(귀하는 각각의 친구에 대해서 ${YOU_COUNT}장을 받습니다)", + "earnTicketsForRecommendingText": "게임을 공유하고\n무료 티켓을 받으세요...", + "emailItText": "이메일 보내기", + "favoritesSaveText": "즐겨찾기로 저장", + "favoritesText": "즐겨찾기", + "freeCloudServerAvailableMinutesText": "다음 클라우드 서버는 ${MINUTES} 분 후에 사용할 수 있습니다.", + "freeCloudServerAvailableNowText": "무료 클라우드 서버가 이용가능 합니다!", + "freeCloudServerNotAvailableText": "이용가능한 무료 클라우드 서버가 없습니다.", + "friendHasSentPromoCodeText": "${NAME} 님이 ${APP_NAME} 티켓 ${COUNT}장을 보냄", + "friendPromoCodeAwardText": "코드가 사용될 때마다 귀하는 티켓 ${COUNT}장을 받습니다.", + "friendPromoCodeExpireText": "이 코드는 ${EXPIRE_HOURS}시간 후 만료되며 신규 플레이어에게만 적용됩니다.", + "friendPromoCodeInstructionsText": "사용하려면 ${APP_NAME} 앱을 열고 '설정->고급->코드 입력'으로 이동합니다.\n지원되는 모든 플랫폼의 다운로드 링크는 bombsquadgame.com에서 확인하세요.", + "friendPromoCodeRedeemLongText": "최대 ${MAX_USES}명의 사람이 무료 티켓 ${COUNT}장과 교환할 수 있습니다.", + "friendPromoCodeRedeemShortText": "게임에서 티켓 ${COUNT}장과 교환할 수 있습니다.", + "friendPromoCodeWhereToEnterText": "('설정->고급->코드 입력')", + "getFriendInviteCodeText": "친구 초대 코드 받기", + "googlePlayDescriptionText": "Google Play 플레이어들을 파티에 초대하세요.", + "googlePlayInviteText": "초대", + "googlePlayReInviteText": "새 초대를 시작하면 파티 내의 Google Play 플레이어\n${COUNT}명의 연결이 끊깁니다. 그들을 다시 초대하려면\n새 초대에 포함시키세요.", + "googlePlaySeeInvitesText": "초대 보기", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(안드로이드 / Google Play 버전)", + "hostPublicPartyDescriptionText": "공개 파티 만들기", + "hostingUnavailableText": "호스팅 불가", + "inDevelopmentWarningText": "참고:\n\n네트워크 플레이는 계속 발전 중인 신규 기능입니다.\n당분간은 모든 플레이어가 같은 Wi-Fi 네트워크에\n접속할 것을 적극 권장합니다.", + "internetText": "인터넷", + "inviteAFriendText": "친구가 이 게임을 갖고 있지 않나요? 초대해서 함께\n플레이하세요. 친구들은 티켓 ${COUNT}장을 무료로 받습니다.", + "inviteFriendsText": "친구 초대", + "joinPublicPartyDescriptionText": "공개 파티 참가하기", + "localNetworkDescriptionText": "근접한 파티에 가입하기 (LAN, 블루투스, 기타.)", + "localNetworkText": "로컬 네트워크", + "makePartyPrivateText": "비공개 파티로 전환", + "makePartyPublicText": "공개 파티 만들기", + "manualAddressText": "주소", + "manualConnectText": "연결", + "manualDescriptionText": "주소로 파티에 가입하기:", + "manualJoinSectionText": "주소로 가입하기", + "manualJoinableFromInternetText": "인터넷을 통한 가입 가능 여부:", + "manualJoinableNoWithAsteriskText": "아니오*", + "manualJoinableYesText": "예", + "manualRouterForwardingText": "*이 문제를 해결하려면 UDP 포트 ${PORT}번을 로컬 주소로 전달하도록 라우터를 설정해보세요", + "manualText": "수동", + "manualYourAddressFromInternetText": "인터넷에서 귀하의 주소:", + "manualYourLocalAddressText": "귀하의 로컬 주소:", + "nearbyText": "근처", + "noConnectionText": "<연결 없음>", + "otherVersionsText": "(다른 버전)", + "partyCodeText": "파티 코드", + "partyInviteAcceptText": "수락", + "partyInviteDeclineText": "거절", + "partyInviteGooglePlayExtraText": "('파티 모집' 창에서 'Google Play' 탭을 확인하세요)", + "partyInviteIgnoreText": "무시", + "partyInviteText": "${NAME} 님이 귀하를\n파티에 초대했습니다!", + "partyNameText": "파티 이름", + "partyServerRunningText": "현제 파티 서버가 운영중입니다.", + "partySizeText": "인원", + "partyStatusCheckingText": "등급 확인 중...", + "partyStatusJoinableText": "당신의 파티는 이제 인터넷에 참가됩니다.", + "partyStatusNoConnectionText": "서버에 연결할 수 없습니다.", + "partyStatusNotJoinableText": "당신의 파티는 인터넷에 참가할 수 없습니다.", + "partyStatusNotPublicText": "당신의 파티는 비공개입니다.", + "pingText": "핑", + "portText": "포트", + "privatePartyCloudDescriptionText": "비공개 파티는 전용 클라우드 서버를 통해 운용됩니다; 공유기 설정은 필요 없습니다.", + "privatePartyHostText": "비공개 파티 호스팅하기", + "privatePartyJoinText": "비공개 파티 참가하기", + "privateText": "비공개", + "publicHostRouterConfigText": "공유기 설정에서 포트포워딩 설정이 필요할수도 있습니다. 더 쉬운 설정을 위해 비공개 파티를 호스팅하세요.", + "publicText": "공개", + "requestingAPromoCodeText": "코드 요청 중...", + "sendDirectInvitesText": "직접 초대 보내기", + "shareThisCodeWithFriendsText": "다음 코드를 친구들과 공유하세요.", + "showMyAddressText": "내 IP주소 보기", + "startHostingPaidText": "${COST} 으로 지금 호스팅하기", + "startHostingText": "방 만들기", + "startStopHostingMinutesText": "다음 ${MINUTES} 분 동안, 호스팅을 시작하거나 멈출수 있습니다.", + "stopHostingText": "호스팅 중지", + "titleText": "파티 모집", + "wifiDirectDescriptionBottomText": "모든 장치에 'Wi-Fi 다이렉트' 패널이 있으면 이를 통해서 서로 찾고 연결할 수 있어야\n합니다. 모든 장치가 연결되면 일반 Wi-Fi 네트워크와 똑같이 '로컬 네트워크' 탭을\n이용해 이곳에서 파티를 결성할 수 있습니다.\n\n최선의 결과를 얻으려면 Wi-Fi 다이렉트 호스트가 ${APP_NAME} 파티 호스트이어야 합니다.", + "wifiDirectDescriptionTopText": "Wi-Fi 다이렉트는 Wi-Fi 네트워크 없이 직접 안드로이드 장치들을 연결하는 데\n사용될 수 있습니다. 이 기능은 안드로이드 버전 4.2 이상에서 가장 잘 작동합니다.\n\n이 기능을 사용하려면 Wi-Fi 설정을 열고 메뉴에서 'Wi-Fi 다이렉트'를 찾으세요.", + "wifiDirectOpenWiFiSettingsText": "Wi-Fi 설정 열기", + "wifiDirectText": "Wi-Fi 다이렉트", + "worksBetweenAllPlatformsText": "(모든 플랫폼 간에 작동합니다)", + "worksWithGooglePlayDevicesText": "(이 게임의 Google Play (안드로이드) 버전을 실행하는 장치들과 함께 작동합니다)", + "youHaveBeenSentAPromoCodeText": "${APP_NAME} 프로모션 코드가 도착했습니다." + }, + "getTicketsWindow": { + "freeText": "무료!", + "freeTicketsText": "무료 티켓", + "inProgressText": "거래가 진행 중입니다. 조금 후 다시 시도해주십시오.", + "purchasesRestoredText": "구매 항목이 복원되었습니다.", + "receivedTicketsText": "티켓 ${COUNT}장을 받았습니다!", + "restorePurchasesText": "구매 항목 복원", + "ticketPack1Text": "소형 티켓 팩", + "ticketPack2Text": "중형 티켓 팩", + "ticketPack3Text": "대형 티켓 팩", + "ticketPack4Text": "점보 티켓 팩", + "ticketPack5Text": "매머드 티켓 팩", + "ticketPack6Text": "궁극의 티켓 팩", + "ticketsFromASponsorText": "광고 보고\n티켓 ${COUNT}장 받기", + "ticketsText": "티켓 ${COUNT}장", + "titleText": "티켓 구입", + "unavailableLinkAccountText": "죄송합니다만 이 플랫폼에서는 구매할 수 없습니다.\n해결책으로, 이 계정을 다른 플랫폼의 계정에 연동하여\n그곳에서 구매를 진행할 수 있습니다.", + "unavailableTemporarilyText": "이 옵션은 현재 이용할 수 없습니다. 나중에 다시 시도해주십시오.", + "unavailableText": "죄송합니다만 이 옵션은 이용할 수 없습니다.", + "versionTooOldText": "죄송합니다만 이 게임 버전은 너무 오래되었습니다. 최신 버전으로 업데이트해주십시오.", + "youHaveShortText": "티켓 보유량: ${COUNT}", + "youHaveText": "보유량: ${COUNT} 티켓" + }, + "googleMultiplayerDiscontinuedText": "죄송하지만, 구글의 멀티플레이어 서비스는 더이상 이용할수가 없어요.\n지금 대체제에 가능한 빨리 작업중이에요.\n그 때까지는, 다른 접속 방법을 사용해주세요.\n-Eric", + "googlePlayPurchasesNotAvailableText": "구매가 되지 않았습니다.\n아마 스토어 앱을 업데이트 해야 합니다.", + "googlePlayServicesNotAvailableText": "Google Play 서비스를 사용할 수 없습니다.\n 일부 앱 기능이 비활성화될 수 있습니다.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "언제나", + "fullScreenCmdText": "전체 화면 (Cmd-F)", + "fullScreenCtrlText": "전체 화면 (Ctrl-F)", + "gammaText": "감마", + "highText": "높음", + "higherText": "매우 높음", + "lowText": "낮음", + "mediumText": "중간", + "neverText": "안 함", + "resolutionText": "해상도", + "showFPSText": "fps 수치 표시", + "texturesText": "질감", + "titleText": "그래픽", + "tvBorderText": "TV 테두리", + "verticalSyncText": "수직 동기화", + "visualsText": "비주얼" + }, + "helpWindow": { + "bombInfoText": "- 폭탄 -\n펀치보다 강력하지만 자신도\n심각한 부상을 입을 수 있습니다.\n도화선이 다 타기 전에 적들에게\n던지는 것이 가장 좋습니다.", + "canHelpText": "${APP_NAME}가 여러분을 도울 수 있습니다.", + "controllersInfoText": "네트워크를 통해 친구들과 함께 ${APP_NAME}를 즐기거나\n컨트롤러가 충분할 경우 동일한 기기에서 함께 플레이할 수 있습니다.\n${APP_NAME}는 다양한 기기를 지원합니다. \n심지어 무료로 '${REMOTE_APP_NAME}' 앱을 사용해 휴대폰을 컨트롤러로\n사용할 수도 있습니다. 자세한 사항은 설정->컨트롤러를 참고하세요.", + "controllersInfoTextRemoteOnly": "당신은 네트워크를 이용하여 ${APP_NAME}을 친구들과 즐길 수 있고, 또는 당신은\n폰을 이용하여 '${REMOTE_APP_NAME}'앱을 깔아 \n같은 장치에서 다 같이 즐길 수 있습니다.", + "controllersText": "컨트롤러", + "controlsSubtitleText": "당신의 ${APP_NAME} 캐릭터는 약간의 기본적인 행동이 가능합니다", + "controlsText": "컨트롤", + "devicesInfoText": "일반 버전을 이용해 네트워크에서 ${APP_NAME}의 VR 버전을 \n플레이할 수 있습니다. 그러므로 남는 스마트폰, 태블릿, 컴퓨터를\n꺼내서 게임을 즐겨보세요. 이 게임의 일반 버전을 VR 버전에\n연결시켜서 다른 사람들이 게임을 감상하게 할 때에도\n유용합니다.", + "devicesText": "기기", + "friendsGoodText": "친구들이 있으면 좋습니다. ${APP_NAME}는 여러 친구가 함께 즐길 때\n가장 재미있으며 최대 8명을 지원할 수 있습니다.", + "friendsText": "친구", + "jumpInfoText": "- 점프 -\n점프를 이용해 작은 틈을 건너고\n물건을 더 높이 던지며 기쁜\n감정을 표현할 수 있습니다.", + "orPunchingSomethingText": "또는 무언가를 절벽에서 던져버리거나 끈적한 폭탄으로 저 멀리 날려버리고 싶을 때도 있을 겁니다.", + "pickUpInfoText": "- 줍기 -\n깃발, 적 또는 땅에 고정되지 않은\n것을 움켜잡을 수 있습니다.\n다시 누르면 던집니다.", + "powerupBombDescriptionText": "한 개가 아니라 연속해서\n세 개의 폭탄을 꺼냅니다.", + "powerupBombNameText": "3연발 폭탄", + "powerupCurseDescriptionText": "이것은 피하고 싶을 겁니다.\n ...혹시 원하는 건가요?", + "powerupCurseNameText": "저주", + "powerupHealthDescriptionText": "체력을 완전히 회복합니다.\n생각도 못했을 걸요.", + "powerupHealthNameText": "치유 팩", + "powerupIceBombsDescriptionText": "일반 폭탄보다는 약하지만\n적들을 얼려버리고\n약하게 만듭니다.", + "powerupIceBombsNameText": "얼음 폭탄", + "powerupImpactBombsDescriptionText": "일반 폭탄보다 약간 더 약하지만\n충격을 받으면 폭발합니다.", + "powerupImpactBombsNameText": "반응 폭탄", + "powerupLandMinesDescriptionText": "3개가 든 팩으로 제공됩니다.\n기지 방어 또는 빠른 적들을\n저지하는 데 유용합니다.", + "powerupLandMinesNameText": "지뢰", + "powerupPunchDescriptionText": "당신의 펀치를 더 단단하고,\n빠르고, 더 강하게 만들어 줍니다.", + "powerupPunchNameText": "권투 장갑", + "powerupShieldDescriptionText": "상대방의 공격을 막아\n피해를 줄입니다.", + "powerupShieldNameText": "에너지 실드", + "powerupStickyBombsDescriptionText": "뭐든 맞으면 달라붙습니다.\n그 다음이 재미있어요.", + "powerupStickyBombsNameText": "끈적이 폭탄", + "powerupsSubtitleText": "다양한 파워업 아이템들이 있습니다", + "powerupsText": "파워업", + "punchInfoText": "- 펀치 -\n주먹을 움직이는 속도가 빠를수록\n펀치가 더 강력해집니다. 그러니\n미친 사람처럼 달리고 회전하세요.", + "runInfoText": "- 달리기 -\n아무 버튼이나 길게 누르면 달립니다. 트리거 또는 숄더 버튼이 있으면 잘 작동합니다.\n달리면 더 빠르게 우위를 차지할 수 있으나 회전하기 어려우므로 절벽을 주의하세요.", + "someDaysText": "그냥 뭔가를 주먹으로 치고 싶을 때가 있을 겁니다. 아니면 무언가 날려버리고 싶거나요.", + "titleText": "${APP_NAME} 도움말", + "toGetTheMostText": "이 게임을 최대한 즐기기 위해 필요한 준비물", + "welcomeText": "${APP_NAME}에 오신 것을 환영합니다!" + }, + "holdAnyButtonText": "<아무 버튼이나 길게 누르세요>", + "holdAnyKeyText": "<아무 키나 길게 누르세요>", + "hostIsNavigatingMenusText": "- ${HOST}가 메뉴를 탐색 중입니다 -", + "importPlaylistCodeInstructionsText": "다른 곳으로 이 플레이 목록을 불러오기 위해 다음 코드를 사용하세요:", + "importPlaylistSuccessText": "${TYPE} 플레이 목록 '${NAME}' 를 불러왔습니다", + "importText": "불러오기", + "importingText": "불러오는 중...", + "inGameClippedNameText": "게임 내에서는 다음과 같이 보여질 것입니다.\n\"${NAME}\"", + "installDiskSpaceErrorText": "오류: 설치를 완료할 수 없습니다.\n기기에 공간이 부족한 것 같습니다.\n공간을 확보한 후 다시 시도해보세요.", + "internal": { + "arrowsToExitListText": "목록에서 나가려면 ${LEFT} 또는 ${RIGHT}를 누르세요", + "buttonText": "버튼", + "cantKickHostError": "당신은 호스트를 추방할 수 없습니다.", + "chatBlockedText": "${TIME} 초 동안 ${NAME} 님의 채팅이 차단됩니다.", + "connectedToGameText": "'${NAME}' 에 참가했습니다.", + "connectedToPartyText": "${NAME} 님의 파티에 가입했습니다!", + "connectingToPartyText": "연결 중...", + "connectionFailedHostAlreadyInPartyText": "연결에 실패했습니다. 호스트가 다른 파티에 있습니다.", + "connectionFailedPartyFullText": "연결에 실패했습니다. 파티가 꽉 찼습니다.", + "connectionFailedText": "연결에 실패했습니다.", + "connectionFailedVersionMismatchText": "연결에 실패했습니다. 호스트가 다른 게임 버전을 실행하고 있습니다.\n모두 최신 버전인지 확인한 후 다시 시도해보세요.", + "connectionRejectedText": "연결이 거부되었습니다.", + "controllerConnectedText": "${CONTROLLER}(이)가 연결되었습니다.", + "controllerDetectedText": "1개의 컨트롤러가 검색되었습니다.", + "controllerDisconnectedText": "${CONTROLLER}의 연결이 끊김.", + "controllerDisconnectedTryAgainText": "${CONTROLLER}의 연결이 끊겼습니다. 다시 연결을 시도해주십시오.", + "controllerForMenusOnlyText": "이 컨트롤러는 메뉴 전용으로 게임에는 사용하실 수 없습니다.", + "controllerReconnectedText": "${CONTROLLER}(이)가 다시 연결되었습니다.", + "controllersConnectedText": "${COUNT}개의 컨트롤러가 연결되었습니다.", + "controllersDetectedText": "${COUNT}개의 컨트롤러가 검색되었습니다.", + "controllersDisconnectedText": "${COUNT}개의 컨트롤러의 연결이 끊겼습니다.", + "corruptFileText": "손상된 파일이 검색되었습니다. 다시 설치하거나 ${EMAIL}에 이메일을 보내주십시오", + "errorPlayingMusicText": "음악 재생 오류: ${MUSIC}", + "errorResettingAchievementsText": "온라인 업적을 재설정할 수 없습니다. 나중에 다시 시도해주십시오.", + "hasMenuControlText": "${NAME} 님이 메뉴 컨트롤을 보유합니다.", + "incompatibleNewerVersionHostText": "호스트는 게임의 최신버전을 실행중입니다.\n최신버전으로 업데이트 하고 다시 시도해주세요.", + "incompatibleVersionHostText": "호스트가 다른 게임 버전을 실행하고 있습니다.\n모두 최신 버전인지 확인한 후 다시 시도해보세요.", + "incompatibleVersionPlayerText": "${NAME} 님이 다른 게임 버전을 실행하고 있습니다.\n모두 최신 버전인지 확인한 후 다시 시도해보세요.", + "invalidAddressErrorText": "오류: 잘못된 주소.", + "invalidNameErrorText": "오류: 잘못된 이름.", + "invalidPortErrorText": "오류: 잘못된 포트.", + "invitationSentText": "초대를 보냈습니다.", + "invitationsSentText": "${COUNT}개의 초대를 보냈습니다.", + "joinedPartyInstructionsText": "누가 파티에 가입했습니다.\n'플레이'에서 게임을 시작하세요.", + "keyboardText": "키보드", + "kickIdlePlayersKickedText": "부재 중인 ${NAME} 님을 추방하는 중.", + "kickIdlePlayersWarning1Text": "${NAME} 님은 계속 부재 중이면 ${COUNT}초 후 추방됩니다.", + "kickIdlePlayersWarning2Text": "(설정->고급에서 이 옵션을 끌 수 있습니다)", + "leftGameText": "'${NAME}' 을 떠났습니다.", + "leftPartyText": "${NAME} 님의 파티를 떠났습니다.", + "noMusicFilesInFolderText": "폴더에 음악 파일이 없습니다.", + "playerJoinedPartyText": "${NAME} 님이 파티에 가입했습니다!", + "playerLeftPartyText": "${NAME} 님이 파티를 떠났습니다.", + "rejectingInviteAlreadyInPartyText": "초대를 거절하는 중 (이미 파티 중임).", + "serverRestartingText": "서버를 다시 시작하는 중입니다. 곧 다시 합류해주세요...", + "serverShuttingDownText": "서버가 중지중입니다...", + "signInErrorText": "로그인 오류.", + "signInNoConnectionText": "로그인할 수 없습니다. (인터넷에 연결되지 않았습니까?)", + "telnetAccessDeniedText": "오류: 사용자가 텔넷 액세스를 부여하지 않았습니다.", + "timeOutText": "(${TIME}초 후 시간 초과)", + "touchScreenJoinWarningText": "터치스크린을 이용해 가입했습니다.\n실수로 그러신 경우 '메뉴->게임 나가기'를 누르세요.", + "touchScreenText": "터치스크린", + "unableToResolveHostText": "오류: 호스트를 확인할 수 없습니다.", + "unavailableNoConnectionText": "이 기능은 현재 이용할 수 없습니다 (인터넷에 연결되지 않았습니까?)", + "vrOrientationResetCardboardText": "이것을 이용해 VR 방향을 재설정합니다.\n게임을 플레이하려면 외부 컨트롤러가 필요합니다.", + "vrOrientationResetText": "VR 방향이 재설정되었습니다.", + "willTimeOutText": "(부재 중이면 시간 초과가 됩니다)" + }, + "jumpBoldText": "점프", + "jumpText": "점프", + "keepText": "유지", + "keepTheseSettingsText": "이 설정을 유지합니까?", + "keyboardChangeInstructionsText": "스페이스를 두번 눌러 키보드를 변경하시오.", + "keyboardNoOthersAvailableText": "다른 사용가능한 키보드가 없습니다.", + "keyboardSwitchText": "\"${NAME}\" 키보드로 전환중.", + "kickOccurredText": "${NAME} 님이 추방당했습니다.", + "kickQuestionText": "${NAME} 님을 추방하시겠습니까?", + "kickText": "추방", + "kickVoteCantKickAdminsText": "관리자들을 추방할 수 없습니다.", + "kickVoteCantKickSelfText": "스스로 킥 할수 없습니다.", + "kickVoteFailedNotEnoughVotersText": "투표 인원이 모자랍니다.", + "kickVoteFailedText": "추방 투표를 실패했습니다.", + "kickVoteStartedText": "${NAME} 님에 대한 추방 투표가 시작됐습니다.", + "kickVoteText": "추방 투표", + "kickVotingDisabledText": "추방 투표가 비활성 되있습니다.", + "kickWithChatText": "채팅 창에 ${YES} (을)를 치셔서 찬성 또는 ${NO} (을)를 치셔서 반대하십시오.", + "killsTallyText": "${COUNT}번 처치", + "killsText": "처치", + "kioskWindow": { + "easyText": "쉬움", + "epicModeText": "에픽 모드", + "fullMenuText": "전체 메뉴", + "hardText": "어려움", + "mediumText": "보통", + "singlePlayerExamplesText": "싱글 플레이어 / 협동 모드의 예", + "versusExamplesText": "대결 모드의 예" + }, + "languageSetText": "현재 언어는 '${LANGUAGE}'입니다.", + "lapNumberText": "랩 ${CURRENT}/${TOTAL}", + "lastGamesText": "(마지막 ${COUNT} 게임)", + "leaderboardsText": "순위표", + "league": { + "allTimeText": "역대", + "currentSeasonText": "현재 시즌 (${NUMBER})", + "leagueFullText": "${NAME} 리그", + "leagueRankText": "리그 순위", + "leagueText": "리그", + "rankInLeagueText": "#${RANK}, ${NAME} 리그${SUFFIX}", + "seasonEndedDaysAgoText": "시즌은 ${NUMBER}일 전에 종료되었습니다.", + "seasonEndsDaysText": "시즌은 ${NUMBER}일 후 종료됩니다.", + "seasonEndsHoursText": "시즌은 ${NUMBER}시간 후 종료됩니다.", + "seasonEndsMinutesText": "시즌은 ${NUMBER}분 후 종료됩니다.", + "seasonText": "시즌 ${NUMBER}", + "tournamentLeagueText": "이 토너먼트에 참가하려면 ${NAME} 리그에 도달해야 합니다.", + "trophyCountsResetText": "트로피 수는 다음 시즌에 초기화됩니다." + }, + "levelBestScoresText": "${LEVEL}의 최고 점수", + "levelBestTimesText": "${LEVEL}의 최고 시간", + "levelIsLockedText": "${LEVEL}(은)는 잠겼습니다.", + "levelMustBeCompletedFirstText": "${LEVEL}(을)를 먼저 완료해야 합니다.", + "levelText": "레벨 ${NUMBER}", + "levelUnlockedText": "레벨이 잠겼습니다!", + "livesBonusText": "생명력 보너스", + "loadingText": "불러오는 중", + "loadingTryAgainText": "로딩중입니다. 나중에 다시 시도하십시오...", + "macControllerSubsystemBothText": "둘 다 (권장하지 않음)", + "macControllerSubsystemClassicText": "클래식", + "macControllerSubsystemDescriptionText": "(컨트롤러가 작동하지 않는 경우 이것을 변경해보십시오)", + "macControllerSubsystemMFiNoteText": "Made-for-OS / Mac 컨트롤러가 감지되었습니다.\n설정 -> 컨트롤러에서 활성화 할 수 있습니다.", + "macControllerSubsystemMFiText": "iOS용/Mac용", + "macControllerSubsystemTitleText": "컨트롤러 지원", + "mainMenu": { + "creditsText": "개발진", + "demoMenuText": "데모 메뉴", + "endGameText": "게임 종료", + "endTestText": "테스트 종료", + "exitGameText": "게임 종료", + "exitToMenuText": "메뉴로 나가시겠습니까?", + "howToPlayText": "게임 방법", + "justPlayerText": "(${NAME} 님만)", + "leaveGameText": "게임 나가기", + "leavePartyConfirmText": "정말로 파티를 떠나시겠습니까?", + "leavePartyText": "파티 떠나기", + "quitText": "끝내기", + "resumeText": "계속하기", + "settingsText": "설정" + }, + "makeItSoText": "적용", + "mapSelectGetMoreMapsText": "다른 지도 보기...", + "mapSelectText": "선택...", + "mapSelectTitleText": "${GAME} 지도", + "mapText": "지도", + "maxConnectionsText": "최대 연결", + "maxPartySizeText": "최대 인원", + "maxPlayersText": "최대 플레이어", + "merchText": "상품!", + "modeArcadeText": "아케이드 모드", + "modeClassicText": "클래식 모드", + "modeDemoText": "데모 모드", + "mostValuablePlayerText": "가장 뛰어난 플레이어", + "mostViolatedPlayerText": "가장 비참한 플레이어", + "mostViolentPlayerText": "가장 난폭한 플레이어", + "moveText": "이동", + "multiKillText": "${COUNT}연속 처치!!!", + "multiPlayerCountText": "${COUNT}명의 플레이어", + "mustInviteFriendsText": "참고: 멀티 플레이어 게임을 하려면\n'${GATHER}' 패널에서 친구들을\n초대하거나 컨트롤러를 연결하세요.", + "nameBetrayedText": "${NAME} 님이 ${VICTIM} 님을 배반했습니다.", + "nameDiedText": "${NAME} 님이 죽었습니다.", + "nameKilledText": "${NAME} 님이 ${VICTIM} 님을 처치했습니다.", + "nameNotEmptyText": "이름은 비워둘 수 없습니다.", + "nameScoresText": "${NAME} 님 점수 획득!", + "nameSuicideKidFriendlyText": "${NAME} 님이 실수로 죽었습니다.", + "nameSuicideText": "${NAME} 님이 자살했습니다.", + "nameText": "이름", + "nativeText": "기본", + "newPersonalBestText": "새 개인 최고 기록!", + "newTestBuildAvailableText": "새 테스트 빌드가 나왔습니다! (${VERSION} 빌드 ${BUILD}).\n${ADDRESS}에서 다운로드 하세요", + "newText": "새", + "newVersionAvailableText": "${APP_NAME}의 새 버전이 나왔습니다! (${VERSION})", + "nextAchievementsText": "남은 도전과제:", + "nextLevelText": "다음 레벨", + "noAchievementsRemainingText": "- 없음", + "noContinuesText": "(계속 없음)", + "noExternalStorageErrorText": "이 기기에서 외부 저장소를 찾지 못했습니다.", + "noGameCircleText": "오류: GameCircle에 로그인되지 않았습니다", + "noScoresYetText": "아직 점수 없음.", + "noThanksText": "아니요", + "noTournamentsInTestBuildText": "경고: 이 테스트 빌드의 토너먼트 점수는 기록되지 않습니다.", + "noValidMapsErrorText": "이 게임 유형에 유효한 지도를 찾지 못했습니다.", + "notEnoughPlayersRemainingText": "남은 플레이어가 충분하지 않습니다. 게임을 종료한 후 새로 시작하세요.", + "notEnoughPlayersText": "이 게임을 시작하려면 ${COUNT}명 이상의 플레이어가 필요합니다!", + "notNowText": "다음에", + "notSignedInErrorText": "이 작업을 하려면 로그인해야 합니다.", + "notSignedInGooglePlayErrorText": "이 작업을 하려면 Google Play로 로그인해야 합니다.", + "notSignedInText": "로그인하지 않음", + "notUsingAccountText": "참고: ${SERVICE} 계정을 사용하지 않고 있습니다.\n 사용하려면 '계정 -> ${SERVICE}로 로그인'으로 이동하세요.", + "nothingIsSelectedErrorText": "선택된 것이 없습니다!", + "numberText": "#${NUMBER}", + "offText": "끔", + "okText": "확인", + "onText": "켬", + "oneMomentText": "잠시만요...", + "onslaughtRespawnText": "${PLAYER} 님은 ${WAVE} 웨이브에서 부활합니다", + "orText": "${A} 또는 ${B}", + "otherText": "기타...", + "outOfText": "(#${RANK} / ${ALL})", + "ownFlagAtYourBaseWarning": "자신의 깃발이 기지에 있어야\n점수를 획득할 수 있습니다!", + "packageModsEnabledErrorText": "로컬 패키지 모드를 사용하는 동안은 네트워크 플레이가 허용되지 않습니다 (설정->고급 참고)", + "partyWindow": { + "chatMessageText": "채팅 메시지", + "emptyText": "파티가 비어 있습니다", + "hostText": "(호스트)", + "sendText": "보내기", + "titleText": "내 파티" + }, + "pausedByHostText": "(호스트가 일시 중지함)", + "perfectWaveText": "완벽한 웨이브!", + "pickUpText": "줍기", + "playModes": { + "coopText": "협동", + "freeForAllText": "개인전", + "multiTeamText": "멀티 팀", + "singlePlayerCoopText": "싱글 플레이어 / 협동", + "teamsText": "팀전" + }, + "playText": "플레이", + "playWindow": { + "oneToFourPlayersText": "1-4 플레이어", + "titleText": "플레이", + "twoToEightPlayersText": "2-8 플레이어" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} 님이 다음 라운드 시작 시 참가합니다.", + "playerInfoText": "플레이어 정보", + "playerLeftText": "${PLAYER} 님이 게임을 나갔습니다.", + "playerLimitReachedText": "${COUNT}명의 플레이어 한도에 도달함. 더 이상 가입할 수 없습니다.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "자신의 계정 프로필을 삭제할 수 없습니다.", + "deleteButtonText": "프로필\n삭제", + "deleteConfirmText": "'${PROFILE}' 삭제합니까?", + "editButtonText": "프로필\n편집", + "explanationText": "(이 계정에 대한 맞춤형 플레이어 이름 및 외관)", + "newButtonText": "새\n프로필", + "titleText": "플레이어 프로필" + }, + "playerText": "플레이어", + "playlistNoValidGamesErrorText": "이 플레이 목록에 포함된 잠금 해제된 유효한 게임이 없습니다.", + "playlistNotFoundText": "플레이 목록이 없음", + "playlistText": "플레이리스트", + "playlistsText": "플레이 목록", + "pleaseRateText": "${APP_NAME} 앱이 마음에 드시면 잠시 시간을 내어\n평가를 하거나 리뷰를 남겨주세요. 저희가 유용한\n피드백을 얻을 수 있고 향후 개발에 도움이 됩니다.\n\n감사합니다!\n-eric", + "pleaseWaitText": "잠시만 기다려 주십시오...", + "pluginClassLoadErrorText": "플러그인(${PLUGIN})을 불러오는 도중에 오류가 생겼습니다. 오류 : ${ERROR}", + "pluginInitErrorText": "플러그인(${PLUGIN})을 실행하는 도중에 오류가 생겼습니다. 오류 : ${ERROR}", + "pluginsDetectedText": "새로운 플러그인이 감지되었습니다. 게임을 재시작 하거나 설정을 바꿔 주십시오.", + "pluginsRemovedText": "${NUM} 플러그인을 더 이상 찾을 수 없습니다.", + "pluginsText": "플러그인", + "practiceText": "연습", + "pressAnyButtonPlayAgainText": "다시 플레이하려면 아무 버튼이나 누르세요...", + "pressAnyButtonText": "계속하려면 아무 버튼이나 누르세요...", + "pressAnyButtonToJoinText": "가입하려면 아무 버튼이나 누르세요...", + "pressAnyKeyButtonPlayAgainText": "다시 플레이하려면 아무 키/버튼이나 누르세요...", + "pressAnyKeyButtonText": "계속하려면 아무 키/버튼이나 누르세요...", + "pressAnyKeyText": "아무 키나 누르세요...", + "pressJumpToFlyText": "** 비행하려면 점프를 반복해서 누르세요 **", + "pressPunchToJoinText": "펀치를 눌러서 가입합니다...", + "pressToOverrideCharacterText": "캐릭터를 덮어쓰려면 ${BUTTONS} 버튼을 누르세요", + "pressToSelectProfileText": "플레이어를 선택하려면 ${BUTTONS} 버튼을 누르세요", + "pressToSelectTeamText": "팀을 선택하려면 ${BUTTONS} 버튼을 누르세요", + "promoCodeWindow": { + "codeText": "코드", + "enterText": "입력" + }, + "promoSubmitErrorText": "코드 제출 오류. 인터넷 연결 상태를 확인하세요", + "ps3ControllersWindow": { + "macInstructionsText": "PS3의 전원을 끄고, 블루투스를 켠 뒤 컨트롤러를 USB로 연결하면 페어링이 됩니다.\n그 이후, 컨트롤러의 홈 버튼을 사용하면 유선 모드(USB)와 무선 모드(블루투스)를\n바꿀 수 있습니다.\n\n\n페어링 도중 패스워드를 입력해야 하는 경우가 있는데,\n이 경우 다음의 하는 방법 또는 구글링을 통하여 도움을 받을 수 있습니다.\n\n\n\n\n\n연결된 무선 컨트롤러의 리스트는\n시스템 환경설정->블루투스에서 확인이 가능합니다.\n만약 PS3에서의 사용을 원하신다면 블루투스에서 연결을 끊어야 쓸 수 있습니다.\n\n\n미사용중일시 블루투스에서 연결을 끊어야 배터리를 아낄 수 있습니다.\n\n\n차이가 있을 수 있으나, 블루투스는 최대 7개의 컨트롤러를 연결할 수 있습니다.", + "ouyaInstructionsText": "PS3 컨트롤러를 OUYA에서 사용하시려면, 우선 USB 케이블로 연결하여 페어링을 하면 됩니다.\n이 경우 다른 컨트롤러의 연결을 끊을 수도 있으므로 이 경우 OUYA를 재가동하신 후\nUSB 케이블을 빼면 됩니다.\n\n\n그 이후 홈 버튼을 누르면 무선 연결이 가능해집니다.\n그만 사용하고 싶다면 10초동안 홈 버튼을 눌러서 컨트롤러를 꺼야 합니다;\n하지 않으면 배터리가 낭비됩니다.", + "pairingTutorialText": "페어링 설명 동영상", + "titleText": "${APP_NAME} 앱과 함께 PS3 컨트롤러 사용하기:" + }, + "punchBoldText": "펀치", + "punchText": "펀치", + "purchaseForText": "${PRICE}에 구입", + "purchaseGameText": "게임 구입", + "purchasingText": "구입 중...", + "quitGameText": "${APP_NAME}를 종료하시겠습니까?", + "quittingIn5SecondsText": "5초 후 종료됩니다...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "무작위", + "rankText": "순위", + "ratingText": "등급", + "reachWave2Text": "순위에 들려면 웨이브 2에 도달하세요.", + "readyText": "준비", + "recentText": "최근", + "remoteAppInfoShortText": "${APP_NAME}는 친구 또는 가족과 같이 할 때 더 재미있습니다.\n컨트롤러 몇개를 연결하거나 또는\n${REMOTE_APP_NAME} 앱을 폰 또는 태블릿에\n설치하여 컨트롤러처럼 사용하실 수 있습니다.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "버튼 위치", + "button_size": "버튼 크기", + "cant_resolve_host": "호스트를 확인할 수 없습니다.", + "capturing": "캡처 중...", + "connected": "연결됨.", + "description": "스마트폰 또는 태블릿을 BombSquad의 컨트롤러로 사용하세요.\n하나의 TV 또는 태블릿에서 최대 8대의 기기를 동시에 연결해 멋진 로컬 멀티 플레이어 게임을 즐길 수 있습니다.", + "disconnected": "서버에서 연결이 끊겼습니다.", + "dpad_fixed": "고정", + "dpad_floating": "변동", + "dpad_position": "D-패드 위치", + "dpad_size": "D-패드 크기", + "dpad_type": "D-패드 종류", + "enter_an_address": "주소 입력", + "game_full": "게임이 만원이거나 연결을 받지 않습니다.", + "game_shut_down": "게임이 종료되었습니다.", + "hardware_buttons": "하드웨어 버튼", + "join_by_address": "주소로 가입...", + "lag": "랙: ${SECONDS}초", + "reset": "기본값으로 재설정", + "run1": "달리기 1", + "run2": "달리기 2", + "searching": "BombSquad 게임 검색 중...", + "searching_caption": "게임의 이름을 눌러서 가입하세요.\n게임과 같은 Wi-Fi 네트워크에 연결되어 있는지 확인하세요.", + "start": "시작", + "version_mismatch": "버전이 일치하지 않습니다.\nBombSquad 및 BombSquad Remote가\n최신 버전인지 확인한 후 다시 시도하세요." + }, + "removeInGameAdsText": "게임 내 광고를 제거하려면 상점에서 \"${PRO}\"를 잠금 해제하세요.", + "renameText": "이름 바꾸기", + "replayEndText": "다시 보기 종료", + "replayNameDefaultText": "마지막 게임 다시 보기", + "replayReadErrorText": "다시 보기 파일 읽기 오류.", + "replayRenameWarningText": "보관하고 싶으면 게임 후 \"${REPLAY}\"의 이름을 바꾸세요. 그렇지 않으면 덮어쓰게 됩니다.", + "replayVersionErrorText": "죄송합니다만 이 다시 보기는 다른 게임 버전에서\n만들어져서 사용할 수 없습니다.", + "replayWatchText": "다시 보기 감상", + "replayWriteErrorText": "다시 보기 파일 쓰기 오류.", + "replaysText": "다시 보기", + "reportPlayerExplanationText": "치팅, 부적절한 언어 또는 기타 나쁜 행위를 신고하려면 이 이메일을 사용하세요.\n아래에 기재해주십시오.", + "reportThisPlayerCheatingText": "치팅", + "reportThisPlayerLanguageText": "부적절한 언어", + "reportThisPlayerReasonText": "무엇을 신고하고 싶으세요?", + "reportThisPlayerText": "이 플레이어 신고", + "requestingText": "요청 중...", + "restartText": "다시 시작", + "retryText": "다시 시도", + "revertText": "되돌리기", + "runText": "달리기", + "saveText": "저장", + "scanScriptsErrorText": "스크립트를 검색하는 중 오류가 발생했습니다. 자세한 내용은 로그를 참조하십시오.", + "scoreChallengesText": "점수 챌린지", + "scoreListUnavailableText": "점수 목록을 이용할 수 없습니다.", + "scoreText": "점수", + "scoreUnits": { + "millisecondsText": "밀리초", + "pointsText": "점수", + "secondsText": "초" + }, + "scoreWasText": "(이전: ${COUNT})", + "selectText": "선택", + "seriesWinLine1PlayerText": "님이 시리즈에서", + "seriesWinLine1TeamText": "님이 시리즈에서", + "seriesWinLine1Text": "님이 시리즈에서", + "seriesWinLine2Text": "승리했습니다!", + "settingsWindow": { + "accountText": "계정", + "advancedText": "고급", + "audioText": "오디오", + "controllersText": "컨트롤러", + "graphicsText": "그래픽", + "playerProfilesMovedText": "참고: 플레이어 프로필은 메인 메뉴의 계정 창으로 이동했습니다.", + "titleText": "설정" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(간편하고 사용하기 쉬운 텍스트 편집용 온스크린 키보드)", + "alwaysUseInternalKeyboardText": "언제나 내부 키보드를 사용함", + "benchmarksText": "벤치마크 및 스트레스 테스트", + "disableCameraGyroscopeMotionText": "시야 자이로스코프 동작 비활성 하기", + "disableCameraShakeText": "화면 진동 비활성하기", + "disableThisNotice": "(고급설정에서 이 알림을 중지 할 수 있습니다)", + "enablePackageModsDescriptionText": "(추가 모드 기능을 활성화하지만 네트워크 플레이를 비활성화합니다)", + "enablePackageModsText": "로컬 패키지 모드 활성화", + "enterPromoCodeText": "코드 입력", + "forTestingText": "참고: 이 값들은 테스트용으로 앱을 종료하면 없어집니다.", + "helpTranslateText": "${APP_NAME}의 비영어권 번역은 커뮤니티에서 지원된\n결과입니다. 공헌하거나 번역을 교정하고 싶으면\n아래 링크를 이용하세요. 감사합니다!", + "kickIdlePlayersText": "부재 중 플레이어 추방", + "kidFriendlyModeText": "어린이 보호 모드 (폭력 순화 등)", + "languageText": "언어", + "moddingGuideText": "모딩 가이드", + "mustRestartText": "이 설정이 적용되려면 게임을 다시 시작해야 합니다.", + "netTestingText": "네트워크 테스트", + "resetText": "재설정", + "showBombTrajectoriesText": "폭탄 궤적 표시", + "showPlayerNamesText": "플레이어 이름 표시", + "showUserModsText": "모드 폴더 표시", + "titleText": "고급", + "translationEditorButtonText": "${APP_NAME} 번역 편집기", + "translationFetchErrorText": "번역 상태를 이용할 수 없습니다", + "translationFetchingStatusText": "번역 상태 확인 중...", + "translationInformMe": "언어 업데이트 알림 활성화", + "translationNoUpdateNeededText": "현재 언어는 최신 상태입니다. 만세!", + "translationUpdateNeededText": "** 현재 언어는 업데이트가 필요합니다!! **", + "vrTestingText": "VR 테스트" + }, + "shareText": "공유", + "sharingText": "공유 중...", + "showText": "표시", + "signInForPromoCodeText": "코드가 적용되려면 계정에 로그인해야 합니다.", + "signInWithGameCenterText": "Game Center 계정을 이용하려면\nGame Center 앱으로 로그인하세요.", + "singleGamePlaylistNameText": "${GAME}만", + "singlePlayerCountText": "1 플레이어", + "soloNameFilterText": "솔로 ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "캐릭터 선택", + "Chosen One": "선택된 자", + "Epic": "에픽 모드 게임", + "Epic Race": "에픽 레이스", + "FlagCatcher": "깃발 탈환", + "Flying": "행복한 생각", + "Football": "축구", + "ForwardMarch": "전진", + "GrandRomp": "정복", + "Hockey": "하키", + "Keep Away": "차단", + "Marching": "행군", + "Menu": "메인 메뉴", + "Onslaught": "맹습", + "Race": "레이스", + "Scary": "킹 오브 더 힐", + "Scores": "점수 화면", + "Survival": "제거", + "ToTheDeath": "데스 매치", + "Victory": "최종 점수 화면" + }, + "spaceKeyText": "스페이스", + "statsText": "전적", + "storagePermissionAccessText": "이 행위는 저장소 접근이 필요합니다.", + "store": { + "alreadyOwnText": "이미 ${NAME}(을)를 소유 중입니다!", + "bombSquadProDescriptionText": "• 업적 티켓 보상 두 배\n• 게임 내 광고 제거\n• 보너스 티켓 ${COUNT}장 포함\n• +${PERCENT}% 리그 점수 보너스\n• '${INF_ONSLAUGHT}' 및\n '${INF_RUNAROUND}' 협동 레벨 잠금 해제", + "bombSquadProNameText": "${APP_NAME} 프로", + "bombSquadProNewDescriptionText": "• 광고 제거와 게임 중 자성 화면 제거\n• 추가 게임 설정 사용 가능\n• 이것들도 제공됩니다:", + "buyText": "구입", + "charactersText": "캐릭터", + "comingSoonText": "향후 예정...", + "extrasText": "추가", + "freeBombSquadProText": "현재 봄스쿼드는 무료이지만, 당신은 무료로 전환되기 전 구매를 하였으므로\n봄스쿼드 프로판 업그레이드와 티켓 ${COUNT}를 감사의 의미로 드리겠습니다.\n새 기능을 즐기시고, 후원해 주셔서 감사합니다!\n-Eric", + "holidaySpecialText": "연휴 특가 상품", + "howToSwitchCharactersText": "(\"${SETTINGS} -> ${PLAYER_PROFILES}\"에서 캐릭터들을 할당 및 커스터마이징하세요)", + "howToUseIconsText": "(이것을 사용하려면 계정 창에서 글로벌 플레이어 프로필을 만드세요)", + "howToUseMapsText": "(이 지도들을 팀전/개인전 플레이 목록에서 사용하세요)", + "iconsText": "아이콘", + "loadErrorText": "페이지를 불러올 수 없습니다.\n인터넷 연결 상태를 확인하세요.", + "loadingText": "불러오는 중", + "mapsText": "지도", + "miniGamesText": "미니 게임", + "oneTimeOnlyText": "(마지막 기회)", + "purchaseAlreadyInProgressText": "이 아이템의 구매가 이미 진행 중입니다.", + "purchaseConfirmText": "${ITEM}(을)를 구매합니까?", + "purchaseNotValidError": "구매가 유효하지 않습니다.\n오류인 경우 ${EMAIL}에 문의해주십시오.", + "purchaseText": "구매", + "saleBundleText": "번들 세일!", + "saleExclaimText": "세일!", + "salePercentText": "(${PERCENT}% 할인)", + "saleText": "세일", + "searchText": "검색", + "teamsFreeForAllGamesText": "팀전 / 개인전", + "totalWorthText": "*** ${TOTAL_WORTH}만큼 가치가 있음! ***", + "upgradeQuestionText": "계정을 승급시키겠습니까?", + "winterSpecialText": "겨울 특가 상품", + "youOwnThisText": "- 보유 중 -" + }, + "storeDescriptionText": "광란의 8 플레이어 파티 게임!\n\n깃발-탈환, 폭탄-하키, 에픽-슬로-모션-데스-매치 등의 폭발성 미니 게임 토너먼트에서\n친구들 (또는 컴퓨터)을 날려버리세요!\n\n간단한 컨트롤과 폭넓은 컨트롤러 지원을 바탕으로 최대 8명의 플레이어가 손쉽게 액션을 즐길 수 있습니다. 무료 ‘BombSquad Remote’ 앱을 통해서 모바일 기기를 컨트롤러로서 사용할 수도 있습니다!\n\n폭탄으로 날려버리세요!\n\n자세한 사항은 www.froemling.net/bombsquad에서 확인하세요.", + "storeDescriptions": { + "blowUpYourFriendsText": "친구들을 날려버리세요.", + "competeInMiniGamesText": "레이싱에서 비행까지 다양한 미니 게임에서 경쟁하세요.", + "customize2Text": "캐릭터, 미니 게임 및 사운드트랙을 커스터마이징하세요.", + "customizeText": "캐릭터를 커스터마이징하고 자신만의 미니 게임 플레이 목록을 만드세요.", + "sportsMoreFunText": "폭탄이 있으면 스포츠가 더 재미있어요.", + "teamUpAgainstComputerText": "팀으로 컴퓨터에 맞서세요." + }, + "storeText": "상점", + "submitText": "제출", + "submittingPromoCodeText": "코드 제출 중...", + "teamNamesColorText": "팀 이름/색상...", + "telnetAccessGrantedText": "텔넷 액세스가 활성화됨.", + "telnetAccessText": "텔넷 액세스가 검색됨, 허용하시겠습니까?", + "testBuildErrorText": "이 테스트 빌드는 더 이상 유효하지 않습니다. 새 버전을 확인해주십시오.", + "testBuildText": "테스트 빌드", + "testBuildValidateErrorText": "테스트 빌드를 확인할 수 없습니다. (네트워크에 연결되지 않았습니까?)", + "testBuildValidatedText": "테스트 빌드 확인 완료. 즐거운 시간 되세요!", + "thankYouText": "지원해주셔서 감사합니다! 즐거운 시간 되세요!!", + "threeKillText": "트리플 킬!!", + "timeBonusText": "시간 보너스", + "timeElapsedText": "시간 경과", + "timeExpiredText": "시간 종료", + "timeSuffixDaysText": "${COUNT}일", + "timeSuffixHoursText": "${COUNT}시간", + "timeSuffixMinutesText": "${COUNT}분", + "timeSuffixSecondsText": "${COUNT}초", + "tipText": "팁", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "절친들", + "tournamentCheckingStateText": "토너먼트 상태를 확인 중입니다. 잠시 기다리세요...", + "tournamentEndedText": "이 토너먼트는 종료되었습니다. 새 토너먼트가 곧 시작됩니다.", + "tournamentEntryText": "토너먼트 참가", + "tournamentResultsRecentText": "최근 토너먼트 결과", + "tournamentStandingsText": "토너먼트 성적", + "tournamentText": "토너먼트", + "tournamentTimeExpiredText": "토너먼트 시간이 종료되었습니다", + "tournamentsDisabledWorkspaceText": "워크숍이 가동 중이라 토너먼트를 할 수 없습니다.\n토너먼트를 하려면, 워크숍을 끄고 게임을 재시작 하시오.", + "tournamentsText": "토너먼트", + "translations": { + "characterNames": { + "Agent Johnson": "존슨 요원", + "B-9000": "B-9000", + "Bernard": "버나드", + "Bones": "본즈", + "Butch": "부치", + "Easter Bunny": "부활절 토끼", + "Flopsy": "플롭시", + "Frosty": "프로스티", + "Gretel": "그레텔", + "Grumbledorf": "그럼블도프 마법사", + "Jack Morgan": "잭 모건", + "Kronk": "크롱크", + "Lee": "리", + "Lucky": "럭키", + "Mel": "멜", + "Middle-Man": "삼순신", + "Minimus": "미니무스", + "Pascal": "펭귄 파스칼", + "Pixel": "픽셀", + "Sammy Slam": "새미 슬램", + "Santa Claus": "산타클로스", + "Snake Shadow": "스네이크 셰도우", + "Spaz": "스파즈", + "Taobao Mascot": "타오바오 마스코트", + "Todd McBurton": "토드 맥버튼", + "Zoe": "조우", + "Zola": "졸라" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} 트레이닝", + "Infinite ${GAME}": "무한 ${GAME}", + "Infinite Onslaught": "무한 맹습", + "Infinite Runaround": "무한 행군", + "Onslaught Training": "맹습 트레이닝", + "Pro ${GAME}": "프로 ${GAME}", + "Pro Football": "프로 축구", + "Pro Onslaught": "프로 맹습", + "Pro Runaround": "프로 행군", + "Rookie ${GAME}": "루키 ${GAME}", + "Rookie Football": "루키 축구", + "Rookie Onslaught": "루키 맹습", + "The Last Stand": "최후의 저항", + "Uber ${GAME}": "슈퍼 ${GAME}", + "Uber Football": "슈퍼 축구", + "Uber Onslaught": "슈퍼 맹습", + "Uber Runaround": "슈퍼 행군" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "승리하려면 일정 시간 동안 선택된 자가 되세요.\n그 지위를 뺏으려면 선택된 자를 처치하세요.", + "Bomb as many targets as you can.": "가능한 한 많은 목표에 폭탄을 던지세요.", + "Carry the flag for ${ARG1} seconds.": "${ARG1}초 동안 깃발을 나르세요.", + "Carry the flag for a set length of time.": "일정 시간 동안 깃발을 나르세요.", + "Crush ${ARG1} of your enemies.": "적 ${ARG1}명을 분쇄하세요.", + "Defeat all enemies.": "모든 적을 물리치세요.", + "Dodge the falling bombs.": "떨어지는 폭탄을 피하세요.", + "Final glorious epic slow motion battle to the death.": "끝까지 싸우는 장렬하고 서사적인 마지막 슬로 모션 전투.", + "Gather eggs!": "달걀을 모으시오!", + "Get the flag to the enemy end zone.": "깃발을 적진 끝까지 가져가세요.", + "How fast can you defeat the ninjas?": "얼마나 빨리 닌자들을 물리칠 수 있어요?", + "Kill a set number of enemies to win.": "승리하려면 정해진 수의 적을 처치하세요.", + "Last one standing wins.": "최후까지 살아남은 자가 승리합니다.", + "Last remaining alive wins.": "마지막까지 살아남으면 승리합니다.", + "Last team standing wins.": "최후까지 살아남은 팀이 승리합니다.", + "Prevent enemies from reaching the exit.": "적들이 출구에 도달하지 못하게 하세요.", + "Reach the enemy flag to score.": "적의 깃발에 도달해서 점수를 획득하세요.", + "Return the enemy flag to score.": "적의 깃발을 되찾아서 점수를 획득하세요.", + "Run ${ARG1} laps.": "${ARG1} 랩을 달리세요.", + "Run ${ARG1} laps. Your entire team has to finish.": "${ARG1} 랩을 달리세요. 팀 전체가 완료해야 합니다.", + "Run 1 lap.": "1 랩을 달리세요.", + "Run 1 lap. Your entire team has to finish.": "1 랩을 달리세요. 팀 전체가 완료해야 합니다.", + "Run real fast!": "정말로 빨리 달리세요!", + "Score ${ARG1} goals.": "${ARG1} 골을 기록하세요.", + "Score ${ARG1} touchdowns.": "${ARG1} 터치다운을 기록하세요.", + "Score a goal.": "1 골을 기록하세요.", + "Score a touchdown.": "1 터치다운을 기록하세요.", + "Score some goals.": "골 몇 개를 기록하세요.", + "Secure all ${ARG1} flags.": "${ARG1}개의 깃발 전부를 확보하세요.", + "Secure all flags on the map to win.": "승리하려면 지도 상의 깃발 전부를 확보하세요.", + "Secure the flag for ${ARG1} seconds.": "${ARG1}초 동안 깃발을 확보하세요.", + "Secure the flag for a set length of time.": "일정 시간 동안 깃발을 확보하세요.", + "Steal the enemy flag ${ARG1} times.": "적 깃발을 ${ARG1}번 훔치세요.", + "Steal the enemy flag.": "적 깃발을 훔치세요.", + "There can be only one.": "한 명만 남을 수 있습니다.", + "Touch the enemy flag ${ARG1} times.": "적 깃발을 ${ARG1}번 터치하세요.", + "Touch the enemy flag.": "적 깃발을 터치하세요.", + "carry the flag for ${ARG1} seconds": "${ARG1}초 동안 깃발을 나르세요", + "kill ${ARG1} enemies": "적 ${ARG1}명을 처치하세요", + "last one standing wins": "최후까지 살아남은 자가 승리합니다", + "last team standing wins": "최후까지 살아남은 팀이 승리합니다", + "return ${ARG1} flags": "깃발 ${ARG1}개를 되찾으세요", + "return 1 flag": "깃발 1개를 되찾으세요", + "run ${ARG1} laps": "${ARG1} 랩을 달리세요", + "run 1 lap": "1 랩을 달리세요", + "score ${ARG1} goals": "${ARG1} 골을 기록하세요", + "score ${ARG1} touchdowns": "${ARG1} 터치다운을 기록하세요", + "score a goal": "1 골을 기록하세요", + "score a touchdown": "1 터치다운을 기록하세요", + "secure all ${ARG1} flags": "${ARG1}개의 깃발 전부를 확보하세요", + "secure the flag for ${ARG1} seconds": "${ARG1}초 동안 깃발을 확보하세요", + "touch ${ARG1} flags": "깃발 ${ARG1}개를 터치하세요", + "touch 1 flag": "깃발 1개를 터치하세요" + }, + "gameNames": { + "Assault": "전진", + "Capture the Flag": "깃발 탈환", + "Chosen One": "선택된 자", + "Conquest": "정복", + "Death Match": "데스 매치", + "Easter Egg Hunt": "부활절 달걀 찾기", + "Elimination": "제거", + "Football": "축구", + "Hockey": "하키", + "Keep Away": "차단", + "King of the Hill": "킹 오브 더 힐", + "Meteor Shower": "유성우", + "Ninja Fight": "닌자 전투", + "Onslaught": "맹습", + "Race": "레이스", + "Runaround": "행군", + "Target Practice": "투척 연습", + "The Last Stand": "최후의 저항" + }, + "inputDeviceNames": { + "Keyboard": "키보드", + "Keyboard P2": "키보드 P2" + }, + "languages": { + "Arabic": "아랍어", + "Belarussian": "벨로루시어", + "Chinese": "중국어 간체", + "ChineseTraditional": "중국어 번체", + "Croatian": "크로아티아어", + "Czech": "체코어", + "Danish": "덴마크어", + "Dutch": "네덜란드어", + "English": "영어", + "Esperanto": "에스페란토", + "Filipino": "필리핀어", + "Finnish": "핀란드어", + "French": "프랑스어", + "German": "독일어", + "Gibberish": "횡설수설", + "Greek": "그리스어", + "Hindi": "힌디어", + "Hungarian": "헝가리어", + "Indonesian": "인도네시아어", + "Italian": "이탈리아어", + "Japanese": "일본어", + "Korean": "한국어", + "Malay": "말레이어", + "Persian": "페르시아어", + "Polish": "폴란드어", + "Portuguese": "포르투갈어", + "Romanian": "루마니아어", + "Russian": "러시아어", + "Serbian": "세르비아어", + "Slovak": "슬로바키아어", + "Spanish": "스페인어", + "Swedish": "스웨덴어", + "Tamil": "타밀어", + "Thai": "태국어", + "Turkish": "터키어", + "Ukrainian": "우크라이나어", + "Venetian": "베네토어", + "Vietnamese": "베트남어" + }, + "leagueNames": { + "Bronze": "브론즈", + "Diamond": "다이아몬드", + "Gold": "골드", + "Silver": "실버" + }, + "mapsNames": { + "Big G": "빅 G", + "Bridgit": "브리짓", + "Courtyard": "코트야드", + "Crag Castle": "크래그 캐슬", + "Doom Shroom": "둠 쉬룸", + "Football Stadium": "풋볼 스타디움", + "Happy Thoughts": "행복한 생각", + "Hockey Stadium": "하키 스타디움", + "Lake Frigid": "레이크 프리짓", + "Monkey Face": "몽키 페이스", + "Rampage": "램페이지", + "Roundabout": "런어바웃", + "Step Right Up": "스텝 라잇 업", + "The Pad": "더 패드", + "Tip Top": "팁 톱", + "Tower D": "타워 D", + "Zigzag": "지그재그" + }, + "playlistNames": { + "Just Epic": "에픽 전용", + "Just Sports": "스포츠 전용" + }, + "scoreNames": { + "Flags": "깃발", + "Goals": "골", + "Score": "점수", + "Survived": "생존", + "Time": "시간", + "Time Held": "보유 시간" + }, + "serverResponses": { + "A code has already been used on this account.": "코드가 이 계정에 이미 사용되었습니다.", + "A reward has already been given for that address.": "보상이 이미 지급되었습니다.", + "Account linking successful!": "계정 연동 성공!", + "Account unlinking successful!": "계정 연동 해제 완료!", + "Accounts are already linked.": "계정들이 이미 연동되었습니다.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "광고 시청 인증이 될수 없었습니다.\n공식 게임이고 최신 버전의 게임으로 실행하고 있도록 해주십시오.", + "An error has occurred; (${ERROR})": "에러가 발생했습니다; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "심각한 에러가 발생했습니다.; 지원센터로 연락해주시오. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "오류가 발생했습니다. support@froemling.net으로 문의해주십시오.", + "An error has occurred; please try again later.": "에러가 발생하였습니다; 나중에 다시 시도하여 주시기 바랍니다.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "정말로 이 계정들을 연동하시겠습니까?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n이 작업은 취소할 수 없습니다!", + "BombSquad Pro unlocked!": "BombSquad 프로 잠금 해제!", + "Can't link 2 accounts of this type.": "이 유형의 계정 2개를 연동할 수 없습니다.", + "Can't link 2 diamond league accounts.": "다이아몬드 리그 계정 2개를 연동할 수 없습니다.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "연동할 수 없습니다. 최대 연동 계정 수 ${COUNT}(을)를 초과합니다.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "부정행위 사용이 감지되었습니다. ${COUNT}일 간 점수 및 상품이 중지됩니다.", + "Could not establish a secure connection.": "보안 연결을 수립할 수 없습니다.", + "Daily maximum reached.": "일일 한도에 도달했습니다.", + "Entering tournament...": "토너먼트에 참가 중...", + "Invalid code.": "잘못된 코드.", + "Invalid payment; purchase canceled.": "구매 무효화; 구매가 취소되었습니다.", + "Invalid promo code.": "잘못된 프로모션 코드.", + "Invalid purchase.": "잘못된 구매.", + "Invalid tournament entry; score will be ignored.": "잘못된 토너먼트 참가. 점수는 무시됩니다.", + "Item unlocked!": "아이템 잠금해제!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "연동 거부됨. ${ACCOUNT} 에 모두 지워질 \n매우 중요한 데이터가 있습니다.\n원한다면 반대 순서로 연동이 가능합니다\n(이 계정의 데이터가 지워지는 대신에)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "${ACCOUNT} 을 이 계정에 연동하시겠습니까?\n${ACCOUNT} 계정에 있는 모든 데이터가 삭제됩니다.\n이 동작은 번복할 수 없습니다. 확실합니까?", + "Max number of playlists reached.": "최대 플레이 목록 수에 도달했습니다.", + "Max number of profiles reached.": "최대 프로필 수에 도달했습니다.", + "Maximum friend code rewards reached.": "최대의 친구 코드 보상에 도달했습니다.", + "Message is too long.": "메시지가 너무 깁니다.", + "No servers are available. Please try again soon.": "가능한 서버가 없습니다. 나중에 다시 시도해주십시오.", + "Profile \"${NAME}\" upgraded successfully.": "프로필 \"${NAME}\" 업그레이드 성공.", + "Profile could not be upgraded.": "프로필을 업그레이드하지 못했습니다.", + "Purchase successful!": "구매 성공!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "로그인 선물로 티켓 ${COUNT}장을 받았습니다.\n내일 ${TOMORROW_COUNT}장을 받으세요.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "서버 기능이 이 버전의 게임에는 더이상 지원되지 않습니다;\n새 버전으로 업데이트 하시오.", + "Sorry, there are no uses remaining on this code.": "죄송합니다만 이 코드에 남은 사용 횟수가 없습니다.", + "Sorry, this code has already been used.": "죄송합니다만 이 코드는 이미 사용되었습니다.", + "Sorry, this code has expired.": "죄송합니다만 이 코드는 만료되었습니다.", + "Sorry, this code only works for new accounts.": "죄송합니다만 이 코드는 새 계정에만 유효합니다.", + "Still searching for nearby servers; please try again soon.": "아직 근처에 있는 서버를 찾는 중입니다; 나중에 다시 시도해주십시오.", + "Temporarily unavailable; please try again later.": "일시적으로 사용불가; 나중에 다시 시도하세요.", + "The tournament ended before you finished.": "귀하가 완료하기 전에 토너먼트가 종료되었습니다.", + "This account cannot be unlinked for ${NUM} days.": "이 계정은 ${NUM} 일 동안 연동 해제가 불가능합니다.", + "This code cannot be used on the account that created it.": "이 코드는 생성된 계정에 사용할 수 없습니다.", + "This is currently unavailable; please try again later.": "이건 현제 이용할수 없습니다; 나중에 다시 시도하시오.", + "This requires version ${VERSION} or newer.": "${VERSION} 버전 이상이 필요합니다.", + "Tournaments disabled due to rooted device.": "기기가 루팅되있어 토너먼트 기능이 비활성화되었습니다.", + "Tournaments require ${VERSION} or newer": "토너먼트는 ${VERSION} 또는 그 보다 새로운 버전이 필요합니다.", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "이 계정에서 ${ACCOUNT} 의 연동을 해제하시겠습니까?\n${ACCOUNT} 에 있는 모든 데이터가 초기화됩니다.\n(일부 상황에서 도전과제 빼고는)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "경고: 당신 계정에 해킹 관련 경고가 전해졌습니다.\n해킹 중인 걸로 밝혀진 계정은 즉시 차단됩니다. 제발 게임만은 공정하게 합시다.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "귀하의 기기를 이 계정에 연동하시겠습니까?\n\n귀하의 기기 계정: ${ACCOUNT1}\n이 계정: ${ACCOUNT2}\n\n이로써 기존 진행 상황을 유지할 수 있습니다.\n경고: 이 작업은 취소할 수 없습니다!", + "You already own this!": "이미 소유 중입니다!", + "You can join in ${COUNT} seconds.": "${COUNT} 초 후에 참가할 수 있습니다.", + "You don't have enough tickets for this!": "티켓이 충분하지 않습니다!", + "You don't own that.": "이미 소유하지 않았습니다.", + "You got ${COUNT} tickets!": "티켓 ${COUNT}장을 받았습니다!", + "You got a ${ITEM}!": "${ITEM}(을)를 받았습니다!", + "You have been promoted to a new league; congratulations!": "새 리그로 승격되었습니다. 축하합니다!", + "You must update to a newer version of the app to do this.": "이 작업을 하려면 새 앱 버전으로 업데이트해야 합니다.", + "You must update to the newest version of the game to do this.": "이 작업을 하려면 새로운 게임 버전으로 업데이트해야 합니다.", + "You must wait a few seconds before entering a new code.": "새 코드를 입력하기 전에 수초 간 기다려야 합니다.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "마지막 토너먼트에서 #${RANK}위에 랭크되었습니다. 플레이해주셔서 감사합니다!", + "Your account was rejected. Are you signed in?": "계정이 거부되었습니다. 로그인 되어있으시나요?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "게임 사본이 수정되었습니다.\n변경 사항을 되돌린 후 다시 시도해주십시오.", + "Your friend code was used by ${ACCOUNT}": "${ACCOUNT} 님이 친구 코드를 사용했습니다" + }, + "settingNames": { + "1 Minute": "1분", + "1 Second": "1초", + "10 Minutes": "10분", + "2 Minutes": "2분", + "2 Seconds": "2초", + "20 Minutes": "20분", + "4 Seconds": "4초", + "5 Minutes": "5분", + "8 Seconds": "8초", + "Allow Negative Scores": "마이너스 점수 허용", + "Balance Total Lives": "총 생명력 같게 하기", + "Bomb Spawning": "폭탄 생성주기", + "Chosen One Gets Gloves": "선택된 자가 글러브 획득", + "Chosen One Gets Shield": "선택된 자가 실드 획득", + "Chosen One Time": "선택된 자의 시간", + "Enable Impact Bombs": "충격 폭탄 사용", + "Enable Triple Bombs": "3연발 폭탄 사용", + "Entire Team Must Finish": "전체의 팀이 통과해야 합니다.", + "Epic Mode": "에픽 모드", + "Flag Idle Return Time": "유휴 깃발 귀환 시간", + "Flag Touch Return Time": "터치 깃발 귀환 시간", + "Hold Time": "유지 시간", + "Kills to Win Per Player": "승리하기 위한 플레이어당 처치 수", + "Laps": "랩", + "Lives Per Player": "플레이어당 생명력", + "Long": "김", + "Longer": "매우 김", + "Mine Spawning": "지뢰 출현", + "No Mines": "지뢰 없음", + "None": "없음", + "Normal": "보통", + "Pro Mode": "프로 모드", + "Respawn Times": "출현 시간", + "Score to Win": "승리 점수", + "Short": "짧음", + "Shorter": "매우 짧음", + "Solo Mode": "솔로 모드", + "Target Count": "표적 수", + "Time Limit": "시간 제한" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${PLAYER} 님이 이탈하여 ${TEAM} 팀이 실격됬습니다.", + "Killing ${NAME} for skipping part of the track!": "트랙 일부를 건너뛴 ${NAME} 님을 처치하는 중!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "${NAME}님에게 경고: 터보 / 버튼 과다 연타는 당신의 캐릭터를 쓰러트립니다." + }, + "teamNames": { + "Bad Guys": "나쁜 녀석들", + "Blue": "블루", + "Good Guys": "좋은 녀석들", + "Red": "레드" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "완벽한 타이밍의 달리기-점프-회전-펀치로 한 번에 처치하고\n친구들로부터 평생 존경을 받을 수 있습니다.", + "Always remember to floss.": "꼭 치실질 하는 걸 기억하세요.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "무작위로 생성된 이름 및 외관 대신 원하는 이름과 외관으로\n자신과 친구들의 플레이어 프로필을 생성하세요.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "저주 상자는 사용자를 시한 폭탄으로 변하게 합니다.\n유일한 치료 방법은 체력 팩을 빨리 집는 것입니다.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "여러 외관에도 불구하고 모든 캐릭터의 능력은 동일합니다.\n그러므로 가장 닮은 캐릭터를 아무거나 선택하세요.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "에너지 실드가 있다고 너무 건방 떨지는 마세요. 여전히 절벽으로 떨어질 수 있거든요.", + "Don't run all the time. Really. You will fall off cliffs.": "언제나 뛰지는 마세요. 정말이에요. 그러다 절벽에서 떨어질 거예요.", + "Don't spin for too long; you'll become dizzy and fall.": "너무 오랫동안 회전하지 마십시오. 현기증이 나서 넘어 질 것입니다.", + "Hold any button to run. (Trigger buttons work well if you have them)": "달리려면 아무 버튼이나 길게 누르세요. (트리거 버튼이 있으면 더 잘 작동합니다)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "아무 버튼이나 길게 누르면 달립니다. 달리면 더 빨리 우위를\n차지할 수 있으나 잘 회전이 안 되므로 절벽을 주의하세요.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "얼음 폭탄은 아주 강력하지는 않지만 맞은 것은 무엇이든\n얼려서 부서지기 쉽게 만듭니다.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "누군가 당신을 잡으면 펀치를 날리세요. 그럼 풀어줄 거예요.\n현실에서도 효과가 있어요.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "컨트롤러가 부족하면 모바일 기기에 '${REMOTE_APP_NAME}' 앱을\n설치해서 컨트롤러로 사용하세요.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "끈적이 폭탄이 당신에게 붙으면 마구 점프하고 빙빙 도세요. 폭탄을 흔들어 떨어트릴 수\n있어요. 아니면, 적어도 마지막 순간은 재미있을 거예요.", + "If you kill an enemy in one hit you get double points for it.": "적을 한 번에 처치하면 점수를 두 배로 얻어요.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "저주에 걸리면 생존 가능한 유일한 희망은 다음\n수초 이내에 체력 파워업을 찾는 거예요.", + "If you stay in one place, you're toast. Run and dodge to survive..": "한 곳에 머물면 토스트가 되버릴 거예요. 달리고 피해서 생존하세요.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "많은 플레이어가 들어왔다 나갔다 하면 설정에서 '부재 중-플레이어-자동-추방'을\n켜세요. 게임 나가기를 잊은 플레이어가 있을 수 있거든요.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "기기가 너무 뜨거워지거나 배터리를 절약하고 싶으면\n설정->그래픽에서 '비주얼' 또는 '해상도'를 낮게 하세요", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "프레임 속도가 고르지 않으면 게임의 그래픽 설정에서\n해상도 또는 비주얼을 낮게 해보세요.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "깃발-탈환에서 점수를 획득하려면 자신의 깃발이 자신의 기지에 있어야 해요.\n다른 팀이 점수를 얻으려고 할 때 깃발을 훔치는 것도 방해하는 좋은 방법이에요.", + "In hockey, you'll maintain more speed if you turn gradually.": "하키에서 점차적으로 회전하면 더 큰 스피드를 유지할 수 있어요.", + "It's easier to win with a friend or two helping.": "한 두 명의 도와주는 친구가 있으면 더 쉽게 이길 수 있어요.", + "Jump just as you're throwing to get bombs up to the highest levels.": "더 높은 곳으로 폭탄을 던지려면 던지면서 점프하세요.", + "Land-mines are a good way to stop speedy enemies.": "지뢰는 빠르게 움직이는 적들을 저지할 때 좋은 수단이에요.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "다른 플레이어를 포함해서 많은 것을 집고 던질 수 있어요. 적들을 절벽 밖으로\n던지는 것은 효과적이고 만족스러운 전략이 될 수 있어요.", + "No, you can't get up on the ledge. You have to throw bombs.": "아니요, 바위 턱에는 올라갈 수 없어요. 폭탄을 던져야 해요.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "대부분의 게임에서 플레이어들이 중간에 들어오고 나갈 수 있어요.\n그리고 언제든 컨트롤러를 연결하거나 분리할 수도 있어요.", + "Practice using your momentum to throw bombs more accurately.": "탄력을 이용해 더 정확히 폭탄을 던지는 법을 연습하세요.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "주먹을 빠르게 움직일수록 펀치로 더 많은 대미지를 가해요.\n그러니 미친 듯이 달리고 점프하고 회전하세요.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "폭탄을 던지기 전에 왔다 갔다 달리면 \n더 멀리 던질 수 있어요.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "TNT 상자 근처에서 폭탄을 터트려\n적의 무리를 처치하세요.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "목은 가장 약한 부분이어서 끈적이 폭탄이 머리에 붙으면\n보통은 게임 오버죠.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "이 레벨은 절대로 끝나지 않아요. 그러나 이곳에서 높은 점수를\n얻으면 전 세계에서 영원한 존경을 받게 될 거예요.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "던지는 힘은 길게 누르는 방향에 따라 달라져요.\n무언가 앞으로 가볍게 던지려면 어떤 방향도 길게 누르지 마세요.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "사운드트랙이 싫증나세요? 자신의 입맛대로 바꾸세요!\n설정->오디오->사운드트랙에서 변경하세요.", + "Try 'Cooking off' bombs for a second or two before throwing them.": "던지기 전에 1~2초 동안 폭탄을 자연 발화시켜보세요.", + "Try tricking enemies into killing eachother or running off cliffs.": "적들을 속여서 서로 죽이게 하거나 절벽에서 떨어지게 해보세요.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "깃발을 집으려면 줍기 버튼을 사용하세요 < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "더 멀리 던지려면 왔다 갔다 하세요.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "왼쪽 또는 오른쪽으로 회전해서 펀치를 '조준'할 수 있어요.\n모서리에서 악당들을 밀쳐내거나 하키에서 점수를 딸 때 유용해요.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "도화선 불꽃의 색깔로 폭탄이 언제 폭발할지 판단할 수 있어요.\n노랑.. 오렌지.. 빨강.. 그리고 터져버리죠.", + "You can throw bombs higher if you jump just before throwing.": "던지기 바로 전에 점프해서 폭탄을 더 높이 던질 수 있어요.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "머리를 물체에 부딪히면 대미지를 입어요.\n그러니 머리를 물체에 부딪히지 않도록 하세요.", + "Your punches do much more damage if you are running or spinning.": "달리거나 회전하고 있으면 펀치로 더 많은 대미지를 가해요." + } + }, + "trophiesRequiredText": "이것은 최소 ${NUMBER} 개의 트로피가 필요합니다.", + "trophiesText": "트로피", + "trophiesThisSeasonText": "이번 시즌 트로피", + "tutorial": { + "cpuBenchmarkText": "말도 안되는 속도로 튜토리얼을 실행 중(우선 CPU 속도를 테스트합니다)", + "phrase01Text": "안녕하세요!", + "phrase02Text": "${APP_NAME}에 환영합니다!", + "phrase03Text": "캐릭터를 컨트롤하는 팁을 몇 가지 알려드릴 게요.", + "phrase04Text": "${APP_NAME}의 많은 것이 물리학에 바탕을 두고 있어요.", + "phrase05Text": "예를 들어, 펀치를 날릴 때...", + "phrase06Text": "...대미지는 주먹의 속도에 기반하죠.", + "phrase07Text": "보셨죠? 움직이지 않으니 ${NAME} 님에게 거의 피해를 안 줘요.", + "phrase08Text": "이제 점프 및 회전을 해서 스피드를 더 올려보세요.", + "phrase09Text": "네, 훨씬 더 낫군요.", + "phrase10Text": "달리는 것도 도움이 돼요.", + "phrase11Text": "달리려면 아무 버튼이나 길게 누르세요.", + "phrase12Text": "멋진 펀치를 날리려면 달리고 회전해보세요.", + "phrase13Text": "어이쿠, 저 ${NAME} 님에게 미안하군요.", + "phrase14Text": "깃발이나... 또는 ${NAME} 님 같은 물체를 집을 수 있어요.", + "phrase15Text": "마지막으로 폭탄이 있군요.", + "phrase16Text": "폭탄을 던지려면 연습이 필요해요.", + "phrase17Text": "윽! 멋지게 던지지 못했군요.", + "phrase18Text": "움직이면 더 멀리 던지는 데 도움이 돼요.", + "phrase19Text": "점프하면 더 높이 던지는 데 도움이 돼죠.", + "phrase20Text": "폭탄을 '왔다 갔다'하면 훨씬 더 멀리 던질 수 있어요.", + "phrase21Text": "폭탄의 타이밍을 맞추는 게 까다로울 수 있어요.", + "phrase22Text": "이런.", + "phrase23Text": "1, 2초 동안 도화선을 '자연 발화'시켜보세요.", + "phrase24Text": "만세! 멋지게 태웠군요.", + "phrase25Text": "그럼, 다 됐네요.", + "phrase26Text": "이제 출발하세요!", + "phrase27Text": "배운 걸 기억하면 살아서 돌아올 거예요!", + "phrase28Text": "...아마도, 그럴 거예요...", + "phrase29Text": "행운을 빌어요!", + "randomName1Text": "프레드", + "randomName2Text": "해리", + "randomName3Text": "빌", + "randomName4Text": "척", + "randomName5Text": "필", + "skipConfirmText": "정말로 튜토리얼을 건너뛰세요? 눌러서 확인하세요.", + "skipVoteCountText": "${COUNT}/${TOTAL} 건너뜀", + "skippingText": "튜토리얼을 건너뛰는 중...", + "toSkipPressAnythingText": "(튜토리얼을 건너뛰려면 아무거나 누르세요)" + }, + "twoKillText": "더블 킬!", + "unavailableText": "이용할 수 없음", + "unconfiguredControllerDetectedText": "구성되지 않은 컨트롤러가 검색됨:", + "unlockThisInTheStoreText": "상점에서 잠금 해제해야 합니다.", + "unlockThisProfilesText": "${NUM}개 이상의 프로필을 만들기 위해, 다음 사항이 필요합니다. :", + "unlockThisText": "잠금 해제 필요 사항:", + "unsupportedHardwareText": "죄송합니다만 이 하드웨어는 본 게임 빌드에 의해 지원되지 않습니다.", + "upFirstText": "첫 번째:", + "upNextText": "게임 ${COUNT}의 다음:", + "updatingAccountText": "계정 업데이트 중...", + "upgradeText": "업그레이드", + "upgradeToPlayText": "플레이하려면 상점에서 \"${PRO}\"를 잠금 해제하세요.", + "useDefaultText": "기본값 사용", + "usesExternalControllerText": "이 게임은 외부 컨트롤러를 입력용으로 사용합니다.", + "usingItunesText": "사운트트랙에 음악 앱 사용 중...", + "usingItunesTurnRepeatAndShuffleOnText": "iTunes에서 임의 재생이 켜져있고 반복은 모두로 되어 있는지 확인해주십시오.", + "v2AccountLinkingInfoText": "V2 계정을 연결하려면 '계정 관리' 버튼을 누르세요.", + "validatingTestBuildText": "테스트 빌드 확인 중...", + "victoryText": "승리!", + "voteDelayText": "${NUMBER} 초 동안 다른 투표를 시작할 수 없습니다.", + "voteInProgressText": "투표가 이미 진행 중입니다.", + "votedAlreadyText": "이미 투표했습니다.", + "votesNeededText": "${NUMBER} 표 필요", + "vsText": "대", + "waitingForHostText": "(${HOST}를 기다리는 중)", + "waitingForPlayersText": "플레이어들의 가입을 기다리는 중...", + "waitingInLineText": "줄 서서 기다리는 중 (파티가 꽉 찼습니다)...", + "watchAVideoText": "비디오 감상", + "watchAnAdText": "광고 감상", + "watchWindow": { + "deleteConfirmText": "\"${REPLAY}\"를 삭제하시겠습니까?", + "deleteReplayButtonText": "다시 보기\n삭제", + "myReplaysText": "내 다시 보기", + "noReplaySelectedErrorText": "선택된 다시 보기 없음", + "playbackSpeedText": "재생 속도: ${SPEED}", + "renameReplayButtonText": "다시 보기\n이름 바꾸기", + "renameReplayText": "\"${REPLAY}\" 이름 변경", + "renameText": "이름 바꾸기", + "replayDeleteErrorText": "다시 보기 삭제 오류.", + "replayNameText": "다시 보기 이름", + "replayRenameErrorAlreadyExistsText": "같은 이름의 다시 보기가 이미 존재합니다.", + "replayRenameErrorInvalidName": "다시 보기의 이름을 바꿀 수 없습니다. 잘못된 이름.", + "replayRenameErrorText": "다시 보기 이름 바꾸기 오류", + "sharedReplaysText": "공유된 다시 보기", + "titleText": "감상", + "watchReplayButtonText": "다시 보기\n감상" + }, + "waveText": "웨이브", + "wellSureText": "확인!", + "whatIsThisText": "이게 뭔가요?", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote 저작권" + }, + "wiimoteListenWindow": { + "listeningText": "Wii 리모컨 등록중...", + "pressText": "Wii 리모컨의 1과 2를 동시에 누르시오.", + "pressText2": "신형 Wii 리모컨 모션 플러스의 경우는 뒤의 빨간 등록 버튼을 누르시오." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote 저작권", + "listenText": "등록하기", + "macInstructionsText": "Wiii를 꺼 놓고 블루투스를 킨 후 '등록하기' 버튼을 누르시오.\n현재 Wii 리모컨으로 하는 경우는 다소 잘 안될 수 도 있으므로\n연결 전 테스트를 몇번 하시는 것을 추천합니다.\n\n기본적으로 블루투스는 총 7개의 Wii 리모컨을 지원하나\n실제 성능은 다를 수 있습니다.\n\n\nBombSquad는 Wii 리모컨, 눈차크,\n그리고 클래식 컨트롤러를 지원합니다.\n현재 신형 Wii 리모컨 모션 플러스도 지원하나\n눈차크 등 추가 컨트롤러는 지원하지 않습니다.", + "thanksText": "이 기능을 가능하게 해 주신\nDarwiinRemote 팀에게 감사드립니다.", + "titleText": "Wii 리모컨 설정" + }, + "winsPlayerText": "${NAME} 님 승리!", + "winsTeamText": "${NAME} 팀 승리!", + "winsText": "${NAME} 님 승리!", + "workspaceSyncErrorText": "${WORKSPACE}를 동기화하다가 오류가 났습니다. 로그를 확인하세요.", + "workspaceSyncReuseText": "${WORKSPACE}를 동기화 할 수 없습니다. 마지막으로 동기화 된 버전으로 돌아갑니다.", + "worldScoresUnavailableText": "세계 기록을 이용할 수 없습니다.", + "worldsBestScoresText": "세계 최고 점수", + "worldsBestTimesText": "세계 최고 시간", + "xbox360ControllersWindow": { + "getDriverText": "드라이버 받기", + "macInstructions2Text": "컨트롤러를 무선으로 이용하기 위해선 윈도우즈용 Xbox 360 무선 컨트롤러와\n같이 있는 무선 리시버가 필요합니다.\n리시버 하나당 최대 4개의 컨트롤러를 연결할 수 있습니다.\n\n중요: 마이크로소프트 외의 회사에서 개발한 리시버의 경우 해당 드라이버와의\n사용이 불가능 합니다; 무선 리시버에 'XBOX 360'이 아니라 'Microsoft'가\n적혀 있어야 합니다. 현재 마이크로소프트는 이 무선 리시버를 단품으로 팔지 않으므로\n무선 리시버가 있는 컨트롤러를 구매거나 온라인 쇼핑몰에서 찾아야 합니다.\n\n이 드라이버가 유용하다면 드라이버 개발진에게\n기부를 하시는 것을 추천합니다.", + "macInstructionsText": "Xbox 360 컨트롤러를 사용하기 위해선 하단 링크의 맥용 드라이버를\n설치하신 후 사용하실 수 있습니다.\n유선 컨트롤러와 무선 컨트롤러 둘다 지원합니다.", + "ouyaInstructionsText": "Xbox 360 컨트롤러를 BombSquad에 사용하기 위해선 기기의\nUSB 포트에 연결하시면 됩니다. 여러개의 컨트롤러를 연결하시려면\nUSB 허브를 사용하시면 됩니다.\n\n무선 컨트롤러를 사용하기 위해선 윈도우즈용 시중에 판매중인\nXbox 360 무선 컨트롤러용 무선 리시버를 사용하시면 됩니다.\n각 리시버를 USB 포트에 연결하시면\n각 리시버당 4개의 컨트롤러를 연결 할 수 있습니다.", + "titleText": "${APP_NAME} 앱과 함께 Xbox 360 컨트롤러 사용하기:" + }, + "yesAllowText": "예, 허용합니다!", + "yourBestScoresText": "내 최고 점수", + "yourBestTimesText": "내 최고 시간" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/malay.json b/dist/ba_data/data/languages/malay.json new file mode 100644 index 0000000..089a1b4 --- /dev/null +++ b/dist/ba_data/data/languages/malay.json @@ -0,0 +1,1878 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Nama akaun tidak boleh mengandungi emoji atau aksara khas lain", + "accountsText": "Akaun", + "achievementProgressText": "Pencapaian: ${COUNT} daripada ${TOTAL}", + "campaignProgressText": "Perkembangan Kempen [Susah]: ${PROGRESS}", + "changeOncePerSeason": "Anda hanya boleh menukar ini sekali sahaja pada setiap musim.", + "changeOncePerSeasonError": "Anda mesti menunggu sehingga musim depan untuk menukarkannya lagi (${NUM} hari)", + "customName": "Nama Tersuai", + "googlePlayGamesAccountSwitchText": "Jika anda ingin menggunakan akaun Google lain,\ngunakan apl Permainan Google Play untuk bertukar.", + "linkAccountsEnterCodeText": "Masukkan Kod", + "linkAccountsGenerateCodeText": "Hasilkan Kod", + "linkAccountsInfoText": "(kongsi perkembangan melalui platform yang berbeza)", + "linkAccountsInstructionsNewText": "Untuk pautkan dua akaun, hasilkan kod pada yang pertama\ndan masukkan kod itu pada yang kedua. Data dari\nakaun kedua akan dikongsikan antara kedua-duanya.\n(Data dari akaun pertama akan hilang)\n\nAnda boleh memaut sebanyak ${COUNT} akaun.\n\nPENTING: pautkan akaun anda miliki sahaja;\nJika anda pautkan dengan akaun rakan anda,\nanda tidak boleh bermain dalam talian pada masa yang sama.", + "linkAccountsText": "Paut Akaun", + "linkedAccountsText": "Akaun yang Dipautkan:", + "manageAccountText": "Urus Akaun", + "nameChangeConfirm": "Tukar nama akaun anda kepada ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Ini akan menetap semula perkembangan co-op anda dan\nskor tinggi tempatan (tapi bukan tiket anda).\nIni tidak boleh dibuat asal. Adakah anda pasti?", + "resetProgressConfirmText": "Ini akan menetap semula perkembangan co-op,\npencapaian, dan skor tinggi tempatan\n(tapi bukan tiket anda). Ini tidak boleh\ndibuat asal. Adakah anda pasti?", + "resetProgressText": "Tetapkan Semula Perkembangan", + "setAccountName": "Tetapkan Nama Akaun", + "setAccountNameDesc": "Pilih nama untuk dipaparkan untuk akaun anda.\nAnda boleh menggunakan nama itu dari salah satu akaun pautan anda \natau buat nama tersuai unik.", + "signInInfoText": "Daftar masuk untuk dapatkan tiket, bersaing dalam talian,\ndan kongsi perkembangan melalui peranti.", + "signInText": "Daftar Masuk", + "signInWithDeviceInfoText": "(akaun automatik yang hanya tersedia untuk peranti ini)", + "signInWithDeviceText": "Daftar masuk dengan akaun peranti", + "signInWithGameCircleText": "Daftar masuk dengan Game Circle", + "signInWithGooglePlayText": "Daftar masuk dengan Google Play", + "signInWithTestAccountInfoText": "(jenis akaun warisan; gunakan akaun peranti untuk ke hadapan)", + "signInWithTestAccountText": "Daftar masuk dengan akaun ujian", + "signInWithV2InfoText": "(akaun yang berfungsi untuk semua platform)", + "signInWithV2Text": "Log masuk dengan akaun BombSquad", + "signOutText": "Daftar Keluar", + "signingInText": "Mendaftar masuk...", + "signingOutText": "Mendaftar keluar...", + "ticketsText": "Tiket: ${COUNT}", + "titleText": "Akaun", + "unlinkAccountsInstructionsText": "Pilih akaun untuk nyahpaut", + "unlinkAccountsText": "Nyahpaut Akaun", + "unlinkLegacyV1AccountsText": "Nyahsambung Akaun Legacy (V1)", + "v2LinkInstructionsText": "Gunakan pautan ini untuk mencipta akaun atau daftar masuk", + "viaAccount": "(melalui akaun ${NAME})", + "youAreSignedInAsText": "Anda didaftar masuk sebagai:" + }, + "achievementChallengesText": "Cabaran Pencapaian", + "achievementText": "Pencapaian", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Pukul 3 musuh dengan TNT", + "descriptionComplete": "Memukul 3 musuh dengan TNT", + "descriptionFull": "Terajang 3 musuh dengan TNT di ${LEVEL}", + "descriptionFullComplete": "Penyepak 3 musuh dengan TNT di ${LEVEL}", + "name": "Letupan Dinamit" + }, + "Boxer": { + "description": "Menang tanpa menggunakan apa-apa bom", + "descriptionComplete": "Memenangi tanpa menggunakan apa-apa bom", + "descriptionFull": "Selesaikan ${LEVEL} tanpa menggunakan apa-apa bom", + "descriptionFullComplete": "Menyelesaikan ${LEVEL} tanpa menggunakan apa-apa bom", + "name": "Burung apa, burung puyuh" + }, + "Dual Wielding": { + "descriptionFull": "Sambungkan 2 alat kawalan (perkakasan atau aplikasi)", + "descriptionFullComplete": "Menyambungkan 2 alat kawalan (perkakasan atau aplikasi)", + "name": "Dua Kawalan" + }, + "Flawless Victory": { + "description": "Menang tanpa terkena serangan", + "descriptionComplete": "Memenangi tanpa terkena serangan", + "descriptionFull": "Menang ${LEVEL} tanpa terkena serangan", + "descriptionFullComplete": "Memenangi ${LEVEL} tanpa terkena serangan", + "name": "Kemenangan Sempurna" + }, + "Free Loader": { + "descriptionFull": "Mulakan permainan Bebas Untuk Semua dengan 2+ pemain", + "descriptionFullComplete": "Memulakan permainan Bebas Untuk Semua dengan 2+ pemain", + "name": "Free Loader" + }, + "Gold Miner": { + "description": "Lempang 6 musuh dengan periuk api", + "descriptionComplete": "Menerajangi 6 musuh dengan periuk api", + "descriptionFull": "Lempang 6 musuh dengan periuk api di ${LEVEL}", + "descriptionFullComplete": "Terlempang 6 musuh dengan periuk api di ${LEVEL}", + "name": "Pelombong Emas" + }, + "Got the Moves": { + "description": "Menang tanpa menumbuk atau menggunakan bom", + "descriptionComplete": "Memenangi tanpa menumbuk atau menggunakan bom", + "descriptionFull": "Menangkan ${LEVEL} tanpa menumbuk atau menggunakan bom", + "descriptionFullComplete": "Memenangi ${LEVEL} tanpa menumbuk dan menggunakan bom", + "name": "Gerakan Hebat" + }, + "In Control": { + "descriptionFull": "Sambungkan alat kawalan (perkakasan atau aplikasi)", + "descriptionFullComplete": "Menyambungkan alat kawalan. (perkakasan atau aplikasi)", + "name": "Dalam Kawalan" + }, + "Last Stand God": { + "description": "Dapatkan 1000 mata", + "descriptionComplete": "Dapat 1000 mata", + "descriptionFull": "Dapatkan 1000 mata di ${LEVEL}", + "descriptionFullComplete": "Dapat 1000 mata di ${LEVEL}", + "name": "Raja ${LEVEL}" + }, + "Last Stand Master": { + "description": "Dapatkan 250 mata", + "descriptionComplete": "Dapat 250 mata", + "descriptionFull": "Dapatkan 250 mata di ${LEVEL}", + "descriptionFullComplete": "Dapat 250 mata di ${LEVEL}", + "name": "Pakar ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Dapatkan 500 mata", + "descriptionComplete": "Dapat 500 mata", + "descriptionFull": "Dapatkan 500 mata di ${LEVEL}", + "descriptionFullComplete": "Dapat 500 mata di ${LEVEL}", + "name": "Ahli Sihir ${LEVEL}" + }, + "Mine Games": { + "description": "Lempang 3 musuh dengan periuk api", + "descriptionComplete": "Sepak 3 musuh dengan periuk api", + "descriptionFull": "Sepak 3 musuh dengan periuk api di ${LEVEL}", + "descriptionFullComplete": "Menyepak 3 musuh dengan periuk api di ${LEVEL}", + "name": "Permainan Periuk Api" + }, + "Off You Go Then": { + "description": "Buang 3 musuh", + "descriptionComplete": "Membuang 3 orang jahat", + "descriptionFull": "Buang 3 musuh di ${LEVEL}", + "descriptionFullComplete": "Membuang 3 musuh ${LEVEL}", + "name": "Abang Aziz jatuh bot" + }, + "Onslaught God": { + "description": "Dapatkan 5000 mata", + "descriptionComplete": "Dapat 5000 mata", + "descriptionFull": "Dapatkan 5000 mata di ${LEVEL}", + "descriptionFullComplete": "Dapat 5000 mata di ${LEVEL}", + "name": "Raja ${LEVEL}" + }, + "Onslaught Master": { + "description": "Dapatkan 500 mata", + "descriptionComplete": "Dapat 500 mata", + "descriptionFull": "Dapatkan 500 mata di ${LEVEL}", + "descriptionFullComplete": "Dapat 500 mata di ${LEVEL}", + "name": "Pakar ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Kalahkan semua serangan", + "descriptionComplete": "Mengalahkan semua serangan", + "descriptionFull": "Kalahkan semua serangan di ${LEVEL}", + "descriptionFullComplete": "Mengalahkan semua serangan di ${LEVEL}", + "name": "Berjaya ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Skorkan 1000 mata", + "descriptionComplete": "Menjaringkan 1000 mata", + "descriptionFull": "Skor 1000 mata dalam level ${LEVEL}", + "descriptionFullComplete": "Menjaringkan 1000 mata dalam level ${LEVEL}", + "name": "${LEVEL} Ahli sihir" + }, + "Precision Bombing": { + "description": "Menang tanpa sebarang kuasa tambahan", + "descriptionComplete": "Menang tanpa kuasa tambahan", + "descriptionFull": "Menangkan ${LEVEL} tanpa sebarang kuasa tambahan", + "descriptionFullComplete": "Menang ${LEVEL} tanpa kuasa tambahan", + "name": "Pengeboman tepat" + }, + "Pro Boxer": { + "description": "Menang tanpa menggunakan bom", + "descriptionComplete": "Monang tanpa menggunakan bom", + "descriptionFull": "Lengkapkan ${LEVEL} tanpa menggunakan bom", + "descriptionFullComplete": "Selesai level ${LEVEL} tanpa menggunakan bom", + "name": "Peninju Pro" + }, + "Pro Football Shutout": { + "description": "Menang tanpa membiarkan penjahat mendapat markah", + "descriptionComplete": "Memonangi tanpa membiarkan penjahat mendapat markah", + "descriptionFull": "Menangkan level ${LEVEL} tanpa membiarkan penjahat mendapat markah", + "descriptionFullComplete": "Menang ${LEVEL} tanpa membiarkan penjahat mendapat markah", + "name": "${LEVEL} Menutup" + }, + "Pro Football Victory": { + "description": "Menang permainan", + "descriptionComplete": "Memenangi permainan", + "descriptionFull": "Menang permainan dalam ${LEVEL}", + "descriptionFullComplete": "Monang permainan dalam ${LEVEL}", + "name": "${LEVEL} Kemenangan" + }, + "Pro Onslaught Victory": { + "description": "Kalahkan semua tahap", + "descriptionComplete": "Telah mengalahkan semua gelombang", + "descriptionFull": "Kalahkan semua gelombang ${LEVEL}", + "descriptionFullComplete": "Telah mengalahkan semua gelombang ${LEVEL}", + "name": "${LEVEL} Kemenangan" + }, + "Pro Runaround Victory": { + "description": "Lengkapkan semua gelombang", + "descriptionComplete": "Telah selesai semua gelombang", + "descriptionFull": "Lengkapkan semua gelombang pada ${LEVEL}", + "descriptionFullComplete": "Telah selesai semua gelombang pada ${LEVEL}", + "name": "pemenang ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Menang tanpa membiarkan penjahat mendapat markah", + "descriptionComplete": "Menang tanpa membiarkan penjahat mendapat markah", + "descriptionFull": "Menang ${LEVEL} tanpa membiarkan penjahat mendapat markah", + "descriptionFullComplete": "Menang ${LEVEL} tanpa membiarkan penjahat mendapat markah", + "name": "Menutup ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Menangkan permainan", + "descriptionComplete": "Memenangi permainan", + "descriptionFull": "Menang permainan dalam ${LEVEL}", + "descriptionFullComplete": "Memenang permainan dalam ${LEVEL}", + "name": "Kejayaan ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Kalahan semua gelombang", + "descriptionComplete": "Telah mengalahkan semua gelombang", + "descriptionFull": "Kalahan semua gelombang dalam ${LEVEL}", + "descriptionFullComplete": "Telah mengalahkan semua gelombang dalam ${LEVEL}", + "name": "${LEVEL} Kemenangan" + }, + "Runaround God": { + "description": "Skor 2000 mata", + "descriptionComplete": "Telah skorkan 2000 mata", + "descriptionFull": "Skor 2000 mata pada ${LEVEL}", + "descriptionFullComplete": "Menjaringkan 2000 mata pada ${LEVEL}", + "name": "Pemonang ${LEVEL}" + }, + "Runaround Master": { + "description": "Skor 500 mata", + "descriptionComplete": "Menjaringkan 500 mata", + "descriptionFull": "Skor 500 mata dalam ${LEVEL}", + "descriptionFullComplete": "Menjaringkan 500 mata pada ${LEVEL}", + "name": "${LEVEL} Bossku" + }, + "Runaround Wizard": { + "description": "Dapatkan 1000 mata", + "descriptionComplete": "Mendapat 1000 mata", + "descriptionFull": "Dapatkan 1000 mata pada ${LEVEL}", + "descriptionFullComplete": "Mendapat 1000 mata pada ${LEVEL}", + "name": "${LEVEL} Ahli Sihir" + }, + "Sharing is Caring": { + "descriptionFull": "Berjaya kongsikan permainan dengan rakan", + "descriptionFullComplete": "Dengan jayanya berkongsi permainan dengan rakan", + "name": "Perkongsian yang bermakna" + }, + "Stayin' Alive": { + "description": "Menang tanpa meninggal", + "descriptionComplete": "Menang tanpa meninggal", + "descriptionFull": "Menang ${LEVEL} tanpa meninggal", + "descriptionFullComplete": "Menang ${LEVEL} tanpa niggal bin sila", + "name": "Lindung' Diri" + }, + "Super Mega Punch": { + "description": "Lepaskan tenaga 100% dengan satu tumbukan", + "descriptionComplete": "Menimbulkan kerosakan 100% dengan satu tumbukan", + "descriptionFull": "Lepaskan 100% tenaga dengan satu pukulan dalam ${LEVEL}", + "descriptionFullComplete": "Menimbulkan kerosakan 100% dengan satu tumbukan dalam ${LEVEL}", + "name": "Pelempang Super Mega" + }, + "Super Punch": { + "description": "Berikan 50% kerosakan dengan satu tumbukan", + "descriptionComplete": "Menimbulkan kerosakan 50% dengan satu tumbukan", + "descriptionFull": "Berikan 50% kerosakan dengan satu pukulan pada ${LEVEL}", + "descriptionFullComplete": "Menimbulkan kerosakan sebanyak 50% dengan satu pelempang pada ${LEVEL}", + "name": "Pelempang Super" + }, + "TNT Terror": { + "description": "Letupkan 6 orang jahat dengan TNT", + "descriptionComplete": "6 orang jahat telah diletupkan dengan TNT", + "descriptionFull": "Letupkan 6 orang jahat dengan TNT di ${LEVEL}", + "descriptionFullComplete": "6 orang jahat telah diletupkan dengan TNT di ${LEVEL}", + "name": "Ta an ta" + }, + "Team Player": { + "descriptionFull": "Mulakan permainan Berpasukan dengan 4+ pemain", + "descriptionFullComplete": "Telah memulakan permainan Berpasukan, dengan 4+ pemain", + "name": "Pemain berpasukan" + }, + "The Great Wall": { + "description": "Hentikan niat setiap orang jahat", + "descriptionComplete": "Hentikan setiap orang jahat", + "descriptionFull": "Hentikan setiap orang jahat di ${LEVEL}", + "descriptionFullComplete": "Hentikan niat setiap orang jahat di ${LEVEL}", + "name": "Tembok Besar" + }, + "The Wall": { + "description": "Hentikan setiap orang jahat", + "descriptionComplete": "Telah berjaya mengentikan setiap orang jahat", + "descriptionFull": "Hentikan setiap orang jahat di ${LEVEL}", + "descriptionFullComplete": "Berjaya menghentikan setiap orang jahat di ${LEVEL}", + "name": "Dinding" + }, + "Uber Football Shutout": { + "description": "Menang tanpa membiarkan messi menjaringkan gol", + "descriptionComplete": "Menang tanpa membiarkan Ronaldo menjaringkan gol", + "descriptionFull": "Menang ${LEVEL} tanpa membiarkan Safee Sali menjaringkan gol", + "descriptionFullComplete": "Memenangi ${LEVEL} tanpa membiarkan Mohamed Salah menjaringkan gol", + "name": "${LEVEL} Tertutup" + }, + "Uber Football Victory": { + "description": "Menangkan permainan", + "descriptionComplete": "Memenangi permainan", + "descriptionFull": "Menangi permainan dalam ${LEVEL}", + "descriptionFullComplete": "Telah memenangi permainan dalam ${LEVEL}", + "name": "${LEVEL} Kemenangan" + }, + "Uber Onslaught Victory": { + "description": "Lawan dalam semua gelombang", + "descriptionComplete": "Mengalahkan dalam semua gelombang", + "descriptionFull": "Kalahkan semua gelombang dalam ${LEVEL}", + "descriptionFullComplete": "Berjaya mengalahkan kesemua gelombang dalam ${LEVEL}", + "name": "Kemenangan ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Lengkapkan semua gelombang", + "descriptionComplete": "Telah selesai semua gelombang", + "descriptionFull": "Lengkapkan semua gelombang pada ${LEVEL}", + "descriptionFullComplete": "Selesaikan semua gelombang pada ${LEVEL}", + "name": "Kemenangan ${LEVEL}" + } + }, + "achievementsRemainingText": "Pencapaian yang Tinggal:", + "achievementsText": "Pencapaian", + "achievementsUnavailableForOldSeasonsText": "Maaf, pencapaian spesifik tidak tersedia untuk musim lama.", + "activatedText": "${THING} diaktifkan.", + "addGameWindow": { + "getMoreGamesText": "Dapatkan Lebih Banyak Permainan...", + "titleText": "Tambahkan Permainan" + }, + "allowText": "Benarkan", + "alreadySignedInText": "Akaun anda didaftar masuk dari peranti lain;\nsila tukar akaun atau tutupkan permainan pada\nperanti itu dan cuba lagi.", + "apiVersionErrorText": "Tidak dapat memuatkan modul ${NAME}; ia menyasarkan versi api ${VERSION_USED}; kami memerlukan ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Automatik\" menghidupkan ini apabila fon kepala dimasukkan)", + "headRelativeVRAudioText": "Audio VR Set-Kelapa Relatif", + "musicVolumeText": "Kelantangan Muzik", + "soundVolumeText": "Kelantangan Bunyi", + "soundtrackButtonText": "Runut Bunyi", + "soundtrackDescriptionText": "(uruskan muzik anda untuk dimainkan semasa bermain)", + "titleText": "Audio" + }, + "autoText": "Automatik", + "backText": "Kembali", + "banThisPlayerText": "Haramkan Pemain Ini", + "bestOfFinalText": "Terbaik-dalam-${COUNT} Akhir", + "bestOfSeriesText": "Terbaik daripada siri ${COUNT} :", + "bestRankText": "Kedudukan tertinggi anda adalah #${RANK}", + "bestRatingText": "Penilaian terbaik anda ialah ${RATING}", + "bombBoldText": "BOM", + "bombText": "Bom", + "boostText": "Tingkatkan", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} dapat ditatarajah di aplikasinya", + "buttonText": "butang", + "canWeDebugText": "Adakah anda mahu BombSquad melaporkan pepijat, kerosakan, dan\nmaklumat penggunaan asas kepada pembangun secara automatik?\n\nData ini tidak mengandungi maklumat peribadi dan membantu\npermainan selalu berjalan dengan lancar dan bebas pepijat.", + "cancelText": "Batal", + "cantConfigureDeviceText": "Maaf, ${DEVICE} tidak dapat diatur.", + "challengeEndedText": "Cabaran ini telah tamat", + "chatMuteText": "Senyapkan Perbualan", + "chatMutedText": "Perbualan Disenyapkan", + "chatUnMuteText": "Nyahsenyapkan Perbualan", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Anda mesti menyelasaikan\nperingkat ini untuk teruskan!", + "completionBonusText": "Bonus Penyelesaian", + "configControllersWindow": { + "configureControllersText": "Atur Alat Kawalan", + "configureKeyboard2Text": "Atur Papan Kekunci Pemain Kedua", + "configureKeyboardText": "Atur Papan Kekunci", + "configureMobileText": "Peranti Mudah Alih sebagai Alat Kawalan", + "configureTouchText": "Atur Skrin Sentuhan", + "ps3Text": "Alat Kawalan PS3", + "titleText": "Alat Kawalan", + "wiimotesText": "Wiimote", + "xbox360Text": "Alat Kawalan Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Peringatan: alat kawalan menyokong pelbagai peranti dan versi Android", + "pressAnyButtonText": "Tekan mana-mana butang pada alat kawalan\nyang anda hendak atur...", + "titleText": "Atur Kawalan" + }, + "configGamepadWindow": { + "advancedText": "Lanjutan", + "advancedTitleText": "Tetapan Lanjutan Alat Kawalan", + "analogStickDeadZoneDescriptionText": "(naikkan ini jika watak anda 'melayang' semasa anda melepaskan tongkat)", + "analogStickDeadZoneText": "Tengah Kayu Analog", + "appliesToAllText": "(berlaku untuk semua pengawal jenis ini)", + "autoRecalibrateDescriptionText": "(guna ini jika watak anda tidak bergerak pada kelajuan penuh)", + "autoRecalibrateText": "Analog Stick tentukan semula automatik", + "axisText": "paksi", + "clearText": "bersihkan", + "dpadText": "dpad", + "extraStartButtonText": "Butang Mula Tambahan", + "ifNothingHappensTryAnalogText": "Jika tiada apa-apa yang berlaku, cuba gunakan kayu analog , sebaliknya.", + "ifNothingHappensTryDpadText": "Jika tiada apa-apa berlaku, cuba gunakan d-pad sebagai ganti.", + "ignoreCompletelyDescriptionText": "(halang pengawal ini daripada menjejaskan, sama ada di dalam permainan atau menu)", + "ignoreCompletelyText": "Abaikan Sepenuhnya", + "ignoredButton1Text": "Butang Abaikan 1", + "ignoredButton2Text": "Butang Abaikan 2", + "ignoredButton3Text": "Butang Abaikan 3", + "ignoredButton4Text": "Butang Abaikan 4", + "ignoredButtonDescriptionText": "(gunakan ini untuk mengelakkan butang 'rumah' atau 'sync' daripada menjejaskan UI)", + "pressAnyAnalogTriggerText": "Tekan mana-mana pencetus analog...", + "pressAnyButtonOrDpadText": "Tekan mana-mana butang atau dpad...", + "pressAnyButtonText": "Tekan mana-mana butang...", + "pressLeftRightText": "Tekan kiri atau kanan...", + "pressUpDownText": "Tekan bawah atau atas...", + "runButton1Text": "Butang Jalankan 1", + "runButton2Text": "Butang Jalankan 2", + "runTrigger1Text": "Jalankan Pencetus 1", + "runTrigger2Text": "Jalankan Pencetus 2", + "runTriggerDescriptionText": "(pencetus analog membolehkan anda berlari pada kelajuan yang berbeza)", + "secondHalfText": "Gunakan ini untuk mengkonfigurasi pengawal kedua\ndalam peranti, 2-pengawal-dalam-1 yang\nmuncul sebagai pengawal tunggal.", + "secondaryEnableText": "Dayakan", + "secondaryText": "Pengawal Kedua", + "startButtonActivatesDefaultDescriptionText": "(matikan ini jika butang mula anda lebih kepada butang 'menu')", + "startButtonActivatesDefaultText": "Butang Mula Mengaktifkan Widget Biasa", + "titleText": "Setup Pengawal", + "twoInOneSetupText": "Persediaan Pengawal 2-dalam-1", + "uiOnlyDescriptionText": "(halang pengawal ini daripada menyertai permainan)", + "uiOnlyText": "Had kepada Penggunaan Menu", + "unassignedButtonsRunText": "Semua Butang yang Tidak Ditugaskan Dijalankan", + "unsetText": "", + "vrReorientButtonText": "Butang VR Reorient" + }, + "configKeyboardWindow": { + "configuringText": "Mengkonfigurasi ${DEVICE}", + "keyboard2NoteText": "Nota: kebanyakan papan kekunci boleh mendaftarkan beberapa tekanan kekunci dalam\nsesuatu masa, jadi papan kekunci kedua mungkin boleh berfungsi dengan lebih baik\njika terdapat papan kekunci berasingan yang dilampirkan untuk mereka gunakan.\nAmbil perhatian bahawa anda masih perlu memberikan kunci unik kepada\ndua pemain walaupun dalam kes itu." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Skala Kawalan Aksi", + "actionsText": "Aksi", + "buttonsText": "butang", + "dragControlsText": "< seret kawalan untuk ubah kedudukan >", + "joystickText": "kayu ria", + "movementControlScaleText": "Skala Kawalan Gerakan", + "movementText": "Pergerakan", + "resetText": "Tetap Semula", + "swipeControlsHiddenText": "Sembunyikan Ikon Sapu", + "swipeInfoText": "Gaya kawalan 'sapu' sangat sedikit digunakan tapi ia\nmembuatkan lebih senang bermain tanpa melihat kawalan", + "swipeText": "sapu", + "titleText": "Atur Skrin Sentuhan" + }, + "configureItNowText": "Aturnya sekarang?", + "configureText": "Atur", + "connectMobileDevicesWindow": { + "amazonText": "Amazon AppStore", + "appStoreText": "App Store", + "bestResultsText": "Untuk hasil terbaik, anda memerlukan rangkaian Wi-Fi yang bebas lambat.\nAnda boleh mengurangkan kelambatan Wi-Fi dengan mematikan peranti wayarles,\ndengan bermain berdekatan dengan penghala Wi-Fi anda, dan dengan menyambungkan\nhos permainan ke rangkaian melalui ethernet.", + "explanationText": "Untuk menggunakan telefon pintar atau tablet sebagai alat kawalan tanpa\nwayar, pasang aplikasi \"${REMOTE_APP_NAME}\" padanya. Banyak peranti boleh\nsambung ke satu permainan ${APP_NAME} melalui Wi-Fi, dan percuma!", + "forAndroidText": "Untuk Android:", + "forIOSText": "Untuk iOS:", + "getItForText": "Dapatkan ${REMOTE_APP_NAME} bagi iOS di Apple App Store\natau untuk Android di Google Play Store atau Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Menggunakan Peranti Mudah Alih sebagai Pengawal:" + }, + "continuePurchaseText": "Teruskan untuk ${PRICE}?", + "continueText": "Teruskan", + "controlsText": "Kawalan", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Ini tidak terpakai pada kedudukan sepanjang masa.", + "activenessInfoText": "Pengganda ini meningkat pada hari apabila anda\nbermain dan jatuh pada hari apabila anda tidak.", + "activityText": "Aktiviti", + "campaignText": "Kempen", + "challengesInfoText": "Dapat hadiah apabila melengkapkan permainan mini.\n\nHadiah dan tahap kesukaran meningkat\nsetiap kali cabaran selesai dan\nberkurangan apabila tamat tempoh atau dilucuthakkan.", + "challengesText": "Cabaran", + "currentBestText": "Yang Terbaik", + "customText": "Ubah suai", + "entryFeeText": "Kemasukan", + "forfeitConfirmText": "Hilang cabaran ini?", + "forfeitNotAllowedYetText": "Cabaran ini tidak boleh diketepikan lagi.", + "forfeitText": "Mengalah", + "multipliersText": "Pengganda", + "nextChallengeText": "Cabaran Seterusnya", + "nextPlayText": "Main Seterusnya", + "ofTotalTimeText": "daripada ${TOTAL}", + "playNowText": "Main sekarang", + "pointsText": "Mata", + "powerRankingFinishedSeasonUnrankedText": "(musim tamat tidak berperingkat)", + "powerRankingNotInTopText": "(bukan dalam ${NUMBER} teratas)", + "powerRankingPointsEqualsText": "= ${NUMBER} mata", + "powerRankingPointsMultText": "(x ${NUMBER} mata)", + "powerRankingPointsText": "${NUMBER} mata", + "powerRankingPointsToRankedText": "(${CURRENT} daripada ${REMAINING} mata)", + "powerRankingText": "Kedudukan Kuasa", + "prizesText": "Hadiah", + "proMultInfoText": "Pemain dengan peningkatan ${PRO}.\nterima peningkatan mata ${PERCENT}% di sini.", + "seeMoreText": "Lagi...", + "skipWaitText": "Langkau Tunggu", + "timeRemainingText": "Masa yang tinggal", + "toRankedText": "Untuk Peringkat", + "totalText": "jumlah", + "tournamentInfoText": "Bersaing untuk markah tinggi dengan\npemain lain dalam liga anda.\n\nHadiah diberikan kepada markah tertinggi\npemain apabila masa kejohanan tamat.", + "welcome1Text": "Selamat datang ke ${LEAGUE}. Anda boleh memperbaiki\nkedudukan liga dengan memperoleh penarafan bintang, melengkapkan\npencapaian, dan memenangi trofi dalam kejohanan.", + "welcome2Text": "Anda juga boleh mendapatkan tiket daripada banyak aktiviti yang sama.\nTiket boleh digunakan untuk membuka kunci aksara baharu, peta dan\npermainan mini, untuk menyertai kejohanan dan banyak lagi.", + "yourPowerRankingText": "Kedudukan Terhebat Anda:" + }, + "copyConfirmText": "Disalin ke papan keratan.", + "copyOfText": "Salinan ${NAME}", + "copyText": "Salinan", + "createEditPlayerText": "", + "createText": "Cipta", + "creditsWindow": { + "additionalAudioArtIdeasText": "Audio Tambahan, Hasil Kerja Awal, dan Idea oleh ${NAME}", + "additionalMusicFromText": "Muzik tambahan dari ${NAME}", + "allMyFamilyText": "Seluruh kawan dan keluarga saya yang tolong main uji", + "codingGraphicsAudioText": "Aturcara, Grafik, dan Audio oleh ${NAME}", + "languageTranslationsText": "Penerjemah Bahasa:", + "legalText": "Sah:", + "publicDomainMusicViaText": "Muzik awam melalui ${NAME}", + "softwareBasedOnText": "Perisian ini berdasarkan kerjasama ${NAME}", + "songCreditText": "${TITLE} Dipersembahkan oleh ${PERFORMER}\nDikarang oleh ${COMPOSER}, Disusun oleh ${ARRANGER}, Diterbitkan oleh ${PUBLISHER},\nIhsan ${SOURCE}", + "soundAndMusicText": "Bunyi & Muzik:", + "soundsText": "Bunyi (${SOURCE})", + "specialThanksText": "Terima Kasih Banyak kepada:", + "thanksEspeciallyToText": "Terima kasih terutamanya kepada ${NAME}", + "titleText": "Penghargaan ${APP_NAME}", + "whoeverInventedCoffeeText": "Sesiapa yang buatkan kopi" + }, + "currentStandingText": "Kedudukan semasa anda adalah #${RANK}", + "customizeText": "Ubahsuai...", + "deathsTallyText": "${COUNT} meninggal", + "deathsText": "Meninggal", + "debugText": "nyahpep..izzat", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Nota: adalah disyorkan agar anda menetapkan Tetapan->Grafik->Tekstur kepada 'Tinggi' semasa menguji ini.", + "runCPUBenchmarkText": "Jalankan Penanda Aras CPU", + "runGPUBenchmarkText": "Jalankan Penanda Aras GPU", + "runMediaReloadBenchmarkText": "Jalankan Penanda Aras Muat Semula Media", + "runStressTestText": "Jalankan ujian tekanan", + "stressTestPlayerCountText": "Kiraan Pemain", + "stressTestPlaylistDescriptionText": "Ujian Tekanan Senarai Main", + "stressTestPlaylistNameText": "Nama Senarai Main", + "stressTestPlaylistTypeText": "Jenis Senarai Main", + "stressTestRoundDurationText": "Tempoh Pusingan", + "stressTestTitleText": "Ujian Tekanan", + "titleText": "Penanda Aras & Ujian Tekanan", + "totalReloadTimeText": "Jumlah masa muat semula: ${TIME} (lihat log untuk butiran)" + }, + "defaultGameListNameText": "Senarai Main ${PLAYMODE} biasa", + "defaultNewGameListNameText": "Senarai Main ${PLAYMODE} Saya", + "deleteText": "Buang", + "demoText": "Demo", + "denyText": "Nafikan", + "deprecatedText": "Ditamatkan", + "desktopResText": "Desktop Res", + "deviceAccountUpgradeText": "Amaran:\nAnda telah log masuk dengan akaun peranti (${NAME}).\nAkaun peranti akan dialih keluar dalam kemas \nkini akan datang.", + "difficultyEasyText": "Mudah", + "difficultyHardOnlyText": "Mod Susah Sahaja", + "difficultyHardText": "Susah", + "difficultyHardUnlockOnlyText": "Tahap ini hanya dapat dibuka dalam mod sukar.\nAdakah anda mempunyai apa yang diperlukan!?!?!", + "directBrowserToURLText": "Sila arahkan pelayar web ke URL berikut:", + "disableRemoteAppConnectionsText": "Lumpuhkan Sambungan Apl Jauh", + "disableXInputDescriptionText": "Membenarkan lebih daripada 4 pengawal tetapi mungkin tidak berfungsi juga.", + "disableXInputText": "Lumpuhkan XInput", + "doneText": "Selesai", + "drawText": "Seri", + "duplicateText": "Pendua", + "editGameListWindow": { + "addGameText": "Tambah\nPermainan", + "cantOverwriteDefaultText": "Tidak boleh menulis ganti senarai main biasa!", + "cantSaveAlreadyExistsText": "Senarai main dengan nama itu sudah ada!", + "cantSaveEmptyListText": "Tidak dapat menyimpan senarai main kosong!", + "editGameText": "Sunting\nPermainan", + "listNameText": "Nama Senarai Main", + "nameText": "Nama", + "removeGameText": "Buang\nPermainan", + "saveText": "Simpan senarai", + "titleText": "Editor Senarai Main" + }, + "editProfileWindow": { + "accountProfileInfoText": "Profil istimewa ini mempunyai nama\ndan ikon berdasarkan akaun anda.\n\n${ICONS}\n\nBuat profil tersuai untuk menggunakan\nnama yang berbeza atau ikon tersuai.", + "accountProfileText": "(profil akaun)", + "availableText": "Nama \"${NAME}\" tersedia.", + "characterText": "watak", + "checkingAvailabilityText": "Menyemak ketersediaan untuk \"${NAME}\"...", + "colorText": "warna", + "getMoreCharactersText": "Dapatkan Lebih Banyak Watak...", + "getMoreIconsText": "Dapatkan Lebih Banyak Ikon...", + "globalProfileInfoText": "Profil pemain global dijamin nama\nunik di seluruh dunia. Ia juga termasuk ikon tersuai.", + "globalProfileText": "(profil global)", + "highlightText": "sorotan", + "iconText": "ikon", + "localProfileInfoText": "Profil pemain tempatan tidak mempunyai ikon dan namanya\ntidak dijamin unik. Tingkatkan ke profil global\nuntuk menempah nama unik dan menambahkan ikon sesuai.", + "localProfileText": "(profil lokal)", + "nameDescriptionText": "Nama Pemain", + "nameText": "Nama", + "randomText": "rawak", + "titleEditText": "Sunting profil", + "titleNewText": "Profil Baru", + "unavailableText": "\"${NAME}\" tidak tersedia; cuba nama lain.", + "upgradeProfileInfoText": "Ini akan menyimpan nama pemain anda di seluruh dunia\ndan membolehkan anda memberikan ikon khusus kepadanya.", + "upgradeToGlobalProfileText": "Naik taraf kepada Profil Global" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Anda tidak boleh memadamkan runut bunyi terbiasa.", + "cantEditDefaultText": "Tidak boleh mengedit runut bunyi biasa. Duplikasikan nya atau buat yang baharu.", + "cantOverwriteDefaultText": "Tidak dapat menulis ganti runut bunyi biasa", + "cantSaveAlreadyExistsText": "Lagu dengan nama itu sudah wujud!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Runut Bunyi Biasa", + "deleteConfirmText": "Padam Runut Bunyi:\n\n'${NAME}'?", + "deleteText": "Lombu\nGoreng", + "duplicateText": "Pendua\nrunut bunyi", + "editSoundtrackText": "Editor Lagu Bunyi", + "editText": "Sunting\nrunut bunyi", + "fetchingITunesText": "mengambil senarai main Apl Muzik...", + "musicVolumeZeroWarning": "Amaran: kelantangan muzik ditetapkan ke 0", + "nameText": "Nama", + "newSoundtrackNameText": "Runut Bunyi Saya ${COUNT}", + "newSoundtrackText": "Runut Bunyi Baharu:", + "newText": "Runut bunyi\nBaru", + "selectAPlaylistText": "Pilih Senarai Main", + "selectASourceText": "Sumber Muzik", + "testText": "Uji", + "titleText": "Runut bunyi", + "useDefaultGameMusicText": "Muzik Permainan Lalai", + "useITunesPlaylistText": "Senarai Main Apl Muzik", + "useMusicFileText": "Fail Muzik (mp3, dll)", + "useMusicFolderText": "Folder Fail Muzik" + }, + "editText": "Sunting", + "endText": "Tamatkan", + "enjoyText": "Nikmatilah!", + "epicDescriptionFilterText": "${DESCRIPTION} dalam gerakan perlahan epik", + "epicNameFilterText": "${NAME} Mod Epik", + "errorAccessDeniedText": "akses dinafikan", + "errorDeviceTimeIncorrectText": "Masa peranti anda tidak betul sebanyak ${HOURS} jam.\nIni berkemungkinan menyebabkan masalah.\nSila semak tetapan masa dan zon waktu anda.", + "errorOutOfDiskSpaceText": "kekurangan ruang", + "errorSecureConnectionFailText": "Tidak dapat mewujudkan sambungan awan selamat; fungsi rangkaian mungkin gagal.", + "errorText": "Ralat", + "errorUnknownText": "ralat tidak diketahui", + "exitGameText": "Keluar daripada ${APP_NAME}?", + "exportSuccessText": "'${NAME}' dieksport.", + "externalStorageText": "Storan Luaran", + "failText": "Gagal", + "fatalErrorText": "Alamak; ada sesuatu yang tiada atau rosak.\nSila memasang semula aplikasi atau hantar\nemel kepada ${EMAIL} untuk bantuan", + "fileSelectorWindow": { + "titleFileFolderText": "Pilih satu Fail atau Pelipat", + "titleFileText": "Pilih satu Fail", + "titleFolderText": "Pilih satu Pelipat", + "useThisFolderButtonText": "Guna Pelipat Ini" + }, + "filterText": "Penapis", + "finalScoreText": "Skor Terakhir", + "finalScoresText": "Skor Terakhir", + "finalTimeText": "Masa Terakhir", + "finishingInstallText": "Memasang: sila tunggu...", + "fireTVRemoteWarningText": "* Untuk pengalaman yang lebih baik,\ngunakan Game Controllers atau pasang\naplikasi '${REMOTE_APP_NAME}' pada\ntelefon atau tablet anda.", + "firstToFinalText": "Yang pertama untuk ${COUNT} pusingan akhir", + "firstToSeriesText": "Siri Pertama kepada-${COUNT}.", + "fiveKillText": "KENTUT BERLIMA!!!", + "flawlessWaveText": "Pusingan Sempurna!", + "fourKillText": "KENTUT BERAMAI-RAMAI!!!", + "friendScoresUnavailableText": "Skor rakan tidak tersedia.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Permainan ${COUNT} Ketua", + "gameListWindow": { + "cantDeleteDefaultText": "Anda tidak dapat memadamkan senarai main asal.", + "cantEditDefaultText": "Tidak dapat mengedit senarai main asal! Gandakannya atau buat yang baru.", + "cantShareDefaultText": "Anda tidak dapat kongsi senarai main asal.", + "deleteConfirmText": "Buang \"${LIST}\"?", + "deleteText": "Padam\nSenarai Main", + "duplicateText": "Pendua\nSenarai main", + "editText": "Sunting\nSenarai main", + "newText": "Senarai Main\nBaru", + "showTutorialText": "Tunjukkan Cara-cara", + "shuffleGameOrderText": "Pesanan Permainan Rombak", + "titleText": "Ubahsuai Senarai Main ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Tambah Permainan" + }, + "gamesToText": "${WINCOUNT} permainan hingga ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Ingat: mana-mana peranti dalam parti boleh lebih daripada\nsatu pemain jika anda mempunyai alat kawalan yang cukup.", + "aboutDescriptionText": "Gunakan halaman ini untuk mengadakan parti.\n\nParti membolehkan anda bermain permainan dan kejohanan\ndengan rakan anda melalui peranti yang berlainan.\n\nGunakan butang ${PARTY} di atas kanan untuk\nberbual dan berinteraksi dengan parti anda.\n(untuk alat kawalan, tekan ${BUTTON} apabila berada di menu)", + "aboutText": "Mengenai", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} beri anda ${COUNT} tiket di ${APP_NAME}", + "appInviteSendACodeText": "Hantarkan Kod", + "appInviteTitleText": "Jemputan Aplikasi ${APP_NAME}", + "bluetoothAndroidSupportText": "(berfungsi dengan mana-mana peranti Android yang menyokong Bluetooth)", + "bluetoothDescriptionText": "Hos/sertai parti melalui Bluetooth:", + "bluetoothHostText": "Hos melalui Bluetooth", + "bluetoothJoinText": "Sertai melalui Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "memeriksa...", + "copyCodeConfirmText": "Kod telah disalin.", + "copyCodeText": "Salin Kod", + "dedicatedServerInfoText": "Untuk pengalaman yang lebih baik, tetapkan pelayan berdedikasi. Lihat di bombsquadgame.com/server untuk mengetahui caranya.", + "disconnectClientsText": "Ini akan memutuskan sambungan ${COUNT} pemain\ndi parti anda. Anda pasti?", + "earnTicketsForRecommendingAmountText": "Rakan anda akan menerima ${COUNT} tiket jika mereka cuba main\n(anda akan menerima ${YOU_COUNT} tiket untuk setiap yang cuba)", + "earnTicketsForRecommendingText": "Kongsi permainan\nuntuk tiket percuma...", + "emailItText": "Hantar emel", + "favoritesSaveText": "Simpan Sebagai Kegemaran", + "favoritesText": "Kegemaran", + "freeCloudServerAvailableMinutesText": "Pelayan awan percuma seterusnya tersedia dalam ${MINUTES} minit.", + "freeCloudServerAvailableNowText": "Pelayan awan percuma tersedia!", + "freeCloudServerNotAvailableText": "Tidak ada pelayan awan percuma.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} tiket daripada ${NAME}", + "friendPromoCodeAwardText": "Anda akan menerima ${COUNT} tiket setiap kali kod digunakan.", + "friendPromoCodeExpireText": "Kod akan tamat tempoh dalam ${EXPIRE_HOURS} jam dan cuma berfungsi untuk pemain baru.", + "friendPromoCodeInstructionsText": "Untuk gunakan kod, buka ${APP_NAME} dan pergi ke \"Tetapan->Lanjutan->Masukkan Kod\".\nLihat di bombsquadgame.com untuk pautan muat turun untuk semua platform yang disokong.", + "friendPromoCodeRedeemLongText": "Ia boleh ditebus untuk ${COUNT} tiket percuma oleh sebanyak ${MAX_USES} orang.", + "friendPromoCodeRedeemShortText": "Ia boleh ditebus untuk ${COUNT} tiket di dalam permainan.", + "friendPromoCodeWhereToEnterText": "(tebus di \"Tetapan->Lanjutan->Masukkan Kod\")", + "getFriendInviteCodeText": "Dapatkan Kod Jemputan Rakan", + "googlePlayDescriptionText": "Jemput pemain Google Play ke parti anda:", + "googlePlayInviteText": "Jemput", + "googlePlayReInviteText": "Ada ${COUNT} pemain Google Play di parti anda\nyang akan diputus sambungan jika anda buat jemputan lagi.\nTermasuk mereka yang dijemput lagi untuk memasukkan mereka balik.", + "googlePlaySeeInvitesText": "Lihat Jemputan", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(versi Android / Google Play)", + "hostPublicPartyDescriptionText": "Hos Parti Awam", + "hostingUnavailableText": "Pengehosan Tidak Tersedia", + "inDevelopmentWarningText": "Peringatan:\n\nMain secara berangkaian ialah ciri baharu dan masih dibaik-pulih.\nUntuk sekarang, ianya sangat dicadangkan untuk semua pemain\ndisambung pada rangkaian Wi-Fi yang sama.", + "internetText": "Internet", + "inviteAFriendText": "Rakan tak main permainan ini? Jemput mereka untuk mereka\ncuba dan mereka akan dapat ${COUNT} tiket secara percuma.", + "inviteFriendsText": "Jemput Rakan", + "joinPublicPartyDescriptionText": "Sertai Parti Awam", + "localNetworkDescriptionText": "Sertailah Permainan Berdekatan (Wi-fi, LAN, Bluetooth, dll.)", + "localNetworkText": "Rangkaian Tempatan", + "makePartyPrivateText": "Peribadikan Parti Saya", + "makePartyPublicText": "Awamkan Parti Saya", + "manualAddressText": "Alamat", + "manualConnectText": "Sambung", + "manualDescriptionText": "Sertai parti melalui alamat:", + "manualJoinSectionText": "Sertai Mengikut Alamat", + "manualJoinableFromInternetText": "Parti anda dapat disertai dari internet?", + "manualJoinableNoWithAsteriskText": "TIDAK*", + "manualJoinableYesText": "YES", + "manualRouterForwardingText": "*untuk membaiki benda ini, cuba mengatur penghala ke UDP port ${PORT} ke alamat tempatan anda", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Alamat internet anda", + "manualYourLocalAddressText": "Alamat tempatan anda", + "nearbyText": "Berdekatan", + "noConnectionText": "", + "otherVersionsText": "(versi lain)", + "partyCodeText": "Kod Permainan", + "partyInviteAcceptText": "Terima", + "partyInviteDeclineText": "Tolak", + "partyInviteGooglePlayExtraText": "(lihat di halaman 'Google Play' di tetingkap 'Himpun')", + "partyInviteIgnoreText": "Abai", + "partyInviteText": "${NAME} menjemput anda\nuntuk menyertai partinya!", + "partyNameText": "Nama Parti", + "partyServerRunningText": "Server parti anda sedang berjalan.", + "partySizeText": "maks orang parti", + "partyStatusCheckingText": "memeriksa status...", + "partyStatusJoinableText": "parti anda kini dapat disertai dari internet", + "partyStatusNoConnectionText": "tidak dapat menyambung ke pelayan", + "partyStatusNotJoinableText": "parti anda tidak dapat disertai dari internet", + "partyStatusNotPublicText": "jenis parti anda bukan awam", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Parti swasta berjalan di cloud servers khusus; tidak diperlukan konfigurasi penghala.", + "privatePartyHostText": "Mengadakan Pesta Peribadi", + "privatePartyJoinText": "Sertai Parti Peribadi", + "privateText": "Peribadi", + "publicHostRouterConfigText": "Ini mungkin memerlukan konfigurasi pemajuan port pada penghala anda. Untuk pilihan yang lebih mudah, menganjurkan parti persendirian.", + "publicText": "Secara Awam", + "requestingAPromoCodeText": "Menghasilkan code...", + "sendDirectInvitesText": "Hantar Jemputan Terus", + "shareThisCodeWithFriendsText": "Kongsikan kod ini dengan rakan:", + "showMyAddressText": "Tunjukkan Alamat Saya", + "startHostingPaidText": "Hoskan Sekarang dengan ${COST}", + "startHostingText": "Mengacara", + "startStopHostingMinutesText": "Anda boleh memulakan dan menghentikan acara secara percuma selama ${MINUTES} minit seterusnya.", + "stopHostingText": "Hentikan Acara", + "titleText": "Himpun", + "wifiDirectDescriptionBottomText": "Jika semua peranti ada panel 'Wi-Fi Direct', mereka dapat mjumpa dan sambung satu sama lain.\nApabila semua peranti telah disambung, anda boleh membentuk parti dengan halaman\n'Rangkaian Tempatan', sama sahaja seperti rangkaian Wi-Fi biasa.\n\nUntuk hasil terbaik, hos Wi-Fi Direct juga patut menjadi hos parti ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct boleh diguna untuk menyambung peranti Andoid secara terus tanpa memerlukan\nrangkaian Wi-Fi. Ia berfungsi dengan baik pada versi Android 4.2 dan keatas.\n\nUntuk gunakannya, buka tetapan Wi-Fi dan cari 'Wi-Fi Direct' di menu.p", + "wifiDirectOpenWiFiSettingsText": "Buka Tetapan Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(berfungsi untuk semua platformer)", + "worksWithGooglePlayDevicesText": "(berfungsi dengan peranti yang mempunyai permainan versi dari Google Play (android))", + "youHaveBeenSentAPromoCodeText": "Anda menerima satu kod promosi ${APP_NAME}:" + }, + "getTicketsWindow": { + "freeText": "PERCUMA!", + "freeTicketsText": "Tiket Percuma", + "inProgressText": "Transaksi dalam penghantaran; sila cuba lagi nanti.", + "purchasesRestoredText": "Pembelian dikembalikan.", + "receivedTicketsText": "${COUNT} tiket diterima!", + "restorePurchasesText": "Kembalikan Pembelian", + "ticketPack1Text": "Pek Tiket Kecil", + "ticketPack2Text": "Pek Tiket Biasa", + "ticketPack3Text": "Pek Tiket Besar", + "ticketPack4Text": "Pek Tiket Jumbo", + "ticketPack5Text": "Pek Tiket Raksasa", + "ticketPack6Text": "Pek Tiket Muktamad", + "ticketsFromASponsorText": "Tonton iklan\n untuk ${COUNT} tiket", + "ticketsText": "${COUNT} Tiket", + "titleText": "Dapatkan Tiket", + "unavailableLinkAccountText": "Maaf, pembelian tidak tersedia di platform ini.\nSebagai penyelesaian, anda boleh pautkan akaun ini pada\nplatform lain dan buat pembeliannya.", + "unavailableTemporarilyText": "Ini tidak tersedia pada masa ini; sila cuba lagi nanti.", + "unavailableText": "Maaf, ini tidak tersedia.", + "versionTooOldText": "Maaf, versi permainan ini sangat lama; sila kemaskini ke versi baharu.", + "youHaveShortText": "anda mempunyai ${COUNT} tiket", + "youHaveText": "anda mempunyai ${COUNT} tiket" + }, + "googleMultiplayerDiscontinuedText": "Maaf, perkhidmatan berbilang pemain Google tidak lagi tersedia.\nSaya sedang mencari pengganti secepat mungkin.\nSementara itu, sila cuba kaedah sambungan lain.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Pembelian Google Play tidak tersedia.\nAnda mungkin perlu mengemas kini apl kedai anda.", + "googlePlayServicesNotAvailableText": "Perkhidmatan Google Play tidak tersedia.\nSesetengah fungsi apl mungkin dilumpuhkan.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Sentiasa", + "fullScreenCmdText": "Skrin penuh (Cmd-F)", + "fullScreenCtrlText": "Skrin penuh (Ctrl-F)", + "gammaText": "Gamma", + "highText": "Tinggi", + "higherText": "Lebih tinggi", + "lowText": "Rendah", + "mediumText": "Sederhana", + "neverText": "Tidak pernah", + "resolutionText": "Resolusi", + "showFPSText": "Tunjuk FPS", + "texturesText": "Tekstur", + "titleText": "Grafik", + "tvBorderText": "Sempadan TV", + "verticalSyncText": "Penyegerakan Menegak", + "visualsText": "Visual" + }, + "helpWindow": { + "bombInfoText": "- Bom -\nLebih kuat daripada menumbuk,\ntapi boleh menyebabkan kematian.\nUntuk hasil terbaik, baling bom\nkepada musuh sebelum tali habis terbakar", + "canHelpText": "${APP_NAME} boleh tolong", + "controllersInfoText": "Anda boleh bermain ${APP_NAME} dengan rakan melalui rangkaian, atau anda boleh\nmain bersama sekaligus dalam satu peranti jika anda ada alat kawalan yang cukup.\n${APP_NAME} sokong pelbagai jenis alat kawalan; anda boleh gunakan telefon\nbimbit sebagai alat kawalan melalui aplikasi percuma ${REMOTE_APP_NAME}.\nLihat pada Tetapan->Kawalan untuk maklumat lanjut.", + "controllersInfoTextRemoteOnly": "Anda boleh bermain ${APP_NAME} dengan rakan melalui rangkaian atau\nanda boleh bermain pada peranti yang sama dengan menggunakan telefon\nsebagai pengawal melalui apl percuma iaitu '${REMOTE_APP_NAME}'.", + "controllersText": "Alat Kawalan", + "controlsSubtitleText": "Watak mesra ${APP_NAME} anda ada beberapa aksi asas:", + "controlsText": "Kawalan", + "devicesInfoText": "${APP_NAME} versi VR boleh dimain melalui rangkaian\ndengan versi biasa, jadi ia memerlukan telefon, tablet,\ndan komputer lebih untuk menghidupkan permainan.\nIa berguna untuk menyambungkan permainan versi biasa ke versi\nVR yang membenarkan orang di luar menonton aksi permainan.", + "devicesText": "Peranti", + "friendsGoodText": "Memang bagus ada. ${APP_NAME} lebih seronok bersama dan\nsokong sebanyak 8 pemain dalam satu masa, yang bawa kita ke:", + "friendsText": "Rakan", + "jumpInfoText": "- Lompat -\nLompat untuk melintas jurang kecil,\nuntuk baling benda lebih tinggi,\ndan untuk meluahkan rasa gembira.", + "orPunchingSomethingText": "Atau menumbuk sesuatu, balingkannya dari atas tebing, dan letupkannya dengan bom melekit.", + "pickUpInfoText": "- Angkat -\nAngkat bendera, musuh, atau mana-mana\nsahaja yang tidak melekat di darat.\nTekan lagi untuk baling.", + "powerupBombDescriptionText": "Buatkan anda dapat baling tiga bom\ndalam satu masa daripada satu bom.", + "powerupBombNameText": "Bom Bertiga", + "powerupCurseDescriptionText": "Anda mungkin mahu elakkan diri\ndaripada ini... atau tidak?", + "powerupCurseNameText": "Sumpah", + "powerupHealthDescriptionText": "Pulihkan nyawa penuh.\nAnda mungkin tidak terfikir.", + "powerupHealthNameText": "Pek Rawatan", + "powerupIceBombsDescriptionText": "Lebih lemah daripada bom biasa\ntapi membekukan musuh anda\ndan terutamanya memecahkan.", + "powerupIceBombsNameText": "Bom Ais", + "powerupImpactBombsDescriptionText": "Lemah sikit daripada bom biasa,\ntapi ia letup bila dihentam.", + "powerupImpactBombsNameText": "Bom Pencetus", + "powerupLandMinesDescriptionText": "Satu pek ada tiga;\nBerguna untuk perlindungan pangkal\natau menghentikan musuh yang laju.", + "powerupLandMinesNameText": "Periuk Api", + "powerupPunchDescriptionText": "Mengeraskan, mencepatkan,\nmenguatkan tumbukan anda.", + "powerupPunchNameText": "Sarung Tangan Tinju", + "powerupShieldDescriptionText": "Menyerap kerosakan\njadi jangan takut.", + "powerupShieldNameText": "Perlindungan Tenaga", + "powerupStickyBombsDescriptionText": "Melekat di mana sahaja ia kena.\nMenghasilkan keseronokan.", + "powerupStickyBombsNameText": "Bom Melekit", + "powerupsSubtitleText": "Sudah tentu; tiada permainan yang selesai tanpa kuasa tambahan", + "powerupsText": "Kuasa Tambahan", + "punchInfoText": "- Tumbuk -\nSemakin laju tumbukan, semakin banyak\nkesakitan diberi. Jadi, lari dan\npusing seperti orang gila.", + "runInfoText": "- Lari -\nTahan MANA-MANA butang untuk lari. Lari membuat anda cepat tapi\nmenyusahkan untuk membelok, jadi hati-hati dengan tebing.", + "someDaysText": "Kadangkala anda berasa macam mahu tumbuk sesuatu. Atau meletupkan sesuatu.", + "titleText": "Bantuan ${APP_NAME}", + "toGetTheMostText": "Untuk menyeronokkan permainan ini, anda perlu:", + "welcomeText": "Selamat Datang ke ${APP_NAME}" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} sedang melayari menu -", + "importPlaylistCodeInstructionsText": "Gunakan kod berikut untuk import senarai main ini mana-mana:", + "importPlaylistSuccessText": "Senarai main ${TYPE} '${NAME}' diimport", + "importText": "Import", + "importingText": "Mengimport...", + "inGameClippedNameText": "dalam permainan dilihat\n\"${NAME}\"", + "installDiskSpaceErrorText": "RALAT: Tidak dapat menyelesaikan pemasangan.\nAnda mungkin kehabisan storan pada peranti anda.\nKosongkan sikit ruang dan cuba lagi.", + "internal": { + "arrowsToExitListText": "tekan ${LEFT} atau ${RIGHT} untuk terkeluar senarai", + "buttonText": "butang", + "cantKickHostError": "Anda tidak boleh menendang penganjur.", + "chatBlockedText": "${NAME} disekat beburak selamo ${TIME} saat.", + "connectedToGameText": "'${NAME}' Menyertai", + "connectedToPartyText": "Menyertai parti ${NAME}!", + "connectingToPartyText": "Menyambung...", + "connectionFailedHostAlreadyInPartyText": "Sambungan telah gagal; penganjur berada dalam parti lain.", + "connectionFailedPartyFullText": "Sambungan telah gagal; majlis penuh.", + "connectionFailedText": "Sambungan telah gagal.", + "connectionFailedVersionMismatchText": "Sambungan telah gagal; hos menjalankan versi permainan yang berbeza.\nPastikan anda berdua mengemas kini dan cuba lagi.", + "connectionRejectedText": "Sambungan ditolak.", + "controllerConnectedText": "${CONTROLLER} disambungkan.", + "controllerDetectedText": "1 pengawal dikesan.", + "controllerDisconnectedText": "${CONTROLLER} terputus sambungan.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} terputus sambungan. Sila cuba sambung semula.", + "controllerForMenusOnlyText": "Pengawal ini tidak boleh digunakan untuk bermain; hanya untuk menavigasi menu.", + "controllerReconnectedText": "${CONTROLLER} disambung semula.", + "controllersConnectedText": "${COUNT} pengawal disambungkan.", + "controllersDetectedText": "${COUNT} pengawal dikesan.", + "controllersDisconnectedText": "${COUNT} pengawal diputuskan sambungan.", + "corruptFileText": "Fail rosak dikesan. Sila cuba pasang semula, atau e-mel ${EMAIL}", + "errorPlayingMusicText": "Ralat memainkan muzik: ${MUSIC}", + "errorResettingAchievementsText": "Tidak dapat menetapkan semula pencapaian dalam talian; sila cuba sebentar lagi.", + "hasMenuControlText": "${NAME} mempunyai kawalan menu.", + "incompatibleNewerVersionHostText": "Hos sedang menjalankan versi permainan yang lebih baharu.\nKemas kini kepada versi terkini dan cuba lagi.", + "incompatibleVersionHostText": "Hos menjalankan versi permainan yang berbeza.\nPastikan anda berdua mengemas kini dan cuba lagi.", + "incompatibleVersionPlayerText": "${NAME} menjalankan versi permainan yang berbeza. \nPastikan anda semua mempunyai versi yang terkini dan cuba lagi.", + "invalidAddressErrorText": "Ralat: alamat tidak sah.", + "invalidNameErrorText": "Ralat: nama tidak sah.", + "invalidPortErrorText": "Ralat: port tidak sah.", + "invitationSentText": "Jemputan dihantar.", + "invitationsSentText": "${COUNT} jemputan dihantar.", + "joinedPartyInstructionsText": "Seseorang telah menyertai parti anda.\nPergi untuk 'Main' bagi memulakan permainan.", + "keyboardText": "Papan Kekunci", + "kickIdlePlayersKickedText": "Menendang ${NAME} kerana tidur.", + "kickIdlePlayersWarning1Text": "${NAME} akan ditendang dalam ${COUNT} saat jika masih tidur.", + "kickIdlePlayersWarning2Text": "(anda boleh mematikannya di Tetapan -> Lanjutan)", + "leftGameText": "'${NAME}' pergi.", + "leftPartyText": "Meninggalkan parti ${NAME} .", + "noMusicFilesInFolderText": "Folder tidak mengandungi fail muzik.", + "playerJoinedPartyText": "${NAME} menyertai parti!", + "playerLeftPartyText": "${NAME} meninggalkan parti ini.", + "rejectingInviteAlreadyInPartyText": "Menolak jemputan (sudah ada dalam parti).", + "serverRestartingText": "Pelayan dimulakan semula. Nanti sertai semula sebentar lagi...", + "serverShuttingDownText": "Pelayan sedang ditutup...", + "signInErrorText": "Ralat semasa me log masuk.", + "signInNoConnectionText": "Tidak dapat log masuk. (tiada sambungan internet?)", + "telnetAccessDeniedText": "RALAT: pengguna tidak memberikan akses telnet.", + "timeOutText": "(masa tamat dalam ${TIME} saat)", + "touchScreenJoinWarningText": "Anda telah bergabung dengan skrin sentuh.\nJika ini satu kesilapan, ketik 'Menu->Tinggalkan Permainan' dengannya.", + "touchScreenText": "Skrin-Sesentuh", + "unableToResolveHostText": "Ralat: tidak dapat menyelesaikan hos.", + "unavailableNoConnectionText": "Ini tidak tersedia pada masa ini (tiada sambungan internet?)", + "vrOrientationResetCardboardText": "Gunakan ini untuk menetapkan semula orientasi VR.\nUntuk bermain permainan, anda memerlukan pengawal lain.", + "vrOrientationResetText": "Tetapan semula orientasi VR.", + "willTimeOutText": "(tamat masa jika terbiar)" + }, + "jumpBoldText": "LOMPAT", + "jumpText": "Lompat", + "keepText": "Simpan", + "keepTheseSettingsText": "Simpan tetapan ini?", + "keyboardChangeInstructionsText": "Tekan dua kali \"spacebar\" untuk menukar papan kekunci.", + "keyboardNoOthersAvailableText": "Tiada papan kekunci lain tersedia.", + "keyboardSwitchText": "Menukar papan kekunci kepada \"${NAME}\".", + "kickOccurredText": "${NAME} telah diterajang.", + "kickQuestionText": "Tendang ${NAME}?", + "kickText": "Terajang", + "kickVoteCantKickAdminsText": "Admin tidak boleh ditendang.", + "kickVoteCantKickSelfText": "Anda tidak boleh menendang diri sendiri.", + "kickVoteFailedNotEnoughVotersText": "Tidak cukup pemain untuk undian.", + "kickVoteFailedText": "Undi sepakan gagal.", + "kickVoteStartedText": "Undian sepakan telah dimulakan untuk ${NAME}.", + "kickVoteText": "Undi untuk Menendang", + "kickVotingDisabledText": "Undian sepakan dilumpuhkan.", + "kickWithChatText": "Taip ${YES} dalam sembang untuk ya dan ${NO} untuk tidak.", + "killsTallyText": "${COUNT} meninggal", + "killsText": "Meninggal", + "kioskWindow": { + "easyText": "Senang", + "epicModeText": "Mod Epik", + "fullMenuText": "Menu Penuh", + "hardText": "Susah", + "mediumText": "Sederhana", + "singlePlayerExamplesText": "Contoh Pemain Tunggal / Koperasi", + "versusExamplesText": "Contoh Perbandingan" + }, + "languageSetText": "Bahasa ditetapkan ke \"${LANGUAGE}\"", + "lapNumberText": "Pusingan ${CURRENT}/${TOTAL}", + "lastGamesText": "( ${COUNT} permainan terakhir)", + "leaderboardsText": "Papan pendahulu", + "league": { + "allTimeText": "Setiap masa", + "currentSeasonText": "Musim Semasa (${NUMBER})", + "leagueFullText": "Liga ${NAME}.", + "leagueRankText": "Kedudukan Liga", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, Liga ${NAME}${SUFFIX}", + "seasonEndedDaysAgoText": "Musim tamat ${NUMBER} hari yang lalu.", + "seasonEndsDaysText": "Musim tamat dalam ${NUMBER} hari.", + "seasonEndsHoursText": "Musim tamat dalam ${NUMBER} jam.", + "seasonEndsMinutesText": "Musim tamat dalam ${NUMBER} minit.", + "seasonText": "Musim ${NUMBER}", + "tournamentLeagueText": "Anda mesti mencapai liga ${NAME} untuk menyertai kejohanan ini.", + "trophyCountsResetText": "Kiraan trofi akan ditetapkan semula musim depan." + }, + "levelBestScoresText": "Markah terbaik pada ${LEVEL}", + "levelBestTimesText": "Masa terbaik di ${LEVEL}", + "levelIsLockedText": "${LEVEL} dikunci.", + "levelMustBeCompletedFirstText": "${LEVEL} mesti diselesaikan terlebih dahulu.", + "levelText": "Tahap ${NUMBER}", + "levelUnlockedText": "Tahap Dibuka!", + "livesBonusText": "Bonus Kehidupan", + "loadingText": "Aubing", + "loadingTryAgainText": "Memuatkan; cuba lagi aubing...", + "macControllerSubsystemBothText": "Kedua-duanya (tidak disyorkan)", + "macControllerSubsystemClassicText": "Klasik", + "macControllerSubsystemDescriptionText": "(cuba tukar ini jika pengawal anda tidak berfungsi)", + "macControllerSubsystemMFiNoteText": "Pengawal Dibuat untuk iOS/Mac dikesan;\nAnda mungkin mahu mengunakan ini dalam Tetapan -> Pengawal", + "macControllerSubsystemMFiText": "Dibuat-untuk-iOS/Mac", + "macControllerSubsystemTitleText": "Sokongan Pengawal", + "mainMenu": { + "creditsText": "Kredit", + "demoMenuText": "Demo Menu", + "endGameText": "Tamatkan Permainan", + "endTestText": "Ujian Tamat", + "exitGameText": "Keluar Permainan", + "exitToMenuText": "Keluar ke menu?", + "howToPlayText": "Cara Bermain", + "justPlayerText": "(Hanya ${NAME})", + "leaveGameText": "Tinggalkan Permainan", + "leavePartyConfirmText": "Adakah anda hendak meninggalkan parti?", + "leavePartyText": "Keluar Parti", + "quitText": "Berhenti", + "resumeText": "Sambung semula", + "settingsText": "Tetapan" + }, + "makeItSoText": "Jadikannya", + "mapSelectGetMoreMapsText": "Dapatkan Peta Lagi..", + "mapSelectText": "Pilih...", + "mapSelectTitleText": "${GAME} Peta", + "mapText": "Peta", + "maxConnectionsText": "Sambungan Maksima", + "maxPartySizeText": "Saiz Parti Maksima", + "maxPlayersText": "Pemain Maksima", + "merchText": "Cenderamata", + "modeArcadeText": "Mod arked", + "modeClassicText": "Mod Klasik", + "modeDemoText": "Demo Mode", + "mostValuablePlayerText": "Pemain yang amat berharga", + "mostViolatedPlayerText": "Pemain yang Amat Melanggar", + "mostViolentPlayerText": "Pemain Paling Ganas", + "moveText": "Bergerak", + "multiKillText": "${COUNT}-Meninggal!!", + "multiPlayerCountText": "${COUNT} pemain", + "mustInviteFriendsText": "Nota: anda mesti menjemput rakan masuk\npanel \"${GATHER}\" atau lampirkan\npengawal untuk bermain berbilang pemain.", + "nameBetrayedText": "${NAME} mengkhianati ${VICTIM}.", + "nameDiedText": "${NAME} ninggal.", + "nameKilledText": "${NAME} meng ninggal ${VICTIM}.", + "nameNotEmptyText": "Nama tidak boleh kosong!", + "nameScoresText": "Markah ${NAME}!", + "nameSuicideKidFriendlyText": "${NAME} ter ninggal.", + "nameSuicideText": "${NAME} mening gal.", + "nameText": "Nama", + "nativeText": "Asal", + "newPersonalBestText": "Markah sendiri baharu!", + "newTestBuildAvailableText": "Binaan ujian yang lebih baharu tersedia! (${VERSION} bina ${BUILD}).\nDapatkannya di ${ADDRESS}", + "newText": "Baru", + "newVersionAvailableText": "Versi ${APP_NAME} yang lebih baharu tersedia! (${VERSION})", + "nextAchievementsText": "Pencapaian Seterusnya:", + "nextLevelText": "Peringkat seterusnya", + "noAchievementsRemainingText": "- tiada", + "noContinuesText": "(tidak boleh bersambung)", + "noExternalStorageErrorText": "Tiada storan luaran ditemui pada peranti ini", + "noGameCircleText": "Ralat: tidak log masuk ke GameCircle", + "noScoresYetText": "Tiada markah lagi.", + "noThanksText": "Tak Terimo Kasih, Yo", + "noTournamentsInTestBuildText": "AMARAN: Markah kejohanan daripada binaan ujian ini akan diabaikan.", + "noValidMapsErrorText": "Tiada peta yang sah ditemui untuk jenis permainan ini.", + "notEnoughPlayersRemainingText": "Tidak cukup pemain yang tinggal; keluar dan mulakan permainan baharu.", + "notEnoughPlayersText": "Anda memerlukan sekurang-kurangnya ${COUNT} pemain untuk memulakan permainan ini!", + "notNowText": "Bukan sekarang", + "notSignedInErrorText": "Anda mesti log masuk untuk melakukan ini.", + "notSignedInGooglePlayErrorText": "Anda mesti log masuk dengan Google Play untuk melakukan ini.", + "notSignedInText": "tidak dilog masuk", + "notUsingAccountText": "Nota: mengabaikan akaun ${SERVICE}.\nPergi ke 'Akaun -> Log masuk dengan ${SERVICE}' jika anda mahu menggunakannya.", + "nothingIsSelectedErrorText": "Tiada pilihan!", + "numberText": "#${NUMBER}", + "offText": "Tutup", + "okText": "Ok", + "onText": "Hidup", + "oneMomentText": "Tunggu Seketika...", + "onslaughtRespawnText": "${PLAYER} akan muncul semula dalam gelombang ${WAVE}", + "orText": "${A} atau ${B}", + "otherText": "Lain-lain...", + "outOfText": "(#${RANK} daripada ${ALL})", + "ownFlagAtYourBaseWarning": "Bendera anda sendiri mestilah ada\ndi pangkalan anda untuk menjaringkan gol!", + "packageModsEnabledErrorText": "Main rangkaian internet tidak dibenarkan semasa mod pakej tempatan didayakan (lihat Tetapan-> Lanjutan)", + "partyWindow": { + "chatMessageText": "Mesej Perbualan", + "emptyText": "Tiada siapa yang menyertai parti anda", + "hostText": "(hos)", + "sendText": "Hantar", + "titleText": "Parti Anda" + }, + "pausedByHostText": "(dijeda oleh hos)", + "perfectWaveText": "Serangan Sempurna!", + "pickUpText": "Angkat", + "playModes": { + "coopText": "Co-op", + "freeForAllText": "Bebas untuk Semua", + "multiTeamText": "Pelbagai Pasukan", + "singlePlayerCoopText": "Pemain Tunggal / Kerjasama", + "teamsText": "Pasukan" + }, + "playText": "Main", + "playWindow": { + "oneToFourPlayersText": "1-4 pemain", + "titleText": "Main", + "twoToEightPlayersText": "2-8 pemain" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} akan masuk pada permulaan pusingan seterusnya.", + "playerInfoText": "Info Pemain", + "playerLeftText": "${PLAYER} meninggalkan permainan.", + "playerLimitReachedText": "Had pemain ${COUNT} dicapai; tidak dibenarkan menyertai.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Anda tidak boleh memadamkan profil akaun anda.", + "deleteButtonText": "Padam\nProfil", + "deleteConfirmText": "Padam '${PROFILE}'?", + "editButtonText": "Sunting\nProfil", + "explanationText": "(nama dan nama pemain tersuai untuk akaun ini)", + "newButtonText": "Profil\nBaharu", + "titleText": "Profil Pemain" + }, + "playerText": "Pemain", + "playlistNoValidGamesErrorText": "Senarai main ini mengandungi permainan dikunci tidak sah.", + "playlistNotFoundText": "senarai main tidak dijumpai", + "playlistText": "Senarai main", + "playlistsText": "Senarai main", + "pleaseRateText": "Sekiranya anda menikmati ${APP_NAME}, sila ambil perhatian\nseketika dan berikan penarafan atau menulis ulasan. Ini akan menyediakan\nmaklum balas berguna dan membantu menyokong pembangunan masa hadapan.\n\nterima kasih!\n-eric", + "pleaseWaitText": "Sila tunggu...", + "pluginClassLoadErrorText": "Ralat memuatkan kelas pemalam '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Ralat semasa memulakan pemalam '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Pemalam baharu dikesan. Mulakan semula untuk mengaktifkannya, atau konfigurasikannya dalam tetapan.", + "pluginsRemovedText": "${NUM} pemalam tidak ditemui lagi.", + "pluginsText": "Bahan Tambahan", + "practiceText": "Latihan", + "pressAnyButtonPlayAgainText": "Tekan mana-mana butang untuk bermain semula...", + "pressAnyButtonText": "Tekan mana-mana butang untuk sambung...", + "pressAnyButtonToJoinText": "tekan mana-mana butang untuk sertai...", + "pressAnyKeyButtonPlayAgainText": "Tekan sebarang kekunci/butang untuk bermain semula...", + "pressAnyKeyButtonText": "Tekan sebarang kekunci/butang untuk meneruskan...", + "pressAnyKeyText": "Tekan mana-mana kekunci...", + "pressJumpToFlyText": "** Tekan lompat berulang kali untuk terbang **", + "pressPunchToJoinText": "tekan TUMBUK untuk menyertai...", + "pressToOverrideCharacterText": "tekan ${BUTTONS} untuk mengawal watak anda", + "pressToSelectProfileText": "tekan ${BUTTONS} untuk memilih pemain", + "pressToSelectTeamText": "tekan ${BUTTONS} untuk memilih pasukan", + "promoCodeWindow": { + "codeText": "Kod", + "enterText": "Masuk" + }, + "promoSubmitErrorText": "Ralat menghantar kod; semak sambungan internet anda", + "ps3ControllersWindow": { + "macInstructionsText": "Matikan kuasa di belakang PS3 anda, dan pastikan\nBluetooth didayakan pada Mac anda, kemudian sambungkan pengawal anda\nke Mac anda melalui kabel USB untuk memasangkan kedua-duanya.\nSelepas itu, boleh menggunakan butang rumah pengawal untuk menyambungkannya\nke Mac anda sama ada dalam mod berwayar (USB) atau wayarles (Bluetooth).\n\nPada sesetengah Mac, anda mungkin digesa untuk mendapatkan kod laluan\nsemasa berpasangan. Jika ini berlaku, lihat tutorial\natau google berikut untuk mendapatkan bantuan.\n\n\n\nPengawal PS3 yang disambungkan secara wayarles harus dipaparkan dalam peranti\nsenarai dalam Keutamaan Sistem->Bluetooth. Anda mungkin perlu mengeluarkannya\ndaripada senarai itu apabila anda mahu menggunakannya dengan PS3 anda sekali lagi.\n\nJuga pastikan untuk memutuskan sambungannya daripada Bluetooth apabila tidak\ndigunakan atau bateri mereka akan terus kehabisan.\n\nBluetooth boleh mengendalikan sehingga 7 peranti yang disambungkan,\nwalaupun perbatuan anda mungkin berbeza-beza.", + "ouyaInstructionsText": "Untuk menggunakan pengawal PS3 dengan OUYA anda, hanya sambungkannya dengan kabel USB\nsekali untuk memasangkannya. Melakukan ini mungkin memutuskan sambungan pengawal\nyang lain, jadi anda hendaklah mulakan semula OUYA anda dan cabut kabel USB.\n\nSelepas itu anda sepatutnya boleh menggunakan butang HOME pengawal untuk\nsambungkannya secara wayarles. Apabila anda selesai bermain, tahan butang HOME\nselama 10 saat untuk mematikan pengawal; jika tidak ia mungkin kekal dihidupkan\ndan membazir bateri.", + "pairingTutorialText": "video tutorial berpasangan", + "titleText": "Menggunakan Pengawal PS3 dengan ${APP_NAME}:" + }, + "punchBoldText": "LEMPANG", + "punchText": "Lempeng", + "purchaseForText": "Beli dengan harga ${PRICE}", + "purchaseGameText": "Permainan Belian", + "purchasingText": "Membeli...", + "quitGameText": "Blah ${APP_NAME}?", + "quittingIn5SecondsText": "Berhenti dalam 5 saat...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Rawak", + "rankText": "Pangtkat", + "ratingText": "Penilaian", + "reachWave2Text": "Capai gelombang 2 untuk mendapat kedudukan.", + "readyText": "sedia", + "recentText": "Baru-baru ini", + "remoteAppInfoShortText": "${APP_NAME} paling menyeronokkan apabila dimainkan bersama keluarga & rakan.\nSambungkan satu atau lebih pengawal perkakasan atau pasang\nAplikasi ${REMOTE_APP_NAME} pada telefon atau tablet untuk menggunakannya\nsebagai pengawal.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Kedudukan Butang", + "button_size": "Saiz Butang", + "cant_resolve_host": "Tidak dapat menentukan hos.", + "capturing": "Menangkap...", + "connected": "Disambung.", + "description": "Gunakan telefon atau tablet anda sebagai alat kawalan BombSquad.\nSebanyak 8 peranti boleh sambung sekaligus untuk kegilaan permainan jamak tempatan epik di satu TV atau tbalet.", + "disconnected": "Putus sambungan oleh pelayan.", + "dpad_fixed": "tetap", + "dpad_floating": "terapung", + "dpad_position": "Kedudukan D-Pad", + "dpad_size": "Saiz D-Pad", + "dpad_type": "Jenis D-Pad", + "enter_an_address": "Masukkan Alamat", + "game_full": "Permainan penuh atau tidak menerima.", + "game_shut_down": "Permainan telah ditutup.", + "hardware_buttons": "Butang Perkakasan", + "join_by_address": "Sertai melalui Alamat", + "lag": "Kelambatan: ${SECONDS} saat", + "reset": "Tetap semula ke lalai", + "run1": "Set 1", + "run2": "Set 2", + "searching": "Mencari permainan BombSquad...", + "searching_caption": "Tekan pada nama permainan untuk sertainya.\nPastikan anda pada rangkaian Wi-Fi yang sama.", + "start": "Mula", + "version_mismatch": "Versi tidak sepadan.\nPastikan BombSquad dan BombSquad Remote\nadalah verisi terkini dan cuba lagi." + }, + "removeInGameAdsText": "Buka kunci \"${PRO}\" di kedai untuk mengalih keluar iklan dalam permainan.", + "renameText": "Namakan semula", + "replayEndText": "Tamatkan Rakaman ulang", + "replayNameDefaultText": "Main Ulang Permainan Terakhir", + "replayReadErrorText": "Ralat semasa membaca fail ulangan.", + "replayRenameWarningText": "Ganti nama \"${REPLAY}\" selepas permainan jika anda mahu menyimpannya; jika tidak, ia akan ditimpa.", + "replayVersionErrorText": "Maaf, ulangan ini dibuat dengan cara yang berbeza\nversi permainan dan tidak boleh digunakan.", + "replayWatchText": "Tonton Main semula", + "replayWriteErrorText": "Ralat semasa menulis fail ulangan.", + "replaysText": "Main semula", + "reportPlayerExplanationText": "Gunakan emel ini untuk melaporkan penipuan, bahasa tidak sesuai, atau kelakuan kasar yang lain.\nSila huraikan di bawah:", + "reportThisPlayerCheatingText": "Penipu", + "reportThisPlayerLanguageText": "Bahasa tidak sesuai", + "reportThisPlayerReasonText": "Apakah yang anda ingin laporkan?", + "reportThisPlayerText": "Laporkan Pemain Ini", + "requestingText": "Meminta...", + "restartText": "Mula semula", + "retryText": "Cuba lagi", + "revertText": "Kembalikan", + "runText": "Lari", + "saveText": "Simpan", + "scanScriptsErrorText": "Ralat mengimbas skrip; lihat log untuk butiran.", + "scoreChallengesText": "Cabaran Skor", + "scoreListUnavailableText": "Senarai skor tidak tersedia.", + "scoreText": "Markah", + "scoreUnits": { + "millisecondsText": "Milisaat", + "pointsText": "Mata", + "secondsText": "Saat" + }, + "scoreWasText": "(telah ${COUNT})", + "selectText": "Pilih", + "seriesWinLine1PlayerText": "MEMENANGI", + "seriesWinLine1TeamText": "MEMENANGI", + "seriesWinLine1Text": "MENANGKAN", + "seriesWinLine2Text": "SIRI!", + "settingsWindow": { + "accountText": "Akaun", + "advancedText": "Lanjutan", + "audioText": "Audio", + "controllersText": "Kawalan", + "graphicsText": "Grafik", + "playerProfilesMovedText": "Peringatan: Profil Pemain telah dipindah ke tetingkap Akaun di menu utama.", + "titleText": "Tetapan" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(papan kekunci skrin yang ringkas dan mesra)", + "alwaysUseInternalKeyboardText": "Gunakan Papan Kekunci Dalaman", + "benchmarksText": "Penanda Aras & Ujian Tekanan", + "disableCameraGyroscopeMotionText": "Lumpuhkan Pergerakan Giroskop Kamera", + "disableCameraShakeText": "Lumpuhkan Goncangan Kamera", + "disableThisNotice": "(anda boleh mematikan pemberitahuan ini di tetapan lanjutan)", + "enablePackageModsDescriptionText": "(menghidupkan kecekapan mod tambahan tapi mematikan permainan rangkaian)", + "enablePackageModsText": "Hidupkan Pakej Mod Tempatan", + "enterPromoCodeText": "Masukkan Kod", + "forTestingText": "Peringatan: nilai ini hanya untuk ujian dan akan hilang apabila aplikasi ditutup.", + "helpTranslateText": "terjemahan ${APP_NAME} selain Inggeris adalah usaha sokongan\nkomuniti. Jika anda ingin membantu menyumbang atau memperbetulkan \nterjemahan, sila ke pautan di bawah. Terima kasih!", + "kickIdlePlayersText": "Keluarkan Pemain yang Duduk Diam", + "kidFriendlyModeText": "Mod Mesra (kurangkan kekerasan, dll)", + "languageText": "Bahasa", + "moddingGuideText": "Panduan Menge-mod", + "mustRestartText": "Anda perlu memula semula permainan untuk dapat berkesan.", + "netTestingText": "Ujian Rangkaian", + "resetText": "Tetap Semula", + "showBombTrajectoriesText": "Tunjukkan Trajektori Bom", + "showPlayerNamesText": "Tunjukkan Nama Pemain", + "showUserModsText": "Tunjukkan Pelipat Mod", + "titleText": "Lanjutan", + "translationEditorButtonText": "Penyunting Terjemahan ${APP_NAME}", + "translationFetchErrorText": "status terjemahan tidak tersedia", + "translationFetchingStatusText": "memeriksa status terjemahan...", + "translationInformMe": "Beritahu saya apabila bahasa saya perlu dikemaskini", + "translationNoUpdateNeededText": "bahasa semasa telah dikemaskini; sting aku yahoo", + "translationUpdateNeededText": "** bahasa semasa perlu dikemaskini **", + "vrTestingText": "Cubaan VR" + }, + "shareText": "Kongsi", + "sharingText": "Mengongsi...", + "showText": "Tunjukkan", + "signInForPromoCodeText": "Anda mesti log masuk ke akaun agar kod berkuat kuasa.", + "signInWithGameCenterText": "Untuk menggunakan akaun Game Center,\nlog masuk dengan aplikasi Game Center.", + "singleGamePlaylistNameText": "Cuma ${GAME}", + "singlePlayerCountText": "1 pemain", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Pemilihan watak", + "Chosen One": "Yang terhebat", + "Epic": "Permainan Mod Epik", + "Epic Race": "Perlumbaan Epik", + "FlagCatcher": "Tangkap Bendera", + "Flying": "Pemikiran gembira", + "Football": "Tangkap Galah", + "ForwardMarch": "Serangan", + "GrandRomp": "Penaklukan", + "Hockey": "Hoki", + "Keep Away": "Bawak Lari", + "Marching": "Berlari-lari", + "Menu": "Menu Utama", + "Onslaught": "Serangan", + "Race": "Lumba", + "Scary": "Raja Gunung Ledang", + "Scores": "Skrin Skor", + "Survival": "Penghapusan", + "ToTheDeath": "Kalah Mati", + "Victory": "Skrin Markah Akhir" + }, + "spaceKeyText": "space", + "statsText": "Statistik", + "storagePermissionAccessText": "Ini memerlukan akses storan", + "store": { + "alreadyOwnText": "Anda telah memiliki ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Buang iklan dan timbulan pembelian\n• Membuka kunci lebih banyak tetapan permainan\n• Juga termasuk:", + "buyText": "Beli", + "charactersText": "Watak", + "comingSoonText": "Akan Datang...", + "extrasText": "Tambahan", + "freeBombSquadProText": "BombSquad kini percuma, tapi sejak anda membelinya secara sah anda menerima\npenaiktarafan BombSquad Pro dan ${COUNT} tiket sebagai tanda terima kasih.\nNikmatilah ciri-ciri baru, dan terima kasih atas sokongan anda!\n- Eric", + "holidaySpecialText": "Istimewa Cuti Perayaan", + "howToSwitchCharactersText": "(pergi ke \"${SETTINGS} -> ${PLAYER_PROFILES}\" untuk urus & ubahsuai watak)", + "howToUseIconsText": "(cipta profil pemain global (di tetingkap akaun) untuk gunakan ini)", + "howToUseMapsText": "(gunakan peta ini di senarai main pasukan/bebas untuk semua anda)", + "iconsText": "Ikon", + "loadErrorText": "Tidak dapat memuatkan halaman.\nSila periksa sambungan internet.", + "loadingText": "memuat", + "mapsText": "Peta", + "miniGamesText": "Permainan Kecil", + "oneTimeOnlyText": "(satu masa sahaja)", + "purchaseAlreadyInProgressText": "Pembelian item ini dalam pembelian.", + "purchaseConfirmText": "Beli ${ITEM}?", + "purchaseNotValidError": "Pembelian tidak sah.\nHubungi ${EMAIL} jika ini disebabkan ralat.", + "purchaseText": "Beli", + "saleBundleText": "Jualan Banyak!", + "saleExclaimText": "Jualan!", + "salePercentText": "(${PERCENT}% potongan)", + "saleText": "BOSKUR", + "searchText": "Cari", + "teamsFreeForAllGamesText": "Pasukan / Permainan Percuma-untuk-Semua", + "totalWorthText": "*** Nila ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Naik taraf?", + "winterSpecialText": "Istimewa Musim Sejuk", + "youOwnThisText": "- anda memiliki ini -" + }, + "storeDescriptionText": "8 Kegilaan Permainan Pesta Pemain!\n\nMeletupkan rakan anda (atau komputer) dalam kejohanan permainan mini yang meletup seperti Capture-the-Flag, Bomber-Hockey, dan Epic-Slow-Motion-Death-Match! \n\nKawalan ringkas dan sokongan pengawal yang luas memudahkan sehingga 8 orang masuk ke dalam aksi; anda bahkan boleh menggunakan peranti mudah alih anda sebagai pengawal melalui aplikasi ‘BombSquad Remote’ percuma!\n\nBom Jauh! \n\nLihat www.froemling.net/bombsquad untuk maklumat lebih lanjut.", + "storeDescriptions": { + "blowUpYourFriendsText": "Meletupkan rakan anda.", + "competeInMiniGamesText": "Bersaing dalam permainan mini dari perlumbaan hingga terbang.", + "customize2Text": "Sesuaikan watak, permainan mini dan juga runut bunyi.", + "customizeText": "Sesuaikan watak dan buat senarai main permainan mini anda sendiri.", + "sportsMoreFunText": "Sukan lebih menyeronokkan dengan bahan letupan.", + "teamUpAgainstComputerText": "Bekerjasama dengan komputer." + }, + "storeText": "Kedai", + "submitText": "Hantar", + "submittingPromoCodeText": "Mengemukakan Kod...", + "teamNamesColorText": "Nama/Warna Pasukan...", + "telnetAccessGrantedText": "Akses telnet diaktifkan.", + "telnetAccessText": "Akses telnet dikesan; benarkan?", + "testBuildErrorText": "Binaan ujian ini tidak lagi aktif; sila periksa versi baru.", + "testBuildText": "Uji Bina", + "testBuildValidateErrorText": "Tidak dapat mengesahkan binaan ujian. (tiada sambungan net?)", + "testBuildValidatedText": "Binaan Ujian Disahkan; Sting aku yahoo!", + "thankYouText": "Terima kasih atas sokongan anda! Nikmati permainan!!", + "threeKillText": "PELEPASAN GAS TIGA KALI!!", + "timeBonusText": "Bonus Masa", + "timeElapsedText": "Masa Berlalu", + "timeExpiredText": "Masa Tamat", + "timeSuffixDaysText": "${COUNT}h", + "timeSuffixHoursText": "${COUNT}j", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Tip", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Rakan Karib", + "tournamentCheckingStateText": "Memeriksa keadaan kejohanan; sila tunggu...", + "tournamentEndedText": "Kejohanan ini telah berakhir. Yang baru akan dimulakan tidak lama lagi.", + "tournamentEntryText": "Kemasukan Kejohanan", + "tournamentResultsRecentText": "Keputusan Kejohanan Terkini", + "tournamentStandingsText": "Kedudukan Kejohanan", + "tournamentText": "Kejohanan", + "tournamentTimeExpiredText": "Masa Kejohanan Tamat", + "tournamentsDisabledWorkspaceText": "Kejohanan dilumpuhkan apabila ruang kerja aktif.\nUntuk mendayakan semula kejohanan, lumpuhkan ruang kerja anda dan mulakan semula.", + "tournamentsText": "Kejohanan", + "translations": { + "characterNames": { + "Agent Johnson": "Ejen Johnson", + "B-9000": "B-9000", + "Bernard": "Ted", + "Bones": "Si Kerangka", + "Butch": "Kobi", + "Easter Bunny": "Arnab Easter", + "Flopsy": "Gebu", + "Frosty": "Si Salji", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Gasar", + "Lee": "Lina", + "Lucky": "Tuah", + "Mel": "Wan", + "Middle-Man": "Badang", + "Minimus": "Minimus", + "Pascal": "Pingu", + "Pixel": "Pari", + "Sammy Slam": "Ali", + "Santa Claus": "Santa Klaus", + "Snake Shadow": "Shadow", + "Spaz": "Faz", + "Taobao Mascot": "Maskot Taobao", + "Todd McBurton": "Todd", + "Zoe": "Farz", + "Zola": "Zila" + }, + "coopLevelNames": { + "${GAME} Training": "Latihan ${GAME}.", + "Infinite ${GAME}": "${GAME} tanpa had", + "Infinite Onslaught": "Serangan Tak Terhingga", + "Infinite Runaround": "Larian Tak Terhingga", + "Onslaught Training": "Berserang latihan", + "Pro ${GAME}": "Pro ${GAME}", + "Pro Football": "Bola Sepak Pro", + "Pro Onslaught": "Berserang Pro", + "Pro Runaround": "Lari padang Pro", + "Rookie ${GAME}": "Bentes ${GAME}", + "Rookie Football": "Bola Sepak Baru", + "Rookie Onslaught": "Berserang baru", + "The Last Stand": "Berdiri Terakhir", + "Uber ${GAME}": "Food panda ${GAME}", + "Uber Football": "Bola Sepak Urban", + "Uber Onslaught": "Berserang Urban", + "Uber Runaround": "Lari padang Urban" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Jadilah orang yang terpilih untuk masa yang lama untuk menang.\nLawan untuk terpilih.", + "Bomb as many targets as you can.": "Bom seberapa banyak sasaran yang anda boleh.", + "Carry the flag for ${ARG1} seconds.": "Bawa bendera selama ${ARG1} saat.", + "Carry the flag for a set length of time.": "Bawa bendera untuk jangka masa yang ditetapkan.", + "Crush ${ARG1} of your enemies.": "Hancurkan ${ARG1} lawan anda.", + "Defeat all enemies.": "Kalahkan semua lawan.", + "Dodge the falling bombs.": "Elak bom yang jatuh.", + "Final glorious epic slow motion battle to the death.": "Pertempuran gerakan perlahan epik terakhir yang terkoncat hingga mati.", + "Gather eggs!": "Kumpul tolo!", + "Get the flag to the enemy end zone.": "Dapatkan bendera ke zon hujung musuh.", + "How fast can you defeat the ninjas?": "Seberapa pantas anda boleh mengalahkan ninja?", + "Kill a set number of enemies to win.": "Sepak segerombolan musuh untuk memenangi.", + "Last one standing wins.": "Kedudukan terakhir menang.", + "Last remaining alive wins.": "Kemenangan terakhir yang masih ada.", + "Last team standing wins.": "Kedudukan pasukan terakhir menang.", + "Prevent enemies from reaching the exit.": "Elakkan musuh daripada sampai ke pintu keluar.", + "Reach the enemy flag to score.": "Sampai ke bendera musuh untuk menerima mata.", + "Return the enemy flag to score.": "Kembalikan bendera musuh untuk menerima mata.", + "Run ${ARG1} laps.": "Telah berlari ${ARG1} pusingan.", + "Run ${ARG1} laps. Your entire team has to finish.": "Lari pusingan ${ARG1}. Mesti semua ahli pasukan sudah selesai.", + "Run 1 lap.": "Lari 1 pusingan", + "Run 1 lap. Your entire team has to finish.": "Lari 1 pusingan. Seluruh pasukan anda perlu selesai.", + "Run real fast!": "Lari macam pelesit!", + "Score ${ARG1} goals.": "Menjaringkan ${ARG1} gol.", + "Score ${ARG1} touchdowns.": "Skor ${ARG1} pendaratan.", + "Score a goal.": "Menjaringkan gol", + "Score a touchdown.": "Skorkan gol", + "Score some goals.": "Menjaringkan beberapa gol.", + "Secure all ${ARG1} flags.": "Lindungi semua bendera ${ARG1}.", + "Secure all flags on the map to win.": "Lindungi semua bendera pada peta untuk menang.", + "Secure the flag for ${ARG1} seconds.": "Selamatkan bendera dalam ${ARG1} saat", + "Secure the flag for a set length of time.": "Selamatkan bendera untuk jangka masa yang ditetapkan.", + "Steal the enemy flag ${ARG1} times.": "Curi bendera musuh ${ARG1} kali.", + "Steal the enemy flag.": "Curi bendera lawan.", + "There can be only one.": "Hanya boleh ada satu.", + "Touch the enemy flag ${ARG1} times.": "Sentuh bendera musuh sebanyak ${ARG1} kali.", + "Touch the enemy flag.": "Sentuh bendera musuh.", + "carry the flag for ${ARG1} seconds": "membawa bendera selama ${ARG1} saat", + "kill ${ARG1} enemies": "lempang musuh ${ARG1}", + "last one standing wins": "yang terakhir menang", + "last team standing wins": "pasukan terakhir berdiri menang", + "return ${ARG1} flags": "kembalikan bendera ${ARG1}.", + "return 1 flag": "pulangkan 1 bendera", + "run ${ARG1} laps": "pusingan ke ${ARG1} larian", + "run 1 lap": "lari 1 pusingan", + "score ${ARG1} goals": "menjaringkan ${ARG1} gol.", + "score ${ARG1} touchdowns": "skor ${ARG1} pendaratan", + "score a goal": "menjaringkan gol", + "score a touchdown": "skorkan gol", + "secure all ${ARG1} flags": "selamatkan semua bendera ${ARG1}.", + "secure the flag for ${ARG1} seconds": "selamatkan bendera dalam ${ARG1} saat", + "touch ${ARG1} flags": "sentuh ${ARG1} bendera.", + "touch 1 flag": "sentuh 1 bendera" + }, + "gameNames": { + "Assault": "Serangan", + "Capture the Flag": "Kibarkan Bendera", + "Chosen One": "Yang Terpilih", + "Conquest": "Penaklukan", + "Death Match": "Perlawanan Kematian", + "Easter Egg Hunt": "Pencarian Telur Easter", + "Elimination": "Penyingkiran", + "Football": "Ragbi", + "Hockey": "Hoki", + "Keep Away": "Berjauhan", + "King of the Hill": "Raja Bukit", + "Meteor Shower": "Hujan Meteor", + "Ninja Fight": "Perlawanan Ninja", + "Onslaught": "Penyerangan", + "Race": "Perlumbaan", + "Runaround": "Berlarian", + "Target Practice": "Praktis Sasaran", + "The Last Stand": "Yang Terakhir" + }, + "inputDeviceNames": { + "Keyboard": "Papan kekunci", + "Keyboard P2": "Papan kekunci P2" + }, + "languages": { + "Arabic": "Bahasa Arab", + "Belarussian": "Bahasa Belarus", + "Chinese": "Bahasa Cina", + "ChineseTraditional": "Bahasa Tradisional Cina", + "Croatian": "Bahasa Kroatia", + "Czech": "Bahasa Czech", + "Danish": "Bahasa Denmark", + "Dutch": "Bahasa Belanda", + "English": "Bahasa Inggeris", + "Esperanto": "Bahasa Esperanto", + "Filipino": "Filipina", + "Finnish": "Bahasa Finland", + "French": "Bahasa Perancis", + "German": "Bahasa Jerman", + "Gibberish": "Karut", + "Greek": "Bahasa Yunani", + "Hindi": "Bahasa Hindi", + "Hungarian": "Bahasa Hungari", + "Indonesian": "Bahasa Indonesia", + "Italian": "Bahasa Itali", + "Japanese": "Bahasa Jepun", + "Korean": "Bahasa Korea", + "Malay": "Melayu", + "Persian": "Bahasa Farsi", + "Polish": "Bahasa Poland", + "Portuguese": "Bahasa Portugis", + "Romanian": "Bahasa Romania", + "Russian": "Bahasa Rusia", + "Serbian": "Bahasa Serbia", + "Slovak": "Bahasa Slovak", + "Spanish": "Bahasa Sepanyol", + "Swedish": "Bahasa Sweden", + "Tamil": "Bahasa Tamil", + "Thai": "Bahasa Thai", + "Turkish": "Bahasa Turki", + "Ukrainian": "Bahasa Ukrain", + "Venetian": "Bahasa Venetian", + "Vietnamese": "Bahasa Vietnam" + }, + "leagueNames": { + "Bronze": "Gangsa", + "Diamond": "Mutiara", + "Gold": "Emas", + "Silver": "Perak" + }, + "mapsNames": { + "Big G": "G Besar", + "Bridgit": "Jambatan", + "Courtyard": "Halaman Mahkamah", + "Crag Castle": "Istana Batu", + "Doom Shroom": "Cendawan Malapetaka", + "Football Stadium": "Stadium Ragbi", + "Happy Thoughts": "Mimpi Indah", + "Hockey Stadium": "Stadium Hoki", + "Lake Frigid": "Tasik Beku", + "Monkey Face": "Muka Monyet", + "Rampage": "Amukan", + "Roundabout": "Bulatan", + "Step Right Up": "Langkah Ke Atas", + "The Pad": "Lapang", + "Tip Top": "Puncak Pangkat", + "Tower D": "Menara D", + "Zigzag": "Bengkang-bengkok" + }, + "playlistNames": { + "Just Epic": "Mod Epik Sahaja", + "Just Sports": "Sukan Sahaja" + }, + "scoreNames": { + "Flags": "Bendera", + "Goals": "Gol", + "Score": "Skor", + "Survived": "Terselamat", + "Time": "Masa", + "Time Held": "Masa Dijalankan" + }, + "serverResponses": { + "A code has already been used on this account.": "Kod telah digunakan pada akaun ini.", + "A reward has already been given for that address.": "Ganjaran telah pun diberikan untuk alamat itu.", + "Account linking successful!": "Pemautan akaun berjaya!", + "Account unlinking successful!": "Penyahpautan akaun berjaya!", + "Accounts are already linked.": "Akaun sudah dipautkan.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Paparan iklan mengacau tidak dapat disahkan.\nSila pastikan anda menjalankan versi permainan yang rasmi dan terkini.", + "An error has occurred; (${ERROR})": "Ralat telah berlaku; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Ralat telah berlaku; sila hubungi sokongan. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Ralat telah berlaku; sila hubungi support@froemling.net.", + "An error has occurred; please try again later.": "Ralat telah berlaku; sila cuba sebentar lagi.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Adakah anda pasti mahu memautkan akaun ini?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nPerkara ini tidak boleh diubah semula .!", + "BombSquad Pro unlocked!": "BombSquad Pro dibuka kunci!", + "Can't link 2 accounts of this type.": "Tidak dapat memautkan 2 akaun jenis ini.", + "Can't link 2 diamond league accounts.": "Tidak dapat memautkan 2 akaun liga berlian.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Tidak dapat memaut; akan melepasi maksimum ${COUNT} akaun terpaut.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Penipuan dikesan; markah dan hadiah digantung selama ${COUNT} hari.", + "Could not establish a secure connection.": "Tidak dapat mewujudkan sambungan selamat.", + "Daily maximum reached.": "Maksimum harian dicapai.", + "Entering tournament...": "Memasuki kejohanan...", + "Invalid code.": "Kod tidak sah.", + "Invalid payment; purchase canceled.": "Pembayaran tidak sah; pembelian dibatalkan.", + "Invalid promo code.": "Kod promosi tidak sah.", + "Invalid purchase.": "Pembelian tidak sah.", + "Invalid tournament entry; score will be ignored.": "Penyertaan kejohanan tidak sah; markah akan diabaikan.", + "Item unlocked!": "Item dibuka!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "MEMAUT DITOLAK. ${ACCOUNT} mengandungi\ndata penting yang akan KESEMUANYA HILANG.\nAnda boleh memaut dalam susunan yang bertentangan jika anda mahu\n(dan akan menghilangan data akaun INI sebagai ganti)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Pautkan akaun ${ACCOUNT} ke akaun ini?\nSemua data sedia ada pada ${ACCOUNT} akan hilang.\nPerkara ini tidak boleh diubah. Adakah anda pastis?", + "Max number of playlists reached.": "Bilangan maksimum senarai main dicapai.", + "Max number of profiles reached.": "Bilangan profil maksimum dicapai.", + "Maximum friend code rewards reached.": "Ganjaran kod rakan telah maksimum dicapai.", + "Message is too long.": "Mesej terlalu panjang.", + "No servers are available. Please try again soon.": "Tiada pelayan tersedia. Nanti cuba lagi, sebentar lagi.", + "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" berjaya dinaik taraf.", + "Profile could not be upgraded.": "Profil tidak dapat ditingkatkan.", + "Purchase successful!": "Pembelian berjaya!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Menerima ${COUNT} tiket untuk log masuk.\nKembali esok untuk menerima ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Kefungsian pelayan tidak lagi disokong dalam versi permainan ini;\nSila kemas kini kepada versi yang lebih baharu", + "Sorry, there are no uses remaining on this code.": "Maaf, tiada penggunaan yang tinggal pada kod ini.", + "Sorry, this code has already been used.": "Maaf, kod ini telah digunakan.", + "Sorry, this code has expired.": "Maaf, kod ini telah tamat tempoh.", + "Sorry, this code only works for new accounts.": "Maaf, kod ini hanya berfungsi untuk akaun baharu.", + "Still searching for nearby servers; please try again soon.": "Masih mencari pelayan berdekatan; sila cuba lagi nanti.", + "Temporarily unavailable; please try again later.": "Tidak tersedia buat sementara waktu; sila cuba sebentar lagi.", + "The tournament ended before you finished.": "Kejohanan tamat sebelum anda tamat.", + "This account cannot be unlinked for ${NUM} days.": "Akaun ini tidak boleh dinyahpautkan selama ${NUM} hari.", + "This code cannot be used on the account that created it.": "Kod ini tidak boleh digunakan pada akaun yang menciptanya.", + "This is currently unavailable; please try again later.": "Ini tidak tersedia pada masa ini; sila cuba sebentar lagi.", + "This requires version ${VERSION} or newer.": "Ini memerlukan versi ${VERSION} atau lebih baharu.", + "Tournaments disabled due to rooted device.": "Kejohanan dilumpuhkan kerana peranti root.", + "Tournaments require ${VERSION} or newer": "Kejohanan memerlukan ${VERSION} atau lebih baharu", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Nyahpaut ${ACCOUNT} daripada akaun ini?\nSemua data pada ${ACCOUNT} akan ditetapkan semula.\n(kecuali untuk pencapaian dalam kes tertentu)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "AMARAN: aduan penggodaaman telah dikeluarkan terhadap akaun anda.\nAkaun yang didapati menggodam akan diharamkan. Tolong main adil.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Adakah anda ingin memautkan akaun peranti anda ke akaun ini?\n\nAkaun peranti anda ialah ${ACCOUNT1}\nAkaun ini ialah ${ACCOUNT2}\n\nIni akan membolehkan anda mengekalkan data sedia ada anda.\nAmaran: ini tidak boleh dibaiki semula!", + "You already own this!": "Anda sudah memiliki ini!", + "You can join in ${COUNT} seconds.": "Anda boleh menyertai dalam ${COUNT} saat.", + "You don't have enough tickets for this!": "Anda tidak mempunyai tiket yang mencukupi untuk ini!", + "You don't own that.": "Anda tidak memilikinya.", + "You got ${COUNT} tickets!": "Anda mendapat ${COUNT} tiket!", + "You got a ${ITEM}!": "Anda mendapat ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Anda telah dinaikkan pangkat ke liga baharu; tahniah!", + "You must update to a newer version of the app to do this.": "Anda mesti mengemas kini kepada versi apl yang lebih baharu untuk melakukan ini.", + "You must update to the newest version of the game to do this.": "Anda mesti mengemas kini kepada versi terbaharu permainan untuk melakukan ini.", + "You must wait a few seconds before entering a new code.": "Anda mesti menunggu beberapa saat sebelum memasukkan kod baharu.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Anda menduduki #${RANK} dalam kejohanan terakhir. Terima kasih kerana bermain!", + "Your account was rejected. Are you signed in?": "Akaun anda telah ditolak. Adakah anda telah log masuk?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Salinan permainan anda telah diubah suai.\nSila kembalikan sebarang perubahan dan cuba lagi.", + "Your friend code was used by ${ACCOUNT}": "Kod rakan anda telah digunakan oleh ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minit", + "1 Second": "1 Saat", + "10 Minutes": "10 Minit", + "2 Minutes": "2 Minit", + "2 Seconds": "2 Saat", + "20 Minutes": "20 Minit", + "4 Seconds": "4 Saat", + "5 Minutes": "5 Minit", + "8 Seconds": "8 Saat", + "Allow Negative Scores": "Benarkan Skor Negatif", + "Balance Total Lives": "Baki Jumlah Nyawa", + "Bomb Spawning": "Pemijahan Bom", + "Chosen One Gets Gloves": "Yang Terpilih Dapat Sarung Tangan", + "Chosen One Gets Shield": "Yang Terpilih Dapat Perisai", + "Chosen One Time": "Masa Bagi Yg Terpilih", + "Enable Impact Bombs": "Dayakan Bom Kesan", + "Enable Triple Bombs": "Dayakan Triple Bombs", + "Entire Team Must Finish": "Seluruh Pasukan Mesti Selesai", + "Epic Mode": "Mod Epik", + "Flag Idle Return Time": "Tandakan Masa Pulang Terbiar", + "Flag Touch Return Time": "Tandakan Masa Pulang Sentuh", + "Hold Time": "Tahan Masa", + "Kills to Win Per Player": "Memukul untuk Menang Setiap Pemain", + "Laps": "Pusingan", + "Lives Per Player": "Nyawa Setiap Pemain", + "Long": "Panjang", + "Longer": "Lebih Panjang", + "Mine Spawning": "Pemijahan Periuk api", + "No Mines": "Tiada Periuk api", + "None": "Tiada", + "Normal": "Biasa", + "Pro Mode": "Mod Pro", + "Respawn Times": "Masa Kembali", + "Score to Win": "Skor untuk Menang", + "Short": "Pendek", + "Shorter": "Lebih pendek", + "Solo Mode": "Mod Solo", + "Target Count": "Kiraan Sasaran", + "Time Limit": "Masa Terhad" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} hilang kelayakan kerana ${PLAYER} pergi", + "Killing ${NAME} for skipping part of the track!": "Menerajang ${NAME} kerana melangkau sebahagian daripada trek!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Amaran kepada ${NAME}: turbo / butang-spamming akan memghentikan awak." + }, + "teamNames": { + "Bad Guys": "Musuh", + "Blue": "Biru", + "Good Guys": "Orang Baik", + "Red": "Merah" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Pukulan lari-lompat-putaran yang tepat pada masanya boleh menyepak dalam satu pukulan\ndan mendapat penghormatan sepanjang hayat daripada rakan-rakan anda.", + "Always remember to floss.": "Jangan lupa untuk floss.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Buat profil pemain untuk diri sendiri dan rakan anda\ndengan penampilan pilihan anda dan bukannya menggunakan nama secara rawak.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Kotak sumpahan mengubah anda menjadi bom masa yang berdetik.\nSatu-satunya ubat adalah dengan mengambil pek kesihatan.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Rupa mereka berbeza, tetapi kebolehan watak adalah sama,\njadi pilih sahaja yang mana satu yang paling anda sukai.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Tolong jangan sombong dengan perisai tenaga itu; anda masih boleh tercampak dari tebing.", + "Don't run all the time. Really. You will fall off cliffs.": "Jangan berlari sepanjang masa. Den koba ni. Anda akan jatuh dari tebing.", + "Don't spin for too long; you'll become dizzy and fall.": "Jangan berputar terlalu lama; anda akan menjadi pening dan jatuh.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Tahan sebarang butang untuk dijalankan. (Butang pencetus berfungsi dengan baik jika anda memilikinya)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Tahan mana-mana butang untuk dijalankan. Anda akan berjalan lebih cepat\ntetapi tidak akan menjadi lebih baik, jadi hati-hati dengan tebing.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Bom ais tidak begitu kuat, tetapi ia membeku\nsesiapa sahaja yang mereka pukul, menyebabkan mereka terdedah kepada kehancuran.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Jika seseorang mengangkat anda, tumbuk mereka dan mereka akan melepaskannya.\nIni juga berfungsi dalam kehidupan sebenar.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Jika anda kekurangan pengawal, pasang apl '${REMOTE_APP_NAME}'\npada peranti mudah alih anda untuk menggunakannya sebagai pengawal.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Jika anda mendapat bom melekit yang melekat pada anda, lompat dan putar dalam bulatan.\nAnda dapat goncangkan bom, atau jika tiada detik terakhir anda akan menghiburkan.", + "If you kill an enemy in one hit you get double points for it.": "Jika anda melempang musuh dalam satu pukulan anda mendapat mata berganda untuknya.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Jika anda menerima sumpahan, satu-satunya harapan anda untuk terus hidup adalah\ncari kuasa kesihatan dalam beberapa saat seterusnya.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Jika anda tinggal di satu tempat, habislah. Lari dan mengelak untuk bertahan..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jika anda mempunyai ramai pemain yang datang dan pergi, hidupkan 'auto-kick-idle-players'\ndi bawah tetapan sekiranya sesiapa terlupa meninggalkan permainan.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Jika peranti anda menjadi terlalu panas atau anda ingin menjimatkan kuasa bateri,\ntolak \"Visual\" atau \"Resolusi\" dalam Tetapan->Grafik", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Jika kadar bingkai anda berombak, cuba tolak peleraian\natau visual dalam tetapan grafik permainan.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Dalam Capture-the-Flag, bendera anda mesti berada di pangkalan anda untuk mata, Jika\npasukan lain hampir menang, curi bendera mereka boleh meperlahankan mereka.", + "In hockey, you'll maintain more speed if you turn gradually.": "Dalam hoki, anda akan mengekalkan kelajuan jika berpusing secara beransur-ansur.", + "It's easier to win with a friend or two helping.": "Lebih mudah untuk menang dengan seorang atau dua rakan bantu.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Lompat semasa anda melontar untuk melontarkan bom sehingga ke tahap tertinggi.", + "Land-mines are a good way to stop speedy enemies.": "Periuk api adalah cara yang baik untuk menghentikan musuh yang pantas.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Banyak benda boleh diangkat dan dilempar termasuk pemain lain. Melambung\nlawan anda dari tebing boleh menjadi strategi yang berkesan dan memuaskan emosi.", + "No, you can't get up on the ledge. You have to throw bombs.": "Tidak, anda tidak boleh bangun di atas belebas. Anda perlu baling bom.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Pemain boleh menyertai dan keluar di tengah-tengah kebanyakan permainan,\ndan anda juga boleh pasang dan cabut pengawal dengan cepat.", + "Practice using your momentum to throw bombs more accurately.": "Berlatih menggunakan momentum anda untuk melontar bom dengan lebih tepat.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Tumbukan lebih merosakkan lebih cepat penumbuk anda bergerak,\njadi cuba berlari, melompat dan berputar seperti orang tak siuman.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Berlari ke sana ke mari sebelum melontar bom\nuntuk 'whiplash' dan membuangnya lebih jauh.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Keluarkan sekumpulan musuh dengan\nmelancarkan bom berhampiran kotak TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Kepala adalah kawasan yang paling terdedah, jadi bom melekit\nkepada orang biasanya bermaksud game-over.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Tahap ini tidak pernah berakhir, tetapi skor tinggi di sini\nakan memberi anda penghormatan kekal di seluruh dunia.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Kekuatan lontaran adalah berdasarkan arah yang anda tuju.\nUntuk melemparkan sesuatu, jangan tuju ke sebarang arah.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Bosan dengan runut bunyi? Gantikan dengan pilihan anda sendiri!\nLihat Tetapan->Audio->Runut Bunyi", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Cuba 'Memasak' bom selama satu atau dua saat sebelum melontarkannya.", + "Try tricking enemies into killing eachother or running off cliffs.": "Cuba menipu musuh untuk memukul satu sama lain atau melarikan diri dari tebing.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Gunakan butang ambil untuk mengambil bendera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Bergerak ke sana ke mari untuk mendapatkan lebih jarak pada lontaran anda..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Anda boleh 'membidik' pukulan anda dengan berputar ke kiri atau kanan.\nIni berguna untuk mengetuk orang jahat dari tepi atau menjaringkan gol dalam hoki.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Anda boleh menilai bila bom akan meletup berdasarkan\nwarna percikan api dari fiusnya: kuning..oren..merah..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Anda boleh melontar bom lebih tinggi jika anda melompat sebelum melontar.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Anda menerima kesakitan apabila anda terhantuk kepala anda pada sesuatu,\njadi cuba untuk tidak memeningkan kepala anda.", + "Your punches do much more damage if you are running or spinning.": "Tumbukan anda menghasilkan lebih banyak kesakitan jika anda berlari atau berputar." + } + }, + "trophiesRequiredText": "Ini memerlukan sekurang-kurangnya ${NUMBER} trofi.", + "trophiesText": "Piala", + "trophiesThisSeasonText": "Trofi Musim Ini", + "tutorial": { + "cpuBenchmarkText": "Menjalankan tutorial pada kelajuan menggelikan (menguji kelajuan CPU)", + "phrase01Text": "Hi lombu", + "phrase02Text": "Selamat datang ke ${APP_NAME}!", + "phrase03Text": "Berikut ialah beberapa petua untuk mengawal watak anda:", + "phrase04Text": "Banyak perkaro dalam ${APP_NAME} berasaskan FIZIK.", + "phrase05Text": "Contohnya, apabila anda menumbuk,..", + "phrase06Text": "..kerosakan adalah berdasarkan kelajuan penumbuk anda.", + "phrase07Text": "Nampak taak? Kami tidak bergerak, jadi hampir tidak mencederakan ${NAME}.", + "phrase08Text": "Sekarang mari melompat dan berputar untuk mendapatkan lebih kelajuan.", + "phrase09Text": "Aah, itu lebih baik.", + "phrase10Text": "Berlari juga membantu.", + "phrase11Text": "Tekan dan tahan Mana-mana butang untuk lari.", + "phrase12Text": "Untuk pukulan yang lebih hebat, cuba berlari DAN berputar.", + "phrase13Text": "Umakkaw; maaf 'tentang itu ${NAME}.", + "phrase14Text": "Anda boleh mengambil dan membuang benda seperti bendera.. atau ${NAME}.", + "phrase15Text": "Akhir sekali, ada bom.", + "phrase16Text": "Melempar bom memerlukan latihan.", + "phrase17Text": "Aduh! Bukan satu balingan yang bagus.", + "phrase18Text": "Bergerak membantu anda melontar lebih jauh.", + "phrase19Text": "Melompat membantu anda melontar lebih tinggi.", + "phrase20Text": "\"Sebat\" bom anda untuk lontaran lebih lama.", + "phrase21Text": "Mengangar bom anda boleh menjadi rumit.", + "phrase22Text": "Iyam.", + "phrase23Text": "Cuba \"memasak\" fius selama satu atau dua saat.", + "phrase24Text": "Sting aku! Elok dimasak.", + "phrase25Text": "Dah, itu sahaja.", + "phrase26Text": "Sekarang pergi selamatkan abang Aziz, dekat bot!", + "phrase27Text": "Ingat latihan anda, dan jangan tingal solat lima waktu", + "phrase28Text": "...selamat maju jaya...", + "phrase29Text": "Semoga berjaya!", + "randomName1Text": "Syed", + "randomName2Text": "Ayien", + "randomName3Text": "Ilham", + "randomName4Text": "Abang Irfan", + "randomName5Text": "Jasini", + "skipConfirmText": "Taknak tengok tutorial? Ketik atau tekan untuk mengesahkan.", + "skipVoteCountText": "${COUNT}/${TOTAL} langkau undi", + "skippingText": "ponteng tutorial...", + "toSkipPressAnythingText": "(ketik atau tekan apa-apa untuk melangkau tutorial)" + }, + "twoKillText": "KENTUT BERGANDA!", + "unavailableText": "tidak ada", + "unconfiguredControllerDetectedText": "Pengawal tidak dikonfigurasikan dikesan:", + "unlockThisInTheStoreText": "Mangga mesti dibuka kunci di kedai.", + "unlockThisProfilesText": "Untuk membuat lebih daripada ${NUM} profil, anda memerlukan:", + "unlockThisText": "Untuk membuka kunci ini, anda memerlukan:", + "unsupportedHardwareText": "Maaf, perkakasan ini tidak disokong oleh binaan permainan ini.", + "upFirstText": "Bangun dahulu:", + "upNextText": "Seterusnya dalam permainan ${COUNT}:", + "updatingAccountText": "Mengemas kini akaun anda...", + "upgradeText": "Naik Taraf", + "upgradeToPlayText": "Buka kunci \"${PRO}\" dalam gedung di dalam permainan untuk mainkan ini.", + "useDefaultText": "Gunakan seperti Biasa", + "usesExternalControllerText": "Permainan ini menggunakan pengawal luaran untuk input.", + "usingItunesText": "Menggunakan Apl Muzik untuk runut bunyi...", + "v2AccountLinkingInfoText": "Untuk memautkan akaun V2, gunakan butang 'Urus Akaun'.", + "validatingTestBuildText": "Mengesahkan Binaan Ujian...", + "victoryText": "Kemenangan!", + "voteDelayText": "Anda tidak boleh memulakan undian lain selama ${NUMBER} saat", + "voteInProgressText": "Undian sedang dijalankan.", + "votedAlreadyText": "Anda sudah mengundi", + "votesNeededText": "${NUMBER} undian diperlukan", + "vsText": "lwn", + "waitingForHostText": "(menunggu ${HOST} untuk meneruskan)", + "waitingForPlayersText": "menunggu pemain menyertai...", + "waitingInLineText": "Menunggu dalam barisan (parti penuh)...", + "watchAVideoText": "Tonton Video", + "watchAnAdText": "Tengok iklan Adabi", + "watchWindow": { + "deleteConfirmText": "Padamkan \"${REPLAY}\"?", + "deleteReplayButtonText": "Padam\nMain semula", + "myReplaysText": "Tayangan Ulang Saya", + "noReplaySelectedErrorText": "Tiada Main Ulang Dipilih", + "playbackSpeedText": "Kelajuan Main Semula: ${SPEED}", + "renameReplayButtonText": "Namakan\nMain semula", + "renameReplayText": "Namakan semula \"${REPLAY}\" kepada:", + "renameText": "Namakan semula", + "replayDeleteErrorText": "Ralat memadamkan ulang tayang.", + "replayNameText": "Nama Main Semula", + "replayRenameErrorAlreadyExistsText": "Tayangan semula dengan nama itu sudah wujud.", + "replayRenameErrorInvalidName": "Tidak boleh menamakan semula main semula; nama tidak sah.", + "replayRenameErrorText": "Ralat menamakan main semula.", + "sharedReplaysText": "Main Semula Dikongsi", + "titleText": "Tonton", + "watchReplayButtonText": "Tonton\nMain Semula" + }, + "waveText": "Gelombang musuh", + "wellSureText": "Baiklah!", + "whatIsThisText": "Apakah Ini?", + "wiimoteLicenseWindow": { + "titleText": "Hak Cipta DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "Mendengarkan Wiimotes...", + "pressText": "Tekan butang Wiimote 1 dan 2 serentak.", + "pressText2": "Pada Wiimotes yang lebih baharu dengan Motion Plus terbina dalam, tekan butang 'sync' merah di bahagian belakang." + }, + "wiimoteSetupWindow": { + "copyrightText": "Hak Cipta DarwiinRemote", + "listenText": "Dengar", + "macInstructionsText": "Pastikan Wii anda dimatikan dan Bluetooth diaktifkan\npada Mac anda, kemudian tekan 'Dengar'. Sokongan Wiimote boleh\nmenjadi sedikit berkilat, jadi anda mungkin perlu mencuba beberapa kali\nsebelum anda mendapat sambungan.\n\nBluetooth sepatutnya boleh mengendalikan sehingga 7 peranti sekaligus,\nwalaupun perbatuan anda mungkin berbeza-beza.\n\nBombSquad menyokong Wiimotes asli, Nunchuks,\ndan Pengawal Klasik.\nWii Remote Plus yang baru kini berfungsi juga\ntetapi tidak dengan lampiran.", + "thanksText": "Terima kasih kepada team DarwiinRemote \nUntuk membuat ini mungkin.", + "titleText": "Persediaan Wiimote" + }, + "winsPlayerText": "${NAME} Menang!", + "winsTeamText": "${NAME} Menang!", + "winsText": "${NAME} Monang!", + "workspaceSyncErrorText": "Ralat menyegerakkan ${WORKSPACE}. Lihat log untuk butiran.", + "workspaceSyncReuseText": "Tidak dapat menyegerakkan ${WORKSPACE}. Menggunakan semula versi disegerakkan sebelumnya.", + "worldScoresUnavailableText": "Markah dunia tidak tersedia.", + "worldsBestScoresText": "Skor Terbaik Dunia", + "worldsBestTimesText": "Masa Terbaik Dunia", + "xbox360ControllersWindow": { + "getDriverText": "Dapatkan Pemandu", + "macInstructions2Text": "Untuk menggunakan alat kawalan tanpa wayar, anda juga memerlukan penerima\ndilengkapi dengan 'Xbox 360 Wireless Controller for Windows'. Satu penerima membolehkan anda menyambungkan sehingga 4 pengawal. \n\nPenting: Penerima 3rd-party tidak akan berfungsi dengan pemacu ini; \npastikan penerima mengatakan 'Microsoft' di atasnya, bukan 'XBOX 360'. \nMicrosoft tidak lagi menjualnya secara berasingan, jadi anda perlu mendapatkan pengawal atau cari di shopee.\n\nSekiranya anda menganggap ini berguna, pertimbangkan untuk memberi sumbangan kepada pemaju pemandu di laman webnya.", + "macInstructionsText": "Untuk menggunakan pengawal Xbox 360, anda perlu memasang\npemacu Mac boleh didapati di pautan di bawah.\nIa berfungsi dengan pengawal berwayar dan tanpa wayar.", + "ouyaInstructionsText": "Untuk menggunakan pengawal Xbox 360 berwayar dengan BombSquad, dengan\nmemasangkan ke port USB peranti anda. Anda boleh menggunakan hab USB\nuntuk menghubungkan pelbagai pengawal.\n\nUntuk menggunakan alat kawalan tanpa wayar,\nanda memerlukan penerima tanpa wayar, tersedia sebagai sebahagian daripada\n\"Pengawal tanpa wayar Xbox 360 untuk Windows\"\nbungkusan atau dijual secara berasingan. Setiap penerima dipasang ke port USB dan\nmembolehkan anda menyambungkan sehingga 4 pengawal tanpa wayar.", + "titleText": "Menggunakan Pengawal Xbox 360 dengan ${APP_NAME}:" + }, + "yesAllowText": "Ya, Benarkan!", + "yourBestScoresText": "Markah Terbaik Anda", + "yourBestTimesText": "Masa Terbaik Anda" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/persian.json b/dist/ba_data/data/languages/persian.json new file mode 100644 index 0000000..9e2396c --- /dev/null +++ b/dist/ba_data/data/languages/persian.json @@ -0,0 +1,1892 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "نام نمی‌تواند اموجی (شکلک) یا نویسه‌ های ویژه داشته باشد", + "accountProfileText": "(مشخصات حساب)", + "accountsText": "پروفایل ها", + "achievementProgressText": "${TOTAL}/${COUNT} :دستاوردها", + "campaignProgressText": "${PROGRESS} :[سخت]‎ پیشروی در بازی اصلی", + "changeOncePerSeason": ".فقط یک‌بار در هر فصل می‌توانید این مورد را تغییر دهید", + "changeOncePerSeasonError": "(روز تا فصل بعد‎ ${NUM}) برای تغییر این گزینه باید تا فصل بعد صبر کنید", + "customName": "نام سفارشی", + "googlePlayGamesAccountSwitchText": "اگه میخوای اکانت گوگلت رو استفاده کنی\nاستفاده کن اکانت گوگل پلی بازی های دیگت رو", + "linkAccountsEnterCodeText": "کد را وارد کنید", + "linkAccountsGenerateCodeText": "ایجاد کد", + "linkAccountsInfoText": "(به اشتراک گذاری پیشروی بین دستگاه‌های مختلف)", + "linkAccountsInstructionsNewText": "برای اتصال دو پروفایل، ابتدا یک کد در پروفایل اول بسازید\nسپس آن را در پروفایل دوم وارد کنید. پس از این کار \n.اطلاعات پروفایل دوم بین دو پروفایل به اشتراک گذاشته می‌شود\n(اطلاعات پروفایل اول از بین خواهد رفت)\n\n.پروفایل را به هم متصل کنید‎ ${COUNT} شما می‌توانید تا\nتوجه: تنها پروفایل‌هایی که مال خودتان است را\nبه هم متصل کنید! اگر به پروفایل دوستانتان وصل\n.شوید، نمی‌توانید همزمان آنلاین بازی کنید", + "linkAccountsInstructionsText": "برای اتصال دو حساب، در یکی از\nآن ها کدی ایجاد کرده \nو آن را در دیگری وارد کنید.\nپیشرفت ها و موجودی ترکیب خواهد شد.\nحساب را وصل کنید ${COUNT} شما می توانید.\n!توجه : فقط حساب هایی را وصل کنید که برای\n شماست\nاگر شما حساب دیگری را وصل کنید، شما توانایی این را ندارید که در یک زمان بازی کنید!\nاین عمل برگشت پذیر نیست، پس \nدقت کنید!", + "linkAccountsText": "متصل کردن حساب ها", + "linkedAccountsText": ":حساب های متصل شده", + "manageAccountText": "تنظیمات حساب کاربری", + "nameChangeConfirm": "تغییر کند؟‎ ${NAME} آیا نام شما به", + "resetProgressConfirmNoAchievementsText": "همهٔ پیشروی‌های شما در بخش همکاری و بالاترین امتیازات\nشما پاک خواهد شد. (به استثنای بلیت‌های شما)\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟", + "resetProgressConfirmText": "همهٔ پیشروی‌ها در بخش همکاری، دستاوردها\n.و امتیازات بالای شما پاک خواهد شد\n(به استثنای بلیت‌های شما)\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟", + "resetProgressText": "بازنشانی پیشروی", + "setAccountName": "تنظیم نام حساب", + "setAccountNameDesc": "نامی که می‌خواهید برای این حساب نمایش داده شود را انتخاب کنید\nمی‌توانید از یکی از نام‌های حساب‌های وصل‌شده استفاده کنید\nیا یک نام جدید بسازید", + "signInInfoText": "به حسابتان وصل شوید تا بلیت جمع کنید، آنلاین رقابت کنید \n.و پیشرفت خود را با دیگران به اشتراک بگذارید", + "signInText": "ورود به حساب", + "signInWithDeviceInfoText": "(یک حساب خودکار فقط از این دستگاه در دسترس می‌باشد)", + "signInWithDeviceText": "وصل شدن با حساب دستگاه", + "signInWithGameCircleText": "وصل شدن از طریق حوزهٔ بازی", + "signInWithGooglePlayText": "ورود با حساب بازی‌های گوگل", + "signInWithTestAccountInfoText": "(حساب میراثی؛ از حساب‌های دستگاه برای پیشروی استفاده می‌کند)", + "signInWithTestAccountText": "ورود با حساب آزمایشی", + "signInWithV2InfoText": "یک حساب کاربری که بر روی تمام سیستم عامل ها کار می کند", + "signInWithV2Text": "ورود به سیستم با حساب بمب اسکواد", + "signOutText": "خروج از حساب", + "signingInText": "در حال اتصال…", + "signingOutText": "در حال خروج…", + "ticketsText": "${COUNT} :بلیت‌ها", + "titleText": "حساب", + "unlinkAccountsInstructionsText": "یک حساب را برای جداسازی انتخاب کنید", + "unlinkAccountsText": "جداسازی حساب‌ها", + "unlinkLegacyV1AccountsText": "لغو پیوند حساب‌های قدیمی (V1)", + "v2LinkInstructionsText": "استفاده از این لینک برای ایجاد یک حساب کاربری و یا ورود به سیستم.", + "viaAccount": "(${NAME} از طریق حساب)", + "youAreSignedInAsText": ":با این حساب وصل شده‌اید" + }, + "achievementChallengesText": "چالش‌های دستاورددار", + "achievementText": "دستاورد", + "achievements": { + "Boom Goes the Dynamite": { + "description": ".نابود کن TNT سه حریف را با", + "descriptionComplete": "!نابود کردی TNT سه حریف را با", + "descriptionFull": "از بین ببر TNT با ${LEVEL} سه حریف را در", + "descriptionFullComplete": "از بین بردی TNT با ${LEVEL} سه حریف را در", + "name": "!ترکوندی" + }, + "Boxer": { + "description": "بدون استفاده از هیچ بمبی برنده شو", + "descriptionComplete": "بدون استفاده از بمب برنده شدی", + "descriptionFull": "را بدون استفاده از هیچ بمبی کامل کن ${LEVEL} مرحلهٔ", + "descriptionFullComplete": "را بدون استفاده از بمب کامل کردی ${LEVEL} مرحلهٔ", + "name": "مشت‌زن" + }, + "Dual Wielding": { + "descriptionFull": "(‏دو دستهٔ بازی وصل کن ‏(سخت‌افزاری یا نرم‌افزاری", + "descriptionFullComplete": "(دو دستهٔ بازی وصل کردی (سخت‌افزار یا نرم‌افزار", + "name": "دوگانه اداره کردن" + }, + "Flawless Victory": { + "description": "بدون ضربه خوردن برنده شو", + "descriptionComplete": "بدون ضربه خوردن برنده شدی", + "descriptionFull": "را بدون ضربه خوردن برنده شو ${LEVEL} مرحلهٔ", + "descriptionFullComplete": "را بدون ضربه خوردن برنده شدی ${LEVEL} مرحلهٔ", + "name": "پیروزی بی‌نقص" + }, + "Free Loader": { + "descriptionFull": "یک بازی به سبک تک به تک را با ۲+ بازیکن شروع کن", + "descriptionFullComplete": "یک بازی تک به تک را با ۲+ بازیکن شروع کردی", + "name": "بارگذار رایگان" + }, + "Gold Miner": { + "description": "شش حریف را با مین زمینی نابود کن", + "descriptionComplete": "شش حریف را با مین زمینی نابود کردی", + "descriptionFull": "با مین زمینی از بین ببر ${LEVEL} شش حریف را در مرحلهٔ", + "descriptionFullComplete": "با مین زمینی نابود کردی ${LEVEL} شش حریف را در مرحلهٔ", + "name": "مین‌گذار حرفه‌ای" + }, + "Got the Moves": { + "description": "بدون استفاده از مشت یا بمب برنده شو", + "descriptionComplete": "بدون استفاده از هیچ مشت یا بمبی برنده شدی", + "descriptionFull": "را بدون مشت یا بمب برنده شو ${LEVEL} بازی", + "descriptionFullComplete": "را بدون مشت یا بمب برنده شدی ${LEVEL} بازی", + "name": "عجب حرکتی" + }, + "In Control": { + "descriptionFull": "(یک دستهٔ بازی وصل کن (سخت‌افزاری یا نرم‌افزاری", + "descriptionFullComplete": "(یک دستهٔ بازی وصل کردی (سخت‌افزار یا نرم‌افزار", + "name": "تحت کنترل" + }, + "Last Stand God": { + "description": "‏۱۰۰۰ امتیاز بگیر", + "descriptionComplete": "‏۱۰۰۰ امتیاز گرفتی‏", + "descriptionFull": "‏۱۰۰۰ امتیاز بگیر ${LEVEL} در مرحلهٔ", + "descriptionFullComplete": "‏۱۰۰۰ امتیاز گرفتی‏ ${LEVEL} در مرحلهٔ", + "name": "${LEVEL} سَرور" + }, + "Last Stand Master": { + "description": "‏۲۵۰ امتیاز بگیر", + "descriptionComplete": "‏۲۵۰ امتیاز گرفتی", + "descriptionFull": "‏۲۵۰ امتیاز بگیر ${LEVEL} در مرحلهٔ", + "descriptionFullComplete": "‏۲۵۰ امتیاز گرفتی ${LEVEL} در مرحلهٔ", + "name": "${LEVEL} استاد" + }, + "Last Stand Wizard": { + "description": "‏۵۰۰ امتیاز بگیر", + "descriptionComplete": "‏۵۰۰ امتیاز گرفتی", + "descriptionFull": "‏۵۰۰ امتیاز بگیر ${LEVEL} در مرحلهٔ", + "descriptionFullComplete": "‏۵۰۰ امتیاز گرفتی ${LEVEL} در مرحلهٔ", + "name": "${LEVEL} جادوگر" + }, + "Mine Games": { + "description": "سه حریف را با مین زمینی از بین ببر", + "descriptionComplete": "سه حریف را با مین زمینی از بین بردی", + "descriptionFull": "با مین از بین ببر ${LEVEL} سه حریف را در مرحلهٔ", + "descriptionFullComplete": "با مین از بین بردی ${LEVEL} سه حریف را در مرحلهٔ", + "name": "بازی با مین" + }, + "Off You Go Then": { + "description": "سه حریف رو از زمین بنداز بیرون", + "descriptionComplete": "سه حریف رو از نقشه انداختی پایین", + "descriptionFull": "از نقشه بنداز پایین${LEVEL}سه حریف رو در مرحله ی", + "descriptionFullComplete": "از نقشه انداختی پایین ${LEVEL} سه حریف رو در مرحله ی", + "name": "حالا میتونی بری" + }, + "Onslaught God": { + "description": "پنج هزار امتیاز بگیر", + "descriptionComplete": "پنج هزار امتیاز گرفتی", + "descriptionFull": "بگیر${LEVEL}پنج هزار امتیاز در مرحله ی", + "descriptionFullComplete": "گرفتی${LEVEL}پنج هزار امتیاز در مرحله ی", + "name": "${LEVEL} خدا" + }, + "Onslaught Master": { + "description": "پونصد امتیاز بگیر", + "descriptionComplete": "پونصد امتیاز گرفتی", + "descriptionFull": "بگیر ${LEVEL} پونصد امتیاز در مرحله ی", + "descriptionFullComplete": "گرفتی ${LEVEL} پونصد امتیاز در مرحله ی", + "name": "${LEVEL} استاد" + }, + "Onslaught Training Victory": { + "description": "تمام موج ها را بگذران", + "descriptionComplete": "تمام موج ها را گذراندی", + "descriptionFull": "بگذران ${LEVEL} تمام موج ها رو در مرحله ی", + "descriptionFullComplete": "گذراندی ${LEVEL} تمام موج ها رو در مرحله ی", + "name": "${LEVEL} پیروزی" + }, + "Onslaught Wizard": { + "description": "هزار امتیاز بگیر", + "descriptionComplete": "هزار امتیاز گرفتی", + "descriptionFull": "بگیر ${LEVEL} هزار امتیاز در مرحله ی", + "descriptionFullComplete": "گرفتی ${LEVEL} هزار امتیاز در مرحله ی", + "name": "${LEVEL} جادوگر" + }, + "Precision Bombing": { + "description": "بدون گرفتن هیچ جعبه ای برنده شو", + "descriptionComplete": "بدون گرفتن هیچ جعبه ای برنده شدی", + "descriptionFull": "رو بدون گرفتن جعبه برنده شو ${LEVEL} مرحله ی", + "descriptionFullComplete": "رو بدون گرفتن جعبه برنده شدی ${LEVEL} مرحله ی", + "name": "بمب اندازی دقیق" + }, + "Pro Boxer": { + "description": "بدون استفاده از هر بمبی برنده شو", + "descriptionComplete": "بدون استفاده از هر بمبی برنده شدی", + "descriptionFull": "رو بدون استفاده از هر بمبی تمام کن ${LEVEL} مرحله ی", + "descriptionFullComplete": "رو بدون استفاده از هر بمبی تمام کردی ${LEVEL} مرحله", + "name": "مشت‌زن حرفه‌ای" + }, + "Pro Football Shutout": { + "description": "بدون اینکه اجازه بدی حریف امتیاز بگیره برنده شو", + "descriptionComplete": "بدون اینکه اجازه بدی حریف امتیاز بگیره برنده شدی", + "descriptionFull": "اجازه نده حریف امتیاز بگیره و برنده شو ${LEVEL} در مرحله", + "descriptionFullComplete": "اجازه ندادی حریف امتیاز بگیره و برنده شدی ${LEVEL} در مرحله", + "name": "${LEVEL} امتیاز ندادن" + }, + "Pro Football Victory": { + "description": "برنده شو", + "descriptionComplete": "! برنده شدی", + "descriptionFull": "برنده شو ${LEVEL} در مرحله", + "descriptionFullComplete": "برنده شدی ${LEVEL} در مرحله", + "name": "${LEVEL} پیروزی" + }, + "Pro Onslaught Victory": { + "description": "همه ی موج ها را بگذران", + "descriptionComplete": "همه ی موج ها را گذراندی", + "descriptionFull": "همه ی موج ها را بگذران ${LEVEL} در مرحله", + "descriptionFullComplete": "همه ی موج ها را گذراندی ${LEVEL} در مرحله", + "name": "${LEVEL} پیروزی" + }, + "Pro Runaround Victory": { + "description": "همه ی موج ها را بگذران", + "descriptionComplete": "همه ی موج ها را گذراندی", + "descriptionFull": "همه ی موج ها را بگذران ${LEVEL} در مرحله", + "descriptionFullComplete": "همه ی موج ها را گذراندی ${LEVEL} در مرحله", + "name": "${LEVEL} پیروزی" + }, + "Rookie Football Shutout": { + "description": "برنده شو و اجازه نده حریف امتیاز بگیره", + "descriptionComplete": "برنده شدی و اجازه ندادی حریف امتیاز بگیره", + "descriptionFull": "برنده شو و اجازه نده حریف امتیاز بگیره ${LEVEL} در مرحله", + "descriptionFullComplete": "برنده شدی و اجازه ندادی حریف امتیاز بگیره ${LEVEL} در مرحله", + "name": "${LEVEL} بدون امتیاز دادن" + }, + "Rookie Football Victory": { + "description": "برنده شو", + "descriptionComplete": "برنده شدی", + "descriptionFull": "برنده شو ${LEVEL} در مرحله", + "descriptionFullComplete": "برنده شدی ${LEVEL} در مرحله", + "name": "${LEVEL} پیروزی" + }, + "Rookie Onslaught Victory": { + "description": "همه ی موج ها را بگذران", + "descriptionComplete": "همه ی موج ها را گذراندی", + "descriptionFull": "همه ی موج ها را بگذران ${LEVEL} در مرحله", + "descriptionFullComplete": "همه ی موج ها را گذراندی ${LEVEL} در مرحله", + "name": "${LEVEL} پیروزی" + }, + "Runaround God": { + "description": "دو هزار امتیاز بگیر", + "descriptionComplete": "دو هزار امتیاز گرفتی", + "descriptionFull": "دو هزار امتیاز بگیر ${LEVEL} در مرحله", + "descriptionFullComplete": "دو هزار امتیاز گرفتی ${LEVEL} در مرحله", + "name": "${LEVEL} خدا" + }, + "Runaround Master": { + "description": "پانصد امتیاز بگیر", + "descriptionComplete": "پانصد امتیاز گرفتی", + "descriptionFull": "پونصد امتیاز بگیر ${LEVEL} در مرحله", + "descriptionFullComplete": "پونصد امتیاز گرفتی ${LEVEL} در مرحله", + "name": "${LEVEL} استاد" + }, + "Runaround Wizard": { + "description": "هزار امتیاز بگیر", + "descriptionComplete": "هزار امتیاز گرفتی", + "descriptionFull": "هزار امتیاز بگیر ${LEVEL} در مرحله", + "descriptionFullComplete": "هزار امتیاز گرفتی ${LEVEL} در مرحله", + "name": "${LEVEL} جادوگر" + }, + "Sharing is Caring": { + "descriptionFull": "بازی را با یک دوست به اشتراک بگذار", + "descriptionFullComplete": "بازی را با یک دوست به اشتراک گذاشتی", + "name": "به اشتراک‌گذاشتن یه‌جور مراقبت است" + }, + "Stayin' Alive": { + "description": "بدون از بین‌رفتن برنده‌شو", + "descriptionComplete": "بدون از بین‌رفتن برنده شدی", + "descriptionFull": "بدون از بین رفتن شو ${LEVEL} در مرحله", + "descriptionFullComplete": "بدون از بین رفتن برنده شدی ${LEVEL} در مرحله", + "name": "زنده ماندن" + }, + "Super Mega Punch": { + "description": "فقط با یک مشت، یکی رو نابود کن", + "descriptionComplete": "فقط با یک مشت، یه نفرو کشتی", + "descriptionFull": "فقط با یک مشت، یه نفر رو نابود کن ${LEVEL} در مرحله", + "descriptionFullComplete": "فقط با یک مشت، یه نفر رو کشتی ${LEVEL} در مرحله", + "name": "مشت فوق‌العاده" + }, + "Super Punch": { + "description": "با یک مشت، نصف جون یه نفر رو ببر", + "descriptionComplete": "با یک مشت، نصف جون یه نفر رو بردی", + "descriptionFull": "با یک مشت، نصف جون یه نفر رو ببر ${LEVEL} در مرحله", + "descriptionFullComplete": "با یک مشت، نصف جون یه نفر رو بردی ${LEVEL} در مرحله", + "name": "مشت فوق‌العاده" + }, + "TNT Terror": { + "description": "نابود کنTNT شش حریف رو با", + "descriptionComplete": "نابود کردی TNT شش حریف رو با", + "descriptionFull": "نابود کن TNT شش حریف رو با ${LEVEL} در مرحله", + "descriptionFullComplete": "نابود کردی TNT شش حریف رو با ${LEVEL} در مرحله", + "name": "TNT وحشت" + }, + "Team Player": { + "descriptionFull": "یه بازی تیمی با چهارتا از دوستات شروع کن", + "descriptionFullComplete": "یه بازی تیمی با چهارتا از دوستات شروع کردی", + "name": "بازیکن تیم" + }, + "The Great Wall": { + "description": "جلوی تک تک حریف ها رو بگیر", + "descriptionComplete": "جلوی تک تک حریف ها رو گرفتی", + "descriptionFull": "جلوی تک تک حریف ها رو بگیر ${LEVEL} در مرحله", + "descriptionFullComplete": "جلوی تک تک حریف ها رو گرفتی ${LEVEL} در مرحله", + "name": "دیوار بزرگ" + }, + "The Wall": { + "description": "جلوی تک تک حریف ها رو بگیر", + "descriptionComplete": "جلوی تک تک حریف ها رو گرفتی", + "descriptionFull": "جلوی تک تک حریف ها رو بگیر ${LEVEL} در مرحله", + "descriptionFullComplete": "جلوی تک تک حریف ها رو بگیر ${LEVEL} در مرحله", + "name": "دیوار" + }, + "Uber Football Shutout": { + "description": "برنده شو و اجازه نده حریف امتیاز بگیره", + "descriptionComplete": "برنده شدی و اجازه ندادی حریف امتیاز بگیره", + "descriptionFull": "برنده شو و اجازه نده حریف امتیاز بگیره ${LEVEL} در مرحله", + "descriptionFullComplete": "برنده شدی و اجازه ندادی حریف امتیاز بگیره ${LEVEL} در مرحله", + "name": "${LEVEL} بدون امتیاز دادن" + }, + "Uber Football Victory": { + "description": "برنده شو", + "descriptionComplete": "برنده شدی", + "descriptionFull": "برنده شو ${LEVEL} در مرحله", + "descriptionFullComplete": "برنده شدی ${LEVEL} در مرحله", + "name": "${LEVEL} پیروزی" + }, + "Uber Onslaught Victory": { + "description": "تمام موج ها رو بگذران", + "descriptionComplete": "تمام موج ها رو گذراندی", + "descriptionFull": "تمام موج ها رو بگذران ${LEVEL} در مرحله", + "descriptionFullComplete": "تمام موج ها رو گذراندی ${LEVEL} در مرحله", + "name": "${LEVEL} پیروزی" + }, + "Uber Runaround Victory": { + "description": "همه ی موج ها رو بگذران", + "descriptionComplete": "همه ی موج ها رو گذرونی", + "descriptionFull": "همه ی موج ها رو بگذران ${LEVEL} در مرحله", + "descriptionFullComplete": "همه ی موج ها رو گذروندی ${LEVEL} در مرحله", + "name": "${LEVEL} پیروزی" + } + }, + "achievementsRemainingText": "دستاورد های باقیمانده:", + "achievementsText": "دستاوردها", + "achievementsUnavailableForOldSeasonsText": "ببخشید، دستاوردهای مخصوص فصل گذشته در دسترس نیستند", + "activatedText": "${THING} فعال شد.", + "addGameWindow": { + "getMoreGamesText": "...بازی های بیشتر", + "titleText": "افزودن بازی" + }, + "allowText": "اجازه دادن", + "alreadySignedInText": "این حساب کاربری توسط یک دستگاه دیگر در حال استفاده می باشد.\nلطفا از حساب کاربری دیگری استفاده کنید یا بازی را \nدر بقیه دستگاه هایتان ببندید و دوباره امتحان کنید.", + "apiVersionErrorText": "نیاز داریم ${VERSION_REQUIRED} است. به ورژن ${VERSION_USED} بالا نمی آید. هدفش ${NAME} مدل", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(به صورت اتوماتیک فعال شود وقتی که هدفون متصل است)", + "headRelativeVRAudioText": "(صدای واقعیت مجازی(مخصوص هدفون", + "musicVolumeText": "صدای موسیقی", + "soundVolumeText": "صدای بازی", + "soundtrackButtonText": "تراک های موسیقی", + "soundtrackDescriptionText": "(موسیقی مورد نظر خود را برای هنگام بازی تعیین کنید)", + "titleText": "صدا" + }, + "autoText": "خودکار", + "backText": "بازگشت", + "banThisPlayerText": "این بازیکن را محروم کن", + "bestOfFinalText": "${COUNT} برترین های نهایی از", + "bestOfSeriesText": "${COUNT} برترین های مجموعه از", + "bestRankText": "است #${RANK} برترین رتبه ی شما", + "bestRatingText": "است ${RATING} بهترین امتیاز شما", + "bombBoldText": "بمب", + "bombText": "بمب", + "boostText": "تقویت", + "bsRemoteConfigureInAppText": "در خود برنامه تنظیم شده است ${REMOTE_APP_NAME} برنامه", + "buttonText": "دکمه", + "canWeDebugText": "آیا مایلید که بازی، اتوماتیک خرابی ها \nو باگ ها را به نویسنده ی بازی گزارش دهد ؟\n\nداده ای که فرستاده میشود حاوی هیچ یک از\n اطلاعات شخصی شما نیست و باعث میشود بازی روان تر شود", + "cancelText": "لغو", + "cantConfigureDeviceText": "قابل تنظیم نیست ${DEVICE} متاسفانه دستگاه", + "challengeEndedText": "این چالش به پایان رسیده است", + "chatMuteText": "گفتگو رو بیصدا کن", + "chatMutedText": "گفتگو بیصدا شد", + "chatUnMuteText": "گفتگو رو صدادار کن", + "choosingPlayerText": "<انتخاب بازیکن>", + "completeThisLevelToProceedText": "برای ادامه باید این مرحله را تمام کنید", + "completionBonusText": "پاداش به اتمام رساندن", + "configControllersWindow": { + "configureControllersText": "تنظیم دسته ها", + "configureKeyboard2Text": "تنظیمات کیبورد بازیکن دوم", + "configureKeyboardText": "تنظیمات کیبورد", + "configureMobileText": "گوشی همراه به‌عنوان دستهٔ بازی", + "configureTouchText": "تنظیمات صفحه لمسی", + "ps3Text": "PS3 دسته", + "titleText": "دسته ها", + "wiimotesText": "Wii دسته", + "xbox360Text": "Xbox 360 دسته" + }, + "configGamepadSelectWindow": { + "androidNoteText": "تذکر: پشتیبانی از دسته با توجه به دستگاه و نسخه ی اندرویدش متفاوت است", + "pressAnyButtonText": "یکی از دکمه های دسته ای که میخواهید\n تنظیم کنید را فشار دهید", + "titleText": "تنظیم دسته" + }, + "configGamepadWindow": { + "advancedText": "پیشرفته", + "advancedTitleText": "تنظیمات پیشرفته ی دسته", + "analogStickDeadZoneDescriptionText": "این گزینه را فعال کنید اگر بازیکن شما بی خودی حرکت میکند", + "analogStickDeadZoneText": "دکمه ی آنالوگ منطقه ی مرگ و میر", + "appliesToAllText": "(بر همه دسته ها از این نوع اعمال میشود)", + "autoRecalibrateDescriptionText": "(این گزینه را فعال کنید اگر بازیکن شما با تمام سرعت نمیدود)", + "autoRecalibrateText": "کالیبره ی اتوماتیک مجدد دکمه ی آنالوگ", + "axisText": "محور", + "clearText": "پاک کردن", + "dpadText": "dpad", + "extraStartButtonText": "یه دکمه ی شروع اضافی", + "ifNothingHappensTryAnalogText": "اگر اتفاقی نمی‌افتد، سعی کنید به دکمه‌ی آنالوگ ارجاع دهید", + "ifNothingHappensTryDpadText": "اگر اتفاقی نمیفتد، سعی کنید به دیپَد ازجاع دهید در عوض", + "ignoreCompletelyDescriptionText": "(از این دسته در برابر اثر گذاشتن بر بازی یا منوها جلوگیری کنید)", + "ignoreCompletelyText": "کاملاً نادیده گرفتن", + "ignoredButton1Text": "نادیده گرفتن دکمه 1", + "ignoredButton2Text": "نادیده گرفتن دکمه 2", + "ignoredButton3Text": "نادیده گرفتن دکمه 3", + "ignoredButton4Text": "نادیده گرفتن دکمه 4", + "ignoredButtonDescriptionText": "از این استفاده کنید تا از تاثیر گذاشتن دکمه ی \"خانه\" و \" همگامسازی\" بر واسط کاربر جلوگیری شود", + "pressAnyAnalogTriggerText": "دکمه ی آنالوگ را تکان دهید", + "pressAnyButtonOrDpadText": "هر دکمه ای یا دیپَد را فشار دهید", + "pressAnyButtonText": "یک دکمه ای را فشار بده", + "pressLeftRightText": "چپ یا راست را فشار بده", + "pressUpDownText": "بالا یا پایین را فشار بده", + "runButton1Text": "دکمه ی دویدن ۱", + "runButton2Text": "دکمه ی دویدن ۲", + "runTrigger1Text": "آنالوگ دویدن ۱", + "runTrigger2Text": "آنالوگ دویدن ۲", + "runTriggerDescriptionText": "دکمه های آنالوگ به شما این امکان را میدهند که در سرعت های مختلف بدویید", + "secondHalfText": "از این برای تنظیم نیمه ی دوم \"دو دسته\nدر یک دستگاه\" استفاده کنید و به صورت\nدسته ی جداگانه نمایش داده میشود", + "secondaryEnableText": "فعال", + "secondaryText": "دسته ی دوم", + "startButtonActivatesDefaultDescriptionText": "این گزینه را غیر فعال کنید اگر دکمه ی شروع شما بیشتر از بالا آوردن منو کاری انجام میدهد", + "startButtonActivatesDefaultText": "دکمه ی شروع حالت پیشفرض را فعال می کند", + "titleText": "تنظیمات دسته", + "twoInOneSetupText": "\"تنظیمات \"دو دسته در یک", + "uiOnlyDescriptionText": "(از این دسته برای وصل شدن به بازی جلوگیری کنید)", + "uiOnlyText": "به استفاده ی منو محدود شود", + "unassignedButtonsRunText": "تمام دکمه های تنظیم نشده برای دویدن", + "unsetText": "<تعیین نشده>", + "vrReorientButtonText": "دکمه ی تنظیم واقعیت مجازی" + }, + "configKeyboardWindow": { + "configuringText": "${DEVICE} پیکربندی", + "keyboard2NoteScale": 0.7, + "keyboard2NoteText": "تذکر:بیشتر کیبوردها فقط چند دکمه را همزمان میپذیرند\nپس داشتن یه کیبورد دیگه ممکنه مفید باشه\nاگر کیبورد متصل و جدای دیگه هم برای استفاده باشه\nتوجه کنید که هنوز هم لازمه دکمه های خاصی رو \nبرای دو کیبورد تنظیم کنید" + }, + "configTouchscreenWindow": { + "actionControlScaleText": "اندازه ی دکمه ها", + "actionsText": "اعمال", + "buttonsText": "کلید ها", + "dragControlsText": "<دکمه ها را بکشید و موقعیتشان را تعیین کنید>", + "joystickText": "دکمه ی حرکت", + "movementControlScaleText": "اندازه ی دکمه ی حرکت", + "movementText": "حرکت", + "resetText": "بازگرداندن", + "swipeControlsHiddenText": "مخفی کردن دکمه ی حرکت", + "swipeInfoText": "کمی طول میکشد به این نوع حرکت عادت کنید\nولی راحت باشید و بدون نگاه کردن به آن بازی کنید", + "swipeText": "حرکت جاروبی", + "titleText": "پیکربندی صفحه لمسی" + }, + "configureItNowText": "همین الآن تنظیم شود ؟", + "configureText": "پیکربندی", + "connectMobileDevicesWindow": { + "amazonText": "فروشگاه برنامه آمازون", + "appStoreText": "فروشگاه برنامه", + "bestResultsScale": 0.65, + "bestResultsText": "برای بهترین نتایج شما به یک شبکه وای‌فای بدون لَگ نیاز دارید\nبرای رفع لگ می‌توانید بقیه دستگاه‌های متصل به وای‌فای را خاموش کنید\nیا نزدیک مودم بازی کنید و یا با شبکه محلی به شبکه وصل شوید و میزبان\nبازی را مستقیماً وصل کنید", + "explanationText": "برای استفاده کردن از یک گوشی هوشمند یا تبلت به عنوان دسته ی بی سیم\nرا بر روی آن نصب کنید. هر تعداد دلخواه گوشی ${REMOTE_APP_NAME} برنامه\nتوسط وای فای به صورت رایگان وصل شوند ${APP_NAME} به برنامه", + "forAndroidText": "برای اندروید", + "forIOSText": "iOS برای", + "getItForText": "را برای آی‌اواس از فروشگاه برنامه‌های اپل ${REMOTE_APP_NAME} برنامهٔ\nیا برای اندروید از فروشگاه گوگل پلی و یا فروشگاه برنامهٔ آمازون دریافت کنید.", + "googlePlayText": "گوگل پلی", + "titleText": "استفاده از گوشی همراه به‌عنوان دسته" + }, + "continuePurchaseText": "ادامه می‌دهید؟ ${PRICE} با قیمت", + "continueText": "ادامه", + "controlsText": "دکمه‌ها", + "coopSelectWindow": { + "activenessAllTimeInfoText": "بر روی رده‌بندی کلی اِعمال نمی‌شود.", + "activenessInfoText": "این افزاینده در روزهایی که بازی می‌کنید افزایش می‌یابد\nو در روزهایی که بازی نمی‌کنید کاهش می‌یابد.", + "activityText": "فعالیت", + "campaignText": "عملیات", + "challengesInfoText": "برای کامل کردن مینی‌بازی‌ها جایزه بگیرید.\n\nهرگاه چالشی را انجام می‌دهید، جایزه‌ها و\nسختی مراحل افزایش می‌یابد و هرگاه چالشی\nباطل شود یا به هدر رود، کاهش می‌یابد.", + "challengesText": "چالش‌ها", + "currentBestText": "بهترین امتیاز کنونی", + "customText": "سفارشی", + "entryFeeText": "ورود", + "forfeitConfirmText": "هدر دادن این چالش؟", + "forfeitNotAllowedYetText": "این چالش هنوز نمی‌تواند از بین برود.", + "forfeitText": "هدر دادن", + "multipliersText": "افزاینده‌ها", + "nextChallengeText": "چالش بعدی", + "nextPlayText": "بازی بعدی", + "ofTotalTimeText": "${TOTAL} از", + "playNowText": "حالا بازی کنید", + "pointsText": "امتیازات", + "powerRankingFinishedSeasonUnrankedText": "(فصل بدون رده‌بندی پایان یافته)", + "powerRankingNotInTopText": "(نفر برتر نیستید ${NUMBER} بین)", + "powerRankingPointsEqualsText": "= امتیاز ${NUMBER}", + "powerRankingPointsMultText": "(x ${NUMBER} امتیاز)", + "powerRankingPointsText": "امتیاز ${NUMBER}", + "powerRankingPointsToRankedText": "(امتیاز ${REMAINING} از ${CURRENT})", + "powerRankingText": "رتبه‌بندی قدرت", + "prizesText": "جایزه‌ها", + "proMultInfoText": "ارتقا داده‌اند ${PRO} بازیکنانی که بازی را به\nافزایندهٔ امتیاز دریافت می‌کنند %${PERCENT}", + "seeMoreText": "...بیشتر", + "skipWaitText": "توقف انتظار", + "timeRemainingText": "زمان باقی‌مانده", + "toRankedText": "تا رتبه‌بندی شوید", + "totalText": "در مجموع", + "tournamentInfoText": "بر سر امتیاز بیشتر با بازیکنان در\nلیگ خود رقابت کنید.\n\nهنگامی که زمان مسابقه تمام شود، جایزه به\nنفرات برتر با امتیازهای بالا داده می‌شود.", + "welcome1Text": "خوش آمدید. شما می‌توانید ${LEAGUE} به لیگ\nبا گرفتن امتیاز، کامل کردن دستاوردها یا گرفتن جام\n.در مسابقات رتبهٔ خود را بهبود بخشید", + "welcome2Text": "همچنین می‌توانید از راه‌های مشابه بلیت جمع‌آوری کنید.\nبلیت‌ها می‌توانند برای باز کردن بازیکنان جدید، نقشه‌ها، مینی‌بازی‌ها یا برای ورود در مسابقه‌ها و موارد\nبیشتر مورد استفاده قرار گیرند.", + "yourPowerRankingText": "رتبه‌بندی قدرت شما:" + }, + "copyConfirmText": "در حافظه کلیپ بورد شما کپی شد.", + "copyOfText": "${NAME} کپی", + "copyText": "کپی کردن", + "createEditPlayerText": "<ایجاد/ویرایش بازیکن>", + "createText": "ساختن", + "creditsWindow": { + "additionalAudioArtIdeasText": "${NAME} صداهای افزوده، کارهای هنری و ایده‌های ابتدایی توسط", + "additionalMusicFromText": "${NAME} موسیقی‌های افزوده از", + "allMyFamilyText": "همهٔ دوستان و خانواده‌ام که با بازی نسخهٔ آزمایشی کمک کردند", + "codingGraphicsAudioText": "${NAME} کدگذاری، گرافیک و صدا توسط", + "languageTranslationsText": "مترجمان زبان‌ها:", + "legalText": "حقوقی:", + "publicDomainMusicViaText": "${NAME} موسیقی خاصهٔ مردم از", + "softwareBasedOnText": "میباشد ${NAME} این نرم افزار در بخش هایی الهام گرفته از", + "songCreditText": "اجرا شده و ${PERFORMER} توسط ${TITLE} آهنگ\n.می باشد ${COMPOSER}تنظیم شده و نوشته ی${ARRANGER}انتشار یافته، توسط${PUBLISHER}توسط\n${SOURCE} ادب و مهربانی", + "soundAndMusicText": "صدا & آهنگ:", + "soundsText": "(${SOURCE})صداها :", + "specialThanksText": "تشکر ویژه:", + "thanksEspeciallyToText": "${NAME} تشکر مخصوص از", + "titleText": "${APP_NAME} درباره", + "whoeverInventedCoffeeText": "هر کسی که قهوه را اختراع کرد!" + }, + "currentStandingText": "است #${RANK} رتبه ی کنونی شما", + "customizeText": "...سفارشی کردن", + "deathsTallyText": "مرگ ${COUNT}", + "deathsText": "مرگ و میرها", + "debugText": "رفع اشكال", + "debugWindow": { + "reloadBenchmarkBestResultsText": "تذکر: توصیه میشود که در قسمت تنظیمات>گرافیک، کیفیت بافت را آخر ببرید در هنگام تست این", + "runCPUBenchmarkText": "را بسنجید CPU عملکرد", + "runGPUBenchmarkText": "را بسنجید GPU عملکرد", + "runMediaReloadBenchmarkText": "بارگذاری رسانه را بسنجید", + "runStressTestText": "اجرای تست استرس", + "stressTestPlayerCountText": "شمارش بازیکن", + "stressTestPlaylistDescriptionText": "لیست بازی تست استرس", + "stressTestPlaylistNameText": "نام لیست بازی", + "stressTestPlaylistTypeText": "نوع لیست بازی", + "stressTestRoundDurationText": "مدت زمان دور", + "stressTestTitleText": "تست استرس", + "titleText": "معیارها و تست‌های استرس", + "totalReloadTimeText": "مجموع زمان بارگذاری: ${TIME} (برای جزئیات گزارش را مشاهده کنید)" + }, + "defaultGameListNameText": "به صورت پیشفرض ${PLAYMODE} لیست بازی", + "defaultNewGameListNameText": "من ${PLAYMODE} لیست بازی", + "deleteText": "پاک کن", + "demoText": "نسخه آزمایشی", + "denyText": "نپذیرفتن", + "deprecatedText": "ناراحت شد", + "desktopResText": "رزولوشن دسکتاپ", + "deviceAccountUpgradeText": "هشدار:\nشما با حساب کاربری دستگاه ثبت نام کرده اید (${NAME}).\nدر بروزرسانی های آینده حساب کاربری دستگاه حذف خواهد شد.\nبه حساب کاربری نسخه 2 بروزرسانی کنید اگر می خواهید روند را ادامه دهید.", + "difficultyEasyText": "آسان", + "difficultyHardOnlyText": "فقط حالت سخت", + "difficultyHardText": "سخت", + "difficultyHardUnlockOnlyText": ".این مرحله فقط در حالت سخت باز میشود\nفکر میکنی توان انجام دادنشو داری ؟", + "directBrowserToURLText": "لطفا آدرس زیر رو توی مرورگر خود باز کنید:", + "disableRemoteAppConnectionsText": "غیر فعال کردن ارتباطات از راه دور برنامه", + "disableXInputDescriptionText": "اجازه می‌دهد به بیش از 4 کنترل کننده اما ممکن است کار نکند.", + "disableXInputText": "غیرفعال کردن ورودی ایکس", + "doneText": "انجام شد", + "drawText": "برابر", + "duplicateText": "تکراری", + "editGameListWindow": { + "addGameText": "افزودن\nبازی", + "cantOverwriteDefaultText": "نمیشه لیست پیشفرض رو بازنویسی کرد", + "cantSaveAlreadyExistsText": "یک لیست بازی با همین نام وجود دارد", + "cantSaveEmptyListText": "نمیشه یه لیست خالی رو ذخیره کرد", + "editGameText": "ویرایش\nبازی", + "listNameText": "نام لیست بازی", + "nameText": "نام", + "removeGameText": "حذف\nبازی", + "saveText": "ذخیره لیست", + "titleText": "ویرایشگر لیست بازی" + }, + "editProfileWindow": { + "accountProfileInfoText": "این نمایۀ ویژه دارای یک نام\n.و تندیس بر اساس حسابتان است\n\n${ICONS}\n\nنمایه‌های سفارشی بسازید تا از نام‌ها\n.و تندیس‌های مختلف استفاده کرده باشید", + "accountProfileText": "(نمایهٔ حساب)", + "availableText": ".در دسترس میباشد \"${NAME}\" نام", + "characterText": "بازیکن", + "checkingAvailabilityText": "...\"${NAME}\" بررسی برای در دسترس بودن نام", + "colorText": "رنگ", + "getMoreCharactersText": "...بازیکن های بیشتر", + "getMoreIconsText": "... تندیس های بیشتر", + "globalProfileInfoText": "ضمانت می‌شود که نمایه‌های جهانی بازیکنان، نام‌های یکتا\n.دارند. همچنین یک تندیس سفارشی ضمیمهٔ آن‌ها است", + "globalProfileText": "(نمایهٔ جهانی)", + "highlightText": "بخش درخشان", + "iconText": "تندیس", + "localProfileInfoText": "نمایه‌های محلی بازیکنان تندیس ندارند و ضمانت نمی‌شود\nکه نام آن‌ها یکتا باشد. نمایه را جهانی کنید تا\n.نامی یکتا و تندیسی سفارشی داشته باشید", + "localProfileText": "(نمایهٔ محلی)", + "nameDescriptionText": "نام بازیکن", + "nameText": "نام", + "randomText": "تصادفی", + "titleEditText": "ویرایش نمایه", + "titleNewText": "نمایهٔ جدید", + "unavailableText": ".در دسترس نمی‌باشد؛ نامی دیگر امتحان کنید «${NAME}» نام", + "upgradeProfileInfoText": "این کار نام بازیکن شما را در جهان ذخیره میکند\n.و اجازه میدهد که تندیسی سفارشی به آن دهید", + "upgradeToGlobalProfileText": "ارتقا به نمایهٔ جهانی" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "نمیتوانید صدای پیشفرض را حذف کنید", + "cantEditDefaultText": ".نمیتوانید صدای پیشفرض رو دست کاری کنید. آن را کپی کنید یا یه جدید بسازید", + "cantOverwriteDefaultText": "نمیشه صدای پیشفرض رو بازنویسی کرد", + "cantSaveAlreadyExistsText": "یک صدا با همین نام وجود داره", + "defaultGameMusicText": "<موسیقی پیش فرض بازی>", + "defaultSoundtrackNameText": "صدای پیش فرض", + "deleteConfirmText": "حذف صدا با نام:\n\n'${NAME}'?", + "deleteText": "حذف\nصدا", + "duplicateText": "ایجاد کپی\nاز صدا", + "editSoundtrackText": "ویرایشگر صدا", + "editText": "ویرایش\nصدا", + "fetchingITunesText": "گرفتن صدا از لیست پخش برنامه", + "musicVolumeZeroWarning": "هشدار:درجه ی صدای موسیقی روی صفر است", + "nameText": "نام", + "newSoundtrackNameText": "${COUNT} صدای من", + "newSoundtrackText": "صدای جدید:", + "newText": "صدای\nجدید", + "selectAPlaylistText": "انتخاب یه لیست", + "selectASourceText": "منبع موسیقی", + "testText": "آزمایشی", + "titleText": "صداهای پس زمینه", + "useDefaultGameMusicText": "موسیقی پیشفرض بازی", + "useITunesPlaylistText": "لیست موسیقی برنامه", + "useMusicFileText": "(...و mp3)فایل موسیقی", + "useMusicFolderText": "پوشه ی فایل های موسیقی" + }, + "editText": "ویرایش", + "endText": "پایان", + "enjoyText": "لذت ببرید", + "epicDescriptionFilterText": "در حماسهٔ حرکت آهسته ${DESCRIPTION}", + "epicNameFilterText": "${NAME} حماسهٔ", + "errorAccessDeniedText": "دسترسی رد شد", + "errorDeviceTimeIncorrectText": "ساعت گوشی‌تان ${HOURS} ساعت خطا دارد.\nممکن است مشکل به‌وجود بیاید.\nلطفاً ساعت و منطقه زمانی گوشی‌تان را بررسی کنید.", + "errorOutOfDiskSpaceText": "حافظه جا ندارد", + "errorSecureConnectionFailText": "قادر به ایجاد اتصال ابری امن نیست. عملکرد شبکه ممکن است خراب شود.", + "errorText": "خطا", + "errorUnknownText": "خطای ناشناخته", + "exitGameText": "؟${APP_NAME} خروج از", + "exportSuccessText": "منتقل شد ${NAME}", + "externalStorageText": "حافظه ی خارجی", + "failText": "باختی", + "fatalErrorText": ".اوه اوه؛ فایلی خراب یا گم شده\nلطفا برنامه را از اول نصب کنید یا\n.در تماس باشید ${EMAIL} برای کمک با", + "fileSelectorWindow": { + "titleFileFolderText": "یه فایل یا پوشه را انتخاب نمایید", + "titleFileText": "یک فایل انتخاب نمایید", + "titleFolderText": "یک پوشه انتخاب نمایید", + "useThisFolderButtonText": "استفاده از این پوشه" + }, + "filterText": "فیلتر", + "finalScoreText": "امتیاز نهایی", + "finalScoresText": "امتیازهای نهایی", + "finalTimeText": "زمان نهایی", + "finishingInstallText": "...در حال اتمام نصب؛ یه لحظه", + "fireTVRemoteWarningText": "برای یک تجربه ی بهتر، از دسته ها*\n'${REMOTE_APP_NAME}' یا برنامه\nبر روی گوشی های هوشمند یا تبلت\n.خود استفاده کنید", + "firstToFinalText": "فینال ${COUNT} اولین در", + "firstToSeriesText": "مجموعه ${COUNT} اولین در", + "fiveKillText": "!!پنج نفر رو کشتی", + "flawlessWaveText": "!یک موج بدون عیب", + "fourKillText": "!!چهار نفر رو نابود کردی", + "friendScoresUnavailableText": "امتیاز دوستان در دسترس نیست", + "gameCenterText": "مرکز بازی", + "gameCircleText": "GameCircle", + "gameLeadersText": "نفر برتر بازی ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "نمیتوانید لیست بازی پیش فرض را حذف کنید", + "cantEditDefaultText": "نمیتوانید لیست بازی پیش فرض را دست کاری کنید. آن را کپی کنید یا یه لیست جدید بسازید", + "cantShareDefaultText": "شما نمیتونید لیست بازی پیش فرض رو به اشتراک بگذارید", + "deleteConfirmText": "؟ \"${LIST}\" حذف", + "deleteText": "حذف\nلیست بازی", + "duplicateText": "کپی کردن\nلیست بازی", + "editText": "ویرایش\nلیست بازی", + "newText": "لیست بازی\nجدید", + "showTutorialText": "نمایش آموزش", + "shuffleGameOrderText": "ترتیب تصادفی بازی ها", + "titleText": "${TYPE} تنظیم لیست های" + }, + "gameSettingsWindow": { + "addGameText": "افزودن بازی" + }, + "gamesToText": "${LOSECOUNT} بازی به ${WINCOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "فراموش نکنید: هردستگاه در یک گروه میتواند بیشتر\n.از یک بازیکن داشته باشد اگر به اندازه ی کافی دسته دارید", + "aboutDescriptionText": ".از این صفحات برای تشکیل یک گروه استفاده کنید\n\nگروه به شما این امکان را میدهد که بازی ها و مسابقات\n.را با دوستانتان بر روی گوشی های متفاوت بازی کنید\n\nدر گوشه ی بالای سمت راست استفاده کنید ${PARTY}از دکمه ی\n.تا با گروه چت و تعامل کنید\n(را هنگامی که در منو هستید فشار دهید${BUTTON} با دسته، دکمه ی)", + "aboutText": "درباره", + "addressFetchErrorText": "<خطا در اتصال به آدرس>", + "appInviteMessageText": "${APP_NAME}بلیط فرستاده در برنامه ی ${COUNT}برای شما ${NAME}", + "appInviteSendACodeText": "برایشان یه کد ارسال کن", + "appInviteTitleText": "${APP_NAME} دعوت به", + "bluetoothAndroidSupportText": "(کار میکنه با هر دستگاه اندرویدی که از بلوتوث پشتیبانی میکنه)", + "bluetoothDescriptionText": "میزبان/مهمان شدن یک گروه با بلوتوث :", + "bluetoothHostText": "میزبانی با بلوتوث", + "bluetoothJoinText": "ملحق شدن با بلوتوث", + "bluetoothText": "بلوتوث", + "checkingText": "...در حال چک کردن", + "copyCodeConfirmText": "کد در کلیپ بورد کپی شد.", + "copyCodeText": "کپی کردن کد", + "dedicatedServerInfoText": "برای نتیجه بهتر،یه سرور اختصاصی بزنید.به سایت زیر برین bombsquadgame.com/serverتا بفهمین چطوری", + "disconnectClientsText": "بازیکن را از ${COUNT} این کار ارتباط\nبازی قطع میکند. مطمئنید؟", + "earnTicketsForRecommendingAmountText": ".بلیط خواهند گرفت اگر این بازی را امتحان کنند ${COUNT} دوستانتان\n(بلیط به ازای هر کدامشان میگیرید${YOU_COUNT}و شما هم)", + "earnTicketsForRecommendingText": "به اشتراک گذاری بازی\nبرای بلیط های رایگان", + "emailItText": "ایمیلش کن", + "favoritesSaveText": "ذخیره به‌عنوان مورد علاقه", + "favoritesText": "مورد علاقه‌ها", + "freeCloudServerAvailableMinutesText": "سرور ابری رایگان بعدی در عرض ${MINUTES} دقیقه در دسترس است.", + "freeCloudServerAvailableNowText": "!سرور ابری رایگان در دسترس است", + "freeCloudServerNotAvailableText": ".سرورهای ابری رایگان در دسترس نیست", + "friendHasSentPromoCodeText": "${NAME}از طرف ${APP_NAME}بلیطِ بازی ${COUNT}", + "friendPromoCodeAwardText": ".بلیط خواهید گرفت هر بار که استفاده شود${COUNT}شما", + "friendPromoCodeExpireText": ".ساعت منقضی میشود و تنها بر روی بازیکنان جدید کار میکند${EXPIRE_HOURS}این کد در", + "friendPromoCodeInstructionsText": ".را باز کنید و به قسمت تنظیمات>پیشرفته>وارد کردن کد بروید${APP_NAME}برای استفاده از کد، برنامه\n.سر بزنید تا لینک دانلود بازی برای سیستم عامل های مختلف بازی را بگیرید BombSquadgame.com به سایت", + "friendPromoCodeRedeemLongText": ".بلیط رایگان به دست آورند${COUNT}نفر میتوانند از این کد استفاده کنند تا${MAX_USES}", + "friendPromoCodeRedeemShortText": ".بلیط در بازی بگیرید${COUNT}با این کد میتوانید", + "friendPromoCodeWhereToEnterText": "(در بخش تنظیمات>پیشرفته>وارد کردن کد)", + "getFriendInviteCodeText": "گرفتن کد برای دعوت دوستان", + "googlePlayDescriptionText": ":دعوت از بازیکنان گوگل پلی برای ملحق شدن به گروه شما", + "googlePlayInviteText": "دعوت", + "googlePlayReInviteText": "بازیکن از گوگل پلی در گروه شما هستند${COUNT}\n.که ارتباط‌شان قطع می‌شود اگر یک دعوت جدید را شروع کنید\n.آن ها را هم در دعوت جدید، ضمیمه کنید", + "googlePlaySeeInvitesText": "دیدن دعوت ها", + "googlePlayText": "گوگل پلی", + "googlePlayVersionOnlyText": "(Android/Google Play ورژن)", + "hostPublicPartyDescriptionText": "میزبانی یک سرور عمومی", + "hostingUnavailableText": "میزبانی در دسترس نیست", + "inDevelopmentWarningText": ":تذکر\n\n.بازی شبکه‌ای یک ویژگی جدید و درحال گسترشه\nاکنون شدیداً توصیه می‌شود همه بازیکنان\n.در یک شبکه وای‌فای مشترک باشند", + "internetText": "اینترنت", + "inviteAFriendText": "رفیقات این بازی رو ندارند؟ دعوتشون کن\n.بلیط رایگان بگیرند${COUNT}بیان بازی کننده و", + "inviteFriendsText": "دعوت دوستان", + "joinPublicPartyDescriptionText": "پیوستن به سرور های عمومی", + "localNetworkDescriptionText": "به یک سرور دیگر از طریق LAN , Bluetooth , etc بپیوندید", + "localNetworkText": "شبکه محلی", + "makePartyPrivateText": "گروه من رو از عمومی خارج کن", + "makePartyPublicText": "گروه بازی من رو عمومی کن", + "manualAddressText": "آدرس", + "manualConnectText": "وصل شدن", + "manualDescriptionText": ":ملحق شدن به یک گروه با آدرس", + "manualJoinSectionText": "پیوستن با نشانی", + "manualJoinableFromInternetText": ":کسی میتوانداز طریق اینترنت به شما ملحق شود؟", + "manualJoinableNoWithAsteriskText": "خیر*", + "manualJoinableYesText": "بلی", + "manualRouterForwardingText": "را به آدرس محلی بفرستد${PORT} برای حل این مشکل، روتر خود را تنظیم کنید تا یو دی پی پورت", + "manualText": "بطور دستی", + "manualYourAddressFromInternetText": ":آدرس شما در اینترنت", + "manualYourLocalAddressText": ":آدرس محلی شما", + "nearbyText": "افراد نزدیک", + "noConnectionText": "<اتصال برقرار نیست>", + "otherVersionsText": "(نسخه های دیگر)", + "partyCodeText": "کد گروه", + "partyInviteAcceptText": "پذیرفتن", + "partyInviteDeclineText": "نپذیرفتن", + "partyInviteGooglePlayExtraText": "(صفحه گوگل‌پلی را در صفحه \"شبکه با دوستان\" ببینید)", + "partyInviteIgnoreText": "نادیده گرفتن", + "partyInviteText": "شما را دعوت کرده${NAME} \nتا به گروهشان ملحق شوید", + "partyNameText": "نام گروه", + "partyServerRunningText": ".سرور گروه شما در حال اجراست", + "partySizeText": "اندازه دسته", + "partyStatusCheckingText": "در حال چک کردن وضعیت...", + "partyStatusJoinableText": "گروه شما حالا دیگه از طریق اینترنت قابل اتصال برای بقیه است.", + "partyStatusNoConnectionText": "عدم توانایی برقراری ارتباط با سرور", + "partyStatusNotJoinableText": "گروه شما قابل اتصال از طریق اینترنت نیست", + "partyStatusNotPublicText": "گروه بازی شما در اینترنت عمومی نیست", + "pingText": "پینگ", + "portText": "درگاه", + "privatePartyCloudDescriptionText": ".گروه‌های خصوصی بر روی سرورهای ابری اختصاصی اجرا می شوند; و نیازی به پیکربندی روتر/مودم نیست", + "privatePartyHostText": "میزبانی گروه خصوصی", + "privatePartyJoinText": "ملحق شدن به سرور خصوصی", + "privateText": "خصوصی", + "publicHostRouterConfigText": "این ممکن است نیاز به پیکربندی انتقال پورت در روتر شما داشته باشد. برای یک گزینه آسانتر ، یک سرور خصوصی برگزار کنید.", + "publicText": "عمومی", + "requestingAPromoCodeText": "...درخواست یک کد", + "sendDirectInvitesText": "ارسال دعوت مستقیم", + "shareThisCodeWithFriendsText": ":اشتراک این کد با دوستان", + "showMyAddressText": "آدرس من رو نشون بده", + "startHostingPaidText": "${COST} میزبانی اکنون برای", + "startHostingText": "میزبان", + "startStopHostingMinutesText": "شما می توانید میزبانی رایگان را برای ${MINUTES}  دقیقه دیگر شروع کرده و متوقف کنید.", + "stopHostingText": "میزبانی را متوقف کنید", + "titleText": "شبکه با دوستان", + "wifiDirectDescriptionBottomText": "داشته باشند حتماً میتونید ازش استفاده کنندWi-Fi Direct اگر دستگاه هاتون قابلیت\nو به یکدیگر وصل شوند.وقتی که دستگاه ها بهم وصل شدند میتوانید اینجا در صفحه ی\nشبکه محلی گروه تشکیل دهید.دقیقاً مثل وصل شدن از طریق وای فای معمولی\n\n.هم میزبان شود${APP_NAME}میزبان میشود درWi-Fi Directبرای گرفتن بهترین نتیجه،کسی که در", + "wifiDirectDescriptionTopText": "استفاده کرد تا دستگاه های اندرویدی را مستقیماً بهم وصل کرد بدونWi-Fi Directمیشود از\n.نیاز به شبکه ی وای فای.این روش برای اندروید۴.۲ و بالاتر عالی است\n\nبگردیدWi-Fi Directبرای استفاده از این روش، تنظیمات وای فای را باز کنید و دنبال", + "wifiDirectOpenWiFiSettingsText": "بازکردن تنظیمات وای فای", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(سیستم عامل های مختلف میتوانند به یکدیگر متصل شوند)", + "worksWithGooglePlayDevicesText": "(سازگار با تمام دستگاه های دارای ورژن گوگل پلی ایِ این بازی)", + "youHaveBeenSentAPromoCodeText": ":برایتان ارسال شده است${APP_NAME}یک کد تبلیغی از بازی" + }, + "getTicketsWindow": { + "freeText": "!مجانی", + "freeTicketsText": "بلیط های رایگان", + "inProgressText": ".یک تراکنش در حال جریان است؛ لطفاً چند لحظه بعد تلاش کنید", + "purchasesRestoredText": ".خریدهای شما بازگردانی شدند", + "receivedTicketsText": "!بلیط گرفتی${COUNT}", + "restorePurchasesText": "بازگردانی خریدهایتان", + "ticketPack1Text": "پک کوچک بلیط", + "ticketPack2Text": "پک متوسط بلیط", + "ticketPack3Text": "پک بزرگ بلیط", + "ticketPack4Text": "پک خیلی بزرگ بلیط", + "ticketPack5Text": "پک ماموتی بلیط", + "ticketPack6Text": "پک نهایی بلیط", + "ticketsFromASponsorText": "در ازای ${COUNT} بلیت\nیک آگهی ببینید", + "ticketsText": "بلیط${COUNT}", + "titleText": "بلیط بگیرید", + "unavailableLinkAccountText": ".ببخشید،خرید به وسیله ی این دستگاه در دسترس نمیباشد\nمیتوانید حسابتان بر روی این دستگاه را به حسابی در دستگاهی\n.دیگر متصل کنید و آنجا خرید خود را انجام دهید", + "unavailableTemporarilyText": "در حال حاضر در دسترس نمیباشد. لطفا بعدا دوباره امتحان کنید", + "unavailableText": "متاسفانه , دردسترس نیست", + "versionTooOldText": "متاسفم،این ورژن بازی خیلی قدیمی است. لطفا بازی را آپدیت کنید", + "youHaveShortText": "دارید ${COUNT} شما", + "youHaveText": ".بلیط دارید ${COUNT} شما" + }, + "googleMultiplayerDiscontinuedText": "متأسفیم ، سرویس چند نفره Google دیگر در دسترس نیست.\nمن در اسرع وقت در حال جایگزینی هستم.\nتا آن زمان ، لطفاً روش اتصال دیگری را امتحان کنید.", + "googlePlayPurchasesNotAvailableText": "خرید های گوگل‌پلی در دسترس نیستند.\nاحتمالا باید برنامه‌ی استور خود را بروز‌رسانی کنید.", + "googlePlayServicesNotAvailableText": ".سرویس گوگل پلی در دسترس نیست\n.بعضی عملکرد های برنامه ممکن غیرفعال باشند", + "googlePlayText": "گوگل پلی", + "graphicsSettingsWindow": { + "alwaysText": "همیشه", + "fullScreenCmdText": "تمام صفحه (Cmd-F)", + "fullScreenCtrlText": "تمام صفحه (Ctrl-F)", + "gammaText": "گاما", + "highText": "زیاد", + "higherText": "بالاتر", + "lowText": "کم", + "mediumText": "معمولی", + "neverText": "هرگز", + "resolutionText": "رزولوشن", + "showFPSText": "نمایش عدد فریم بر ثانیه", + "texturesText": "بافت", + "titleText": "گرافیک", + "tvBorderText": "مرزبندی تلویزیونی", + "verticalSyncText": "انطباق عمودی", + "visualsText": "کیفیت تصویر" + }, + "helpWindow": { + "bombInfoText": "- بمب -\nقوی تر از مشته امامیتونه\n.برای خودتون هم خطرناک باشه\nدر بهترین زمان ممکن قبل از اینکه\n.در دست خودتون بترکه، پرتش بدید", + "canHelpText": "میتونه به شما کمک کنه${APP_NAME}", + "controllersInfoText": "بازی کنید و یا${APP_NAME}میتوانید توسط شبکه با دوستانتان\n.روی یک دستگاه بازی کنید اگر به اندازه ی کافی دسته دارید\nاز این تنوع پشتیبانی میکند؛ شما حتی میتوانید${APP_NAME}\nاز گوشی های هوشمند به عنوان دسته استفاده کنید از طریق برنامه\n.برای اطلاعات بیشتر به تنظیمات>کنترلرها بروید.${REMOTE_APP_NAME}", + "controllersInfoTextRemoteOnly": "شما میتونید ${APP_NAME} رو همراه دوستانتان به صورت اینترنتی ، یا\nبا استفاده از نرم‌افزار '${REMOTE_APP_NAME}' گوشیتون رو\nبه دسته بازی تبدیل کنید تا همه با هم در یک گوشی بازی کنید.", + "controllersText": "کنترلرها", + "controlsSubtitleText": ":شما چندتا حرکت اساسی داره ${APP_NAME} بازیکن", + "controlsText": "کنترل‌ها", + "devicesInfoText": "نسخه وی آر ${APP_NAME} میتونه با شبکه با\n نسخه معمولی بازی کنه، پس تلفن یا تبلت \nیا کامپیوتر اضافیتونو آماده کنید و بازیو شروع کنید.\n حتی وقتی بخواین فقط کاری کنین که چن نفر از \nبیرون بتونن بازیو تماشا کنن هم بکار میاد.", + "devicesText": "دستگاه‌ها", + "friendsGoodText": "داشتن چنتا ازینا خیلی خوبه. ${APP_NAME} حالش بیشتره وقتی با چن نفر\nبازی بشه و میتونه همزمان تا 8 نفر ساپورت کنه که این قضیه ما رو میبره سمت:", + "friendsText": "دوستان", + "jumpInfoText": "پرش\nبرای پریدن ازاین دکمه کمک بگیرید\n همچنین پریدن قبل از پرتاب بمب و\nهمزمان بامشت بسیار در بازی بکارمیره", + "orPunchingSomethingText": "یا بهش مشت بزنی یا از یه بلندی پرتش کنی و توی راه که داره پرت میشه با یه بمب چسبونکی بترکونیش.", + "pickUpInfoText": "بلند کردن\nمیتونید هر فرد یا بمب یا هر چیزی رو\nاز زمین بلند و پرتاب کنید,حتی \nمیتونید بازیکنان رو از زمین بیرون بندازین", + "powerupBombDescriptionText": "به شما اجازه پرتاب هر بار سه بمب\nرو پشت سر هم همزمان میده", + "powerupBombNameText": "سه بمب", + "powerupCurseDescriptionText": "بهتره اینو نگیرین چون طی چند ثانیه اگه\nبه جعبه درمان نرسین منفجر میشین", + "powerupCurseNameText": "نابودگر", + "powerupHealthDescriptionText": "این جعبه درمان و خون های از دست \nرفته رو بر میگردونه و پر میکنه", + "powerupHealthNameText": "جعبه درمان", + "powerupIceBombsDescriptionText": "با این بمب های یخی میتونید حریف ها\nرو منجمد و آسیب پذیر کنید ولی بهتر خودتون\nتوی نزدیکی انفجار این بمب ها قرار نگیرین", + "powerupIceBombsNameText": "بمب یخی", + "powerupImpactBombsDescriptionText": "بهش میگن بمب فعال‌شونده تا به چیزی برخورد\nنکنن منفجر نمیشن", + "powerupImpactBombsNameText": "بمب فعال‌شونده", + "powerupLandMinesDescriptionText": "با این جعبه به شما سه تا مین\nداده میشه که تا وقتی پرتاب بشن\nتا چیزی روشون میخوره منفجر میشن", + "powerupLandMinesNameText": "مین زمینی", + "powerupPunchDescriptionText": "بهتون دستکش بکس میده و باعث\nمیشه ضربه مشت های قویتری داشته باشید", + "powerupPunchNameText": "دستکش بکس", + "powerupShieldDescriptionText": "سپر محافظ دورتون قرار میگیره\nو ضربه وانفجار ها روتون کم اثر میشه", + "powerupShieldNameText": "سپر محافظ", + "powerupStickyBombsDescriptionText": "این بمب ها رو به سمت هر چی پرتاب \nکنی میچسبن به اون تا لحظه ی انفجار", + "powerupStickyBombsNameText": "بمب های چسبنده", + "powerupsSubtitleText": "البته هیچ بازی کامل نیست بدون استفاده از بسته های ویژه", + "powerupsText": "بسته های ویژه", + "punchInfoText": "مشت\nبرا ضربه به حریف از این کلید \nاستفاده کنید ضربه مشت های قوی تر\nهمزمان با پرش و سرعت و چرخش هستن", + "runInfoText": "حرکت\nبرا حرکت از جهت های جوی استیک استفاده کنید و برای حرکت سریع تر میتونید جهت ها رو همزمان با یک کلید دیگه بکار ببرید\nبرای پرتاب بمب ها به مسافت بیشتر همزمان با حرکت قابل انجامه ضربه مشت ها همزمان با حرکت هم موثرتر هستن", + "someDaysText": "بعضی روزا دوس داری مشت بزنی یه جایی. یا یه چیزیو بزنی بترکونی.", + "titleText": "${APP_NAME} راهنمایی", + "toGetTheMostText": "To get the most out of this game, you'll need:", + "welcomeText": "!خوش آمدید ${APP_NAME} به" + }, + "holdAnyButtonText": "<نگه داشتن هر دکمه>", + "holdAnyKeyText": "<نگه داشتن هر کلید>", + "hostIsNavigatingMenusText": "- ${HOST} مدیر تغییر منو ها در بازیست -", + "importPlaylistCodeInstructionsText": "از کدی که در ادامه است برای وارد کردن این لیست بازی در جای دیگر استفاده کنید:", + "importPlaylistSuccessText": "لیست بازی شد ${TYPE} وارد '${NAME}'", + "importText": "وارد کردن", + "importingText": "...وارد کردن", + "inGameClippedNameText": "نام درون بازیتان خواهد بود\n\"${NAME}\"", + "installDiskSpaceErrorText": "خطا: قادر به تکمیل نصب نیست\nممکنه مربوط به فضای ذخیره دستگاه شما باشه\nچک کنید و مجددا امتحان کنید", + "internal": { + "arrowsToExitListText": "برای خروج از لیست ${LEFT} یا ${RIGHT} فشار دهید", + "buttonText": "دکمه", + "cantKickHostError": ".شما نمیتوانید میزبان را بیرون کنید", + "chatBlockedText": ".ثانیه مسدود شد ${TIME} برای ${NAME} چت", + "connectedToGameText": "متصل شد '${NAME}'", + "connectedToPartyText": "${NAME} پیوستن به", + "connectingToPartyText": "در حال اتصال", + "connectionFailedHostAlreadyInPartyText": "ارتباط ناموفق: میزبان در بخش دیگریست", + "connectionFailedPartyFullText": ".اتصال ناموفق پارتی پر شده است", + "connectionFailedText": "اتصال ناموفق بود", + "connectionFailedVersionMismatchText": "ارتباط ناموفق بود؛ میزبان در حال اجرا یک نسخه متفاوت از بازی است.\nمطمئن شوید که شما هر دوتا بروز هستید و دوباره امتحان کنید.", + "connectionRejectedText": "اتصال رد شد", + "controllerConnectedText": "متصل شد ${CONTROLLER}", + "controllerDetectedText": "یک کنترلر شناسایی شد", + "controllerDisconnectedText": "اتصالش قطع شد ${CONTROLLER}", + "controllerDisconnectedTryAgainText": "قطع اتصال شد. لطفا تلاش کنید برای اتصال ازنو ${CONTROLLER}", + "controllerForMenusOnlyText": ".این کنترلر نمی‌تواند در بازی مورد استفاده قرار بگیرد. استفاده فقط برای پیمایش در منوها", + "controllerReconnectedText": "دوباره متصل شد ${CONTROLLER}", + "controllersConnectedText": "کنترولر متصل شد ${COUNT}", + "controllersDetectedText": "کنترولر شناسایی شد ${COUNT}", + "controllersDisconnectedText": "قطع اتصال شد ${COUNT}", + "corruptFileText": "Corrupt file(s) detected. Please try re-installing, or email ${EMAIL}", + "errorPlayingMusicText": "خطای موزیک بازی:${MUSIC}", + "errorResettingAchievementsText": "قادر نیست برای تنظیم مجدد دستاوردهای آنلاین. لطفا بعدا دوباره امتحان کنید.", + "hasMenuControlText": "دسترسی به منو دارد ${NAME}", + "incompatibleNewerVersionHostText": "میزبان در حال استفاده از نسخه جدید تری از بازی هست نسخه بازیتون رو به اخرین نسخه ارتقا بدین\nدوباره امتحان کنید", + "incompatibleVersionHostText": "میزبان در حال اجرا از نسخه دیگری از این بازی است.\nمطمئن شوید که شما هر دو تا بروز هستید و دوباره امتحان کنید.", + "incompatibleVersionPlayerText": "${NAME} در حال اجرا از نسخه دیگری از این بازی است.\nمطمئن شوید که شما هر دو تا بروز هستید و دوباره امتحان کنید.", + "invalidAddressErrorText": "خطا: آدرس در دسترس نیست", + "invalidNameErrorText": "نام نا معتبر", + "invalidPortErrorText": "مشکل:درگاه بی اعتبار", + "invitationSentText": "دعوت نامه ارسال شد.", + "invitationsSentText": "دعوت نامه ارسال شد ${COUNT}", + "joinedPartyInstructionsText": "فردی به گروه شما پیوسته\nبرید به بازی و بازی را شروع کنید", + "keyboardText": "صفحه‌کلید", + "kickIdlePlayersKickedText": "بعلت غیرفعال بودن ${NAME} خروج", + "kickIdlePlayersWarning1Text": "${NAME} will be kicked in ${COUNT} seconds if still idle.", + "kickIdlePlayersWarning2Text": "(شما می توانید اینو خاموش کنید در تنظیمات -> پیشرفته)", + "leftGameText": "خارج شد '${NAME}'", + "leftPartyText": "پارتی رو ترک کرد ${NAME}", + "noMusicFilesInFolderText": "پوشه حاوی هیچ فایل موسیقی نیست.", + "playerJoinedPartyText": "به گروه بازی پیوست ${NAME}", + "playerLeftPartyText": "${NAME} گروه رو ترک کرد", + "rejectingInviteAlreadyInPartyText": "رد کردن دعوت (already in a party)", + "serverRestartingText": "سرور در حال شروع مجدد است. لطفا چند لحظه دیگر مجددا متصل شوید", + "serverShuttingDownText": ".سرور درحال بسته شدن است", + "signInErrorText": "خطای ورود به سیستم", + "signInNoConnectionText": "ورود ناموفق بود اتصال به اینترنت در دسترسه؟", + "telnetAccessDeniedText": "خطا: کاربر از دسترسی به شبکه خارج شد", + "timeOutText": "(times out in ${TIME} seconds)", + "touchScreenJoinWarningText": "You have joined with the touchscreen.\nIf this was a mistake, tap 'Menu->Leave Game' with it.", + "touchScreenText": "صفحه لمسی", + "unableToResolveHostText": "مشکل:توانایی حل مشکل میزبان وجود ندارد", + "unavailableNoConnectionText": "در دسترس نیست. اتصال به اینترنت برقرار است آیا؟", + "vrOrientationResetCardboardText": "برای تنظیم مجدد جهت گیری VR از این استفاده کنید.\nبرای بازی کردن به یک کنترلر خارجی نیاز دارید.", + "vrOrientationResetText": "تنظیم مجدد VR.", + "willTimeOutText": "(زمان تموم میشه اگه بیکار بود)" + }, + "jumpBoldText": "پرش", + "jumpText": "پرش", + "keepText": "نگه داشتن", + "keepTheseSettingsText": "حفظ کردن این تنظیمات؟", + "keyboardChangeInstructionsText": ".برای تغییر صفحه‌کلید، کلید فاصله را دو بار فشار دهید", + "keyboardNoOthersAvailableText": ".صفحه‌کلید دیگری موجود نیست", + "keyboardSwitchText": ".«${NAME}» تغییر صفحه‌کلید به", + "kickOccurredText": ".بیرون انداخته شد ${NAME}", + "kickQuestionText": "بیرون انداخته شود؟ ${NAME}", + "kickText": "بیرون انداختن", + "kickVoteCantKickAdminsText": "نمیشود ادمین ها رو اخراج کنید", + "kickVoteCantKickSelfText": "نمیشه خودت رو اخراج کنی اسکل", + "kickVoteFailedNotEnoughVotersText": ".بازیکنان برای رای گیری کافی نیستند", + "kickVoteFailedText": ".رای گیری برای بیرون انداختن ناموفق", + "kickVoteStartedText": ".شروع شد ${NAME} رای گیری برای بیرون انداختن", + "kickVoteText": "رای برای بیرون انداختن", + "kickVotingDisabledText": ".رأی گیری غیرفعاله", + "kickWithChatText": "را برای نه تایپ کن ${NO} را برای بله و ${YES} در چت", + "killsTallyText": "${COUNT} کشته ها", + "killsText": "کشته ها", + "kioskWindow": { + "easyText": "آسان", + "epicModeText": "حرکت آهسته", + "fullMenuText": "فهرست کامل", + "hardText": "سخت", + "mediumText": "متوسط", + "singlePlayerExamplesText": "Single Player / Co-op Examples", + "versusExamplesText": "Versus Examples" + }, + "languageSetText": "زبان فعلی: ${LANGUAGE}", + "lapNumberText": "${TOTAL}/${CURRENT} دور", + "lastGamesText": "(بازی آخر ${COUNT})", + "leaderboardsText": "مدیران", + "league": { + "allTimeText": "همیشه", + "currentSeasonText": "(${NUMBER}) فصل جاری", + "leagueFullText": "${NAME} لیگ", + "leagueRankText": "رتبه لیگ", + "leagueText": "لیگ", + "rankInLeagueText": "#${RANK}, ${NAME} League${SUFFIX}", + "seasonEndedDaysAgoText": ".روز پیش پایان یافت ${NUMBER} فصل", + "seasonEndsDaysText": ".روز دیگر پایان می‌یابد ${NUMBER} فصل", + "seasonEndsHoursText": ".ساعت دیگر پایان می‌یابد ${NUMBER} فصل", + "seasonEndsMinutesText": ".دقیقهٔ دیگر پایان می‌یابد ${NUMBER} فصل", + "seasonText": "${NUMBER} فصل", + "tournamentLeagueText": ".برسید ${NAME} برای ورود به این مسابقه، باید به لیگ", + "trophyCountsResetText": ".جوایز در فصل بعد بازنشانی می‌شوند" + }, + "levelBestScoresText": "${LEVEL} بهترین امتیاز در", + "levelBestTimesText": "${LEVEL} بهترین زمان در", + "levelIsLockedText": ".قفل است ${LEVEL}", + "levelMustBeCompletedFirstText": ".باید تکمیل شود ${LEVEL} ابتدا", + "levelText": "${NUMBER} مرحله", + "levelUnlockedText": "!قفل مرحله باز شد", + "livesBonusText": "پاداش تعداد جان ها", + "loadingText": "در حال بارگزاری", + "loadingTryAgainText": "…در حال بارگذاری؛ چند لحظهٔ دیگر دوباره امتحان کنید", + "macControllerSubsystemBothText": "(هر دو (توصیه نمی‌شود", + "macControllerSubsystemClassicText": "معمولی", + "macControllerSubsystemDescriptionText": "(موقعی سعی کنید این را عوض کنید که کنترلر شما درست کار نمیکند.)", + "macControllerSubsystemMFiNoteText": ".ساخته شده برای کنترلر آی‌اواِس/مک تشخیص داده شد\n شما شاید بخواهید این‌ها رو در تنظیمات فعال کنید", + "macControllerSubsystemMFiText": "ساخته شده برای ای او اس و مک", + "macControllerSubsystemTitleText": "پشتیبانی کنترل کننده", + "mainMenu": { + "creditsText": "درباره", + "demoMenuText": "منو نسخه ی نمایشی", + "endGameText": "پایان بازی", + "endTestText": "پایان تست", + "exitGameText": "خروج از بازی", + "exitToMenuText": "خروج به منو؟", + "howToPlayText": "روش بازی", + "justPlayerText": "(فقط ${NAME})", + "leaveGameText": "ترک کردن بازی", + "leavePartyConfirmText": "واقعا میخوای دسته رو ترک کنی؟", + "leavePartyText": "ترک دسته", + "quitText": "خروج", + "resumeText": "ادامه", + "settingsText": "تنظیمات" + }, + "makeItSoText": "درستش کن", + "mapSelectGetMoreMapsText": "رفتن به زمین‌های بازیِ بیشتر...", + "mapSelectText": "انتخاب . . .", + "mapSelectTitleText": "${GAME} نقشه", + "mapText": "نقشه", + "maxConnectionsText": "حداکثر اتصالات", + "maxPartySizeText": "حداکثر فضای پارتی", + "maxPlayersText": "حداکثر بازیکنان", + "merchText": "اجناس", + "modeArcadeText": "حالت بازی", + "modeClassicText": "حالت کلاسیک", + "modeDemoText": "حالت نمایشی", + "mostValuablePlayerText": "ارزشمندترین بازیکن", + "mostViolatedPlayerText": "پُراشتباه‌ترین بازیکن", + "mostViolentPlayerText": "خشن‌ترین بازیکن", + "moveText": "انتقال", + "multiKillText": "! !${COUNT} ازبین بردن.", + "multiPlayerCountText": "بازیکن ${COUNT}", + "mustInviteFriendsText": "توجه:\nشما باید دعوت کنید از دوستان درصفحه اصلی از قسمت\n\"${GATHER}\"", + "nameBetrayedText": ".خیانت کرد ${VICTIM} به ${NAME}", + "nameDiedText": ".از بین رفت ${NAME}", + "nameKilledText": ".را از بین برد ${VICTIM} ${NAME}", + "nameNotEmptyText": "!نام نمی‌تواند خالی باشد", + "nameScoresText": "!موفق شد ${NAME}", + "nameSuicideKidFriendlyText": ".بیرون افتاد ${NAME}", + "nameSuicideText": ".خودکشی کرد ${NAME}", + "nameText": "نام", + "nativeText": "بومی", + "newPersonalBestText": "!رکورد قبلیتو شکستی", + "newTestBuildAvailableText": "(${BUILD} نسخهٔ ${VERSION}) !نسخهٔ آزمایشی جدیدتری دردسترس است\n${ADDRESS} :از این نشانی دریافت کنید", + "newText": "جدید", + "newVersionAvailableText": "(${VERSION}) !در دسترس است ${APP_NAME} نسخهٔ جدیدتری از", + "nextAchievementsText": ":دستاوردهای بعدی", + "nextLevelText": "مرحله بعد", + "noAchievementsRemainingText": "- هیچی", + "noContinuesText": "(ادامه ندارد)", + "noExternalStorageErrorText": "محل ذخیره سازی در این دستگاه یافت نشد", + "noGameCircleText": "GameCircleخطا: وارد نشدید به", + "noScoresYetText": "هیچ امتیازی نیست", + "noThanksText": "نه مرسی", + "noTournamentsInTestBuildText": ".هشدار: امتیازات مسابقه از این نسخهٔ آزمایشی نادیده گرفته می‌شوند", + "noValidMapsErrorText": "هیچ نقشه معتبری برای این نوع بازی یافت نشد.", + "notEnoughPlayersRemainingText": "بازیکنان باقیمانده کافی نیستند خارج بشید و دوباره یه بازی جدید رو شروع کنید", + "notEnoughPlayersText": "!بازیکن نیاز دارید ${COUNT} برای شروع بازی حداقل به", + "notNowText": "حالا نه", + "notSignedInErrorText": ".برای انجام این کار باید وارد شوید", + "notSignedInGooglePlayErrorText": "برا استفاده از این مورد شما باید به گوگل‌پلی وارد شوید", + "notSignedInText": "وارد نشده‌ای", + "notUsingAccountText": "توجه: نادیده گرفتن حساب ${SERVICE}.\n اگر می‌خواهید از آن استفاده کنید، به «حساب -> با ${SERVICE}» وارد شوید.", + "nothingIsSelectedErrorText": "چیزی انتخاب نشده", + "numberText": "#${NUMBER}", + "offText": "خاموش", + "okText": "تایید", + "onText": "روشن", + "oneMomentText": "یک لحظه...", + "onslaughtRespawnText": "${PLAYER} will respawn in wave ${WAVE}", + "orText": "${A} یا ${B}", + "otherText": "دیگر...", + "outOfText": "(#${RANK} از ${ALL})", + "ownFlagAtYourBaseWarning": "پرچم شما باید در پایگاه خودتان باشد تا امتیاز کسب کنید.", + "packageModsEnabledErrorText": "شبکه‌بازی دردسترس نیست. بروبه تظیمات》 تنظیمات پیشرفته و تیک پکیج محلی رو وردار", + "partyWindow": { + "chatMessageText": "پیام\"چت\"", + "emptyText": "هیچکس نیست", + "hostText": "(میزبان)", + "sendText": "ارسال", + "titleText": "گروه شما" + }, + "pausedByHostText": "(مکث شده توسط میزبان)", + "perfectWaveText": "! عالی کار کردی", + "pickUpText": "بلند کردن", + "playModes": { + "coopText": "چند نفره", + "freeForAllText": "تک به تک", + "multiTeamText": "چند تیم", + "singlePlayerCoopText": "بازی با کامپیوتر", + "teamsText": "بازی تیمی" + }, + "playText": "شروع بازی", + "playWindow": { + "oneToFourPlayersText": "حداکثر ۴ بازیکن", + "titleText": "شروع بازی", + "twoToEightPlayersText": "حداکثر ۸ بازیکن" + }, + "playerCountAbbreviatedText": "بازیکن ${COUNT}", + "playerDelayedJoinText": ".در دور بعد وارد می‌شود ${PLAYER}", + "playerInfoText": "اطلاعات بازیکن", + "playerLeftText": ".بازی را ترک کرد ${PLAYER}", + "playerLimitReachedText": "محدودیت بازکن به ${COUNT} رسیده; عضو جدید مجاز نیست.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "شما نمی‌توانید نمایهٔ مربوط به حساب‌کاربری را حذف کنید.", + "deleteButtonText": "حذف\nنمایه", + "deleteConfirmText": "؟'${PROFILE}' حذف", + "editButtonText": "ویرایش\nنمایه", + "explanationText": "نام سفارشی بازیکن حاضر در این حساب کاربری", + "newButtonText": "نمایهٔ\nجدید", + "titleText": "نمایه‌های بازیکن" + }, + "playerText": "بازیکن", + "playlistNoValidGamesErrorText": "این لیست حاوی هیچ بازی معتبری نیست", + "playlistNotFoundText": "لیست بازی یافت نشد", + "playlistText": "لیست پخش", + "playlistsText": "لیست بازی ها", + "pleaseRateText": "خوشتان آمده، لطفاً چند لحظه‌ای وقت بگذارید و ${APP_NAME} اگر از\nآن را رتبه‌بندی کنید یا مروری بر آن بنویسید. این کار بازخوردهای مفیدی\n.را به همراه دارد و به پشتیبانی از توسعه‌ها در آینده کمک خواهد کرد\n\n!با تشکر\nاریک—", + "pleaseWaitText": "…لطفاً صبر کنید", + "pluginClassLoadErrorText": "${ERROR} :«${PLUGIN}» خطا در بارگیری دسته‌بندی افزونهٔ", + "pluginInitErrorText": "${ERROR} :«${PLUGIN}» خطا در راه‌اندازی افزونهٔ", + "pluginSettingsText": "تنظیمات پلاگین", + "pluginsAutoEnableNewText": "فعال کردن خودکار افزونه های جدید", + "pluginsDetectedText": "افزونه(ها)ی جدید شناسایی شد. آن‌ها را در تنظیمات فعال، یا پیکربندی کنید.", + "pluginsDisableAllText": "غیرفعال کردن همه افزونه ها", + "pluginsEnableAllText": "فعال کردن همه افزونه ها", + "pluginsRemovedText": "${NUM} افزونه دیگر یافت نمی‌شود.", + "pluginsText": "افزونه‌ها", + "practiceText": "تمرین", + "pressAnyButtonPlayAgainText": "…فشردن هر دکمه‌ای برای بازی دوباره", + "pressAnyButtonText": "…فشردن هر دکمه‌ای برای ادامه", + "pressAnyButtonToJoinText": "…پیوستن با فشردن هر دکمه‌ای", + "pressAnyKeyButtonPlayAgainText": "…فشردن هر کلیدی/دکمه‌ای برای بازی دوباره", + "pressAnyKeyButtonText": "…فشردن هر کلیدی/دکمه‌ای برای ادامه", + "pressAnyKeyText": "…کلیدی را فشار دهید", + "pressJumpToFlyText": "** روی پرش مکرراً ضربه بزنید تا پرواز کنید **", + "pressPunchToJoinText": "…برای پیوستن دکمهٔ مشت را فشار دهید", + "pressToOverrideCharacterText": "را فشار دهید ${BUTTONS} برای انتخاب کاراکتر", + "pressToSelectProfileText": "را فشار دهید ${BUTTONS} برای انتخاب بازیکن", + "pressToSelectTeamText": "را فشار دهید ${BUTTONS} برای انتخاب تیم", + "promoCodeWindow": { + "codeText": "کد", + "enterText": "ورود" + }, + "promoSubmitErrorText": "خطا در ارسال کد؛ لطفاً اتصال اینترنت را بررسی کنید", + "ps3ControllersWindow": { + "macInstructionsText": "Switch off the power on the back of your PS3, make sure\nBluetooth is enabled on your Mac, then connect your controller\nto your Mac via a USB cable to pair the two. From then on, you\ncan use the controller's home button to connect it to your Mac\nin either wired (USB) or wireless (Bluetooth) mode.\n\nOn some Macs you may be prompted for a passcode when pairing.\nIf this happens, see the following tutorial or google for help.\n\n\n\n\nPS3 controllers connected wirelessly should show up in the device\nlist in System Preferences->Bluetooth. You may need to remove them\nfrom that list when you want to use them with your PS3 again.\n\nAlso make sure to disconnect them from Bluetooth when not in\nuse or their batteries will continue to drain.\n\nBluetooth should handle up to 7 connected devices,\nthough your mileage may vary.", + "ouyaInstructionsText": "To use a PS3 controller with your OUYA, simply connect it with a USB cable\nonce to pair it. Doing this may disconnect your other controllers, so\nyou should then restart your OUYA and unplug the USB cable.\n\nFrom then on you should be able to use the controller's HOME button to\nconnect it wirelessly. When you are done playing, hold the HOME button\nfor 10 seconds to turn the controller off; otherwise it may remain on\nand waste batteries.", + "pairingTutorialText": "آموزش تصویری جفت‌شدن", + "titleText": ":${APP_NAME} در PS3 استفاده از کنترلر" + }, + "punchBoldText": "مشت", + "punchText": "مشت", + "purchaseForText": "خرید برای ${PRICE}", + "purchaseGameText": "خرید بازی", + "purchasingText": "…در حال خرید", + "quitGameText": "؟${APP_NAME} خروج از", + "quittingIn5SecondsText": "…ترک در ۵ ثانیه", + "randomPlayerNamesText": "نام پیش‌فرض", + "randomText": "تصادفی", + "rankText": "رتبه", + "ratingText": "امتیاز", + "reachWave2Text": "برای ثبت امتیاز به دور دوم برسید", + "readyText": "آماده", + "recentText": "اخیر", + "remoteAppInfoShortText": ".خیلی جذاب تره وقتی با دوستانتون بازی می کنید ${APP_NAME} بازی\nکافیه چند تا دسته ی بازی به دستگاهتون وصل کنید یا\nرا روی گوشی و تبلت های دیگر نصب کنید تا ${REMOTE_APP_NAME} برنامه ی\n.به عنوان دسته برای بازی استفاده شوند", + "remote_app": { + "app_name": "BombSquad کنترولر مخصوص", + "app_name_short": "BSRemote", + "button_position": "مکان دکمه", + "button_size": "اندازه دکمه", + "cant_resolve_host": "میزبان را نمی‌توان یافت.", + "capturing": "گرفتن…", + "connected": ".متصل شد", + "description": "از گوشی یا تبلتتان به‌عنوان دستهٔ بازی برای بمب‌اسکواد استفاده کنید.\nتا ۸ دستگاه می‌توانند به‌صورت هم‌زمان برای جنون حماسهٔ محلی چندنفره روی یک تی‌وی یا تبلت متصل شوند.", + "disconnected": "قطع اتصال از سرور", + "dpad_fixed": "ثابت", + "dpad_floating": "شناور", + "dpad_position": "D-Pad موقعیت", + "dpad_size": "D-Pad اندازه", + "dpad_type": "D-Pad Type", + "enter_an_address": "وارد کردن یه آدرس", + "game_full": "بازی تکمیل است یا اتصالات پذیرفته نشدند", + "game_shut_down": "بازی تعطیل شد", + "hardware_buttons": "دکمه سخت افزاری", + "join_by_address": "پیوستن با آدرس", + "lag": "ثانیه ${SECONDS} : تاخیر", + "reset": "برگرداند به پیشفرض", + "run1": "Run 1", + "run2": "Run 2", + "searching": "جستجو برای بازی‌های فعال", + "searching_caption": "بر روی نام یک بازی برای پیوستن به آن ضربه بزنید.\nاطمینان حاصل کنید که شما در شبکه وای فای همان بازی هستید.", + "start": "شروع", + "version_mismatch": "عدم تطابق نسخه‌ها\nاطمینان حاصل کنید که بمب‌اسکوار و کنترولر\nآخرین ورژن باشن و دوباره امتحان کنید" + }, + "removeInGameAdsText": "بازی را در فروشگاه بخرید تا تبلیغات حذف شوند «${PRO}» نسخهٔ", + "renameText": "تغییر نام", + "replayEndText": "پایان بازپخش", + "replayNameDefaultText": "بازپخش بازی اخیر", + "replayReadErrorText": "خطا در خواندن فایل بازپخش", + "replayRenameWarningText": "عبارت «${REPLAY}» را تغییر دهید، اگر می‌خواهید بعد از یک بازی آن را از دست ندهید. در غیر این صورت بازنویسی می‌شود.", + "replayVersionErrorText": "با عرض پوزش این بازبخش در ورژن مختلفیاز بازی ایجاد شده\n است و نمیتوان مورد استفاده قرار گیرد", + "replayWatchText": "دیدن بازبخش بازی", + "replayWriteErrorText": "خطا در نوشتن فایل بازپخش.", + "replaysText": "بازپخش ها", + "reportPlayerExplanationText": "از این ایمیل برای گزارش تقلب، زبان نامناسب یا موارد نامناسب دیگر استفاده کنید.\nلطفا این پایین توضیح دهید:", + "reportThisPlayerCheatingText": "تقلب کردن", + "reportThisPlayerLanguageText": "زبان نامناسب", + "reportThisPlayerReasonText": "میخواهید چه چیزی رو گزارش بدید؟", + "reportThisPlayerText": "گزارش کردن این بازیکن", + "requestingText": "درخواست", + "restartText": "شروع دوباره", + "retryText": "مجدد", + "revertText": "بازگشت", + "runText": "دویدن", + "saveText": "ذخیره", + "scanScriptsErrorText": "اسکریپت ها در حال بررسی خطا ها است؛ برای جزئیات لوگ را ببینید", + "scoreChallengesText": "امتیاز چالش", + "scoreListUnavailableText": ".لیست امتیازات در دسترس نیست", + "scoreText": "امتیاز", + "scoreUnits": { + "millisecondsText": "میلی ثانیه", + "pointsText": "امتیاز", + "secondsText": "ثانیه" + }, + "scoreWasText": "(بود ${COUNT})", + "selectText": "انتخاب", + "seriesWinLine1PlayerText": "برنده", + "seriesWinLine1TeamText": "برنده", + "seriesWinLine1Text": "برنده", + "seriesWinLine2Text": "مجموعه بازی", + "settingsWindow": { + "accountText": "حساب", + "advancedText": "پیشرفته", + "audioText": "صدا", + "controllersText": "کنترلرها", + "graphicsText": "تصویر", + "playerProfilesMovedText": "توجه: مشخصات بازیکن به پنجره حساب در منوی اصلی نقل مکان کرد.", + "titleText": "تنظیمات" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(یه صفحه‌کلید ساده و خوش‌دست بر روی صفحهٔ نمایش برای ویرایش متنی)", + "alwaysUseInternalKeyboardText": "همیشه از صفحه‌کلید داخلی استفاده شود", + "benchmarksText": "معیار و تست استرس", + "disableCameraGyroscopeMotionText": "غیرفعال کردن حرکت ژیروسکوپ دوربین", + "disableCameraShakeText": "غیرفعال کردن لرزش دوربین", + "disableThisNotice": "(شما میتوانید این اخطار را در تنظیمات یشرفته خاموش کنید)", + "enablePackageModsDescriptionText": "(فعالسازی قابلیت مد اکسترا اما شبکه بازی غیر فعال میشود)", + "enablePackageModsText": "فعالسازی پکیج مد محلی", + "enterPromoCodeText": "وارد کردن کد", + "forTestingText": "توجه: این تغیرات برای آزمایش کردن هستند و هنگام خروج به حال اول باز میگردند", + "helpTranslateText": "ترجمه‌های غیرانگلیسی ${APP_NAME} تلاشی است که\nتوسط انجمن پشتیبانی می‌شود. اگر مایل به کمک یا تصحیح\nترجمه هستید، پیوند زیر را دنبال کنید. پیشاپیش متشکرم!", + "kickIdlePlayersText": "بیرون انداختن بازیکنان غیرفعال", + "kidFriendlyModeText": "حالت دوستانه برای کودکان. خشونت کم", + "languageText": "زبان", + "moddingGuideText": "راهنمای برنامه‌نویسان", + "mustRestartText": "برای اعمال تغییرات باید بازی را دوباره راه اندازی کنید", + "netTestingText": "تست شبکه", + "resetText": "باز گرداندن", + "showBombTrajectoriesText": "نمایش خط سیر بمب", + "showInGamePingText": "نمایش پینگ در بازی", + "showPlayerNamesText": "نمایش نام بازیکنان", + "showUserModsText": "نمایش پوشهٔ سبک بازی‌ها", + "titleText": "پیشرفته", + "translationEditorButtonText": "${APP_NAME} ویرایشگر زبان", + "translationFetchErrorText": "وضعیت ترجمه در دسترس نیست", + "translationFetchingStatusText": "چک کردن وضعیت ترجمه ...", + "translationInformMe": "!وقتی زبان من به‌روزرسانی نیاز داشت، خبرم کن", + "translationNoUpdateNeededText": "!زبان کنونی به‌روز است؛ ووهو", + "translationUpdateNeededText": "! زبان فعلی نیاز به به روز رسانی دارد", + "vrTestingText": "VR تست" + }, + "shareText": "اشتراک‌گذاری", + "sharingText": "...در حال اشتراک‌گذاری", + "showText": "نمایش", + "signInForPromoCodeText": "برای اثر گذاری کد ها باید با یک حساب کاربری وارد شوید", + "signInWithGameCenterText": "برای استفاده از حسابی که در یک گیم سنتر دارید,\nبا برنامه گیم سنتر خود وارد شوید.", + "singleGamePlaylistNameText": "${GAME} فقط", + "singlePlayerCountText": "1 بازیکن", + "soloNameFilterText": "رو در رو ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "انتخاب کارکتر", + "Chosen One": "انتخاب شده", + "Epic": "بازی قدرت", + "Epic Race": "مسابقه حرکت آهسته", + "FlagCatcher": "گرفتن پرچم", + "Flying": "رویا", + "Football": "فوتبال", + "ForwardMarch": "مبارزه", + "GrandRomp": "پیروز شدن", + "Hockey": "هاکی", + "Keep Away": "دور نگه داشتن", + "Marching": "گریز", + "Menu": "منوی اصلی", + "Onslaught": "حمله", + "Race": "مسابقه", + "Scary": "پادشاه تپه", + "Scores": "صفحه امتیاز", + "Survival": "از بين بردن", + "ToTheDeath": "نبرد مرگبار", + "Victory": "صفحه نمایش نتایج نهایی" + }, + "spaceKeyText": "فاصله", + "statsText": "آمار", + "storagePermissionAccessText": "به اجازه شما برای دسترسی به حافظه نیاز دارد", + "store": { + "alreadyOwnText": "!را در اختیار دارید ${NAME} شما", + "bombSquadProDescriptionText": "• Doubles achievement ticket rewards\n• Removes in-game ads\n• Includes ${COUNT} bonus tickets\n• +${PERCENT}% league score bonus\n• Unlocks '${INF_ONSLAUGHT}' and\n '${INF_RUNAROUND}' co-op levels", + "bombSquadProNameText": "حرفه ای ${APP_NAME}", + "bombSquadProNewDescriptionText": ".تبلیغات داخل بازی حذف میشود\n.بیشتر تنظیمات بازی باز میشوند\n:همچنین شامل", + "buyText": "خرید", + "charactersText": "شخصیت ها", + "comingSoonText": "...به زودی", + "extrasText": "دیگر", + "freeBombSquadProText": "جوخه بمب حالا مجانیه، ولی چون شما زمانی خریدینش که پولی بود؛ ما داریم\nشمارو به جوخه بمب پرو ارتقا میدیم و ${COUNT} بلیط بعنوان تشکر برای شما.\nاز امکانات جدید لذت ببرید. از شما بابت پشتیبانی و دلگرمی تان ممنونیم!\n-اریک", + "holidaySpecialText": "ویژه‌ی تعطیلات", + "howToSwitchCharactersText": "(برو به \"${SETTINGS} -> ${PLAYER_PROFILES}\" برای ایجاد و شخصی‌سازی شخصیت‌ها)", + "howToUseIconsText": "(ایجاد نمایه‌های جهانی از قسمت پنجرهٔ حساب برای استفاده در این مورد)", + "howToUseMapsText": "(از این نقشه‌ها میتونید تو بازی‌های تیمی و تک‌به‌تکی خودتون استفاده کنید)", + "iconsText": "نشانه‌ها", + "loadErrorText": "لود شدن صفحه ناموفق بود\nاتصال اینترنت رو چک کنید", + "loadingText": "در حال بارگزاری", + "mapsText": "نقشه ها", + "miniGamesText": "تک بازی‌های کوچک", + "oneTimeOnlyText": "(فقط یک بار)", + "purchaseAlreadyInProgressText": "این مورد قبلا سفارش داده شده", + "purchaseConfirmText": "را بخرید ؟ ${ITEM} واقعا می خواهید", + "purchaseNotValidError": ". سفارش معتبر نیست\n. ایمیل بزنید ${EMAIL} اگر مشکلی دارید به", + "purchaseText": "خرید", + "saleBundleText": "فروش بسته نرم‌افزاری!", + "saleExclaimText": "فروش", + "salePercentText": "(${PERCENT}% تخفیف)", + "saleText": "فروش ویژه", + "searchText": "جستجو", + "teamsFreeForAllGamesText": "بازی‌های تیمی / تک به تک", + "totalWorthText": "*** ${TOTAL_WORTH} قیمت! ***", + "upgradeQuestionText": "ارتقا؟", + "winterSpecialText": "ویژه ی زمستان", + "youOwnThisText": "شما این را در اختیار دارید" + }, + "storeDescriptionText": "8 بازیکن حزب جنون بازی!\n\nدوستان خود (یا رایانه) را در مسابقات مینی بازی‌های انفجاری مانند: پرچم، هاکی و حرکت آهسته\n\nکنترل ساده و پشتیبانی گسترده می‌توان تا حداکثر 8 نفر برای ورود به بازی اقدام کند؛ شما حتی می‌توانید دستگاه‌های تلفن‌همراه خود را به عنوان کنترل از طریق برنامه رایگان BombSquadremote استفاده کنید!\n\nبمب‌اندازی از راه دور!\n\nwww.froemling.net/bombsquad را برای اطلاعات بیشتر چک کنید.", + "storeDescriptions": { + "blowUpYourFriendsText": "بازیکن دوستات رو بترکون 😁", + "competeInMiniGamesText": "رقابت در بازی‌های کوچک بویژه مسابقه پرواز.", + "customize2Text": "سفارشی کردن شخصیت‌ها، بازی‌های کوچک، و حتی موسیقی‌های متن .", + "customizeText": "شما می تونید شخصیت‌ها رو شخصی‌سازی کنید و به سلیقه خودتون لیست‌بازی درست کنید", + "sportsMoreFunText": "ورزش ها سرگرم کننده تر میشن با انفجار", + "teamUpAgainstComputerText": "تیم در مقابل کامپیوتر ." + }, + "storeText": "فروشگاه", + "submitText": "ثبت", + "submittingPromoCodeText": "...ثبت کردن کد", + "teamNamesColorText": "نام/رنگ تیم...", + "telnetAccessGrantedText": "شبکه ی در دسترس فعال", + "telnetAccessText": "شبکه راه دور دردسترس است اجازه میدید؟", + "testBuildErrorText": "این نسخه دیگر فعال نیست، لطفا نسخه جدید را بررسی کنید", + "testBuildText": "آزمایش ساخت", + "testBuildValidateErrorText": "قادر به تأیید نسخه نیست (اتصال برقره نشد؟)", + "testBuildValidatedText": "نسخه معتبر است؛ لذت ببرید.!", + "thankYouText": "تشکر بخاطر حمایت از ما ! از بازی لذت ببرید", + "threeKillText": "نابود کردن همزمان سه نفر", + "timeBonusText": "پاداش سرعت عمل", + "timeElapsedText": "زمان سپری شده", + "timeExpiredText": "زمان تمام شده", + "timeSuffixDaysText": "روز ${COUNT}", + "timeSuffixHoursText": "ساعت ${COUNT}", + "timeSuffixMinutesText": "دقیقه ${COUNT}", + "timeSuffixSecondsText": "ثانیه ${COUNT}", + "tipText": "نکته", + "titleText": "بمب‌اسکواد", + "titleVRText": "BombSquad VR", + "topFriendsText": "بالاترین امتیاز دوستان", + "tournamentCheckingStateText": "چک کردن وضعیت مسابقات؛ لطفا صبر کنید", + "tournamentEndedText": "این دوره از مسابقات به پایان رسیده است دوره جدیدی بزودی آغاز خواهد شد", + "tournamentEntryText": "ورودیِ مسابقات", + "tournamentResultsRecentText": "آخرین نتایج مسابقات", + "tournamentStandingsText": "جدول رده بندی مسابقات", + "tournamentText": "جام حذفی", + "tournamentTimeExpiredText": "زمان مسابقات پایان یافت", + "tournamentsDisabledWorkspaceText": "وقتی فضاهای کاری فعال هستند، مسابقات غیرفعال می شوند.\n برای فعال کردن مجدد مسابقات، فضای کاری خود را غیرفعال کنید و دوباره راه اندازی کنید.", + "tournamentsText": "مسابقات", + "translations": { + "characterNames": { + "Agent Johnson": "مامور جانسون", + "B-9000": "B-9000", + "Bernard": "برنارد", + "Bones": "اسکلت", + "Butch": "بوچ", + "Easter Bunny": "خرگوش عید پاک", + "Flopsy": "فلاپسی", + "Frosty": "آدم‌برفی", + "Gretel": "گرتل", + "Grumbledorf": "جادوگر", + "Jack Morgan": "جک مورگان", + "Kronk": "کرانک", + "Lee": "لی", + "Lucky": "خوش شانس", + "Mel": "مل", + "Middle-Man": "کودن", + "Minimus": "مینیموس", + "Pascal": "پاسکال", + "Pixel": "پیکسل", + "Sammy Slam": "سامی کشتی‌گیر", + "Santa Claus": "بابا نوئل", + "Snake Shadow": "سایه ی مار", + "Spaz": "اسپاز", + "Taobao Mascot": "تائوبائو", + "Todd": "تاد", + "Todd McBurton": "تاد", + "Xara": "ژارا", + "Zoe": "زو", + "Zola": "زولا" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} محل تمرین", + "Infinite ${GAME}": "بی پایان ${GAME}", + "Infinite Onslaught": "نبرد بی‌پایان", + "Infinite Runaround": "دوره بی نهایت", + "Onslaught Training": "نبرد مبتدی", + "Pro ${GAME}": "حرفه ای ${GAME}", + "Pro Football": "فوتبال حرفه‌ای", + "Pro Onslaught": "حمله ی سخت", + "Pro Runaround": "نگهبان خروج", + "Rookie ${GAME}": "${GAME} قدرت", + "Rookie Football": "مبارز فوتبال", + "Rookie Onslaught": "میدان مبارزه", + "The Last Stand": "آخرین مقاومت", + "Uber ${GAME}": "${GAME} بازی", + "Uber Football": "فوتبال حرفه‌ای", + "Uber Onslaught": "هجوم", + "Uber Runaround": "ایست بازرسی" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "یکی از بهترین ها برای پیروزی در زمان بازی است.\nیکی را انتخاب کنید و از بین ببرید تا به آن تبدیل شوید.", + "Bomb as many targets as you can.": "هدف ها را با بمب بزن", + "Carry the flag for ${ARG1} seconds.": "ثانیه${ARG1}حمل و نگهداری پرچم برای", + "Carry the flag for a set length of time.": "حمل و حفاظت از پرچم برای برای یک زمان معین", + "Crush ${ARG1} of your enemies.": "بار از حریف ${ARG1} پیروز شدن", + "Defeat all enemies.": "همه ی حریف ها را شکست بده", + "Dodge the falling bombs.": "از بمب ها جاخالی بده", + "Final glorious epic slow motion battle to the death.": "نبرد در حرکت آهسته", + "Gather eggs!": "تخم مرغ ها رو جمع کن", + "Get the flag to the enemy end zone.": "بردن پرچم به منطقه پایانی حریف", + "How fast can you defeat the ninjas?": "با چه سرعتی میتونید نینجاها رو شکست بدید؟", + "Kill a set number of enemies to win.": "ازبین بردن تعدادی ازحریف ها برای بردن", + "Last one standing wins.": "آخرین کسی که موند برنده س", + "Last remaining alive wins.": "تاریخ و زمان آخرین برنده زنده باقی مانده", + "Last team standing wins.": "آخرین تیمی که می‌مونه تو بازی برنده‌س", + "Prevent enemies from reaching the exit.": "جلوگیری از خروج حریف", + "Reach the enemy flag to score.": "رسیدن به پرچم دشمن", + "Return the enemy flag to score.": "برداشتن پرچم دشمن برای امتیاز گرفتن", + "Run ${ARG1} laps.": "دور ${ARG1} حرکت", + "Run ${ARG1} laps. Your entire team has to finish.": "دور ,کل تیم ${ARG1} حرکت", + "Run 1 lap.": "یک دور", + "Run 1 lap. Your entire team has to finish.": "یک دور کل تیم به خط پایان برسند", + "Run real fast!": "!حرکت واقعا سریع", + "Score ${ARG1} goals.": "گل ${ARG1}زدن", + "Score ${ARG1} touchdowns.": "بار ${ARG1}عبور پرچم ازخط", + "Score a goal.": "گل بزنید", + "Score a touchdown.": "امتیاز پرش", + "Score some goals.": "امتیاز برخی گل ها", + "Secure all ${ARG1} flags.": "پرچم ${ARG1}مال خودکردن همه", + "Secure all flags on the map to win.": "حفاظت از تمام پرچم ها. در نقشه", + "Secure the flag for ${ARG1} seconds.": "ثانیه ${ARG1} حفاظت از پرچم برای", + "Secure the flag for a set length of time.": "حفاظت از پرچم در مدت زمان معین", + "Steal the enemy flag ${ARG1} times.": "بار ${ARG1} ربودن پرچم حریف", + "Steal the enemy flag.": "ربودن پرچم حریف", + "There can be only one.": "صاحب پرچم فقط میتونه یه نفر باشه", + "Touch the enemy flag ${ARG1} times.": "${ARG1} بار لمس پرچم دشمن", + "Touch the enemy flag.": "لمس پرچم دشمن", + "carry the flag for ${ARG1} seconds": "ثانیه${ARG1}حمل و نگهداری پرچم برای", + "kill ${ARG1} enemies": "حریف ${ARG1} ازبین بردن", + "last one standing wins": "آخرین کسی که موند برنده س", + "last team standing wins": "آخرین تیمی که می‌مونه روصحنه برنده‌س", + "return ${ARG1} flags": "پرچم ${ARG1} بدست آوردن", + "return 1 flag": "بدست آوردن 1 پرچم", + "run ${ARG1} laps": "دور ${ARG1} حرکت", + "run 1 lap": "یک دور", + "score ${ARG1} goals": "گل ${ARG1}زدن", + "score ${ARG1} touchdowns": "بار ${ARG1}عبور پرچم ازخط", + "score a goal": "گل بزنید", + "score a touchdown": "امتیاز یک پرش", + "secure all ${ARG1} flags": "پرچم ${ARG1}مال خودکردن همه", + "secure the flag for ${ARG1} seconds": "ثانیه ${ARG1} حفاظت از پرچم برای", + "touch ${ARG1} flags": "پرچم ${ARG1}لمس", + "touch 1 flag": "لمس 1 پرچم" + }, + "gameNames": { + "Assault": "لمس پرچم", + "Capture the Flag": "تسخیر پرچم", + "Chosen One": "فرد منتخب", + "Conquest": "قدرت نمایی", + "Death Match": "نبرد مرگبار", + "Easter Egg Hunt": "شکار تخم‌مرغ عید پاک", + "Elimination": "استقامت", + "Football": "فوتبال آمریکایی", + "Hockey": "هاکی", + "Keep Away": "دور نگه داشتن", + "King of the Hill": "پادشاه تپه", + "Meteor Shower": "بمباران", + "Ninja Fight": "نبرد با نینجاها", + "Onslaught": "مبارزه", + "Race": "مسابقهٔ دو", + "Runaround": "مانع", + "Target Practice": "تمرین بمب‌اندازی", + "The Last Stand": "دفاع آخر" + }, + "inputDeviceNames": { + "Keyboard": "صفحه‌کلید", + "Keyboard P2": "p2 صفحه‌کلید" + }, + "languages": { + "Arabic": "عربی", + "Belarussian": "بلاروسی", + "Chinese": "چینی ساده شده", + "ChineseTraditional": "چینی سنتی", + "Croatian": "کرواتی", + "Czech": "چک", + "Danish": "دانمارکی", + "Dutch": "هلندی", + "English": "انگلیسی", + "Esperanto": "اسپرانتو", + "Filipino": "فلیپینی", + "Finnish": "فنلاندی", + "French": "فرانسوی", + "German": "آلمانی", + "Gibberish": "قبرسی", + "Greek": "یونانی", + "Hindi": "هندی", + "Hungarian": "مجارستانی", + "Indonesian": "اندونزی", + "Italian": "ایتالیایی", + "Japanese": "ژاپنی", + "Korean": "کره‌ای", + "Malay": "مالایی", + "Persian": "فارسی‎", + "Polish": "لهستانی", + "Portuguese": "پرتغالی", + "Romanian": "رومانیایی", + "Russian": "روسی", + "Serbian": "صربستانی", + "Slovak": "اسلواک", + "Spanish": "اسپانیایی", + "Swedish": "سوئدی", + "Tamil": "تامیلی", + "Thai": "تایلندی", + "Turkish": "ترکی", + "Ukrainian": "اوکراینی", + "Venetian": "ونیزی", + "Vietnamese": "ویتنامی" + }, + "leagueNames": { + "Bronze": "برنز", + "Diamond": "الماس", + "Gold": "طلا", + "Silver": "نقره" + }, + "mapsNames": { + "Big G": "بزرگ G", + "Bridgit": "بریدگیت", + "Courtyard": "حیاط", + "Crag Castle": "قلعه پرتگاه", + "Doom Shroom": "رستاخیز", + "Football Stadium": "استادیوم فوتبال", + "Happy Thoughts": "پرواز", + "Hockey Stadium": "استادیوم هاکی", + "Lake Frigid": "یخبندان", + "Monkey Face": "صورت میمون", + "Rampage": "خشم", + "Roundabout": "میدان", + "Step Right Up": "پایدار", + "The Pad": "رینگ", + "Tip Top": "تیپ تاپ", + "Tower D": "برج دی", + "Zigzag": "زیگ زاگ" + }, + "playlistNames": { + "Just Epic": "فقط حرکت آهسته", + "Just Sports": "فقط ورزشی" + }, + "scoreNames": { + "Flags": "پرچم‌ها", + "Goals": "اهداف", + "Score": "امتیاز", + "Survived": "زنده موندی", + "Time": "زمان", + "Time Held": "زمان برگزاری" + }, + "serverResponses": { + "A code has already been used on this account.": "کد قبلا در این حساب استفاده شده است.", + "A reward has already been given for that address.": "پاداش برای آن آدرس داده شده است.", + "Account linking successful!": "ارتباط موفق با حساب کاربری", + "Account unlinking successful!": "قطع شدن حساب با موفقیت انجام شد", + "Accounts are already linked.": "حساب‌ها قبلا مرتبط شده‌اند", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "نمای آگهی تأیید نمی شود\nلطفا مطمئن باشید که نسخه رسمی و به روز بازی را اجرا می کنید", + "An error has occurred; (${ERROR})": "متاسفانه یک مشکل رخ داده ؛ (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "یک مشکل رخ داده! لطفا با پشتیبانی تماس بگیرید؛ (${ERROR})", + "An error has occurred; please contact support@froemling.net.": ".تماس بگیرید support@froemling.net خطایی رخ داده است. لطفاً با", + "An error has occurred; please try again later.": ".خطایی رخ داده است. لطفاً بعداً تلاش کنید", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "آیا مطمئن هستید که می‌خواهید این حساب‌ها را به هم متصل کنید؟\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n!این کار برگشت‌پذیر نیست", + "BombSquad Pro unlocked!": "!نسخهٔ حرفه‌ای باز شد", + "Can't link 2 accounts of this type.": ".نمی‌توان دو حساب از این نوع را پیوند داد", + "Can't link 2 diamond league accounts.": "نمی‌توان حساب دو لیگ الماس را پیوند داد.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "پیوند نمی‌شود; حداکثر از ${COUNT} پیوند پشتیبانی می‌شود.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "تقلب تشخیص داده شد; امتیازات و جوایز برای ${COUNT} روز تعلیق شد.", + "Could not establish a secure connection.": "نمیتوان یک اتصال امن ایجاد کرد", + "Daily maximum reached.": "به حداکثر روزانه رسیده است", + "Entering tournament...": "ورود به مسابقات ...", + "Invalid code.": "کد نامعتبر", + "Invalid payment; purchase canceled.": "پرداخت با خطا مواجه شد؛ خرید لغو شد", + "Invalid promo code.": "کد نامعتبر است.", + "Invalid purchase.": "خرید نا معتبر", + "Invalid tournament entry; score will be ignored.": "ورود مسابقات نامعتبر است؛ نمره نادیده گرفته می شود.", + "Item unlocked!": "!مورد باز شد", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "پیوند کردن ممنوع شد ${ACCOUNT} شامل\nداده های قابل توجهی که می توانند از دست بدهند.\nشما می توانید در صورت مخالفت پیوست کنید اگر دوست دارید\n(و در عوض داده های این حساب را از دست می دهید)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "را به این حساب پیوند دهید؟ ${ACCOUNT} آیا مایلید که حساب کاربری \n.از بین خواهد رفت ${ACCOUNT} تمام اطلاعات روی حساب\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟", + "Max number of playlists reached.": "تعداد بازی ها به حداکثر رسیده است", + "Max number of profiles reached.": ".تعداد نمایه‌ها به حداکثر رسیده است", + "Maximum friend code rewards reached.": ".حداکثر جایزه کد ارسالی برای دوستان دریافت شد", + "Message is too long.": "پیام خیلی طولانی است", + "No servers are available. Please try again soon.": "هیچ سروری در دسترس نیست. لطفا به زودی دوباره امتحان کنید", + "Profile \"${NAME}\" upgraded successfully.": ".با موفقیت ارتقا یافت «${NAME}» نمایهٔ", + "Profile could not be upgraded.": ".نمایه نمی‌تواند ارتقا یابد", + "Purchase successful!": "خرید با موفقیت انجام شد", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "بدست آمده ${COUNT} بلیت برای ورود به سیستم.\nفردا برگرد برای دریافت ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "این نسخه از بازی دیگر توسط سرور پشتیبانی نمی شود.\nلطفا از جدید ترین نسخه بازی استفاده کنید.", + "Sorry, there are no uses remaining on this code.": "با عرض پوزش, این کد دیگر کاربرد ندارد", + "Sorry, this code has already been used.": "با عرض پوزش، این کد قبلا استفاده شده است.", + "Sorry, this code has expired.": "متاسفانه این کد منقضی شده", + "Sorry, this code only works for new accounts.": "با عرض وزش پوزش, این کد فقط برا حساب کاربری جدید کاربرد داره", + "Still searching for nearby servers; please try again soon.": "هنوز سرورهای اطراف را جستجو می کنید. لطفا به زودی دوباره امتحان کنید", + "Temporarily unavailable; please try again later.": "در حال حاضر این گذینه موجود نمی باشد؛لطفا بعدا امتحان کنید", + "The tournament ended before you finished.": "مسابقات به پایان رسید قبل از اینکه شما به پایان برسید.", + "This account cannot be unlinked for ${NUM} days.": "این حساب برای مدت ${NUM} روز قابل جداسازی نیست!", + "This code cannot be used on the account that created it.": "کد در حسابی که با آن ساخته شده قابل استفاده نیست", + "This is currently unavailable; please try again later.": ".این گزینه در حال حاضر در دسترس نیست; لطفا بعدا دوباره تلاش کنید", + "This requires version ${VERSION} or newer.": "یا جدیدتر باشد ${VERSION} برای این کار نسخه ی بازی باید", + "Tournaments disabled due to rooted device.": "مسابقات به دلیل روت بودن دستگاه غیر فعال شده است", + "Tournaments require ${VERSION} or newer": "تورنومنت ها به${VERSION}جدید تر یا حرفه ای نیاز دارند", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "آیا مایلبد حساب ${ACCOUNT} را از حساب خودتان جداسازی کنید؟\nتمام اطلاعات حساب ${ACCOUNT} بازنویسی خواهد شد.\n(به جز بعضی از افتخارات کسب شده)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "اخطار: شکایت هایی مبنی بر استفاده شما از ابزار های تقلب به دست ما رسیده!\nدر صورت تکرار حساب کاربری شما مسدود خواهد شد! لطفا جوانمردانه بازی کنید.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "می‌خواهید دستگاه‌تون رو به این دستگاه متصل کنید؟\n\nحساب دستگاهی شما ${ACCOUNT1}\nاین حساب ${ACCOUNT2}\n\nاین مشکلی توی سیو و پیشرفت شما ایجاد نمیکنه.\nاخطار: بعدا نمی‌تونید پشیمون بشید!", + "You already own this!": "قبلا اینو گرفتی", + "You can join in ${COUNT} seconds.": ".ثانیه ${COUNT} شما میتوانید متصل شوید در", + "You don't have enough tickets for this!": "شما بلیط کافی برای این ندارید", + "You don't own that.": ".اون مال شما نیست", + "You got ${COUNT} tickets!": "! تا بلیط گرفتی ${COUNT}", + "You got a ${ITEM}!": "! گرفتی ${ITEM} یه دونه", + "You have been promoted to a new league; congratulations!": "شما به یک لیگ جدید ارتقا داده‌اید؛ تبریک می‌گوییم!", + "You must update to a newer version of the app to do this.": "برای انجام این کار شما باید بازی را به روز رسانی کنید", + "You must update to the newest version of the game to do this.": "برای انجام این کار باید از آخرین نسخه بازی استفاده کنید.", + "You must wait a few seconds before entering a new code.": "شما باید چند ثانیه قبل از وارد کردن یک کد جدید صبر کنید.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "! شدید . ممنون که شرکت کردید ${RANK} شما در آخرین مسابقه رتبه ی", + "Your account was rejected. Are you signed in?": "حساب شما رد شده است. آیا وارد حساب خود شده اید؟", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "نسخه بازی شما دستکاری شده است.\nلطفا تغییرات رو به حالت اول برگردونید و دوباره امتحان کنید.", + "Your friend code was used by ${ACCOUNT}": "کد دوست شما استفاده شده توسط ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "یک دقیقه", + "1 Second": "یک ثانیه", + "10 Minutes": "ده دقیقه", + "2 Minutes": "دو دقیقه", + "2 Seconds": "دو ثانیه", + "20 Minutes": "۲۰ دقیقه", + "4 Seconds": "چهار ثانیه", + "5 Minutes": "پنج دقیقه", + "8 Seconds": "هشت ثانیه", + "Allow Negative Scores": "نمرات منفی", + "Balance Total Lives": "مجموعِ جانِ باقيمانده", + "Bomb Spawning": "بازسازی بمب", + "Chosen One Gets Gloves": "دستکش بکس برای مالک پرچم", + "Chosen One Gets Shield": "قرار دادن سپر برای مالک پرچم", + "Chosen One Time": "انتخاب زمان", + "Enable Impact Bombs": "فعالسازی تاثیر بمب ها", + "Enable Triple Bombs": "فعال کردن بمب سه گانه", + "Entire Team Must Finish": "کل تیم باید نابود بشن", + "Epic Mode": "حرکت آهسته", + "Flag Idle Return Time": "پرچم زمان بازگشت بیدرنگ", + "Flag Touch Return Time": "زمان بازگشت لمس پرچم", + "Hold Time": "زمان نگه داشتن", + "Kills to Win Per Player": "هرکی بیشتر نابود کنه", + "Laps": "دور ها", + "Lives Per Player": "تعداد جان برای بازیکن", + "Long": "طولانی", + "Longer": "خیلی طولانی", + "Mine Spawning": "مین گذاری", + "No Mines": "بدون مین", + "None": "هيچ", + "Normal": "معمولی", + "Pro Mode": "حالت حرفه ای", + "Respawn Times": "زمان برگشت بازیکن مرده", + "Score to Win": "امتیاز بگیر تا برنده شی", + "Short": "کوتاه", + "Shorter": "کوتاه تر", + "Solo Mode": "حالت انفرادی", + "Target Count": "تعداد هدف", + "Time Limit": "محدودیت زمانی" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "بازی‌رو ترک کرد ${PLAYER} ردصلاحیت شد چون ${TEAM}", + "Killing ${NAME} for skipping part of the track!": "! از بین رفت چون جِرزنی کرد ${NAME}", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "هشدار به ${NAME}: توربو/اسپم دادن شما را مسدود میکند" + }, + "teamNames": { + "Bad Guys": "تیم حریف", + "Blue": "آبی", + "Good Guys": "تیم خودی", + "Red": "قرمز" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "یه مشت جهشی پرشی چرخشی با زمان بندی درست ، با یه ضربه حریف رو نابود میکنه\n! از این حرکتا بزن بعدش برا دوستات تعریف کن", + "Always remember to floss.": "حرفه‌ای باش، بَرنده باش..", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "برای خودت و دوستات نمایه بساز تا مجبور نشی\n.از «بازیکنان تصادفی» خودِ بازی استفاده کنی", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "جعبه ی مرگ تو رو تبدیل به یه بمب ساعتی می کنه\nاگه می خوای زنده بمونی باید سریع یه جعبه درمان بگیری", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "تمام کارکتر های بازی دارای توانایی های یکسانی هستند بنابراین شما فقط کافیه\nنزدیکترین کارکتر به شخصیت خودتون رو انتخاب و پیکربندی کنید", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "فکر میکنی با گرفتن ضد ضربه شکست ناپذیر میشی ؟ اگه از زمین پرت بشی پایین چی ؟", + "Don't run all the time. Really. You will fall off cliffs.": "تمام وقت درطول بازی با سرعت حرکت نکنید ممکنه از صخره پرت بشید", + "Don't spin for too long; you'll become dizzy and fall.": "زیاد به دور خودت نچرخ؛ سرگیجه می‌گیری و می‌افتی.", + "Hold any button to run. (Trigger buttons work well if you have them)": "هر دکمه رو با زدن روش کار میکنه همه دکمه ها بدرستی کار میکنه اگه صحیح زده بشن", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "موقع حرکت یه دکمه رو همزمان نگهدار مثلا مشت رو تا سرعت حرکت بیشتر شه\nاما توی سرعت زیاد مراقب پایین افتادن از صخره باش", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "بمب های یخی برا نابودی خیلی قدرتمند نیستن ولی نزدیک هر کی منفجر بشه منجمد میشه \n اگه نمیخواید منجمد و آسیب پذیر بشوید نزدیک این بمب ها نمونید", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "اگه کسی شما رو از زمین بلند کرد با مشت و پرش و کشیدن اجازه \nحرکت بهش ندید تا رها بشید", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "اگر روی کنترلرها کوتاه هستید، برنامه '${REMOTE_APP_NAME}' را نصب کنید\nبر روی دستگاه های تلفن همراه خود را میتوان به عنوان کنترلر استفاده کنید.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "اگر بمب چسبنده ای به شما چسبید به اطراف بپرید و بچرخید\n😅کار دیگری از شما بر نمی‌آید", + "If you kill an enemy in one hit you get double points for it.": "اگه حریف رو تنها با یک ضربه نابود کنی امتیاز دو برابر بهت تعلق میگیره برا این حرکت", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "اگه یه جعبه نابودگر رو به اشتباه گرفتین کارتون تمومه مگه اینکه ظرف چند\nثانیه یه جعبه ی درمان گیر بیارید", + "If you stay in one place, you're toast. Run and dodge to survive..": "اگه فقط توی یه مکان ثابت بمونید کباب میشید پس بهتره مرتب توی زمین تحرک داشته باشی", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "اگر تعداد زیادی از بازیکنان در حال رفت و آمد هستند، بازیکنان \"بیروت انداختن بازیکنان غیرفعال\" را روشن کنید\nتحت تنظیمات در صورتی که کسی فراموش می‌کندپیش از خروج از بازی ترک بازی را بزند.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "اگر دستگاه شما بیش از حد گرم می شود یا شما می خواهید برای حفظ قدرت باتری،\nکم کنید \"کیفیت\" یا \"وضوح تصویر\" رو در تنظیمات> گرافیک", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "اگر دیدید که نرخ فریم تصویر کمی متلاطم است کاهش بدید رزولوشن \nیا کیفیت تصویر رو در تنظیمات گرافیک بازی", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "توی بازی رساندن پرچم ، باید پرچم تیم شما همون جا باقی بمونه\nاگه تیم حریف پرچم تیم شما رو برداشت باید از دستش کش بری", + "In hockey, you'll maintain more speed if you turn gradually.": "روی زمین های یخی ، یه دفعه چرخیدن خیلی از سرعت بازیکن کم میکنه", + "It's easier to win with a friend or two helping.": "بازی خیلی راحت تر میشه اگه از یکی دوتا از دوستاتون کمک بگیرید", + "Jump just as you're throwing to get bombs up to the highest levels.": "پرش فقط به درد این می خوره که بمب ها رو بالاتر پرتاب کنی", + "Land-mines are a good way to stop speedy enemies.": "بهترین روش نابود کردن دشمن های سریع ، استفاده از مین زمینی است", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "خیلی چیزها می تونن از زمین برداشته بشن ... حتی بازیکنهای دیگه\nیه راه خوب برای از بین بردن دشمنها اینه که بلندشون کنی و پرتشون کنی توی دره ... که خیلی هم حال میده", + "No, you can't get up on the ledge. You have to throw bombs.": "! فکر کردی خونه ی خاله س ؟ باید بزنی لهشون کنی", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "بازیکن ها میتونن هر زمان وسط بازی وارد بازی بشن\nاگه کسی برای ورود مجدد مشکلی داشت ترک کنه دسته رو ومجدد وارد بشه", + "Practice using your momentum to throw bombs more accurately.": "تمرین کنید با استفاده از شتاب بیشتر دقیق تر پرتاب کنید بمب ها رو", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "برای قوی تر شدن مشت ها باید\nمثل دیوونه ها بدوی و بپری و بچرخی", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "حرکت شلاقی به عقب و جلو برای پرتاب بمب\nبه مسافت بیشتر", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "برای از بین بردن یه گله دشمن\nکافیه نزدیکشون یه جعبه تی.ان.تی بترکونی", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "سر آسیب پذیر ترین قسمت بدن یه بازیکنه بطوریکه \nاگه یه بمب چسبنده به سرش چسبید دیگه کارش تمومه", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "این مرحله هیچ وقت تمام نمی شود\nولی امتیازات بالای آن در سطح جهانی ثبت خواهد شد", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "هر چیزی دستت باشه به اون سمتی پرتاب میشه که داری حرکت میکنی\nاگه میخوای بندازیش جلوی پای خودت اصلا حرکت نکن", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "! از موزیک بازی خوشت نمیاد ؟ خب عوضش کن\nبرو به تنظیمات ، صدا ، موسیقی بازی", + "Try 'Cooking off' bombs for a second or two before throwing them.": "قبل از پرتاب بمب چند لحظه نگهشون دارید بعد پرتاب کنید تا هنگام رسیدن به حریف سریع منفجر شوند", + "Try tricking enemies into killing eachother or running off cliffs.": "سعی کنید جاهایی باشید که دشمنان اشتباهی همدیگر را بزنند یا به پایین پرتاب شوند", + "Use the pick-up button to grab the flag < ${PICKUP} >": "با این دکمه می توانید پرچم را از زمین یا از دست حریف بگیرید< ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "حرکت شلاقی سریع به چپ یا راشت برای پرتاب بمب به مسافت بیشتر", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "شما می تونید مشت های خودتون رو به جهت مشخصی وارد کنید با چرخیدن به چپ و راست\nاین کار برای پرت کردن دشمنان از لبه ی زمین به پایین یا امتیاز گرفت در هاکی موثره", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "با دیدن رنگ جرقه ی بمب میشه فهمید چه موقع منفجر میشه\n!!!! زرد ... نارنجی ... قرمز ... بوم", + "You can throw bombs higher if you jump just before throwing.": "شما می‌تونید بمب‌هاتون رو دورتر پرتاب کنید اگه همزمان با یه پرش به موقع باشه", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "شما آسیب می بینید زمانی که سرتون به چیزی برخورد میکنه پس بیشر احتیاط کنید\nزمانی هم که چیزی به سمتتون پرتاب میشه", + "Your punches do much more damage if you are running or spinning.": "مشت هاتون موثر تر خواهند بود اگر هنگام حرکت سریع و یا چرخش وارد بشن" + } + }, + "trophiesRequiredText": "جام نیاز دارد ${NUMBER} این حداقل به", + "trophiesText": "تندیس و مدال", + "trophiesThisSeasonText": "تندیس ها و مدال های این فصل", + "tutorial": { + "cpuBenchmarkText": "آموزش اجرای بهتر بازی در بدترین وضعیت سرعت بازی در درجه اول تست سرعت پردازنده", + "phrase01Text": "!سلام جیگر", + "phrase02Text": "! خوش آمدی ${APP_NAME} به", + "phrase03Text": ". قبل از شروع ، یک سری آموزش ها هست که باید ببینی", + "phrase04Text": "متکی به اعمال فیزیکی اند ${APP_NAME} چیزای زیادی در", + "phrase05Text": "... مثلا وقتی با مشت میفتی به جون یه نفر", + "phrase06Text": "! این جوری حتی خون از دماغش نمیاد", + "phrase07Text": "... چجوری برات دلقک بازی در میاره ${NAME} نگاه کن", + "phrase08Text": ".باید حالشو بگیری ! پرش و چرخش قدرت مشت رو بیشتر می کنه", + "phrase09Text": "! آهان ! حالا شد", + "phrase10Text": ".دویدن هم موثره", + "phrase11Text": "برای دویدن باید یه دکمه ی دلخواه رو فشار بدی و نگه داری", + "phrase12Text": "! دویدن و چرخیدن باعث میشه که فکش بیاد پایین", + "phrase13Text": "اومد پایین ؟ ${NAME} دیدی چطوری فک", + "phrase14Text": "${NAME} خیلی چیزها رو میشه بلند کرد و پرت کرد . یعنی پرچم یا بازیکنهای دیگه مثل", + "phrase15Text": "! حالا وقت بمبارون کردنه", + "phrase16Text": "بمب انداختن یه کم تمرین لازم داره", + "phrase17Text": "این چه طرز بمب انداختنه ؟", + "phrase18Text": "اگه حرکت کنی بمب دورتر پرت میشه", + "phrase19Text": "اگه بپری بمب بیشتر پرت میشه", + "phrase20Text": "! اگه به صورت شلاقی بمب پرت کنی که دیگه هیچی ... نمی دونی تا کجا میره", + "phrase21Text": "این که چه موقع پرتش کنی خیلی مهمه", + "phrase22Text": "!!! بوم", + "phrase23Text": "قبل از انداختن بمب یه کم نگهش دار ... تا به محض این که به هدف رسید بترکه", + "phrase24Text": "باریکلا ! به این میگن انفجار", + "phrase25Text": "دیدی اصلا سخت نبود ؟", + "phrase26Text": "حالا دیگه مثل یه ببر قوی شدی", + "phrase27Text": "این آموزش ها رو به یاد داشته باش، و مطمئن باش که زنده برمی‌گردی!", + "phrase28Text": "! ببینم چند مرده حلاجی پهلوون", + "phrase29Text": "! خدا قوت", + "randomName1Text": "فرد", + "randomName2Text": "هری", + "randomName3Text": "بیل", + "randomName4Text": "چاک", + "randomName5Text": "فیل", + "skipConfirmText": ".واقعا از آموزش رد می‌شی ؟ هر کلیدی رو بزن تا رد بشیم", + "skipVoteCountText": "نفر خواستار رد شدن از آموزش هستند ${TOTAL} نفر از ${COUNT}", + "skippingText": "از آموزش می گذریم", + "toSkipPressAnythingText": "هر کلیدی را بزنید تا از آموزش خارج شوید" + }, + "twoKillText": "نابودی دونفر همزمان", + "unavailableText": "چیزی در دسترس نیست", + "unconfiguredControllerDetectedText": ":کنترول پیکربندی نشده شناسایی شد", + "unlockThisInTheStoreText": ". این مورد باید در فروشگاه باز شود", + "unlockThisProfilesText": "برای ایجاد بیش از ${NUM} پروفال٫ احتیاج به این موارد دارید:", + "unlockThisText": ": برا باز کردن قفل این شما نیاز دارید که", + "unsupportedHardwareText": "با عرض پوزش، این سخت افزار توسط این ساخت بازی پشتیبانی نمی شود.", + "upFirstText": "برای بار اول :", + "upNextText": "${COUNT} بعدی در بازی", + "updatingAccountText": "... در حال به‌روزرسانی حساب", + "upgradeText": "ارتقا", + "upgradeToPlayText": "بازی را خریداری کنید تا این گزینه فعال شود ${PRO} نسخه ی", + "useDefaultText": "استفاده از پیش فرض", + "usesExternalControllerText": "این بازی از یک کنترلر خارجی برای ورودی استفاده می کند.", + "usingItunesText": "استفاده از برنامه ی موسیقی برای موسیقی متن", + "usingItunesTurnRepeatAndShuffleOnText": "مطمین شید که شافل روشن است و تکرار کنید همه رو در آیتونز", + "v2AccountLinkingInfoText": "برای پیوند دادن حساب‌های V2، از دکمه «مدیریت حساب» استفاده کنید.", + "validatingTestBuildText": "... در حال بررسی حالت آزمایشی", + "victoryText": "! برنده شدی", + "voteDelayText": ".ثانیه رای گیری کنید ${NUMBER} شما نمیتوانید به مدت", + "voteInProgressText": ".یک رای گیری در حال انجام است", + "votedAlreadyText": ".شما رای داده اید", + "votesNeededText": ".رای نیاز است ${NUMBER}", + "vsText": "علیه", + "waitingForHostText": "ادامه بدهد ${HOST} صبر می کنیم تا", + "waitingForPlayersText": "...انتظار برای پیوستن بازیکنان", + "waitingInLineText": "در صف انتظار(پارتی تکمیل است) ...", + "watchAVideoText": "یک ویدئو ببینید", + "watchAnAdText": "تبلیغ ببین", + "watchWindow": { + "deleteConfirmText": "حذف شود؟\"${REPLAY}\"", + "deleteReplayButtonText": "حذف\nبازبخش", + "myReplaysText": "بازی‌های ضبط‌شدهٔ من", + "noReplaySelectedErrorText": "بازپخشی انتخاب نشده", + "playbackSpeedText": "سرعت باز پخش:${SPEED}", + "renameReplayButtonText": "تغییرنام\nبازبخش", + "renameReplayText": ":به \"${REPLAY}\"تغییر نام", + "renameText": "تغییر نام", + "replayDeleteErrorText": "خطا در حذف بازبخش", + "replayNameText": "نام بازبخش", + "replayRenameErrorAlreadyExistsText": "بازبخش با این نام از قبل وجود دارد", + "replayRenameErrorInvalidName": "نمی‌توان نام بازبخش را تغیر داد: نام نامعتبر است", + "replayRenameErrorText": "خطا در تغییر نام بازپخش.", + "sharedReplaysText": "اشتراک گزاری بازی ها", + "titleText": "بازی‌های ضبط‌شده", + "watchReplayButtonText": "تماشای بازی\nضبط‌شده" + }, + "waveText": "دست", + "wellSureText": "! حتما", + "whatIsThisText": "این چیه؟", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "گوش دادن به Wiimotes ...", + "pressText": "دکمه های Wiimote 1 و 2 را به طور همزمان فشار دهید.", + "pressText2": "در Wiimotes جدیدتر با حرکت به علاوه در ساخته شده است، به جای فشار قرمز \"همگام\" را فشار دهید در پشت." + }, + "wiimoteSetupWindow": { + "copyrightText": "ناظر بر کپی رایت", + "listenText": "گوش بده", + "macInstructionsText": "اطمینان حاصل کنید که رشته خود خاموش است و بلوتوث را فعال کنید\nدر مک خود را، و سپس دکمه \"گوش دهید\". پشتیبانی Wiimote می توانید\nیک کمی پوسته پوسته، بنابراین شما ممکن است باید سعی کنید چند بار\nقبل از شما یک اتصال.\nبلوتوث باید به 7 دستگاه های متصل رسیدگی کردن،\nهر چند مسافت پیموده شده شما ممکن است متفاوت باشد.\n\nBombSquad پشتیبانی از Wiimotes اصلی، Nunchuks،\nو کنترل کلاسیک.\nجدیدتر رشته از راه دور علاوه در حال حاضر بیش از حد کار\nاما با فایل پیوست است.", + "thanksText": "تشکر از تیم ناظر\nبرای ایجاد این امکان", + "titleText": "Wiimote Setup" + }, + "winsPlayerText": "${NAME} برنده شد", + "winsTeamText": "${NAME} برنده شد", + "winsText": "${NAME} برنده شد", + "workspaceSyncErrorText": "خطا در همگام‌سازی ${WORKSPACE}. برای جزئیات به لاگ مراجعه کنید.", + "workspaceSyncReuseText": "نمی‌توان ${WORKSPACE} را همگام‌سازی کرد. استفادهٔ مجدد از نسخهٔ همگام‌سازی‌شده قبلی.", + "worldScoresUnavailableText": "امتیاز های جهانی قابل دسترس نیستند.", + "worldsBestScoresText": "بهترین امتیازهای جهانی", + "worldsBestTimesText": "بهترین زمان های جهانی", + "xbox360ControllersWindow": { + "getDriverText": "درایور", + "macInstructions2Text": "برای استفاده از کنترلرها به صورت بی سیم، شما همچنین باید گیرنده را دریافت کنید\nXbox 360 Wireless Controller for Windows می آید.\nیک گیرنده به شما اجازه می دهد تا تا 4 کنترل کننده را وصل کنید.\n\nمهم: گیرنده های شخص ثالث با این راننده کار نخواهند کرد؛\nاطمینان حاصل کنید که گیرنده شما \"مایکروسافت\" را در آن می گوید، نه \"XBOX 360\".\nمایکروسافت این را به طور جداگانه به فروش نمی رساند، بنابراین شما باید آن را دریافت کنید\nیک همراه با کنترلر و یا دیگری جستجو بی.\n\nاگر این مفید را پیدا کنید، لطفا کمک مالی به آن بدهید\nتوسعه دهنده راننده در سایت خود.", + "macInstructionsText": "برای استفاده از کنترلر Xbox 360، باید نصب کنید\nدرایور Mac موجود در لینک زیر است.\nبا کنترلر های سیمی و بی سیم کار می کند.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "برای استفاده از کنترلر Xbox 360 با BombSquad، به سادگی\nآنها را به پورت USB دستگاهتان وصل کنید. شما می توانید یک هاب USB استفاده کنید\nبرای اتصال چندین کنترل کننده.\n\nبرای استفاده از کنترلرهای بی سیم، به یک گیرنده بی سیم نیاز دارید\nبه عنوان بخشی از \"کنسول بی سیم Xbox 360 برای ویندوز\"\nبسته بندی یا فروش جداگانه. هر گیرنده به یک پورت USB وصل می شود\nاجازه می دهد تا به 4 کنترل کننده بی سیم وصل شوید.", + "titleText": "${APP_NAME}:استفاده از کنترولر های ایکس باکس با" + }, + "yesAllowText": "!بله, اجازه داده میشود", + "yourBestScoresText": "بهترین امتیاز شما", + "yourBestTimesText": "بهترین زمان شما" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/polish.json b/dist/ba_data/data/languages/polish.json new file mode 100644 index 0000000..e5bee29 --- /dev/null +++ b/dist/ba_data/data/languages/polish.json @@ -0,0 +1,1981 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Nazwy kont nie mogą zawierać emotikonków ani innych znaków specjalnych", + "accountProfileText": "(profil konta)", + "accountsText": "Konta", + "achievementProgressText": "Osiągnięcia: ${COUNT} z ${TOTAL}", + "campaignProgressText": "Postęp Kampanii [Trudny]: ${PROGRESS}", + "changeOncePerSeason": "Możesz to zmienić tylko raz na sezon.", + "changeOncePerSeasonError": "Musisz poczekać do następnego sezonu by znowu to zmienić (${NUM} dni)", + "customName": "Losowa Nazwa", + "googlePlayGamesAccountSwitchText": "Jeśli chcesz użyć innego konta Google,\nużyj aplikacji Gry Google Play, aby przełączyć się na to konto.", + "linkAccountsEnterCodeText": "Wpisz Kod", + "linkAccountsGenerateCodeText": "Wygeneruj Kod", + "linkAccountsInfoText": "(przenoś postęp między różnymi platformami)", + "linkAccountsInstructionsNewText": "Aby połączyć dwa konta, wygeneruj kod na pierwszym,\ni wpisz ten kod na drugim. Postęp z drugiego\nbędzie podzielony między oba konta.\n(Postęp z pierwszego zostanie utracony)\n\nMożesz połączyć do ${COUNT} kont.\n\nWAŻNE: łącz tylko swoje własne konta;\nJeśli łączysz konto ze znajomym, nie będziecie\nmogli grać przez internet w tym samym czasie.", + "linkAccountsInstructionsText": "By połączyć dwa konta, wygeneruj kod\nna jednym z nich i wpisz na drugim.\nPostęp i ekwipunek zostaną połączone.\nMożesz połączyć do ${COUNT} kont.\n\nUWAGA: Łącz tylko konta, które należą do Ciebie!\nJeśli połączysz konto z przyjacielem,\nnie będziecie mogli grać w tym samym czasie!\n\nAktualnie nie można tego cofnąć, więc uważaj!", + "linkAccountsText": "Połącz Konta", + "linkedAccountsText": "Połączone Konta:", + "manageAccountText": "Zarządzaj Kontem", + "nameChangeConfirm": "Zmienić twoją nazwę konta na ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Spowoduje to wyczyszczenie postępu i lokalnych\nrekordów w trybie Kooperacji (kupony pozostaną).\nOperacja nieodwracalna. Jesteś pewny?", + "resetProgressConfirmText": "Spowoduje wyczyszczenie postępu,\nosiągnięć i lokalnych rekordów w\ntrybie Kooperacji (kupony pozostaną).\nOperacja nieodwracalna. Jesteś pewny?", + "resetProgressText": "Wyczyść postęp", + "setAccountName": "Wybierz nazwę konta", + "setAccountNameDesc": "Wybierz nazwę do wyświetlenia dla swojego konta.\nMożesz użyć nazwy z jednego z połączonych kont\n lub utworzyć unikalną niestandardową nazwę.", + "signInInfoText": "Zapisz się, by zbierać kupony, rywalizować online\ni przenosić postęp gry między urządzeniami", + "signInText": "Zapisz się", + "signInWithDeviceInfoText": "(automatyczne konto dostępne tylko z tego urządzenia)", + "signInWithDeviceText": "Zapisz się kontem z urządzenia.", + "signInWithGameCircleText": "Zapisz się z Game Circle", + "signInWithGooglePlayText": "Zapisz się kontem Google Play", + "signInWithTestAccountInfoText": "Konto.", + "signInWithTestAccountText": "Zapisz się testowym kontem.", + "signInWithV2InfoText": "(konto działa na wszystkich platformach)", + "signInWithV2Text": "Zaloguj się używając konta BombSquad", + "signOutText": "Wypisz się", + "signingInText": "Zapisywanie się...", + "signingOutText": "Wypisywanie...", + "testAccountWarningCardboardText": "Ostrzeżenie: Zapisujesz się przy użyciu konta \"test\".\nZostanie ono zastąpione kontem Google w momencie\nwspierania gry przez Google Cardboard.\n\nOd tego momentu musisz zdobywać wszystkie kupony w grze.\n(zaktualizuj grę do wersji BombSquad Pro za darmo)", + "testAccountWarningOculusText": "Ostrzeżenie: zapisujesz się przy użyciu konta \"test\".\nZostanie ono zastąpione kontem oculusowym jeszcze w tym roku,\nktóre będzie oferowało zakup kuponów i inne funkcje.\n\nTeraz musisz zarobić wszystkie kupony grając.\n(jednakże możesz uzyskać aktualizację do wersji Pro za darmo)", + "testAccountWarningText": "Ostrzeżenie: możesz się zapisać używając konta \"test\".\nTo konto jest powiązane z konkretnym urządzeniem i \nmoże okresowo się zresetować. (wobec tego proszę nie\nzbierać/odblokowywać rzeczy lub osiągnięć dla tego konta)", + "ticketsText": "Kuponów: ${COUNT}", + "titleText": "Konto", + "unlinkAccountsInstructionsText": "Wybierz konto do rozłączenia", + "unlinkAccountsText": "Rozłącz konta", + "unlinkLegacyV1AccountsText": "Rozłącz stare konta (V1)", + "v2LinkInstructionsText": "Użyj tego linku aby stworzyć konto lub zaloguj się.", + "viaAccount": "(przez konto ${NAME})", + "youAreLoggedInAsText": "Jesteś zalogowany jako:", + "youAreSignedInAsText": "Jesteś zalogowany jako:" + }, + "achievementChallengesText": "Lista Osiągnięć i Wyzwań", + "achievementText": "Osiągnięcia", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Zabij 3 złych gości używając TNT", + "descriptionComplete": "Zabiłeś 3 złych gości używając TNT", + "descriptionFull": "Zabij 3 złych gości za pomocą TNT w trybie ${LEVEL}", + "descriptionFullComplete": "Zabiłeś 3 złych gości za pomocą TNT w trybie ${LEVEL}", + "name": "Uwaga Leci Dynamit" + }, + "Boxer": { + "description": "Wygraj bez używania bomb", + "descriptionComplete": "Wygrałeś bez używania bomb", + "descriptionFull": "Ukończ ${LEVEL} bez używania żadnych bomb", + "descriptionFullComplete": "Ukończyłeś ${LEVEL} bez używania żadnych bomb", + "name": "Bokser" + }, + "Dual Wielding": { + "descriptionFull": "Podłącz dwa kontrolery (fizyczne lub BSRemote)", + "descriptionFullComplete": "Podłączono dwa kontrolery (fizyczne lub BSRemote)", + "name": "Podwójne dzierżenie" + }, + "Flawless Victory": { + "description": "Wygraj nie dając się uderzyć", + "descriptionComplete": "Wygrałeś nie dając się uderzyć", + "descriptionFull": "Wygraj w trybie ${LEVEL} nie dając się uderzyć", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} nie dając się uderzyć", + "name": "Zwycięstwo bez skazy" + }, + "Free Loader": { + "descriptionFull": "Zacznij grę Free-For-All z dwoma graczami lub więcej", + "descriptionFullComplete": "Zaczęto grę Free-For-All z dwoma, lub większą ilością graczy", + "name": "Łącznik graczy" + }, + "Gold Miner": { + "description": "Zabij 6 złych gości minami lądowymi.", + "descriptionComplete": "Zabiłeś 6 złych gości minami lądowymi.", + "descriptionFull": "Zabij 6 złych gości za pomocą min lądowych w trybie ${LEVEL}", + "descriptionFullComplete": "Zabiłeś 6 złych gości za pomocą min lądowych w trybie ${LEVEL}", + "name": "Złoty Saper" + }, + "Got the Moves": { + "description": "Wygraj bez użycia pięści i bomb", + "descriptionComplete": "Wygrałeś bez użycia pięści i bomb", + "descriptionFull": "Wygraj w trybie ${LEVEL} bez użycia pięści i bomb", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} bez użycia pięści i bomb", + "name": "Masz Ruchy" + }, + "In Control": { + "descriptionFull": "Podłącz kontroler (fizyczny lub BSRemote)", + "descriptionFullComplete": "Podłączono kontroler (fizyczny lub BSRemote)", + "name": "Pod kontrolą" + }, + "Last Stand God": { + "description": "Zdobądź 1000 punktów", + "descriptionComplete": "Zdobyłeś 1000 punktów", + "descriptionFull": "Zdobądź 1000 punktów w trybie ${LEVEL}", + "descriptionFullComplete": "Zdobyłeś 1000 punktów w trybie ${LEVEL}", + "name": "Bóg trybu ${LEVEL}" + }, + "Last Stand Master": { + "description": "Zdobądź 250 punktów", + "descriptionComplete": "Zdobyłeś 250 punktów", + "descriptionFull": "Zdobądź 250 punktów w trybie ${LEVEL}", + "descriptionFullComplete": "Zdobyłeś 250 punktów w trybie ${LEVEL}", + "name": "Mistrz trybu ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Zdobądź 500 punktów", + "descriptionComplete": "Zdobyłeś 500 punktów", + "descriptionFull": "Zdobądź 500 punktów w trybie ${LEVEL}", + "descriptionFullComplete": "Zdobyłeś 500 punktów w trybie ${LEVEL}", + "name": "Czarodziej trybu ${LEVEL}" + }, + "Mine Games": { + "description": "Zabij 3 złych gości minami lądowymi", + "descriptionComplete": "Zabiłeś 3 złych gości minami lądowymi", + "descriptionFull": "Zabij 3 złych gości za pomocą min lądowych w trybie ${LEVEL}", + "descriptionFullComplete": "Zabiłeś 3 złych gości za pomocą min lądowych w trybie ${LEVEL}", + "name": "Saperskie Gierki" + }, + "Off You Go Then": { + "description": "Wyrzuć 3 złych gości poza mapę", + "descriptionComplete": "Wyrzuciłeś 3 złych gości z mapy", + "descriptionFull": "Zrzuć 3 złych gości z mapy w trybie ${LEVEL}", + "descriptionFullComplete": "Zrzuciłeś 3 złych gości z mapy w trybie ${LEVEL}", + "name": "Spadaj!" + }, + "Onslaught God": { + "description": "Zdobądź 5000 punktów", + "descriptionComplete": "Zdobyłeś 5000 punktów", + "descriptionFull": "Zdobądź 5000 punktów w trybie ${LEVEL}", + "descriptionFullComplete": "Zdobyłeś 5000 punktów w trybie ${LEVEL}", + "name": "Bóg trybu ${LEVEL}" + }, + "Onslaught Master": { + "description": "Zdobądź 500 punktów", + "descriptionComplete": "Zdobyłeś 500 punktów", + "descriptionFull": "Zdobądź 500 punktów w trybie ${LEVEL}", + "descriptionFullComplete": "Zdobyłeś 500 punktów w trybie ${LEVEL}", + "name": "Mistrz trybu ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Pokonaj wszystkie fale", + "descriptionComplete": "Pokonałeś wszystkie fale", + "descriptionFull": "Pokonaj wszystkie fale w trybie ${LEVEL}", + "descriptionFullComplete": "Pokonałeś wszystkie fale w trybie ${LEVEL}", + "name": "Zwycięstwo w trybie ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Zdobądź 1000 punktów", + "descriptionComplete": "Zdobyłeś 1000 punktów", + "descriptionFull": "Zdobądź 1000 punktów w trybie ${LEVEL}", + "descriptionFullComplete": "Zdobyłeś 1000 punktów w trybie ${LEVEL}", + "name": "Czarodziej trybu ${LEVEL}" + }, + "Precision Bombing": { + "description": "Wygraj bez używania bonusów", + "descriptionComplete": "Wygrałeś bez używania bonusów", + "descriptionFull": "Wygraj w trybie ${LEVEL} bez pomocy bonusów", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} bez pomocy bomb", + "name": "Precyzyjne Bombardowanie" + }, + "Pro Boxer": { + "description": "Wygraj bez używania bomb", + "descriptionComplete": "Wygrałeś bez używania bomb", + "descriptionFull": "Ukończ tryb ${LEVEL} bez używania bomb", + "descriptionFullComplete": "Ukończyłeś tryb ${LEVEL} bez używania bomb", + "name": "Zawodowy Bokser" + }, + "Pro Football Shutout": { + "description": "Wygraj nie pozwalając zapunktować złym gościom", + "descriptionComplete": "Wygrałeś nie pozwalając zapunktować złym gościom", + "descriptionFull": "Wygraj w trybie ${LEVEL} nie pozwalając zapunktować złym gościom", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} nie pozwalając zapunktować złym gościom", + "name": "Zamurowanie bramki w trybie ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Wygraj mecz", + "descriptionComplete": "Wygrałeś mecz", + "descriptionFull": "Wygraj mecz w trybie ${LEVEL}", + "descriptionFullComplete": "Wygrałeś mecz w trybie ${LEVEL}", + "name": "Zwycięstwo w trybie ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Pokonaj wszystkie fale", + "descriptionComplete": "Pokonałeś wszystkie fale", + "descriptionFull": "Pokonaj wszystkie fale w trybie ${LEVEL}", + "descriptionFullComplete": "Pokonałeś wszystkie fale w trybie ${LEVEL}", + "name": "Zwycięstwo w trybie ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Przetrwaj wszystkie fale", + "descriptionComplete": "Ukończyłeś wszystkie fale", + "descriptionFull": "Przetrwaj wszystkie fale w trybie ${LEVEL}", + "descriptionFullComplete": "Ukończyłeś wszystkie fale w trybie ${LEVEL}", + "name": "Zwycięstwo w trybie ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Wygraj nie pozwalając zapunktować wrogom", + "descriptionComplete": "Wygrałeś nie pozwalając zapunktować wrogom", + "descriptionFull": "Wygraj w trybie ${LEVEL} nie pozwalając zapunktować złym gościom", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} nie pozwalając zapunktować wrogom", + "name": "Zamurowanie bramki w trybie ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Wygraj mecz", + "descriptionComplete": "Wygrałeś mecz", + "descriptionFull": "Wygraj mecz w trybie ${LEVEL}", + "descriptionFullComplete": "Wygrałeś mecz w trybie ${LEVEL}", + "name": "Zwycięstwo w trybie ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Pokonaj wszystkie fale", + "descriptionComplete": "Pokonałeś wszystkie fale", + "descriptionFull": "Pokonaj wszystkie fale w trybie ${LEVEL}", + "descriptionFullComplete": "Pokonałeś wszystkie fale w trybie ${LEVEL}", + "name": "Zwycięstwo w trybie ${LEVEL}" + }, + "Runaround God": { + "description": "Zdobądź 2000 punktów", + "descriptionComplete": "Zdobyłeś 2000 punktów", + "descriptionFull": "Zdobądź 2000 punktów w trybie ${LEVEL}", + "descriptionFullComplete": "Zdobyłeś 2000 punktów w trybie ${LEVEL}", + "name": "Bóg trybu ${LEVEL}" + }, + "Runaround Master": { + "description": "Zdobądź 500 punktów", + "descriptionComplete": "Zdobyłeś 500 punktów", + "descriptionFull": "Zdobądź 500 punktów w trybie ${LEVEL}", + "descriptionFullComplete": "Zdobyłeś 500 punktów w trybie ${LEVEL}", + "name": "Mistrz trybu ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Zdobądź 1000 punktów", + "descriptionComplete": "Zdobyłeś 1000 punktów", + "descriptionFull": "Zdobądź 1000 punktów w trybie ${LEVEL}", + "descriptionFullComplete": "Zdobyłeś 1000 punktów w trybie ${LEVEL}", + "name": "Czarodziej trybu ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Poleć grę kumplowi", + "descriptionFullComplete": "Polecono grę kumplowi", + "name": "Troska o dzielenie" + }, + "Stayin' Alive": { + "description": "Wygraj bez umierania", + "descriptionComplete": "Wygrałeś bez umierania", + "descriptionFull": "Wygraj w trybie ${LEVEL} bez umierania", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} bez umierania", + "name": "Pozostań przy życiu" + }, + "Super Mega Punch": { + "description": "Zadaj jednym ciosem 100% obrażeń", + "descriptionComplete": "Zadałeś jednym ciosem 100% obrażeń", + "descriptionFull": "Zadaj jednym ciosem 100% obrażeń w trybie ${LEVEL}", + "descriptionFullComplete": "Zadałeś jednym ciosem 100% obrażeń w trybie ${LEVEL}", + "name": "Super Mega Cios" + }, + "Super Punch": { + "description": "Zadaj jednym ciosem 50% obrażeń", + "descriptionComplete": "Zadałeś jednym ciosem 50% obrażeń", + "descriptionFull": "Zadaj jednym ciosem 50% obrażeń w trybie ${LEVEL}", + "descriptionFullComplete": "Zadałeś jednym ciosem 50% obrażeń w trybie ${LEVEL}", + "name": "Super Cios" + }, + "TNT Terror": { + "description": "Zabij 6 złych gości używając TNT", + "descriptionComplete": "Zabiłeś 6 złych gości używając TNT", + "descriptionFull": "Zabij 6 złych gości używając TNT w trybie ${LEVEL}", + "descriptionFullComplete": "Zabiłeś 6 złych gości używając TNT w trybie ${LEVEL}", + "name": "Terror TNT" + }, + "Team Player": { + "descriptionFull": "Rozpocznij grę drużynową z czwórką lub większą ilością graczy", + "descriptionFullComplete": "Rozpoczęto grę drużynową z czwórką lub większą ilością graczy", + "name": "Gracz drużynowy" + }, + "The Great Wall": { + "description": "Zatrzymaj każdego złego gościa", + "descriptionComplete": "Zatrzymałeś każdego złego gościa", + "descriptionFull": "Zatrzymaj każdego złego gościa w trybie ${LEVEL}", + "descriptionFullComplete": "Zatrzymałeś każdego złego gościa w trybie ${LEVEL}", + "name": "Wielki Mur" + }, + "The Wall": { + "description": "Zatrzymaj każdego złego gościa", + "descriptionComplete": "Zatrzymałeś każdego złego gościa", + "descriptionFull": "Zatrzymaj każdego złego gościa w trybie ${LEVEL}", + "descriptionFullComplete": "Zatrzymałeś każdego złego gościa w trybie ${LEVEL}", + "name": "Ściana" + }, + "Uber Football Shutout": { + "description": "Wygraj nie pozwalając zapunktować wrogom", + "descriptionComplete": "Wygrałeś nie pozwalając zapunktować wrogom", + "descriptionFull": "Wygraj w trybie ${LEVEL} nie pozwalając zapunktować wrogom", + "descriptionFullComplete": "Wygrałeś w trybie ${LEVEL} nie pozwalając zapunktować wrogom", + "name": "Zamurowanie bramki w trybie ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Wygraj mecz", + "descriptionComplete": "Wygrałeś mecz", + "descriptionFull": "Wygraj mecz w trybie ${LEVEL}", + "descriptionFullComplete": "Wygrałeś mecz w trybie ${LEVEL}", + "name": "Zwycięstwo w trybie ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Pokonaj wszystkie fale", + "descriptionComplete": "Pokonałeś wszystkie fale", + "descriptionFull": "Pokonaj wszystkie fale w trybie ${LEVEL}", + "descriptionFullComplete": "Pokonałeś wszystkie fale w trybie ${LEVEL}", + "name": "Zwycięstwo w trybie ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Przetrwaj wszystkie fale", + "descriptionComplete": "Przetrwałeś wszystkie fale", + "descriptionFull": "Przetrwaj wszystkie fale w trybie ${LEVEL}", + "descriptionFullComplete": "Przetrwałeś wszystkie fale w trybie ${LEVEL}", + "name": "Zwycięstwo w ${LEVEL}" + } + }, + "achievementsRemainingText": "Pozostałe Osiągnięcia:", + "achievementsText": "Osiągnięcia", + "achievementsUnavailableForOldSeasonsText": "Wybacz, lecz szczegóły osiągnięć nie są dostępne dla starych sezonów.", + "activatedText": "${THING} aktywowane/a", + "addGameWindow": { + "getMoreGamesText": "Więcej rozgrywek...", + "titleText": "Dodaj grę" + }, + "allowText": "Zezwól", + "alreadySignedInText": "Twoje konto jest zalogowane z innego urządzenia;\nproszę zmienić konta lub zamknąć grę na innych\nurządzeniach i spróbować ponownie.", + "apiVersionErrorText": "Nie mogę załadować modułu ${NAME}; wersja używana - ${VERSION_USED}; wymagana - ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" aktywuj tylko wtedy, gdy są podłączone słuchawki)", + "headRelativeVRAudioText": "Head-Relative VR Audio", + "musicVolumeText": "Głośność muzyki", + "soundVolumeText": "Głośność dźwięku", + "soundtrackButtonText": "Ścieżki dźwiękowe", + "soundtrackDescriptionText": "(przypisz własne utwory aby je odtwarzać podczas rozgrywki)", + "titleText": "Audio" + }, + "autoText": "Auto", + "backText": "Wróć", + "banThisPlayerText": "Zbanuj tego gracza", + "bestOfFinalText": "Wyniki Najlepszych-z-${COUNT} Finału", + "bestOfSeriesText": "Wyniki Najlepszych z ${COUNT} serii:", + "bestOfUseFirstToInstead": 0, + "bestRankText": "Najlepsza pozycja w rankingu: ${RANK}", + "bestRatingText": "Twoja najlepsza pozycja w generalnej klasyfikacji: ${RATING}", + "betaErrorText": "Ta wersja beta jest nieaktywna; sprawdź czy istnieje nowa wersja.", + "betaValidateErrorText": "Nie można zweryfikować wersji beta. (brak połączenia z internetem?)", + "betaValidatedText": "Wersja Beta zatwierdzona; Dobrej zabawy!", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Dopalacz", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} jest konfigurowany w samej aplikacji.", + "buttonText": "Przycisk", + "canWeDebugText": "Chcesz aby BombSquad automatycznie raportował błędy,\nawarie i podstawowe informacje o użytkowaniu deweloperowi?\n\nPrzesyłane dane nie będą zawierać Twoich osobistych danych,\na pomogą jedynie poprawić działanie gry i usunąć jej błędy.", + "cancelText": "Anuluj", + "cantConfigureDeviceText": "Wybacz ale ${DEVICE} nie jest konfigurowalne.", + "challengeEndedText": "To wyzwanie zostało zakończone.", + "chatMuteText": "Wycisz Czat", + "chatMutedText": "Czat Wyciszony", + "chatUnMuteText": "Podgłośnij Czat", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Musisz ukończyć ten\netap aby kontynuować!", + "completionBonusText": "Bonusowe zakończenie", + "configControllersWindow": { + "configureControllersText": "Konfiguracja Kontrolerów", + "configureGamepadsText": "Skonfiguruj gamepady", + "configureKeyboard2Text": "Skonfiguruj klawiaturę P2", + "configureKeyboardText": "Skonfiguruj klawiaturę P1", + "configureMobileText": "Urządzenia mobilne jako Kontrolery", + "configureTouchText": "Skonfiguruj ekran dotykowy", + "ps3Text": "Kontrolery PS3", + "titleText": "Kontrolery", + "wiimotesText": "Kontrolery Wiimote", + "xbox360Text": "Kontrolery Xbox360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Uwaga: wsparcie kontrolera uzależnione jest od urządzenia i wersji Androida.", + "pressAnyButtonText": "Naciśnij dowolny na kontrolerze,\nktórego chcesz skonfigurować...", + "titleText": "Skonfiguruj Kontrolery" + }, + "configGamepadWindow": { + "advancedText": "Zaawansowane", + "advancedTitleText": "Zaawansowane ustawienia Kontrolera", + "analogStickDeadZoneDescriptionText": "(włącz jeśli Twoja postać dryfuje po zwolnieniu drążka)", + "analogStickDeadZoneText": "Martwa strefa analogowego drążka", + "appliesToAllText": "(zastosuj dla wszystkich kontrolerów tego typu)", + "autoRecalibrateDescriptionText": "(aktywuj jeśli Twoja postać nie porusza się z pełną szybkością)", + "autoRecalibrateText": "Auto kalibracja drążka analogowego", + "axisText": "oś", + "clearText": "wyczyść", + "dpadText": "dpad", + "extraStartButtonText": "Dodatkowy przycisk Start", + "ifNothingHappensTryAnalogText": "Jeśli nic się nie dzieje, spróbuj przypisać zamiast drążka analogowego.", + "ifNothingHappensTryDpadText": "Jeśli nic się nie dzieje, spróbuj przypisać zamiast d-pada.", + "ignoreCompletelyDescriptionText": "(uniemożliw wpływ tego kontrolera na grę lub menu)", + "ignoreCompletelyText": "Ignoruj całkowicie", + "ignoredButton1Text": "Pomijany przycisk 1", + "ignoredButton2Text": "Pomijany przycisk 2", + "ignoredButton3Text": "Pomijany przycisk 3", + "ignoredButton4Text": "Pomijany Przycisk 4", + "ignoredButtonDescriptionText": "(użyj tego aby zapobiec wpływaniu przycisków 'home' lub 'sync' na UI)", + "ignoredButtonText": "Przycisk ignorowania", + "pressAnyAnalogTriggerText": "Naciśnij dowolny analogowy spust...", + "pressAnyButtonOrDpadText": "Naciśnij dowolny przycisk lub dpad...", + "pressAnyButtonText": "Naciśnij dowolny przycisk...", + "pressLeftRightText": "Naciśnij lewo lub prawo...", + "pressUpDownText": "Naciśnij w górę lub w dół...", + "runButton1Text": "Uruchom przycisk 1", + "runButton2Text": "Uruchom przycisk 2", + "runTrigger1Text": "Uruchom spust 1", + "runTrigger2Text": "Uruchom spust 2", + "runTriggerDescriptionText": "(analogowe triggery pozwalają na uruchomione przy różnych prędkościach)", + "secondHalfText": "Użyj aby skonfigurować drugiego kontrolera,\nktóry widoczny jest jako pierwszy będąc\npodłączonym do tego samego urządzenia.", + "secondaryEnableText": "Aktywuj", + "secondaryText": "Drugi Kontroler", + "startButtonActivatesDefaultDescriptionText": "(wyłącz jeśli przycisk 'start' używany jest jako przycisk 'menu')", + "startButtonActivatesDefaultText": "Przycisk Start aktywuje domyślny widget", + "titleText": "Ustawienia Kontrolera", + "twoInOneSetupText": "Ustawienia kontrolerów 2-w-1", + "uiOnlyDescriptionText": "(zapobiegnij temu kontrolerowi dołączenia do gry)", + "uiOnlyText": "Limit używania Menu", + "unassignedButtonsRunText": "Uruchamianie wszystkich nieprzypisanych przycisków", + "unsetText": "", + "vrReorientButtonText": "Przycisk resetu orientacji VR" + }, + "configKeyboardWindow": { + "configuringText": "Konfiguracja: ${DEVICE}", + "keyboard2NoteText": "Uwaga: większość klawiatur pozwala na\njednoczesne naciśnięcie tylko kilku klawiszy.\nLepszym rozwiązaniem będzie podłączenie dodatkowej klawiatury.\nPamiętać należy o tym, że w obydwu przypadkach\ntrzeba przypisać klawisze dla obydwu graczy." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Skala przycisków akcji", + "actionsText": "Akcje", + "buttonsText": "przyciski", + "dragControlsText": "< przeciągnij kontrolki aby zmienić ich położenie >", + "joystickText": "joystick", + "movementControlScaleText": "Skala przycisków poruszania się", + "movementText": "Przesunięcie", + "resetText": "Resetuj", + "swipeControlsHiddenText": "Ukryj ikony przycisków", + "swipeInfoText": "Kontrolowanie poprzez styl 'Swipe' wymaga przyzwyczajenia\nlecz łatwiej się wówczas gra nie zwracając uwagi na kontrolki.", + "swipeText": "swipe", + "titleText": "Skonfiguruj ekran dotykowy", + "touchControlsScaleText": "Skala przycisków dotykowych" + }, + "configureItNowText": "Skonfigurować teraz?", + "configureText": "Skonfiguruj", + "connectMobileDevicesWindow": { + "amazonText": "Sklep Amazon", + "appStoreText": "App Store", + "bestResultsText": "Dla lepszych efektów stwórz szybką sieć bezprzewodową.\nMożesz zredukować opóźnienia w grze poprzez: wyłączenie innych\nurządzeń korzystających w czasie gry z sieci wifi, będąc\nodpowiednio blisko routera wifi lub podpięcie się do hosta\nbezpośrednio przewodem sieciowym.", + "explanationText": "Aby użyć smartfona lub tableta jako kontrolera w grze,\nzainstaluj na nim aplikację ${REMOTE_APP_NAME}. Do gry ${APP_NAME} można\nprzyłączyć dowolną ilość urządzeń poprzez sieć WiFi i to całkowicie za darmo!", + "forAndroidText": "dla Androida:", + "forIOSText": "dla iOS:", + "getItForText": "Pobierz ${REMOTE_APP_NAME} dla systemu iOS ze sklepu Apple, a \ndla systemu Android ze sklepu Google Play lub Amazon Appstore.", + "googlePlayText": "Google Play", + "titleText": "Używanie urządzeń mobilnych jako kontrolerów:" + }, + "continuePurchaseText": "Kontynuować za ${PRICE}?", + "continueText": "Kontynuuj", + "controlsText": "Przyciski", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Powyższe nie ma zastosowania do rankingu wszechczasów.", + "activenessInfoText": "Ten mnożnik wzrasta w dniach, kiedy grasz\ni spada w dni, kiedy nie grasz.", + "activityText": "Aktywność", + "campaignText": "Kampania", + "challengesInfoText": "Zdobywaj nagrody za wykonywanie mini-gier.\n\nNagrody i poziomy trudności wzrastają\nza każdym razem kiedy wyzwanie jest ukończone i \nzmniejszają kiedy wygasa bądź jest umorzone.", + "challengesText": "Wyzwania", + "currentBestText": "Obecnie Najlepszy", + "customText": "Własne", + "entryFeeText": "Wpis", + "forfeitConfirmText": "Umorzyć to wyzwanie?", + "forfeitNotAllowedYetText": "To wyzwanie nie może być jeszcze umorzone.", + "forfeitText": "Umorzyć", + "multipliersText": "Mnożniki", + "nextChallengeText": "Następne wyzwanie", + "nextPlayText": "Następna gra", + "ofTotalTimeText": "z ${TOTAL}", + "playNowText": "Zagraj teraz", + "pointsText": "Punkty", + "powerRankingFinishedSeasonUnrankedText": "(sezon zakończony, poza rankingiem)", + "powerRankingNotInTopText": "(nie jesteś na liście top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pkt", + "powerRankingPointsMultText": "(x ${NUMBER} pkt)", + "powerRankingPointsText": "${NUMBER} pkt", + "powerRankingPointsToRankedText": "(${CURRENT} z ${REMAINING} pkt)", + "powerRankingText": "Osiągnięcia", + "prizesText": "Nagrody", + "proMultInfoText": "Gracze z aktualizacją ${PRO} otrzymują\n${PERCENT}% punktów więcej.", + "seeMoreText": "Więcej...", + "skipWaitText": "Pomiń oczekiwanie", + "timeRemainingText": "Pozostały czas", + "titleText": "Kooperacja", + "toRankedText": "Do awansu", + "totalText": "Suma", + "tournamentInfoText": "Graj o wysokie wyniki z\ninnymi graczami z twojej ligi.\n\nNagrody dostają gracze z najlepszymi\nwynikami kiedy zawody się kończą.", + "welcome1Text": "Witaj w ${LEAGUE}. Możesz podnieść swój ligowy\nranking zdobywając gwiazdki, kompletując osiągnięcia\ni wygrywając trofea w turniejach.", + "welcome2Text": "Możesz również zdobywać kupony z wielu tych samych działań.\nKupony mogą zostać użyte do: odblokowywania nowych postaci,\nmap, mini-gierek, uczestniczenia w turniejach i innych.", + "yourPowerRankingText": "Twoje miejsce:" + }, + "copyConfirmText": "Skopiowano do schowka.", + "copyOfText": "${NAME} - kopia", + "copyText": "Kopiuj", + "createAPlayerProfileText": "Utworzyć profil gracza?", + "createEditPlayerText": "", + "createText": "Utwórz", + "creditsWindow": { + "additionalAudioArtIdeasText": "Dodatkowe udźwiękowienie, wczesna szata graficzna i pomysł - ${NAME}", + "additionalMusicFromText": "Dodatkowa muzyka - ${NAME}", + "allMyFamilyText": "Całej mojej rodzinie i wszystkim znajomym, którzy graniem pomogli w testach", + "codingGraphicsAudioText": "Kodowanie, grafika i udźwiękowienie - ${NAME}", + "languageTranslationsText": "Tłumaczenia na inne języki:", + "legalText": "Prawa autorskie:", + "publicDomainMusicViaText": "Podkład muzyczny - ${NAME}", + "softwareBasedOnText": "To oprogramowanie jest częściowo oparte na pracy ${NAME}", + "songCreditText": "${TITLE} wykonywana przez ${PERFORMER}.\nSkomponowana przez ${COMPOSER}. Zorganizowana przez ${ARRANGER}.\nOpublikowana przez ${PUBLISHER}.\nDzięki uprzejmości ${SOURCE}", + "soundAndMusicText": "Dźwięk i muzyka:", + "soundsText": "Dźwięki (${SOURCE}):", + "specialThanksText": "Specjalne podziękowania dla:", + "thanksEspeciallyToText": "Szczególne podziękowania dla ${NAME}", + "titleText": "Informacje o ${APP_NAME}", + "whoeverInventedCoffeeText": "Temu kto wymyślił kawę ;)" + }, + "currentStandingText": "Twoja obecna pozycja w rankingu: #${RANK}", + "customizeText": "Własne...", + "deathsTallyText": "${COUNT} zgonów", + "deathsText": "Zgonów", + "debugText": "debuguj", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Uwaga: zalecane jest ustawienie 'Ustawienia->Grafika->Tekstury' na 'Wysokie' aby wykonać test.", + "runCPUBenchmarkText": "Benchmark Procesora", + "runGPUBenchmarkText": "Benchmark Grafiki", + "runMediaReloadBenchmarkText": "Wykonaj Benchmark Media-Reload", + "runStressTestText": "Przeprowadź test wydajności", + "stressTestPlayerCountText": "Liczba graczy", + "stressTestPlaylistDescriptionText": "Lista testów maks. wydajności", + "stressTestPlaylistNameText": "Nazwa listy", + "stressTestPlaylistTypeText": "Typ listy", + "stressTestRoundDurationText": "Czas trwania rundy", + "stressTestTitleText": "Test wysokiej wydajności", + "titleText": "Benchmarki & testy wydajności", + "totalReloadTimeText": "Ogólny czas przeładowania: ${TIME} (szczegóły w pliku log)", + "unlockCoopText": "Odblokuj poziomy trybu Kooperacji" + }, + "defaultFreeForAllGameListNameText": "Domyślna rozgrywka Free-for-All", + "defaultGameListNameText": "Domyślna lista rozgrywek trybu ${PLAYMODE}", + "defaultNewFreeForAllGameListNameText": "Moja nowa rozgrywka Free-for-All", + "defaultNewGameListNameText": "Moja lista rozgrywek trybu ${PLAYMODE}", + "defaultNewTeamGameListNameText": "Moja nowa rozgrywka zespołowa", + "defaultTeamGameListNameText": "Domyślna rozgrywka zespołowa", + "deleteText": "Usuń", + "demoText": "Demo", + "denyText": "Odmów", + "deprecatedText": "Przestarzałe", + "desktopResText": "Rozdzielczość ekranu", + "deviceAccountUpgradeText": "Uwaga:\nLogujesz się kontem urządzenia (${NAME}).\nKonta urządzenia zostaną usunięte w przyszłej aktualizacji.\nUlepsz do konta V2, jeżeli chcesz zachować swój postęp.", + "difficultyEasyText": "Łatwy", + "difficultyHardOnlyText": "Tylko w trudnym trybie", + "difficultyHardText": "Trudny", + "difficultyHardUnlockOnlyText": "Ten poziom może zostać odblokowany tylko w trudnym trybie.\nCzy uważasz, że posiadasz to czego wymaga?!", + "directBrowserToURLText": "Proszę, otwórz przeglądarkę na podanym adresie:", + "disableRemoteAppConnectionsText": "Wyłącz łączenia aplikacji BS-Remote", + "disableXInputDescriptionText": "Pozwala na podłączenie 4 kontrolerów, ale może nie działać.", + "disableXInputText": "Wyłącz XInput", + "doneText": "Gotowe", + "drawText": "Remis", + "duplicateText": "Duplikuj", + "editGameListWindow": { + "addGameText": "Dodaj\ngrę", + "cantOverwriteDefaultText": "Nie można nadpisać domyślnej listy rozgrywek!", + "cantSaveAlreadyExistsText": "Lista rozgrywek z taką nazwą już istnieje!", + "cantSaveEmptyListText": "Nie można zapisać pustej listy rozgrywek!", + "editGameText": "Edytuj\ngrę", + "gameListText": "Lista rozgrywek", + "listNameText": "Nazwa listy rozgrywek", + "nameText": "Nazwa", + "removeGameText": "Usuń\ngrę", + "saveText": "Zapisz listę", + "titleText": "Edytor list rozgrywek" + }, + "editProfileWindow": { + "accountProfileInfoText": "To jest specjalny profil z nazwą i ikonką\nz konta, na które jesteś zalogowany.\n\n${ICONS}\n\nStwórz swój profil, jeśli chcesz użyć innych nazw i ikonek.\n:)", + "accountProfileText": "(nazwa profilu)", + "availableText": "Imię \"${NAME}\" jest dostępne!", + "changesNotAffectText": "Uwaga: zmiany nie będą miały wpływu na postacie będące w grze", + "characterText": "postać", + "checkingAvailabilityText": "Sprawdzanie dostępności imienia \"${NAME}\"...", + "colorText": "kolor 1", + "getMoreCharactersText": "Zdobądź więcej postaci...", + "getMoreIconsText": "Zdobądź więcej ikonek...", + "globalProfileInfoText": "Profilowi globalnemu możesz wybrać unikalną nazwę.\nMogą także mieć ikonkę.", + "globalProfileText": "(Profil globalny)", + "highlightText": "kolor 2", + "iconText": "Ikonka", + "localProfileInfoText": "Lokalny profil gracza nie może mieć ikonki i nie ma\ngwarancji, że takiej nazwy jeszcze nie ma. Ulepsz do profilu globalnego\naby stworzyć unikalną nazwę gracza i dodać ikonkę.", + "localProfileText": "(lokalny profil)", + "nameDescriptionText": "Nazwa gracza", + "nameText": "Nazwa", + "randomText": "losuj", + "titleEditText": "Edytuj profil", + "titleNewText": "Nowy profil", + "unavailableText": "\"${NAME}\" jest zajęta, spróbuj innej.", + "upgradeProfileInfoText": "To zarezerwuje nazwę gracza tylko dla\nciebie i pozwoli ci dodać do niego ikonkę.", + "upgradeToGlobalProfileText": "Ulepsz do Profilu Globalnego" + }, + "editProfilesAnyTimeText": "(możesz edytować profile w każdej chwili przechodząc do 'ustawień')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Nie możesz usunąć domyślnej ścieżki dźwiękowej.", + "cantEditDefaultText": "Nie można edytować domyślnej ścieżki dźwiękowej. Powiel ją lub utwórz nową.", + "cantEditWhileConnectedOrInReplayText": "Nie można edytować ścieżek dźwiękowych podczas imprezy lub oglądania powtórki.", + "cantOverwriteDefaultText": "Nie można nadpisać domyślnej ścieżki dźwiękowej", + "cantSaveAlreadyExistsText": "Ścieżka dźwiękowa o takiej nazwie już istnieje!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Domyślna ścieżka dźwiękowa", + "deleteConfirmText": "Usunąć ścieżkę dźwiękową:\n\n'${NAME}'?", + "deleteText": "Usuń\nścieżkę", + "duplicateText": "Powiel\nścieżkę", + "editSoundtrackText": "Edytor ścieżek dźwiękowych", + "editText": "Edytuj\nścieżkę dźwiękową", + "fetchingITunesText": "pobieranie listy z aplikacji muzycznej...", + "musicVolumeZeroWarning": "Ostrzeżenie: głośność muzyki ustawiona na 0", + "nameText": "Nazwa", + "newSoundtrackNameText": "Moja ${COUNT} ścieżka dźwiękowa", + "newSoundtrackText": "Nowa ścieżka dźwiękowa:", + "newText": "Nowa\nścieżka", + "selectAPlaylistText": "Wybierz listę", + "selectASourceText": "Wybierz źródło muzyki", + "soundtrackText": "Ścieżka dźwiękowa", + "testText": "test", + "titleText": "Ścieżki dźwiękowe", + "useDefaultGameMusicText": "Domyślna muzyka w grze", + "useITunesPlaylistText": "Lista aplikacji muzycznej", + "useMusicFileText": "Plik muzyczny (mp3, itp.)", + "useMusicFolderText": "Katalog plików muzycznych" + }, + "editText": "Edytuj", + "endText": "Koniec", + "enjoyText": "Miłej zabawy!", + "epicDescriptionFilterText": "${DESCRIPTION} Epickie zwolnione tempo.", + "epicNameFilterText": "Epicki tryb - ${NAME}", + "errorAccessDeniedText": "odmowa dostępu", + "errorDeviceTimeIncorrectText": "Czas na Twoim urządzeniu różni się o ${HOURS} godziny.\nTo może spowodować problemy.\nSprawdź swoje ustawienia czasu i strefy czasowej.", + "errorOutOfDiskSpaceText": "brak miejsca na dysku", + "errorSecureConnectionFailText": "Wystąpił błąd z ustanowieniem bezpiecznego połączenia z chmurą; funkcje sieciowe mogą nie działać.", + "errorText": "Błąd", + "errorUnknownText": "nieznany błąd", + "exitGameText": "Wyjść z ${APP_NAME}?", + "exportSuccessText": "'${NAME}' eksportowane.", + "externalStorageText": "Pamięć zewnętrzna", + "failText": "Niepowodzenie", + "fatalErrorText": "O nie, czegoś brakuje lub jest uszkodzone.\nSpróbuj przeinstalować grę lub skontaktuj się \npoprzez ${EMAIL} dla uzyskania pomocy.", + "fileSelectorWindow": { + "titleFileFolderText": "Wybierz plik lub katalog", + "titleFileText": "Wybierz plik", + "titleFolderText": "Wybierz katalog", + "useThisFolderButtonText": "Użyj tego katalogu" + }, + "filterText": "Filtr", + "finalScoreText": "Wynik końcowy", + "finalScoresText": "Wyniki końcowe", + "finalTimeText": "Ostateczny czas", + "finishingInstallText": "Kończenie instalacji; chwilka...", + "fireTVRemoteWarningText": "* Dla lepszych wrażeń, użyj\nkontrolerów do gier lub zainstaluj\naplikację ${REMOTE_APP_NAME} na\nTwoich telefonach lub tabletach.", + "firstToFinalText": "Wyniki Pierwsze-z-${COUNT}", + "firstToSeriesText": "Seria Pierwsza-z-${COUNT}", + "fiveKillText": "PIĘCIU ZABITYCH!!!", + "flawlessWaveText": "Fala Bez Skazy!", + "fourKillText": "CZWORO ZABITYCH!!!", + "freeForAllText": "Free-for-All", + "friendScoresUnavailableText": "Wyniki znajomego niedostępne.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Liderzy ${COUNT} rozgrywki", + "gameListWindow": { + "cantDeleteDefaultText": "Nie możesz usunąć domyślnej listy rozgrywek!", + "cantEditDefaultText": "Nie można edytować domyślnej listy rozgrywek! Powiel ją lub utwórz nową.", + "cantShareDefaultText": "Nie możesz udostępnić domyślnej listy rozgrywek.", + "deleteConfirmText": "Usunąć \"${LIST}\"?", + "deleteText": "Usuń\nlistę", + "duplicateText": "Powiel\nlistę", + "editText": "Edytuj\nlistę", + "gameListText": "Lista rozgrywek", + "newText": "Nowa\nlista", + "showTutorialText": "Pokaż samouczek po grze", + "shuffleGameOrderText": "Losowa kolejność rozgrywek", + "titleText": "Własne listy rozgrywek trybu ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Dodaj grę" + }, + "gamepadDetectedText": "Wykryto 1 gamepad.", + "gamepadsDetectedText": "Wykryto ${COUNT} gamepadów.", + "gamesToText": "${WINCOUNT} do ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Pamiętaj: każde urządzenie podczas imprezy może posiadać\nwięcej niż jednego gracza jeśli masz więcej kontrolerów.", + "aboutDescriptionText": "Używaj tych zakładek aby zorganizować imprezę.\n\nImprezy pozwalają na organizowanie rozgrywek i\nturniejów ze znajomymi wykorzystując różne urządzenia.\n\nUżyj przycisku ${PARTY} w prawym górnym rogu aby\nrozmawiać i współdziałać podczas imprezy.\n(na kontrolerze wciśnij ${BUTTON} gdy jesteś w menu)", + "aboutText": "Info", + "addressFetchErrorText": "", + "appInviteInfoText": "Zaproś przyjaciół by wypróbowali BombSquada, a dostaną \n${COUNT} darmowych kuponów. Dostaniesz ${YOU_COUNT}\nza każdego ktory wypróbuje.", + "appInviteMessageText": "${NAME} wysłał ci ${COUNT} kuponów w ${APP_NAME}", + "appInviteSendACodeText": "Wyślij im kod", + "appInviteTitleText": "Zaproszenie do gry ${APP_NAME}", + "bluetoothAndroidSupportText": "(działa z każdym urządzeniem na Androidzie wyposażonym w Bluetooth'a)", + "bluetoothDescriptionText": "Utwórz/dołącz do imprezy wykorzystując Bluetooth'a:", + "bluetoothHostText": "Utwórz poprzez BT", + "bluetoothJoinText": "Dołącz poprzez BT", + "bluetoothText": "Bluetooth", + "checkingText": "sprawdzam...", + "copyCodeConfirmText": "Kod skopiowany do schowka.", + "copyCodeText": "Skopiuj kod", + "dedicatedServerInfoText": "Dla najlepszych wyników ustaw serwer dedykowany. Zobacz jak na bombsquadgame.com/server.", + "disconnectClientsText": "Spowoduje to rozłączenie ${COUNT} graczy\nbędących na imprezie. Jesteś pewny?", + "earnTicketsForRecommendingAmountText": "Znajomi dostaną ${COUNT} kuponów jeżeli wypróbują grę\n(a Ty dostaniesz ${YOU_COUNT} za każdego kto zagra.)", + "earnTicketsForRecommendingText": "Poleć grę dla darmowych\n kuponów...", + "emailItText": "Prześlij to", + "favoritesSaveText": "Zapisz jako ulubione", + "favoritesText": "Ulubione", + "freeCloudServerAvailableMinutesText": "Następny darmowy serwer w chmurze będzie dostępny za ${MINUTES} minut.", + "freeCloudServerAvailableNowText": "Darmowy serwer w chmurze jest dostępny!", + "freeCloudServerNotAvailableText": "Aktualnie nie ma dostępnego żadnego darmowego serwera w chmurze.", + "friendHasSentPromoCodeText": "${COUNT} kuponów ${APP_NAME} od ${NAME}", + "friendPromoCodeAwardText": "Dostaniesz ${COUNT} kuponów zawsze gdy tego użyjesz.", + "friendPromoCodeExpireText": "Ten kod wygaśnie po ${EXPIRE_HOURS} godzinach i działa tylko dla nowych graczy.", + "friendPromoCodeInfoText": "Może zostać wykupione do ${COUNT} kuponów.\n\nIdź do \"Ustawienia->Zaawansowane->Wpisz Kod Promocyjny\" w grze aby go użyć. Idź do bombsquadgame.com by pobrać\nlinki do wszystkich wspieranych platform. Ten kod\nwygaśnie w ${EXPIRE_HOURS} godzin i jest prawidłowy tylko dla nowych graczy.", + "friendPromoCodeInstructionsText": "Aby użyć, otwórz ${APP_NAME} i idź do \"Ustawienia->Zaawansowane-> Wpisz kod\".\nWejdź na bombsquadgame.com by zobaczyć linki dla wszystkich dostępnych platform (Android itp.)", + "friendPromoCodeRedeemLongText": "Może być żądane do ${COUNT} darmowych kuponów dla najwięcej ${MAX_USES} ludzi.", + "friendPromoCodeRedeemShortText": "Może być żądane do ${COUNT} kuponów w grze.", + "friendPromoCodeWhereToEnterText": "(W \"Ustawienia->Zaawansowane->Wpisz kod\")", + "getFriendInviteCodeText": "Zdobądź kod promocyjny kumpla", + "googlePlayDescriptionText": "Zaproś użytkowników Google Play na imprezę:", + "googlePlayInviteText": "Zaproś", + "googlePlayReInviteText": "Obecnie jest ${COUNT} graczy Google Play'a na imprezie,\nktórzy zostaną rozłączeni jeśli uruchomisz nowe zaproszenie.\nUwzględnij ich w nowym zaproszeniu, aby mogli powrócić.", + "googlePlaySeeInvitesText": "Zobacz zaproszenia", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Tylko Android / Google Play)", + "hostPublicPartyDescriptionText": "Hostuj imprezę publiczną", + "hostingUnavailableText": "Hostowanie niedostępne", + "inDevelopmentWarningText": "Uwaga:\n\nOpcja gry sieciowej jest nowa i będąca w fazie\nrozwojowej. Na razie mocno zalecane jest aby\nwszyscy gracze byli w tej samej sieci (Wi-Fi lub LAN).", + "internetText": "Internet", + "inviteAFriendText": "Znajomi nie mają gry?\nZaproś ich do sprawdzenia a oni otrzymają ${COUNT} darmowych kuponów.", + "inviteFriendsText": "Zaproś przyjaciół", + "joinPublicPartyDescriptionText": "Dołącz do Publicznej Imprezy", + "localNetworkDescriptionText": "Dołącz do najbliższej imprezy (LAN, Bluetooth itp.)", + "localNetworkText": "Lokalna Sieć", + "makePartyPrivateText": "Stwórz Prywatną Imprezę", + "makePartyPublicText": "Stwórz Publiczną Imprezę", + "manualAddressText": "Adres", + "manualConnectText": "Połącz", + "manualDescriptionText": "Wbijaj na imprezę przez adres IP:", + "manualJoinSectionText": "Dołącz poprzez adres", + "manualJoinableFromInternetText": "Czy jesteś dostępny z internetu?:", + "manualJoinableNoWithAsteriskText": "NIE*", + "manualJoinableYesText": "TAK", + "manualRouterForwardingText": "*aby to naprawić, spróbuj skonfigurować router aby przepuszczał UDP port ${PORT} na Twój lokalny adres", + "manualText": "Ręczne", + "manualYourAddressFromInternetText": "Twój adres dostępny z internetu:", + "manualYourLocalAddressText": "Twój adres lokalny:", + "nearbyText": "W pobliżu", + "noConnectionText": "", + "otherVersionsText": "(Inne wersje)", + "partyCodeText": "Kod imprezy", + "partyInviteAcceptText": "Akceptuj", + "partyInviteDeclineText": "Ignoruj", + "partyInviteGooglePlayExtraText": "(zobacz zakładkę 'Google Play' w oknie 'Punkt Zborny')", + "partyInviteIgnoreText": "Ignoruj", + "partyInviteText": "${NAME} zaprosił Cię abyś\ndołączył do ich imprezy.", + "partyNameText": "Nazwa Imprezy", + "partyServerRunningText": "Twój prywatny serwer jest uruchomiony.", + "partySizeText": "ilość graczy", + "partyStatusCheckingText": "sprawdzanie statusu...", + "partyStatusJoinableText": "twoja impreza jest teraz widoczna przez internet", + "partyStatusNoConnectionText": "nie można się podłączyć", + "partyStatusNotJoinableText": "twoja impreza jest niedostępna przez internet", + "partyStatusNotPublicText": "twoja impreza nie jest publiczna", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Prywatne imprezy działają na dedykowanych serwerach w chmurze; konfiguracja rutera nie jest wymagana.", + "privatePartyHostText": "Hostuj prywatną imprezę", + "privatePartyJoinText": "Dołącz do prywatnej imprezy", + "privateText": "Prywatne", + "publicHostRouterConfigText": "To może wymagać konfiguracji przekierowywania portów twojego rutera. Prostszym rozwiązaniem będzie zahostowanie prywatnej imprezy.", + "publicText": "Publiczne", + "requestingAPromoCodeText": "Żądanie kodu...", + "sendDirectInvitesText": "Ślij bezpośrednie zaproszenia", + "sendThisToAFriendText": "Wyslij ten kod do znajomego:", + "shareThisCodeWithFriendsText": "Podziel się tym kodem z kumplami:", + "showMyAddressText": "Pokaż mój adres", + "startHostingPaidText": "Hostuj teraz za ${COST}", + "startHostingText": "Hostuj", + "startStopHostingMinutesText": "Możesz rozpocząć i zakończyć hostowanie za darmo przez następne ${MINUTES} minut.", + "stopHostingText": "Zakończ hostowanie", + "titleText": "Punkt Zborny", + "wifiDirectDescriptionBottomText": "Jeśli wszystkie urządzenia posiadają panel 'Wi-Fi Direct', to powinny użyć go aby\nodnaleźć i połączyć się między sobą. Kiedy wszystkie są już połączone, możesz utworzyć\nimprezę używając zakładki 'Lokalna sieć', tak samo jak w standardowej sieci Wi-Fi.\n\nDla optymalnego działania, host Wi-Fi Direct powinien być hostem imprezy w ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct może być używany do bezpośredniego łączenia urządzeń na\nAndroidzie bez konieczności stosowania sieci Wi-Fi. Najlepiej działa na\nurządzeniach z systemem Android 4.2 lub nowszym.\nAby go użyć, otwórz ustawienia Wi-Fi urządzenia i odszukaj 'Wi-Fi Direct'.", + "wifiDirectOpenWiFiSettingsText": "Otwórz ustawienia Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(działa między wszystkimi platformami)", + "worksWithGooglePlayDevicesText": "(współpracuje z urządzeniami systemu Google Play (Android) tej wersji gry)", + "youHaveBeenSentAPromoCodeText": "Wysłałeś kod promocyjny ${APP_NAME}." + }, + "getCoinsWindow": { + "coinDoublerText": "Podwajacz monety", + "coinsText": "${COUNT} monet", + "freeCoinsText": "Darmowe monety", + "restorePurchasesText": "Odzyskaj zakupy", + "titleText": "Zdobądź monety" + }, + "getTicketsWindow": { + "freeText": "DARMOWE!", + "freeTicketsText": "Darmowe kupony", + "inProgressText": "Transakcja w toku; proszę spróbować za chwilkę.", + "purchasesRestoredText": "Zakupy przywrócone.", + "receivedTicketsText": "Otrzymano ${COUNT} kuponów!", + "restorePurchasesText": "Przywróć zakupy", + "ticketDoublerText": "Podwójne kupony", + "ticketPack1Text": "Mała paczka kuponów", + "ticketPack2Text": "Średnia paczka kuponów", + "ticketPack3Text": "Duża paczka kuponów", + "ticketPack4Text": "Paczka Kolos kuponów", + "ticketPack5Text": "Mamucia paczka kuponów", + "ticketPack6Text": "Paczka Ultimate kuponów", + "ticketsFromASponsorText": "Obejrzyj reklamę\ndla ${COUNT} kuponów", + "ticketsText": "${COUNT} kuponów", + "titleText": "Zdobądź kupony", + "unavailableLinkAccountText": "Niestety, zakupy nie są możliwe na tej platformie. \nJeśli chcesz, możesz połączyć to konto z kontem na innej platformie\ni dokonać zakupu tam.", + "unavailableTemporarilyText": "Chwilowo niedostępne; spróbuj później.", + "unavailableText": "Niestety to jest niedostępne.", + "versionTooOldText": "Ta wersja gry jest nieaktualna; spróbuj zaktualizować do nowszej wersji.", + "youHaveShortText": "masz ${COUNT} kuponów", + "youHaveText": "masz ${COUNT} kuponów" + }, + "googleMultiplayerDiscontinuedText": "Przepraszam, usługa gry wieloosobowej Google nie jest już dostępna.\nPracuję nad zamiennikiem tak szybko jak potrafię.\nTymczasem proszę o wypróbowanie innej metody połączenia.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Zakupy Google Play niedostępne.\nSpróbuj zaktualizować aplikację Google Play.", + "googlePlayServicesNotAvailableText": "Usługi Google Play są niedostępne.\nNiektóre funkcje aplikacji mogą być wyłączone.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Zawsze", + "fullScreenCmdText": "Pełny ekran (Cmd-F)", + "fullScreenCtrlText": "Pełny ekran (Ctrl+F)", + "gammaText": "Gamma", + "highText": "Wysokie", + "higherText": "Max", + "lowText": "Niskie", + "mediumText": "Średnie", + "neverText": "Nigdy", + "resolutionText": "Rozdzielczość", + "showFPSText": "Pokazuj FPS", + "texturesText": "Tekstury", + "titleText": "Grafika", + "tvBorderText": "Ramka TV", + "verticalSyncText": "Synchronizacja pionowa", + "visualsText": "Wizualizacje" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nSilniejsza niż ciosy, lecz\nz powodu obrażeń może Cię\nwpędzić do grobu. Dla\nlepszego efektu wyrzuć ją przed\nwypaleniem się lontu.", + "canHelpText": "${APP_NAME} może Ci w tym pomóc", + "controllersInfoText": "Możesz zagrać w ${APP_NAME} ze znajomymi poprzez sieć lub na tym\nsamym urządzeniu jeśli masz wystarczająco dużo kontrolerów.\n${APP_NAME} obsługuje wiele z nich; możesz nawet użyć smartfonów\njako kontrolery wykorzystując aplikację '${REMOTE_APP_NAME}'.\nZobacz Ustawienia->Kontrolery, aby uzyskać szczegółowe informacje", + "controllersInfoTextFantasia": "Gracz może używać zdalnego kontrolera, jednak zalecane są\ngamepady. Możesz także użyć urządzeń mobilnych jako kontrolerów\ngry za pomocą darmowej aplikacji 'BombSquad Remote'.\nSprawdź informacje dostępne w ustawieniach kontrolerów.", + "controllersInfoTextMac": "Jeden lub dwóch graczy może używać klawiatury, jednak najlepiej korzystać z\ngamepadów. Gra obsługuje pady USB, kontrolery PS3, Xbox360, Wiimote i urządzenia\nz systemem iOS/Android. Na pewno coś z tego posiadasz aby sterować postaciami?\nWięcej informacji dostępnych jest w ustawieniach kontrolerów.", + "controllersInfoTextOuya": "Do gry w BombSquad możesz wykorzystać kontrolery OUYA, PS3, Xbox360\ni wiele innych gamepadów podłączanych za pomocą USB lub Bluetootha.\nMożesz również używać jako kontrolery urządzenia z systemami iOS/Android\nz pomocą darmowej aplikacji 'BombSquad Remote'. Więcej informacji w\nustawieniach kontrolerów.", + "controllersInfoTextRemoteOnly": "Możesz grać w ${APP_NAME} ze znajomymi przez sieć lub\nna tym samym urządzeniu, używając telefonów jako\nkontrolerów dzięki bezpłatnej aplikacji \"${REMOTE_APP_NAME}\".", + "controllersText": "Kontrolery", + "controlsSubtitleText": "Twoja postać w ${APP_NAME} posiada kilka podstawowych umiejętności:", + "controlsText": "Przyciski", + "devicesInfoText": "Wersja VR ${APP_NAME} może być używana w rozgrywce sieciowej wraz z\nwersją regularną, więc wbijaj do gry ze swoimi telefonami, tabletami\ni komputerami do rozgrywki. Wersja regularna gry może być również\nwykorzystana do przyłączenia się zainteresowanych do wersji VR aby\npokazać jak wygląda rozgrywka.", + "devicesText": "Urządzenia", + "friendsGoodText": "Dobrze ich mieć. ${APP_NAME} sprawia największą frajdę\nz kilkoma graczami. Gra może obsłużyć do 8 graczy jednocześnie.", + "friendsText": "Znajomych", + "jumpInfoText": "- Skok -\nPodskocz aby pokonać małe luki,\nrzucać wyżej i dalej oraz wyrażać\nswoją radość.", + "orPunchingSomethingText": "chcesz walnąć w coś lub rzucić się z klifu albo przykleić komuś bombkę.", + "pickUpInfoText": "- Podnoszenie -\nPodnieś flagi, wrogów lub cokolwiek\ninnego nie przytwierdzonego do\nziemi. Naciśnij ponownie by rzucić.", + "powerupBombDescriptionText": "Pozwala wyrzucić trzy bomby\njednocześnie zamiast jednej.", + "powerupBombNameText": "Potrójne Bomby", + "powerupCurseDescriptionText": "Lepiej jej unikaj.\nChyba, że chcesz spróbować?", + "powerupCurseNameText": "Klątwa", + "powerupHealthDescriptionText": "Przywraca pełne zdrowie.\nWoah, nie zgadłbyś...", + "powerupHealthNameText": "Apteczka", + "powerupIceBombsDescriptionText": "Słabsze od normalnych bomb lecz\nzamrażają wrogów, którzy stają\nsię wówczas podatni na kruszenie.", + "powerupIceBombsNameText": "Lodowe Bomby", + "powerupImpactBombsDescriptionText": "Nieco słabsze od normalnych bomb,\nale eksplodują zaraz po upadku.", + "powerupImpactBombsNameText": "Bomby Dotykowe", + "powerupLandMinesDescriptionText": "Dostępne w paczkach po 3.\nPrzydatne do obrony bazy lub \nzatrzymania szybkich wrogów.", + "powerupLandMinesNameText": "Miny Lądowe", + "powerupPunchDescriptionText": "Sprawiają, że ciosy są silniejsze,\nszybsze i ogólnie mocniejsze.", + "powerupPunchNameText": "Rękawice Bokserskie", + "powerupShieldDescriptionText": "Pochłania groźne obrażenia,\nwięc jest niezastąpiona.", + "powerupShieldNameText": "Tarcza Energetyczna", + "powerupStickyBombsDescriptionText": "Przyklejają się do wszystkiego\nco dotkną. Niezły ubaw.", + "powerupStickyBombsNameText": "Bomby Przylepne", + "powerupsSubtitleText": "Oczywiście, gra bez bonusów byłaby niekompletna:", + "powerupsText": "Bonusy", + "punchInfoText": "- Cios -\nCiosy robią większe obrażenia\ngdy szybciej boksujesz, więc\nbiegaj i skakaj jak szaleniec!", + "runInfoText": "- Bieganie -\nPrzytrzymaj dowolny przycisk aby biec. Przyciski boczne lub triggery (o ile je masz) działają\nlepiej. Bieganie pozwala na szybsze przemieszczanie lecz trudniej kierować, więc uwaga na klify.", + "someDaysText": "Czasami masz chęć przyłożenia komuś, wysadzenia kogoś w powietrze,", + "titleText": "Pomoc ${APP_NAME}", + "toGetTheMostText": "Aby w pełni korzystać z tej gry, musisz mieć:", + "welcomeText": "Witaj w ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} nawiguje w menu jako szef -", + "importPlaylistCodeInstructionsText": "Użyj tego kodu, by zimportować tą listę w innym miejscu:", + "importPlaylistSuccessText": "Zimportowano playlistę '${NAME}' rozgrywek ${TYPE}", + "importText": "Importuj", + "importingText": "Importowanie...", + "inGameClippedNameText": "w grze widoczne jako\n\"${NAME}\"", + "installDiskSpaceErrorText": "BŁĄD: Niemożliwe dokończenie instalacji.\nByć może mało miejsca w pamięci urządzenia.\nZrób więcej miejsca i spróbuj jeszcze raz.", + "internal": { + "arrowsToExitListText": "wciśnij ${LEFT} lub ${RIGHT} aby opuścić listę", + "buttonText": "przycisk", + "cantKickHostError": "Nie możesz wyrzucić hosta.", + "chatBlockedText": "${NAME} jest zablokowany na czacie na ${TIME} sekund.", + "connectedToGameText": "Dołączono do \"${NAME}\"", + "connectedToPartyText": "${NAME}'s wbił się na imprezę!", + "connectingToPartyText": "Łączenie...", + "connectionFailedHostAlreadyInPartyText": "Połączenie nieudane; host jest na innej imprezie.", + "connectionFailedPartyFullText": "Połączenie nieudane; impreza jest pełna.", + "connectionFailedText": "Połączenie nieudane.", + "connectionFailedVersionMismatchText": "Połączenie nieudane; host pracuje na innej wersji gry.\nUpewnij się, że masz aktualne wersje i spróbuj ponownie.", + "connectionRejectedText": "Połączenie odrzucone.", + "controllerConnectedText": "${CONTROLLER} połączony.", + "controllerDetectedText": "Wykryto 1 kontroler.", + "controllerDisconnectedText": "${CONTROLLER} rozłączony.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} rozłączony. Proszę spróbuj połączyć ponownie.", + "controllerForMenusOnlyText": "Ten kontroler nie może być używany do gry; można nim sterować tylko w menu.", + "controllerReconnectedText": "${CONTROLLER} połączony ponownie.", + "controllersConnectedText": "Podłączono ${COUNT} kontrolerów.", + "controllersDetectedText": "Wykryto ${COUNT} kontrolery/ów.", + "controllersDisconnectedText": "Rozłączono ${COUNT} kontrolerów.", + "corruptFileText": "Wykryto uszkodzone(y) plik(i). Proszę przeinstalować grę lub zgłosić problem na ${EMAIL}", + "errorPlayingMusicText": "Błąd odtwarzania muzyki: ${MUSIC}", + "errorResettingAchievementsText": "Niemożliwe wyczyszczenie osiągnięć online; spróbuj ponownie później.", + "hasMenuControlText": "${NAME} ma kontrolę nad menu", + "incompatibleNewerVersionHostText": "Serwer posiada nowszą wersję gry.\nZaaktualizuj do najnowszej wersji i spróbuj ponownie.", + "incompatibleVersionHostText": "Host pracuje na innej wersji gry.\nUpewnij się, że masz aktualne wersje gry i spróbuj ponownie.", + "incompatibleVersionPlayerText": "${NAME} pracuje na innej wersji gry.\nUpewnij się, że masz aktualne wersje gry i spróbuj ponownie.", + "invalidAddressErrorText": "Błąd: nieprawidłowy adres.", + "invalidNameErrorText": "Błąd: nieprawidłowa nazwa.", + "invalidPortErrorText": "Błąd: nieprawidłowy port.", + "invitationSentText": "Zaproszenie wysłane.", + "invitationsSentText": "${COUNT} wysłanych zaproszeń.", + "joinedPartyInstructionsText": "Znajomy dołączył na imprezę.\nRozpocznij grę w menu 'Graj'.", + "keyboardText": "Klawiatura", + "kickIdlePlayersKickedText": "${NAME} wyrzucony za bezczynność.", + "kickIdlePlayersWarning1Text": "${NAME} zostanie wyrzucony za ${COUNT} sekund jeśli dalej\nbędzie bezczynnie patrzył.", + "kickIdlePlayersWarning2Text": "(możesz wyłączyć opcję w Ustawieniach -> Zaawansowane)", + "leftGameText": "Opuściłeś '${NAME}'.", + "leftPartyText": "${NAME}'s opuścił imprezę.", + "noMusicFilesInFolderText": "Katalog nie zawiera plików muzycznych.", + "playerJoinedPartyText": "${NAME} wbił się na imprezę!", + "playerLeftPartyText": "${NAME} opuścił imprezę.", + "rejectingInviteAlreadyInPartyText": "Odrzucono zaproszenie (już na imprezie).", + "serverRestartingText": "Serwer się restartuje. Dołącz za chwilę...", + "serverShuttingDownText": "Serwer się wyłącza...", + "signInErrorText": "Błąd zapisania się.", + "signInNoConnectionText": "Zapisanie się niemożliwe. (brak połączenia z internetem?)", + "teamNameText": "Zespół ${NAME}", + "telnetAccessDeniedText": "BŁĄD: użytkownikowi nie przyznano dostępu do telnetu.", + "timeOutText": "(czas upłynie za ${TIME} sekund)", + "touchScreenJoinWarningText": "Dołączyłeś się wykorzystując ekran dotykowy.\nJeśli to pomyłka, stuknij 'Menu->Opuść grę'.", + "touchScreenText": "Ekran dotykowy", + "trialText": "trial", + "unableToResolveHostText": "Błąd: nie można odnaleźć hosta.", + "unavailableNoConnectionText": "Obecnie niedostępne (sprawdź połączenie internetowe).", + "vrOrientationResetCardboardText": "Użyj tego aby zresetować orientację VR.\nAby zagrać w grę będziesz potrzebować zewnętrznego kontrolera.", + "vrOrientationResetText": "Reset orientacji VR.", + "willTimeOutText": "(czas upłynie przy bezczynności)" + }, + "jumpBoldText": "SKOK", + "jumpText": "Skok", + "keepText": "Zachowaj", + "keepTheseSettingsText": "Zachować te ustawienia?", + "keyboardChangeInstructionsText": "Wciśnij dwa razy spację, aby zmienić klawiatury.", + "keyboardNoOthersAvailableText": "Brak dostępnych innych klawiatur.", + "keyboardSwitchText": "Zmiana klawiatury na \"${NAME}\".", + "kickOccurredText": "${NAME} został wyrzucony.", + "kickQuestionText": "Wyrzucić ${NAME}?", + "kickText": "Wyrzuć", + "kickVoteCantKickAdminsText": "Nie można wyrzucić adminów.", + "kickVoteCantKickSelfText": "Nie możesz wyrzucić siebie.", + "kickVoteFailedNotEnoughVotersText": "Za mało graczy, by rozpocząć głosowanie.", + "kickVoteFailedText": "Głosowanie nie powiodło się.", + "kickVoteStartedText": "Głosowanie za wyrzuceniem gracza ${NAME}.", + "kickVoteText": "Głosuj za wyrzuceniem", + "kickVotingDisabledText": "Głosowania są wyłączone.", + "kickWithChatText": "Wpisz ${YES} na czacie żeby wyrzucić i ${NO} żeby nie wyrzucać.", + "killsTallyText": "${COUNT} zabitych", + "killsText": "Zabitych", + "kioskWindow": { + "easyText": "Łatwy", + "epicModeText": "Tryb Epicki", + "fullMenuText": "Pełne Menu", + "hardText": "Trudny", + "mediumText": "Średni", + "singlePlayerExamplesText": "Przykłady trybu Pojedynczego Gracza / Kooperacji", + "versusExamplesText": "Przykłady trybu Versus" + }, + "languageSetText": "Obecny język gry to \"${LANGUAGE}\".", + "lapNumberText": "Okrążenie ${CURRENT}/${TOTAL}", + "lastGamesText": "(ostatnich ${COUNT} rozgrywek)", + "leaderboardsText": "Rankingi", + "league": { + "allTimeText": "Całość", + "currentSeasonText": "Obecny Sezon (${NUMBER})", + "leagueFullText": "${NAME} Liga", + "leagueRankText": "Pozycja w Lidze", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga ${SUFFIX}", + "seasonEndedDaysAgoText": "Zezon zakończył się ${NUMBER} dni temu.", + "seasonEndsDaysText": "Ilość dni do zakończenia sezonu: ${NUMBER}.", + "seasonEndsHoursText": "Do zakończenia sezonu pozostało ${NUMBER} godzin.", + "seasonEndsMinutesText": "Sezon zakończy się za ${NUMBER} minut.", + "seasonText": "Sezon ${NUMBER}", + "tournamentLeagueText": "Musisz uzyskać ligę ${NAME} aby wejść do tego turnieju.", + "trophyCountsResetText": "Liczba Zdobyczy zresetuje się w przyszłym sezonie." + }, + "levelBestScoresText": "Najlepsze wyniki w ${LEVEL}", + "levelBestTimesText": "Najlepsze czasy w ${LEVEL}", + "levelFastestTimesText": "Najszybsze czasy w ${LEVEL}", + "levelHighestScoresText": "Najwyższe wyniki w ${LEVEL}", + "levelIsLockedText": "${LEVEL} jest zablokowany.", + "levelMustBeCompletedFirstText": "${LEVEL} musi zostać ukończony jako pierwszy.", + "levelText": "Poziom ${NUMBER}", + "levelUnlockedText": "Poziom Odblokowany!", + "livesBonusText": "Bonusowe Życie", + "loadingText": "ładowanie", + "loadingTryAgainText": "Wczytywanie; spróbuj ponownie za chwilę...", + "macControllerSubsystemBothText": "Oba naraz (nie zalecane)", + "macControllerSubsystemClassicText": "Klasyczne", + "macControllerSubsystemDescriptionText": "(zmień to, jeśli kontrolery nie działają)", + "macControllerSubsystemMFiNoteText": "Kontroler Dla-iOS/Mac wykryty;\nZechcesz pewnie aktywować je w Ustawienia -> Kontrolery", + "macControllerSubsystemMFiText": "Zrobione-dla-iOS/Mac", + "macControllerSubsystemTitleText": "Wsparcie Kontrolerów", + "mainMenu": { + "creditsText": "Info", + "demoMenuText": "Menu Demo", + "endGameText": "Koniec Gry", + "endTestText": "Zakończ test", + "exitGameText": "Wyjście z Gry", + "exitToMenuText": "Wyjść do menu?", + "howToPlayText": "Jak grać", + "justPlayerText": "(Tylko ${NAME})", + "leaveGameText": "Opuść Grę", + "leavePartyConfirmText": "Naprawdę opuszczasz imprezę?", + "leavePartyText": "Opuść Imprezę", + "leaveText": "Opuść grę", + "quitText": "Zakończ", + "resumeText": "Kontynuuj", + "settingsText": "Ustawienia" + }, + "makeItSoText": "Zastosuj", + "mapSelectGetMoreMapsText": "Zdobądź więcej map...", + "mapSelectText": "Wybierz...", + "mapSelectTitleText": "Mapy ${GAME}", + "mapText": "Mapa", + "maxConnectionsText": "Maksymalne Połączenia", + "maxPartySizeText": "Maksymalna ilość graczy", + "maxPlayersText": "Maksymalna ilość graczy", + "merchText": "Merch!", + "modeArcadeText": "Tryb Salonu Gier", + "modeClassicText": "Tryb Klasyczny", + "modeDemoText": "Tryb Demo", + "mostValuablePlayerText": "Najwartościowszy gracz", + "mostViolatedPlayerText": "Gracz najbardziej sprofanowany", + "mostViolentPlayerText": "Gracz najbardziej brutalny", + "moveText": "Przenieś", + "multiKillText": "${COUNT}-ZABITYCH!!!", + "multiPlayerCountText": "${COUNT} graczy", + "mustInviteFriendsText": "Uwaga: aby zagrać sieciowo musisz\nzaprosić znajomych w panelu\n\"${GATHER}\" lub dołączyć kontrolery.", + "nameBetrayedText": "${NAME} zdradził ${VICTIM}.", + "nameDiedText": "${NAME} zginął.", + "nameKilledText": "${NAME} zabił ${VICTIM}.", + "nameNotEmptyText": "Nazwa nie może być pusta!", + "nameScoresText": "${NAME} zdobył punkty!", + "nameSuicideKidFriendlyText": "${NAME} przypadkowo zginął.", + "nameSuicideText": "${NAME} popełnił samobójstwo.", + "nameText": "Nazwa", + "nativeText": "Natywna", + "newPersonalBestText": "Nowy rekord życiowy!", + "newTestBuildAvailableText": "Dostępna jest nowa wersja! (${VERSION} build ${BUILD}).\nPobierz ją z ${ADDRESS}", + "newText": "Nowy", + "newVersionAvailableText": "Dostępna jest nowa wersja ${APP_NAME}! (${VERSION})", + "nextAchievementsText": "Następne osiągnięcia:", + "nextLevelText": "Następny poziom", + "noAchievementsRemainingText": "- brak", + "noContinuesText": "(bez kontynuacji)", + "noExternalStorageErrorText": "Brak pamięci zewnętrznej w tym urządzeniu", + "noGameCircleText": "Błąd: niezalogowany w GameCircle", + "noJoinCoopMidwayText": "Rozgrywki trybu Kooperacji nie mogą być łączone w czasie ich trwania.", + "noProfilesErrorText": "Nie masz własnego profilu gracza, dlatego nazwano Cię: '${NAME}'.\nPrzejdź do Ustawień->Profile Gracza aby stworzyć własny.", + "noScoresYetText": "Brak wyników do tej pory.", + "noThanksText": "Nie, dziękuję", + "noTournamentsInTestBuildText": "OSTRZEŻENIE: Wyniki turniejów z tej wersji testowej będą ignorowane.", + "noValidMapsErrorText": "Nie znaleziono żadnych map dla tego typu rozgrywki.", + "notEnoughPlayersRemainingText": "Niewystarczająca ilość graczy. Spróbuj zacząć nową grę.", + "notEnoughPlayersText": "Aby rozpocząć grę potrzeba ${COUNT} graczy!", + "notNowText": "Nie teraz", + "notSignedInErrorText": "Musisz zalogować się, aby to zrobić.", + "notSignedInGooglePlayErrorText": "Zaloguj się z Google Play, by to zrobić.", + "notSignedInText": "Nie zapisany", + "notUsingAccountText": "Uwaga: ignorowanie konta ${SERVICE}.\nIdź do \"Konto -> Zaloguj się kontem ${SERVICE}\", jeżeli chcesz go używać.", + "nothingIsSelectedErrorText": "Nic nie zaznaczyłeś!", + "numberText": "#${NUMBER}", + "offText": "Off", + "okText": "Ok", + "onText": "On", + "oneMomentText": "Chwileczkę...", + "onslaughtRespawnText": "${PLAYER} odrodzi się w fali ${WAVE}", + "orText": "${A} lub ${B}", + "otherText": "Inny...", + "outOfText": "(#${RANK} na ${ALL})", + "ownFlagAtYourBaseWarning": "Twoja flaga musi być w\nTwojej bazie aby zapunktować!", + "packageModsEnabledErrorText": "Gra sieciowa nie jest dozwolona kiedy są włączone lokalne pakiety modów (zobacz Ustawienia->Zaawansowane)", + "partyWindow": { + "chatMessageText": "Wiadomość", + "emptyText": "Twoja impreza nie ma gości", + "hostText": "(host)", + "sendText": "Wyślij", + "titleText": "Twoja Impreza" + }, + "pausedByHostText": "(rozgrywka zatrzymana przez host)", + "perfectWaveText": "Perfekcyjna Fala!", + "pickUpBoldText": "PODNIEŚ", + "pickUpText": "Podnieś", + "playModes": { + "coopText": "Kooperacja", + "freeForAllText": "Free-for-All", + "multiTeamText": "Multi-Drużyny", + "singlePlayerCoopText": "Pojedynczy gracz / Kooperacja", + "teamsText": "Drużyny" + }, + "playText": "Graj", + "playWindow": { + "coopText": "Kooperacja", + "freeForAllText": "Free-for-All", + "oneToFourPlayersText": "1-4 graczy", + "teamsText": "Gra Zespołowa", + "titleText": "Graj", + "twoToEightPlayersText": "2-8 graczy" + }, + "playerCountAbbreviatedText": "${COUNT} graczy", + "playerDelayedJoinText": "${PLAYER} wejdzie do gry przy następnej rundzie.", + "playerInfoText": "Info o graczu", + "playerLeftText": "${PLAYER} opuścił grę.", + "playerLimitReachedText": "Limit ${COUNT} graczy osiągnięty, nie można się przyłączyć.", + "playerLimitReachedUnlockProText": "Zaktualizuj do wersji \"${PRO}\" aby zagrać z więcej niż ${COUNT} graczami.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Nie możesz usunąć swojego profilu.", + "deleteButtonText": "Usuń\nProfil", + "deleteConfirmText": "Usunąć '${PROFILE}'?", + "editButtonText": "Edytuj\nProfil", + "explanationText": "(utwórz własne nazwy i postacie graczy na tym profilu)", + "newButtonText": "Nowy\nProfil", + "titleText": "Profile Graczy" + }, + "playerText": "Gracz", + "playlistNoValidGamesErrorText": "Ta lista nie zawiera żadnych odblokowanych rozgrywek.", + "playlistNotFoundText": "nie znaleziono listy", + "playlistText": "Lista", + "playlistsText": "Listy gier", + "pleaseRateText": "Jeśli polubiłeś ${APP_NAME}, proszę o poddanie go ocenie\nlub napisanie krótkiej recenzji. Pozwoli to zebrać przydatne\ninformacje, które pomogą wesprzeć rozwój gry w przyszłości.\n\nDziękuję!\n-Eric", + "pleaseWaitText": "Czekaj chwilkę...", + "pluginClassLoadErrorText": "Błąd ładowania klasy pluginu '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Błąd inicjowania pluginu '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Ustawienia pluginów", + "pluginsAutoEnableNewText": "Auto uruchomienie nowych wtyczek", + "pluginsDetectedText": "Wykryto nowe pluginy. Uruchom ponownie grę, aby je aktywować, lub skonfiguruje je w ustawieniach.", + "pluginsDisableAllText": "Wyłącz wszystkie pluginy", + "pluginsEnableAllText": "Włącz wszystkie pluginy", + "pluginsRemovedText": "Usunięto ${NUM} pluginy(ów)", + "pluginsText": "Pluginy", + "practiceText": "Praktyka", + "pressAnyButtonPlayAgainText": "Naciśnij dowolny przycisk aby zagrać ponownie...", + "pressAnyButtonText": "Naciśnij dowolny przycisk aby kontynuować...", + "pressAnyButtonToJoinText": "naciśnij dowolny przycisk aby dołączyć...", + "pressAnyKeyButtonPlayAgainText": "Naciśnij dowolny klawisz/przycisk aby zagrać ponownie...", + "pressAnyKeyButtonText": "Naciśnij dowolny klawisz/przycisk aby kontynuować...", + "pressAnyKeyText": "Naciśnij dowolny klawisz...", + "pressJumpToFlyText": "** Naciśnij wielokrotnie skok aby polecieć **", + "pressPunchToJoinText": "naciśnij CIOS aby dołączyć...", + "pressToOverrideCharacterText": "naciśnij ${BUTTONS} aby zastąpić swoją postać", + "pressToSelectProfileText": "naciśnij ${BUTTONS} aby wybrać gracza.", + "pressToSelectTeamText": "naciśnij ${BUTTONS} aby wybrać drużynę.", + "profileInfoText": "Stwórz profile dla siebie i swoich znajomych\ndostosowując ich nazwy i kolory postaci.", + "promoCodeWindow": { + "codeText": "Kod", + "codeTextDescription": "Kod Promocyjny", + "enterText": "Wprowadź" + }, + "promoSubmitErrorText": "Błąd wprowadzonego kodu; sprawdź połączenie internetowe", + "ps3ControllersWindow": { + "macInstructionsText": "Wyłącz zasilanie konsoli PS3, upewnij się, że masz uruchomiony\nBluetooth w swoim Mac'u, następnie podłącz kontroler do portu\nUSB Mac'a aby sparować urządzenia. Od teraz można używać na\nkontrolerze przycisku 'home' aby podłączyć go do Mac'a w obu\ntrybach - przewodowym (USB) i bezprzewodowym (Bluetooth).\n\nNa niektórych Mac'ach trzeba podać kod aby urządzenia sparować.\nJeśli się tak stanie poszukaj poradnika na google.\n\n\n\n\nKontrolery PS3 podłączone bezprzewodowo powinny być widoczne na\nliście urządzeń w Preferencjach Systemu->Bluetooth. Być może\ntrzeba będzie je usunąć z tej listy, kiedy zechcesz korzystać\nz nich ponownie w PS3.\n\nPamiętaj aby rozłączyć je z Bluetootha kiedy nie będą używane\nponieważ wyładują się ich baterie.\n\nBluetooth powinien obsłużyć do 7 podłączonych urządzeń, chociaż\nliczba ta może się wahać.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "Aby używać kontrolerów PS3 z konsolą OUYA, po prostu podłącz je kablem USB\naby sparować urządzenia. Może to spowodować rozłączenie innych kontrolerów,\nwięc powinieneś później uruchomić ponownie konsolę OUYA i odłączyć kabel USB.\n\nOd teraz powinien być aktywny przycisk HOME aby połączyć się bezprzewodowo. Kiedy zakończysz grę, przytrzymaj HOME przez 10 sekund aby wyłączyć kontroler;\nw przeciwnym razie może on wyczerpać jego baterie.", + "ouyaInstructionsTextScale": 0.74, + "pairingTutorialText": "poradnik video parowania kontrolerów", + "titleText": "Korzystanie z kontrolerów PS3 w ${APP_NAME}:" + }, + "publicBetaText": "PUBLICZNA BETA", + "punchBoldText": "CIOS", + "punchText": "Cios", + "purchaseForText": "Kup za ${PRICE}", + "purchaseGameText": "Zakup Grę", + "purchasingText": "Kupowanie...", + "quitGameText": "Wyjść z ${APP_NAME}?", + "quittingIn5SecondsText": "Wyjście za 5 sekund...", + "randomPlayerNamesText": "DOMYŚLNE_NAZWY", + "randomText": "Losowo", + "rankText": "Ranking", + "ratingText": "Ocena", + "reachWave2Text": "Aby zdobyć punkty dotrwaj do 2 fali.", + "readyText": "gotowy", + "recentText": "Ostatnie", + "remainingInTrialText": "pozostań w wersji trial", + "remoteAppInfoShortText": "${APP_NAME} jest najfajniejszy gdy grasz z rodziną i przyjaciółmi. \nPodłącz jeszcze jeden lub więcej kontrolerów lub zainstaluj \n${REMOTE_APP_NAME} na telefony lub tablety i używaj ich\njako kontrolerów.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Pozycja Przycisku", + "button_size": "Wielkość Przycisku", + "cant_resolve_host": "Nie można zanalizować hosta.", + "capturing": "Przechwytywanie...", + "connected": "Połączony.", + "description": "Użyj telefonu lub tabletu jako kontrolera w BombSquad.\nDo 8 urządzeń może być połączone na raz w epickiej wieloosobowej grze na jednym telewizorze lub tablecie.", + "disconnected": "Rozłączono przez serwer.", + "dpad_fixed": "nieruchomy", + "dpad_floating": "ruchomy", + "dpad_position": "Pozycja Joysticka", + "dpad_size": "Wielkość Joysticka", + "dpad_type": "Rodzaj Joysticka", + "enter_an_address": "Wpisz adres", + "game_full": "Gra jest pełna lub nie akceptuje połączeń.", + "game_shut_down": "Gra została zamknięta.", + "hardware_buttons": "Przyciski Sprzętu Komputerowego", + "join_by_address": "Wejdź przez adres...", + "lag": "Lag (opóźnienie): ${SECONDS} sekund", + "reset": "Resetuj do domyślnych", + "run1": "Run 1", + "run2": "Run 2", + "searching": "Szukanie gier BombSquad...", + "searching_caption": "Kliknij na nazwę gry by do niej dołączyć.\nUpewnij się, że jesteś w tej samej sieci Wi-Fi, co gra.", + "start": "Start", + "version_mismatch": "Wersje nie pasują.\nSprawdź czy BombSquad i BombSquad Remote\nmają najnowszą wersję i spróbuj ponownie." + }, + "removeInGameAdsText": "Odblokowywując wersję \"${PRO}\" pozbędziesz się reklam w grze.", + "renameText": "Zmień nazwę", + "replayEndText": "Zakończ powtórkę", + "replayNameDefaultText": "Ostatnia powtórka", + "replayReadErrorText": "Błąd odczytu pliku powtórki.", + "replayRenameWarningText": "Zmień nazwę \"${REPLAY}\" po zakończeniu gry jeśli chcesz zachować powtórkę, w przeciwnym wypadku zostanie ona nadpisana.", + "replayVersionErrorText": "Przepraszam, ale ta powtórka została utworzona\nw innej wersji gry i nie może być użyta.", + "replayWatchText": "Obejrzyj powtórkę", + "replayWriteErrorText": "Błąd zapisania pliku powtórki.", + "replaysText": "Powtórki", + "reportPlayerExplanationText": "Użyj tego emaila by zgłosić oszukiwanie, nieprawidłowy język lub inne złe zachowanie.\nProszę opisz je poniżej:", + "reportThisPlayerCheatingText": "Oszukiwanie", + "reportThisPlayerLanguageText": "Nieprawidłowy Język", + "reportThisPlayerReasonText": "Co chcesz zgłosić?", + "reportThisPlayerText": "Zgłoś tego gracza", + "requestingText": "Żądanie...", + "restartText": "Restart", + "retryText": "Ponów", + "revertText": "Przywróć", + "runBoldText": "URUCHOM", + "runText": "Uruchom", + "saveText": "Zapisz", + "scanScriptsErrorText": "Błąd w skanowaniu skryptów; sprawdź konsolę dla szczegółów", + "scoreChallengesText": "Wyzwania Punktowe", + "scoreListUnavailableText": "Lista wyników niedostępna.", + "scoreText": "Wynik", + "scoreUnits": { + "millisecondsText": "Milisekund", + "pointsText": "Punktów", + "secondsText": "Sekund" + }, + "scoreWasText": "(było ${COUNT})", + "selectText": "Wybierz", + "seriesWinLine1PlayerText": "WYGRAŁ", + "seriesWinLine1TeamText": "WYGRALI", + "seriesWinLine1Text": "WYGRAŁ", + "seriesWinLine2Text": "SERIĘ!", + "settingsWindow": { + "accountText": "Konto", + "advancedText": "Zaawansowane", + "audioText": "Audio", + "controllersText": "Kontrolery", + "graphicsText": "Grafika", + "playerProfilesMovedText": "Notka: Profile graczy zostały przeniesione do menu profili w menu głównym.", + "playerProfilesText": "Profile Gracza", + "titleText": "Ustawienia" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(prosta klawiatura na ekranie do edycji tekstu - przyjazna kontrolerom)", + "alwaysUseInternalKeyboardText": "Zawsze używaj wewn. klawiatury", + "benchmarksText": "Benchmarki & Testy Wydajności", + "disableCameraGyroscopeMotionText": "Wyłącz Kontrolę Kamery Żyroskopem", + "disableCameraShakeText": "Wyłącz Trzęsącą Kamerę", + "disableThisNotice": "(możesz wyłączyć to powiadomienie w ustawieniach zaawansowanych)", + "enablePackageModsDescriptionText": "(aktywuje dodatkowe możliwości modowania ale wyłącza grę sieciową)", + "enablePackageModsText": "Włącz lokalne pakiety modów", + "enterPromoCodeText": "Wpisz kod", + "forTestingText": "Uwaga: wartości stosowane do testów będą utracone po wyjściu z gry.", + "helpTranslateText": "Tłumaczenia ${APP_NAME} na inne języki są wysiłkiem społeczności\nfanów tej gry. Jeśli chcesz przyczynić się lub poprawić istniejące\nbłędy w tłumaczeniu, kliknij w poniższy link. Z góry dziękuję!", + "kickIdlePlayersText": "Wyrzuć nieaktywnych graczy", + "kidFriendlyModeText": "Tryb dla dzieciaków (zredukowana przemoc itd.)", + "languageText": "Język", + "moddingGuideText": "Przewodnik modowania gry", + "mustRestartText": "Musisz uruchomić ponownie grę aby zastosować zmiany.", + "netTestingText": "Testowanie sieci", + "resetText": "Reset", + "showBombTrajectoriesText": "Pokaż trajektorię bomb", + "showInGamePingText": "Pokaż ping w grze", + "showPlayerNamesText": "Pokazuj nazwy graczy", + "showUserModsText": "Pokaż katalog modów", + "titleText": "Zaawansowane", + "translationEditorButtonText": "Edytor tłumaczeń ${APP_NAME}", + "translationFetchErrorText": "status tłumaczenia niedostępny", + "translationFetchingStatusText": "sprawdzanie statusu tłumaczenia...", + "translationInformMe": "Powiadom mnie gdy mój język będzie potrzebował uaktualnienia", + "translationNoUpdateNeededText": "Obecnie używany język jest aktualny; ekstra!", + "translationUpdateNeededText": "** obecnie używany język wymaga jego zaktualizowania! **", + "vrTestingText": "Testowanie VR" + }, + "shareText": "Udostępnij", + "sharingText": "Udostępnianie...", + "showText": "Wyświetl", + "signInForPromoCodeText": "Musisz się zalogować do konta aby kody zadziałały.", + "signInWithGameCenterText": "By użyć konta Game Center\nzapisz się aplikacją Game Center.", + "singleGamePlaylistNameText": "Tylko ${GAME}", + "singlePlayerCountText": "1 gracz", + "soloNameFilterText": "Solówka ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Wybór postaci", + "Chosen One": "Wybraniec", + "Epic": "Tryb gier epickich", + "Epic Race": "Epicki Wyścig", + "FlagCatcher": "Przechwyć Flagę", + "Flying": "Skrzydła Fantazji", + "Football": "Futbol", + "ForwardMarch": "Szturm", + "GrandRomp": "Podbój", + "Hockey": "Hokej", + "Keep Away": "Trzymaj się z dala", + "Marching": "Otaczanie", + "Menu": "Menu główne", + "Onslaught": "Atak", + "Race": "Wyścig", + "Scary": "Król Wzgórza", + "Scores": "Ekran Wyników", + "Survival": "Eliminacja", + "ToTheDeath": "Mecz Śmierci", + "Victory": "Ekran Wyników Końcowych" + }, + "spaceKeyText": "spacja", + "statsText": "Statystyki", + "storagePermissionAccessText": "To wymaga dostępu do pamięci masowej", + "store": { + "alreadyOwnText": "Masz już ${NAME}!", + "bombSquadProDescriptionText": "• Zdobywanie podwójnych kuponów w grze\n• Usunięcie reklam z rozgrywek\n•Zawiera ${COUNT} bonusowych kuponów\n•Bonus +${PERCENT}% w wyniku ligowym\n•Odblokowanie '${INF_ONSLAUGHT}' i\n'${INF_RUNAROUND}' w trybie kooperacji", + "bombSquadProFeaturesText": "Cechy:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Usuwa reklamy i wyskakujące okienka\n• Odblokowuje również więcej opcji\n• Zawiera także:", + "buyText": "Kup", + "charactersText": "Postacie", + "comingSoonText": "Wkrótce...", + "extrasText": "Dodatki", + "freeBombSquadProText": "BombSquad jest teraz darmowy, ale od kiedy oficjalnie go zakupiłeś\notrzymujesz wersję BombSquad Pro i ${COUNT} kuponów jako wyraz wdzięczności.\nMiłego korzystania z nowych funkcji i dziękuję za wsparcie!\n-Eric", + "gameUpgradesText": "Aktualizacje Gry", + "getCoinsText": "Zdobądź monety", + "holidaySpecialText": "Świąteczne Okazje", + "howToSwitchCharactersText": "(idź do \"${SETTINGS} -> ${PLAYER_PROFILES}\" aby przypisać i dostosować postacie)", + "howToUseIconsText": "(Stwórz profil globalny (w opcjach profilowych) aby tego użyć)", + "howToUseMapsText": "(użyj tych plansz w twoich listach gier free-for-all/drużynowych)", + "iconsText": "Ikonki", + "loadErrorText": "Nie można załadować strony.\nSprawdź połączenie internetowe.", + "loadingText": "ładowanie", + "mapsText": "Mapy", + "miniGamesText": "MiniGierki", + "oneTimeOnlyText": "(tylko jeden raz)", + "purchaseAlreadyInProgressText": "Zakup tego przedmiotu jest w trakcie realizacji.", + "purchaseConfirmText": "Kupujesz ${ITEM}?", + "purchaseNotValidError": "Niewłaściwy zakup.\nJeśli jest to błąd, skontaktuj się - ${EMAIL}.", + "purchaseText": "Kupuję", + "saleBundleText": "Wyprzedaż!", + "saleExclaimText": "Sprzedaż!", + "salePercentText": "(${PERCENT}% wyprzedaż)", + "saleText": "WYPRZEDAŻ", + "searchText": "Szukaj", + "teamsFreeForAllGamesText": "Rozgrywki Zespołowe / Free-for-All", + "totalWorthText": "*** Warte ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Ulepszyć?", + "winterSpecialText": "Specjały Zimowe", + "youOwnThisText": "- zdobyłeś już to -" + }, + "storeDescriptionText": "8 Osobowe Szaleństwo!\n\nWysadź w powietrze swoich znajomych (lub komputerowych przeciwników) w turnieju z wybuchowymi mini gierkami jak np. Przechwyć Flagę, Bombowy Hokej i Epicki Mecz Śmierci w zwolnionym tempie!\n\nProste sterowanie i rozszerzone wsparcie dla kontrolerów może wprowadzić do gry aż 8 przeciwników; możesz nawet wykorzystać swoje mobilne urządzenie jako kontroler do gry dostępne jako darmowa aplikacja 'BombSquad Remote'!\n\nBomby w Górę!\n\nSprawdź na www.froemling.net/bombsquad i dowiedz się więcej.", + "storeDescriptions": { + "blowUpYourFriendsText": "Wysadź w powietrze swoich znajomych.", + "competeInMiniGamesText": "Ukończ mini gierki aby awansować z wyścigów do lotów.", + "customize2Text": "Dostosuj postacie, mini gierki, a nawet ścieżkę dźwiękową.", + "customizeText": "Dostosuj postacie i stwórz własne listy mini gierek.", + "sportsMoreFunText": "Sporty są zabawniejsze z bombami.", + "teamUpAgainstComputerText": "Współpracuj przeciwko komputerowi." + }, + "storeText": "Sklep", + "submitText": "Prześlij", + "submittingPromoCodeText": "Przesyłanie Kodu...", + "teamNamesColorText": "Nazwy Drużyn/Kolory...", + "teamsText": "Gra Zespołowa", + "telnetAccessGrantedText": "Dostęp telnet włączony.", + "telnetAccessText": "Dostęp telnet wykryty; zezwolić?", + "testBuildErrorText": "Ta wersja testowa nie jest już dłużej aktywna; sprawdź dostępność nowej wersji.", + "testBuildText": "Wersja Testowa", + "testBuildValidateErrorText": "Niemożliwe zatwierdzenie wersji testowej. (brak internetu?)", + "testBuildValidatedText": "Wersja Testowa Zatwierdzona! Miłej zabawy!", + "thankYouText": "Dziękuję za Twoje wsparcie! Miłej gry!", + "threeKillText": "POTRÓJNE ZABÓJSTWO!!", + "timeBonusText": "Bonus czasowy", + "timeElapsedText": "Czas upłynął", + "timeExpiredText": "Czas minął", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}min", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Wskazówka", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Najlepsi znajomi", + "tournamentCheckingStateText": "Sprawdzanie statusu turnieju; proszę czekać...", + "tournamentEndedText": "Ten turniej został zakończony. Nowy wkrótce się rozpocznie.", + "tournamentEntryText": "Wejście do Turnieju", + "tournamentResultsRecentText": "Najnowsze wyniki Turnieju", + "tournamentStandingsText": "Klasyfikacja Turnieju", + "tournamentText": "Turniej", + "tournamentTimeExpiredText": "Czas Turnieju wygasł", + "tournamentsDisabledWorkspaceText": "Turnieje są wyłączone gdy obszary robocze są aktywne.\nBy włączyć turnieje, wyłącz obszar roboczy i zrestartuj grę.", + "tournamentsText": "Turnieje", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Kostek", + "Butch": "Butch", + "Easter Bunny": "Zajączek Wielkanocny", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Małgosia", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Fuks", + "Mel": "Mel", + "Middle-Man": "Kapitan Niepełniak", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Grzmot", + "Santa Claus": "Święty Mikołaj", + "Snake Shadow": "Snake Shadow", + "Spaz": "Spaz", + "Taobao Mascot": "Maskotka Taobao", + "Todd": "Todd", + "Todd McBurton": "Todd McBurton", + "Xara": "Xara", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Nieskończony\nAtak", + "Infinite\nRunaround": "Nieskończone\nOtaczanie", + "Onslaught\nTraining": "Atakujący\nTrening", + "Pro\nFootball": "Zawodowy\nFutbol", + "Pro\nOnslaught": "Atak\nZawodowca", + "Pro\nRunaround": "Zawodowe\nOtaczanie", + "Rookie\nFootball": "Futbol\nRekruta", + "Rookie\nOnslaught": "Atak\nRekruta", + "The\nLast Stand": "Ostatni\nBastion", + "Uber\nFootball": "Super\nFutbol", + "Uber\nOnslaught": "Super\nAtak", + "Uber\nRunaround": "Super\nOtaczanie" + }, + "coopLevelNames": { + "${GAME} Training": "Trening ${GAME}", + "Infinite ${GAME}": "Nieskończony tryb ${GAME}", + "Infinite Onslaught": "Nieskończony Atak", + "Infinite Runaround": "Nieskończone Otaczanie", + "Onslaught": "Nieskończony Atak", + "Onslaught Training": "Atakujący Trening", + "Pro ${GAME}": "Zawodowy tryb ${GAME}", + "Pro Football": "Zawodowy Futbol", + "Pro Onslaught": "Atak Zawodowca", + "Pro Runaround": "Zawodowe Otaczanie", + "Rookie ${GAME}": "Rekrucki tryb ${GAME}", + "Rookie Football": "Futbol Rekruta", + "Rookie Onslaught": "Atak Rekruta", + "Runaround": "Nieskończone Otaczanie", + "The Last Stand": "Ostatni Bastion", + "Uber ${GAME}": "Superowy tryb ${GAME}", + "Uber Football": "Super Futbol", + "Uber Onslaught": "Super Atak", + "Uber Runaround": "Super Otaczanie" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Bądź wybrańcem przez określony czas aby wygrać.\nZabij wybrańca aby się nim stać.", + "Bomb as many targets as you can.": "Zbombarduj tyle celów, ile tylko możesz.", + "Carry the flag for ${ARG1} seconds.": "Utrzymaj flagę przez ${ARG1} sekund.", + "Carry the flag for a set length of time.": "Utrzymaj flagę przez określony czas.", + "Crush ${ARG1} of your enemies.": "Rozbij ${ARG1} swoich wrogów.", + "Defeat all enemies.": "Pokonaj wszystkich wrogów.", + "Dodge the falling bombs.": "Unikaj spadających bomb.", + "Final glorious epic slow motion battle to the death.": "Ostateczna i chwalebna epicka bitwa w zwolnionym tempie do śmierci.", + "Gather eggs!": "Zbieraj jaja!", + "Get the flag to the enemy end zone.": "Przenieś flagę do końcowej strefy wroga.", + "How fast can you defeat the ninjas?": "Jak szybko jesteś w stanie pokonać ninja?", + "Kill a set number of enemies to win.": "Zabij ustaloną ilość wrogów aby wygrać.", + "Last one standing wins.": "Ostatni stojący wygrywa.", + "Last remaining alive wins.": "Ostatni pozostały przy życiu wygrywa.", + "Last team standing wins.": "Ostatni stojący zespół wygrywa.", + "Prevent enemies from reaching the exit.": "Zapobiegnij przed dotarciem wrogów do wyjścia.", + "Reach the enemy flag to score.": "Dotrzyj do wrogiej flagi aby zapunktować.", + "Return the enemy flag to score.": "Odzyskaj flagę wroga aby zapunktować.", + "Run ${ARG1} laps.": "Pokonaj ${ARG1} okrążeń.", + "Run ${ARG1} laps. Your entire team has to finish.": "Pokonaj ${ARG1} okrążeń. Cały Twoj zespół musi ukończyć.", + "Run 1 lap.": "Pokonaj 1 okrążenie.", + "Run 1 lap. Your entire team has to finish.": "Pokonaj 1 okrążenie. Cały Twój zespół musi ukończyć.", + "Run real fast!": "Biegnij naprawdę szybko!", + "Score ${ARG1} goals.": "Zdobądź ${ARG1} bramek.", + "Score ${ARG1} touchdowns.": "Zdobądź ${ARG1} przyłożeń.", + "Score a goal.": "Zdobądź bramkę.", + "Score a touchdown.": "Zdobądź przyłożenie.", + "Score some goals.": "Zdobądź kilka bramek.", + "Secure all ${ARG1} flags.": "Zabezpiecz wszystkie ${ARG1} flagi.", + "Secure all flags on the map to win.": "Zabezpiecz wszystkie flagi na mapie aby wygrać.", + "Secure the flag for ${ARG1} seconds.": "Zabezpiecz flagę przez ${ARG1} sekund.", + "Secure the flag for a set length of time.": "Zabezpiecz flagę przez ustalony okres czasu.", + "Steal the enemy flag ${ARG1} times.": "Ukradnij wrogą flagę ${ARG1} razy.", + "Steal the enemy flag.": "Ukradnij wrogą flagę.", + "There can be only one.": "Może być tylko jeden.", + "Touch the enemy flag ${ARG1} times.": "Dotknij wrogą flagę ${ARG1} razy.", + "Touch the enemy flag.": "Dotknij wrogą flagę.", + "carry the flag for ${ARG1} seconds": "Utrzymaj flagę przez ${ARG1} sekund", + "kill ${ARG1} enemies": "zabij ${ARG1} wrogów", + "last one standing wins": "ostatni stojący wygrywa", + "last team standing wins": "ostatni stojący zespół wygrywa", + "return ${ARG1} flags": "odzyskaj ${ARG1} flagi", + "return 1 flag": "odzyskaj 1 flagę", + "run ${ARG1} laps": "pokonaj ${ARG1} okrążenia", + "run 1 lap": "pokonaj 1 okrążenie", + "score ${ARG1} goals": "zdobądź ${ARG1} bramek", + "score ${ARG1} touchdowns": "zdobądź ${ARG1} przyłożeń", + "score a goal": "zdobądź bramkę", + "score a touchdown": "zdobądź przyłożenie", + "secure all ${ARG1} flags": "zabezpiecz wszystkie ${ARG1} flagi", + "secure the flag for ${ARG1} seconds": "zabezpiecz flagę przez ${ARG1} sekund", + "touch ${ARG1} flags": "dotknij ${ARG1} flag", + "touch 1 flag": "dotknij 1 flagę" + }, + "gameNames": { + "Assault": "Szturm", + "Capture the Flag": "Przechwyć Flagę", + "Chosen One": "Wybraniec", + "Conquest": "Podbój", + "Death Match": "Mecz śmierci", + "Easter Egg Hunt": "Polowanie na Jaja", + "Elimination": "Eliminacja", + "Football": "Futbol", + "Hockey": "Hokej", + "Keep Away": "Nie Podchodź", + "King of the Hill": "Król Wzgórza", + "Meteor Shower": "Deszcz Meteorytów", + "Ninja Fight": "Walka Ninja", + "Onslaught": "Atak", + "Race": "Wyścig", + "Runaround": "Otaczanie", + "Target Practice": "Ćwiczenie Celności", + "The Last Stand": "Ostatni Bastion" + }, + "inputDeviceNames": { + "Keyboard": "Klawiatura P1", + "Keyboard P2": "Klawiatura P2" + }, + "languages": { + "Arabic": "Arabski", + "Belarussian": "Białoruski", + "Chinese": "Chiński Uproszczony", + "ChineseTraditional": "Chiński Tradycyjny", + "Croatian": "Chorwacki", + "Czech": "Czeski", + "Danish": "Duński", + "Dutch": "Holenderski", + "English": "Angielski", + "Esperanto": "Esperanto", + "Filipino": "Filipiński", + "Finnish": "Fiński", + "French": "Francuski", + "German": "Niemiecki", + "Gibberish": "Szwargot", + "Greek": "Grecki", + "Hindi": "Hinduski", + "Hungarian": "Węgierski", + "Indonesian": "Indonezyjski", + "Italian": "Włoski", + "Japanese": "Japoński", + "Korean": "Koreański", + "Malay": "Malajski", + "Persian": "Perski", + "Polish": "Polski", + "Portuguese": "Portugalski", + "Romanian": "Rumuński", + "Russian": "Rosyjski", + "Serbian": "Serbski", + "Slovak": "słowacki", + "Spanish": "Hiszpański", + "Swedish": "Szwedzki", + "Tamil": "Tamil", + "Thai": "Tajski", + "Turkish": "Turecki", + "Ukrainian": "Ukraiński", + "Venetian": "Wenecki", + "Vietnamese": "Wietnamski" + }, + "leagueNames": { + "Bronze": "Brązowa", + "Diamond": "Diamentowa", + "Gold": "Złota", + "Silver": "Srebrna" + }, + "mapsNames": { + "Big G": "Wielkie G", + "Bridgit": "Mostowo", + "Courtyard": "Dziedziniec", + "Crag Castle": "Urwany Zamek", + "Doom Shroom": "Fatalny Grzyb", + "Football Stadium": "Stadion Futbolowy", + "Happy Thoughts": "Skrzydła Fantazji", + "Hockey Stadium": "Hala Hokejowa", + "Lake Frigid": "Lodowate Jeziorko", + "Monkey Face": "Małpiatka", + "Rampage": "Nerwówa", + "Roundabout": "Wokoło", + "Step Right Up": "Krzątanina", + "The Pad": "Płyta", + "Tip Top": "Tip Top", + "Tower D": "Wieża D", + "Zigzag": "Zygzag" + }, + "playlistNames": { + "Just Epic": "Tylko rozgrywki Epickie", + "Just Sports": "Tylko rozgrywki Sportowe" + }, + "promoCodeResponses": { + "invalid promo code": "nieprawidłowy kod promocyjny" + }, + "scoreNames": { + "Flags": "Flagi", + "Goals": "Bramki", + "Score": "Wynik", + "Survived": "Przeżył", + "Time": "Czas", + "Time Held": "Czas trzymania" + }, + "serverResponses": { + "A code has already been used on this account.": "Kod został już użyty na tym koncie.", + "A reward has already been given for that address.": "Nagroda została już wręczona na tym adresie.", + "Account linking successful!": "Łączenie kont zakończone sukcesem!", + "Account unlinking successful!": "Pomyślnie rozłączono konta!", + "Accounts are already linked.": "Konta są już połączone.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Nie można zweryfikować widoku reklamy.\nUpewnij się, że korzystasz z oficjalnej i aktualnej wersji gry.", + "An error has occurred; (${ERROR})": "Wystąpił błąd; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Wystąpił błąd; skontaktuj się z pomocą techniczną. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Wystąpił błąd; skontaktuj się z support@froemling.net.", + "An error has occurred; please try again later.": "Wystąpił błąd; spróbuj ponownie później.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Na pewno chcesz połączyć te konta?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nUwaga: To nie może być cofnięte!", + "BombSquad Pro unlocked!": "BombSquad Pro odblokowane!", + "Can't link 2 accounts of this type.": "Nie można połączyć dwóch kont tego typu.", + "Can't link 2 diamond league accounts.": "Nie można połączyć dwóch kont w diamentowej lidze.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Nie można połączyć; przekroczono limit ${COUNT} połączonych kont.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Oszukiwanie wykryte; punkty i nagrody zawieszone na ${COUNT} dni.", + "Could not establish a secure connection.": "Nie udało się nawiązać bezpiecznego połączenia.", + "Daily maximum reached.": "Dzienne maksimum wykorzystane.", + "Entering tournament...": "Wchodzenie do turnieju...", + "Invalid code.": "Nieprawidłowy kod.", + "Invalid payment; purchase canceled.": "Nieprawidłowa zapłata; zamówienie anulowane.", + "Invalid promo code.": "Nieprawidłowy kod promocyjny.", + "Invalid purchase.": "Nieprawidłowy zakup.", + "Invalid tournament entry; score will be ignored.": "Nieprawidłowe wejście do turnieju; wynik będzie zignorowany.", + "Item unlocked!": "Przedmiot odblokowany!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ŁĄCZENIE ODRZUCONE. ${ACCOUNT} zawiera\nznaczący postęp który zostałby USUNIĘTY.\nMożesz połączyć konta na odwrót jeśli chcesz\n(i stracić postęp Z TEGO konta).", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Połączyć konto ${ACCOUNT} z tym kontem?\nCały postęp z konta ${ACCOUNT} będzie stracony.\nNie można tego odwrócić. Pewna decyzja?", + "Max number of playlists reached.": "Osiągnięto maksymalną ilość playlist.", + "Max number of profiles reached.": "Osiągnięto maksymalną liczbę profili.", + "Maximum friend code rewards reached.": "Osiągnięto limit kodów promocyjnych.", + "Message is too long.": "Wiadomość jest za długa.", + "No servers are available. Please try again soon.": "Brak dostępnych serwerów. Spróbuj ponownie wkrótce.", + "Profile \"${NAME}\" upgraded successfully.": "Nazwa \"${NAME}\" ulepszona pomyślnie.", + "Profile could not be upgraded.": "Profil nie może być ulepszony.", + "Purchase successful!": "Udany zakup!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Otrzymano ${COUNT} kuponów za zapisanie się. Wróć jutro aby otrzymać\n${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Funkcje serwerowe nie są dalej wspierane na tej wersji gry;\nZaktualizuj grę i spróbuj ponownie.", + "Sorry, there are no uses remaining on this code.": "Sorka, ten kod został już raz użyty.", + "Sorry, this code has already been used.": "Przepraszamy, ten kod został już użyty.", + "Sorry, this code has expired.": "Przepraszamy, ten kod wygasł.", + "Sorry, this code only works for new accounts.": "Przepraszamy, ten kod działa tylko na nowych kontach.", + "Still searching for nearby servers; please try again soon.": "Wciąż szukam pobliskich serwerów; proszę spróbuj ponownie wkrótce.", + "Temporarily unavailable; please try again later.": "Tymczasowo niedostępne; spróbuj ponownie później.", + "The tournament ended before you finished.": "Wyniki po zakończonym turnieju.", + "This account cannot be unlinked for ${NUM} days.": "To konto nie może zostać rozłączone przez ${NUM} dni.", + "This code cannot be used on the account that created it.": "Kod nie może zostać użyty na koncie, które go stworzyło.", + "This is currently unavailable; please try again later.": "To jest obecnie niedostępne; proszę spróbować ponownie później.", + "This requires version ${VERSION} or newer.": "Wymagana wersja ${VERSION} gry lub nowsza.", + "Tournaments disabled due to rooted device.": "Turnieje wyłączone z powodu zrootowanego urządzenia.", + "Tournaments require ${VERSION} or newer": "Turnieje potrzebują ${VERSION} albo nowszej", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Rozłączyć konto ${ACCOUNT} z tego konta?\nCały postęp z konta ${ACCOUNT} zostanie zresetowany.\n(oprócz osiągnięć w niektórych przypadkach)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "OSTRZEŻENIE: przeciwko Tobie zostały złożone skargi o oszukiwanie.\nKonta ludzi oszukujących zostaną zablokowane. Proszę grać uczciwie.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Chcesz połączyć swoje konto z urządzenia z tym?\n\nTwoje konto urządzenia to ${ACCOUNT1}\nTo konto to ${ACCOUNT2}\n\nTo pozwoli Ci zapisać istniejący postęp.\nUwaga: To nie może zostać cofnięte!!!", + "You already own this!": "Już to posiadasz!", + "You can join in ${COUNT} seconds.": "Możesz dołączyć w ciągu ${COUNT} sekund.", + "You don't have enough tickets for this!": "Nie masz wystarczająco dużo kuponów!", + "You don't own that.": "Nie posiadasz tego.", + "You got ${COUNT} tickets!": "Masz ${COUNT} kuponów!", + "You got a ${ITEM}!": "Otrzymałeś ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Zostałeś awansowany do nowej ligi; gratulacje!", + "You must update to a newer version of the app to do this.": "Musisz zaktualizować do nowszej wersji gry aby to zrobić.", + "You must update to the newest version of the game to do this.": "Musisz zaktualizować grę do nowej wersji aby to zrobić.", + "You must wait a few seconds before entering a new code.": "Musisz odczekać kilka sekund zanim wpiszesz nowy kod.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Zostałeś sklasyfikowany na ${RANK} pozycji w ostatnim turnieju. Dzięki za udział!", + "Your account was rejected. Are you signed in?": "Twoje Konto Zostało Odrzucone. Jesteś Zalogowany?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Twoja kopia gry została zmodyfikowana.\nCofnij zmiany i spróbuj ponownie.", + "Your friend code was used by ${ACCOUNT}": "Kod kumpla został użyty przez ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minuta", + "1 Second": "1 Sekunda", + "10 Minutes": "10 Minut", + "2 Minutes": "2 Minuty", + "2 Seconds": "2 Sekundy", + "20 Minutes": "20 Minut", + "4 Seconds": "4 Sekundy", + "5 Minutes": "5 Minut", + "8 Seconds": "8 Sekund", + "Allow Negative Scores": "Pozostaw Wyniki Negatywne", + "Balance Total Lives": "Zbalansuj ogólną ilość żyć", + "Bomb Spawning": "Pojawianie się Bomb", + "Chosen One Gets Gloves": "Rękawice dla Wybrańca", + "Chosen One Gets Shield": "Tarcza dla Wybrańca", + "Chosen One Time": "Czas bycia Wybrańcem", + "Enable Impact Bombs": "Uaktywnij Bomby Dotykowe", + "Enable Triple Bombs": "Uaktywnij Potrójne Bomby", + "Entire Team Must Finish": "Cała drużyna musi ukończyć", + "Epic Mode": "Tryb Epicki", + "Flag Idle Return Time": "Powrót flagi po jej upuszczeniu", + "Flag Touch Return Time": "Powrót flagi po jej dotknięciu", + "Hold Time": "Czas wstrzymania", + "Kills to Win Per Player": "Zabójstw do zwycięstwa", + "Laps": "Okrążenia", + "Lives Per Player": "Życia na gracza", + "Long": "Długi", + "Longer": "Dłuższy", + "Mine Spawning": "Czas założenia miny", + "No Mines": "Bez Min", + "None": "Żaden", + "Normal": "Normalny", + "Pro Mode": "Tryb Zaawansowany", + "Respawn Times": "Czas odrodzenia", + "Score to Win": "Punktów do zwycięstwa", + "Short": "Krótki", + "Shorter": "Krótszy", + "Solo Mode": "Tryb pojedynczego gracza", + "Target Count": "Liczba docelowa", + "Time Limit": "Limit czasowy" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} zostali zdyskwalifikowani, gdyż ${PLAYER} wyszedł", + "Killing ${NAME} for skipping part of the track!": "Zabito ${NAME} za pominięcie części toru!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Ostrzeżenie dla ${NAME}: turbo / spam kontrolkami nokautuje Cię." + }, + "teamNames": { + "Bad Guys": "Źli goście", + "Blue": "Niebiescy", + "Good Guys": "Dobrzy Goście", + "Red": "Czerwoni" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Perfekcyjne w czasie wykonanie biegu, skoku, obrotu i uderzenia\nmoże zabić jednym ruchem wzbudzając respekt wśród znajomych.", + "Always remember to floss.": "Pamiętaj żeby nitkować zęby.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Stwórz takie profile gracza (nazwa i wygląd) dla siebie i znajomych, które\nbędą Wam najbardziej odpowiadać zamiast tych losowo dobieranych.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Pudła z Klątwą zamienią Cię w tykającą bombę.\nJedynym ratunkiem jest wtedy szybkie zdobycie apteczki.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Pomimo różnego wyglądu, postacie posiadają te same umiejętności, więc ma\non tylko znaczenie wizualne. Wobec tego dobierz taki, który Ci odpowiada.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Nie bądź zbyt pewny siebie mając tarczę energetyczną; wciąż ktoś może Cię zrzucić z klifu.", + "Don't run all the time. Really. You will fall off cliffs.": "Nie biegaj cały czas, bo spadniesz z klifu.", + "Don't spin for too long; you'll become dizzy and fall.": "Nie obracaj się za długo; zakręci ci się w głowie i się wywrócisz.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Przytrzymaj dowolny przycisk aby biec. (Triggery działają równie\ndobrze (jeśli je masz)).", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Przytrzymaj dowolny przycisk aby biec. Wówczas osiągniesz szybciej\nswój cel lecz biegnąc ciężko się skręca, więc uważaj aby nie spaść.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Lodowe bomby nie są potężne, ale potrafią zamrozić każdego kto\nbędzie w ich polu rażenia, wówczas będzie on podatny na skruszenie.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Jeśli ktoś Cię podniesie, uderz go wówczas Cię puści.\nSkutkuje to również w prawdziwym życiu ;)", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Jeśli brakuje Ci kontrolerów, zainstaluj aplikację '${REMOTE_APP_NAME}'\nna swoich urządzeniach, aby użyć ich jako kontrolerów.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Jeśli brakuje Ci kontrolerów do gry, zainstaluj 'BombSquad Remote'\ndostępny w odpowiednich sklepach dla urządzeń iOS/Android.\nUżyj telefonów i tabletów jako kontrolerów do gry.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Jeśli przyklei się do Ciebie bomba przylepna, skacz i kręć się szalenie, to może ją\nzrzucisz. Jeżeli Ci się nie uda, wówczas twoje ostatnie chwile będą przezabawne ;).", + "If you kill an enemy in one hit you get double points for it.": "Jeśli zabijesz wroga jednym uderzeniem, otrzymasz podwójne punkty.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Jeśli zbierzesz 'Klątwę', to jedyną nadzieją aby\nprzetrwać jest szybkie zebranie apteczki.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Jeśli będziesz się czaił w jednym miejscu to jesteś usmażony.\nBiegaj i unikaj ataków aby przetrwać.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Jeśli doświadczasz dużej rotacji wśród graczy, najlepiej włącz 'auto wyrzucanie\nbezczynnych graczy' w ustawieniach. Wyrzuci to tych, którzy nie grają a jedynie\nwiszą w grze blokując nowych chcących zagrać.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Jeśli Twoje urządzenie mocno się przegrzewa lub po prostu chcesz oszczędzić baterię,\nwyłącz 'Wizualizacje' lub zmniejsz 'Rozdzielczość' w Ustawienia->Grafika", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Jeśli ilość klatek na sekundę jest zbyt niska, spróbuj\nzmniejszyć rozdzielczość lub jakość ustawień graficznych.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "W trybie 'Przechwycenia Flagi', Twoja flaga musi znajdować się w bazie aby zapunktować.\nJeśli drugi zespół zamierza zdobyć punkt, przechwycenie ich flagi będzie dobrym\nrozwiązaniem aby ich powstrzymać.", + "In hockey, you'll maintain more speed if you turn gradually.": "Grając w hokeja, większą prędkość utrzymywać będziesz przy\nstopniowym i delikatnym skręcaniu postacią.", + "It's easier to win with a friend or two helping.": "Łatwiej zwyciężyć grając w zespole z jednym lub kilkoma\ntowarzyszami broni.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Dzięki podskokowi przy wyrzucaniu bomby można je wrzucić\nna wyższe, ciężko dostępne poziomy mapy.", + "Land-mines are a good way to stop speedy enemies.": "Miny lądowe są dobrym rozwiązaniem aby powstrzymywać\nszybkich i wściekłych wrogów.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Można podnosić i rzucać wieloma rzeczami, włącznie z graczami. Zrzucanie\nwrogów z klifów może być skuteczne, a taka strategia satysfakcjonująca.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nie, nie dostaniesz się na wyższe półki. Może rzuć na nie bomby? :)", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Gracze mogą dołączyć/opuścić grę w trakcie jej trwania,\na Ty możesz dołączać/odłączać kontrolery w locie.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Gracze mogą się dołączać/opuszczać grę w trakcie większości\nrozgrywek, tak samo można w locie podłączać/rozłączać gamepady.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Bonusy mają czasowe limity jedynie w rozgrywkach trybu Kooperacji.\nW rozgrywkach drużynowych i Free-for-All są Twoje aż do śmierci.", + "Practice using your momentum to throw bombs more accurately.": "Poćwicz wyczucie tempa aby rzucać bombami dokładniej.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Ciosy powodują większe obrażenia jeśli się energicznie porusza\npięściami, więc staraj się biegać, skakać i kręcić jak szalony.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Podbiegnij do tyłu i przed rzuceniem bomby znów\ndo przodu. Pozwoli to na jej dalsze wyrzucenie.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Pozbądź się grupy wrogów poprzez\nrzucenie bomby blisko skrzyni TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Głowa jest najbardziej wrażliwym obszarem ciała, więc przyklejona\ndo niej przylepna bomba zazwyczaj oznacza koniec dla ofiary.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Ten poziom nigdy się nie kończy, ale wysoki wynik \nda Ci wieczny szacunek na całym świecie.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Siła rzutu zależy od kierunku, który trzymasz. Aby delikatnie tylko\ncoś podrzucić przed sobą, nie trzymaj żadnego klawisza kierunku.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Zmęczony domyślną ścieżką dźwiękową? Zamień ją na swoją!\nZobacz Ustawienia->Audio->Ścieżka dźwiękowa", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Przytrzymaj 'odpaloną bombę' przez 1 lub 2 sekundy zanim ją rzucisz.", + "Try tricking enemies into killing eachother or running off cliffs.": "Spróbuj oszukać wrogów aby się wzajemnie pozabijali lub zrzucili z klifów.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Użyj przycisku 'Podnieś' aby chwycić flagę < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Cofnij się... i do przodu, aby uzyskać dalsze rzuty...", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Możesz wycelować swoje uderzenia obracając się w lewo lub prawo.\nJest to przydatne do spychania wrogów poza krawędzie lub w hokeju.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Możesz sam kontrolować i określić czas kiedy bomba eksploduje\npo kolorze iskier na jej loncie: żółty.. pomarańczowy.. czerwony.. BUM!", + "You can throw bombs higher if you jump just before throwing.": "Możesz rzucać bombami wyżej jeśli podskoczysz przed wyrzuceniem.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Nie musisz edytować swojego profilu aby zmienić postacie. Naciśnij górny\nprzycisk (podnoszenie) kiedy dołączasz do gry aby zamienić domyślną postać.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Przyjmujesz obrażenia jeśli uderzasz głową w różne\nrzeczy, więc staraj się tego nie robić.", + "Your punches do much more damage if you are running or spinning.": "Twoje ciosy zadadzą więcej obrażeń, jeśli będziesz biegać lub się kręcić." + } + }, + "trialPeriodEndedText": "Wersja trial wygasła. Czy chcesz zakupić\nBombSquad i kontynuować grę?", + "trophiesRequiredText": "Potrzebujesz przynajmniej ${NUMBER} zdobyczy.", + "trophiesText": "Zdobycze", + "trophiesThisSeasonText": "Zdobycze w tym Sezonie", + "tutorial": { + "cpuBenchmarkText": "Wykonywanie testu szybkości (głównie testuje szybkość procesora)", + "phrase01Text": "Hejka!", + "phrase02Text": "Witaj w ${APP_NAME}!", + "phrase03Text": "Oto kilka porad jak kontrolować swoją postać:", + "phrase04Text": "Wiele zachowań w ${APP_NAME} to czysta FIZYKA.", + "phrase05Text": "Przykładowo, jeśli uderzasz...", + "phrase06Text": "...skala obrażeń uzależniona jest od szybkości pięści.", + "phrase07Text": "Widzisz? Nie poruszaliśmy się, więc ${NAME} prawie nie ucierpiał.", + "phrase08Text": "Teraz skoczymy i wykonamy obrót aby zwiększyć szybkość.", + "phrase09Text": "Ooo, tak lepiej.", + "phrase10Text": "Bieganie również pomaga.", + "phrase11Text": "Przytrzymaj dowolny przycisk aby biec.", + "phrase12Text": "Dla uzyskania mocnych uderzeń, staraj się biegać i obracać.", + "phrase13Text": "Ojjj... sorki ${NAME}.", + "phrase14Text": "Możesz podnosić i rzucać np. flagami, bombami, a nawet przeciwnikiem - ${NAME}.", + "phrase15Text": "Ale BombSquad to głównie BOMBY.", + "phrase16Text": "Skuteczne rzucanie bombami wymaga odrobinę praktyki.", + "phrase17Text": "Ałć! Niezbyt dobry rzut.", + "phrase18Text": "Poruszanie się przy rzucie pozwala rzucać dalej.", + "phrase19Text": "Skakanie pozwala rzucać wyżej.", + "phrase20Text": "Kręć bombą, aby cisnąć nią dalej.", + "phrase21Text": "Wyczucie czasu przy rzucaniu bombami może być trudne.", + "phrase22Text": "Pudło.", + "phrase23Text": "Spróbuj \"przysmażyć\" lont przez sekundę lub dwie.", + "phrase24Text": "I proszę! Nieźle upieczony.", + "phrase25Text": "Cóż, to by było na tyle.", + "phrase26Text": "A teraz bierz ich tygrysie!", + "phrase27Text": "Zapamiętaj to szkolenie rekrucie, a RACZEJ wrócisz żywy!", + "phrase28Text": "...może...", + "phrase29Text": "Powodzenia!", + "randomName1Text": "Fred", + "randomName2Text": "Adaś", + "randomName3Text": "Benio", + "randomName4Text": "Czesio", + "randomName5Text": "Ignaś", + "skipConfirmText": "Naprawdę chcesz pominąć samouczek? Stuknij lub naciśnij aby zatwierdzić.", + "skipVoteCountText": "${COUNT}/${TOTAL} pominiętych głosów", + "skippingText": "pomijam samouczek...", + "toSkipPressAnythingText": "(stuknij lub naciśnij cokolwiek aby pominąć samouczek)" + }, + "twoKillText": "PODWÓJNE ZABÓJSTWO!", + "unavailableText": "niedostępne", + "unconfiguredControllerDetectedText": "Wykryto nieskonfigurowany kontroler:", + "unlockThisInTheStoreText": "To musi zostać odblokowane w sklepie.", + "unlockThisProfilesText": "By stworzyć więcej niż ${NUM} kont, potrzebujesz:", + "unlockThisText": "Żeby to odblokować, potrzebujesz:", + "unsupportedHardwareText": "Przepraszam ale ten sprzęt nie jest obsługiwany przez tą wersję gry.", + "upFirstText": "Pierwsza gra:", + "upNextText": "Kolejna, ${COUNT} gra w rozgrywce:", + "updatingAccountText": "Aktualizowanie twojego konta...", + "upgradeText": "Ulepsz", + "upgradeToPlayText": "Aby zagrać odblokuj grę w wersji \"${PRO}\".", + "useDefaultText": "Użyj domyślnych", + "usesExternalControllerText": "Ta gra wykorzystuje zewnętrzny kontroler jako wejście.", + "usingItunesText": "Korzystanie z aplikacji muzycznej jako ścieżki dźwiękowej...", + "usingItunesTurnRepeatAndShuffleOnText": "Upewnij się, że w ustawieniach iTunes tasowanie utworów i powtarzanie całości jest włączone.", + "v2AccountLinkingInfoText": "Aby połączyć konta V2, użyj przycisku \"Zarządzaj Kontem\".", + "validatingBetaText": "Legalizowanie wersji Beta...", + "validatingTestBuildText": "Sprawdzanie wersji testowej...", + "victoryText": "Zwycięstwo!", + "voteDelayText": "Nie możesz zagłosować przez następne ${NUMBER} sekund", + "voteInProgressText": "Głosowanie jest już w toku.", + "votedAlreadyText": "Już zagłosowałeś", + "votesNeededText": "Potrzeba ${NUMBER} głosów", + "vsText": "kontra", + "waitingForHostText": "(oczekiwanie na ${HOST} aby kontynuować)", + "waitingForLocalPlayersText": "Oczekiwanie na lokalnych graczy...", + "waitingForPlayersText": "oczekiwanie na dołączenie graczy...", + "waitingInLineText": "Czekanie w kolejce (impreza pełna)...", + "watchAVideoText": "Zobacz Filmik", + "watchAnAdText": "Obejrzyj reklamę", + "watchWindow": { + "deleteConfirmText": "Usunąć \"${REPLAY}\"?", + "deleteReplayButtonText": "Usuń\nPowtórkę", + "myReplaysText": "Moje Powtórki", + "noReplaySelectedErrorText": "Nie wybrano powtórki", + "playbackSpeedText": "Szybkość Powtórki: ${SPEED}", + "renameReplayButtonText": "Zmień nazwę\nPowtórki", + "renameReplayText": "Zmień nazwę \"${REPLAY}\" na:", + "renameText": "Zmień nazwę", + "replayDeleteErrorText": "Błąd usuwania powtórki.", + "replayNameText": "Nazwa Powtórki", + "replayRenameErrorAlreadyExistsText": "Powtórka z taką nazwą już istnieje.", + "replayRenameErrorInvalidName": "Nie można zmienić nazwy powtórki; nieprawidłowa nazwa.", + "replayRenameErrorText": "Błąd zmiany nazwy powtórki.", + "sharedReplaysText": "Udostępnione Powtórki", + "titleText": "Oglądaj", + "watchReplayButtonText": "Zobacz\nPowtórkę" + }, + "waveText": "Fala", + "wellSureText": "No pewnie!", + "whatIsThisText": "Co to jest?", + "wiimoteLicenseWindow": { + "titleText": "Prawa autorskie DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "Nasłuchiwanie za Wiimotami...", + "pressText": "Naciśnij jednocześnie przyciski 1 i 2 na kontrolerze Wiimote.", + "pressText2": "Na nowszych kontrolerach Wiimote z wbudowanym czujnikiem Motion Plus, naciśnij zamiennie czerwony przycisk synchronizacji." + }, + "wiimoteSetupWindow": { + "copyrightText": "Prawa autorskie DarwiinRemote", + "listenText": "Nasłuchiwanie", + "macInstructionsText": "Upewnij się, że twój kontroler Wii jest wyłączony a\nBluetooth uruchomiony na twoim Mac'u, następnie\nnaciśnij 'Słuchaj'. Wsparcie dla Wiimote może być\ntroszkę ciężko kojarzone, więc musisz spróbować\nkilkakrotnie aby uzyskać połączenie.\n\nBluetooth poradzi sobie z połączeniem do 7 urządzeń,\nchociaż ta liczba może się wahać.\n\nBombSquad wspiera oryginalne Wiimotes, Nunchuks,\ni klasyczne kontrolery. Nowy Wii Remote Plus również\npowinien współpracować lecz bez dodatków.", + "thanksText": "Podziękowania dla zespołu DarwiinRemote\nza wykonanie tej możliwości.", + "titleText": "Ustawienia Wiimote" + }, + "winsPlayerText": "${NAME} Wygrywa!", + "winsTeamText": "${NAME} Wygrywają!", + "winsText": "${NAME} Wygrywa!", + "workspaceSyncErrorText": "Błąd synchronizowania ${WORKSPACE}. Zobacz detale w logu.", + "workspaceSyncReuseText": "Nie można zsynchronizować ${WORKSPACE}. Ponowne użycie zsynchronizowanej wersji.", + "worldScoresUnavailableText": "Ogólnoświatowe wyniki niedostępne.", + "worldsBestScoresText": "Najlepsze ogólnoświatowe wyniki", + "worldsBestTimesText": "Najlepsze ogólnoświatowe czasy", + "xbox360ControllersWindow": { + "getDriverText": "Pobierz sterownik", + "macInstructions2Text": "Aby używać kontrolery bezprzewodowo, musisz posiadać odbiornik\ndostępny w zestawie 'Bezprzewodowy kontroler Xbox360 dla Windows'.\nJeden odbiornik pozwala na podłączenie do 4 kontrolerów.\n\nWażne: inne odbiorniki mogą nie współpracować ze sterownikiem;\nupewnij się, czy odbiornik posiada napis 'Microsoft', nie 'XBOX360'.\nMicrosoft nie sprzedaje odbiorników osobno, więc musisz nabyć go\nw zestawie z kontrolerem lub zakupić na aukcjach.\n\nJeśli powyższe informacje okazały się przydatne, rozważ przekazanie\ndotacji dla producenta sterownika na jego stronie.", + "macInstructionsText": "Aby użyć kontrolerów z konsoli Xbox360, musisz\nzainstalować sterownik Mac'a dostępny w poniższym linku.\nSterownik współpracuje zarówno z przewodowymi jak i\nbezprzewodowymi kontrolerami.", + "ouyaInstructionsText": "Aby skorzystać z bezprzewodowych kontrolerów konsoli Xbox360,\npodłącz je do portów USB urządzeń. Możesz skorzystać z hubu USB\naby podłączyć klika kontrolerów.\n\nAby użyć bezprzewodowe kontrolery musisz posiadać bezprzewodowy\nodbiornik, dostępny w zestawie \"Bezprzewodowy kontroler Xbox360\ndla Windows\" lub sprzedawany oddzielnie. Każdy odbiornik podłączony\ndo portu USB urządzenia pozwoli na podłączenie do 4 bezprzewodowych\nkontrolerów.", + "titleText": "Wykorzystywanie kontrolerów Xbox360 w ${APP_NAME}" + }, + "yesAllowText": "Dajesz!", + "yourBestScoresText": "Twoje najlepsze wyniki", + "yourBestTimesText": "Twoje najlepsze czasy" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/portuguese.json b/dist/ba_data/data/languages/portuguese.json new file mode 100644 index 0000000..20bdf20 --- /dev/null +++ b/dist/ba_data/data/languages/portuguese.json @@ -0,0 +1,2016 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "O seu nome não pode conter emojis ou outros caracteres especiais", + "accountProfileText": "Perfil da Conta", + "accountsText": "Contas", + "achievementProgressText": "Conquistas: ${COUNT} de ${TOTAL}", + "campaignProgressText": "Progresso da campanha [Difícil]: ${PROGRESS}", + "changeOncePerSeason": "Você só pode mudar isso uma vez por temporada.", + "changeOncePerSeasonError": "Você deve esperar até a próxima temporada para mudar isso novamente (${NUM} dias)", + "customName": "Nome personalizado", + "googlePlayGamesAccountSwitchText": "Se você quer usar uma conta Google diferente,\nUse o Google Play Games para trocar de conta.", + "linkAccountsEnterCodeText": "Inserir código", + "linkAccountsGenerateCodeText": "Gerar código", + "linkAccountsInfoText": "(compartilhar progresso entre várias plataformas)", + "linkAccountsInstructionsNewText": "Para vincular duas contas, gere um código na primeira\ne insira o código na segunda. O progresso da\nsegunda conta será sincronizado com ambas.\n(O progresso da primeira conta será perdido)\n\nVocê pode vincular até ${COUNT} contas.\n\nIMPORTANTE: vincule apenas contas que tem acesso; \nSe você vincular a conta de um amigo, vocês não\nirão conseguir jogar online ao mesmo tempo.", + "linkAccountsInstructionsText": "Para vincular duas contas, gere um código\nem uma delas e o insira na outra.\nProgresso e inventário serão combinados.\nVocê pode vincular até ${COUNT} contas.\n\nIMPORTANTE: Vincule apenas as contas que você possui!\nSe você vincular contas a seus amigos, você\nnão será capaz de jogar ao mesmo tempo!\n\nAlém disso: isso não pode ser desfeito atualmente, então tenha cuidado!", + "linkAccountsText": "Vincular contas", + "linkedAccountsText": "Contas vinculadas:", + "manageAccountText": "Gerenciar Conta", + "nameChangeConfirm": "Mudar o nome da sua conta para ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Isto reiniciará o seu progresso no cooperativo e\nas suas pontuações (mas não os seus bilhetes).\nIsto não pode ser desfeito. Tem certeza?", + "resetProgressConfirmText": "Isto reiniciará o seu progresso no cooperativo,\nas suas conquistas e as suas pontuações\n(mas não os seus bilhetes). Isto não pode\nser desfeito. Tem certeza?", + "resetProgressText": "Reiniciar progresso", + "setAccountName": "Escolha o nome da conta", + "setAccountNameDesc": "Escolha o nome que será exibido na sua conta.\nVocê pode usar o nome de uma de suas contas\nou criar um nome personalizado exclusivo.", + "signInInfoText": "Inicie sessão para ganhar bilhetes, compita online e compartilhe\no seu progresso entre vários dispositivos.", + "signInText": "Iniciar sessão", + "signInWithDeviceInfoText": "(uma conta automática disponível apenas neste aparelho)", + "signInWithDeviceText": "Iniciar sessão com conta do dispositivo", + "signInWithGameCircleText": "Iniciar sessão com Game Circle", + "signInWithGooglePlayText": "Iniciar sessão com Google Play", + "signInWithTestAccountInfoText": "(tipo de conta legado; use as contas do dispositivo daqui em diante)", + "signInWithTestAccountText": "Iniciar sessão com conta teste", + "signInWithV2InfoText": "(uma conta que funciona em todas as plataformas)", + "signInWithV2Text": "Iniciar sessão com conta do BombSquad", + "signOutText": "Finalizar sessão", + "signingInText": "Iniciando sessão...", + "signingOutText": "Finalizando sessão...", + "testAccountWarningCardboardText": "Atenção: você está entrando com uma conta \"teste\".\nUma hora elas serão trocadas por contas Google\nassim que elas forem suportadas nos apps do cardboard.\n\nPor agora, você terá que ganhar todos os tickets dentro do jogo.\n(mesmo assim você ganha o upgrade BombSquad Pro gratuitamente)", + "testAccountWarningOculusText": "Aviso: você está conectando com uma \"conta de teste\".\nEles serão substituídos por contas Oculus mais tarde que oferecerá compras de tickets\ne muito mais. \n\nPor enquanto você terá que ganhar todos os tickets no jogo.\n(No entanto, você obterá a atualização BombSquad Pro de graça)", + "testAccountWarningText": "Aviso: você está conectando com uma \"conta teste\".\nEsta conta está vinculada somente à este aparelho e \npoderá ser restaurada periodicamente. (Então por favor\nnão gaste tempo coletando/desbloqueando itens nela)\n\nExecute a versão completa do jogo para usar uma\n\"conta real\" (Game-Center, Google Plus, etc.)\nIsto permite o armazenamento do seu progresso\nna nuvem e compartilha-lo com outros aparelhos. \n", + "ticketsText": "Bilhetes: ${COUNT}", + "titleText": "Conta", + "unlinkAccountsInstructionsText": "Selecione uma conta para desvincular", + "unlinkAccountsText": "Desvincular contas", + "unlinkLegacyV1AccountsText": "Desvincular contas herdadas (V1)", + "v2LinkInstructionsText": "Utilize o link para criar uma conta ou entrar nela.", + "viaAccount": "(via ${NAME})", + "youAreLoggedInAsText": "Você está logado como:", + "youAreSignedInAsText": "Iniciou sessão como:" + }, + "achievementChallengesText": "Desafios conquistados", + "achievementText": "Conquistas", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Mate 3 inimigos com TNT", + "descriptionComplete": "Matou 3 inimigos com TNT", + "descriptionFull": "Mate 3 inimigos com TNT no ${LEVEL}", + "descriptionFullComplete": "Matou 3 inimigos com TNT no ${LEVEL}", + "name": "Quem brinca com fogo, sai queimado" + }, + "Boxer": { + "description": "Ganhe sem usar bombas", + "descriptionComplete": "Ganhou sem usar bombas", + "descriptionFull": "Complete o ${LEVEL} sem usar bombas", + "descriptionFullComplete": "Completou o ${LEVEL} sem usar bombas", + "name": "Boxeador" + }, + "Dual Wielding": { + "descriptionFull": "Conecte 2 controles (hardware ou aplicativo)", + "descriptionFullComplete": "Conectou 2 controles (hardware ou aplicativo)", + "name": "Dominação dupla" + }, + "Flawless Victory": { + "description": "Ganhe sem ser atingido", + "descriptionComplete": "Ganhou sem ser atingido", + "descriptionFull": "Ganhe o ${LEVEL} sem ser atingido", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem ser atingido", + "name": "Vitória perfeita" + }, + "Free Loader": { + "descriptionFull": "Comece um Todos contra todos com mais de 2 jogadores", + "descriptionFullComplete": "Começou um Todos contra todos com mais de 2 jogadores", + "name": "Carregador livre" + }, + "Gold Miner": { + "description": "Mate 6 inimigos com minas", + "descriptionComplete": "Matou 6 inimigos com minas", + "descriptionFull": "Mate 6 inimigos com minas no ${LEVEL}", + "descriptionFullComplete": "Matou 6 inimigos com minas no ${LEVEL}", + "name": "Garimpeiro" + }, + "Got the Moves": { + "description": "Ganhe sem usar socos ou bombas", + "descriptionComplete": "Ganhou sem usar socos ou bombas", + "descriptionFull": "Ganhe o ${LEVEL} sem socos ou bombas", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem socos ou bombas", + "name": "Esse Tem Gingado" + }, + "In Control": { + "descriptionFull": "Conecte um controle (hardware ou aplicativo)", + "descriptionFullComplete": "Conectou um controle. (hardware ou aplicativo)", + "name": "No controle" + }, + "Last Stand God": { + "description": "Marque 1000 pontos", + "descriptionComplete": "Marcou 1000 pontos", + "descriptionFull": "Marque 1000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 1000 pontos no ${LEVEL}", + "name": "${LEVEL} Deus" + }, + "Last Stand Master": { + "description": "Marque 250 pontos", + "descriptionComplete": "Marcou 250 pontos", + "descriptionFull": "Marque 250 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 250 pontos no ${LEVEL}", + "name": "${LEVEL} Mestre" + }, + "Last Stand Wizard": { + "description": "Marque 500 pontos", + "descriptionComplete": "Marcou 500 pontos", + "descriptionFull": "Marque 500 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 500 pontos no ${LEVEL}", + "name": "${LEVEL} Mago" + }, + "Mine Games": { + "description": "Mate 3 inimigos com minas", + "descriptionComplete": "Matou 3 inimigos com minas", + "descriptionFull": "Mate 3 inimigos com minas no ${LEVEL}", + "descriptionFullComplete": "Matou 3 inimigos com minas no ${LEVEL}", + "name": "Brincando com Minas" + }, + "Off You Go Then": { + "description": "Mande 3 inimigos para fora do mapa", + "descriptionComplete": "Mandou 3 inimigos para fora do mapa", + "descriptionFull": "Mande 3 inimigos para fora do mapa no ${LEVEL}", + "descriptionFullComplete": "Mandou 3 inimigos para fora do mapa no ${LEVEL}", + "name": "Pode Ir Agora" + }, + "Onslaught God": { + "description": "Marque 5000 pontos", + "descriptionComplete": "Marcou 5000 pontos", + "descriptionFull": "Marque 5000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 5000 pontos no ${LEVEL}", + "name": "${LEVEL} Deus" + }, + "Onslaught Master": { + "description": "Marque 500 pontos", + "descriptionComplete": "Marcou 500 pontos", + "descriptionFull": "Marque 500 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 500 pontos no ${LEVEL}", + "name": "${LEVEL} Mestre" + }, + "Onslaught Training Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Derrotou todas as ondas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Derrotou todas as ondas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Marque 1000 pontos", + "descriptionComplete": "Marcou 1000 pontos", + "descriptionFull": "Marque 1000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 1000 pontos no ${LEVEL}", + "name": "Mago do ${LEVEL}" + }, + "Precision Bombing": { + "description": "Ganhe sem poderes", + "descriptionComplete": "Ganhou sem poderes", + "descriptionFull": "Ganhe ${LEVEL} sem poderes", + "descriptionFullComplete": "Ganhou ${LEVEL} sem poderes", + "name": "Chuva de Bomba" + }, + "Pro Boxer": { + "description": "Ganhe sem usar bombas", + "descriptionComplete": "Ganhou sem usar bombas", + "descriptionFull": "Complete o ${LEVEL} sem usar bombas", + "descriptionFullComplete": "Completou o ${LEVEL} sem usar bombas", + "name": "Pugilista" + }, + "Pro Football Shutout": { + "description": "Ganhe sem deixar os inimigos marcarem", + "descriptionComplete": "Ganhou sem deixar os inimigos marcarem", + "descriptionFull": "Ganhe o ${LEVEL} sem deixar os inimigos marcarem", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem deixar os inimigos marcarem", + "name": "${LEVEL} De Lavada" + }, + "Pro Football Victory": { + "description": "Ganhe a partida", + "descriptionComplete": "Ganhou a partida", + "descriptionFull": "Ganhe a partida no ${LEVEL}", + "descriptionFullComplete": "Ganhou a partida no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Todas as ondas derrotadas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Todas as ondas do ${LEVEL} derrotadas", + "name": "Vitória no ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Complete todas as ondas", + "descriptionComplete": "Todas as ondas completadas", + "descriptionFull": "Complete todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Todas as ondas completadas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Ganhe sem deixar os inimigos marcarem", + "descriptionComplete": "Ganhou sem deixar os inimigos marcarem", + "descriptionFull": "Ganhe no ${LEVEL} sem deixar os inimigos marcarem", + "descriptionFullComplete": "Ganhou no ${LEVEL} sem deixar os inimigos marcarem", + "name": "${LEVEL} de levada" + }, + "Rookie Football Victory": { + "description": "Ganhe a partida", + "descriptionComplete": "Ganhou a partida", + "descriptionFull": "Ganhe a partida no ${LEVEL}", + "descriptionFullComplete": "Ganhou a partida no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Todas as ondas derrotadas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Todas as ondas no ${LEVEL} derrotadas", + "name": "Vitória no ${LEVEL}" + }, + "Runaround God": { + "description": "Marque 2000 pontos", + "descriptionComplete": "Marcou 2000 pontos", + "descriptionFull": "Marque 2000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 2000 pontos no ${LEVEL}", + "name": "Deus da ${LEVEL}" + }, + "Runaround Master": { + "description": "Marque 500 pontos", + "descriptionComplete": "Marcou 500 pontos", + "descriptionFull": "Marque 500 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 500 pontos no ${LEVEL}", + "name": "Mestre do ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Marque 1000 pontos", + "descriptionComplete": "Marcou 1000 pontos", + "descriptionFull": "Marque 1000 pontos no ${LEVEL}", + "descriptionFullComplete": "Marcou 1000 pontos no ${LEVEL}", + "name": "Mago do ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Compartilhe o jogo com um amigo", + "descriptionFullComplete": "Jogo compartilhado com um amigo", + "name": "Compartilhar é amar" + }, + "Stayin' Alive": { + "description": "Ganhe sem morrer", + "descriptionComplete": "Ganhou sem morrer", + "descriptionFull": "Ganhe o ${LEVEL} sem morrer", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem morrer", + "name": "Sobrevivendo" + }, + "Super Mega Punch": { + "description": "Cause 100% de dano com um soco", + "descriptionComplete": "Causou 100% de dano com um soco", + "descriptionFull": "Cause 100% de dano com um soco no ${LEVEL}", + "descriptionFullComplete": "Causou 100% de dano com um soco no ${LEVEL}", + "name": "Super mega soco" + }, + "Super Punch": { + "description": "Cause 50% de dano com um soco", + "descriptionComplete": "Causou 50% de dano com um soco", + "descriptionFull": "Cause 50% de dano com um soco no ${LEVEL}", + "descriptionFullComplete": "Causou 50% de dano com um soco no ${LEVEL}", + "name": "Supersoco" + }, + "TNT Terror": { + "description": "Mate 6 inimigos com TNT", + "descriptionComplete": "Matou 6 inimigos com TNT", + "descriptionFull": "Mate 6 inimigos com TNT no ${LEVEL}", + "descriptionFullComplete": "Matou 6 inimigos com TNT no ${LEVEL}", + "name": "Terror do TNT" + }, + "Team Player": { + "descriptionFull": "Comece um jogo de equipes com mais de 4 jogadores", + "descriptionFullComplete": "Começou um jogo de equipes com mais de 4 jogadores", + "name": "Jogador de equipe" + }, + "The Great Wall": { + "description": "Pare todos os inimigos", + "descriptionComplete": "Parou todos os inimigos", + "descriptionFull": "Pare todos os inimigos no ${LEVEL}", + "descriptionFullComplete": "Parou todos os inimigos no ${LEVEL}", + "name": "A Grande Muralha" + }, + "The Wall": { + "description": "Pare todos os inimigos", + "descriptionComplete": "Parou todos os inimigos", + "descriptionFull": "Pare todos os inimigos no ${LEVEL}", + "descriptionFullComplete": "Parou todos os inimigos no ${LEVEL}", + "name": "A Muralha" + }, + "Uber Football Shutout": { + "description": "Ganhe sem deixar os inimigos marcarem", + "descriptionComplete": "Ganhou sem deixar os inimigos marcarem", + "descriptionFull": "Ganhe o ${LEVEL} sem deixar os inimigos marcarem", + "descriptionFullComplete": "Ganhou o ${LEVEL} sem deixar os inimigos marcarem", + "name": "${LEVEL} De Lavada" + }, + "Uber Football Victory": { + "description": "Ganhe a partida", + "descriptionComplete": "Ganhou a partida", + "descriptionFull": "Ganhe a partida no ${LEVEL}", + "descriptionFullComplete": "Ganhou a partida no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Derrote todas as ondas", + "descriptionComplete": "Derrotou todas as ondas", + "descriptionFull": "Derrote todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Derrotou todas as ondas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Complete todas as ondas", + "descriptionComplete": "Completou todas as ondas", + "descriptionFull": "Complete todas as ondas no ${LEVEL}", + "descriptionFullComplete": "Completou todas as ondas no ${LEVEL}", + "name": "Vitória no ${LEVEL}" + } + }, + "achievementsRemainingText": "Conquistas restantes:", + "achievementsText": "Conquistas", + "achievementsUnavailableForOldSeasonsText": "Desculpe, algumas conquistas não estão disponíveis em temporadas antigas.", + "activatedText": "${THING} foi ativado.", + "addGameWindow": { + "getMoreGamesText": "Mais jogos...", + "titleText": "Adicionar jogo" + }, + "allowText": "Permitir", + "alreadySignedInText": "A conta tem sessão iniciada em outro dispositivo;\nMude de conta ou feche o jogo no seu\noutro dispositivo e tente novamente.", + "apiVersionErrorText": "Não é possível carregar o módulo ${NAME}; ele é destinado à versão ${VERSION_USED}; exigimos a ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" ativado apenas quando os fones estão conectados)", + "headRelativeVRAudioText": "Áudio para fones de RV", + "musicVolumeText": "Volume da música", + "soundVolumeText": "Volume do som", + "soundtrackButtonText": "Trilha sonora", + "soundtrackDescriptionText": "(tocar a sua própria música durante o jogo)", + "titleText": "Áudio" + }, + "autoText": "Auto", + "backText": "Voltar", + "banThisPlayerText": "Banir este jogador", + "bestOfFinalText": "Final de Melhor-de-${COUNT}", + "bestOfSeriesText": "Melhor série de ${COUNT}:", + "bestRankText": "Sua melhor pontuação é #${RANK}", + "bestRatingText": "Sua melhor classificação é ${RATING}", + "betaErrorText": "Essa versão beta não está mais ativa; por favor verifique a nova versão.", + "betaValidateErrorText": "Incapaz de validar versão beta. (sem conexão de internet?) ", + "betaValidatedText": "Versão beta Validada; Aproveite!", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Impulso", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} é configurado no próprio aplicativo.", + "buttonText": "botão", + "canWeDebugText": "Deseja que o BombSquad comunique os erros, falhas e \ninformações básicas de uso para o desenvolvedor?\n\nEstes dados não contêm informações pessoais e ajudam\na manter o jogo funcionando corretamente.", + "cancelText": "Cancelar", + "cantConfigureDeviceText": "Desculpe, ${DEVICE} não é configurável.", + "challengeEndedText": "Este desafio acabou.", + "chatMuteText": "Silenciar chat", + "chatMutedText": "Chat silenciado", + "chatUnMuteText": "Reativar som do chat", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Você deve completar \neste nível para continuar!", + "completionBonusText": "Bônus de conclusão", + "configControllersWindow": { + "configureControllersText": "Configurar controles", + "configureGamepadsText": "Configurar Controles", + "configureKeyboard2Text": "Configurar teclado P2", + "configureKeyboardText": "Configurar teclado", + "configureMobileText": "Usar dispositivos como controles", + "configureTouchText": "Configurar touchscreen", + "ps3Text": "Controles PS3", + "titleText": "Controles", + "wiimotesText": "Wiimotes", + "xbox360Text": "Controles Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Nota: o suporte ao controle varia conforme o dispositivo e a versão do Android.", + "pressAnyButtonText": "Aperte qualquer botão no controle\nque você deseja configurar...", + "titleText": "Configurar controles" + }, + "configGamepadWindow": { + "advancedText": "Avançado", + "advancedTitleText": "Configuração avançada dos controles", + "analogStickDeadZoneDescriptionText": "(ative isto se o personagem 'escorrega' quando você solta o direcional)", + "analogStickDeadZoneText": "Área morta do analógico", + "appliesToAllText": "(serve para todos os controles deste tipo)", + "autoRecalibrateDescriptionText": "(ative isto se o personagem não se move na velocidade máxima)", + "autoRecalibrateDescriptionTextScale": 0.4, + "autoRecalibrateText": "Calibrar automaticamente o analógico", + "autoRecalibrateTextScale": 0.65, + "axisText": "eixo", + "clearText": "limpar", + "dpadText": "direcional", + "extraStartButtonText": "Botão Start Extra", + "ifNothingHappensTryAnalogText": "Se nada acontecer, tente mudar para o analógico.", + "ifNothingHappensTryDpadText": "Se nada acontecer, tente mudar para o botão direcional.", + "ignoreCompletelyDescriptionText": "(impedir este controle de afetar tanto o jogo quanto o menu)", + "ignoreCompletelyText": "Ignorar totalmente", + "ignoredButton1Text": "Botão 1 ignorado", + "ignoredButton2Text": "Botão 2 ignorado", + "ignoredButton3Text": "Botão 3 ignorado", + "ignoredButton4Text": "Botão 4 ignorado", + "ignoredButtonDescriptionText": "(use isto para evitar que os botões 'home' ou 'sync' afetem a UI)", + "ignoredButtonDescriptionTextScale": 0.4, + "ignoredButtonText": "Botão Ignorado", + "pressAnyAnalogTriggerText": "Aperte qualquer gatilho...", + "pressAnyButtonOrDpadText": "Aperte qualquer botão ou direcional...", + "pressAnyButtonText": "Aperte qualquer botão...", + "pressLeftRightText": "Aperte esquerda ou direita...", + "pressUpDownText": "Aperte cima ou baixo...", + "runButton1Text": "Executar botão 1", + "runButton2Text": "Executar botão 2", + "runTrigger1Text": "Executar gatilho 1", + "runTrigger2Text": "Executar gatilho 2", + "runTriggerDescriptionText": "(os gatilhos o permitem correr em diferentes velocidades)", + "secondHalfText": "Use isto para configurar a segunda metade\nde um controle que funciona\ncomo 2-em-1.", + "secondaryEnableText": "Ativar", + "secondaryText": "Controle secundário", + "startButtonActivatesDefaultDescriptionText": "(desative se o seu botão start está mais para um botão de menu)", + "startButtonActivatesDefaultText": "O botão Start ativa o widget padrão", + "startButtonActivatesDefaultTextScale": 0.65, + "titleText": "Configuração do controle", + "twoInOneSetupText": "Configuração do Controle 2-em-1", + "uiOnlyDescriptionText": "(impede que este controle entre em um jogo)", + "uiOnlyText": "Limitar o Uso ao Menu", + "unassignedButtonsRunText": "Todo o botão não definido executa", + "unassignedButtonsRunTextScale": 0.8, + "unsetText": "", + "vrReorientButtonText": "Botão Reorientar VR" + }, + "configKeyboardWindow": { + "configuringText": "Configurando ${DEVICE}", + "keyboard2NoteScale": 0.7, + "keyboard2NoteText": "Nota: a maioria dos teclados só podem registrar\nalgumas teclas pressionadas de uma só vez, portanto\npode funcionar melhor se houver um segundo teclado\nconectado. Perceba que, mesmo nesse caso, você ainda\nprecisará definir teclas exclusivas para os dois jogadores." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Escala de ação do controle", + "actionsText": "Ações", + "buttonsText": "botões", + "dragControlsText": "< arraste controles para reposicioná-los >", + "joystickText": "joystick", + "movementControlScaleText": "Escala de movimento do controle", + "movementText": "Movimento", + "resetText": "Reiniciar", + "swipeControlsHiddenText": "Ocultar ícones de deslize", + "swipeInfoText": "O estilo 'Deslize' do controle leva um tempo para se acostumar, mas\nfaz com que seja mais fácil de jogar sem olhar para os controles.", + "swipeText": "deslize", + "titleText": "Configurar touchscreen", + "touchControlsScaleText": "Escala de Toque do Controle" + }, + "configureItNowText": "Configurar agora?", + "configureText": "Configurar", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsScale": 0.65, + "bestResultsText": "Para melhores resultados, é necessário uma rede Wi-Fi\nsem lag. Você pode melhorar o desempenho desligando outros\ndispositivos, jogando perto do seu roteador e conectando\no anfitrião do jogo à rede através do Ethernet.", + "explanationScale": 0.8, + "explanationText": "Para usar um telefone ou tablet como controle,\nbaixe gratuitamente o aplicativo \"${REMOTE_APP_NAME}\".\nDá para conectar quantos dispositivos quiser a ${APP_NAME} pelo Wi-Fi!", + "forAndroidText": "para Android:", + "forIOSText": "para iOS:", + "getItForText": "Baixe ${REMOTE_APP_NAME} para iOS na Apple App Store\nou para Android na Google Play Store ou na Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Usando dispositivos como controles:" + }, + "continuePurchaseText": "Continuar por ${PRICE}?", + "continueText": "Continuar", + "controlsText": "Controles", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Isso não se aplica às classificações de todos os tempos.", + "activenessInfoText": "Este multiplicador aumenta nos dias que você joga\ne diminui nos dias que você não joga.", + "activityText": "Atividade", + "campaignText": "Campanha", + "challengesInfoText": "Ganhe prêmios por completar minijogos.\n\nPrêmios e dificuldade aumentam toda\nvez que um desafio é concluído e\ndiminui quando expira ou é abandonado.", + "challengesText": "Desafios", + "currentBestText": "O Melhor do Momento", + "customText": "Personalizado", + "entryFeeText": "Entrada", + "forfeitConfirmText": "Abandonar este desafio?", + "forfeitNotAllowedYetText": "Este desafio ainda não pode ser abandonado.", + "forfeitText": "Abandonar", + "multipliersText": "Multiplicadores", + "nextChallengeText": "Próximo desafio", + "nextPlayText": "Próximo jogo", + "ofTotalTimeText": "de ${TOTAL}", + "playNowText": "Jogar agora", + "pointsText": "Pontos", + "powerRankingFinishedSeasonUnrankedText": "(acabou a temporada casual)", + "powerRankingNotInTopText": "(não está no top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} pts)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)", + "powerRankingText": "Classificação geral", + "prizesText": "Prêmios", + "proMultInfoText": "Jogadores com a versão ${PRO}\nrecebem um aumento de ${PERCENT}% nos pontos.", + "seeMoreText": "Mais...", + "skipWaitText": "Pular espera", + "timeRemainingText": "Tempo restante", + "titleText": "Cooperativo", + "toRankedText": "Para classificar", + "totalText": "total", + "tournamentInfoText": "Jogue para ser o melhor contra\noutros jogadores na sua liga.\n\nOs prêmios são dados aos melhores\njogadores quando o torneio acaba.", + "welcome1Text": "Bem-vindo à ${LEAGUE}. Você pode melhorar a sua\nclassificação de liga ao receber estrelas, ao obter\nconquistas e ao ganhar troféus em torneios.", + "welcome2Text": "Você também pode ganhar bilhetes ao fazer várias dessas atividades.\nOs bilhetes podem ser usados para desbloquear novos personagens,\nmapas e minijogos, entrar em torneios e muito mais.", + "yourPowerRankingText": "Sua classificação geral:" + }, + "copyConfirmText": "Copiado para a área de transferência", + "copyOfText": "Cópia de ${NAME}", + "copyText": "Copiar", + "copyrightText": "© 2013 Eric Froemling", + "createAPlayerProfileText": "Criar um perfil de jogador?", + "createEditPlayerText": "", + "createText": "Criar", + "creditsWindow": { + "additionalAudioArtIdeasText": "Áudio adicional, Arte inicial e ideias por ${NAME}", + "additionalMusicFromText": "Música adicional de ${NAME}", + "allMyFamilyText": "Toda a família e amigos que ajudaram nos testes", + "codingGraphicsAudioText": "Programação, gráficos e áudio por ${NAME}", + "creditsText": " Codificação, Gráficos, e Áudio por Eric Froemling\n \n Áudio Adicional, Trabalho de Arte Inicial, e Ideias por Raphael Suter\n \n Som & Música:\n\n${SOUND_AND_MUSIC}\n\n Música de Domínio Público via Musopen.com (um ótimo site para música clássica)\n Agradecimentos especialmente para o Exército dos EUA, Marinha e Bandas da Marinha.\n\n Um grande obrigado aos seguintes colaboradores do freesound.org para o uso de seus sons:\n${FREESOUND_NAMES}\n\n Agradecimentos Especiais:\n\n Todd, Laura, e Robert Froemling\n Todos os meus amigos e familiares que ajudaram a testar o jogo\n Quem quer que inventou o café\n\n Legal:\n\n${LEGAL_STUFF}\n\n www.froemling.net\n", + "languageTranslationsText": "Traduções:", + "legalText": "Legal:", + "publicDomainMusicViaText": "Musica de domínio público via ${NAME}", + "softwareBasedOnText": "Este software é baseado em parte do trabalho de ${NAME}", + "songCreditText": "${TITLE} Executada por ${PERFORMER}\nComposta por ${COMPOSER}, Arranjo por ${ARRANGER}, Publicada por ${PUBLISHER},\nCortesia de ${SOURCE}", + "soundAndMusicText": "Som e música:", + "soundsText": "Sons (${SOURCE}):", + "specialThanksText": "Agradecimentos especiais:", + "thanksEspeciallyToText": "Obrigado especialmente a ${NAME}", + "titleText": "Créditos do ${APP_NAME}", + "whoeverInventedCoffeeText": "Seja lá quem for o inventor do café" + }, + "currentStandingText": "Sua posição atual é #${RANK}", + "customizeText": "Personalizar...", + "deathsTallyText": "${COUNT} mortes", + "deathsText": "Mortes", + "debugText": "depurar", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Nota: recomenda-se que defina Configurações->Gráficos->Texturas para \"Alto\" ao testar isto.", + "runCPUBenchmarkText": "Testar desempenho da CPU", + "runGPUBenchmarkText": "Testar desempenho da GPU", + "runMediaReloadBenchmarkText": "Testar carregamento de mídia", + "runStressTestText": "Testar estabilidade", + "stressTestPlayerCountText": "Contador de jogadores", + "stressTestPlaylistDescriptionText": "Playlist teste de estabilidade", + "stressTestPlaylistNameText": "Nome da playlist", + "stressTestPlaylistTypeText": "Tipo de playlist", + "stressTestRoundDurationText": "Tempo da rodada", + "stressTestTitleText": "Teste de estabilidade", + "titleText": "Testes de performance e estabilidade", + "totalReloadTimeText": "Tempo total de carregamento: ${TIME} (veja relatório para detalhes)", + "unlockCoopText": "Desbloquear níveis cooperativos" + }, + "defaultFreeForAllGameListNameText": "Jogos Livre-para-Todos Padrão", + "defaultGameListNameText": "Playlist ${PLAYMODE} Padrão", + "defaultNewFreeForAllGameListNameText": "Meus Jogos Livre-para-Todos", + "defaultNewGameListNameText": "Minha playlist ${PLAYMODE}", + "defaultNewTeamGameListNameText": "Meus Jogos em Equipe", + "defaultTeamGameListNameText": "Jogos em Equipe Padrão", + "deleteText": "Excluir", + "demoText": "Teste", + "denyText": "Recusar", + "deprecatedText": "Descontinuado", + "desktopResText": "Resolução da área de trabalho", + "deviceAccountUpgradeText": "Aviso:\nVocê está logado com a conta do seu dispositivo\n(${NAME}).\nContas de dispositivo serão removidas em uma atualização futura.", + "difficultyEasyText": "Fácil", + "difficultyHardOnlyText": "Modo difícil apenas", + "difficultyHardText": "Difícil", + "difficultyHardUnlockOnlyText": "Esta fase só pode ser desbloqueada no modo difícil.\nVocê acha que aguenta o desafio!?!?!", + "directBrowserToURLText": "Por favor, direcione a seguinte URL para um navegador:", + "disableRemoteAppConnectionsText": "Desativar conexões do aplicativo BombSquad Remote", + "disableXInputDescriptionText": "Permite mais de 4 controles mas pode não funcionar bem.", + "disableXInputText": "Desativar XInput", + "doneText": "Concluído", + "drawText": "Empate", + "duplicateText": "Duplicar", + "editGameListWindow": { + "addGameText": "Adicionar\nJogo", + "cantOverwriteDefaultText": "Não é possível sobrescrever a playlist padrão!", + "cantSaveAlreadyExistsText": "Já existe uma playlist com este nome!", + "cantSaveEmptyListText": "Não é possível salvar uma playlist vazia!", + "editGameText": "Editar\nJogo", + "gameListText": "Lista de Jogos", + "listNameText": "Nome da playlist", + "nameText": "Nome", + "removeGameText": "Remover\nJogo", + "saveText": "Salvar lista", + "titleText": "Editor de playlist" + }, + "editProfileWindow": { + "accountProfileInfoText": "Este perfil especial tem nome e\nícone baseado na sua conta.\n\n${ICONS}\n\nCrie perfis personalizados para usar\nnomes diferentes ou ícones personalizados.", + "accountProfileText": "(perfil da conta)", + "availableText": "O nome \"${NAME}\" está disponível.", + "changesNotAffectText": "Nota: as alterações não afetarão personagens já contidos no jogo", + "characterText": "personagem", + "checkingAvailabilityText": "Verificando disponibilidade para \"${NAME}\"...", + "colorText": "cor", + "getMoreCharactersText": "Obter mais personagens...", + "getMoreIconsText": "Obter mais ícones...", + "globalProfileInfoText": "Garante-se que perfis globais tenham nomes\núnicos. Possuem também ícones personalizados.", + "globalProfileText": "(perfil global)", + "highlightText": "detalhe", + "iconText": "ícone", + "localProfileInfoText": "Os perfis locais não possuem ícones e não se garante que seus\nnomes sejam únicos. Atualize para um perfil global para\nreservar um nome único e adicionar um ícone personalizado.", + "localProfileText": "(perfil local)", + "nameDescriptionText": "Nome do jogador", + "nameText": "Nome", + "randomText": "aleatório", + "titleEditText": "Editar perfil", + "titleNewText": "Novo perfil", + "unavailableText": "\"${NAME}\" está indisponível; tente outro nome.", + "upgradeProfileInfoText": "Isso irá reservar o nome do seu jogador mundialmente\ne permitirá definir um ícone personalizado a ele.", + "upgradeToGlobalProfileText": "Atualizar para perfil global" + }, + "editProfilesAnyTimeText": "(você pode editar os perfis a qualquer momento em \"Configurações\")", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Você não pode excluir a trilha sonora padrão.", + "cantEditDefaultText": "Não é possível editar a trilha sonora padrão. Duplique ou crie uma nova.", + "cantEditWhileConnectedOrInReplayText": "Você não pode editar trilhas sonoras enquanto estiver conectado a um grupo ou em um replay.", + "cantOverwriteDefaultText": "Não é possível sobrescrever a trilha sonora padrão", + "cantSaveAlreadyExistsText": "Já existe uma trilha sonora com esse nome!", + "copyText": "Copiar", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Trilha sonora padrão", + "deleteConfirmText": "Excluir trilha sonora:\n\n'${NAME}'?", + "deleteText": "Excluir\nTrilha sonora", + "duplicateText": "Duplicar\nTrilha sonora", + "editSoundtrackText": "Editor de trilha sonora", + "editText": "Editar\nTrilha sonora", + "fetchingITunesText": "Buscando playlists do app de música", + "musicVolumeZeroWarning": "Aviso: o volume da música está zerado", + "nameText": "Nome", + "newSoundtrackNameText": "Minha trilha sonora ${COUNT}", + "newSoundtrackText": "Nova trilha sonora:", + "newText": "Nova\nTrilha sonora", + "selectAPlaylistText": "Selecione uma playlist", + "selectASourceText": "Fonte de música", + "soundtrackText": "Trilha Sonora", + "testText": "teste", + "titleText": "Trilhas sonoras", + "useDefaultGameMusicText": "Música padrão", + "useITunesPlaylistText": "Playlist do app de música", + "useMusicFileText": "Arquivo de música (mp3, etc)", + "useMusicFolderText": "Pasta de arquivos de música" + }, + "editText": "Editar", + "endText": "Fim", + "enjoyText": "Aproveite!", + "epicDescriptionFilterText": "${DESCRIPTION} em câmera lenta épica.", + "epicNameFilterText": "${NAME} épico(a)", + "errorAccessDeniedText": "acesso negado", + "errorDeviceTimeIncorrectText": "A hora do seu dispositivo está incorreta por ${HOURS} horas.\nIsso causará problemas. \nPor-Favor cheque suas configurações de hora e fuso horário.", + "errorOutOfDiskSpaceText": "pouco espaço em disco", + "errorSecureConnectionFailText": "Não foi possível estabelecer uma conexão segura à nuvem; a funcionalidade da rede pode falhar.", + "errorText": "Erro", + "errorUnknownText": "erro desconhecido", + "exitGameText": "Sair do ${APP_NAME}?", + "exportSuccessText": "'${NAME}' foi exportado.", + "externalStorageText": "Armazenamento externo", + "failText": "Falhou", + "fatalErrorText": "Ops; algo está faltando ou está corrompido.\nPor favor, tente reinstalar BombSquad ou\nentre em contato ${EMAIL} para ajuda.", + "fileSelectorWindow": { + "titleFileFolderText": "Selecione um arquivo ou pasta", + "titleFileText": "Selecione um arquivo", + "titleFolderText": "Selecione uma pasta", + "useThisFolderButtonText": "Use esta pasta" + }, + "filterText": "Filtro", + "finalScoreText": "Pontuação final", + "finalScoresText": "Pontuações finais", + "finalTimeText": "Tempo final", + "finishingInstallText": "Terminando de instalar; aguarde...", + "fireTVRemoteWarningText": "* Para uma melhor experiência, use\njoysticks ou baixe o aplicativo\n'${REMOTE_APP_NAME}' no seu\ntelefone ou tablet.", + "firstToFinalText": "Primeiro-a-${COUNT} Final", + "firstToSeriesText": "Primeiro-a-${COUNT} Séries", + "fiveKillText": "MATOU CINCO!!!", + "flawlessWaveText": "Onda Perfeita!", + "fourKillText": "MORTE QUÁDRUPLA!!!", + "freeForAllText": "Livre-para-Todos", + "friendScoresUnavailableText": "Pontuação dos amigos indisponível.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Game ${COUNT} Líderes", + "gameListWindow": { + "cantDeleteDefaultText": "Você não pode excluir a playlist padrão!", + "cantEditDefaultText": "Você não pode editar a playlist padrão! Duplique ou crie uma nova.", + "cantShareDefaultText": "Você não pode compartilhar a playlist padrão.", + "deleteConfirmText": "Excluir ${LIST}?", + "deleteText": "Excluir\nPlaylist", + "duplicateText": "Duplicar\nPlaylist", + "editText": "Editar\nPlaylist", + "gameListText": "Lista de Games", + "newText": "Nova\nPlaylist", + "showTutorialText": "Mostrar Tutorial", + "shuffleGameOrderText": "Ordem de partida aleatória", + "titleText": "Personalizar playlists de ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Adicionar jogo" + }, + "gamepadDetectedText": "1 controle detectado.", + "gamepadsDetectedText": "${COUNT}controles detectados.", + "gamesToText": "${WINCOUNT} jogos para ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Lembre-se: qualquer dispositivo em uma sala pode ter\nmais de um jogador se você tiver outros controles.", + "aboutDescriptionText": "Use estas guias para montar uma sala.\n\nAs salas o permitem jogar com seus amigos\natravés de dispositivos diferentes.\n\nUse o botão ${PARTY} no canto superior direito\npara conversar e interagir com a sua sala.\n(em um controle, aperte ${BUTTON} quando estiver em um menu)", + "aboutText": "Sobre", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} mandou ${COUNT} cupons ${APP_NAME}", + "appInviteSendACodeText": "Envie um código", + "appInviteTitleText": "Convite para testar ${APP_NAME}", + "bluetoothAndroidSupportText": "(funciona com qualquer dispositivo Android com Bluetooth)", + "bluetoothDescriptionText": "Criar/entrar em uma sala pelo Bluetooth:", + "bluetoothHostText": "Criar pelo Bluetooth", + "bluetoothJoinText": "Entrar pelo Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "verificando...", + "copyCodeConfirmText": "Código copiado para área de transferência.", + "copyCodeText": "Copiar código", + "dedicatedServerInfoText": "Para melhores resultados, inicie um servidor dedicado. Visite bombsquadgame.com/server para saber como.", + "disconnectClientsText": "Você está prestes a desconectar o(s) ${COUNT}\njogador(es) da sua sala. Tem certeza?", + "earnTicketsForRecommendingAmountText": "Os amigos ganharão ${COUNT} bilhetes ao experimentar o jogo\n(e você ganhará ${YOU_COUNT} por cada um que o fizer)", + "earnTicketsForRecommendingText": "Compartilhe o jogo\npara bilhetes grátis...", + "emailItText": "Enviar e-mail", + "favoritesSaveText": "Salvar como favorito", + "favoritesText": "Favoritos", + "freeCloudServerAvailableMinutesText": "Próximo servidor na nuvem grátis disponível em ${MINUTES} minutos.", + "freeCloudServerAvailableNowText": "Servidor na nuvem grátis disponível!", + "freeCloudServerNotAvailableText": "Nenhum servidor na nuvem grátis disponível.", + "friendHasSentPromoCodeText": "${COUNT} bilhetes do ${APP_NAME} mandados por ${NAME}", + "friendPromoCodeAwardText": "Você ganhará ${COUNT} bilhetes toda vez que for usado.", + "friendPromoCodeExpireText": "O código expira em ${EXPIRE_HOURS} horas e só funcionará para novos jogadores.", + "friendPromoCodeInstructionsText": "Para usar, abra ${APP_NAME} e vá até \"Configurações-> Avançado-> Inserir código\".\nVeja bombsquadgame.com para os links de download para todas as plataformas disponíveis.", + "friendPromoCodeRedeemLongText": "Pode ser resgatado por ${COUNT} bilhetes gratuitos por até ${MAX_USES} pessoas.", + "friendPromoCodeRedeemShortText": "Pode ser resgatado por ${COUNT} bilhetes no jogo.", + "friendPromoCodeWhereToEnterText": "(em \"Configurações-> Avançado-> Inserir código\")", + "getFriendInviteCodeText": "Obter código de convite", + "googlePlayDescriptionText": "Convidar jogadores do Google Play para a sua sala:", + "googlePlayInviteText": "Convidar", + "googlePlayReInviteText": "Há ${COUNT} jogador(es) do Google Play na sua sala\nque serão desconectados se você iniciar um novo convite.\nInclua-os neste novo convite para adicioná-los de volta.", + "googlePlaySeeInvitesText": "Ver convites", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android/versão Google Play)", + "hostPublicPartyDescriptionText": "Criar uma sala pública", + "hostingUnavailableText": "Host indisponível", + "inDevelopmentWarningText": "Nota:\n\nJogo em rede ainda é um novo recurso em desenvolvimento.\nPor enquanto, é altamente recomendável que todos\nos jogadores estejam na mesma rede Wi-Fi.", + "internetText": "Internet", + "inviteAFriendText": "Seus amigos ainda não têm o jogo? Convide para\nexperimentar e eles ganharão ${COUNT} bilhetes grátis.", + "inviteFriendsText": "Convidar amigos", + "joinPublicPartyDescriptionText": "Entrar em uma sala pública", + "localNetworkDescriptionText": "Entrar em uma Sala Próxima (LAN, Bluetooth, etc.)", + "localNetworkText": "Rede local", + "makePartyPrivateText": "Tornar minha sala privada", + "makePartyPublicText": "Tornar minha sala pública", + "manualAddressText": "Endereço", + "manualConnectText": "Conectar", + "manualDescriptionText": "Entrar em uma sala pelo endereço:", + "manualJoinSectionText": "Entrar pelo endereço", + "manualJoinableFromInternetText": "Consegue entrar pela internet?:", + "manualJoinableNoWithAsteriskText": "NÃO*", + "manualJoinableYesText": "SIM", + "manualRouterForwardingText": "*para resolver, tente configurar seu roteador para encaminhar a porta UDP ${PORT} para o seu endereço local", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Seu endereço na internet:", + "manualYourLocalAddressText": "Seu endereço local:", + "nearbyText": "Próximo", + "noConnectionText": "", + "otherVersionsText": "(outras versões)", + "partyCodeText": "Código da Sala", + "partyInviteAcceptText": "Aceitar", + "partyInviteDeclineText": "Negar", + "partyInviteGooglePlayExtraText": "(veja a guia 'Google Play' na janela 'Montar Sala')", + "partyInviteIgnoreText": "Ignorar", + "partyInviteText": "${NAME} chamou você para\nentrar na sala dele(a)!", + "partyNameText": "Nome da sala", + "partyServerRunningText": "Sua Sala pública está funcionando.", + "partySizeText": "tamanho da sala", + "partyStatusCheckingText": "verificando estado...", + "partyStatusJoinableText": "agora podem entrar na sua sala pela internet", + "partyStatusNoConnectionText": "não foi possível conectar ao servidor", + "partyStatusNotJoinableText": "não podem entrar na sua sala pela internet", + "partyStatusNotPublicText": "sua sala não é pública", + "pingText": "latência", + "portText": "Porta", + "privatePartyCloudDescriptionText": "Salas privadas funcionam em servidores da nuvem dedicados; nenhuma configuração no roteador é requirida.", + "privatePartyHostText": "Crie uma Sala Privada", + "privatePartyJoinText": "Entre em uma Sala Pública", + "privateText": "Privado", + "publicHostRouterConfigText": "Isso pode requerir uma configuração de porta no seu roteador. Para uma opção mais simples, crie uma sala privada.", + "publicText": "Público", + "requestingAPromoCodeText": "Solicitando um código...", + "sendDirectInvitesText": "Enviar convites diretos", + "shareThisCodeWithFriendsText": "Compartilhe esse código com seus amigos:", + "showMyAddressText": "Mostrar meu endereço", + "startHostingPaidText": "Crie Agora por ${COST}", + "startHostingText": "Criar", + "startStopHostingMinutesText": "Você pode iniciar ou interromper a hospedagem de graça nos próximos ${MINUTES} minutos.", + "stopHostingText": "Interromper hospedagem", + "titleText": "Montar sala", + "wifiDirectDescriptionBottomText": "Se todos os dispositivos tiverem 'Wi-Fi Direct', poderão usar para encontrar\ne conectar um com o outro. Conectados todos os dispositivos, você pode montar salas\naqui usando a guia 'Rede Local', como em uma rede Wi-Fi comum.\n\nPara melhores resultados, o anfitrião do Wi-Fi Direct deverá ser também o anfitrião do grupo do ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct pode conectar dispositivos Android sem a necessidade\nde uma rede Wi-Fi. Funciona melhor a partir da versão Android 4.2.\n\nPara usar, abra as configurações de Wi-Fi e procure por 'Wi-Fi Direct'.", + "wifiDirectOpenWiFiSettingsText": "Abrir as configurações de Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(funciona entre todas as plataformas)", + "worksWithGooglePlayDevicesText": "(funciona com dispositivos rodando o jogo na versão Google Play)", + "youHaveBeenSentAPromoCodeText": "Mandaram um código promocional do ${APP_NAME} para você:" + }, + "getCoinsWindow": { + "coinDoublerText": "Duplicador de moedas", + "coinsText": "${COUNT}Moedas", + "freeCoinsText": "Moedas grátis", + "restorePurchasesText": "Restaurar Compras", + "titleText": "Pegue moedas" + }, + "getTicketsWindow": { + "freeText": "GRÁTIS!", + "freeTicketsText": "Cupons Grátis", + "inProgressText": "Uma transação está em andamento; tente de novo em um momento.", + "purchasesRestoredText": "Compras restauradas.", + "receivedTicketsText": "Você recebeu ${COUNT} cupons!", + "restorePurchasesText": "Restaurar Compras", + "ticketDoublerText": "Duplicador de Cupons", + "ticketPack1Text": "Pacote pequeno de bilhetes", + "ticketPack2Text": "Pacote médio de bilhetes", + "ticketPack3Text": "Pacote grande de bilhetes", + "ticketPack4Text": "Pacote jumbo de bilhetes", + "ticketPack5Text": "Pacote mamute de bilhete", + "ticketPack6Text": "Pacote ultimate de bilhetes", + "ticketsFromASponsorText": "Assista a um anúncio \ne ganhe ${COUNT} bilhetes", + "ticketsText": "${COUNT} bilhetes", + "titleText": "Obter bilhetes", + "unavailableLinkAccountText": "Desculpe, as compras não estão disponíveis nesta plataforma.\nComo solução alternativa, você pode vincular esta conta para\noutra conta de outra plataforma e fazer compras lá.", + "unavailableTemporarilyText": "Indisponível no momento; tente novamente mais tarde.", + "unavailableText": "Desculpe, não está disponível.", + "versionTooOldText": "Desculpe, esta versão do jogo é muito antiga; por favor, atualize.", + "youHaveShortText": "você tem ${COUNT}", + "youHaveText": "você possui ${COUNT} bilhetes" + }, + "googleMultiplayerDiscontinuedText": "Desculpe, o serviço multijogador do Google não está mais disponível.\nEstou trabalhando em uma substituição o mais rápido possível.\nAté lá, tente outro método de conexão.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Compras pela Google Play não estão disponíveis.\nTalvez seja necessário atualizar sua loja para isso.", + "googlePlayServicesNotAvailableText": "Os serviços do Google Play não estão disponíveis. \nAlgumas funções do aplicativo talvez serão desabilitadas.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Sempre", + "autoText": "Auto", + "fullScreenCmdText": "Tela cheia (Cmd-F)", + "fullScreenCtrlText": "Tela cheia (Ctrl-F)", + "gammaText": "Gama", + "highText": "Alto", + "higherText": "Mais alto", + "lowText": "Baixo", + "mediumText": "Médio", + "neverText": "Nunca", + "resolutionText": "Resolução", + "showFPSText": "Mostrar FPS", + "texturesText": "Texturas", + "titleText": "Gráficos", + "tvBorderText": "Borda da TV", + "verticalSyncText": "Sincronização vertical", + "visualsText": "Visuais" + }, + "helpWindow": { + "bombInfoText": "- Bomba - \nMais forte que socos, mas pode \ncausar graves ferimentos em você mesmo.\nPara melhores resultados, atire no\ninimigo antes do pavio acabar.", + "bombInfoTextScale": 0.6, + "canHelpText": "${APP_NAME} pode ajudar.", + "controllersInfoText": "Você pode jogar ${APP_NAME} com amigos em uma rede, ou todos \npodem jogar no mesmo dispositivo se tiverem controles suficientes.\n${APP_NAME} suporta muitos deles; você pode até mesmo usar\ncelulares como controle com o aplicativo '${REMOTE_APP_NAME}'.\nVeja as Configurações->Controles para mais informações.", + "controllersInfoTextFantasia": "Um jogador pode usar o controle remoto como controle, mas controles para games\nsão altamente recomendados. Você também pode usar dispositivos móveis\ncomo controles usando o app gratuito 'BombSquad Remote'.\nVeja 'Controles' em 'Configurações' para mais informações.", + "controllersInfoTextMac": "Um ou dois jogadores podem usar o teclado, mas BombSquad é melhor com gamepads.\nBombSquad pode usar gamepads USB, controles de PS3, controles de Xbox 360,\nWiimotes e dispositivos iOS/Android para controlar personagens. Esperamos que você tenha\nalguns desses acessíveis. Consulte 'Controles', em 'Configurações' para mais informações.", + "controllersInfoTextOuya": "Você pode usar controles OUYA, controles PS3, controles Xbox 360,\ne muitos outros controles USB e Bluetooth com BombSquad.\nVocê também pode usar dispositivos iOS e Android como controles via app\ngratuito 'BombSquad Remote'. Veja 'Controles' em 'Configurações' para detalhes.", + "controllersInfoTextRemoteOnly": "Você pode jogar ${APP_NAME} com amigos na rede ou \ntodos podem jogar no mesmo dispositivo usando telefones como\ncontroladores através do aplicativo gratuito '${REMOTE_APP_NAME}'.", + "controllersInfoTextScaleFantasia": 0.51, + "controllersInfoTextScaleMac": 0.58, + "controllersInfoTextScaleOuya": 0.63, + "controllersText": "Controles", + "controllersTextScale": 0.67, + "controlsSubtitleText": "O seu personagem bonitinho do ${APP_NAME} tem algumas ações básicas:", + "controlsSubtitleTextScale": 0.7, + "controlsText": "Controles", + "controlsTextScale": 1.4, + "devicesInfoText": "A versão VR de ${APP_NAME} pode ser jogada em rede com\na versão comum, portanto saquem seus celulares extras, tablets,\ne computadores e mandem ver. Pode ser útil conectar uma\nversão comum do jogo à versão VR para permitir que\npessoas de fora assistam a ação.", + "devicesText": "Dispositivos", + "friendsGoodText": "São sempre boas companhias. ${APP_NAME} é mais divertido com muitos\njogadores e pode suportar até 8 ao mesmo tempo, o que nos leva a:", + "friendsGoodTextScale": 0.62, + "friendsText": "Amigos", + "friendsTextScale": 0.67, + "jumpInfoText": "- Saltar -\nSalte por cima de buracos,\npara jogar coisas mais alto e\npara expressar sua alegria.", + "jumpInfoTextScale": 0.6, + "orPunchingSomethingExtraSpace": 0, + "orPunchingSomethingText": "Ou dar um soco em algo, jogar de um penhasco e explodir em pedacinhos com uma bomba grudenta.", + "pickUpInfoText": "- Pegar -\nAgarre bandeiras, inimigos ou\nqualquer coisa não aparafusada no\nchão. Aperte novamente para jogar.", + "pickUpInfoTextScale": 0.6, + "powerupBombDescriptionText": "Permite você lançar três bombas\nseguidas ao invés de uma só.", + "powerupBombNameText": "Tribombas", + "powerupCurseDescriptionText": "É melhor você ficar longe de um desses.\n...ou será que não?", + "powerupCurseNameText": "Maldição", + "powerupHealthDescriptionText": "Restaura toda a sua energia.\nVocê jamais teria adivinhado.", + "powerupHealthNameText": "Kit médico", + "powerupIceBombsDescriptionText": "Mais fraca que a normal, mas\ndeixa seus inimigos congelados\ne bem fragilizados.", + "powerupIceBombsNameText": "Criobombas", + "powerupImpactBombsDescriptionText": "Um pouco mais fraca que a normal\nregular, mas explode ao impacto.", + "powerupImpactBombsNameText": "Impactobombas", + "powerupLandMinesDescriptionText": "Estes vêm em pacotes de 3;\nÉ útil para proteger a base ou\ndeter inimigos correndo em sua direção.", + "powerupLandMinesNameText": "Minas", + "powerupPunchDescriptionText": "Deixa seus socos poderosos, \nrápidos, melhores, fortes.", + "powerupPunchNameText": "Luvas de Boxe", + "powerupShieldDescriptionText": "Absorve um pouco de dano para\nvocê não ter passar por isso.", + "powerupShieldNameText": "Escudo de Energia", + "powerupStickyBombsDescriptionText": "Gruda em tudo que toca.\nHilaridade segue.", + "powerupStickyBombsNameText": "Bombas Grudentas", + "powerupsSubtitleText": "É claro, nenhum jogo está completo sem poderes:", + "powerupsSubtitleTextScale": 0.8, + "powerupsText": "Poderes", + "punchInfoText": "- Soco -\nQuanto mais rápidos seus punhos,\nmais danos seus socos dão, então\nsaia correndo feito um louco.", + "punchInfoTextScale": 0.6, + "runInfoText": "- Correr -\nSegure QUALQUER botão para correr. Gatilhos ou botões de ombro funcionam bem se você tiver. \nCorrer o leva a lugares mais rápido, mas dificulta na hora de virar, então fique de olho nos penhascos.", + "someDaysText": "Tem dias que você só quer bater em algo. Ou então explodir coisas.", + "titleText": "Ajuda do ${APP_NAME}", + "toGetTheMostText": "Para aproveitar ao máximo este jogo, você precisará de:", + "welcomeText": "Bem-vindo ao ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} está navegando pelos menus como se não houvesse amanhã -", + "importPlaylistCodeInstructionsText": "Use o seguinte código para importar essa playlist:", + "importPlaylistSuccessText": "Playlist '${NAME}' importada ${TYPE}", + "importText": "Importar", + "importingText": "Importando...", + "inGameClippedNameText": "No jogo será\n\"${NAME}\"", + "installDiskSpaceErrorText": "ERRO: Não pôde concluir a instalação.\nVocê deve estar com pouco espaço no seu dispositivo.\nApague algumas coisas e tente novamente.", + "internal": { + "arrowsToExitListText": "aperte ${LEFT} ou ${RIGHT} para sair da lista", + "buttonText": "botão", + "cantKickHostError": "Você não pode expulsar o anfitrião.", + "chatBlockedText": "O chat de ${NAME} está bloqueado por ${TIME} segundo(s).", + "connectedToGameText": "Conectou-se a '${NAME}'", + "connectedToPartyText": "Entrou na sala de ${NAME}!", + "connectingToPartyText": "Conectando...", + "connectionFailedHostAlreadyInPartyText": "A conexão falhou; o anfitrião está em outra sala.", + "connectionFailedPartyFullText": "Conexão falhou; a sala está cheia.", + "connectionFailedText": "A conexão falhou.", + "connectionFailedVersionMismatchText": "A conexão falhou; o anfitrião está rodando uma versão diferente do jogo.\nTenha certeza de que ambos estejam atualizados e tente novamente.", + "connectionRejectedText": "Conexão negada.", + "controllerConnectedText": "${CONTROLLER} conectado.", + "controllerDetectedText": "1 controle detectado.", + "controllerDisconnectedText": "${CONTROLLER} desconectado.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} desconectado. Por favor, tente novamente.", + "controllerForMenusOnlyText": "Este controle não pode ser usado para jogar; apenas para navegar pelo menu.", + "controllerReconnectedText": "${CONTROLLER} reconectado.", + "controllersConnectedText": "${COUNT} controles conectados.", + "controllersDetectedText": "${COUNT} controles detectados.", + "controllersDisconnectedText": "${COUNT} controles desconectados.", + "corruptFileText": "Arquivos corrompidos detectados. Tente reinstalar o jogo ou mande um e-mail para ${EMAIL}", + "errorPlayingMusicText": "Erro ao tocar música: ${MUSIC}", + "errorResettingAchievementsText": "Não foi possível reiniciar as conquistas online; por favor, tente novamente mais tarde.", + "hasMenuControlText": "${NAME} possui o controle do menu.", + "incompatibleNewerVersionHostText": "O anfitrião da sala usa uma versão diferente da sua.\nAtualize seu jogo e tente novamente.", + "incompatibleVersionHostText": "O anfitrião está rodando uma versão diferente do jogo.\nTenha certeza de que ambos estejam atualizados e tente de novo.", + "incompatibleVersionPlayerText": "${NAME} está rodando uma versão diferente do jogo.\nTenha certeza de que ambos estejam atualizados e tente novamente.", + "invalidAddressErrorText": "Erro: endereço invalido.", + "invalidNameErrorText": "Erro: nome inválido.", + "invalidPortErrorText": "Erro: porta inválida.", + "invitationSentText": "Convite enviado.", + "invitationsSentText": "${COUNT} convites enviados.", + "joinedPartyInstructionsText": "Alguém entrou na sua sala.\nAperte 'Jogar' para começar.", + "keyboardText": "Teclado", + "kickIdlePlayersKickedText": "Expulsando ${NAME} por não mostrar movimento.", + "kickIdlePlayersWarning1Text": "${NAME} será expulso em ${COUNT} segundos se continuar imóvel.", + "kickIdlePlayersWarning2Text": "(você pode desativar isto em Configurações-> Avançado)", + "leftGameText": "Saiu de '${NAME}'", + "leftPartyText": "Você saiu da sala de ${NAME}.", + "noMusicFilesInFolderText": "A pasta não contém arquivos de música.", + "playerJoinedPartyText": "${NAME} entrou na sala!", + "playerLeftPartyText": "${NAME} saiu da sala.", + "rejectingInviteAlreadyInPartyText": "Negando convite (já está em uma sala).", + "serverRestartingText": "Servidor reiniciando. Por favor, reconecte-se em um momento...", + "serverShuttingDownText": "Servidor está desligando...", + "signInErrorText": "Erro ao entrar.", + "signInNoConnectionText": "Não pôde entrar. (sem conexão à internet?)", + "teamNameText": "Time ${NAME}", + "telnetAccessDeniedText": "ERRO: o usuário não liberou acesso telnet.", + "timeOutText": "(tempo acaba em ${TIME} segundos)", + "touchScreenJoinWarningText": "Você entrou com o modo touchscreen.\nSe isso foi um erro, toque em 'Menu->Sair do jogo'.", + "touchScreenText": "Touchscreen", + "trialText": "teste", + "unableToResolveHostText": "Erro: não é possível resolver a fonte do anfitrião", + "unavailableNoConnectionText": "Isso não está disponível agora (sem conexão à internet?)", + "vrOrientationResetCardboardText": "Use para reiniciar a orientação do VR.\nPara jogar, você precisa de um controle externo.", + "vrOrientationResetText": "Orientação do VR reiniciada.", + "willTimeOutText": "(o tempo acabará se ficar imóvel)" + }, + "jumpBoldText": "SALTAR", + "jumpText": "Saltar", + "keepText": "Manter", + "keepTheseSettingsText": "Manter essas configurações?", + "keyboardChangeInstructionsText": "Pressione duas vezes o espaço para alterar os teclados.", + "keyboardNoOthersAvailableText": "Nenhum outro teclado disponível.", + "keyboardSwitchText": "Alterando teclado para \"${NAME}\".", + "kickOccurredText": "${NAME} foi expulso.", + "kickQuestionText": "Expulsar ${NAME}?", + "kickText": "Expulsar", + "kickVoteCantKickAdminsText": "O Administrador não pode ser expulso.", + "kickVoteCantKickSelfText": "Você não pode se expulsar.", + "kickVoteFailedNotEnoughVotersText": "Não há jogadores suficientes para uma votação.", + "kickVoteFailedText": "A votação para expulsão falhou.", + "kickVoteStartedText": "Uma votação para expulsar ${NAME} foi iniciada.", + "kickVoteText": "Votação para expulsar", + "kickVotingDisabledText": "A votação para expulsar está desativado.", + "kickWithChatText": "Escreva ${YES} no chat para sim e ${NO} para não.", + "killsTallyText": "${COUNT} abates", + "killsText": "Abates", + "kioskWindow": { + "easyText": "Fácil", + "epicModeText": "Modo épico", + "fullMenuText": "Menu Completo", + "hardText": "Difícil", + "mediumText": "Médio", + "singlePlayerExamplesText": "Exemplos de Um jogador / Cooperativo", + "versusExamplesText": "Exemplos de Versus" + }, + "languageSetText": "O idioma agora é \"${LANGUAGE}\".", + "lapNumberText": "Volta ${CURRENT}/${TOTAL}", + "lastGamesText": "(últimas ${COUNT} partidas)", + "leaderboardsText": "Classificação", + "league": { + "allTimeText": "Todos os Tempos", + "currentSeasonText": "Temporada atual (${NUMBER})", + "leagueFullText": "Liga ${NAME}", + "leagueRankText": "Classificação da liga", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "A temporada acabou ${NUMBER} dia(s) atrás.", + "seasonEndsDaysText": "A temporada acaba em ${NUMBER} dia(s).", + "seasonEndsHoursText": "A temporada acaba em ${NUMBER} hora(s).", + "seasonEndsMinutesText": "Temporada acaba em ${NUMBER} minuto(s).", + "seasonText": "Temporada ${NUMBER}", + "tournamentLeagueText": "Você deve alcançar a liga ${NAME} para entrar neste torneio.", + "trophyCountsResetText": "A contagem de troféus reiniciará na próxima temporada." + }, + "levelBestScoresText": "Melhores pontuações no ${LEVEL}", + "levelBestTimesText": "Melhores tempos no ${LEVEL}", + "levelFastestTimesText": "Melhores tempos em ${LEVEL}", + "levelHighestScoresText": "Melhores pontuações em ${LEVEL}", + "levelIsLockedText": "${LEVEL} está bloqueado.", + "levelMustBeCompletedFirstText": "${LEVEL} deve ser concluído primeiro.", + "levelText": "Nível ${NUMBER}", + "levelUnlockedText": "Nível desbloqueado!", + "livesBonusText": "Bônus de Vida", + "loadingText": "carregando", + "loadingTryAgainText": "Carregando; tente novamente daqui a pouco...", + "macControllerSubsystemBothText": "Ambos (não recomendado)", + "macControllerSubsystemClassicText": "Clássico", + "macControllerSubsystemDescriptionText": "Tente ativar isso se os controles não estiverem funcionando", + "macControllerSubsystemMFiNoteText": "Feito para iOS/Mac controle detectado ;\nvocê pode querer ativar isso em Configurações -> Controles", + "macControllerSubsystemMFiText": "Feito para iOS/Mac", + "macControllerSubsystemTitleText": "Suporte para controle", + "mainMenu": { + "creditsText": "Créditos", + "demoMenuText": "Menu de demonstração", + "endGameText": "Finalizar jogo", + "endTestText": "Finalizar Teste", + "exitGameText": "Sair do jogo", + "exitToMenuText": "Sair para o menu?", + "howToPlayText": "Como jogar", + "justPlayerText": "(Somente ${NAME})", + "leaveGameText": "Sair do jogo", + "leavePartyConfirmText": "Deseja realmente sair da sala?", + "leavePartyText": "Sair da sala", + "leaveText": "Deixar", + "quitText": "Sair", + "resumeText": "Retomar", + "settingsText": "Configurações" + }, + "makeItSoText": "Aplicar", + "mapSelectGetMoreMapsText": "Obter mais mapas...", + "mapSelectText": "Selecionar...", + "mapSelectTitleText": "${GAME} mapas", + "mapText": "Mapa", + "maxConnectionsText": "Limite de Conexões", + "maxPartySizeText": "Tamanho Máximo da Sala", + "maxPlayersText": "Limite de jogadores", + "merchText": "Produtos do BombSquad!", + "modeArcadeText": "Modo Arcade", + "modeClassicText": "Modo Clássico", + "modeDemoText": "Modo Demo", + "mostValuablePlayerText": "Jogador mais valioso", + "mostViolatedPlayerText": "Jogador Mais Violado", + "mostViolentPlayerText": "Jogador Mais Violento", + "moveText": "Mover", + "multiKillText": "MATOU ${COUNT}!!!", + "multiPlayerCountText": "${COUNT} jogadores", + "mustInviteFriendsText": "Nota: você deve convidar amigos no\npainel \"${GATHER}\" ou adicionar\ncontroles para jogar no multijogador.", + "nameBetrayedText": "${NAME} traiu ${VICTIM}.", + "nameDiedText": "${NAME} morreu.", + "nameKilledText": "${NAME} matou ${VICTIM}.", + "nameNotEmptyText": "Nome não pode estar vazio!", + "nameScoresText": "${NAME} fez um ponto!", + "nameSuicideKidFriendlyText": "${NAME} morreu acidentalmente.", + "nameSuicideText": "${NAME} cometeu suicídio.", + "nameText": "Nome", + "nativeText": "Nativo", + "newPersonalBestText": "Novo recorde pessoal!", + "newTestBuildAvailableText": "Uma nova versão de teste está disponível! (${VERSION} teste ${BUILD}).\nAdquira em ${ADDRESS}", + "newText": "Novo", + "newVersionAvailableText": "Uma nova versão de ${APP_NAME} está disponível! (${VERSION})", + "nextAchievementsText": "Próximas conquistas:", + "nextLevelText": "Próximo nível", + "noAchievementsRemainingText": "- nenhum", + "noContinuesText": "(sem continuar)", + "noExternalStorageErrorText": "Armazenamento externo não encontrado", + "noGameCircleText": "Erro: não conectado no GameCircle", + "noJoinCoopMidwayText": "Jogos cooperativos não podem ser afiliados no meio do caminho.", + "noProfilesErrorText": "Você não tem perfis de jogadores, então você está preso com '${NAME}'.\nVá para Configurações->Perfis de Jogador para criar um perfil.", + "noScoresYetText": "Ainda sem pontuação.", + "noThanksText": "Não, obrigado", + "noTournamentsInTestBuildText": "Atenção: As pontuações dos torneios desta compilação de teste serão ignoradas.", + "noValidMapsErrorText": "Nenhum mapa válido encontrado para este tipo de jogo.", + "notEnoughPlayersRemainingText": "Não há jogadores suficientes sobrando; saia e comece um novo jogo.", + "notEnoughPlayersText": "Você precisa de pelo menos ${COUNT} jogadores para começar o jogo!", + "notNowText": "Agora não", + "notSignedInErrorText": "Você deve iniciar sessão primeiro.", + "notSignedInGooglePlayErrorText": "Você deve iniciar sessão no Google Play primeiro.", + "notSignedInText": "sem sessão iniciada", + "notUsingAccountText": "Aviso: Ignorando a conta ${SERVICE}.\nVá em 'Conta -> Entrar com ${SERVICE}' se quiser usá-la.", + "nothingIsSelectedErrorText": "Nada foi selecionado!", + "numberText": "#${NUMBER}", + "offText": "Desligar", + "okText": "OK", + "onText": "Ligar", + "oneMomentText": "Um Momento...", + "onslaughtRespawnText": "${PLAYER} vai renascer na onda ${WAVE}", + "orText": "${A} ou ${B}", + "otherText": "Other...", + "outOfText": "(#${RANK} de ${ALL})", + "ownFlagAtYourBaseWarning": "Sua própria bandeira deve estar\nem sua base para fazer um ponto!", + "packageModsEnabledErrorText": "Não pode jogar em rede enquanto local-package-mods estiverem ativados (veja Configurações > Avançado)", + "partyWindow": { + "chatMessageText": "Mensagem do chat", + "emptyText": "Sua sala está vazia", + "hostText": "(anfitrião)", + "sendText": "Enviar", + "titleText": "Sua sala" + }, + "pausedByHostText": "(pausado pelo anfitrião)", + "perfectWaveText": "Onda Perfeita!", + "pickUpBoldText": "PEGAR", + "pickUpText": "Pegar", + "playModes": { + "coopText": "Cooperativo", + "freeForAllText": "Todos contra todos", + "multiTeamText": "Equipes múltiplas", + "singlePlayerCoopText": "Um jogador / Cooperativo", + "teamsText": "Equipes" + }, + "playText": "Jogar", + "playWindow": { + "coopText": "Cooperativo", + "freeForAllText": "Livre-para-Todos", + "oneToFourPlayersText": "1-4 jogadores", + "teamsText": "Times", + "titleText": "Jogar", + "twoToEightPlayersText": "2-8 jogadores" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} entrará no começo da próxima rodada.", + "playerInfoText": "Info. do jogador", + "playerLeftText": "${PLAYER} saiu da partida.", + "playerLimitReachedText": "Limite de ${COUNT} jogadores atingido; entrada não permitida.", + "playerLimitReachedUnlockProText": "Atualize para \"${PRO}\" na loja para jogar com mais de ${COUNT} jogadores.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Você não pode excluir o seu perfil.", + "deleteButtonText": "Excluir\nPerfil", + "deleteConfirmText": "Excluir '${PROFILE}'?", + "editButtonText": "Editar\nPerfil", + "explanationText": "(personalize nomes e aparências do jogador para esta conta)", + "newButtonText": "Novo\nPerfil", + "titleText": "Perfis de jogadores" + }, + "playerText": "Jogador", + "playlistNoValidGamesErrorText": "Esta playlist não contém nenhum jogo desbloqueado válido.", + "playlistNotFoundText": "playlist não encontrada", + "playlistText": "Playlist", + "playlistsText": "Playlists", + "pleaseRateText": "Se você está curtindo ${APP_NAME}, por favor, dê um tempinho\npara avaliar e comentar. Isso nos dá uma opinião útil\ne ajuda no desenvolvimento do jogo.\n\nobrigado!\n-eric", + "pleaseWaitText": "Por favor, aguarde...", + "pluginClassLoadErrorText": "Erro ao carregar a classe de um plugin '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Erro ao inicializar plugin '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Configurações de plugins", + "pluginsAutoEnableNewText": "Ativar automaticamente novos plug-ins", + "pluginsDetectedText": "Novo(s) plugin(s) detetados. Reinicie o jogo para ativá-los ou configure-os nas configurações.", + "pluginsDisableAllText": "Desativar todos os Plugins!", + "pluginsEnableAllText": "Habilitar todos os plug-ins!", + "pluginsRemovedText": "${NUM} plugin(s) não foram encontrados.", + "pluginsText": "Plugins", + "practiceText": "Praticar", + "pressAnyButtonPlayAgainText": "Aperte qualquer botão para jogar novamente...", + "pressAnyButtonText": "Aperte qualquer botão para continuar...", + "pressAnyButtonToJoinText": "aperte qualquer botão para entrar...", + "pressAnyKeyButtonPlayAgainText": "Aperte qualquer tecla/botão para jogar novamente...", + "pressAnyKeyButtonText": "Aperte qualquer tecla/botão para continuar...", + "pressAnyKeyText": "Aperte qualquer tecla...", + "pressJumpToFlyText": "** Aperte saltar repetidamente para voar **", + "pressPunchToJoinText": "aperte SOCO para entrar...", + "pressToOverrideCharacterText": "aperte ${BUTTONS} para substituir o seu personagem", + "pressToSelectProfileText": "aperte ${BUTTONS} para selecionar um jogador", + "pressToSelectTeamText": "aperte ${BUTTONS} para selecionar uma equipe", + "profileInfoText": "Crie perfis para você e seus amigos\npara personalizar seus nomes, personagens e cores.", + "promoCodeWindow": { + "codeText": "Código", + "codeTextDescription": "Código Promocional", + "enterText": "Entrar" + }, + "promoSubmitErrorText": "Erro ao enviar código; Verifique a sua conexão com a internet!", + "ps3ControllersWindow": { + "macInstructionsText": "Desligue a energia na parte traseira do seu PS3, verifique se\no Bluetooth do seu Mac está ativado, em seguida conecte o seu controle\nno seu Mac através de um cabo USB para emparelhar os dois. A partir daí, você\npode usar o botão home do controle para conectá-lo ao seu Mac\nseja por fio (USB) ou sem fio (Bluetooth).\n\nEm alguns Macs, uma senha pode ser solicitada ao emparelhar.\nSe isso acontecer, consulte o seguinte tutorial ou o Google para obter ajuda.\n\n\n\n\nOs controles de PS3 conectados sem fio devem aparecer na lista de\ndispositivos em Preferências do Sistema > Bluetooth. Você pode precisar remover\nda lista quando você quiser usar com o seu PS3 novamente.\n\nTambém certifique-se de desconectá-los do Bluetooth quando não estiver\nusando ou a bateria ficará acabando.\n\nBluetooth deve suportar até sete dispositivos conectados,\nembora a sua capacidade possa variar.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "Para usar um controle de PS3 com seu OUYA, basta conectá-lo com um cabo USB\numa vez para emparelhá-lo. Fazer isso pode desconectar seus outros controles, por\nisso você deve, em seguida, reiniciar seu OUYA e desconectar o cabo USB.\n\nA partir de então você deve ser capaz de usar o botão HOME do controle para\nconectá-lo sem fio. Quando você terminar de jogar, pressione o botão HOME\npor 10 segundos para desligar o controle; caso contrário, pode permanecer ligado\ne desperdiçar bateria.", + "ouyaInstructionsTextScale": 0.74, + "pairingTutorialText": "vídeo tutorial do emparelhamento", + "titleText": "Usando Controles de PS3 com ${APP_NAME}:" + }, + "publicBetaText": "BETA PÚBLICO", + "punchBoldText": "SOCAR", + "punchText": "Socar", + "purchaseForText": "Compre por ${PRICE}", + "purchaseGameText": "Comprar jogo", + "purchasingText": "Comprando...", + "quitGameText": "Sair do ${APP_NAME}?", + "quittingIn5SecondsText": "Saindo em 5 segundos...", + "randomPlayerNamesText": "João,Maria,Anderson,Lucas,Roberto,César,Felipe,Pedro,Zézinho,Jaílson,Hélvio,Plínio,Clara,Lorena,Beatriz,Wandernilson,Marcos,Michele,Taís,Florentina,Tadeu,Teodoro,Gabriel,Joelma,Chimbinha,Lula,Dilma,Leonardo,Irene,Samanta,Gioconda,Guilhermina,Guilherme,Frederico,Bartolomeu,Dionísio,Diógenes,Haroldo,Ronaldinho,Ricardo,Selma,Bruna,Vanderlei,Danilo,Celso,Vitória,Denise,Samuel,Daniel,Gigi,Manuel,Wiz,Gretchen,Creusa,Chico,Leôncio,Leônidas,Washington,Cleusa,José,Joane,Severino,Casé,Carlos,Davi,Bianca,Clautila,Dafne,Jorge,Sandra,Armando,Basílio,Rochele,Camila,Débora,Rafael,Jonatan,Clodomiro,Clodovil,Vera,Simão,Raíssa,Toni,Tânia,Regina,Bela,Max,Maximiliano,Claudinei,Cláudio,Luciana,Anália,Aparecida,Marcelo,Flávio,Emílio,Tiago,Hebe,Ana,Beth,Gugu,Vítor,Nílton,Maurício,Marciano,Belquior,Clemente,Rosa,Rose,Rosemar,Gabriela,Sérgio,Antônio,Ben,Ivan,jamim,Abreu,Luís,Elton,Fabiana,Waldir,Wilson,Tainá,Tainara,Xuxa,Sacha,Teotônio,Téo,Valdirene,Laurindo,Priscila,Joaquim,Estevão,Gilmar,Erick,Gilson,Romário,Dunga,Ludmila,Luciano,Gilvan,Tamara,Carla,Zezé,Fernando,Fernanda,Adegesto,Acheropita,Anatalino,Lino,Araci,Marluci,Eusébio,Darcília,Dignatario,Ernesto,Cássio,Conrado,Fábio,Heitor,Ivan,Murilo,Andressa,Mateus,Otávio,Helena,Laís,Lavínia,Leila,Letícia,Nair,Henrique,Lara,Diogo,Diego,Geniclécio,Serafim,Lisa,Inri,Eusébio,Gerônimo,Bernardo,Bernadete,Henriete,Eliete,Fudêncio,Peruíbe,Tomás,Tomashedisso,Giovana,Prieto,Gabriely,Suélen,Jamily,Jamil,Geraldo,Nazareth,Forníco,Ícaro,Breno,Bruno,Cilmara,Nilza,Caio,Borges,Cleimara,Janeclécio,Iram,Tico,Teco,Genilson,Marlos,William,Nando,Nanda,Isabel,Jamal,Elias,Félix,Caroline,Carolina,Vilma,Rafaely,Tonho,Túnica,Miguel,Jones,Juan,Anastácio,Francisco,Xavier", + "randomText": "Aleatório", + "rankText": "Classificação", + "ratingText": "Avaliação", + "reachWave2Text": "Chegue a onda 2 para pontuar.", + "readyText": "pronto", + "recentText": "Recente", + "remainingInTrialText": "permanecendo em teste", + "remoteAppInfoShortText": "${APP_NAME} é mais divertido quando é jogado com família e amigos.\nConecte um ou mais controles de hardware ou instale o aplicativo \n${REMOTE_APP_NAME} em telefones ou tablets para usá-los \ncomo controles.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Posição do botão", + "button_size": "Tamanho do botão", + "cant_resolve_host": "Não foi possível localizar o anfitrião.", + "capturing": "Aguardando...", + "connected": "Conectado.", + "description": "Use seu telefone ou tablet como controle com BombSquad.\nAté 8 dispositivos podem se conectar de uma vez para uma loucura épica de multijogador local em uma TV ou tablet.", + "disconnected": "Desconectado pelo servidor.", + "dpad_fixed": "fixo", + "dpad_floating": "Móvel", + "dpad_position": "Posição do direcional", + "dpad_size": "Tamanho do direcional", + "dpad_type": "Tipo de direcional", + "enter_an_address": "Insira um endereço", + "game_full": "A partida está cheia ou não aceita conexões.", + "game_shut_down": "A partida foi fechada.", + "hardware_buttons": "Botões físicos", + "join_by_address": "Entrar por endereço...", + "lag": "Lag: ${SECONDS} segundos", + "reset": "Restaurar padrão", + "run1": "Correr 1", + "run2": "Correr 2", + "searching": "Procurando partidas...", + "searching_caption": "Clique em uma partida para entrar.\nVeja se está na mesma rede Wi-Fi do jogo.", + "start": "Iniciar", + "version_mismatch": "Versão incompatível.\nCertifique-se que o BombSquad e o BombSquad Remote\nestão atualizados e tente novamente." + }, + "removeInGameAdsText": "Desbloqueie \"${PRO}\" na loja para remover anúncios dentro do jogo.", + "renameText": "Renomear", + "replayEndText": "Terminar replay", + "replayNameDefaultText": "Replay do último jogo", + "replayReadErrorText": "Erro ao ler arquivo de replay.", + "replayRenameWarningText": "Renomeie \"${REPLAY}\" após uma partida caso queira salvá-lo; caso contrário será sobrescrito.", + "replayVersionErrorText": "Desculpe, este replay foi feito em uma versão\ndiferente do jogo e não pode ser usado.", + "replayWatchText": "Ver replay", + "replayWriteErrorText": "Erro ao gravar arquivo de replay.", + "replaysText": "Replays", + "reportPlayerExplanationText": "Use este e-mail para denunciar trapaças, linguagem inapropriada, ou outro comportamento ruim.\nPor favor, descreva abaixo:", + "reportThisPlayerCheatingText": "Trapaça", + "reportThisPlayerLanguageText": "Linguagem inapropriada", + "reportThisPlayerReasonText": "O que gostaria de denunciar?", + "reportThisPlayerText": "Denunciar este jogador", + "requestingText": "Solicitando...", + "restartText": "Reiniciar", + "retryText": "Tentar novamente", + "revertText": "Reverter", + "runText": "Correr", + "saveText": "Salvar", + "scanScriptsErrorText": "Erro ao ler scripts; verifica o Log para mais informações", + "scoreChallengesText": "Desafios de Pontuação", + "scoreListUnavailableText": "Lista de pontuação indisponível.", + "scoreText": "Pontuação", + "scoreUnits": { + "millisecondsText": "Milisegundos", + "pointsText": "Pontos", + "secondsText": "Segundos" + }, + "scoreWasText": "(foi ${COUNT})", + "selectText": "Selecionar", + "seriesWinLine1PlayerText": "VENCEU A", + "seriesWinLine1Scale": 0.65, + "seriesWinLine1TeamText": "VENCEU A", + "seriesWinLine1Text": "VENCEU A", + "seriesWinLine2Scale": 1.0, + "seriesWinLine2Text": "SÉRIE!", + "settingsWindow": { + "accountText": "Conta", + "advancedText": "Avançado", + "audioText": "Áudio", + "controllersText": "Controles", + "enterPromoCodeText": "Digite o Código Promocional", + "graphicsText": "Gráficos", + "kickIdlePlayersText": "Chutar Jogadores Ociosos", + "playerProfilesMovedText": "Nota: os perfis de jogador foram movidos à janela de Conta no menu principal.", + "playerProfilesText": "Perfis de Jogador", + "showPlayerNamesText": "Mostrar Nomes dos Jogadores", + "titleText": "Configurações" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(um teclado simples para edição de texto)", + "alwaysUseInternalKeyboardText": "Sempre usar o teclado interno", + "benchmarksText": "Testes de desempenho", + "disableCameraGyroscopeMotionText": "Desativar o movimento do giroscópio da câmera", + "disableCameraShakeText": "Desabilitar o shake da câmera", + "disableThisNotice": "(você pode desativar este aviso em configurações avançadas)", + "enablePackageModsDescriptionText": "(ativa habilidades de modificação do jogo mas desabilita jogos em LAN)", + "enablePackageModsText": "Ativar modificações locais do jogo", + "enterPromoCodeText": "Inserir código", + "forTestingText": "Nota: esses valores são somente para teste e serão perdidos assim que o aplicativo for fechado.", + "helpTranslateText": "As traduções do ${APP_NAME} são sustentadas pelo\nesforço público. Se você gostaria de ajudar ou corrigir\numa tradução, siga o link a seguir. Agradeço desde já!", + "kickIdlePlayersText": "Expulsar jogadores ausentes", + "kidFriendlyModeText": "Modo para crianças (violência reduzida, etc)", + "languageText": "Idioma", + "moddingGuideText": "Guia de modificação", + "mustRestartText": "Você deve reiniciar o jogo para a modificação ter efeito.", + "netTestingText": "Teste de conexão", + "resetText": "Redefinir", + "showBombTrajectoriesText": "Mostrar trajetórias da bomba", + "showInGamePingText": "Mostrar latência no jogo", + "showPlayerNamesText": "Mostrar nomes dos jogadores", + "showUserModsText": "Mostrar Pasta de Modificações", + "titleText": "Avançado", + "translationEditorButtonText": "Editor de tradução do ${APP_NAME}", + "translationFetchErrorText": "estado da tradução indisponível", + "translationFetchingStatusText": "verificando estado da tradução...", + "translationInformMe": "Informe quando meu idioma precisar de atualizações", + "translationNoUpdateNeededText": "o idioma atual está atualizado; woohoo!", + "translationUpdateNeededText": "** o idioma atual precisa de atualizações!! **", + "vrTestingText": "Teste de RV" + }, + "shareText": "Compartilhar", + "sharingText": "Compartilhando...", + "showText": "Mostrar", + "signInForPromoCodeText": "Você deve iniciar uma sessão em uma conta para que os códigos promocionais se efetuem.", + "signInWithGameCenterText": "Para usar uma conta Game Center,\ninicie a sessão com o aplicativo Game Center.", + "singleGamePlaylistNameText": "Somente ${GAME}", + "singlePlayerCountText": "1 jogador", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Seleção do personagem", + "Chosen One": "O Escolhido", + "Epic": "Partidas no modo épico", + "Epic Race": "Corrida épica", + "FlagCatcher": "Capture a bandeira", + "Flying": "Pensamentos felizes", + "Football": "Futebol americano", + "ForwardMarch": "Assalto", + "GrandRomp": "Conquista", + "Hockey": "Hóquei", + "Keep Away": "Fique longe", + "Marching": "Runaround", + "Menu": "Menu principal", + "Onslaught": "Embate", + "Race": "Corrida", + "Scary": "Rei da colina", + "Scores": "Tela de pontuação", + "Survival": "Eliminatória", + "ToTheDeath": "Mata-mata", + "Victory": "Tela de pontuação final" + }, + "spaceKeyText": "espaço", + "statsText": "Estatísticas", + "storagePermissionAccessText": "É necessário acesso ao armazenamento", + "store": { + "alreadyOwnText": "Você já possui ${NAME}!", + "bombSquadProDescriptionText": "• Duplica os tickets ganhos em desafios\n• Remove anúncios no jogo\n• Adiciona ${COUNT} tickets bônus\n• +${PERCENT}% na pontuação da liga de bônus\n• Desbloqueia níveis coop '${INF_ONSLAUGHT}'\n e '${INF_RUNAROUND}'", + "bombSquadProFeaturesText": "Recursos:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Remove anúncios no jogo e nas telas\n• Desbloqueia mais configurações do jogo\n• Também inclui:", + "buyText": "Comprar", + "charactersText": "Personagens", + "comingSoonText": "Em breve...", + "extrasText": "Extras", + "freeBombSquadProText": "BombSquad agora é gratuito, mas já que você já tinha comprado ele\nvocê está recebendo BombSquad Pro e ${COUNT} tickets\ncomo um obrigado.\nDivirta-se com os novos recursos, e obrigado pelo suporte.\n-Eric", + "gameUpgradesText": "Upgrades de Jogo", + "getCoinsText": "Pegue moedas", + "holidaySpecialText": "Especial de feriado", + "howToSwitchCharactersText": "(vá para \"${SETTINGS} -> ${PLAYER_PROFILES}\" para atribuir e personalizar personagens)", + "howToUseIconsText": "(crie perfis globais - na janela de conta - para usá-los)", + "howToUseMapsText": "(use estes mapas em suas próprias playlist de equipes/todos contra todos)", + "iconsText": "Ícones", + "loadErrorText": "Não foi possível carregar a página.\nVerifique a sua conexão com a internet.", + "loadingText": "carregando", + "mapsText": "Mapas", + "miniGamesText": "Minijogos", + "oneTimeOnlyText": "(somente uma vez)", + "purchaseAlreadyInProgressText": "Uma compra deste item já está em progresso.", + "purchaseConfirmText": "Comprar ${ITEM}?", + "purchaseNotValidError": "A compra não é valida.\nEntre em contato com ${EMAIL} se isso foi um erro.", + "purchaseText": "Comprar", + "saleBundleText": "Venda de pacotes!", + "saleExclaimText": "Promoção!", + "salePercentText": "(${PERCENT}% de desconto)", + "saleText": "PROMOÇÃO", + "searchText": "Buscar", + "teamsFreeForAllGamesText": "Jogos em equipes / Todos contra todos", + "totalWorthText": "*** Apenas ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Atualizar?", + "winterSpecialText": "Especial de Inverno", + "youOwnThisText": "- você tem isso -" + }, + "storeDescriptionText": "Loucura total com até 8 jogadores!\n\nExploda seus amigos (ou o computador) em um torneio de minijogos desafiadores como Capture a bandeira, Hóquei bombástico e Mata-mata em câmera lenta épica!\n\nControles normais e controles externos possibilitam jogar com até 8 pessoas no mesmo aparelho; você também pode usar outros aparelhos como controles externos usando o aplicativo grátis ‘BombSquad Remote’!\n\nCuidado com as bombas!\n\nDê uma olhada em www.froemling.net/bombsquad para ficar ligado nas novidades.", + "storeDescriptions": { + "blowUpYourFriendsText": "Exploda seus amigos.", + "competeInMiniGamesText": "Compita em minijogos que vão de corridas a voos.", + "customize2Text": "Personalize personagens, minijogos e até mesmo a trilha sonora.", + "customizeText": "Personalize personagens e crie sua própria playlist de minijogos.", + "sportsMoreFunText": "Esportes são mais divertidos com explosivos.", + "teamUpAgainstComputerText": "Una-se a outros contra o computador." + }, + "storeText": "Loja", + "submitText": "Valor", + "submittingPromoCodeText": "Enviando código promocional...", + "teamNamesColorText": "Nome/cores das equipes...", + "teamsText": "Times", + "telnetAccessGrantedText": "Acesso ao Telnet ativado.", + "telnetAccessText": "Acesso ao Telnet detectado; permitir?", + "testBuildErrorText": "Esta versão de teste não é mais compatível; por favor, confira uma nova versão.", + "testBuildText": "Versão de teste", + "testBuildValidateErrorText": "Não foi possível validar esta versão. (sem conexão com a internet?)", + "testBuildValidatedText": "Versão de teste validada; divirta-se!", + "thankYouText": "Obrigado pelo seu apoio! Aproveite o jogo!!", + "threeKillText": "MATOU TRÊS!!", + "timeBonusText": "Bônus de tempo", + "timeElapsedText": "Tempo Decorrido", + "timeExpiredText": "Tempo Expirado", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Dica", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Melhores amigos", + "tournamentCheckingStateText": "Verificando o estado do torneio; espere um momento...", + "tournamentEndedText": "Este torneio foi finalizado. Um novo começará em breve.", + "tournamentEntryText": "Entrada para o torneio", + "tournamentResultsRecentText": "Resultados recentes do torneio.", + "tournamentStandingsText": "Classificação do torneio", + "tournamentText": "Torneio", + "tournamentTimeExpiredText": "O tempo do torneio expirou.", + "tournamentsDisabledWorkspaceText": "Os torneios são desabilitados quando os espaços de trabalho estão ativos.\nPara reativar os torneios, desative seu espaço de trabalho e reinicie.", + "tournamentsText": "Torneios", + "translations": { + "characterNames": { + "Agent Johnson": "Agente Johnson", + "B-9000": "B-9000", + "Bernard": "Bernardo", + "Bones": "Bones", + "Butch": "Butch", + "Easter Bunny": "Coelho de Páscoa", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumblodor", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Sotavento", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Homenzinho", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Papai Noel", + "Snake Shadow": "Serpente sombria", + "Spaz": "Spaz", + "Taobao Mascot": "Mascote da Taobao", + "Todd": "Teddy", + "Todd McBurton": "Todd McBurton", + "Xara": "Zara", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Infinito\nAtaque Violento", + "Infinite\nRunaround": "Evasiva\nInfinita", + "Onslaught\nTraining": "Embate\nTreinamento", + "Pro\nFootball": "Futebol\nPro", + "Pro\nOnslaught": "Embate\nPro", + "Pro\nRunaround": "Evasiva\nPro", + "Rookie\nFootball": "Futebol\nAmador", + "Rookie\nOnslaught": "Embate\nAmador", + "The\nLast Stand": "O último\na ficar em pé", + "Uber\nFootball": "Futebol\nElite", + "Uber\nOnslaught": "Embate\nElite", + "Uber\nRunaround": "Evasiva\nElite" + }, + "coopLevelNames": { + "${GAME} Training": "Treinamento de ${GAME}", + "Infinite ${GAME}": "${GAME} Infinito", + "Infinite Onslaught": "Embate Infinito", + "Infinite Runaround": "Evasiva Infinita", + "Onslaught": "Embate Infinito", + "Onslaught Training": "Embate Treinamento", + "Pro ${GAME}": "${GAME} Pro", + "Pro Football": "Futebol americano Pro", + "Pro Onslaught": "Embate Pro", + "Pro Runaround": "Evasiva Pro", + "Rookie ${GAME}": "${GAME} Amador", + "Rookie Football": "Futebol Americano Amador", + "Rookie Onslaught": "Embate Amador", + "Runaround": "Evasiva Infinita", + "The Last Stand": "O Sobrevivente", + "Uber ${GAME}": "${GAME} Elite", + "Uber Football": "Futebol Americano Elite", + "Uber Onslaught": "Embate Elite", + "Uber Runaround": "Evasiva Elite" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Seja o escolhido por um período de tempo para vencer.\nElimine o escolhido para se tornar ele.", + "Bomb as many targets as you can.": "Bombardeie o máximo de alvos que você puder.", + "Carry the flag for ${ARG1} seconds.": "Carregue a bandeira por ${ARG1} segundos.", + "Carry the flag for a set length of time.": "Carregue a bandeira por um tempo determinado.", + "Crush ${ARG1} of your enemies.": "Esmague ${ARG1} de seus inimigos.", + "Defeat all enemies.": "Derrote todos inimigos.", + "Dodge the falling bombs.": "Esquive das bombas caindo.", + "Final glorious epic slow motion battle to the death.": "Épica gloriosa batalha final até a morte em câmera lenta.", + "Gather eggs!": "Recolha os ovos!", + "Get the flag to the enemy end zone.": "Pegue a bandeira no final da zona inimiga.", + "How fast can you defeat the ninjas?": "Quão rápido você pode derrotar os ninjas?", + "Kill a set number of enemies to win.": "Mate um determinado número de inimigos para vencer.", + "Last one standing wins.": "Último em pé vence.", + "Last remaining alive wins.": "Último sobrevivente vence.", + "Last team standing wins.": "Última equipe de pé vence.", + "Prevent enemies from reaching the exit.": "Impeça que os inimigos alcancem a saída.", + "Reach the enemy flag to score.": "Alcance a bandeira inimiga para marcar.", + "Return the enemy flag to score.": "Retorne a bandeira inimiga para marcar.", + "Run ${ARG1} laps.": "Corra ${ARG1} voltas.", + "Run ${ARG1} laps. Your entire team has to finish.": "Corra ${ARG1} voltas. Toda a sua equipe precisa terminar.", + "Run 1 lap.": "Corra 1 volta.", + "Run 1 lap. Your entire team has to finish.": "Corra 1 volta. Toda a sua equipe precisa terminar.", + "Run real fast!": "Corra muito rápido!", + "Score ${ARG1} goals.": "Marque ${ARG1} gols.", + "Score ${ARG1} touchdowns.": "Marque ${ARG1} touchdowns.", + "Score a goal": "Marque um gol", + "Score a goal.": "Marque um gol.", + "Score a touchdown.": "Marque um touchdown.", + "Score some goals.": "Marque alguns gols.", + "Secure all ${ARG1} flags.": "Proteja todas as ${ARG1} bandeiras.", + "Secure all flags on the map to win.": "Proteja todas as bandeiras no mapa para vencer.", + "Secure the flag for ${ARG1} seconds.": "Proteja a bandeira por ${ARG1} segundos.", + "Secure the flag for a set length of time.": "Proteja a bandeira por um determinado período de tempo.", + "Steal the enemy flag ${ARG1} times.": "Roube a bandeira do inimigo ${ARG1} vezes.", + "Steal the enemy flag.": "Roube a bandeira do inimigo.", + "There can be only one.": "Só pode existir um.", + "Touch the enemy flag ${ARG1} times.": "Toque a bandeira inimiga ${ARG1} vezes.", + "Touch the enemy flag.": "Toque a bandeira inimiga.", + "carry the flag for ${ARG1} seconds": "carregue a bandeira por ${ARG1} segundos", + "kill ${ARG1} enemies": "mate ${ARG1} inimigos", + "last one standing wins": "último em pé vence", + "last team standing wins": "última equipe de pé vence", + "return ${ARG1} flags": "retorne ${ARG1} bandeiras.", + "return 1 flag": "retorne 1 bandeira", + "run ${ARG1} laps": "corra ${ARG1} voltas", + "run 1 lap": "corra 1 volta", + "score ${ARG1} goals": "marque ${ARG1} gols", + "score ${ARG1} touchdowns": "marque ${ARG1} touchdowns", + "score a goal": "marque um gol", + "score a touchdown": "marque um touchdown", + "secure all ${ARG1} flags": "Proteja todas ${ARG1} bandeiras", + "secure the flag for ${ARG1} seconds": "Proteja a bandeira por ${ARG1} segundos", + "touch ${ARG1} flags": "toque ${ARG1} bandeiras", + "touch 1 flag": "toque uma bandeira" + }, + "gameNames": { + "Assault": "Assalto", + "Capture the Flag": "Capture a Bandeira", + "Chosen One": "O Escolhido", + "Conquest": "Conquista", + "Death Match": "Mata-mata", + "Easter Egg Hunt": "Caça aos ovos de Páscoa", + "Elimination": "Eliminatória", + "Football": "Futebol americano", + "Hockey": "Hóquei", + "Keep Away": "Fique longe", + "King of the Hill": "Rei da colina", + "Meteor Shower": "Chuva de meteoros", + "Ninja Fight": "Luta ninja", + "Onslaught": "Embate", + "Race": "Corrida", + "Runaround": "Evasiva", + "Target Practice": "Treino de Alvo", + "The Last Stand": "O Sobrevivente" + }, + "inputDeviceNames": { + "Keyboard": "Teclado", + "Keyboard P2": "Teclado P2" + }, + "languages": { + "Arabic": "Árabe", + "Belarussian": "Bielorrusso", + "Chinese": "Chinês Simplificado", + "ChineseTraditional": "Chinês Tradicional", + "Croatian": "Croata", + "Czech": "Tcheco", + "Danish": "Dinamarquês", + "Dutch": "Holandês", + "English": "Inglês", + "Esperanto": "Esperanto", + "Filipino": "Filipino", + "Finnish": "Finlandês", + "French": "Francês", + "German": "Alemão", + "Gibberish": "Embromation", + "Greek": "Grego", + "Hindi": "Hindu", + "Hungarian": "Húngaro", + "Indonesian": "Indonésio", + "Italian": "Italiano", + "Japanese": "Japonês", + "Korean": "Coreano", + "Malay": "Malaio", + "Persian": "Persa", + "Polish": "Polonês", + "Portuguese": "Português", + "Romanian": "Romeno", + "Russian": "Russo", + "Serbian": "Sérvio", + "Slovak": "Eslovaco", + "Spanish": "Espanhol", + "Swedish": "Sueco", + "Tamil": "tâmil", + "Thai": "Tailandês", + "Turkish": "Turco", + "Ukrainian": "Ucraniano", + "Venetian": "Veneziano", + "Vietnamese": "Vietnamita" + }, + "leagueNames": { + "Bronze": "Bronze", + "Diamond": "Diamante", + "Gold": "Ouro", + "Silver": "Prata" + }, + "mapsNames": { + "Big G": "Grande G", + "Bridgit": "Bridgit", + "Courtyard": "Pátio", + "Crag Castle": "Castelo Crag", + "Doom Shroom": "Cogumelo da Morte", + "Football Stadium": "Estádio de Futebol", + "Happy Thoughts": "Pensamentos felizes", + "Hockey Stadium": "Estádio de hóquei", + "Lake Frigid": "Lago Frígido", + "Monkey Face": "Cara de macaco", + "Rampage": "Tumulto", + "Roundabout": "Evasiva", + "Step Right Up": "Degrau acima", + "The Pad": "The Pad", + "Tip Top": "Tip Top", + "Tower D": "Torre D", + "Zigzag": "Ziguezague" + }, + "playlistNames": { + "Just Epic": "Somente épico", + "Just Sports": "Somente esportes" + }, + "promoCodeResponses": { + "invalid promo code": "código promocional inválido" + }, + "scoreNames": { + "Flags": "Bandeiras", + "Goals": "Gols", + "Score": "Placar", + "Survived": "Sobreviveu", + "Time": "Tempo", + "Time Held": "Tempo realizado" + }, + "serverResponses": { + "A code has already been used on this account.": "Um código já está sendo usado nesta conta.", + "A reward has already been given for that address.": "Uma recompensa já foi dada para este endereço.", + "Account linking successful!": "A conta foi vinculada com êxito!", + "Account unlinking successful!": "Conta desvinculada com êxito!", + "Accounts are already linked.": "As contas já estão vinculadas.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Não foi possível verificar a exibição do anúncio.\nCertifique-se de que está executando uma versão oficial e atualizada do jogo.", + "An error has occurred; (${ERROR})": "Ocorreu um erro; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Ocorreu um erro; entre em contato com a assistência. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Ocorreu um erro; por favor, entre em contato com support@froemling.net.", + "An error has occurred; please try again later.": "Aconteceu um erro; tente novamente mais tarde.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Tem certeza de que deseja vincular estas contas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nIsso não poderá ser desfeito!", + "BombSquad Pro unlocked!": "BombSquado Pro desbloqueado!", + "Can't link 2 accounts of this type.": "Não é possível vincular duas contas deste tipo.", + "Can't link 2 diamond league accounts.": "Não é possível vincular duas contas de liga diamante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Impossível vincular; ultrapassaria o máximo de ${COUNT} contas vinculadas.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Trapaça detectada; pontuação e prêmios suspensos por ${COUNT} dias.", + "Could not establish a secure connection.": "Não foi possível estabelecer uma conexão segura.", + "Daily maximum reached.": "Máximo diário atingido.", + "Entering tournament...": "Entrando no torneio...", + "Invalid code.": "Código invalido.", + "Invalid payment; purchase canceled.": "Pagamento inválido; compra cancelada.", + "Invalid promo code.": "Código promocional invalido.", + "Invalid purchase.": "Compra inválida.", + "Invalid tournament entry; score will be ignored.": "Entrada errada de treinamento; pontuação será ignorada.", + "Item unlocked!": "Item unlocked", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULAÇÃO NEGADA. ${ACCOUNT} contém\ndados significativos que TODOS SERÃO PERDIDOS.\nVocê pode vincular na ordem oposta se desejar\n(e em vez disso perca os dados desta conta)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Vincular conta ${ACCOUNT} com essa conta?\nTodo o progresso em ${ACCOUNT} será perdido.\nIsso não pode ser desfeito. Tem certeza?", + "Max number of playlists reached.": "Número máximo de playlists alcançado.", + "Max number of profiles reached.": "Número máximo de perfis alcançado.", + "Maximum friend code rewards reached.": "Máximo de recompensas de códigos de amigos atingido.", + "Message is too long.": "A mensagem é muito longa.", + "No servers are available. Please try again soon.": "Nenhum servidor está disponível. Por favor, tente novamente mais tarde.", + "Profile \"${NAME}\" upgraded successfully.": "Perfil \"${NAME}\" atualizado com sucesso.", + "Profile could not be upgraded.": "Perfil não pôde ser criado.", + "Purchase successful!": "Compra feita com êxito!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Recebeu ${COUNT} tickets por entrar.\nVolte amanhã para receber ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "A funcionalidade do servidor não é mais compatível nesta versão do jogo;\nPor favor, atualize-o para uma versão mais recente.", + "Sorry, there are no uses remaining on this code.": "Desculpe, não há mais usos remanescentes neste código.", + "Sorry, this code has already been used.": "Desculpe, este código já foi usado.", + "Sorry, this code has expired.": "Desculpe, este código já expirou.", + "Sorry, this code only works for new accounts.": "Desculpe, este código só funciona para novas contas.", + "Still searching for nearby servers; please try again soon.": "Ainda à procura por servidores próximos; tente novamente mais tarde.", + "Temporarily unavailable; please try again later.": "Não disponível; por favor, tente novamente mais tarde.", + "The tournament ended before you finished.": "O torneio acabou antes de você finalizar.", + "This account cannot be unlinked for ${NUM} days.": "Esta conta não pode ser desvinculada por ${NUM} dias.", + "This code cannot be used on the account that created it.": "Este código não pode ser usado pela conta que o criou.", + "This is currently unavailable; please try again later.": "Isso está atualmente indisponível; por favor tente mais tarde.", + "This requires version ${VERSION} or newer.": "Isso requer a versão ${VERSION} ou novo.", + "Tournaments disabled due to rooted device.": "Torneios desativados devido ao dispositivo estar rooteado.", + "Tournaments require ${VERSION} or newer": "Torneios requerem ${VERSION} ou mais recente", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Desvincular ${ACCOUNT} dessa conta?\nTodo o progresso em ${ACCOUNT} será reiniciado.\n(exceto por conquistas em alguns casos)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ATENÇÃO: denúncias sobre você estar usando hack foram feitas.\nContas que usam hack serão banidas. Por favor, jogue limpo.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Gostaria de vincular a sua conta de dispositivo com esta?\n\nA sua conta de dispositivo é ${ACCOUNT1}\nEsta conta é ${ACCOUNT2}\n\nIsso permitirá que você mantenha seu progresso atual.\nAviso: isso não pode ser desfeito!", + "You already own this!": "Você já possui isso.", + "You can join in ${COUNT} seconds.": "Você poderá entrar em ${COUNT} segundos", + "You don't have enough tickets for this!": "Você não tem bilhetes suficientes para isso!", + "You don't own that.": "Você não comprou isso.", + "You got ${COUNT} tickets!": "Você obteve ${COUNT} tickets!", + "You got a ${ITEM}!": "Você ganhou ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Você foi promovido a uma nova liga; parabéns!", + "You must update to a newer version of the app to do this.": "Você deve atualizar para uma nova versão do aplicativo para fazer isso.", + "You must update to the newest version of the game to do this.": "Você deve atualizar para a nova versão do jogo para fazer isso.", + "You must wait a few seconds before entering a new code.": "Você deve esperar alguns segundos antes de inserir um novo código.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Você teve a classificação #${RANK} no último torneio. Obrigado por jogar!", + "Your account was rejected. Are you signed in?": "Sua conta foi rejeitada. Você iniciou a sessão?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Sua copia do jogo foi modificada.\nReverta as modificações e tente novamente.", + "Your friend code was used by ${ACCOUNT}": "Seu código de amigo foi usado por ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 minuto", + "1 Second": "1 segundo", + "10 Minutes": "10 minutos", + "2 Minutes": "2 minutos", + "2 Seconds": "2 segundos", + "20 Minutes": "20 minutos", + "4 Seconds": "4 segundos", + "5 Minutes": "5 minutos", + "8 Seconds": "8 segundos", + "Allow Negative Scores": "Permite Pontuação Negativa", + "Balance Total Lives": "Saldo Total de Vidas", + "Bomb Spawning": "Bombas Surgindo", + "Chosen One Gets Gloves": "O escolhido obtém luvas", + "Chosen One Gets Shield": "O escolhido obtém escudo", + "Chosen One Time": "Hora do Escolhido", + "Enable Impact Bombs": "Ativar bombas de impacto", + "Enable Triple Bombs": "Ativar tribombas", + "Entire Team Must Finish": "A equipe inteira precisa terminar", + "Epic Mode": "Modo épico", + "Flag Idle Return Time": "Tempo de retorno da bandeira inativa", + "Flag Touch Return Time": "Tempo de retorno da bandeira", + "Hold Time": "Tempo de retenção", + "Kills to Win Per Player": "Mortes para ganhar por jogador", + "Laps": "Voltas", + "Lives Per Player": "Vidas por jogador", + "Long": "Longo", + "Longer": "Mais longo", + "Mine Spawning": "Minas surgindo", + "No Mines": "Sem minas", + "None": "Nenhum", + "Normal": "Normal", + "Pro Mode": "Modo Pro", + "Respawn Times": "Número de renascimentos", + "Score to Win": "Marque para Ganhar", + "Short": "Curto", + "Shorter": "Mais curto", + "Solo Mode": "Modo Solo", + "Target Count": "Número de Alvos", + "Time Limit": "Limite de Tempo" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} está em desvantagem porque ${PLAYER} saiu", + "Killing ${NAME} for skipping part of the track!": "Matando ${NAME} por cortar o caminho!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Aviso para ${NAME}: o turbo / spam de botão faz você sair." + }, + "teamNames": { + "Bad Guys": "Inimigos", + "Blue": "Azul", + "Good Guys": "Aliados", + "Red": "Vermelho" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Se você bater, correr, pular e girar em perfeita sincronia poderá matar\nem um único golpe e garantir o respeito eterno de seus amigos.", + "Always remember to floss.": "Lembre-se de sempre usar fio dental.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crie perfis de jogadores para você e seus amigos com\nseus nomes preferidos e aparências ao invés de usar os aleatórios.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Caixas amaldiçoadas o transformam em uma bomba-relógio.\nA única cura é agarrar rapidamente um pacote de saúde.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Apesar de suas aparências, as habilidades de todos os personagens são idênticas,\nentão basta escolher qualquer um que você mais se assemelha.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Não fique muito convencido com o escudo de energia; você ainda pode ser arremessado de um penhasco.", + "Don't run all the time. Really. You will fall off cliffs.": "Não corra o tempo todo. Sério. Você vai cair de penhascos.", + "Don't spin for too long; you'll become dizzy and fall.": "Não gire por muito tempo; você vai ficar tonto e cair!", + "Hold any button to run. (Trigger buttons work well if you have them)": "Pressione qualquer botão para correr. (Botões de gatilho funcionam bem, se os tiver)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantenha pressionado qualquer botão para correr. Você vai alcançar lugares mais\nrapidamente, mas não vai fazer curvas muito bem, por isso esteja atento para penhascos.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "As bombas de gelo não são muito poderosas, mas elas congelam\nquem for atingido, deixando-os vulneráveis ​​a estilhaçamentos.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Se alguém te levantar, soque-o e ele irá te largar.\nIsso também funciona na vida real.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Se você está sem controles, instale o aplicativo '${REMOTE_APP_NAME}'\nem seus dispositivos móveis para usá-los como controles.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Se você estiver com controles insuficientes, instale o aplicativo 'BombSquad Remote'\nno seu dispositivo iOS ou Android para usá-los como controles.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Se você tiver uma bomba grudenta presa em você, salte e gire em círculos. Você pode\nsacudir a bomba para fora ou, pelo menos, seus últimos momentos serão divertidos.", + "If you kill an enemy in one hit you get double points for it.": "Se você matar um inimigo com um golpe, você obtêm o dobro de pontos por isso.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Se você pegar uma maldição, sua única esperança de sobrevivência é\nencontrar um poder de saúde nos próximos segundos.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Se você ficar em um lugar, você está frito. Corra e se esquive para sobreviver.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Se você tem muitos jogadores entrando e saindo, ligue 'Expulsar Jogadores Ociosos Automaticamente'\nnas configurações no caso de alguém esquecer de deixar o jogo.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Se seu dispositivo ficar muito quente ou você quiser conservar bateria,\nabaixe os \"Visuais\" ou \"Resolução\" nas Configurações-> Graficos", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Se sua taxa de quadros estiver baixa, tente diminuir a resolução\nou visuais nas configurações gráficas do jogo.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Em Capture a bandeira, a sua própria bandeira deve estar em sua base para marcar. Se a outra\nequipe está prestes a marcar, roubar a sua bandeira pode ser uma boa maneira de detê-los.", + "In hockey, you'll maintain more speed if you turn gradually.": "No hóquei, você manterá mais velocidade se girar gradualmente.", + "It's easier to win with a friend or two helping.": "É mais fácil ganhar com um ou dois amigos ajudando.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Apenas salte enquanto você está arremessando para conseguir bombas até os níveis mais altos.", + "Land-mines are a good way to stop speedy enemies.": "Minas terrestres são uma boa maneira de parar inimigos rápidos.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Muitas coisas podem ser apanhadas e lançadas, incluindo outros jogadores. Jogar\nos seus inimigos de penhascos pode ser uma estratégia eficaz e emocionalmente gratificante.", + "No, you can't get up on the ledge. You have to throw bombs.": "Não, você não pode levantar-se na borda. Você tem que jogar bombas.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Jogadores podem entrar e sair no meio da maioria dos jogos,\ne você também pode ligar ou desligar controles quando quiser.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Os jogadores podem entrar e sair no meio da maioria dos jogos,\ne você também pode ligar e desligar gamepads em qualquer momento.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Poderes só tem limite de tempo no modo cooperativo.\nEm times e cada-um-por-si eles são seus até você morrer.", + "Practice using your momentum to throw bombs more accurately.": "Pratique usando a inércia para arremessar bombas com maior precisão.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Socos fazem mais danos quanto mais rápido os punhos estão se movendo,\nentão tente correr, pular e girar como um louco.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corra para frente e para trás antes de arremessar uma bomba\npara 'chicoteá-la' e jogá-la longe.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Elimine um grupo de inimigos ao\ndesencadear uma bomba perto de uma caixa de TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "A cabeça é a área mais vulnerável, portanto uma bomba grudenta\nna cuca geralmente significa fim de jogo.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Este nível nunca termina, mas uma alta pontuação aqui\nfaz você ganhar respeito eterno por todo o mundo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Força de arremesso baseia-se na direção em que você está pressionando.\nPara arremessar algo suavemente na sua frente, não pressione qualquer direção.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Cansado das músicas? Troque-as pelas suas próprias!\nVeja em Configurações-> Áudio-> Músicas", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Experimente 'cozinhar' bombas por um segundo ou dois antes de jogá-las.", + "Try tricking enemies into killing eachother or running off cliffs.": "Tente enganar inimigos para se matarem ou se jogarem do precipício.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Use o botão pegar para pegar a bandeira < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Balance para trás e para frente para fazer arremessos distantes..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Você pode 'mirar' seus socos girando para esquerda ou direita.\nIsso é útil para derrubar inimigos das beiradas ou marcar no hóquei.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Você pode avaliar quando uma bomba vai explodir baseado na\ncor das faíscas do pavio: amarelo..laranja..vermelho..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Você pode jogar as bombas mais alto ao saltar logo antes de arremessar.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Você não precisa editar seu perfil para mudar de personagem; É só pressionar\no botão de cima (pegar) quando estiver entrando numa partida.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Você se fere quando você bate sua cabeça em coisas,\nassim tente não bater sua cabeça em coisas.", + "Your punches do much more damage if you are running or spinning.": "Seus socos causam muito mais dano se você estiver correndo ou girando." + } + }, + "trialPeriodEndedText": "Seu período experimental terminou. Gostaria\nde comprar BombSquad e continuar jogando?", + "trophiesRequiredText": "Isso necessita de pelo menos ${NUMBER} troféus.", + "trophiesText": "Troféus", + "trophiesThisSeasonText": "Troféus nesta temporada", + "tutorial": { + "cpuBenchmarkText": "Rodando o tutorial numa velocidade MUITO baixa (para testar o processador)", + "phrase01Text": "Olá!", + "phrase02Text": "Bem-vindo ao ${APP_NAME}!", + "phrase03Text": "Aqui estão algumas dicas para controlar seu personagem:", + "phrase04Text": "Muitas coisas no ${APP_NAME} são baseadas na física.", + "phrase05Text": "Por exemplo, quando você soca,..", + "phrase06Text": "..o dano é baseado na velocidade de seus punhos.", + "phrase07Text": "Viu? Nós não estávamos nos movendo então mal fez cócegas no ${NAME}.", + "phrase08Text": "Agora vamos pular e girar para ganhar mais velocidade.", + "phrase09Text": "Ah, assim é melhor.", + "phrase10Text": "Correr ajuda também.", + "phrase11Text": "Mantenha QUALQUER botão pressionado para correr.", + "phrase12Text": "Para socos adicionais incríveis, tente correr e girar.", + "phrase13Text": "Ops! foi mal aí, ${NAME}.", + "phrase14Text": "Você pode pegar e jogar coisas como bandeiras.. ou ${NAME}.", + "phrase15Text": "Por último, há bombas.", + "phrase16Text": "Arremessar bombas requer prática.", + "phrase17Text": "Ai! Não foi um arremesso muito bom.", + "phrase18Text": "Movimentar-se te ajuda a arremessar mais longe.", + "phrase19Text": "Saltar ajuda você a arremessar mais alto.", + "phrase20Text": "Gire e corra e suas bombas irão ainda mais longe.", + "phrase21Text": "Calcular o tempo da explosão pode ser complicado.", + "phrase22Text": "Droga!", + "phrase23Text": "Tente deixar o pavio queimar por um ou dois segundos.", + "phrase24Text": "Eba! No tempo ideal.", + "phrase25Text": "Bem, acho que é só isso.", + "phrase26Text": "Agora vai lá e arrebenta!", + "phrase27Text": "Lembre-se do seu treinamento e você voltará vivo!", + "phrase28Text": "...bem, talvez...", + "phrase29Text": "Boa sorte!", + "randomName1Text": "Fernando", + "randomName2Text": "Henrique", + "randomName3Text": "Guilherme", + "randomName4Text": "Carlos", + "randomName5Text": "Felipe", + "skipConfirmText": "Você deseja realmente pular o tutorial? Toque ou aperte confirmar.", + "skipVoteCountText": "${COUNT}/${TOTAL} votos para pular", + "skippingText": "pulando o tutorial...", + "toSkipPressAnythingText": "(pressione qualquer coisa para pular o tutorial)" + }, + "twoKillText": "MATOU DOIS!", + "unavailableText": "indisponível", + "unconfiguredControllerDetectedText": "Controle não configurado detectado:", + "unlockThisInTheStoreText": "Isto deve ser desbloqueado na loja.", + "unlockThisProfilesText": "Para criar mais que ${NUM} perfis, você precisa:", + "unlockThisText": "Para desbloquear isso:", + "unsupportedHardwareText": "Desculpe, este hardware não é suportado por esta versão do jogo.", + "upFirstText": "Em primeiro lugar:", + "upNextText": "O próximo jogo em ${COUNT}:", + "updatingAccountText": "Atualizando sua conta...", + "upgradeText": "Melhorar", + "upgradeToPlayText": "Atualize para \"${PRO}\" na loja para jogar.", + "useDefaultText": "Usar padrão", + "usesExternalControllerText": "Este jogo usa um controle externo para entrada.", + "usingItunesText": "Usando o app de música para a trilha sonora", + "usingItunesTurnRepeatAndShuffleOnText": "Por favor, certifique-se de que o aleatório esteja ligado e que a repetição seja TODAS AS MÚSICAS no iTunes.", + "v2AccountLinkingInfoText": "Para vincular contas V2, use o botão 'Gerenciar conta'.", + "validatingBetaText": "Validando Beta...", + "validatingTestBuildText": "Validando versão de teste...", + "victoryText": "Vitória!", + "voteDelayText": "Você não pode começar outra votação por ${NUMBER} segundo(s)", + "voteInProgressText": "Uma votação já está em progresso.", + "votedAlreadyText": "Você já votou", + "votesNeededText": "${NUMBER} votos necessários", + "vsText": "vs.", + "waitingForHostText": "(esperando ${HOST} continuar)", + "waitingForLocalPlayersText": "esperando por jogadores locais...", + "waitingForPlayersText": "esperando os jogadores entrarem...", + "waitingInLineText": "Esperando na fila (o grupo está cheio)...", + "watchAVideoText": "Ver um vídeo", + "watchAnAdText": "Assistir uma propaganda.", + "watchWindow": { + "deleteConfirmText": "Excluir \"${REPLAY}\"?", + "deleteReplayButtonText": "Excluir\nReplay", + "myReplaysText": "Meus replays", + "noReplaySelectedErrorText": "Nenhum replay selecionado.", + "playbackSpeedText": "Velocidade de reprodução: ${SPEED}", + "renameReplayButtonText": "Renomear\nReplay", + "renameReplayText": "Renomear \"${REPLAY}\" para:", + "renameText": "Renomear", + "replayDeleteErrorText": "Erro ao excluir o replay.", + "replayNameText": "Nome do replay", + "replayRenameErrorAlreadyExistsText": "Um replay com este nome já existe.", + "replayRenameErrorInvalidName": "Não foi possível renomear; nome invalido.", + "replayRenameErrorText": "Erro ao renomear replay.", + "sharedReplaysText": "Replays compartilhados", + "titleText": "Assistir", + "watchReplayButtonText": "Assistir\nReplay" + }, + "waveText": "Onda", + "wellSureText": "Claro!", + "whatIsThisText": "Oque é isto?", + "wiimoteLicenseWindow": { + "licenseTextScale": 0.62, + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Procurando por Wiimotes...", + "pressText": "Aperte os botões 1 e 2 no Wiimote simultaneamente.", + "pressText2": "Em Wiimotes mais recentes com Motion Plus embutido, aperte o botão vermelho 'sync' na parte de trás em seu lugar.", + "pressText2Scale": 0.55, + "pressTextScale": 1.0 + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "copyrightTextScale": 0.6, + "listenText": "Procurar", + "macInstructionsText": "Certifique-se de que o seu Wii está desligado e o Bluetooth\nativado no Mac, então pressione 'Listen'. O Wiimote pode\nser um pouco trabalhoso, você pode ter que tentar algumas\nvezes antes de conseguir uma conexão.\n\nO Bluetooth deve gerenciar até 7 dispositivos conectados,\nembora a distância pode variar.\n\nO BombSquad suporta Wiimotes, Nunchucks\ne o Controle clássico.\nO novo Wii Remote Plus agora também funciona mas não \ncom acessórios.", + "macInstructionsTextScale": 0.7, + "thanksText": "Obrigado à equipe DarwiinRemote\nPor tornar isto possível.", + "thanksTextScale": 0.8, + "titleText": "Configuração do Wiimote" + }, + "winsPlayerText": "${NAME} venceu!", + "winsTeamText": "${NAME} venceu!", + "winsText": "${NAME} ganhou!", + "workspaceSyncErrorText": "Erro ao sincronizar ${WORKSPACE}. Veja o log para mais detalhes.", + "workspaceSyncReuseText": "Não pôde sincronizar ${WORKSPACE}. Reusando uma versão anterior sincronizada.", + "worldScoresUnavailableText": "Pontuações mundiais indisponíveis.", + "worldsBestScoresText": "Melhores pontuações do mundo", + "worldsBestTimesText": "Melhores tempos do mundo", + "xbox360ControllersWindow": { + "getDriverText": "Obter Driver", + "macInstructions2Text": "Para usar os controles sem fio, você também precisará de um receptor\nque acompanha o 'Xbox 360 Wireless Controller for Windows'.\nUm receptor permite conectar até quatro controles.\n\nImportante: receptores de terceiros não irão funcionar com esse driver;\nCertifique-se de que seu receptor exiba 'Microsoft' nele, não 'Xbox 360'.\nMicrosoft não os vende mais separadamente, portanto será preciso comprar\num kit com um controle, ou algo assim, procure no ebay.\n\nSe você achou isso útil, por favor, considere fazer uma doação no site \ndo desenvolvedor do driver.", + "macInstructionsText": "Para usar os controles do Xbox 360, você precisará instalar\no driver Mac disponível no link abaixo.\nIsso funciona com ambos os controles com e sem fios.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Para usar os controles com fio do Xbox 360 com BombSquad, basta\nligá-los na porta USB do seu dispositivo. Você pode usar um hub USB\npara conectar vários controles.\n\nPara usar os controles sem fio, você precisará de um receptor sem fio,\ndisponível como parte do pacote \"Controles sem fios do Xbox 360 para Windows\"\nou vendido separadamente. Cada receptor se conecta a uma porta USB e\npermite conectar até 4 controles sem fio.", + "ouyaInstructionsTextScale": 0.8, + "titleText": "Usando Controles Xbox 360 com o ${APP_NAME}:" + }, + "yesAllowText": "Sim, permitir!", + "yourBestScoresText": "Suas melhores pontuações", + "yourBestTimesText": "Seus melhores tempos" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/romanian.json b/dist/ba_data/data/languages/romanian.json new file mode 100644 index 0000000..0b00739 --- /dev/null +++ b/dist/ba_data/data/languages/romanian.json @@ -0,0 +1,1888 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Numele contulurilor nu pot conține emoji-uri sau alte semne speciale", + "accountProfileText": "(profil de cont)", + "accountsText": "Conturi", + "achievementProgressText": "Realizări: ${COUNT} din ${TOTAL}", + "campaignProgressText": "Progres Campanie [Greu]: ${PROGRESS}", + "changeOncePerSeason": "Acest lucru poate fi schimbat o singură dată pe sezon.", + "changeOncePerSeasonError": "Trebuie să aștepți până la următorul sezon (timp de ${NUM} (de) zile) dacă vrei să schimbi acest lucru din nou", + "customName": "Nume Personalizat", + "deviceSpecificAccountText": "Foloseşti un cont specific dispozitivului: ${NAME}", + "linkAccountsEnterCodeText": "Introdu Codul", + "linkAccountsGenerateCodeText": "Generează Codul", + "linkAccountsInfoText": "(împărtășeşte-ți progresul făcut pe platforme diferite)", + "linkAccountsInstructionsNewText": "Pentru a conecta două conturi între ele, generează un cod pe primul\nși introdu acel cod pe al doilea. Datele din cel\nde-al doilea cont vor fi apoi partajate între ambele conturi.\n(Datele de pe primul cont se vor pierde)\n\nPoți conecta până la ${COUNT} conturi.\n\nIMPORTANT: conectează-te numai la conturile pe care le deții;\nDacă te conectezi la conturile prietenilor tăi, nu vei\nputea să te joci online cu aceștia în același timp.", + "linkAccountsInstructionsText": "Pentru a conecta 2 conturi, generează un cod pe\nunul din ele şi introdu acelmcod pe celălalt.\nProgresul şi inventarul tău vor fi combinate.\nPoți conecta până la ${COUNT} conturi.\n\nAi grijă; acest lucru nu poate fi şters!", + "linkAccountsText": "Conectează Conturi", + "linkedAccountsText": "Conturi Conectate:", + "nameChangeConfirm": "Vrei să schimbi numele contului tău în ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Această acțiune îți va reseta progresul co-op\nși high-score-urile locale (dar nu și biletele).\nAcest lucru nu este reversibil. Sigur vrei să continui?", + "resetProgressConfirmText": "Această acțiune îți va reseta progresul\nco-op, realizările și high-score-urile\n(dar nu și biletele). Acest lucru nu\neste reversibil. Ești sigur(ă) că vrei să continui?", + "resetProgressText": "Resetează-ți Progresul", + "setAccountName": "Setează-ți Numele Contului", + "setAccountNameDesc": "Scrie un nume dorit de tine care vrei să se afișeze pe contul tău.\nPoți folosi și numele unui alt cont conectat de tine\nsau poți să creezi un nume unic personalizat.", + "signInInfoText": "Conectează-te cu un cont pentru a colecta bilete, a concura online,\nşi pentru a te juca cu acelaşi cont pe dispozitive diferite.", + "signInText": "Conectează-te", + "signInWithDeviceInfoText": "(un cont automat care este disponibil doar pe acest dispozitiv)", + "signInWithDeviceText": "Conectează-te cu contul dispozitivului", + "signInWithGameCircleText": "Conectează-te cu Game Circle", + "signInWithGooglePlayText": "Conectează-te cu Google Play", + "signInWithTestAccountInfoText": "(tip de cont normal; foloseşte conturile de tip 'dispozitiv' şi cele noi)", + "signInWithTestAccountText": "Conectează-te cu un cont de test", + "signInWithV2InfoText": "(un cont care funcționează pe toate platformele)", + "signInWithV2Text": "Conectează-te cu un cont Bombsquad", + "signOutText": "Deconectează-te", + "signingInText": "Se conectează...", + "signingOutText": "Se deconectează...", + "testAccountWarningCardboardText": "Atenție: Te conectezi cu un cont \"de test\". Aceste\nconturi vor fi înlocuite cu conturi Google atunci\ncând vor fi suportate în aplicații cardboard.\n\nDeocamdată vei avea să obții toate biletele în joc.\n(Însă vei primi upgrade-ul BombSquad Pro gratis)", + "testAccountWarningOculusText": "Atenție: Te conectezi cu un cont \"de test\". Aceste\nconturi vor fi înlocuite cu conturi Oculus mai încolo anul\nacesta ce vor oferi cumpărarea de bilete și alte funcționalități.\n\nDeocamdată vei avea să obții toate biletele în joc.\n(Însă vei primi upgrade-ul BombSquad Pro gratis)", + "testAccountWarningText": "Atenție: te conectezi cu un cont \"de test\". Acest cont\nva fi legat numai de acest dispozitiv și va fi resetat\nperiodic. (deci nu pierde prea mult timp colectând/\ndeblocând lucruri pe el)\n\nFolosește o versiune retail a jocului pentru a folosi\ncontul \"real\" (Game-Center, Google+ etc.). Aceasta te\nlasă să iți și salvezi progresul pe cloud și să îl\nîmparți pe mai multe dispozitive.", + "ticketsText": "Bilete: ${COUNT}", + "titleText": "Contul tău", + "unlinkAccountsInstructionsText": "Selectează un cont pentru a-l deconecta", + "unlinkAccountsText": "Deconectează Conturi", + "v2LinkInstructionsText": "Folosește acest link pentru a creea un cont sau pentru a te autentifica.", + "viaAccount": "(prin contul ${NAME})", + "youAreSignedInAsText": "Ești conectat ca și:" + }, + "achievementChallengesText": "Provocări Pentru Realizări", + "achievementText": "Realizare", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Omoară 3 inamici folosind TNT", + "descriptionComplete": "Ai omorât 3 inamici folosind TNT", + "descriptionFull": "Omoară 3 inamici folosind TNT în ${LEVEL}", + "descriptionFullComplete": "Ai omorât 3 inamici folosind TNT în ${LEVEL}", + "name": "*Bum* Face Dinamita" + }, + "Boxer": { + "description": "Câștigă fără să folosești vreo bombă", + "descriptionComplete": "Ai câștigat fără să folosești vreo bombă", + "descriptionFull": "Completează ${LEVEL} fără să folosești vreo bombă", + "descriptionFullComplete": "Ai completat ${LEVEL} fără să folosești vreo bombă", + "name": "Boxer" + }, + "Dual Wielding": { + "descriptionFull": "Conectează 2 controllere (fizice sau prin aplicație)", + "descriptionFullComplete": "Ai conectat 2 controllere (fizice sau prin aplicație)", + "name": "Înarmat dublu" + }, + "Flawless Victory": { + "description": "Câștigă fără să fii lovit", + "descriptionComplete": "Ai câștigat fără să fii lovit", + "descriptionFull": "Câștigă ${LEVEL} fără să fii lovit", + "descriptionFullComplete": "Ai câștigat ${LEVEL} fără să fii lovit", + "name": "Victorie Impecabilă" + }, + "Free Loader": { + "descriptionFull": "Începe un joc Fiecare-Pentru-El cu 2+ jucători", + "descriptionFullComplete": "Ai început un joc Fiecare-Pentru-El cu 2+ jucători", + "name": "Încărcător Liber" + }, + "Gold Miner": { + "description": "Omoară 6 inamici folosind mine", + "descriptionComplete": "Ai omorât 6 inamici folosind mine", + "descriptionFull": "Omoară 6 inamici folosind mine în ${LEVEL}", + "descriptionFullComplete": "Ai omorât 6 inamici folosind mine în ${LEVEL}", + "name": "Miner de aur" + }, + "Got the Moves": { + "description": "Câștigă fără să folosești pumni sau bombe", + "descriptionComplete": "Ai câștigat fără să folosești pumnii sau bombele", + "descriptionFull": "Câștigă ${LEVEL} fără să folosești pumni sau bombe", + "descriptionFullComplete": "Ai câștigat ${LEVEL} fără să folosești pumnii sau bombele", + "name": "Știi Mișcările" + }, + "In Control": { + "descriptionFull": "Conectează un controller (fizic sau prin aplicație)", + "descriptionFullComplete": "Ai conectat un controller. (fizic sau prin aplicație)", + "name": "În Control" + }, + "Last Stand God": { + "description": "Înscrie 1000 de puncte", + "descriptionComplete": "Ai înscris 1000 de puncte", + "descriptionFull": "Înscrie 1000 de puncte în ${LEVEL}", + "descriptionFullComplete": "Ai înscris 1000 de puncte în ${LEVEL}", + "name": "Zeul, ${LEVEL}" + }, + "Last Stand Master": { + "description": "Înscrie 250 de puncte", + "descriptionComplete": "Ai înscris 250 de puncte", + "descriptionFull": "Înscrie 250 puncte în ${LEVEL}", + "descriptionFullComplete": "Ai înscris 250 puncte în ${LEVEL}", + "name": "Maestru la ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Înscrie 500 de puncte", + "descriptionComplete": "Ai înscris 500 de puncte", + "descriptionFull": "Înscrie 500 de puncte în ${LEVEL}", + "descriptionFullComplete": "Ai înscris 500 de puncte în ${LEVEL}", + "name": "Vrăjitorul din ${LEVEL}" + }, + "Mine Games": { + "description": "Omoară 3 inamici folosind mine", + "descriptionComplete": "Ai omorât 3 inamici folosind mine", + "descriptionFull": "Omoară 3 inamici folosind mine în ${LEVEL}", + "descriptionFullComplete": "Ai omorât 3 inamici folosind mine în ${LEVEL}", + "name": "Jocurile Minelor" + }, + "Off You Go Then": { + "description": "Aruncă 3 inamici de pe hartă", + "descriptionComplete": "Ai aruncat 3 inamici de pe hartă", + "descriptionFull": "Aruncă 3 inamici de pe hartă în ${LEVEL}", + "descriptionFullComplete": "Ai aruncat 3 inamici de pe hartă în ${LEVEL}", + "name": "Jos Cu tine" + }, + "Onslaught God": { + "description": "Înscrie 5000 de puncte", + "descriptionComplete": "Ai înscris 5000 de puncte", + "descriptionFull": "Înscrie 5000 de puncte în ${LEVEL}", + "descriptionFullComplete": "Ai înscris 5000 de puncte în ${LEVEL}", + "name": "Zeul din ${LEVEL}" + }, + "Onslaught Master": { + "description": "Înscrie 500 de puncte", + "descriptionComplete": "Ai înscris 500 de puncte", + "descriptionFull": "Înscrie 500 de puncte în ${LEVEL}", + "descriptionFullComplete": "Ai înscris 500 de puncte ${LEVEL}", + "name": "Maestru la ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Ieși învingător în toate valurile", + "descriptionComplete": "Ai ieșit învingător în toate valurile", + "descriptionFull": "Ieși învingător în toate valurile din ${LEVEL}", + "descriptionFullComplete": "Ai ieșit învingător în toate valurile din ${LEVEL}", + "name": "Victorie în ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Înscrie 1000 de puncte", + "descriptionComplete": "Ai înscris 1000 de puncte", + "descriptionFull": "Înscrie 1000 de puncte în ${LEVEL}", + "descriptionFullComplete": "Ai înscris 1000 de puncte în ${LEVEL}", + "name": "Vrăjitorul din ${LEVEL}" + }, + "Precision Bombing": { + "description": "Câștigă fără să folosești powerup-uri", + "descriptionComplete": "Ai câștigat fără să folosești powerup-uri", + "descriptionFull": "Câștigă ${LEVEL} fără să folosești powerup-uri", + "descriptionFullComplete": "Ai câștigat ${LEVEL} fără să folosești powerup-uri", + "name": "Bombardament De Precizie" + }, + "Pro Boxer": { + "description": "Câștigă fără să folosești vreo bombă", + "descriptionComplete": "Ai câștigat fără să folosești vreo bombă", + "descriptionFull": "Completează ${LEVEL} fără să folosești vreo bombă", + "descriptionFullComplete": "Ai completat ${LEVEL} fără să folosești vreo bombă", + "name": "Boxeor Profesionist" + }, + "Pro Football Shutout": { + "description": "Câștigă fără să-i lași pe inamici să înscrie", + "descriptionComplete": "Ai câștigat fără să-i lași pe inamici să înscrie", + "descriptionFull": "Câștigă ${LEVEL} fără să-i lași pe inamici să înscrie", + "descriptionFullComplete": "Ai câștigat ${LEVEL} fără să-i lași pe inamici să înscrie", + "name": "Shut-out în ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Câștigă meciul", + "descriptionComplete": "Ai câștigat meciul", + "descriptionFull": "Câștigă meciul din ${LEVEL}", + "descriptionFullComplete": "Ai câștigat meciul din ${LEVEL}", + "name": "Victorie în ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Ieși învingător în toate valurile", + "descriptionComplete": "Ai ieșit învingător în toate valurile", + "descriptionFull": "Ieși învingător în toate valurile din ${LEVEL}", + "descriptionFullComplete": "Ai ieșit învingător în toate valurile din ${LEVEL}", + "name": "Victorie în ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Completează toate valurile", + "descriptionComplete": "Ai completat toate valurile", + "descriptionFull": "Completează toate valurile din ${LEVEL}", + "descriptionFullComplete": "Ai completat toate valurile din ${LEVEL}", + "name": "Victorie în ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Câștigă fără să-i lași pe tipii răi să înscrie", + "descriptionComplete": "Ai câștigat fără să-i lași pe tipii răi să înscrie", + "descriptionFull": "Câștigă ${LEVEL} fără să-i lași pe tipii răi să înscrie", + "descriptionFullComplete": "Ai câștigat ${LEVEL} fără să-i lași pe tipii răi să înscrie", + "name": "Shut-out în ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Câștigă meciul", + "descriptionComplete": "Ai câștigat meciul", + "descriptionFull": "Câștigă meciul din ${LEVEL}", + "descriptionFullComplete": "Ai câștigat meciul din ${LEVEL}", + "name": "Victorie în ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Ieși învingător în toate valurile", + "descriptionComplete": "Ai ieșit învingător în toate valurile", + "descriptionFull": "Ieși învingător în toate valurile din ${LEVEL}", + "descriptionFullComplete": "Ai ieșit învingător în toate valurile din ${LEVEL}", + "name": "Victorie în ${LEVEL}" + }, + "Runaround God": { + "description": "Înscrie 2000 de puncte", + "descriptionComplete": "Ai înscris 2000 de puncte", + "descriptionFull": "Înscrie 2000 de puncte în ${LEVEL}", + "descriptionFullComplete": "Ai înscris 2000 de puncte în ${LEVEL}", + "name": "Zeu la ${LEVEL}" + }, + "Runaround Master": { + "description": "Înscrie 500 de puncte", + "descriptionComplete": "Ai înscris 500 de puncte", + "descriptionFull": "Înscrie 500 de puncte în ${LEVEL}", + "descriptionFullComplete": "Ai înscris 500 de puncte în ${LEVEL}", + "name": "Maestru la ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Înscrie 1000 de puncte", + "descriptionComplete": "Ai înscris 1000 de puncte", + "descriptionFull": "Înscrie 1000 de puncte în ${LEVEL}", + "descriptionFullComplete": "Ai înscris 1000 de puncte în ${LEVEL}", + "name": "Vrăjitorul din ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Împărtăşeşte jocul cu un prieten", + "descriptionFullComplete": "Ai împărtăşit jocul cu un prieten", + "name": "E bine să împarți" + }, + "Stayin' Alive": { + "description": "Câştigă fără să mori", + "descriptionComplete": "Ai câştigat fără să mori", + "descriptionFull": "Câştigă ${LEVEL} fără să mori", + "descriptionFullComplete": "Ai câştigat ${LEVEL} fără să mori", + "name": "Rămănând în viață" + }, + "Super Mega Punch": { + "description": "Cauzează o daună de 100% cu o singură lovitură", + "descriptionComplete": "Ai cauzat o daună de 100% cu o singură lovitură", + "descriptionFull": "Cauzează o daună de 100% cu o singură lovitură în ${LEVEL}", + "descriptionFullComplete": "Ai cauzat o daună de 100% cu o singură lovitură în ${LEVEL}", + "name": "Super-Mega Pumn" + }, + "Super Punch": { + "description": "Cauzează o daună de 50% cu o singură lovitură", + "descriptionComplete": "Ai cauzat o daună de 50% cu o singură lovitură", + "descriptionFull": "Cauzează o daună de 50% cu o singură lovitură în ${LEVEL}", + "descriptionFullComplete": "Ai cauzat o daună de 50% cu o singură lovitură în ${LEVEL}", + "name": "Super Pumn" + }, + "TNT Terror": { + "description": "Omoară 6 inamici folosind TNT", + "descriptionComplete": "Ai omorât 6 inamici folosind TNT", + "descriptionFull": "Omoară 6 inamici folosind TNT în ${LEVEL}", + "descriptionFullComplete": "Ai omorât 6 inamici folosind TNT în ${LEVEL}", + "name": "Teroarea cu TNT" + }, + "Team Player": { + "descriptionFull": "Porneşte un joc pe Echipe cu 4+ jucători", + "descriptionFullComplete": "Ai pornit un joc pe Echipe cu 4+ jucători", + "name": "Jucătorul Din Echipă" + }, + "The Great Wall": { + "description": "Opreşte fiecare inamic", + "descriptionComplete": "Ai oprit fiecare inamic", + "descriptionFull": "Opreşte fiecare inamic din ${LEVEL}", + "descriptionFullComplete": "Ai oprit fiecare inamic din ${LEVEL}", + "name": "Marele Zid" + }, + "The Wall": { + "description": "Oprește fiecare inamic", + "descriptionComplete": "Ai oprit fiecare inamic", + "descriptionFull": "Oprește fiecare inamic din ${LEVEL}", + "descriptionFullComplete": "Ai oprit fiecare inamic din ${LEVEL}", + "name": "Zidul" + }, + "Uber Football Shutout": { + "description": "Câștigă fără să-i lași pe inamici să înscrie", + "descriptionComplete": "Ai câștigat fără să-i lași pe inamici să înscrie", + "descriptionFull": "Câștigă ${LEVEL} fără să-i lași pe inamici să înscrie", + "descriptionFullComplete": "Ai câștigat ${LEVEL} fără să-i lași pe inamici să înscrie", + "name": "Shut-out în ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Câștigă meciul", + "descriptionComplete": "Ai câștigat meciul", + "descriptionFull": "Câștigă meciul din ${LEVEL}", + "descriptionFullComplete": "Ai câștigat meciul din ${LEVEL}", + "name": "Victorie în ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Învinge în toate valurile", + "descriptionComplete": "Ai învins în toate valurile", + "descriptionFull": "Învinge în toate valurile din ${LEVEL}", + "descriptionFullComplete": "Ai învins în toate valurile din ${LEVEL}", + "name": "Victorie în ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Completează toate valurile", + "descriptionComplete": "Ai completat toate valurile", + "descriptionFull": "Completează toate valurile din ${LEVEL}", + "descriptionFullComplete": "Ai completat toate valurile din ${LEVEL}", + "name": "Victorie în ${LEVEL}" + } + }, + "achievementsRemainingText": "Realizări Rămase:", + "achievementsText": "Realizări", + "achievementsUnavailableForOldSeasonsText": "Scuze, dar detaliile realizărilor din sezoanele trecute sunt indisponibile.", + "activatedText": "${THING} a fost activat(ă).", + "addGameWindow": { + "getMoreGamesText": "Ia mai multe MiniJocuri...", + "titleText": "Adaugă un joc" + }, + "allowText": "Permite", + "alreadySignedInText": "Contul tău este deja conectat de pe un alt dispozitiv;\nte rog să schimbi conturile sau să închizi jocul de pe\nalte dispozitive și să încerci din nou.", + "apiVersionErrorText": "Nu se poate încărca modulul ${NAME}; acesta țintește versiunea API ${VERSION_USED}, iar versiunea ${VERSION_REQUIRED} nu îl mai suportă.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" activează asta doar când căștile sunt conectate)", + "headRelativeVRAudioText": "Audio VR relativ capului", + "musicVolumeText": "Volumul Muzicii", + "soundVolumeText": "Volumul Sunetelor", + "soundtrackButtonText": "Soundtrack Personalizat", + "soundtrackDescriptionText": "(selectează melodiile care vrei să cânte în timpul jocului)", + "titleText": "Audio" + }, + "autoText": "Automat", + "backText": "Înapoi", + "banThisPlayerText": "Interzice Accesul Acestui Jucător", + "bestOfFinalText": "Finala Cel-Mai-Bun-Din-${COUNT}", + "bestOfSeriesText": "Seriile Cel-Mai-Bun-Din-${COUNT}:", + "bestOfUseFirstToInstead": 0, + "bestRankText": "Cea mai bună poziție a ta este: #${RANK}", + "bestRatingText": "Cea mai bună notă a ta este ${RATING}", + "bombBoldText": "BOMBĂ", + "bombText": "Bombă", + "boostText": "Crește", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} este configurat în aplicația în sine.", + "buttonText": "buton", + "canWeDebugText": "Ai vrea ca BombSquad să trimită automat bug-uri,\ncrash-uri și informații de bază programatorului jocului?\n\nAceste informații nu conțin date personale, ci doar\najută la îmbunătățirea jocului.", + "cancelText": "Anulează", + "cantConfigureDeviceText": "Scuze, dar ${DEVICE} nu este configurabil.", + "challengeEndedText": "Acest concurs s-a terminat.", + "chatMuteText": "Amuțește Chat-ul", + "chatMutedText": "Chat-ul Este Amuțit", + "chatUnMuteText": "Dezamuțește Chat-ul", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Trebuie să completezi\nacest nivel pentru a continua!", + "completionBonusText": "Bonus De Completare", + "configControllersWindow": { + "configureControllersText": "Configurează Controllere", + "configureKeyboard2Text": "Configurează Tastatura Pentru P2", + "configureKeyboardText": "Configurează Tastatura", + "configureMobileText": "Dispozitive Mobile Drept Controllere", + "configureTouchText": "Configurează Touchscreen-ul", + "ps3Text": "Controllere de PS3", + "titleText": "Controllere", + "wiimotesText": "Controllere pentru Wii", + "xbox360Text": "Controllere de Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Notă: suportul pentru controllere poate varia de la un dispozitiv la altul și de la o versiune Android la alta.", + "pressAnyButtonText": "Apasă pe orice buton de pe controllerul\npe care ai vrea să-l configurezi...", + "titleText": "Configurează Controllere" + }, + "configGamepadWindow": { + "advancedText": "Avansate", + "advancedTitleText": "Setări Avansate Pentru Controller", + "analogStickDeadZoneDescriptionText": "(Ridică această valoare dacă îți \"alunecă\" caracterul când iei mâna de pe \"stick\")", + "analogStickDeadZoneText": "Zona-Moartă a Stick-ului Analog", + "appliesToAllText": "(se aplică la toate controllerele de acest fel)", + "autoRecalibrateDescriptionText": "(activează asta dacă caracterul tău nu se mișcă la viteza maximă)", + "autoRecalibrateText": "Recalibrare Automată a Stick-ului Analog", + "axisText": "axă", + "clearText": "șterge", + "dpadText": "D-Pad", + "extraStartButtonText": "Buton De Start Secundar", + "ifNothingHappensTryAnalogText": "Dacă nu se întâmplă nimic, încearcă să folosești stick-ul analog.", + "ifNothingHappensTryDpadText": "Dacă nu se întâmplă nimic, încearcă D-Pad-ul.", + "ignoreCompletelyDescriptionText": "(fă în așa fel încât acest controller să nu afecteze jocul sau meniul)", + "ignoreCompletelyText": "Ignorare Completă", + "ignoredButton1Text": "Buton Ignorat 1", + "ignoredButton2Text": "Buton Ignorat 2", + "ignoredButton3Text": "Buton Ignorat 3", + "ignoredButton4Text": "Buton Ignorat 4", + "ignoredButtonDescriptionText": "(folosește asta pentru ignorarea butoanelor 'home' sau 'sync' în timpul jocului)", + "pressAnyAnalogTriggerText": "Apasă orice trigger analog...", + "pressAnyButtonOrDpadText": "Apasă orice buton sau D-Pad-ul", + "pressAnyButtonText": "Apasă orice buton...", + "pressLeftRightText": "Apasă stânga sau dreapta...", + "pressUpDownText": "Apasă sus sau jos...", + "runButton1Text": "Buton de Fugă 1", + "runButton2Text": "Buton de Fugă 2", + "runTrigger1Text": "Trigger de Fugă 1", + "runTrigger2Text": "Trigger de Fugă 2", + "runTriggerDescriptionText": "(trigger-urile analogice te lasă să alergi la viteze diferite)", + "secondHalfText": "Foloseşte această opțiune pentru a configura\na doua parte dintr-un dispozitiv 2-controllere-în-1 \ncare defapt se arată ca unul singur.", + "secondaryEnableText": "Permite", + "secondaryText": "Controller Secundar", + "startButtonActivatesDefaultDescriptionText": "(opreşte această funcție dacă butonul tău de start este un buton de 'meniu')", + "startButtonActivatesDefaultText": "Butonul de Start Activează Widget-ul Implicit", + "titleText": "Setup Pentru Controller", + "twoInOneSetupText": "Setup Pentru Un Controller 2-în-1", + "uiOnlyDescriptionText": "(permite-i acestui controller doar navigarea prin meniuri)", + "uiOnlyText": "Limitează la Folosirea Meniului", + "unassignedButtonsRunText": "Rularea Tuturor Butoanelor Neatribuite", + "unsetText": "", + "vrReorientButtonText": "Buton De Reorientare VR" + }, + "configKeyboardWindow": { + "configuringText": "${DEVICE} se configurează", + "keyboard2NoteText": "Notă: majoritatea tastaturilor pot înregistra doar câteva apăsări\nde-odată, deci având o altă tastatură ar merge mai bine\ndacă există un al doilea jucător.\nȚine minte faptul că tot va trebui să atribui controale diferite \ncelor doi jucători, chiar şi în cazul de mai sus." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Dimensiunea Butoanelor De Acțiuni", + "actionsText": "Acțiuni", + "buttonsText": "butoane", + "dragControlsText": "< trage de controale pentru a le repoziționa >", + "joystickText": "joystick", + "movementControlScaleText": "Dimensiunea Săgeților De Mișcare", + "movementText": "Mișcare", + "resetText": "Resetare", + "swipeControlsHiddenText": "Ascunde Săgețile", + "swipeInfoText": "Durează ceva timp până te înveți cu controalele de tip 'Glisare'\ndar o să-ți fie mult mai ușor să te joci fără să te uiți la controale.", + "swipeText": "glisare", + "titleText": "Configurează Touchscreen-ul" + }, + "configureItNowText": "Vrei să îl configurezi acum?", + "configureText": "Configurează", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Pentru cele mai bune rezultate vei avea nevoie de o rețea Wi-Fi \nfără lag. Poți să reduci lag-ul prin oprirea Wi-Fi-ului de pe alte dispozitive,\nprin jucarea lângă router, sau prin conectarea directă la \"jocul-mamă\"\ncu ajutorul Ethernet-ului.", + "explanationText": "Pentru a folosi un telefon sau o tabletă drept controller, instalează\naplicația \"${REMOTE_APP_NAME}\" pe acestea. Orice dispozitiv se poate conecta la\nun joc ${APP_NAME} prin Wi-Fi, şi este gratuită!", + "forAndroidText": "pentru Android:", + "forIOSText": "Pentru iOS:", + "getItForText": "Instalează-ți aplicația ${REMOTE_APP_NAME} pentru iOS din Apple App Store,\npentru Android din Google Play Store sau de pe Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Folosirea Dispozitivelor Mobile Drept Controllere:" + }, + "continuePurchaseText": "Continui pentru ${PRICE}?", + "continueText": "Continuă", + "controlsText": "Controale", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Asta nu se aplică clasamentelor din totdeauna.", + "activenessInfoText": "Acest multiplicator crește în zilele în\ncare joci și scade în cele în care nu joci.", + "activityText": "Activitate", + "campaignText": "Campanie", + "challengesInfoText": "Câștigă premii pentru completarea minijocurilor.\n\nPremiile şi dificultatea nivelelor cresc\nde fiecare dată când un challenge este făcut\nşi scade când unul expiră sau este abandonat.", + "challengesText": "Provocări", + "currentBestText": "Cel mai bun de până acum", + "customText": "Particularizate", + "entryFeeText": "Intrare", + "forfeitConfirmText": "Abandonezi acest challenge?", + "forfeitNotAllowedYetText": "Acest challenge nu poate fi abandonat chiar acum.", + "forfeitText": "Abandonează", + "multipliersText": "Multiplicatori", + "nextChallengeText": "Challenge-ul Următor", + "nextPlayText": "Jocul Următor", + "ofTotalTimeText": "din ${TOTAL}", + "playNowText": "Joacă Acum", + "pointsText": "Puncte", + "powerRankingFinishedSeasonUnrankedText": "(ai terminat sezonul fără rank)", + "powerRankingNotInTopText": "(nu eşti în top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pte", + "powerRankingPointsMultText": "(x ${NUMBER} pte)", + "powerRankingPointsText": "${NUMBER} pte", + "powerRankingPointsToRankedText": "(${CURRENT} din ${REMAINING} pte)", + "powerRankingText": "Rank-ul tău de putere", + "prizesText": "Premii", + "proMultInfoText": "Jucătorii cu upgrade-ul ${PRO} \nprimesc aici un bonus de ${PERCENT}% la puncte.", + "seeMoreText": "Mai multe...", + "skipWaitText": "Treci fără să mai aștepți", + "timeRemainingText": "Timp Rămas", + "toRankedText": "Pentru Rankare", + "totalText": "total", + "tournamentInfoText": "Întrece-te pentru scoruri mari\ncu alți jucători din liga ta.\n\nPremiile sunt dăruite jucătorilor cu\nscoruri din lista de top când expiră concursul.", + "welcome1Text": "Bine ai venit în ${LEAGUE}. Poți să-ți măreşti\nrankul prin adunarea medaliilor, câştigarea trofeelor\nîn concursuri şi prin rankul de 3 stele în jocuri.", + "welcome2Text": "Mai poți primi bilete şi prin alte activități de acelaşi fel.\nBiletele se pot folosi pentru a debloca charactere, hărți,\nmini-jocuri, pentru a intra în concursurii, şi multe altele.", + "yourPowerRankingText": "Rankul tău de Putere:" + }, + "copyOfText": "Copie de ${NAME}", + "copyText": "Copiază", + "createEditPlayerText": "", + "createText": "Creează", + "creditsWindow": { + "additionalAudioArtIdeasText": "Sunet Adițional, Artă, și Idei de ${NAME}", + "additionalMusicFromText": "Muzică Adițională de ${NAME}", + "allMyFamilyText": "Familiei mele și tuturor prietenilor mei care m-au ajutat să testez jocul", + "codingGraphicsAudioText": "Cod, Grafice, şi Audio de ${NAME}", + "languageTranslationsText": "Traduceri:", + "legalText": "Legal:", + "publicDomainMusicViaText": "Muzică din domeniul Public ${NAME}", + "softwareBasedOnText": "Acest software este bazat în partea de lucru a lui ${NAME}", + "songCreditText": "${TITLE} Performat de ${PERFORMER}\nCompus de ${COMPOSER}, Aranjat de ${ARRANGER}, Publicat de ${PUBLISHER},\ncurtoazie din ${SOURCE}", + "soundAndMusicText": "Sunete & Muzică:", + "soundsText": "Sunete (${SOURCE}):", + "specialThanksText": "Mulțumiri Speciale:", + "thanksEspeciallyToText": "Mulțumiri deosebite: ${NAME}", + "titleText": "Credite ${APP_NAME}", + "whoeverInventedCoffeeText": "Celui care a inventat cafeaua" + }, + "currentStandingText": "Rangul tău este #${RANK}", + "customizeText": "Particularizează...", + "deathsTallyText": "${COUNT} vieți pierdute", + "deathsText": "Vieți pierdute", + "debugText": "Debug", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Notă: Este recomandat ca tu să te duci la Setări->Grafici->Texturi și să le dai pe 'Înalte' când testezi asta.", + "runCPUBenchmarkText": "Rulează test CPU", + "runGPUBenchmarkText": "Rulează test GPU", + "runMediaReloadBenchmarkText": "Pornește Test De Reîncărcare Media", + "runStressTestText": "Pornește testul de stres", + "stressTestPlayerCountText": "Număr de Jucători", + "stressTestPlaylistDescriptionText": "Lista de Jocuri pentru Testele de Stres", + "stressTestPlaylistNameText": "Numele Listei de Jocuri", + "stressTestPlaylistTypeText": "Tipul Listei de Jocuri", + "stressTestRoundDurationText": "Durata Rundei", + "stressTestTitleText": "Test de Stres", + "titleText": "Teste de Stres şi Repere", + "totalReloadTimeText": "Timp total de reîncărcare: ${TIME} (vezi jurnalul de activități pentru detalii)" + }, + "defaultGameListNameText": "Lista de Jocuri de \"${PLAYMODE}\" Implicită", + "defaultNewGameListNameText": "Lista mea de jocuri de \"${PLAYMODE}\"", + "deleteText": "Șterge", + "demoText": "Demo", + "denyText": "Refuză", + "desktopResText": "Rezoluție Desktop", + "difficultyEasyText": "Ușor", + "difficultyHardOnlyText": "Numai pe \"Greu\"", + "difficultyHardText": "Greu", + "difficultyHardUnlockOnlyText": "Acest nivel poate fi deblocat numai pe modul \"Greu\".\nTe crezi în stare!?!?!", + "directBrowserToURLText": "Te rog să direcționezi un browser web la următorul URL:", + "disableRemoteAppConnectionsText": "Dezactivează conexiunile de pe Remote-App", + "disableXInputDescriptionText": "Permite mai mult de 4 controlere dar nu va merge chiar așa de bine.", + "disableXInputText": "Dezactivează XInput", + "doneText": "Gata", + "drawText": "Remiză", + "duplicateText": "Multiplică", + "editGameListWindow": { + "addGameText": "Adaugă\nun joc", + "cantOverwriteDefaultText": "Nu poți modifica lista de jocuri implicită!", + "cantSaveAlreadyExistsText": "O listă de jocuri cu acelaşi nume deja există!", + "cantSaveEmptyListText": "Nu poți salva o listă goală!", + "editGameText": "Editează\nJocul", + "listNameText": "Numele Listei", + "nameText": "Nume", + "removeGameText": "Şterge\nJocul", + "saveText": "Salvează Lista", + "titleText": "Editor de Liste de Jocuri." + }, + "editProfileWindow": { + "accountProfileInfoText": "Acest profil special are nume\nşi o imagine bazată pe contul tău.\n\n${ICONS}\n\nCreează profile personalizate\npentru a folosi nume sau iconițe personalizate.", + "accountProfileText": "(profilul contului)", + "availableText": "Numele \"${NAME}\" este utilizabil.", + "changesNotAffectText": "Notă: schimbările nu vor afecta caracterele care sunt deja în joc", + "characterText": "caracter", + "checkingAvailabilityText": "Se verifică dacă numele \"${NAME}\" este disponibil...", + "colorText": "culoare", + "getMoreCharactersText": "Ia mai multe Caractere...", + "getMoreIconsText": "Ia mai multe iconițe...", + "globalProfileInfoText": "Profilurile globale ale jucătorilor sunt garantate \nsa aibă nume și iconițe unice.", + "globalProfileText": "(profil global)", + "highlightText": "accent", + "iconText": "iconiță", + "localProfileInfoText": "Profilurile locale nu au iconițe şi numele lor nu sunt \ngarantate să fie speciale. Upgradează-ți profilul\npentru a-ți rezerva un nume special şi pentru a adăuga o iconiță la acesta.", + "localProfileText": "(profil local)", + "nameDescriptionText": "Numele Jucătorului", + "nameText": "Nume", + "randomText": "auto-generat", + "titleEditText": "Editează profilul", + "titleNewText": "Profil nou", + "unavailableText": "Numele \"${NAME}\" nu este disponibil; încearcă alt nume.", + "upgradeProfileInfoText": "Acest lucru îți va rezerva numele de jucător\nşi te va lăsa să introduci o iconiță pentru acesta.", + "upgradeToGlobalProfileText": "Transformă-l în Profil Global" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Nu poți şterge soundtrack-ul implicit.", + "cantEditDefaultText": "Nu poți edita soundtrack-ul implicit. Duplică-l sau creează altul nou.", + "cantOverwriteDefaultText": "Nu poți înlocui soundtrack-ul implicit", + "cantSaveAlreadyExistsText": "Un soundtrack cu acelaşi nume există deja!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Soundtrack-ul Implicit", + "deleteConfirmText": "Ştergi Soundtrack-ul:\n\n'${NAME}'?", + "deleteText": "Şterge\nSoundtrack-ul", + "duplicateText": "Duplică\nSoundtrack-ul", + "editSoundtrackText": "Editor de Soundtrack", + "editText": "Editează\nSoundtrack-ul", + "fetchingITunesText": "se preiau listele de redare din Aplicațiile Muzicale...", + "musicVolumeZeroWarning": "Atenție: volumul muzicii este setat la 0", + "nameText": "Nume", + "newSoundtrackNameText": "Soundtrack-ul Meu ${COUNT}", + "newSoundtrackText": "Soundtrack Nou:", + "newText": "Soundtrack\nNou", + "selectAPlaylistText": "Selectează o Listă de Redare", + "selectASourceText": "Sursa Muzicii", + "testText": "testează", + "titleText": "Soundtrack-uri", + "useDefaultGameMusicText": "Folosește Muzica Implicită", + "useITunesPlaylistText": "Lista de Redare a Aplicației Muzicale", + "useMusicFileText": "Fişier Audio (MP3, etc)", + "useMusicFolderText": "Dosar cu Fişiere Audio" + }, + "editText": "Editează", + "endText": "Sfârșește", + "enjoyText": "Bucură-te!", + "epicDescriptionFilterText": "${DESCRIPTION} În slow motion epic.", + "epicNameFilterText": "${NAME} Epic", + "errorAccessDeniedText": "acces respins", + "errorDeviceTimeIncorrectText": "Ceasul dispozitivului tău este dat înainte sau înapoi cu ${HOURS} ore.\nAcestu lucru ar putea cauza niște probleme.\nTe rog să verifici setările ceasului și ale fusului orar.", + "errorOutOfDiskSpaceText": "ai rămas fără memorie", + "errorSecureConnectionFailText": "Nu s-a putut stabili o conexiune sigură cloud; funcționalitatea internetului ar putea eșua.", + "errorText": "Eroare", + "errorUnknownText": "eroare necunoscută", + "exitGameText": "Ieși din ${APP_NAME}?", + "exportSuccessText": "'${NAME}' a fost exportat cu succes.", + "externalStorageText": "Memorie Externă", + "failText": "Eșec", + "fatalErrorText": "Oh nu; ceva lipseşte sau este stricat.\nTe rog încearcă să reinstalezi aplicația sau\ncontactează adresa de E-mail ${EMAIL} pentru ajutor.", + "fileSelectorWindow": { + "titleFileFolderText": "Selectează un Fișier sau un Dosar", + "titleFileText": "Selectează un fișier", + "titleFolderText": "Selectează un Dosar", + "useThisFolderButtonText": "Folosește Acest Dosar" + }, + "filterText": "Caută", + "finalScoreText": "Scor Final", + "finalScoresText": "Scoruri Finale", + "finalTimeText": "Timp Final", + "finishingInstallText": "Se termină de instalat; un moment...", + "fireTVRemoteWarningText": "* Pentru o experiență mai bună,\nfolosiți Controllere sau instalați\naplicația '${REMOTE_APP_NAME}' pe \ntelefoane sau pe tablete.", + "firstToFinalText": "Finala Primul-la-${COUNT}", + "firstToSeriesText": "Seriile Primul-la-${COUNT}", + "fiveKillText": "Penta-omor!!!", + "flawlessWaveText": "Val Perfect!", + "fourKillText": "Cvadr-omor!!!", + "friendScoresUnavailableText": "Scorurile prietenilor nu sunt disponibile.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Liderii Jocului ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "Nu poți şterge lista de jocuri implicită.", + "cantEditDefaultText": "Nu poți edita lista de jocuri normală! Duplic-o sau creează una nouă.", + "cantShareDefaultText": "Nu poti trimite mai departe lista de jocuri implicită.", + "deleteConfirmText": "Ştergi \"${LIST}\"?", + "deleteText": "Şterge\nLista de Jocuri", + "duplicateText": "Duplică\nLista de Jocuri", + "editText": "Editează\nLista de Jocuri", + "newText": "Listă de Jocuri\nNouă", + "showTutorialText": "Arată Tutorialul", + "shuffleGameOrderText": "Jocuri Aleatorii", + "titleText": "Particularizează Listele de Jocuri de tip \"${TYPE}\"" + }, + "gameSettingsWindow": { + "addGameText": "Adaugă un Joc" + }, + "gamesToText": "${WINCOUNT} jocuri la ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Ține minte: orice dispozitiv dintr-o petrecere poate avea\nmai mult de un jucător dacă sunt destule controllere.", + "aboutDescriptionText": "Folosește aceste file pentru a asambla un grup.\n\nGrupurile te lasă să joci jocuri și turnee împreună\ncu prietenii tăi, cu ajutorul mai multor dispozitive.\n\nFolosește butonul ${PARTY} din colțul din dreapta-sus pentru a\nvorbi și interacționa cu grupul.\n(dacă folosești un controller, folosește ${BUTTON} cât timp ești într-un meniu)", + "aboutText": "Ajutor", + "addressFetchErrorText": "", + "appInviteInfoText": "Invită-ți prietenii să încerce BombSquad și\nvor primii ${COUNT} bilete gratis. Tu vei primi\n${YOU_COUNT} pentru fiecare care o face.", + "appInviteMessageText": "${NAME} ți-a trimis ${COUNT} de bilete în ${APP_NAME}", + "appInviteSendACodeText": "Trimite-le Un Cod", + "appInviteTitleText": "Invitație Pentru a Încerca ${APP_NAME}", + "bluetoothAndroidSupportText": "(funcționează cu orice dispozitiv Android care suportă Bluetooth)", + "bluetoothDescriptionText": "Ține un joc/intră într-un joc folosind Bluetooth:", + "bluetoothHostText": "Ține un joc pe Bluetooth", + "bluetoothJoinText": "Intră într-un joc de pe Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "se verifică...", + "copyCodeConfirmText": "Codul a fost copiat în clipboard.", + "copyCodeText": "Copiază Codul", + "dedicatedServerInfoText": "Pentru cele mai bune rezultate, configurează un server dedicat. Consultă bombsquadgame.com/server pentru a afla cum.", + "disconnectClientsText": "Această opțiune va deconecta ${COUNT} jucător(i) din\njocul tău curent. Ești sigur?", + "earnTicketsForRecommendingAmountText": "Prietenii tăi vor primi ${COUNT} de bilete dacă vor încerca jocul \n(iar tu vei primi ${YOU_COUNT} pentru fiecare care încearcă)", + "earnTicketsForRecommendingText": "Împărtăşeşte jocul\npentru bilete gratuite...", + "emailItText": "Dă-l prin Email", + "favoritesSaveText": "Salvează ca favorit", + "favoritesText": "Favorite", + "freeCloudServerAvailableMinutesText": "Următorul server gratuit va fi disponibil în ${MINUTES} minute.", + "freeCloudServerAvailableNowText": "Server gratuit disponibil!", + "freeCloudServerNotAvailableText": "Nu sunt disponibile servere gratuite.", + "friendHasSentPromoCodeText": "${COUNT} Bilete pe ${APP_NAME} de la ${NAME}", + "friendPromoCodeAwardText": "Vei primi ${COUNT} de bilete de fiecare dată când este folosit.", + "friendPromoCodeExpireText": "Codul va expira în ${EXPIRE_HOURS} de ore şi este valabil doar pentru jucătorii noi.", + "friendPromoCodeInstructionsText": "Pentru a-l utiliza, deschide ${APP_NAME} și accesează „Setări-> Avansat-> Introdu un cod”.\nConsultă bombsquadgame.com pentru linkuri de descărcare pentru toate platformele acceptate.", + "friendPromoCodeRedeemLongText": "Poate fi introdus pentru ${COUNT} de bilete gratuite de către un maxim de ${MAX_USES} de persoane.", + "friendPromoCodeRedeemShortText": "Poate fi introdus în joc pentru ${COUNT} de bilete.", + "friendPromoCodeWhereToEnterText": "(în \"Setări-> Avansat-> Introdu un cod\")", + "getFriendInviteCodeText": "Cere un Cod pentru Prieteni", + "googlePlayDescriptionText": "Invită jucători Google Play la petrecerea ta:", + "googlePlayInviteText": "Invită", + "googlePlayReInviteText": "Sunt ${COUNT} jucători Google Play în grupul tău care vor\nfi deconectați dacă faci o altă invitație. Include-i și\npe ei în noua invitație pentru a-i avea înapoi la petrecere.", + "googlePlaySeeInvitesText": "Vezi Invitații", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Numai pentru Google Play / Android)", + "hostPublicPartyDescriptionText": "Creează Un Server Public", + "hostingUnavailableText": "Creeare Indisponibilă", + "inDevelopmentWarningText": "Notă:\n\nJocul peste rețea este încă o opțiune în dezvoltare.\nDeocamdată este recomandat ca toți jucătorii să fie pe\naceeași rețea Wi-Fi.", + "internetText": "Internet", + "inviteAFriendText": "Prietenii tăi nu au jocul? Invită-i să-l\nîncerce şi vor primii ${COUNT} de bilete gratis.", + "inviteFriendsText": "Invită-ți Prietenii", + "joinPublicPartyDescriptionText": "Alătură-te Unui Server Public", + "localNetworkDescriptionText": "Alătură-te unui grup din apropiere (LAN, Bluetooth etc.)", + "localNetworkText": "Rețea Locală", + "makePartyPrivateText": "Închide-mi Server-ul", + "makePartyPublicText": "Fă-mi Server-ul Public", + "manualAddressText": "Adresa", + "manualConnectText": "Conectează-te", + "manualDescriptionText": "Intră într-un joc cu adresa:", + "manualJoinSectionText": "Alătură-te cu Ajutorul Adresei", + "manualJoinableFromInternetText": "Se pot conecta alții de pe internet la jocul tău?:", + "manualJoinableNoWithAsteriskText": "NU*", + "manualJoinableYesText": "DA", + "manualRouterForwardingText": "*pentru a repara asta, configurează-ți router-ul încât acesta să dea forward la portul UDP ${PORT} către adresa ta locală", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Adresa ta de pe internet:", + "manualYourLocalAddressText": "Adresa ta locală:", + "nearbyText": "Din apropiere", + "noConnectionText": "", + "otherVersionsText": "(alte versiuni)", + "partyCodeText": "Codul Server-ului", + "partyInviteAcceptText": "Acceptă", + "partyInviteDeclineText": "Refuză", + "partyInviteGooglePlayExtraText": "(vezi tab-ul 'Google Play' din fereastra 'Adunare')", + "partyInviteIgnoreText": "Ignoră", + "partyInviteText": "${NAME} te-a invitat\nsă intri în grupul lui/ei!", + "partyNameText": "Numele Server-ului", + "partyServerRunningText": "Server-ul tău privat este activ.", + "partySizeText": "Jucători", + "partyStatusCheckingText": "Se verifică starea...", + "partyStatusJoinableText": "Server-ul tău este acum accesibil de pe internet", + "partyStatusNoConnectionText": "nu se poate conecta la server", + "partyStatusNotJoinableText": "nimeni de pe internet nu poate intra pe server-ul tău", + "partyStatusNotPublicText": "server-ul tău nu este public", + "pingText": "Ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Serverele private rulează pe servere cloud dedicate; nu este necesară configurarea router-ului.", + "privatePartyHostText": "Creează un Server Privat", + "privatePartyJoinText": "Alătură-te unui Server Privat", + "privateText": "Privat", + "publicHostRouterConfigText": "Acest lucru poate necesita configurarea redirecționării portului de pe router. Ca alternativă, creează un server privat.", + "publicText": "Public", + "requestingAPromoCodeText": "Se obține codul...", + "sendDirectInvitesText": "Trimite Invitații Directe", + "shareThisCodeWithFriendsText": "Trimite-le prietenilor tăi acest cod:", + "showMyAddressText": "Afișează-mi Adresa", + "startHostingPaidText": "Creează Acum Pentru ${COST}", + "startHostingText": "Creează Server", + "startStopHostingMinutesText": "Poți crea și închide servere gratis pentru următoarele ${MINUTES} minute.", + "stopHostingText": "Închide Server-ul", + "titleText": "Adunare", + "wifiDirectDescriptionBottomText": "Dacă toate dispozitivele au un panou 'Wi-Fi Direct', ar trebui să poată să îl folosească să\nse găsească și să se conecteze unii la alții. Când toate dispozitivele sunt conectate se pot\nforma grupuri, aici, folosind tab-ul 'Rețea locală', ca și când ați fi pe aceiași rețea Wi-Fi.\n\nPentru cele mai bune rezultate, host-ul Wi-Fi Direct ar trebui să fie și host-ul server-ului ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Funcția de Wi-Fi direct se poate folosi la conectarea dispozitivelor Android fără\na folosi o rețea Wi-Fi. Aceasta funcționează cel mai bine de la Android 4.2 în sus.\n\nPentru a folosi funcția de Wi-Fi direct, deschide setările Wi-Fi-ului și caută 'Wi-Fi Direct' în meniu.", + "wifiDirectOpenWiFiSettingsText": "Deschide setările Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(funcționează pe toate platformele)", + "worksWithGooglePlayDevicesText": "(funcționează pe orice dispozitiv care are versiunea Google Play (android) a jocului)", + "youHaveBeenSentAPromoCodeText": "Ai primit un cod Promo ${APP_NAME}:" + }, + "getTicketsWindow": { + "freeText": "GRATIS!", + "freeTicketsText": "Bilete Gratuite", + "inProgressText": "O tranzacție e în progres; reîncearcă în câteva secunde.", + "purchasesRestoredText": "Cumpărături Restaurate.", + "receivedTicketsText": "Ai primit ${COUNT} (de) bilete!", + "restorePurchasesText": "Restaurează Cumpărăturile", + "ticketDoublerText": "Dublator Bilete", + "ticketPack1Text": "Pachet de Bilete Mic", + "ticketPack2Text": "Pachet de Bilete Mediu", + "ticketPack3Text": "Pachet de Bilete Mare", + "ticketPack4Text": "Super-Pachet de Bilete", + "ticketPack5Text": "Pachet de Bilete MAMUT", + "ticketPack6Text": "Pachet de Bilete Suprem", + "ticketsFromASponsorText": "Vizionează o reclamă\npentru ${COUNT} bilete", + "ticketsText": "${COUNT} de Bilete", + "titleText": "Ia Bilete", + "unavailableLinkAccountText": "Scuze, dar achizițiile nu sunt disponibile pe această platformă.\nCa soluție, poți conecta acest cont la un alt cont de pe\no altă platformă și să faci cumpărături acolo.", + "unavailableTemporarilyText": "Acest serviciu este indisponibil deocamdată; încearcă din nou mai târziu.", + "unavailableText": "Scuze, această ofertă este indisponibilă.", + "versionTooOldText": "Scuze, dar versiunea jocului e prea veche; actualizează-l la o versiune mai nouă.", + "youHaveShortText": "ai ${COUNT}", + "youHaveText": "ai ${COUNT} (de) bilete" + }, + "googleMultiplayerDiscontinuedText": "Ne pare rău, serviciul multiplayer de pe Google nu mai este disponibil.\nLucrez la un înlocuitor cât mai repede posibil.\nPână atunci, te rog să încerci o altă metodă de conectare.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Achizițiile de pe Google Play nu sunt disponibile.\nÎncearcă să actualizezi Magazin Play și să încerci din nou.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Întotdeauna", + "fullScreenCmdText": "Fullscreen (Cmd+F)", + "fullScreenCtrlText": "Fullscreen (Ctrl+F)", + "gammaText": "Luminozitate", + "highText": "Înalte", + "higherText": "Mai Înalte", + "lowText": "Slabe", + "mediumText": "Medii", + "neverText": "Niciodată", + "resolutionText": "Rezoluție", + "showFPSText": "Arată FPS-urile", + "texturesText": "Texturi", + "titleText": "Grafici", + "tvBorderText": "Margine Pentru Televizor", + "verticalSyncText": "V-sync", + "visualsText": "Vizuale" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nMai puternică decât pumnii, dar poate\nrezulta în a te răni pe tine însuți.\nPentru rezultate pozitive, arunc-o înspre\ninamici înainte să i se termine fitilul.", + "canHelpText": "${APP_NAME} te poate ajuta.", + "controllersInfoText": "Te poți juca ${APP_NAME} cu prietenii cu ajutorul unei rețele de internet sau vă\nputeți juca cu toții pe același dispozitiv dacă aveți suficiente controllere.\n${APP_NAME} suportă o varietate mare de controllere; poți folosi chiar și telefoane\ndrept controllere cu ajutorul aplicației gratuite „${REMOTE_APP_NAME}”.\nConsultă Setări-> Controlere pentru mai multe informații.", + "controllersInfoTextRemoteOnly": "Te poți juca ${APP_NAME} cu prietenii tăi pe o rețea de Wi-Fi/Bluetooth, sau\nvă puteți juca cu toții pe același dispozitiv folosindu-vă telefoanele\ndrept controllere cu ajutorul aplicației gratuite '${REMOTE_APP_NAME}'.", + "controllersText": "Controllere", + "controlsSubtitleText": "Caracterul tău prietenos din ${APP_NAME} are câteva acțiuni de bază:", + "controlsText": "Controalele", + "devicesInfoText": "Te poți juca pe internet pe versiunea VR de ${APP_NAME}\nla fel ca pe cea originală așa că scoateți-vă telefoanele, tabletele,\nporniți computerele și începeți jocul. Poate fi folositor\nși să conectezi versiunea originală la cea VR doar ca cei\ndin afară să poată vedea acțiunea.", + "devicesText": "Dispozitive", + "friendsGoodText": "E bine să ai și din aceștia. ${APP_NAME} e și mai amuzant cu mai\nmulți jucători și suportă până la 8 deodată, ceea ce ne duce la:", + "friendsText": "Prieteni", + "jumpInfoText": "- Săritura -\nSari ca să treci peste gropi mici,\nsă arunci lucruri mai sus,\nși să-ți exprimi fericirea.", + "orPunchingSomethingText": "Sau să dai cu pumnii în ceva, să arunci acel ceva într-o prăpastie și să explodeze până jos de la o bombă lipicioasă.", + "pickUpInfoText": "- Ridicarea -\nRidică steaguri, inamici, sau orice \nlucru care nu e fixat de pământ.\nApasă-l încă odată pentru a arunca lucrul respectiv.", + "pickUpInfoTextScale": 0.5, + "powerupBombDescriptionText": "Te lasă să arunci 3 bombe\nîn loc de una singură.", + "powerupBombNameText": "Bombe Triple", + "powerupCurseDescriptionText": "Ar fi mai bine să eviți astea.\n ...sau oare?", + "powerupCurseNameText": "Blestem", + "powerupHealthDescriptionText": "Îți regenerează viața la maxim.\nNici n-ai fi ghicit.", + "powerupHealthNameText": "Trusă de Prim-Ajutor", + "powerupIceBombsDescriptionText": "Mai slabe decât bombele\nnormale, dar îți lasă inamicii\nînghețați și aparent fragili.", + "powerupIceBombsNameText": "Bombe de Gheață", + "powerupImpactBombsDescriptionText": "Mai slabe decât bombele normale,\ndar explodează imediat ce ating ceva.", + "powerupImpactBombsNameText": "Bombe cu Impact", + "powerupLandMinesDescriptionText": "Acestea vin câte 3; Folositoare\npentru apărarea bazelor sau\npentru oprirea inamicilor vitezomani.", + "powerupLandMinesNameText": "Mine", + "powerupPunchDescriptionText": "Îți va face pumnii mai tari,\nmai rapizi și mai buni.", + "powerupPunchNameText": "Mănuși de Box", + "powerupShieldDescriptionText": "Absoarbe daunele ca să\nnu o faci tu.", + "powerupShieldNameText": "Scut-Energic", + "powerupStickyBombsDescriptionText": "Se lipesc de orice ating.\nHilaritate garantată.", + "powerupStickyBombsNameText": "Bombe Lipicioase", + "powerupsSubtitleText": "Desigur, nici un joc nu e complet fără powerup-uri:", + "powerupsText": "Powerup-uri", + "punchInfoText": "- Pumnii -\nPumnii dăunează mai mult cu cât\nîi miști mai rapid, deci aleargă\nși rotește-te ca un dement!", + "runInfoText": "- Fuga -\nȚine apăsat ORICE buton pentru a fugi. Triggerele sau butoanele de umăr funcționează bine dacă le ai.\nFugitul te ajută să ajungi mai repede în alte locuri, deși virezi greu, deci ai grijă la prăpastii.", + "someDaysText": "În unele zile pur și simplu vrei să lovești ceva. Sau să explodezi altceva.", + "titleText": "Ajutor pentru ${APP_NAME}", + "toGetTheMostText": "Pentru a vedea tot ce oferă jocul acesta, vei avea nevoie de:", + "welcomeText": "Bun venit în ${APP_NAME}!" + }, + "holdAnyButtonText": "<ține apăsat orice buton>", + "holdAnyKeyText": "<ține apăsat pe orice tastă>", + "hostIsNavigatingMenusText": "- ${HOST} navighează meniurile ca un șmecher -", + "importPlaylistCodeInstructionsText": "Folosește următorul cod pentru a importa această listă în altă parte:", + "importPlaylistSuccessText": "Lista de tip ${TYPE} cu numele '${NAME}' a fost importată cu succes", + "importText": "Importă", + "importingText": "Se importă...", + "inGameClippedNameText": "va arăta astfel\n\"${NAME}\"", + "installDiskSpaceErrorText": "EROARE: Nu s-a putut completa instalarea.\nSe poate să fi rămas fără spațiu pe dispozitiv.\nEliberează niște spațiu și încearcă din nou.", + "internal": { + "arrowsToExitListText": "Apasă ${LEFT} sau ${RIGHT} pentru a ieși din listă", + "buttonText": "buton", + "cantKickHostError": "Nu poți da afară hostul server-ului.", + "chatBlockedText": "${NAME} este blocat în chat timp de ${TIME} (de) secunde.", + "connectedToGameText": "Ai intrat în '${NAME}'", + "connectedToPartyText": "Ai intrat în server-ul lui ${NAME}!", + "connectingToPartyText": "Se conectează...", + "connectionFailedHostAlreadyInPartyText": "Conexiunea a eşuat; hostul este în alt joc.", + "connectionFailedPartyFullText": "Conexiune eșuată; server-ul este plin.", + "connectionFailedText": "Conexiunea a eşuat.", + "connectionFailedVersionMismatchText": "Conexiunea a eşuat; hostul rulează o versiune diferită a jocului.\nAsigurați-vă că ambii aveți cea mai nouă versiune a jocului şi încercați din nou.", + "connectionRejectedText": "Conexiune Respinsă.", + "controllerConnectedText": "${CONTROLLER} conectat.", + "controllerDetectedText": "1 controller detectat.", + "controllerDisconnectedText": "${CONTROLLER} a fost deconectat.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} a fost deconectat. Încearcă să-l conectezi din nou.", + "controllerForMenusOnlyText": "Acest controller nu poate fi folosit pentru a juca; ci doar pentru navigarea meniurilor.", + "controllerReconnectedText": "${CONTROLLER} reconectat.", + "controllersConnectedText": "${COUNT} controllere conectate.", + "controllersDetectedText": "${COUNT} controllere detectate.", + "controllersDisconnectedText": "${COUNT} controllere s-au deconectat.", + "corruptFileText": "Fişiere Corupte detectate. Reinstalează jocul, sau trimite un email la adresa ${EMAIL}", + "errorPlayingMusicText": "Nu s-a putut porni muzica: ${MUSIC}", + "errorResettingAchievementsText": "Nu se pot reseta medaliile; încearcă din nou mai tărziu.", + "hasMenuControlText": "${NAME} are controlul meniului.", + "incompatibleNewerVersionHostText": "Hostul rulează o versiune mai nouă a jocului.\nActualizează-ți jocul la cea mai recentă versiune și încearcă din nou.", + "incompatibleVersionHostText": "Hostul rulează o versiune diferită a jocului.\nAsigură-te că ai cea mai nouă versiune şi încearcă din nou.", + "incompatibleVersionPlayerText": "${NAME} rulează o versiune diferită a jocului.\nAsigură-te că ai cea mai nouă versiune si încearcă din nou.", + "invalidAddressErrorText": "Eroare: adresă invalidă.", + "invalidNameErrorText": "Eroare: nume invalid.", + "invalidPortErrorText": "Eroare: port invalid.", + "invitationSentText": "Invitație Trimisă.", + "invitationsSentText": "${COUNT} (de) invitații trimise.", + "joinedPartyInstructionsText": "Cineva s-a alăturat server-ului tău.\nAccesează meniul „Joacă” pentru a începe un joc.", + "keyboardText": "Tastatură", + "kickIdlePlayersKickedText": "${NAME} a fost dat afară deoarece era inactiv.", + "kickIdlePlayersWarning1Text": "${NAME} va fi dat afară în următoarele ${COUNT} secunde dacă continuă să fie inactiv.", + "kickIdlePlayersWarning2Text": "(Poți dezactiva această setare în Setări -> Avansat)", + "leftGameText": "Ai ieșit din '${NAME}'", + "leftPartyText": "Ai ieşit din server-ul lui ${NAME}.", + "noMusicFilesInFolderText": "Folder-ul nu conține niciun fişier de muzică.", + "playerJoinedPartyText": "${NAME} a intrat în joc!", + "playerLeftPartyText": "${NAME} a ieșit.", + "rejectingInviteAlreadyInPartyText": "Se respinge invitația (eşti deja într-un alt server).", + "serverRestartingText": "Server-ul se restartează. Te rog să reintri într-o clipă...", + "serverShuttingDownText": "Server-ul se închide...", + "signInErrorText": "Eroare la Conectare.", + "signInNoConnectionText": "Nu se poate conecta. (nu există o conexiune la internet?)", + "telnetAccessDeniedText": "Eroare: utilizatorul nu are acces la telnet.", + "timeOutText": "(i se va pierde controlul meniului în ${TIME} (de) secunde)", + "touchScreenJoinWarningText": "Ai intrat cu touchscreen-ul.\nDacă ai făcut-o din greşeală, apasă 'Meniu -> Devino Spectator' cu acesta.", + "touchScreenText": "TouchScreen", + "unableToResolveHostText": "Eroare: imposibil de găsit hostul.", + "unavailableNoConnectionText": "Acest serviciu nu este disponibil acum (fără conexiune la internet?)", + "vrOrientationResetCardboardText": "Foloseşte această opțiune pentru resetare orientării VR.\nDacă vrei să te joci vei avea nevoie de un controller external.", + "vrOrientationResetText": "Orientare VR resetată.", + "willTimeOutText": "(i se va lua controlul dacă este inactiv)" + }, + "jumpBoldText": "SARI", + "jumpText": "Sari", + "keepText": "Păstrează", + "keepTheseSettingsText": "Păstrezi aceste setări?", + "keyboardChangeInstructionsText": "Apasă tasta space de două ori pentru a schimba tastaturile.", + "keyboardNoOthersAvailableText": "Nu a fost detectată altă tastatură.", + "keyboardSwitchText": "Tastatura schimbată va fi \"${NAME}\".", + "kickOccurredText": "${NAME} a fost dat afară.", + "kickQuestionText": "Vrei să dai afară pe ${NAME}?", + "kickText": "Dă-l afară", + "kickVoteCantKickAdminsText": "Administratorii nu pot fi dați afară.", + "kickVoteCantKickSelfText": "De ce ai vrea să te dai afară?", + "kickVoteFailedNotEnoughVotersText": "Nu sunt destui jucători pentru un vot.", + "kickVoteFailedText": "Votul a eșuat.", + "kickVoteStartedText": "Un vot de a da afară pe ${NAME} a fost cerut.", + "kickVoteText": "Votează pentru a-l da afară", + "kickVotingDisabledText": "Datul afară este dezactivat.", + "kickWithChatText": "Scrie ${YES} în chat pentru a-l vota sau scrie ${NO} pentru a nu-l vota.", + "killsTallyText": "${COUNT} (de) ucideri", + "killsText": "Ucideri", + "kioskWindow": { + "easyText": "Uşor", + "epicModeText": "Modul Epic", + "fullMenuText": "Meniul Întreg", + "hardText": "Greu", + "mediumText": "Mediu", + "singlePlayerExamplesText": "Exemple de jocuri Solo / Echipe", + "versusExamplesText": "Exemple de jocuri Versus" + }, + "languageSetText": "Limba este acum \"${LANGUAGE}\"", + "lapNumberText": "Tura ${CURRENT}/${TOTAL}", + "lastGamesText": "(ultimele ${COUNT} de jocuri)", + "leaderboardsText": "Clasamente", + "league": { + "allTimeText": "Din totdeauna", + "currentSeasonText": "Sezon curent (${NUMBER})", + "leagueFullText": "Liga de ${NAME}", + "leagueRankText": "Rangul din ligă", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "Sezonul s-a sfârșit acum ${NUMBER} (de) zile.", + "seasonEndsDaysText": "Sezonul se sfârșește în ${NUMBER} (de) zile.", + "seasonEndsHoursText": "Sezonul se sfârșește în ${NUMBER} (de) ore.", + "seasonEndsMinutesText": "Sezonul se sfârșește în ${NUMBER} (de) minute.", + "seasonText": "Sezonul ${NUMBER}", + "tournamentLeagueText": "Trebuie să ajungi în liga ${NAME} dacă vrei să intri în acest turneu.", + "trophyCountsResetText": "Numărul de trofee se va reseta la sfârșitul sezonului." + }, + "levelBestScoresText": "Cele mai bune scoruri din ${LEVEL}", + "levelBestTimesText": "Cele mai scurte timpuri din ${LEVEL}", + "levelFastestTimesText": "Cel mai rapid timp pe ${LEVEL}", + "levelHighestScoresText": "Cel mai mare scor pe ${LEVEL}", + "levelIsLockedText": "${LEVEL} este blocat.", + "levelMustBeCompletedFirstText": "Mai întâi trebuie să termini ${LEVEL}.", + "levelText": "Nivelul ${NUMBER}", + "levelUnlockedText": "Nivel Deblocat!", + "livesBonusText": "Bonus de Vieți", + "loadingText": "se încarcă", + "loadingTryAgainText": "Se încarcă; așteaptă o clipă...", + "macControllerSubsystemBothText": "Ambele (nerecomandat)", + "macControllerSubsystemClassicText": "Simplu", + "macControllerSubsystemDescriptionText": "(încearcă să schimbi această opțiune dacă nu-ți funcționează controllerele)", + "macControllerSubsystemMFiNoteText": "Controller Făcut-Pentru-iOS/Mac detectat;\nPentru a-l porni mergi în Setări -> Controllere", + "macControllerSubsystemMFiText": "Făcut-Pentru-iOS/Mac", + "macControllerSubsystemTitleText": "Suport Pentru Controller", + "mainMenu": { + "creditsText": "Credite", + "demoMenuText": "Meniu Demonstrativ", + "endGameText": "Sfârșește Jocul", + "exitGameText": "Ieși Din Joc", + "exitToMenuText": "Revii la meniu?", + "howToPlayText": "Cum se Joacă?", + "justPlayerText": "(Doar ${NAME})", + "leaveGameText": "Devino Spectator", + "leavePartyConfirmText": "Sigur vrei să părăsești grupul?", + "leavePartyText": "Părăsește Grupul", + "quitText": "Ieși", + "resumeText": "Continuă", + "settingsText": "Setări" + }, + "makeItSoText": "Așa să fie!", + "mapSelectGetMoreMapsText": "Ia Mai Multe Hărți...", + "mapSelectText": "Selectează...", + "mapSelectTitleText": "Hărți Pentru ${GAME}", + "mapText": "Harta", + "maxConnectionsText": "Număr De Locuri", + "maxPartySizeText": "Număr Maxim De Locuri", + "maxPlayersText": "Locuri", + "modeArcadeText": "Mod Pentru Arcade", + "modeClassicText": "Modul Clasic", + "modeDemoText": "Modul Demonstrativ", + "mostValuablePlayerText": "Cel mai valoros jucător este", + "mostViolatedPlayerText": "Cel mai ucis jucător este", + "mostViolentPlayerText": "Cel mai violent jucător este", + "moveText": "Te miști din", + "multiKillText": "${COUNT} ucideri!!!", + "multiPlayerCountText": "${COUNT} jucători", + "mustInviteFriendsText": "Notă: du-te în meniul \"${GATHER}\"\nsau conectează-ți câteva controllere\ndacă vrei să te joci multiplayer cu prietenii.", + "nameBetrayedText": "${NAME} a trădat pe ${VICTIM}", + "nameDiedText": "${NAME} a murit.", + "nameKilledText": "${NAME} a omorât pe ${VICTIM}", + "nameNotEmptyText": "Trebubie să-ți pui un nume!", + "nameScoresText": "${NAME} înscrie!", + "nameSuicideKidFriendlyText": "${NAME} a dat colțul.", + "nameSuicideText": "${NAME} s-a sinucis.", + "nameText": "Numele", + "nativeText": "Nativă", + "newPersonalBestText": "Un nou record personal a fost atins!", + "newTestBuildAvailableText": "O nouă versiune de test a fost lansată: (${VERSION} build ${BUILD}).\nIa-o de pe ${ADDRESS}", + "newText": "Nou", + "newVersionAvailableText": "O versiune nouă de ${APP_NAME} este disponibilă,aceasta fiind (${VERSION})!", + "nextAchievementsText": "Realizările Următoare:", + "nextLevelText": "Următorul Nivel", + "noAchievementsRemainingText": "- niciunul", + "noContinuesText": "(fără continuări)", + "noExternalStorageErrorText": "Nu a fost găsită nicio stocare externă pe acest dispozitiv.", + "noGameCircleText": "Eroare: nu eşti logat cu GameCircle", + "noProfilesErrorText": "Nu ai niciun Profil de Jucător, deci eşti blocat cu '${NAME}'.\nDute la Setări->Profile de Jucător pentru a-ți face un profil.", + "noScoresYetText": "Niciun scor deocamdată.", + "noThanksText": "Nu Mulțumesc", + "noTournamentsInTestBuildText": "ATENȚIE: Scorurile obținute în turnee vor fi ignorate în această versiune de test.", + "noValidMapsErrorText": "Nu sunt hărți disponibile pentru acest mod de joc.", + "notEnoughPlayersRemainingText": "Nu mai sunt destui jucători; ieși din joc și creează altul nou.", + "notEnoughPlayersText": "Ai nevoie de cel puțin ${COUNT} jucători pentru a începe acest joc!", + "notNowText": "Nu Acum", + "notSignedInErrorText": "Trebuie să fi conectat cu un cont dacă vrei să faci asta.", + "notSignedInGooglePlayErrorText": "Trebuie să fii conectat cu Google Play dacă vrei să faci asta.", + "notSignedInText": "nu te-ai conectat cu nici un cont", + "nothingIsSelectedErrorText": "Nu ai selectat nimic!", + "numberText": "#${NUMBER}", + "offText": "Oprit", + "okText": "Ok", + "onText": "Pornit", + "oneMomentText": "Un Moment...", + "onslaughtRespawnText": "${PLAYER} va reveni în valul ${WAVE}", + "orText": "${A} sau ${B}", + "otherText": "Altele...", + "outOfText": "(#${RANK} din ${ALL})", + "ownFlagAtYourBaseWarning": "Steagul tău trebuie să fie\nla bază pentru a înscrie!", + "packageModsEnabledErrorText": "Network-play-ul nu poate fi pornit cât timp modurile-local-package sunt active (vezi Setări->Avansat)", + "partyWindow": { + "chatMessageText": "Mesaj Prin Chat", + "emptyText": "Petrecerea ta este goală", + "hostText": "(hostul)", + "sendText": "Trimite", + "titleText": "Server-ul Tău" + }, + "pausedByHostText": "(pus pe pauză de către host)", + "perfectWaveText": "Val Perfect!", + "pickUpText": "Ridică", + "playModes": { + "coopText": "Cooperare", + "freeForAllText": "Fiecare-pentru-El", + "multiTeamText": "Cu mai multe echipe", + "singlePlayerCoopText": "Un singur jucător / Cooperare", + "teamsText": "Echipe" + }, + "playText": "Joacă", + "playWindow": { + "oneToFourPlayersText": "1-4 jucători", + "titleText": "Joacă", + "twoToEightPlayersText": "2-8 jucători" + }, + "playerCountAbbreviatedText": "${COUNT}P", + "playerDelayedJoinText": "${PLAYER} va intra la începutul rundei următoare.", + "playerInfoText": "Informații Despre Jucător", + "playerLeftText": "${PLAYER} a ieşit din joc.", + "playerLimitReachedText": "Limita de ${COUNT} jucători a fost atinsă; nimeni nu mai are voie să intre.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Nu poți să-ți ștergi profilul contului.", + "deleteButtonText": "Șterge\nprofilul", + "deleteConfirmText": "Ștergi profilul '${PROFILE}'?", + "editButtonText": "Editează\nProfilul", + "explanationText": "(nume și aparențe personalizate pe acest cont)", + "newButtonText": "Profil\nNou", + "titleText": "Profilele Jucătorului" + }, + "playerText": "Jucător", + "playlistNoValidGamesErrorText": "Această listă nu conține jocuri deblocate valide.", + "playlistNotFoundText": "lista nu a fost găsită", + "playlistText": "Lista de jocuri", + "playlistsText": "Liste de Jocuri", + "pleaseRateText": "Dacă îți place ${APP_NAME}, te rog să stai\no clipă și să evaluezi jocul, scriind o recenzie pentru acesta.\nAceasta furnizează feedback folositor și ajută la dezvoltarea jocului în viitor.\n\nmulțumesc!\n-Eric", + "pleaseWaitText": "Te rog să aștepți...", + "pluginClassLoadErrorText": "Nu s-a putut încărca plugin-ul '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Nu s-a putut iniția plugin-ul '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Plugin(uri) noi detectate. Restartează jocul pentru a le activa / configura în setări.", + "pluginsRemovedText": "${NUM} plugin(uri) nu mai există.", + "pluginsText": "Plugin-uri", + "practiceText": "Antrenament", + "pressAnyButtonPlayAgainText": "Apasă orice buton pentru a juca din nou...", + "pressAnyButtonText": "Apasă orice buton pentru a continua...", + "pressAnyButtonToJoinText": "apasă orice buton pentru a intra...", + "pressAnyKeyButtonPlayAgainText": "Apasă orice buton/tastă pentru a juca din nou...", + "pressAnyKeyButtonText": "Apasă orice buton/tastă pentru a continua...", + "pressAnyKeyText": "Apasă orice tastă...", + "pressJumpToFlyText": "** Apasă butonul de sărit de mai multe ori pentru a zbura **", + "pressPunchToJoinText": "apasă PUMN pentru a intra...", + "pressToOverrideCharacterText": "apasă ${BUTTONS} pentru a-ți schimba caracterul", + "pressToSelectProfileText": "apasă ${BUTTONS} pentru a-ți selecta profilul", + "pressToSelectTeamText": "apasă ${BUTTONS} pentru a-ți selecta echipa", + "promoCodeWindow": { + "codeText": "Codul", + "codeTextDescription": "Cod Promoțional", + "enterText": "Trimite-l" + }, + "promoSubmitErrorText": "Eroare la trimiterea codului; verifică-ți conexiunea la internet", + "ps3ControllersWindow": { + "macInstructionsText": "Scoate PS3-ul din priză, asigură-te că \nai Bluetooth-ul pornit pe Mac-ul tău, apoi conectează controllerul\nprintr-un cablu USB pentru a împerechea ambele dispozitive. De acum înainte vei putea\nfolosi butonul 'HOME' de pe controller pentru a-l conecta la Mac-ul tău\nprin USB sau prin Bluetooth (apăsând pe butonul HOME).\n\nPe unele Mac-uri s-ar putea să apară o fereastră care va cere un cod când conectezi controllerul.\nDacă se întâmplă acest lucru, uite-te la tutorialul de mai jos sau caută pe Google ce trebuie să faci.\n\n\n\n\nControllerele PS3 conectate fără fir as trebui să apară în\nlista dispozitivelor în System Preferences->Bluetooth. Ar trebui să le ştergi de\npe acea listă dacă vrei să le foloseşti la PS3-ul tău din nou.\n\nȘi asigură-te să le deconectezi de la Bluetooth când nu le foloseşti \nsau bateriile lor vor continua să se consume.\n\nBluetooth-ul poate ține în jur de 7 dispozitive conectate,\ndar acest lucru ar putea varia de la un dispozitiv la altul.", + "macInstructionsTextScale": 0.73, + "ouyaInstructionsText": "Pentru a folosi un controller de PS3 cu OUYA-ul tău, conectează-l pur și simplu printr-un cablu USB\no singură dată pentru a-l conecta. Acest lucru s-ar putea să-ți deconecteze celelalte controllere, deci \nva trebui să-ți restartezi OUYA-ul şi să scoți cablul USB.\n\nDupă aceea vei putea conecta controllerul prin apăsarea butonului HOME.\nCând nu mai vrei să te joci, ține apăsat pe butonul HOME timp de\n10 secunde ca să închizi controllerul; în caz contrar va continua să\nfie pornit,consumându-și bateriile.", + "ouyaInstructionsTextScale": 0.73, + "pairingTutorialText": "tutorial video pentru împerecherea dispozitivelor", + "titleText": "Controllere de PS3 active în ${APP_NAME}:" + }, + "punchBoldText": "PUMN", + "punchText": "Pumn", + "purchaseForText": "Cumpără pentru ${PRICE}", + "purchaseGameText": "Cumpără Jocul", + "purchasingText": "Se cumpără...", + "quitGameText": "Ieși din ${APP_NAME}?", + "quittingIn5SecondsText": "Se iese în 5 secunde...", + "randomPlayerNamesText": "Andrei, Marius, Marian, Cosmin, Cristi, Ioana, Gabi, Călin, Teodor, Mihai, Alex, Alexandra, Bogdan, Cătălin, Ştefan, George, Nicoleta, Antonio, David, Teodora, Denisa, Iuliana, Mariana, Nicușor, Sebastian", + "randomText": "La Nimereală", + "rankText": "Rank", + "ratingText": "Clasificare", + "reachWave2Text": "Trebuie să ajungi la valul 2 dacă vrei să ți se rankeze scorul.", + "readyText": "pregătit", + "recentText": "Recente", + "remoteAppInfoShortText": "${APP_NAME} este mult mai distractiv când este jucat cu familia & prietenii.\nConectează unul sau mai multe controllere sau instalează \naplicația ${REMOTE_APP_NAME} pe telefoane sau tablete\npentru a le folosi drept controllere.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Poziția Butoanelor", + "button_size": "Dimensiunea Butoanelor", + "cant_resolve_host": "Nu se poate găsi hostul.", + "capturing": "Atribuie un buton...", + "connected": "Conectat.", + "description": "Folosește-ți telefonul sau tableta drept controller pentru BombSquad.\nPoți conecta 8 dispozitive simultan pentru un mod de multiplayer nebunesc pe un Televizor sau pe o tabletă.", + "disconnected": "Deconectat de către server.", + "dpad_fixed": "fixat", + "dpad_floating": "liber", + "dpad_position": "Poziția D-Pad-ului", + "dpad_size": "Dimensiunea D-Pad-ului", + "dpad_type": "Tip de D-Pad", + "enter_an_address": "Introdu o Adresă", + "game_full": "Jocul este plin sau nu acceptă conexiuni noi.", + "game_shut_down": "Jocul a fost oprit.", + "hardware_buttons": "Butoane Hardware", + "join_by_address": "Conectează-te cu adresa...", + "lag": "Lag: ${SECONDS} secunde", + "reset": "Resetează valorile la cele implicite", + "run1": "Buton de Alergare 1", + "run2": "Buton de Alergare 2", + "searching": "Se caută jocuri BombSquad prin internet...", + "searching_caption": "Apasă pe numele unui joc pentru a intra în el.\nFii sigur că ești pe aceiași rețea Wi-Fi ca și jocul hostului.", + "start": "Start", + "version_mismatch": "Versiuni Nepotrivite.\nAsigură-te că BombSquad și BombSquad Remote\nau cea mai nouă versiune și încearcă din nou." + }, + "removeInGameAdsText": "Deblochează \"${PRO}\" în magazin pentru a şterge reclamele din joc.", + "renameText": "Redenumeşte", + "replayEndText": "Sfârşeşte Reluarea", + "replayNameDefaultText": "Reluarea Ultimului Joc", + "replayReadErrorText": "Eroare la citirea fişierului de reluare.", + "replayRenameWarningText": "Redenumeşte \"${REPLAY}\" după un joc dacă vrei s-o păstrezi; în caz contrar va fi înlocuită.", + "replayVersionErrorText": "Scuze, această reluare a fost făcută în altă versiune\na jocului şi nu poate fi pornită în aceasta.", + "replayWatchText": "Vezi Reluarea", + "replayWriteErrorText": "Eroare la scrierea fişierului de reluare.", + "replaysText": "Reluări", + "reportPlayerExplanationText": "Foloseşte această adresă de E-Mail pentru a raporta trişori, limbaj vulgar, sau alte tipuri de comportamente inadecvate.\nTe rog descrie subiectul mai jos:", + "reportThisPlayerCheatingText": "Trișat", + "reportThisPlayerLanguageText": "Limbaj Vulgar", + "reportThisPlayerReasonText": "Ce ai vrea să reclami?", + "reportThisPlayerText": "Raportează Acest Jucător", + "requestingText": "Se ia...", + "restartText": "Restart", + "retryText": "Reîncearcă", + "revertText": "Revino la setările normale", + "runText": "Pentru a fugi", + "saveText": "Salvează", + "scanScriptsErrorText": "Una sau mai multe erori au fost detectate în timpul scanării scripturilor; vezi jurnalul de activități pentru detalii.", + "scoreChallengesText": "Provocări de Scor", + "scoreListUnavailableText": "Lista de Scoruri este indisponibilă.", + "scoreText": "Scor", + "scoreUnits": { + "millisecondsText": "Milisecunde", + "pointsText": "Puncte", + "secondsText": "Secunde" + }, + "scoreWasText": "(a fost ${COUNT})", + "selectText": "Selectează", + "seriesWinLine1PlayerText": "CÂŞTIGĂ", + "seriesWinLine1TeamText": "CÂŞTIGĂ", + "seriesWinLine1Text": "CÂŞTIGĂ", + "seriesWinLine2Text": "SERIILE!", + "settingsWindow": { + "accountText": "Cont", + "advancedText": "Avansat", + "audioText": "Audio", + "controllersText": "Controllere", + "graphicsText": "Grafici", + "playerProfilesMovedText": "Notă: Profilele de jucător au fost mutate în Fereastra conturilor din meniul principal.", + "playerProfilesText": "Profile de Jucător", + "titleText": "Setări" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(o tastatură simplă, folositoare pentru controllere, care ajută la editarea textului)", + "alwaysUseInternalKeyboardText": "Foloseşte Mereu Tastatura Internală", + "benchmarksText": "Teste-Stres & Referințe", + "disableCameraGyroscopeMotionText": "Oprește Mișcarea Camerei De Tip Giroscop", + "disableCameraShakeText": "Dezactivează Cutremurarea Camerei", + "disableThisNotice": "(Poți dezactiva această notificare în setările avansate)", + "enablePackageModsDescriptionText": "Permite mai multe capabilități pentru modare, dar dezactivează net-play-ul)", + "enablePackageModsText": "Activează Moduri cu Pachete Locale", + "enterPromoCodeText": "Introdu un cod", + "forTestingText": "Notă: aceste valori sunt doar pentru teste şi vor fi resetate când jocul va fi închis.", + "helpTranslateText": "Translațiile din ${APP_NAME} sunt un efort depus de comunitate.\nDacă ai dori să te implici la translatarea/corectarea unei limbi,\nurmează linkul de mai jos. Mulțumiri anticipate!", + "kickIdlePlayersText": "Dă Afară Jucătorii Inactivi", + "kidFriendlyModeText": "Modul Pentru Copii (mai puțină violență, etc)", + "languageText": "Limbă", + "moddingGuideText": "Ghid pentru Modare", + "mustRestartText": "Va trebui să restartezi jocul dacă vrei ca acest lucru să își facă efectul.", + "netTestingText": "Testarea Internetului", + "resetText": "Resetează", + "showBombTrajectoriesText": "Arată Traiectoriile Bombelor", + "showPlayerNamesText": "Arată Numele Jucătorilor", + "showUserModsText": "Arată Folderul Pentru Moduri", + "titleText": "Avansat", + "translationEditorButtonText": "Editor de Translatări ${APP_NAME}", + "translationFetchErrorText": "status pentru translatare indisponibil", + "translationFetchingStatusText": "Se verifică statusul limbii...", + "translationInformMe": "Informează-mă când limba mea are nevoie de actualizări", + "translationNoUpdateNeededText": "Limba curentă este actualizată; uraaaaa!", + "translationUpdateNeededText": "** limba curentă are nevoie de update-uri!! **", + "vrTestingText": "Teste Pentru VR" + }, + "shareText": "Partajează", + "sharingText": "Se partajează...", + "showText": "Arată", + "signInForPromoCodeText": "Va trebui să te conectezi cu un cont dacă vrei să funționeze codurile introduse.", + "signInWithGameCenterText": "Pentru a folosi un cont Game Center\nconectează-te folosind aplicația Game Center.", + "singleGamePlaylistNameText": "Doar ${GAME}", + "singlePlayerCountText": "1 jucător", + "soloNameFilterText": "${NAME} Solo", + "soundtrackTypeNames": { + "CharSelect": "Selecția Caracterului", + "Chosen One": "Alesul", + "Epic": "Jocurile în Slow Motion", + "Epic Race": "Cursă în Slow Motion", + "FlagCatcher": "Capturează Steagul", + "Flying": "Amintiri Fericite", + "Football": "TouchDown", + "ForwardMarch": "Asalt", + "GrandRomp": "Cucerire", + "Hockey": "Hockey", + "Keep Away": "Stai Departe", + "Marching": "Runaround", + "Menu": "Meniu principal", + "Onslaught": "Măcel", + "Race": "Cursă", + "Scary": "Regele Dealului", + "Scores": "Ecranul Cu Scoruri", + "Survival": "Eliminare", + "ToTheDeath": "Meciul Morții", + "Victory": "Ecranul cu Scorurile Finale" + }, + "spaceKeyText": "spacebar", + "statsText": "Statistici", + "storagePermissionAccessText": "Acest beneficiu are nevoie de permisiuni de stocare", + "store": { + "alreadyOwnText": "Ai cumpărat ${NAME} deja!", + "bombSquadProDescriptionText": "•Dublează biletele primite\n•Şterge advertismentele din joc\n•Include ${COUNT} de bilete bonus\n•+${PERCENT}% la scorul de la ligi\n•Deblochează '${INF_ONSLAUGHT}' şi \n '${INF_RUNAROUND}' ca nivele co-op", + "bombSquadProFeaturesText": "Caracteristici:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Șterge reclamele și pop-up-urile enervante\n• Deblochează mai multe setări ale jocului\n• Acesta mai include și:", + "buyText": "Cumpără", + "charactersText": "Caractere", + "comingSoonText": "În Curând...", + "extrasText": "Extra", + "freeBombSquadProText": "BombSquad este un joc gratuit, dar fiindcă tu l-ai cumpărat primeşti upgrade-ul \nla BombSquad Pro şi ${COUNT} de bilete drept mulțumire.\nÎți mulțumesc pentru suportul tău!\n-Eric", + "gameUpgradesText": "Upgrade-uri pentru joc", + "holidaySpecialText": "Speciale pe timp de Sărbători", + "howToSwitchCharactersText": "(du-te la \"${SETTINGS} -> ${PLAYER_PROFILES}\" ca să-ți setezi & particularizezi caracterele)", + "howToUseIconsText": "(creează profile de jucător globale (în fereastra conturilor) pentru a le folosi)", + "howToUseMapsText": "(foloseşte aceste hărți în listele cu jocuri de Echipe/Fiecare-Pentru-El făcute de tine)", + "iconsText": "Iconițe", + "loadErrorText": "Nu se poate încărca pagina.\nVerifică-ți conexiunea la internet.", + "loadingText": "se încarcă", + "mapsText": "Hărți", + "miniGamesText": "MiniJocuri", + "oneTimeOnlyText": "(o singură dată)", + "purchaseAlreadyInProgressText": "Deja se cumpără acest obiect.", + "purchaseConfirmText": "Cumperi ${ITEM}?", + "purchaseNotValidError": "Achiziționarea nu este validă.\nContactează adresa de E-Mail ${EMAIL} dacă aceasta este o eroare.", + "purchaseText": "Cumpără", + "saleBundleText": "Pachet La Reducere!", + "saleExclaimText": "Reducere!", + "salePercentText": "(${PERCENT}% mai ieftin)", + "saleText": "REDUCERE", + "searchText": "Caută", + "teamsFreeForAllGamesText": "Joc în echipe / Fiecare-Pentru-El", + "totalWorthText": "*** ofertă cu valoare de ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Vrei să-ți îmbunătățești versiunea?", + "winterSpecialText": "Speciale pe timp de Iarnă", + "youOwnThisText": "- deja ai cumpărat asta -" + }, + "storeDescriptionText": "Nebunie pentru 8 Jucători!\n\nExplodează-ți prietenii (sau computerul) într-un concurs de mini-jocuri explozive cum ar fi Capturează Steagul, Hockey-Bombist, şi Meci-de-Moarte-În-Slow-Motion-Epic!\n\nControalele simple şi suportul pentru diferite tipuri de controller fac posibilă joaca cu un maxim de 8 jucători; îți poți folosi chiar şi telefonul drept controller cu ajutorul aplicației 'BombSquad Remote'!\n\nScoate Bombele La Iveală!\n\nVezi www.froemling.net/bombsquad pentru mai multe informații.", + "storeDescriptions": { + "blowUpYourFriendsText": "Explodează-ți prietenii.", + "competeInMiniGamesText": "Întrece-te în mini-jocuri începând de la curse până la zburat.", + "customize2Text": "Particularizează caractere, mini-jocuri, chiar și muzica jocului.", + "customizeText": "Particularizează-ți caracterele şi creează-ți listele de jocuri cu mini-jocuri cum vrei tu.", + "sportsMoreFunText": "Sporturile sunt mai distractive cu explozibile.", + "teamUpAgainstComputerText": "Fă echipă împotriva computerului." + }, + "storeText": "Magazin", + "submitText": "Trimite", + "submittingPromoCodeText": "Se trimite Codul...", + "teamNamesColorText": "Numele/Culorile Echipelor", + "telnetAccessGrantedText": "Acces la Telnet permis.", + "telnetAccessText": "Acces Telnet detectat; îl permiți?", + "testBuildErrorText": "Acesastă versiune de test nu mai este activă; te rog să cauți alta mai nouă.", + "testBuildText": "Versiune de Test", + "testBuildValidateErrorText": "Nu se poate valida versiunea de test. (fără conexiune la internet?)", + "testBuildValidatedText": "Versiune de Test validată; bucură-te de ea!", + "thankYouText": "Îți mulțumesc pentru suport! Bucură-te de joc!!", + "threeKillText": "TRIPLU-OMOR!!", + "timeBonusText": "Timp Bonus", + "timeElapsedText": "Timp Scurs", + "timeExpiredText": "Timp Expirat", + "timeSuffixDaysText": "${COUNT}z", + "timeSuffixHoursText": "${COUNT}o", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Sfat", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Prieteni de Top", + "tournamentCheckingStateText": "Se verifică starea campionatului; aşteaptă...", + "tournamentEndedText": "Acest turneu s-a terminat. Altul nou va începe în curând.", + "tournamentEntryText": "Prețul Pentru Intrare", + "tournamentResultsRecentText": "Rezultatele Recente ale Turneului", + "tournamentStandingsText": "Clasamentele Turneului", + "tournamentText": "Turneu", + "tournamentTimeExpiredText": "Timpul Turneului a Expirat", + "tournamentsText": "Turnee", + "translations": { + "characterNames": { + "Agent Johnson": "Agentul Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Oase", + "Butch": "Butch", + "Easter Bunny": "Iepurașul de Paște", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Norocosul", + "Mel": "Mel", + "Middle-Man": "Omul-Mijlociu", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Aruncătorul", + "Santa Claus": "Moş Crăciun", + "Snake Shadow": "Umbra Şarpelui", + "Spaz": "Spaz", + "Taobao Mascot": "Mascota Taobao", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "Antrenament pentru ${GAME}", + "Infinite ${GAME}": "${GAME} Infinit", + "Infinite Onslaught": "Măcel Infinit", + "Infinite Runaround": "Runaround Infinit", + "Onslaught Training": "Antrenament Măcel", + "Pro ${GAME}": "${GAME} Pro", + "Pro Football": "TouchDown Pro", + "Pro Onslaught": "Măcel Pro", + "Pro Runaround": "Runaround Pro", + "Rookie ${GAME}": "${GAME} Începător", + "Rookie Football": "TouchDown Începător", + "Rookie Onslaught": "Măcel Începător", + "The Last Stand": "Ultimul Rămas", + "Uber ${GAME}": "MEGA ${GAME}", + "Uber Football": "MEGA TouchDown", + "Uber Onslaught": "MEGA Măcel", + "Uber Runaround": "MEGA Runaround" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Fii cel ales pentru o perioadă de timp pentru a câştiga.\nOmoară alesul pentru a deveni tu acela.", + "Bomb as many targets as you can.": "Bombează cât mai multe ținte.", + "Carry the flag for ${ARG1} seconds.": "Ține steagul pentru ${ARG1} (de) secunde.", + "Carry the flag for a set length of time.": "Ține steagul pentru o perioadă anumită de timp.", + "Crush ${ARG1} of your enemies.": "Ucide ${ARG1} (de) inamici.", + "Defeat all enemies.": "Înfrânge toți inamicii.", + "Dodge the falling bombs.": "Ai grijă la bombe.", + "Final glorious epic slow motion battle to the death.": "Bătălie finală glorioasă până la moarte în slow motion epic .", + "Gather eggs!": "Adună ouăle!", + "Get the flag to the enemy end zone.": "Cară steagul către partea inamicilor.", + "How fast can you defeat the ninjas?": "Cât de rapid îi poți învinge pe ninja?", + "Kill a set number of enemies to win.": "Ucide un număr anumit de inamici pentru a câştiga.", + "Last one standing wins.": "Ultimul rămas în picioare câştigă.", + "Last remaining alive wins.": "Ultimul rămas în viață câştigă.", + "Last team standing wins.": "Ultima echipă rămasă în picioare câştigă.", + "Prevent enemies from reaching the exit.": "Nu lăsa inamicii să ajungă la sfârşit.", + "Reach the enemy flag to score.": "Atinge steagul inamicilor pentru a înscrie.", + "Return the enemy flag to score.": "Returnează steagul inamicilor pentru a puncta.", + "Run ${ARG1} laps.": "Fugi ${ARG1} ture.", + "Run ${ARG1} laps. Your entire team has to finish.": "Fugi ${ARG1} ture. Toată echipa ta trebuie să termine.", + "Run 1 lap.": "Fugi o tură.", + "Run 1 lap. Your entire team has to finish.": "Fugi o tură. Toată echipa ta trebuie să termine.", + "Run real fast!": "Fugi extrem de repede!", + "Score ${ARG1} goals.": "Înscrie ${ARG1} goluri.", + "Score ${ARG1} touchdowns.": "Înscrie ${ARG1} touchdown-uri.", + "Score a goal.": "Înscrie un gol.", + "Score a touchdown.": "Înscrie un touchdown.", + "Score some goals.": "Înscrie nişte goluri.", + "Secure all ${ARG1} flags.": "Cucereşte cele ${ARG1} steaguri.", + "Secure all flags on the map to win.": "Toate steagurile trebuiesc cucerite de echipa ta pentru a câştiga.", + "Secure the flag for ${ARG1} seconds.": "Ține steagul pentru ${ARG1} (de) secunde.", + "Secure the flag for a set length of time.": "Ține steagul pentru o perioadă anumită de timp.", + "Steal the enemy flag ${ARG1} times.": "Fură steagul inamicilor tăi de ${ARG1} ori.", + "Steal the enemy flag.": "Fură steagul inamicilor tăi.", + "There can be only one.": "Aici poate fi numai unul.", + "Touch the enemy flag ${ARG1} times.": "Atinge steagul inamic de ${ARG1} ori", + "Touch the enemy flag.": "Atinge steagul inamicilor.", + "carry the flag for ${ARG1} seconds": "ține steagul pentru ${ARG1} (de) secunde", + "kill ${ARG1} enemies": "omoară ${ARG1} (de) inamici", + "last one standing wins": "ultimul rămas în picioare câştigă", + "last team standing wins": "ultima echipă rămasă în picioare câştigă", + "return ${ARG1} flags": "returnează ${ARG1} steaguri", + "return 1 flag": "returnează un steag", + "run ${ARG1} laps": "fugi ${ARG1} ture", + "run 1 lap": "fugi o tură", + "score ${ARG1} goals": "înscrie ${ARG1} goluri", + "score ${ARG1} touchdowns": "înscrie ${ARG1} touchdown-uri", + "score a goal": "înscrie un gol", + "score a touchdown": "înscrie un touchdown", + "secure all ${ARG1} flags": "cucereşte cele ${ARG1} steaguri.", + "secure the flag for ${ARG1} seconds": "ține steagul pentru ${ARG1} (de) secunde", + "touch ${ARG1} flags": "atinge ${ARG1} steaguri", + "touch 1 flag": "atinge un steag" + }, + "gameNames": { + "Assault": "Asalt", + "Capture the Flag": "Capturează Steagul", + "Chosen One": "Alesul", + "Conquest": "Cucerire", + "Death Match": "Meciul Morții", + "Easter Egg Hunt": "Vânătoarea De Ouă", + "Elimination": "Eliminare", + "Football": "TouchDown", + "Hockey": "Hockey", + "Keep Away": "Stai Departe", + "King of the Hill": "Regele Dealului", + "Meteor Shower": "Ploaie de Meteoriți", + "Ninja Fight": "Luptă cu Ninja", + "Onslaught": "Măcel", + "Race": "Cursă", + "Runaround": "Runaround", + "Target Practice": "Antrenament pe Ținte", + "The Last Stand": "Ultimul Rămas" + }, + "inputDeviceNames": { + "Keyboard": "Tastatura", + "Keyboard P2": "Tastatura pentru P2" + }, + "languages": { + "Arabic": "Arabă", + "Belarussian": "Belarusă", + "Chinese": "Chineză (Simplificată)", + "ChineseTraditional": "Chineză (Tradițională)", + "Croatian": "Croată", + "Czech": "Cehă", + "Danish": "Daneză", + "Dutch": "Olandeză", + "English": "Engleză", + "Esperanto": "Esperanto", + "Filipino": "Filipineză", + "Finnish": "Finlandeză", + "French": "Franceză", + "German": "Germană", + "Gibberish": "Bolboroseală", + "Greek": "Greacă", + "Hindi": "Hindi", + "Hungarian": "Maghiară", + "Indonesian": "Indoneziană", + "Italian": "Italiană", + "Japanese": "Japoneză", + "Korean": "Coreană", + "Persian": "Persană", + "Polish": "Poloneză", + "Portuguese": "Portugheză", + "Romanian": "Română", + "Russian": "Rusă", + "Serbian": "Sârbă", + "Slovak": "Slovacă", + "Spanish": "Spaniolă", + "Swedish": "Suedeză", + "Tamil": "Tamilă", + "Thai": "Thailandeză", + "Turkish": "Turcă", + "Ukrainian": "Ucraineană", + "Venetian": "Venețiană", + "Vietnamese": "Vietnameză" + }, + "leagueNames": { + "Bronze": "Bronz", + "Diamond": "Diamant", + "Gold": "Aur", + "Silver": "Argint" + }, + "mapsNames": { + "Big G": "Marele G", + "Bridgit": "Podul", + "Courtyard": "Curtea", + "Crag Castle": "Castelul Crag", + "Doom Shroom": "Ciuperca Morții", + "Football Stadium": "Stadion de TouchDown", + "Happy Thoughts": "Amintiri Fericite", + "Hockey Stadium": "Stadion de Hockey", + "Lake Frigid": "Lacul Înghețat", + "Monkey Face": "Față de Maimuță", + "Rampage": "Nebunie", + "Roundabout": "Giratorii", + "Step Right Up": "Pășește-n sus", + "The Pad": "Placa", + "Tip Top": "De sus-n jos", + "Tower D": "Turnul D", + "Zigzag": "Zig zag" + }, + "playlistNames": { + "Just Epic": "Doar Slow Motion", + "Just Sports": "Doar Sporturi" + }, + "scoreNames": { + "Flags": "Steaguri", + "Goals": "Goluri", + "Score": "Scor", + "Survived": "Supraviețuit", + "Time": "Timp", + "Time Held": "Timp Ținut" + }, + "serverResponses": { + "A code has already been used on this account.": "Un cod a fost deja folosit pe acest cont.", + "A reward has already been given for that address.": "Un premiu a fost deja revendicat cu această adresă IP.", + "Account linking successful!": "Conectarea conturilor a fost reușită!", + "Account unlinking successful!": "Deconectarea contulurilor a fost reușită!", + "Accounts are already linked.": "Conturile sunt deja conectate între ele.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Vizualizarea reclamelor nu a putut fi verificată.\nTe rog să fii sigur că ai o versiune oficială și actualizată a jocului.", + "An error has occurred; (${ERROR})": "A intervenit o eroare; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "A intervenit o eroare; Te rog să contactezi asistența. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "A apărut o eroare; te rog să contactezi support@froemling.net.", + "An error has occurred; please try again later.": "O eroare a intervenit; te rog să încerci din nou mai târziu.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Eşti sigur că vrei să conectezi aceste 2 conturi între ele?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nAcest lucru nu este reversibil!", + "BombSquad Pro unlocked!": "Versiunea BombSquad Pro a fost deblocată!", + "Can't link 2 accounts of this type.": "Nu se pot conecta 2 conturi de acest fel.", + "Can't link 2 diamond league accounts.": "Nu se pot conecta 2 conturi cu liga de diamant.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Nu se poate conecta; s-ar depăși numărul maxim de ${COUNT} conturi conectate.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Ai fost detectat trișând; scorurile şi premiile vor fi suspendate timp de ${COUNT} (de) zile.", + "Could not establish a secure connection.": "Nu s-a putut stabili o conexiune sigură.", + "Daily maximum reached.": "Limită Zilnică Atinsă.", + "Entering tournament...": "Se intră în turneu...", + "Invalid code.": "Cod Invalid.", + "Invalid payment; purchase canceled.": "Plată invalidă; achiziționare anulată.", + "Invalid promo code.": "Cod promo invalid.", + "Invalid purchase.": "Achiziționare invalidă.", + "Invalid tournament entry; score will be ignored.": "Intrare invalidă în turneu; scorul tău va fi ignorat.", + "Item unlocked!": "Lucru deblocat!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "CONECTARE ÎNTRE CONTURI RESPINSĂ.Contul ${ACCOUNT} conține\ndate semnificative care ar putea FI PIERDUTE PE VECI.\nPoți să conectezi conturile în ordinea opusă acesteia dacă dorești\n(și să pierzi datele ACESTUI cont în locul celuilalt)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Îți legi progresul contului ${ACCOUNT} cu acest cont?\nTot progresul de pe ${ACCOUNT} va fi șters.\nAcest lucru nu poate fi reversibil. Ești sigur?", + "Max number of playlists reached.": "Numărul maxim de liste a fost atins.", + "Max number of profiles reached.": "Numărul maxim de profile a fost atins.", + "Maximum friend code rewards reached.": "Limita codurilor pentru prieteni a fost atinsă.", + "Message is too long.": "Mesajul este prea lung.", + "No servers are available. Please try again soon.": "Niciun server nu este disponibil. Încearcă din nou mai târziu.", + "Profile \"${NAME}\" upgraded successfully.": "Profilul \"${NAME}\" a fost îmbunătățit cu succes.", + "Profile could not be upgraded.": "Profilul nu a putut fi îmbunătățit.", + "Purchase successful!": "Achiziționare reuşită!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Ai primit ${COUNT} (de) bilete pentru conectare.\nRevino mâine pentru a primi ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Serverele nu mai sunt suportate în această versiune a jocului;\nTe rog să actualizezi jocul la o versiune mai nouă.", + "Sorry, there are no uses remaining on this code.": "Scuze, dar codul nu mai poate fi folosit.", + "Sorry, this code has already been used.": "Scuze, dar codul acesta a fost deja folosit.", + "Sorry, this code has expired.": "Scuze, dar acest cod a expirat.", + "Sorry, this code only works for new accounts.": "Scuze, dar acest cod merge numai pentru jucătorii cu conturi noi.", + "Still searching for nearby servers; please try again soon.": "Încă se caută servere din apropiere; te rog să încerci din nou într-un moment.", + "Temporarily unavailable; please try again later.": "Nevalabil temporar; te rog să încerci din nou mai târziu.", + "The tournament ended before you finished.": "Turneul s-a sfârşit înainte să-l termini.", + "This account cannot be unlinked for ${NUM} days.": "Acest cont nu poate fi deconectat timp de ${NUM} (de) zile.", + "This code cannot be used on the account that created it.": "Acest cod nu poate fi folosit pe contul pe care l-a creat.", + "This is currently unavailable; please try again later.": "Nevalabil momentan; te rog să încerci din nou mai târziu.", + "This requires version ${VERSION} or newer.": "Acest lucru este valabil numai de la versiunea ${VERSION} până la cea curentă.", + "Tournaments disabled due to rooted device.": "Turneele sunt dezactivate deoarece dispozitivul este înrădăcinat (rootat).", + "Tournaments require ${VERSION} or newer": "Turneele sunt valabile de la versiunea ${VERSION} în sus", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Deconectezi contul ${ACCOUNT} de la acest cont?\nTot progresul de pe ${ACCOUNT} va fi resetat.\n(exceptând realizările în unele cazuri)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ADVERTISMENT: Reclamații cum că ai fost acuzat de trișat/hackuit au fost legate de contul tău.\nConturile persoanelor prinse trișând/hackuind vor fi restricționate. Te rog să joci cinstit.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Ai dori să îți conectezi contul tău de pe dispozitiv cu acesta?\n\nContul tău de pe dispozitiv este ${ACCOUNT1}\nAcest cont este ${ACCOUNT2}\n\nAcest lucru îți va salva progresul existent.\nAtenție: acest lucru nu poate fi reversibil!", + "You already own this!": "Deja ai acest lucru!", + "You can join in ${COUNT} seconds.": "Poți reintra în ${COUNT} secunde.", + "You don't have enough tickets for this!": "Nu ai destule bilete pentru acest lucru!", + "You don't own that.": "Nu deți asta.", + "You got ${COUNT} tickets!": "Ai primit ${COUNT} (de) bilete!", + "You got a ${ITEM}!": "Ai primit 1 ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Ai fost promovat la o ligă noua; felicitări!", + "You must update to a newer version of the app to do this.": "Trebuie să-ți actualizezi aplicația la o versiune mai nouă pentru a face asta.", + "You must update to the newest version of the game to do this.": "Trebuie să-ți actualizezi jocul la o versiune mai nouă pentru a face asta.", + "You must wait a few seconds before entering a new code.": "Va trebui să aştepți câteva secunde înainte să introduci un cod nou.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ai avut rankul #${RANK} în ultimul campionat. Mulțumesc pentru participare!", + "Your account was rejected. Are you signed in?": "Contul tău a fost respins. Ești conectat?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Copia ta de joc deținută a fost modificată.\nTe rog să treci la normal orice schimbare făcută şi să încerci din nou.", + "Your friend code was used by ${ACCOUNT}": "${ACCOUNT} a folosit codul tău de prieten" + }, + "settingNames": { + "1 Minute": "Un minut", + "1 Second": "O secundă", + "10 Minutes": "10 Minute", + "2 Minutes": "2 Minute", + "2 Seconds": "2 Secunde", + "20 Minutes": "20 De Minute", + "4 Seconds": "4 Secunde", + "5 Minutes": "5 Minute", + "8 Seconds": "8 Secunde", + "Allow Negative Scores": "Permite Scorurile Negative", + "Balance Total Lives": "Balansează Numărul De Vieți", + "Bomb Spawning": "Spaunarea Bombelor", + "Chosen One Gets Gloves": "Alesul Primește Mănuși", + "Chosen One Gets Shield": "Alesul Primește Un Scut", + "Chosen One Time": "Timpul Alesului", + "Enable Impact Bombs": "Folosește Bombele cu Impact", + "Enable Triple Bombs": "Permite Bombele Triple", + "Entire Team Must Finish": "Toată Echipa Ta Trebuie Să Termine", + "Epic Mode": "Modul Epic", + "Flag Idle Return Time": "Timp Pentru Readucerea Steagului Neatins La Bază", + "Flag Touch Return Time": "Timp Pentru Readucerea Steagului Atins La Bază", + "Hold Time": "Timp de Ținut", + "Kills to Win Per Player": "Omoruri Pe Echipă/Jucător Pentru a Câștiga", + "Laps": "Ture", + "Lives Per Player": "Vieți Pe Jucător", + "Long": "Lung", + "Longer": "Foarte Lung", + "Mine Spawning": "Spaunarea Minelor", + "No Mines": "Fără Mine", + "None": "Niciuna", + "Normal": "Normal", + "Pro Mode": "Modul Profesionist", + "Respawn Times": "Timp de Revenire", + "Score to Win": "Înscrieri Pentru a Câştiga", + "Short": "Scurt", + "Shorter": "Foarte Scurt", + "Solo Mode": "Modul Solo", + "Target Count": "Număr de Ținte", + "Time Limit": "Limită de Timp" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "Echipa ${TEAM} este descalificată deoarece ${PLAYER} a ieșit", + "Killing ${NAME} for skipping part of the track!": "${NAME} a murit deoarece a luat o scurtătură!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Atenție, ${NAME}: Apăsatul turbo / spamatul butoanelor te pune la pământ." + }, + "teamNames": { + "Bad Guys": "Tipii Răi", + "Blue": "Albastru", + "Good Guys": "Tipii Buni", + "Red": "Roșu" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "O lovitură alergat-sărit-rotit-pumn perfect sincronizată poate omorî\npe cineva dintr-o singură lovitură și-ți poate câștiga respectul prietenilor.", + "Always remember to floss.": "Nu uita să te speli pe dinți!", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Creează profile de jucător pentru tine şi prietenii tăi cu numele şi\ncaracterele voastre preferate în loc să le folosiți pe cele generate automat.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Blestemele te transformă înntr-o bombă cu ceas.\nSingurul remediu este de a prinde rapid o trusă de prim-ajutor.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Nu te lăsa păcălit de aparențele caracterelor pe care le poți cumpăra din magazin,\ntoate au abilități identice, așa că alege-ți unul cu care te asemeni cel mai mult.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Nu te împăuna cu scutul ăla de energie; tot poți fi aruncat de pe hărți.", + "Don't run all the time. Really. You will fall off cliffs.": "Nu fugi tot timpul. Pe bune. Vei cădea de pe hărți.", + "Don't spin for too long; you'll become dizzy and fall.": "Nu te învârti prea mult timp; vei ameți și vei fi pus la pământ.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Ține apăsat orice buton pentru a fugi. (Butoanele 'Trigger' funcționează bine şi ele dacă le ai)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Pentru a fugi, ține apăsat orice buton. Vei ajunge mai repede unde vrei,\ndar nu vei lua curba prea bine, așa că ai grijă să nu cazi de pe hărți.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Bombele de gheață nu sunt foarte puternice, dar îngheață\npe oricine lovesc, lăsând victimele vulnerabile la spargere.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Dacă cineva te ia pe sus, dă-i un pumn și îți va da drumul.\n (Apropo, merge și în viața reală)", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Dacă nu ai destule controllere, instalează aplicația '${REMOTE_APP_NAME}' \npe dispozitivele tale mobile pentru a le folosi drept controllere.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Dacă nu ai destule controllere, instalează 'BombSquad Remote' pe\nun dispozitiv Android sau iOS pentru a-l folosi ca pe un controller.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Dacă se atinge vreodată o bombă lipicioasă de tine, sari și rotește-te în cercuri. S-ar putea \nsă scapi de aceasta, dar dacă nu, vei face un spectacol minunat din ultimele tale momente rămase în viață.", + "If you kill an enemy in one hit you get double points for it.": "Dacă omori un inamic dintr-o singură lovitură vei primi puncte duble.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Dacă atingi un blestem, singura ta şansă de a trăi este să\nprinzi o trusă de prim-ajutor în următoarele 5 secunde.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Dacă stai într-un singur loc, vei muri ca un fraier. Ferește-te și aleargă din loc în loc pentru a supraviețui..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Dacă sunt foarte mulți jucători care intră și devin inactivi,\nbifează caseta 'Dă Afară Jucătorii Inactivi' din Setări în caz că cineva uită să iasă din joc.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Dacă dispozitivul tău se încălzeşte prea rapid sau ai vrea să-i conservi bateria,\ndu-te în meniul de \"Vizuale\" sau \"Rezoluție\" în Setări -> Grafici și dă-le la un nivel mai slab.", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Dacă jocul nu rulează chiar așa de bine cum ar trebui, \nîncearcă să lași mai jos rezoluția sau vizualele din setările grafice ale jocului.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "În Capturează-Steagul, steagul tău trebuie să fie la baza echipei tale pentru a înscrie. Dacă\nechipa opusă e pe cale să înscrie, o bună opțiune pentru a-i opri din a face asta este să le furi steagul.", + "In hockey, you'll maintain more speed if you turn gradually.": "În Hockey, vei menține mai multă viteză dacă te întorci când trebuie.", + "It's easier to win with a friend or two helping.": "E mai ușor să câștigi cu un prieten sau 2 care te ajută.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Sari imediat ce arunci bombele pentru a le trimite către cele mai înalte nivele.", + "Land-mines are a good way to stop speedy enemies.": "Minele sunt folositoare la oprirea inamicilor rapizi.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Multe lucruri pot fi ridicate şi aruncate, inclusiv alți jucători. Aruncarea\ninamicilor de pe hărți poate fi o strategie efectivă şi plină de emoții.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nu, nu te poți urca pe platformă. Trebuie să arunci cu bombele înspre inamici.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Jucătorii pot să intre și să iasă din majoritatea jocurilor când vor ei,\nși nu uita că poți conecta și deconecta controllere când vrei tu.", + "Practice using your momentum to throw bombs more accurately.": "Antrenează-te folosindu-ți momentum-ul pentru a arunca bombele mai corect.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Pumnii tăi cauzează mai multe daune când te mişti,\ndeci încearcă să fugi, să sari, şi să te învârți ca un nebun.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Mergi în față şi în spate înainte să arunci o bombă\npentru a o 'învârti', aruncând-o mai departe.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Omoară un grup de inamici cu ajutorul\nunei bombe lângă o cutie cu TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Capul este cea mai vulnerabilă parte a corpului tău, \ndeci o bombă lipicioasă în ceafă înseamnă game-over.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Acest nivel nu se termină niciodată, dar un scor mare\nîn acesta îți poate aduce foarte mult respect prin lume.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Puterea aruncării este bazată pe direcția ținută de tine.\nDacă vrei să arunci ceva în fața ta ușurel, va trebui să nu ții nici o direcție și să dai drumul obiectului respectiv.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Te-ai săturat de muzica originală din joc? Schimb-o cu a ta!\n Vezi Setări -> Audio -> Soundtrack Personalizat", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Încearcă să ții bombele în mână pentru o secundă sau două înainte să le arunci.", + "Try tricking enemies into killing eachother or running off cliffs.": "Încearcă să-ți păcăleşti inamicii în așa fel încât aceștia încep să se omoare între ei sau să cadă de pe hărți.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Foloseşte butonul de ridicare < ${PICKUP} > pentru a ridica steagul", + "Whip back and forth to get more distance on your throws..": "Mergi în spate și în față pentru a arunca lucrurile la o distanță mai mare..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Poți să 'țintești' cu pumnii rotindu-te la stânga și la dreapta.\nAcest lucru este folositor pentru a da tipii răi jos de pe marginile hărților sau pentru a înscrie în hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Poți să îți dai seama când o bombă va exploda după culoarea\nscânteilor făcute de fitilul acesteia: galben..portocaliu..roşu..*BOOM*.", + "You can throw bombs higher if you jump just before throwing.": "Poți arunca bombe mai sus dacă le arunci imediat după ce sari.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Iei daune când îți trânteşti capul de lucruri,\ndeci încearcă să nu-ți trântești capul de lucruri.", + "Your punches do much more damage if you are running or spinning.": "Pumnii tăi dau mai multe daune dacă fugi sau te învârți." + } + }, + "trophiesRequiredText": "Acest lucru necesită cel puțin ${NUMBER} trofee.", + "trophiesText": "Trofee", + "trophiesThisSeasonText": "Trofeele Din Acest Sezon", + "tutorial": { + "cpuBenchmarkText": "Se rulează tutorialul la o viteză ridicolă (în principal testează viteza CPU-ului)", + "phrase01Text": "Salut!", + "phrase02Text": "Bun venit în ${APP_NAME}!", + "phrase03Text": "Uite niște sfaturi pentru a-ți controla caracterul:", + "phrase04Text": "Multe lucruri din ${APP_NAME} sunt bazate pe FIZICĂ.", + "phrase05Text": "De exemplu, când dai cu pumnul...", + "phrase06Text": "...daunele sunt bazate pe viteza pumnilor tăi.", + "phrase07Text": "Vezi? Nu ne mișcăm, deci ${NAME} de-abia dacă a simțit ceva.", + "phrase08Text": "Acum hai să sărim și să ne rotim pentru a avea o viteză mai mare.", + "phrase09Text": "Aha, așa mai merge.", + "phrase10Text": "De asemenea, și alergatul ajută.", + "phrase11Text": "Ține apăsat ORICE buton pentru a alerga.", + "phrase12Text": "Pentru lovituri super-puternice, încearcă să te rotești și să fugi.", + "phrase13Text": "Ups; scuze pentru asta, ${NAME}.", + "phrase14Text": "Poți ridica și arunca obiecte cum ar fi steaguri... sau îl poți arunca pe ${NAME}.", + "phrase15Text": "În final, sunt bombele.", + "phrase16Text": "Aruncatul lor are nevoie de antrenament.", + "phrase17Text": "Au! Nu a fost o aruncare chiar bună.", + "phrase18Text": "Mișcatul te ajută să le arunci mai departe.", + "phrase19Text": "Săritul te ajută să le arunci mai sus.", + "phrase20Text": "Iar învârtirea lor te ajută să le arunci și mai departe.", + "phrase21Text": "Cronometrarea bombelor poate fi complicată.", + "phrase22Text": "Fir-ar să fie!", + "phrase23Text": "Încearcă să lași fitilul să ardă pentru un moment.", + "phrase24Text": "Ura! Bine ars.", + "phrase25Text": "Păi, cam asta-i tot.", + "phrase26Text": "Acu' ia-i, tigrule!", + "phrase27Text": "Ține minte antrenamentul și vei supraviețui!", + "phrase28Text": "...probabil...", + "phrase29Text": "Mult Noroc!", + "randomName1Text": "Vasile", + "randomName2Text": "David", + "randomName3Text": "Florin", + "randomName4Text": "Marius", + "randomName5Text": "Ștefan", + "skipConfirmText": "Sigur vrei să treci peste tutorial? Apasă din nou orice buton pentru a confirma.", + "skipVoteCountText": "${COUNT}/${TOTAL} voturi pentru a trece peste tutorial", + "skippingText": "Se trece peste tutorial...", + "toSkipPressAnythingText": "(apasă orice buton pentru a trece peste tutorial)" + }, + "twoKillText": "DUBLU OMOR!", + "unavailableText": "indisponibil", + "unconfiguredControllerDetectedText": "Controller neconfigurat detectat:", + "unlockThisInTheStoreText": "Acest lucru trebuie deblocat din magazin.", + "unlockThisProfilesText": "Că să creezi mai mult de ${NUM} profile, va trebui să ai:", + "unlockThisText": "Pentru a debloca acest lucru, vei avea nevoie de:", + "unsupportedHardwareText": "Scuze, acest hardware nu este suportat de această versiune a jocului.", + "upFirstText": "Primul joc:", + "upNextText": "Următorul joc cu numărul ${COUNT} este:", + "updatingAccountText": "Se îmbunătățeşte contul tău...", + "upgradeText": "Îmbunătățeşte", + "upgradeToPlayText": "Deblochează \"${PRO}\" în magazinul din joc pentru a juca această hartă.", + "useDefaultText": "Folosește Setările Prestabilite", + "usesExternalControllerText": "Acest joc folosește un controller extern ca dispozitiv de intrare.", + "usingItunesText": "Se folosește Aplicația de Muzică pentru soundtrack...", + "usingItunesTurnRepeatAndShuffleOnText": "Fii sigur(ă) că shuffle e activat și repeat e pus pe ALL în iTunes.", + "validatingTestBuildText": "Se Validează Versiunea De Test...", + "victoryText": "Victorie!", + "voteDelayText": "Poți începe alt vot peste ${NUMBER} (de) secunde", + "voteInProgressText": "Un vot este deja în progres.", + "votedAlreadyText": "Ai votat deja", + "votesNeededText": "${NUMBER} voturi necesare", + "vsText": "vs", + "waitingForHostText": "(așteaptă ca ${HOST} să continue)", + "waitingForPlayersText": "se așteaptă pentru jucători noi...", + "waitingInLineText": "Așteaptă la coadă (server-ul este plin)...", + "watchAVideoText": "Uită-te la o Reclamă", + "watchAnAdText": "Uită-te la o Reclamă", + "watchWindow": { + "deleteConfirmText": "Sigur vrei să ștergi reluarea \"${REPLAY}\"?", + "deleteReplayButtonText": "Șterge\nReluarea", + "myReplaysText": "Reluările mele", + "noReplaySelectedErrorText": "Nicio Reluare Selectată", + "playbackSpeedText": "Viteză de redare: ${SPEED}", + "renameReplayButtonText": "Redenumește\nReluarea", + "renameReplayText": "Redenumește \"${REPLAY}\" în:", + "renameText": "Redenumește", + "replayDeleteErrorText": "Eroare la ștergerea reluării.", + "replayNameText": "Numele reluării", + "replayRenameErrorAlreadyExistsText": "O reluare cu acel nume deja există.", + "replayRenameErrorInvalidName": "Nu se poate redenumi reluarea; numele este invalid.", + "replayRenameErrorText": "Eroare la redenumirea reluării.", + "sharedReplaysText": "Reluări împărțite cu alții", + "titleText": "Vizionează", + "watchReplayButtonText": "Vezi\nReluarea" + }, + "waveText": "Valul", + "wellSureText": "Sigur!", + "wiimoteLicenseWindow": { + "titleText": "Copyright de către DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "Se ascultă pentru Wiimote-uri...", + "pressText": "Apasă butoanele 1 și 2 de pe wiimote în același timp.", + "pressText2": "Pe Wiimote-urile noi cu Motion Plus, apasă butonul roșu 'sync' de pe spatele acestora.", + "pressTextScale": 1.0 + }, + "wiimoteSetupWindow": { + "copyrightText": "Copyright de către DarwiinRemote", + "listenText": "Ascultă", + "macInstructionsText": "Asigură-te că Wii-ul tău este închis și Bluetooth-ul este activat\npe Mac, apoi apasă pe 'Listen'. Suportul Wiimote e cam\nslab, deci s-ar putea să fie nevoie să încerci de câteva\nori până să meargă.\n\nBluetooth-ul ar trebui să permită până la 7 dispozitive conectate,\nînsă acest număr poate varia de la un dispozitiv la altul.\n\nBombSquad suportă Wiimote-urile, Nunchuck-urile originale\nși Controllerul Clasic.\nNoul Wii Remote Plus funcționează și el,\nînsă fără atașamente.", + "thanksText": "Multe mulțumiri către echipa DarwiinRemote pentru\ncă au făcut acest lucru posibil.", + "titleText": "Setarea Wiimote-ului" + }, + "winsPlayerText": "${NAME} Câștigă!", + "winsTeamText": "${NAME} Câștigă!", + "winsText": "${NAME} Câștigă!", + "workspaceSyncErrorText": "Nu s-a putut sincroniza ${WORKSPACE}. Vezi jurnalul de activități pentru detalii.", + "workspaceSyncReuseText": "Nu se poate sincroniza ${WORKSPACE}. Se va folosi ultima versiune sincronizată.", + "worldScoresUnavailableText": "Scorurile globale sunt indisponibile.", + "worldsBestScoresText": "Top Scoruri Mondiale", + "worldsBestTimesText": "Top Timpi Mondiali", + "xbox360ControllersWindow": { + "getDriverText": "Instalează Driver-ul.", + "macInstructions2Text": "Pentru a folosi controllerele fără fir, vei avea nevoie de un receptor\ncare vine cu pachetul 'Xbox 360 Wireless Controller for Windows'.\nFiecare receptor te lasă să conectezi până la 4 controllere.\n\nImportant: Receptoare de tip 3rd-party nu vor funcționa cu acest driver;\nAsigură-te că pe receptor scrie 'Microsoft', nu 'XBOX 360'.\nMicrosoft nu mai le vinde separat, deci va trebui să iei unul\nîmpreună cu controllerul sau de pe un site, cum ar fi Ebay.\n\nDacă ai găsit acest mesaj folositor, consideră faptul să-i donezi programatorului\ndriverului pe site-ul lui.", + "macInstructionsText": "Pentru a folosi controllere de Xbox 360, va trebui să instalezi \ndriver-ul pentru Mac disponibil din link-ul de mai jos. \nFuncționează pentru controalele cu/fără fir.", + "ouyaInstructionsText": "Pentru a folosi controllere de Xbox 360 cu fir, pur și simplu\nconectează-le la un port USB. Poți folosi un USB-hub pentru a\nconecta mai multe controllere.\n\nPentru a folosi controllere fără fir vei avea nevoie de un receptor\nwireless, valabil ca parte a pachetului \"Xbox 360 wireless controller\nfor Windows\" sau vândut separat. Fiecare receptor intră într-un port\nUSB și te lasă să conectezi până la 4 controllere.", + "titleText": "Se folosesc controllere de Xbox 360 cu ${APP_NAME}:" + }, + "yesAllowText": "Da, Permite!", + "yourBestScoresText": "Cele Mai Bune Scoruri Ale Tale", + "yourBestTimesText": "Cei Mai Buni Timpi Ai Tăi" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/russian.json b/dist/ba_data/data/languages/russian.json new file mode 100644 index 0000000..6c28592 --- /dev/null +++ b/dist/ba_data/data/languages/russian.json @@ -0,0 +1,1985 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Имена аккаунтов не могут содержать эмодзи или другие специальные символы", + "accountProfileText": "(профиль)", + "accountsText": "Аккаунты", + "achievementProgressText": "Достижения: ${COUNT} из ${TOTAL}", + "campaignProgressText": "Прогресс кампании [Сложный режим]: ${PROGRESS}", + "changeOncePerSeason": "Вы можете изменить это только раз в сезон.", + "changeOncePerSeasonError": "Вы должны подождать до следующего сезона, чтобы изменить это снова (${NUM} дней)", + "customName": "Имя аккаунта", + "deviceSpecificAccountText": "Сейчас используется аккаунт имениустройства: ${NAME}", + "googlePlayGamesAccountSwitchText": "Если хотите сменить внутриигровой аккаунт Google, используйте приложение Google Play.", + "linkAccountsEnterCodeText": "Введите код", + "linkAccountsGenerateCodeText": "Сгенерировать код", + "linkAccountsInfoText": "(делиться достижениями с другими платформами)", + "linkAccountsInstructionsNewText": "Чтобы связать два аккаунта, сгенерируйте код на первом\nи введите этот код на втором. Данные из\nвторого аккаунта будут распределены между ними.\n(Данные из первого будут потеряны)\n\nВы можете связать ${COUNT} аккаунтов.\n\nВАЖНО: связывайте только собственные аккаунты;\nЕсли вы свяжетесь с аккаунтами друзей, вы не сможете\nодновременно играть онлайн.", + "linkAccountsInstructionsText": "Для связки двух аккаунтов, создайте код на одном\nиз них и введите код на другом.\nПрогресс и инвентарь будут объединены.\nВы можете связать до ${COUNT} аккаунтов.", + "linkAccountsText": "Связать акаунты", + "linkedAccountsText": "Привязанные аккаунты:", + "manageAccountText": "Управление аккаунтом", + "nameChangeConfirm": "Вы уверены, что хотите сменить имя аккаунта на ${NAME}?", + "notLoggedInText": "<не авторизован>", + "resetProgressConfirmNoAchievementsText": "Это сбросит весь ваш кооперативный прогресс\nи локальные рекорды (но не билеты).\nЭтот процесс необратим. Вы уверены?", + "resetProgressConfirmText": "Это сбросит весь ваш кооперативный\nпрогресс, достижения и локальные рекорды\n(кроме билетов). Этот процесс необратим.\nВы уверены?", + "resetProgressText": "Сбросить прогресс", + "setAccountName": "Задать имя аккаунта", + "setAccountNameDesc": "Выберите имя для отображения своего аккаунта.\nВы можете использовать имя одного из ваших связанных аккаунтов или создать уникальное имя аккаунта.", + "signInInfoText": "Войдите в аккаунт, чтобы собирать билеты, \nсоревноваться онлайн и делиться успехами.", + "signInText": "Войти", + "signInWithDeviceInfoText": "(стандартный аккаунт только для этого устройства)", + "signInWithDeviceText": "Войти через аккаунт устройства", + "signInWithGameCircleText": "Войти через Game Circle", + "signInWithGooglePlayText": "Войти через Google Play", + "signInWithTestAccountInfoText": "(устаревший тип аккаунта; в дальнейшем используйте аккаунт устройства)", + "signInWithTestAccountText": "Войти через тестовый аккаунт", + "signInWithV2InfoText": "(аккаунт, который работает на всех платформах)", + "signInWithV2Text": "Войти через аккаунт BombSquad", + "signOutText": "Выйти", + "signingInText": "Вход...", + "signingOutText": "Выход...", + "testAccountWarningCardboardText": "Внимание: вы подписываете в с \"тест\" счета.\nЭти данные будут заменены со счетами Google сразу\nони становятся поддерживается в картонные приложений.\n\nСейчас вы будете зарабатывать все билеты в игре.\n(вы , тем не менее , получить Pro обновление BombSquad бесплатно )", + "testAccountWarningOculusText": "Внимание: вы входите под акканутом \"test\".\nОни будут заменены аккаунтами Oculus позже в этом\nгоду, что позволит совершать покупки билетов и многое другое.\n\nНа данный момент вам придется зарабатывать билеты в игре.\n(однако, вы получаете обновление BombSquad Pro бесплатно)", + "testAccountWarningText": "Внимание: вы заходите под аккаунтом \"test\".\nЭтот аккаунт привязан к конкретному устройству и может\nпериодически сбрасываться. (так что лучше особо\nне тратить время на сбор/разблокировку добра в нем)\n\nЧтобы использовать настоящий аккаунт (Game-Center,\nGoogle Plus и т.д.), запустите платную версию. Это также\nпозволит сохранять свой прогресс в облаке и делать его\nдоступным для разных устройств.", + "ticketsText": "Количество билетов: ${COUNT}", + "titleText": "Аккаунт", + "unlinkAccountsInstructionsText": "Выберите аккаунт, который хотите отвязать", + "unlinkAccountsText": "Отвязать аккаунты", + "unlinkLegacyV1AccountsText": "Разблокируйте устаревшие (V1) аккаунты", + "v2LinkInstructionsText": "Используйте эту ссылку чтобы создать аккаунт или войти", + "viaAccount": "(через аккаунт ${NAME})", + "youAreLoggedInAsText": "Вы зашли как:", + "youAreSignedInAsText": "Вы вошли как:" + }, + "achievementChallengesText": "Достижения", + "achievementText": "Достижение", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Убейте 3 негодяев с помощью TNT", + "descriptionComplete": "С помощью TNT убито 3 негодяев", + "descriptionFull": "Убейте 3 негодяев с помощью TNT на уровне ${LEVEL}", + "descriptionFullComplete": "3 негодяя убито с помощью TNT на уровне ${LEVEL}", + "name": "Динамит делает “БУМ”!" + }, + "Boxer": { + "description": "Победите без использования бомб", + "descriptionComplete": "Победа без использования бомб", + "descriptionFull": "Завершите уровень ${LEVEL} без использования бомб", + "descriptionFullComplete": "Уровень ${LEVEL} завершен без использвания бомб", + "name": "Боксёр" + }, + "Dual Wielding": { + "descriptionFull": "Соединить 2 контроллера (аппарат или приложение)", + "descriptionFullComplete": "Соединено 2 контроллера (аппарат или приложение)", + "name": "Пáрное оружие" + }, + "Flawless Victory": { + "description": "Победите не получив урона", + "descriptionComplete": "Победа без получения урона", + "descriptionFull": "Пройдите уровень ${LEVEL} не получив урона", + "descriptionFullComplete": "Уровень ${LEVEL} пройден без урона", + "name": "Чистая победа" + }, + "Free Loader": { + "descriptionFull": "Начать игру “Каждый сам за себя” с 2 и более игроками", + "descriptionFullComplete": "Начата игра “Каждый сам за себя” с 2 и более игроками", + "name": "Один в поле воин" + }, + "Gold Miner": { + "description": "Убейте 6 негодяев с помощью мин", + "descriptionComplete": "С помощью мин убито 6 негодяев", + "descriptionFull": "Убейте 6 негодяев с помощью мин на уровне ${LEVEL}", + "descriptionFullComplete": "6 негодяев убито с помощью мин на уровне ${LEVEL}", + "name": "Сапер-чемпион" + }, + "Got the Moves": { + "description": "Победите без ударов и бомб", + "descriptionComplete": "Победа без ударов и бомб", + "descriptionFull": "Победите уровень ${LEVEL} без ударов и бомб", + "descriptionFullComplete": "Победа на уровне ${LEVEL} без ударов и бомб", + "name": "Точные движения" + }, + "In Control": { + "descriptionFull": "Присоедините контроллер (аппарат или приложение)", + "descriptionFullComplete": "Подсоединен контроллер. (аппарат или приложение)", + "name": "Все под контролем" + }, + "Last Stand God": { + "description": "Наберите 1000 очков", + "descriptionComplete": "Набрано 1000 очков", + "descriptionFull": "Наберите 1000 очков на уровне ${LEVEL}", + "descriptionFullComplete": "Набрано 1000 очков на уровне ${LEVEL}", + "name": "Бог уровня ${LEVEL}" + }, + "Last Stand Master": { + "description": "Наберите 250 очков", + "descriptionComplete": "Набрано 250 очков", + "descriptionFull": "Наберите 250 очков на уровне ${LEVEL}", + "descriptionFullComplete": "250 очков набрано на уровне ${LEVEL}", + "name": "Мастер уровня ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Наберите 500 очков", + "descriptionComplete": "Набрано 500 очков", + "descriptionFull": "Наберите 500 очков на уровне ${LEVEL}", + "descriptionFullComplete": "500 очков набрано на уровне ${LEVEL}", + "name": "Волшебник уровня ${LEVEL}" + }, + "Mine Games": { + "description": "Убейте 3 плохих парней с помощью мин", + "descriptionComplete": "С помощью мин убито 3 негодяя", + "descriptionFull": "Убейте 3 негодяев с помощью мин на уровне ${LEVEL}", + "descriptionFullComplete": "С помощью мин убито 3 негодяя на уровне ${LEVEL}", + "name": "Игры с минами" + }, + "Off You Go Then": { + "description": "Сбросьте 3 негодяев с карты", + "descriptionComplete": "С карты сброшено 3 негодяя", + "descriptionFull": "Сбросьте 3 негодяев с карты на уровне ${LEVEL}", + "descriptionFullComplete": "3 негодяя сброшено с карты на уровне ${LEVEL}", + "name": "Пора учится летать" + }, + "Onslaught God": { + "description": "Наберите 5000 очков", + "descriptionComplete": "Набрано 5000 очков", + "descriptionFull": "Наберите 5000 очков на уровне ${LEVEL}", + "descriptionFullComplete": "5000 очков набрано на уровне ${LEVEL}", + "name": "Бог уровня ${LEVEL}" + }, + "Onslaught Master": { + "description": "Наберите 500 очков", + "descriptionComplete": "Набрано 500 очков", + "descriptionFull": "Наберите 500 очков на уровне ${LEVEL}", + "descriptionFullComplete": "500 очков набрано на уровне ${LEVEL}", + "name": "Мастер уровня ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Победите все волны", + "descriptionComplete": "Побеждены все волны", + "descriptionFull": "Победите все волны на уровне ${LEVEL}", + "descriptionFullComplete": "Все волны побеждены на уровне ${LEVEL}", + "name": "Победа на уровне ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Наберите 1000 очков", + "descriptionComplete": "Набрано 1000 очков", + "descriptionFull": "Наберите 1000 очков на уровне ${LEVEL}", + "descriptionFullComplete": "1000 очков набрано на уровне ${LEVEL}", + "name": "Волшебник уровня ${LEVEL}" + }, + "Precision Bombing": { + "description": "Победите без усилителей", + "descriptionComplete": "Победа без усилителей", + "descriptionFull": "Победите уровень ${LEVEL} без усилителей", + "descriptionFullComplete": "Победа на уровне ${LEVEL} без усилителей", + "name": "Прицельное бомбометание" + }, + "Pro Boxer": { + "description": "Победите без использования бомб", + "descriptionComplete": "Победа без использования бомб", + "descriptionFull": "Пройдите уровень ${LEVEL} без использования бомб", + "descriptionFullComplete": "Уровень ${LEVEL} пройден без использования бомб", + "name": "Боксёр-профи" + }, + "Pro Football Shutout": { + "description": "Победите всухую", + "descriptionComplete": "Уровень был пройден всухую", + "descriptionFull": "Выиграйте матч ${LEVEL} всухую", + "descriptionFullComplete": "Победа в матче ${LEVEL} всухую", + "name": "${LEVEL} всухую" + }, + "Pro Football Victory": { + "description": "Выиграйте матч", + "descriptionComplete": "Матч выигран", + "descriptionFull": "Выиграйте матч ${LEVEL}", + "descriptionFullComplete": "Выигран матч ${LEVEL}", + "name": "Победа на уровне ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Победите все волны", + "descriptionComplete": "Пройдены все волны", + "descriptionFull": "Победите все волны на уровне ${LEVEL}", + "descriptionFullComplete": "Пройдены все волны на ${LEVEL}", + "name": "Победа на уровне ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Пройдите все волны", + "descriptionComplete": "Пройдены все волны", + "descriptionFull": "Пройдите все волны на уровне ${LEVEL}", + "descriptionFullComplete": "Пройдены все волны на уровне ${LEVEL}", + "name": "Победа на уровне ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Выиграйте всухую", + "descriptionComplete": "Победа всухую", + "descriptionFull": "Выиграйте матч ${LEVEL}, всухую", + "descriptionFullComplete": "Победа в матче ${LEVEL} всухую", + "name": "${LEVEL} всухую" + }, + "Rookie Football Victory": { + "description": "Выиграйте матч", + "descriptionComplete": "Матч пройден в вашу пользу", + "descriptionFull": "Выиграйте матч ${LEVEL}", + "descriptionFullComplete": "Выигран матч ${LEVEL}", + "name": "Победа в матче ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Победите все волны", + "descriptionComplete": "Побеждены все волны", + "descriptionFull": "Победите все волны уровня ${LEVEL}", + "descriptionFullComplete": "Побеждены все волны уровня ${LEVEL}", + "name": "Победа на уровне ${LEVEL}" + }, + "Runaround God": { + "description": "Заработайте 2000 очков", + "descriptionComplete": "Заработано 2000 очков", + "descriptionFull": "Наберите 2000 очков на уровне ${LEVEL}", + "descriptionFullComplete": "2000 очков набрано на уровне ${LEVEL}", + "name": "Бог уровня ${LEVEL}" + }, + "Runaround Master": { + "description": "Заработайте 500 очков", + "descriptionComplete": "Заработано 500 очков", + "descriptionFull": "Наберите 500 очков на уровне ${LEVEL}", + "descriptionFullComplete": "500 очков набрано на уровне ${LEVEL}", + "name": "Мастер уровня ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Заработайте 1000 очков", + "descriptionComplete": "Заработано 1000 очков", + "descriptionFull": "Наберите 1000 очков на уровне ${LEVEL}", + "descriptionFullComplete": "1000 очков набрано на уровне ${LEVEL}", + "name": "Волшебник уровня ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Успешно поделиться игрой с другом", + "descriptionFullComplete": "Игра успешно передана другу", + "name": "Делиться - значит заботиться" + }, + "Stayin' Alive": { + "description": "Выиграйте без смертей", + "descriptionComplete": "Победа без смертей", + "descriptionFull": "Выиграйте уровень ${LEVEL} не умирая", + "descriptionFullComplete": "Победа на уровне ${LEVEL} без смертей", + "name": "Поживем еще малец" + }, + "Super Mega Punch": { + "description": "Нанесите 100% урона одним ударом", + "descriptionComplete": "Нанесено 100% урона одним ударом", + "descriptionFull": "Нанесите 100% урона одним ударом на уровне ${LEVEL}", + "descriptionFullComplete": "100% урона нанесено одним ударом на уровне ${LEVEL}", + "name": "Супер-Мега-Удар" + }, + "Super Punch": { + "description": "Нанесите 50% урона одним ударом", + "descriptionComplete": "Нанесено 50% урона одним ударом", + "descriptionFull": "Нанесите 50% урона одним ударом на уровне ${LEVEL}", + "descriptionFullComplete": "Нанесено 50% урона одним ударом на уровне ${LEVEL}", + "name": "Супер-Удар" + }, + "TNT Terror": { + "description": "Убейте 6 негодяев с помощью TNT", + "descriptionComplete": "С помощью TNT убито 6 негодяев", + "descriptionFull": "Убейте 6 злодеев с помощью TNT на уровне ${LEVEL}", + "descriptionFullComplete": "С помощью TNT убито 6 злодеев на уровне ${LEVEL}", + "name": "Тротиловый ужас" + }, + "Team Player": { + "descriptionFull": "Начать игру в командах с 4 и более игроками", + "descriptionFullComplete": "Начал игру в командах с 4 и более игроками", + "name": "Командный игрок" + }, + "The Great Wall": { + "description": "Остановите всех негодяев", + "descriptionComplete": "Остановлены все негодяи", + "descriptionFull": "Остановите всех негодяев до одного на уровне ${LEVEL}", + "descriptionFullComplete": "Остановлены все негодяи на уровне ${LEVEL}", + "name": "Великая Стена" + }, + "The Wall": { + "description": "Остановите всех негодяев", + "descriptionComplete": "Остановлены все негодяи", + "descriptionFull": "Остановите всех негодяев до одного на уровне ${LEVEL}", + "descriptionFullComplete": "Остановлены все негодяи на уровне ${LEVEL}", + "name": "Стена" + }, + "Uber Football Shutout": { + "description": "Выиграйте в сухую", + "descriptionComplete": "Победа в сухую", + "descriptionFull": "Выиграйте матч ${LEVEL} в сухую", + "descriptionFullComplete": "Победа в матче ${LEVEL} в сухую", + "name": "${LEVEL} в сухую" + }, + "Uber Football Victory": { + "description": "Выиграйте матч", + "descriptionComplete": "Матч пройден в вашу пользу", + "descriptionFull": "Выиграйте матч ${LEVEL}", + "descriptionFullComplete": "Выигран матч ${LEVEL}", + "name": "Победа в матче ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Победите все волны", + "descriptionComplete": "Побеждены все волны", + "descriptionFull": "Победите все волны на уровне ${LEVEL}", + "descriptionFullComplete": "Побеждены все волны на уровне ${LEVEL}", + "name": "Победа на уровне ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Пройдите все волны", + "descriptionComplete": "Все волны пройдены", + "descriptionFull": "Пройдите все волны на уровне ${LEVEL}", + "descriptionFullComplete": "Пройдены все волны на уровне ${LEVEL}", + "name": "Победа на уровне ${LEVEL}" + } + }, + "achievementsRemainingText": "Осталось достижений:", + "achievementsText": "Достижения", + "achievementsUnavailableForOldSeasonsText": "К сожалению, подробности достижений не доступны для старых сезонов.", + "activatedText": "${THING} активировано.", + "addGameWindow": { + "getMoreGamesText": "Еще игры", + "titleText": "Добавить игру" + }, + "allowText": "Разрешить", + "alreadySignedInText": "С вашего аккаунта играют на другом устройстве;\nпожалуйста зайдите с другого аккаунта или закройте\nигру на другом устройстве и попытайтесь снова.", + "apiVersionErrorText": "Невозможно загрузить модуль ${NAME}; он предназначен для API версии ${VERSION_USED}; здесь требуется версия ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(Режим \"Авто\" активируется только при подключении наушников)", + "headRelativeVRAudioText": "Позиционно-зависимое VR-аудио", + "musicVolumeText": "Громкость музыки", + "soundVolumeText": "Громкость звука", + "soundtrackButtonText": "Саундтреки", + "soundtrackDescriptionText": "(выберите свою собственную музыку, которая будет звучать во время игры)", + "titleText": "Аудио" + }, + "autoText": "Авто", + "backText": "Назад", + "banThisPlayerText": "Забанить игрока", + "bestOfFinalText": "Финал: лучший из ${COUNT}", + "bestOfSeriesText": "Лучший в ${COUNT} партиях:", + "bestRankText": "Ваш лучший ранг: ${RANK}", + "bestRatingText": "Ваш лучший рейтинг: ${RATING}", + "betaErrorText": "Эта бета-версия больше не активна, проверьте наличие новой версии. ", + "betaValidateErrorText": "Невожно проверить бета-версию. (нет сетевого соединения?)", + "betaValidatedText": "Бета-версия проверена. Наслаждайтесь!", + "bombBoldText": "БОМБА", + "bombText": "Бомба", + "boostText": "Увеличение", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} настраивается в самом приложении.", + "buttonText": "кнопка", + "canWeDebugText": "Хотите, чтобы BombSquad автоматически сообщал разработчику\nоб ошибках, сбоях и основную информацию об использовании?\n\nЭти данные не содержат никакой личной информации и помогают\nподдерживать игру в рабочем состоянии без сбоев и ошибок.", + "cancelText": "Отмена", + "cantConfigureDeviceText": "Извините, ${DEVICE} невозможно настроить.", + "challengeEndedText": "Это состязание завершено.", + "chatMuteText": "Заглушить чат", + "chatMutedText": "Чат заглушен", + "chatUnMuteText": "Включить чат", + "choosingPlayerText": "<выбор игрока>", + "completeThisLevelToProceedText": "Чтобы продолжить, нужно\nпройти этот уровень!", + "completionBonusText": "Бонус за прохождение", + "configControllersWindow": { + "configureControllersText": "Настройка геймпада", + "configureGamepadsText": "Настройка контроллеров", + "configureKeyboard2Text": "Настройка клавиатуры игрока 2", + "configureKeyboardText": "Настройка клавиатуры", + "configureMobileText": "Использовать мобильные устройства в качестве геймпадов", + "configureTouchText": "Настройка сенсорного экрана", + "ps3Text": "Геймпады PS3™", + "titleText": "Геймпады", + "wiimotesText": "Пульт Wiimote™", + "xbox360Text": "Геймпады Xbox 360™" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Внимание: поддержка геймпада различается в зависимости от устройства и версии Android.", + "pressAnyButtonText": "Нажмите любую кнопку на геймпаде,\n которую хотите настроить...", + "titleText": "Настроить геймпад" + }, + "configGamepadWindow": { + "advancedText": "Дополнительно", + "advancedTitleText": "Дополнительные настройки геймпада", + "analogStickDeadZoneDescriptionText": "(Включите, если персонаж продолжает двигаться после того, как стик отпущен)", + "analogStickDeadZoneText": "Мертвая зона аналогового стика", + "appliesToAllText": "(настроить ко всем геймпадам данного типа)", + "autoRecalibrateDescriptionText": "(включить, если персонаж не двигается на полной скорости)", + "autoRecalibrateText": "Авто-перекалибровка аналоговых стиков", + "axisText": "ось", + "clearText": "очистить", + "dpadText": "D-Pad", + "extraStartButtonText": "Настроить дополнительную кнопку \"Start\"", + "ifNothingHappensTryAnalogText": "Если ничего не происходит, попробуйте вместо этого присвоить аналоговому стику.", + "ifNothingHappensTryDpadText": "Если ничего не происходит, попробуйте вместо этого присвоить D-Pad.", + "ignoreCompletelyDescriptionText": "(запретить геймпаду воздействовать на игру, или меню)", + "ignoreCompletelyText": "Игнорировать полностью", + "ignoredButton1Text": "Игнорируемая кнопка 1", + "ignoredButton2Text": "Игнорируемая кнопка 2", + "ignoredButton3Text": "Игнорируемая кнопка 3", + "ignoredButton4Text": "Игнорируемая Кнопка 4", + "ignoredButtonDescriptionText": "(используйте это, чтобы кнопки 'home' или 'sync' не влияли на пользовательский интерфейс)", + "ignoredButtonText": "Проигнорированная кнопка", + "pressAnyAnalogTriggerText": "Нажмите любой аналоговый триггер...", + "pressAnyButtonOrDpadText": "Нажмите любую кнопку или D-Pad...", + "pressAnyButtonText": "Нажмите любую кнопку", + "pressLeftRightText": "Нажмите вправо или влево...", + "pressUpDownText": "Нажмите вверх или вниз...", + "runButton1Text": "Кнопка бега 1", + "runButton2Text": "Кнопка бега 2", + "runTrigger1Text": "Триггер бега 1", + "runTrigger2Text": "Триггер бега 2", + "runTriggerDescriptionText": "(аналоговые триггеры позволяют бегать с разной скоростью)", + "secondHalfText": "Используйте эту опцию для настройки второй\nполовины устройства \"два геймпада в одном\",\nдля использования в качестве одного геймпада.", + "secondaryEnableText": "Включить", + "secondaryText": "Второй геймпад", + "startButtonActivatesDefaultDescriptionText": "(выключить, если ваша кнопка \"старт\" работает в качестве кнопки \"меню\")", + "startButtonActivatesDefaultText": "Кнопка Старт активирует стандартный виджет", + "titleText": "Настройка геймпада", + "twoInOneSetupText": "Настройка геймпада 2-в-1", + "uiOnlyDescriptionText": "(Запретить этому контроллеру присоединяться к игре)", + "uiOnlyText": "Ограничить только для меню", + "unassignedButtonsRunText": "Все неприсвоенные кнопки для бега", + "unsetText": "<не установлено>", + "vrReorientButtonText": "Кнопка переориентации VR" + }, + "configKeyboardWindow": { + "configuringText": "Настройка ${DEVICE}", + "keyboard2NoteScale": 0.7, + "keyboard2NoteText": "Примечание: большинство клавиатур могут зарегистрировать только\nнесколько нажатий клавиш за раз, так что второму игроку с клавиатуры\nлучше играть с отдельной подключенной для них клавиатуры.\nЗаметьте, что даже в этом случае все равно нужно будет присвоить\nуникальные клавиши для двух игроков." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Размеры кнопок действия", + "actionsText": "Действия", + "buttonsText": "кнопки", + "dragControlsText": "< чтобы передвинуть элементы управления, перетащите их >", + "joystickText": "джойстик", + "movementControlScaleText": "Размеры кнопок движения", + "movementText": "Движение", + "resetText": "Сброс", + "swipeControlsHiddenText": "Спрятать иконки смахивания", + "swipeInfoText": "К контроллерам, работающим со смахиванием, нужно привыкнуть,\nзато с ними можно играть, не глядя на контроллер.", + "swipeText": "смахнуть", + "titleText": "Настройка сенсорного экрана", + "touchControlsScaleText": "Шкала сенсоров" + }, + "configureItNowText": "Настроить сейчас?", + "configureText": "Настроить", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Для наилучшего результата вам понадобится сеть Wi-Fi без задержек.\nВы можете уменьшить задержки Wi-Fi, выключив другие беспроводные\nустройства, играя близко к маршрутизатору Wi-Fi, и подключив\nхост игры непосредственно к сети через Ethernet.", + "explanationScale": 0.8, + "explanationText": "Для настройки смартфона или планшета в качестве контроллера\nустановите на нем приложение \"${REMOTE_APP_NAME}\". К игре ${APP_NAME}\nможно подключить любое количество устройств через Wi-Fi, бесплатно!", + "forAndroidText": "для Android:", + "forIOSText": "для iOS:", + "getItForText": "Скачайте приложение ${REMOTE_APP_NAME} для iOS в Apple App Store\nили для Android в Google Play Store или Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Использование мобильных устройств в качестве контроллеров:" + }, + "continuePurchaseText": "Продолжить за ${PRICE}?", + "continueText": "Продолжить", + "controlsText": "Управление", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Это не относится к абсолютным рекордам.", + "activenessInfoText": "Этот множитель повышается когда вы играете,\nи понижается когда вы не играете.", + "activityText": "Активность", + "campaignText": "Кампания", + "challengesInfoText": "Выигрывай призы за мини-игры.\n\nПризы и сложность увеличиваются\nкаждый раз после победы и\nуменьшаются в случае провала.", + "challengesText": "Испытания", + "currentBestText": "Последний рекорд", + "customText": "Другое", + "entryFeeText": "Участвовать", + "forfeitConfirmText": "Сдаться?", + "forfeitNotAllowedYetText": "Вы не можете покинуть это состязание.", + "forfeitText": "Сдаться", + "multipliersText": "Множители", + "nextChallengeText": "Следующее испытание", + "nextPlayText": "Следующая игра", + "ofTotalTimeText": "из ${TOTAL}", + "playNowText": "Играть", + "pointsText": "Очки", + "powerRankingFinishedSeasonUnrankedText": "(сезон завершен без ранга)", + "powerRankingNotInTopText": "(не в ${NUMBER} лучших)", + "powerRankingPointsEqualsText": "= ${NUMBER} очков", + "powerRankingPointsMultText": "(x ${NUMBER} очков)", + "powerRankingPointsText": "${NUMBER} очков", + "powerRankingPointsToRankedText": "(${CURRENT} из ${REMAINING} очков)", + "powerRankingText": "Ранг игрока", + "prizesText": "Призы", + "proMultInfoText": "Здесь игроки с обновлением ${PRO}\nполучают ${PERCENT}% умножение очков.", + "seeMoreText": "Подробнее...", + "skipWaitText": "Пропустить ожидание", + "timeRemainingText": "Оставшееся время", + "titleText": "Кооператив", + "toRankedText": "Получено", + "totalText": "всего", + "tournamentInfoText": "Добейся высокого результата с\nдругими игроками твоей лиги.\n\nНаграды вручаются самым крутым\nпо окончании турнира.", + "welcome1Text": "Добро пожаловать в ${LEAGUE}. Вы можете\nповысить свою лигу получая звёзды, получая \nдостижения и выигрывая трофеи в турнирах.", + "welcome2Text": "Вы также можете заработать билеты от многих из тех же видов деятельности.\nБилеты могут быть использованы , чтобы разблокировать новые персонажи , карты и\nмини -игры, чтобы войти турниры, и многое другое.", + "yourPowerRankingText": "Ваш ранг:" + }, + "copyConfirmText": "Скопировано в буфер обмена", + "copyOfText": "Копия ${NAME}", + "copyText": "Копировать", + "copyrightText": "© 2013 Eric Froemling", + "createAPlayerProfileText": "Создать профиль игрока?", + "createEditPlayerText": "<Создание / редактирование игрока>", + "createText": "Создать", + "creditsWindow": { + "additionalAudioArtIdeasText": "Дополнительное аудио, предварительные иллюстрации и идеи: ${NAME}", + "additionalMusicFromText": "Дополнительная музыка: ${NAME}", + "allMyFamilyText": "Всем моим друзьям и семье, которые помогли играть тестовую версию", + "codingGraphicsAudioText": "Программирование, графика и аудио: ${NAME}", + "languageTranslationsText": "Языковые переводы:", + "legalText": "Юридическая информация:", + "publicDomainMusicViaText": "Общедоступная музыка через ${NAME}", + "softwareBasedOnText": "Это программное обеспечение частично основано на работе ${NAME}", + "songCreditText": "${TITLE} исполняет ${PERFORMER}\nКомпозитор ${COMPOSER}, Аранжировка ${ARRANGER}, Издано ${PUBLISHER},\nПредоставлено ${SOURCE}", + "soundAndMusicText": "Звук и музыка:", + "soundsText": "Звуки (${SOURCE}):", + "specialThanksText": "Особая благодарность:", + "thanksEspeciallyToText": "Отдельное спасибо ${NAME}", + "titleText": "Участвовали в создании ${APP_NAME}", + "whoeverInventedCoffeeText": "Тому, кто изобрел кофе" + }, + "currentStandingText": "Ваша текущая позиция: ${RANK}", + "customizeText": "Изменить...", + "deathsTallyText": "${COUNT} смертей", + "deathsText": "Смерти", + "debugText": "отладка", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Внимание: для этого теста рекомендуется установить Настройки->Графика->Текстуры на 'Высокий'", + "runCPUBenchmarkText": "Запустить тест производительности CPU", + "runGPUBenchmarkText": "Запустить тест производительности GPU", + "runMediaReloadBenchmarkText": "Запустить тест производительности загрузки медиа", + "runStressTestText": "Выполнить тест-нагрузку", + "stressTestPlayerCountText": "Количество игроков", + "stressTestPlaylistDescriptionText": "Плей-лист нагрузочного испытания", + "stressTestPlaylistNameText": "Название плей-листа", + "stressTestPlaylistTypeText": "Тип плей-листа", + "stressTestRoundDurationText": "Продолжительность раунда", + "stressTestTitleText": "Тест-нагрузка", + "titleText": "Тесты производительности и тесты-нагрузки", + "totalReloadTimeText": "Общее время перезагрузки: ${TIME} (подробности см. в логе)", + "unlockCoopText": "Разблокировать кооперативные уровни" + }, + "defaultFreeForAllGameListNameText": "Стандартные игры 'Каждый за себя'", + "defaultGameListNameText": "Стандартный плей-лист режима ${PLAYMODE}", + "defaultNewFreeForAllGameListNameText": "Мои игры 'Каждый за себя'", + "defaultNewGameListNameText": "Мой плей-лист ${PLAYMODE}", + "defaultNewTeamGameListNameText": "Мои командные игры", + "defaultTeamGameListNameText": "Стандартные командные игры", + "deleteText": "Удалить", + "demoText": "Демонстрация", + "denyText": "Отклонить", + "deprecatedText": "Устарело>=", + "desktopResText": "Разреш. экрана", + "deviceAccountUpgradeText": "Внимание!\nВы заригестрированы как (${NAME})!\nДанный аккаунт будет удален в следующем обновлении!\nОбновите его до аккаунта Google Play, если не хотите потерять прогресс!", + "difficultyEasyText": "Легкий", + "difficultyHardOnlyText": "Только в трудном режиме", + "difficultyHardText": "Трудный", + "difficultyHardUnlockOnlyText": "Этот уровень может быть открыт только в сложном режиме.\nДумаете, сможете!?!?!", + "directBrowserToURLText": "Пожалуйста, направьте веб-браузер по следующему адресу:", + "disableRemoteAppConnectionsText": "Отключить соединения RemoteApp", + "disableXInputDescriptionText": "Позволяет подключение более 4 контроллеров, но может не очень хорошо работать.", + "disableXInputText": "Отключить XInput", + "doneText": "Готово", + "drawText": "Ничья", + "duplicateText": "Дублировать", + "editGameListWindow": { + "addGameText": "Добавить\nигру", + "cantOverwriteDefaultText": "Невозможно перезаписать стандартный плей-лист!", + "cantSaveAlreadyExistsText": "Плей-лист с таким именем уже существует!", + "cantSaveEmptyListText": "Невозможно сохранить пустой плей-лист!", + "editGameText": "Изменить\nигру", + "gameListText": "Список игр", + "listNameText": "Название плей-листа", + "nameText": "Название", + "removeGameText": "Удалить\nигру", + "saveText": "Сохранить список", + "titleText": "Редактор плей-листа" + }, + "editProfileWindow": { + "accountProfileInfoText": "У этого особенного профиля есть имя\nи иконка, основанные на вашем аккаунте.\n\n${ICONS}\n\nСоздайте дополнительные профили, чтобы \nиспользовать разные имена и иконки.", + "accountProfileText": "(профиль аккаунта)", + "availableText": "Имя \"${NAME}\" доступно.", + "changesNotAffectText": "Внимание: изменения не повлияют на профили, уже находящиеся в игре", + "characterText": "персонаж", + "checkingAvailabilityText": "Проверка доступности для \"${NAME}\"...", + "colorText": "цвет", + "getMoreCharactersText": "Еще персонажей...", + "getMoreIconsText": "Еще иконок...", + "globalProfileInfoText": "Глобальным профилям игроков гарантированы уникальные\nимена. У них также есть дополнительные иконки.", + "globalProfileText": "(глобальный профиль)", + "highlightText": "акцент", + "iconText": "Иконка", + "localProfileInfoText": "У локальных игровых профилей нет иконок и им не гарантированы\nуникальные имена. Обновите до глобального профиля, чтобы\nзарезервировать уникальное имя и добавить иконку.", + "localProfileText": "(локальный профиль)", + "nameDescriptionText": "Имя игрока", + "nameText": "Имя", + "randomText": "случайное", + "titleEditText": "Изменение профиля", + "titleNewText": "Новый профиль", + "unavailableText": "\"${NAME}\" недоступно; попробуйте другое имя.", + "upgradeProfileInfoText": "Это зарезервирует ваше имя игрока\nи позволит вам добавить иконку.", + "upgradeToGlobalProfileText": "Обновить до глобального профиля" + }, + "editProfilesAnyTimeText": "(профиль можно изменить в любое время в 'настройках')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Невожможно удалить стандартный саундтрек.", + "cantEditDefaultText": "Невозможно изменить стандартный саундтрек. Создайте копию или новый саундтрек.", + "cantEditWhileConnectedOrInReplayText": "Нельзя редактировать саундтреки находясь в лобби или в записи.", + "cantOverwriteDefaultText": "Невозможно перезаписать стандартный саундтрек", + "cantSaveAlreadyExistsText": "Саундтрек с таким именем уже существует!", + "copyText": "Копировать", + "defaultGameMusicText": "<стандартная музыка игры>", + "defaultSoundtrackNameText": "Стандартный саундтрек", + "deleteConfirmText": "Удалить саундтрек:\n\n${NAME}'?", + "deleteText": "Удалить\nсаундтрек", + "duplicateText": "Копировать\nсаундтрек", + "editSoundtrackText": "Редактор саундтрека", + "editText": "Изменить\nсаундтрек", + "fetchingITunesText": "загрузка плей-листов Music App…", + "musicVolumeZeroWarning": "Внимание: громкость музыки установлена на 0", + "nameText": "Название", + "newSoundtrackNameText": "Мой саундтрек ${COUNT}", + "newSoundtrackText": "Новый саундтрек:", + "newText": "Новый\nсаундтрек", + "selectAPlaylistText": "Выберите плей-лист", + "selectASourceText": "Источник музыки", + "soundtrackText": "Саундтрек", + "testText": "тест", + "titleText": "Саундтреки", + "useDefaultGameMusicText": "Стандартная музыка", + "useITunesPlaylistText": "Плейлист музыкального приложения", + "useMusicFileText": "Музыкальный файл (mp3 и т. д.)", + "useMusicFolderText": "Папка с музыкой" + }, + "editText": "Редактировать", + "endText": "Конец", + "enjoyText": "Удачи!", + "epicDescriptionFilterText": "${DESCRIPTION} в эпическом замедленном действии.", + "epicNameFilterText": "${NAME} в эпическом режиме", + "errorAccessDeniedText": "доступ запрещен", + "errorDeviceTimeIncorrectText": "Время на устройстве отстает на ${HOURS} часов.\nЭто может вызывать проблемы.\nПожалуйста, проверьте настройки времени и часового пояса.", + "errorOutOfDiskSpaceText": "нет места на диске", + "errorSecureConnectionFailText": "Ошибка установки безопасного облачного соединения; сетевые функции могут дать сбой.", + "errorText": "Ошибка", + "errorUnknownText": "неизвестная ошибка", + "exitGameText": "Выйти из ${APP_NAME}?", + "exportSuccessText": "'${NAME}' экспортирован.", + "externalStorageText": "Внешняя память", + "failText": "Провал", + "fatalErrorText": "Файлы игры повреждены или отсутствуют.\nПопробуйте переустановить приложение или\nобратитесь к ${EMAIL} за помощью.", + "fileSelectorWindow": { + "titleFileFolderText": "Выберите файл или папку", + "titleFileText": "Выберите файл", + "titleFolderText": "Выберите папку", + "useThisFolderButtonText": "Использовать эту папку" + }, + "filterText": "Поиск", + "finalScoreText": "Финальные очки", + "finalScoresText": "Финальные очки", + "finalTimeText": "Финальное время", + "finishingInstallText": "Завершается установка, минутку...", + "fireTVRemoteWarningText": "* Для лучшего результата используйте\nгеймпады или установите\nприложение '${REMOTE_APP_NAME}'\nна ваших телефонах и планшетах.", + "firstToFinalText": "Финал до ${COUNT} очков", + "firstToSeriesText": "Серия до ${COUNT} очков", + "fiveKillText": "ПЯТЕРЫХ ЗА РАЗ!!!", + "flawlessWaveText": "Безупречная волна!", + "fourKillText": "ЧЕТВЕРЫХ ЗА РАЗ!!!", + "freeForAllText": "Каждый за себя", + "friendScoresUnavailableText": "Очки друзей недоступны.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Лидеры игры ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "Невозможно удалить стандартный плей-лист!", + "cantEditDefaultText": "Невозможно изменить стандартный плей-лист! Создайте копию или новый список.", + "cantShareDefaultText": "Вы не можете делиться стандартным плейлистом.", + "deleteConfirmText": "Удалить \"${LIST}\"?", + "deleteText": "Удалить\nплей-лист", + "duplicateText": "Дублировать\nплей-лист", + "editText": "Изменить\nплей-лист", + "gameListText": "Список игр", + "newText": "Новый\nплей-лист", + "showTutorialText": "Показать обучение", + "shuffleGameOrderText": "Смешать порядок игр", + "titleText": "Настроить плей-листы '${TYPE}'" + }, + "gameSettingsWindow": { + "addGameText": "Добавить игру" + }, + "gamepadDetectedText": "обнаружен 1 контроллер", + "gamepadsDetectedText": "Обнаружены ${COUNT} контроллера.", + "gamesToText": "${WINCOUNT}:${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Помните: любое устройство в совместной игре поддерживает\nнесколько игроков, если у вас хватает контроллеров.", + "aboutDescriptionText": "Используйте эти закладки, чтобы создать лобби.\n\nЛобби позволяет играть в игры и турниры\nс друзьями на разных устройствах.\n\nНажмите кнопку ${PARTY} в правом верхнем углу,\nчтобы общаться с друзьями в вашем лобби.\n(на контроллере, нажмите ${BUTTON} находясь в меню)", + "aboutText": "Инфо", + "addressFetchErrorText": "<ошибка запроса адресов>", + "appInviteInfoText": "Пригласите друзей поиграть в BombSquad и они\nполучат ${COUNT} бесплатных билетов. Ты получишь\n${YOU_COUNT} за каждого друга.", + "appInviteMessageText": "${NAME} отправил вам ${COUNT} билетов в ${APP_NAME}", + "appInviteSendACodeText": "Отправить им код", + "appInviteTitleText": "Приглашение в ${APP_NAME}", + "bluetoothAndroidSupportText": "(работает с любым устройством, поддерживающим Bluetooth)", + "bluetoothDescriptionText": "Создать/войти в лобби через Bluetooth:", + "bluetoothHostText": "Создать лобби через Bluetooth", + "bluetoothJoinText": "Присоединиться через Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "проверка...", + "copyCodeConfirmText": "Код скопирован в буфер обмена.", + "copyCodeText": "Копировать код", + "dedicatedServerInfoText": "Для лучшего результата создайте отдельный сервер. Смотри bombsquadgame.com/server чтобы узнать как.", + "disconnectClientsText": "Это отключит ${COUNT} игроков\nв вашем лобби. Вы уверены?", + "earnTicketsForRecommendingAmountText": "Друзья получат ${COUNT} билетов, если они активируют ваш код\n(а вы будете получать ${YOU_COUNT} билетов за каждую активацию)", + "earnTicketsForRecommendingText": "Поделись игрой\nПолучи билеты...", + "emailItText": "Послать Email", + "favoritesSaveText": "Сохранить как избранное", + "favoritesText": "Избранное", + "freeCloudServerAvailableMinutesText": "Следующий бесплатный облачный сервер будет доступен через ${MINUTES} минут(у).", + "freeCloudServerAvailableNowText": "Облачный сервер доступен!", + "freeCloudServerNotAvailableText": "Нет бесплатных облачных серверов.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} билетов от ${NAME}", + "friendPromoCodeAwardText": "Вы получите ${COUNT} билетов за каждую активацию.", + "friendPromoCodeExpireText": "Код действителен в течении ${EXPIRE_HOURS} часов и только для новых игроков.", + "friendPromoCodeInstructionsText": "Для активации в ${APP_NAME} зайдите в\n\"Настройки->Дополнительно->Ввести промо-код\". Перейди на сайт bombsquadgame.com, чтобы скачать версию игры для своей платформы.", + "friendPromoCodeRedeemLongText": "Каждая активация принесет ${COUNT} билетов до ${MAX_USES} игрокам.", + "friendPromoCodeRedeemShortText": "Он принесет ${COUNT} билетов в игре.", + "friendPromoCodeWhereToEnterText": "(в \"Настройках->Дополнительно->Ввести код\")", + "getFriendInviteCodeText": "Получить промо-код", + "googlePlayDescriptionText": "Пригласить игроков Google Play в ваше лобби:", + "googlePlayInviteText": "Пригласить", + "googlePlayReInviteText": "В вашем лобби ${COUNT} игроков Google Play.\nЕсли вы начнете новое приглашение, они будут отключены.\nДобавьте их в новое приглашение, чтобы их вернуть.", + "googlePlaySeeInvitesText": "Смотреть приглашения", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Только для Android / Google Play)", + "hostPublicPartyDescriptionText": "Создать публичное лобби", + "hostingUnavailableText": "Хостинг недоступен", + "inDevelopmentWarningText": "Примечание:\n\nСетевая игра является новой и еще развивающейся функцией.\nВ настоящее время, настоятельно рекомендуется, чтобы все\nигроки были в той же сети Wi-Fi.", + "internetText": "Интернет", + "inviteAFriendText": "Друзья еще не играют? Пригласи их\nпопробовать и они получат ${COUNT} билетов.", + "inviteFriendsText": "Пригласить друзей", + "joinPublicPartyDescriptionText": "Присоединитесь к публичному лобби", + "localNetworkDescriptionText": "Присоединяйтесь к ближайшему лобби (локальная сеть, Bluetooth, и т.д.)", + "localNetworkText": "Локальная сеть", + "makePartyPrivateText": "Сделать мое лобби приватным", + "makePartyPublicText": "Сделать мое лобби публичным", + "manualAddressText": "Адрес", + "manualConnectText": "Подключиться", + "manualDescriptionText": "Войти в лобби по адресу:", + "manualJoinSectionText": "Присоединиться по адресу", + "manualJoinableFromInternetText": "К вам можно подключаться из Интернета?:", + "manualJoinableNoWithAsteriskText": "НЕТ*", + "manualJoinableYesText": "ДА", + "manualRouterForwardingText": "*чтобы исправить, попробуйте настроить маршрутизатор для перенаправления UDP порта ${PORT} на ваш локальный адрес", + "manualText": "Вручную", + "manualYourAddressFromInternetText": "Ваш адрес из Интернета:", + "manualYourLocalAddressText": "Ваш локальный адрес:", + "nearbyText": "Поблизости", + "noConnectionText": "<нет соединения>", + "otherVersionsText": "(другие версии)", + "partyCodeText": "Код лобби", + "partyInviteAcceptText": "Принять", + "partyInviteDeclineText": "Отклонить", + "partyInviteGooglePlayExtraText": "(смотрите вкладку 'Google Play' в разделе 'Собрать')", + "partyInviteIgnoreText": "Игнорировать", + "partyInviteText": "${NAME} пригласил\nвас в его лобби!", + "partyNameText": "Имя команды", + "partyServerRunningText": "Твой сервер для лобби работает.", + "partySizeText": "Игроки", + "partyStatusCheckingText": "Проверка...", + "partyStatusJoinableText": "Ваша команда доступна через интернет", + "partyStatusNoConnectionText": "Невозможно подключиться к серверу", + "partyStatusNotJoinableText": "Ваше лобби недоступно через интернет", + "partyStatusNotPublicText": "Ваше лобби не публично", + "pingText": "Пинг", + "portText": "Порт", + "privatePartyCloudDescriptionText": "Частные лобби работают на выделенных облачных серверах; настройка маршрутизатора не требуется.", + "privatePartyHostText": "Создать частное лобби", + "privatePartyJoinText": "Присоединиться к частному лобби", + "privateText": "Частный", + "publicHostRouterConfigText": "Это может потребовать настройки переадресации портов на вашем маршрутизаторе. Для более легкого варианта организуйте частное лобби.", + "publicText": "Открытый", + "requestingAPromoCodeText": "Запрашиваем код...", + "sendDirectInvitesText": "Послать приглашение", + "shareThisCodeWithFriendsText": "Поделись кодом с друзьями:", + "showMyAddressText": "Показать мой адрес", + "startAdvertisingText": "Включить доступ", + "startHostingPaidText": "Создать сейчас за ${COST}", + "startHostingText": "Создать", + "startStopHostingMinutesText": "Вы можете начать и остановить хостинг бесплатно в течение следующих ${MINUTES} минут.", + "stopAdvertisingText": "Отключить доступ", + "stopHostingText": "Остановить", + "titleText": "Мультиплеер", + "wifiDirectDescriptionBottomText": "Если у всех устройств есть панель 'Wi-Fi Direct', они могут использовать ее, чтобы найти\nи соединиться друг с другом. Когда все устройства подключены, вы можете создать здесь лобби,\nиспользуя вкладку 'Локальная сеть', также, как и с обычной Wi-Fi сетью.\n\nДля лучших результатов, хост Wi-Fi Direct также должен быть хостом группы ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct может быть использован для соединения устройств Android напрямую без\nWi-Fi сети. Это лучше всего работает на Android 4.2 или новее.\n\nЧтобы использовать, откройте настройки Wi-Fi и поищите Wi-Fi Direct в меню.", + "wifiDirectOpenWiFiSettingsText": "Открыть настройки Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(работает между всеми платформами)", + "worksWithGooglePlayDevicesText": "(работает с устройствами, использующими версию игры Google Play (Android)", + "youHaveBeenSentAPromoCodeText": "Вам был выслан ${APP_NAME} промо-код:" + }, + "getCoinsWindow": { + "coinDoublerText": "Удвоение монет", + "coinsText": "Монеты: ${COUNT}", + "freeCoinsText": "Бесплатные монеты", + "restorePurchasesText": "Восстановить покупки", + "titleText": "Получить монеты" + }, + "getTicketsWindow": { + "freeText": "БЕСПЛАТНО!", + "freeTicketsText": "Бесплатные билеты", + "inProgressText": "Выполняется транзакция; повторите попытку через несколько секунд.", + "purchasesRestoredText": "Покупки восстановлены.", + "receivedTicketsText": "Получено ${COUNT} билетов!", + "restorePurchasesText": "Восстановить покупки", + "ticketDoublerText": "Удвоитель билетов", + "ticketPack1Text": "Маленькая пачка билетов", + "ticketPack2Text": "Средняя пачка билетов", + "ticketPack3Text": "Большая пачка билетов", + "ticketPack4Text": "Огромная пачка билетов", + "ticketPack5Text": "Слоновая пачка билетов", + "ticketPack6Text": "Максимальная пачка билетов", + "ticketsFromASponsorText": "Посмотреть рекламу,\nчтобы получить ${COUNT} билетов", + "ticketsText": "Билетов: ${COUNT}", + "titleText": "Получить билеты", + "unavailableLinkAccountText": "Извините, но на этой платформе покупки недоступны.\nВ качестве решения, вы можете привязать этот аккаунт \nк аккаунту на другой платформе, и совершать покупки там.", + "unavailableTemporarilyText": "Сейчас недоступно; повторите попытку позже.", + "unavailableText": "К сожалению это не доступно.", + "versionTooOldText": "Извините, ваша версия игры устарела; пожалуйста, обновите на новую.", + "youHaveShortText": "у вас ${COUNT}", + "youHaveText": "У вас ${COUNT} билетов" + }, + "googleMultiplayerDiscontinuedText": "Простите, сервис многопользовательской игры Google больше не поддерживается.\nЯ работаю над заменой так быстро, насколько это возможно.\nДо тех пор, пожалуйста выберете другой способ подключения.\n-Эрик", + "googlePlayPurchasesNotAvailableText": "Покупки в Google Play недоступны.\nВозможно, вам необходимо обновить приложение магазина.", + "googlePlayServicesNotAvailableText": "Сервисы Google Play недоступны.\nНекоторый функционал игры могут быть отключены.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Всегда", + "fullScreenCmdText": "Полноэкранный (Cmd-F)", + "fullScreenCtrlText": "Полноэкранный (Ctrl-F)", + "gammaText": "Гамма", + "highText": "Высокий", + "higherText": "Ультра", + "lowText": "Низкий", + "mediumText": "Средний", + "neverText": "Никогда", + "resolutionText": "Разрешение", + "showFPSText": "Показывать FPS", + "texturesText": "Текстуры", + "titleText": "Графика", + "tvBorderText": "Граница телевизора", + "verticalSyncText": "Вертикальная синхронизация (V-Sync)", + "visualsText": "Визуальные эффекты" + }, + "helpWindow": { + "bombInfoText": "- Бомба -\nСильнее ударов, но может привести\nк смертельным повреждениям. Для\nнаилучших результатов бросать в\nпротивника пока не догорел фитиль.", + "bombInfoTextScale": 0.6, + "canHelpText": "${APP_NAME} может помочь.", + "controllersInfoText": "Вы можете играть в ${APP_NAME} с друзьями по сети, или вы все можете\nиграть на одном устройстве, если у вас достаточно контроллеров.\n${APP_NAME} поддерживает любые контроллеры; можно даже использовать телефоны \nв качестве контроллеров через бесплатное приложение '${REMOTE_APP_NAME}.\nСмотрите Настройки→Контроллеры для получения дополнительной информации.", + "controllersInfoTextFantasia": "Один игрок может использовать пульт дистанционного управления,\nно рекомендуется использовать геймпад. Также вместо контроллеров\nможно использовать мобильные устройства с помощью\nбесплатного приложения 'BombSquad Remote'.\nДополнительную информацию см. в 'Настройки'>'Контроллеры'.", + "controllersInfoTextMac": "Один-два игрока могут играть с клавиатуры, но BombSquad лучше всего работает\nс геймпадами. Управлять персонажами в BombSquad можно с помощью USB геймпадов,\nконтроллеров PS3, Xbox 360, Wii и устройств iOS/Android. Надеюсь, у вас есть такие\nпод рукой. Дополнительную информацию см. в разделе 'Настройки' > 'Контроллеры'.", + "controllersInfoTextOuya": "С BombSquad можно использовать контроллеры OUYA, PS3, Xbox 360, а также\nмножество других USB и Bluetooth геймпадов. Также можно использовать\nустройства iOS и Android в качестве контроллеров через бесплатное приложение\n'BombSquad Remote'. Дополнительную информацию см. в 'Настройки' > 'Контроллеры'.", + "controllersInfoTextRemoteOnly": "Ты можешь играть ${APP_NAME} с друзьями по сети, или вы\nвсе можете играть на одном устройстве используя ваши смартфоны как\nконтроллеры через бесплатное приложение '${REMOTE_APP_NAME}'.", + "controllersText": "Контроллеры", + "controlsSubtitleText": "У вашего дружелюбного персонажа из ${APP_NAME} есть несколько простых действий:", + "controlsText": "Управление", + "devicesInfoText": "В VR-версию ${APP_NAME} можно играть по сети с обычной версией,\nтак что вытаскивайте свои дополнительные телефоны, планшеты\nи компьютеры, и играйте на них. Можно даже подключить\nобычную версию игры к VR-версии, чтобы позволить\nостальным наблюдать за действием.", + "devicesText": "Устройства", + "friendsGoodText": "Бывают полезны. В ${APP_NAME} веселее играть с несколькими игроками;\nподдерживается до 8 игроков одновременно, что приводит нас к:", + "friendsText": "Друзья", + "jumpInfoText": "- Прыжок -\nПрыгайте для перескакивания,\nшвыряния предметов подальше\nили для выражения радости.", + "orPunchingSomethingText": "Или ударить, сбросить с обрыва и взорвать бомбой-липучкой по дороге вниз.", + "pickUpInfoText": "- Захват -\nХватайте флаги, врагов\nи все, что не прикручено к полу.\nЧтобы бросить, нажмите еще раз.", + "powerupBombDescriptionText": "Позволяет швырнуть три бомбы\nподряд, вместо одной.", + "powerupBombNameText": "Тройные бомбы", + "powerupCurseDescriptionText": "Этого, наверное, лучше избегать.\n ...или нет?...", + "powerupCurseNameText": "Проклятие", + "powerupHealthDescriptionText": "Ни за что не догадаетесь.\nВозвращает полное здоровье.", + "powerupHealthNameText": "Аптечка", + "powerupIceBombsDescriptionText": "Слабее, чем обычные бомбы\nно оставляет врагов заморожеными\nи чрезвычайно хрупкими.", + "powerupIceBombsNameText": "Ледяные бомбы", + "powerupImpactBombsDescriptionText": "Чуть слабее обычных бомб,\nно взрываются при ударе.", + "powerupImpactBombsNameText": "Моментальные бомбы", + "powerupLandMinesDescriptionText": "Выдаются по 3 штуки.\nПолезны для защиты базы или\nусмирения быстроногих врагов.", + "powerupLandMinesNameText": "Мины", + "powerupPunchDescriptionText": "Делают ваши удары быстрее,\nлучше, сильнее.", + "powerupPunchNameText": "Боксерские перчатки", + "powerupShieldDescriptionText": "Немного поглощает урон,\nвместо вас.", + "powerupShieldNameText": "Энергетический щит", + "powerupStickyBombsDescriptionText": "Липнут ко всему, чего касаются.\nИ начинается веселье.", + "powerupStickyBombsNameText": "Бомбы-липучки", + "powerupsSubtitleText": "Конечно, ни одна игра не обходится без усилителей:", + "powerupsText": "Усилители", + "punchInfoText": "- Удар -\nЧем быстрее двигаются кулаки -\nтем cильнее удар. Так что бегайте\nи крутитесь как ненормальные.", + "runInfoText": "- Бег -\nДля бега удерживайте нажатой ЛЮБУЮ кнопку. Для этого хороши верхние триггеры\nили плечевые кнопки, если они у вас есть. Бегом передвигаться быстрее,\nно труднее поворачивать, так что осторожно с обрывами.", + "someDaysText": "Иногда просто хочется что-нибудь ударить. Или взорвать.", + "titleText": "Справка ${APP_NAME}", + "toGetTheMostText": "Чтобы выжать максимум из этой игры, вам необходимо:", + "welcomeText": "Добро пожаловать в ${APP_NAME}!" + }, + "holdAnyButtonText": "<держать любую кнопку>", + "holdAnyKeyText": "<держать любую клавишу>", + "hostIsNavigatingMenusText": "- ${HOST} в меню навигации как босс -", + "importPlaylistCodeInstructionsText": "Используйте показанный код, чтобы импортировать этот плейлист где-то ещё:", + "importPlaylistSuccessText": "Импортирован плейлист ${TYPE} '${NAME}'", + "importText": "Импорт", + "importingText": "Импортирую...", + "inGameClippedNameText": "В игре будет\n\"${NAME}\"", + "installDiskSpaceErrorText": "ОШИБКА: не удалось завершить установку. Может быть,\nне хватает свободного места на вашем устройстве.\nОсвободите место и попробуйте еще раз.", + "internal": { + "arrowsToExitListText": "чтобы выйти из списка нажмите ${LEFT} или ${RIGHT}", + "buttonText": "кнопка", + "cantKickHostError": "Невозможно кикнуть создателя.", + "chatBlockedText": "${NAME} заблокирован на ${TIME} секунд.", + "connectedToGameText": "Вошел в игру '${NAME}'", + "connectedToPartyText": "Вошел в лобби ${NAME}!", + "connectingToPartyText": "Идет соединение...", + "connectionFailedHostAlreadyInPartyText": "Соединение не удалось; хост находится в другом лобби.", + "connectionFailedPartyFullText": "Соединение не удалось; группа полная", + "connectionFailedText": "Соединение не удалось.", + "connectionFailedVersionMismatchText": "Соединение не удалось; хост использует другую версию игры.\nУбедитесь, что версии обеих сторон обновлены, и попытайтесь снова.", + "connectionRejectedText": "Соединение отклонено.", + "controllerConnectedText": "${CONTROLLER} подключен.", + "controllerDetectedText": "Обнаружен 1 контроллер.", + "controllerDisconnectedText": "${CONTROLLER} отсоединен.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} отсоединен. Попробуйте подключиться еще раз.", + "controllerForMenusOnlyText": "Этот контороллер не используется в игре; только в навигационном меню", + "controllerReconnectedText": "${CONTROLLER} снова подключен.", + "controllersConnectedText": "Подключено ${COUNT} контроллеров.", + "controllersDetectedText": "Обнаружено ${COUNT} контроллеров.", + "controllersDisconnectedText": "Отсоединено ${COUNT} контроллеров.", + "corruptFileText": "Обнаружены поврежденные файлы. Попытайтесь переустановить или обратитесь к ${EMAIL}", + "errorPlayingMusicText": "Ошибка воспроизведения музыки: ${MUSIC}", + "errorResettingAchievementsText": "Не удается сбросить онлайн-медали, пожалуйста, попробуйте позже.", + "hasMenuControlText": "${NAME} контролирует меню", + "incompatibleNewerVersionHostText": "Хост использует более новую версию игры.\nОбновитесь до последней версии и попробуйте снова.", + "incompatibleVersionHostText": "Хост использует другую версию игры.\nУбедитесь, что обе ваши версии обновлены, и попытайтесь снова.", + "incompatibleVersionPlayerText": "${NAME} использует другую версию игры и не может соединится.\nУбедитесь, что обе ваши версии обновлены, и попытайтесь снова.", + "invalidAddressErrorText": "Ошибка: неправильный адрес.", + "invalidNameErrorText": "Ошибка: некорректное имя.", + "invalidPortErrorText": "Ошибка: неверный порт.", + "invitationSentText": "Приглашение отправлено.", + "invitationsSentText": "Отправлено ${COUNT} приглашений.", + "joinedPartyInstructionsText": "Кто-то вошел в ваше лобби.\nНажмите 'Играть' чтобы начать игру.", + "keyboardText": "Клавиатура", + "kickIdlePlayersKickedText": "${NAME} исключён за бездействие.", + "kickIdlePlayersWarning1Text": "${NAME} будет исключён через ${COUNT} секунд при бездействии.", + "kickIdlePlayersWarning2Text": "(это можно выключить в Настройки -> Дополнительно)", + "leftGameText": "Покинул '${NAME}'.", + "leftPartyText": "Вышел из лобби ${NAME}.", + "noMusicFilesInFolderText": "В папке нет музыкальных файлов.", + "playerJoinedPartyText": "${NAME} вошел в лобби!", + "playerLeftPartyText": "${NAME} покинул лобби.", + "rejectingInviteAlreadyInPartyText": "Приглашение отклонено (уже в лобби).", + "serverRestartingText": "Сервер перезагружается. Попробуйте позже...", + "serverShuttingDownText": "Сервер выключается...", + "signInErrorText": "Ошибка входа.", + "signInNoConnectionText": "Невозможно войти. (нет интернет соединения?)", + "teamNameText": "Команда ${NAME}", + "telnetAccessDeniedText": "ОШИБКА: пользователь не предоставил доступ Telnet.", + "timeOutText": "(осталось ${TIME} секунд)", + "touchScreenJoinWarningText": "Вы присоединились с сенсорным экраном.\nЕсли это была ошибка, нажмите 'Меню->Покинуть игру'.", + "touchScreenText": "Сенсорный экран", + "trialText": "проба", + "unableToResolveHostText": "Ошибка: невозможно достичь хоста.", + "unavailableNoConnectionText": "Сейчас это недоступно (нет интернет соединения?)", + "vrOrientationResetCardboardText": "Используйте это, чтобы сбросить ориентации VR.\nЧтобы играть в игру, вам понадобится внешний контроллер.", + "vrOrientationResetText": "Сброс ориентации VR.", + "willTimeOutText": "(время выйдет при бездействии)" + }, + "jumpBoldText": "ПРЫЖОК", + "jumpText": "Прыгнуть", + "keepText": "Оставить", + "keepTheseSettingsText": "Оставить эти настройки?", + "keyboardChangeInstructionsText": "Нажмите на пробел два раза, чтобы сменить раскладку.", + "keyboardNoOthersAvailableText": "Нету других раскладок.", + "keyboardSwitchText": "Раскладка изменена на \"${NAME}\".", + "kickOccurredText": "${NAME} исключили.", + "kickQuestionText": "Исключить ${NAME}?", + "kickText": "Исключить", + "kickVoteCantKickAdminsText": "Администраторов нельзя исключить.", + "kickVoteCantKickSelfText": "Вы не можете исключить самого себя (но можете выйти).", + "kickVoteFailedNotEnoughVotersText": "Недостаточно игроков для голосования.", + "kickVoteFailedText": "Голосование на вылет не удалось.", + "kickVoteStartedText": "Начато голосование за вылет ${NAME}.", + "kickVoteText": "Голосовать за вылет", + "kickVotingDisabledText": "Голосование за вылет отключено.", + "kickWithChatText": "Наберите ${YES} для согласия или ${NO} для отказа.", + "killsTallyText": "Убито ${COUNT}", + "killsText": "Убито", + "kioskWindow": { + "easyText": "Легкий", + "epicModeText": "Эпический режим", + "fullMenuText": "Полное меню", + "hardText": "Трудный", + "mediumText": "Средний", + "singlePlayerExamplesText": "Примеры одиночной игры / кооператива", + "versusExamplesText": "Примеры игр друг против друга" + }, + "languageSetText": "Язык установлен на \"${LANGUAGE}\".", + "lapNumberText": "Круг ${CURRENT}/${TOTAL}", + "lastGamesText": "(последние ${COUNT} игр)", + "leaderboardsText": "Таблицы лидеров", + "league": { + "allTimeText": "Абсолютные", + "currentSeasonText": "Текущий сезон (${NUMBER})", + "leagueFullText": "Лига ${NAME}", + "leagueRankText": "Ранг лиги", + "leagueText": "Лига", + "rankInLeagueText": "#${RANK}, ${NAME} League${SUFFIX}", + "seasonEndedDaysAgoText": "Сезон завершился ${NUMBER} дней назад.", + "seasonEndsDaysText": "Сезон завершится через ${NUMBER} дней.", + "seasonEndsHoursText": "Сезон завершится через ${NUMBER} часов.", + "seasonEndsMinutesText": "Сезон завершится через ${NUMBER} минут.", + "seasonText": "Сезон ${NUMBER}", + "tournamentLeagueText": "Чтобы участвовать в этом турнире, вы должны достичь лиги ${NAME}.", + "trophyCountsResetText": "Трофеи будут сброшены в следующем сезоне." + }, + "levelBestScoresText": "Лучший рекорд на ${LEVEL}", + "levelBestTimesText": "Лучшее время на ${LEVEL}", + "levelFastestTimesText": "Лучшее время уровня ${LEVEL}", + "levelHighestScoresText": "Лучшие очки уровня ${LEVEL}", + "levelIsLockedText": "${LEVEL} заблокирован.", + "levelMustBeCompletedFirstText": "Сначала должен быть пройден ${LEVEL}.", + "levelText": "Уровень ${NUMBER}", + "levelUnlockedText": "Уровень разблокирован!", + "livesBonusText": "Бонус жизней", + "loadingText": "Загрузка", + "loadingTryAgainText": "Загрузка; попробуй снова через несколько секунд...", + "macControllerSubsystemBothText": "Оба (не рекомендуется)", + "macControllerSubsystemClassicText": "Классический", + "macControllerSubsystemDescriptionText": "(попробуйте изменить это, если ваши контроллеры не работают)", + "macControllerSubsystemMFiNoteText": "Обнаружен Сделанный-для-iOS/Mac контроллер;\nВозможно, вы захотите включить его в Настройки → Контроллеры", + "macControllerSubsystemMFiText": "Сделано для iOS/Mac", + "macControllerSubsystemTitleText": "Поддержка контроллера", + "mainMenu": { + "creditsText": "Благодарности", + "demoMenuText": "Меню демо", + "endGameText": "Закончить игру", + "endTestText": "Завершить тест", + "exitGameText": "Выйти из игры", + "exitToMenuText": "Выйти в меню?", + "howToPlayText": "Как играть", + "justPlayerText": "(Только ${NAME})", + "leaveGameText": "Покинуть игру", + "leavePartyConfirmText": "Действительно покинуть лобби?", + "leavePartyText": "Покинуть лобби", + "leaveText": "Уйти", + "quitText": "Выйти", + "resumeText": "Продолжить", + "settingsText": "Настройки" + }, + "makeItSoText": "Да будет так", + "mapSelectGetMoreMapsText": "Ещё карт...", + "mapSelectText": "Выбрать...", + "mapSelectTitleText": "Карты игры ${GAME}", + "mapText": "Карта", + "maxConnectionsText": "Максимум соединений", + "maxPartySizeText": "Размер группы", + "maxPlayersText": "Максимум игроков", + "merchText": "Мерч с символикой Bomb squad!", + "modeArcadeText": "Аркадный режим", + "modeClassicText": "Обычный режим", + "modeDemoText": "Демонстрационный режим", + "mostValuablePlayerText": "Самый ценный игрок", + "mostViolatedPlayerText": "Самый побитый игрок", + "mostViolentPlayerText": "Самый буйный игрок", + "moveText": "Движение", + "multiKillText": "${COUNT} ЗА РАЗ!!!", + "multiPlayerCountText": "${COUNT} игроков", + "mustInviteFriendsText": "Примечание: вы должны пригласить друзей\nна панели \"${GATHER}\" или присоединить\nконтроллеры для совместной игры.", + "nameBetrayedText": "${NAME} предал ${VICTIM}.", + "nameDiedText": "${NAME} умер.", + "nameKilledText": "${NAME} убил ${VICTIM}.", + "nameNotEmptyText": "Имя не может быть пустым!", + "nameScoresText": "${NAME} ведет!", + "nameSuicideKidFriendlyText": "${NAME} случайно убился.", + "nameSuicideText": "${NAME} совершил суицид.", + "nameText": "Имя", + "nativeText": "Разрешение устройства", + "newPersonalBestText": "Новый личный рекорд!", + "newTestBuildAvailableText": "Доступна новая тестовая версия! (${VERSION} сборка ${BUILD}).\nОбновить: ${ADDRESS}", + "newText": "Новый", + "newVersionAvailableText": "Доступна новая версия ${APP_NAME}! (${VERSION})", + "nextAchievementsText": "Следующие достижения:", + "nextLevelText": "Следующий уровень", + "noAchievementsRemainingText": "- нет", + "noContinuesText": "(без продолжений)", + "noExternalStorageErrorText": "На данном устройстве не найдено внешней памяти", + "noGameCircleText": "Ошибка: не вошли в GameCircle", + "noJoinCoopMidwayText": "К кооперативным играм нельзя присоединиться посреди игры.", + "noProfilesErrorText": "У вас нет профиля игрока, так что вас будут звать '${NAME}'.\nСоздать профиль можно перейдя в 'Настройки' > 'Профили игроков'.", + "noScoresYetText": "Счета пока нет.", + "noThanksText": "Нет, спасибо", + "noTournamentsInTestBuildText": "ВНИМАНИЕ: Турнирные очки из этой тестовой сборки будут не засчитаны.", + "noValidMapsErrorText": "Для данного типа игры не найдено корректных карт.", + "notEnoughPlayersRemainingText": "Не осталось достаточно игроков; выйдите и начните новую игру.", + "notEnoughPlayersText": "Для начала этой игры нужно как минимум ${COUNT} игрока!", + "notNowText": "Не сейчас", + "notSignedInErrorText": "Войдите в аккаунт для начала.", + "notSignedInGooglePlayErrorText": "Войдите сначала в Google Play, а там посмотрим.", + "notSignedInText": "(вы не вошли)", + "notUsingAccountText": "Рекомендация: вы не используете аккаунт ${SERVICE}.\nЗайдите в 'Аккаунт' => 'зайти в ${SERVICE}', чтобы зайти в ${SERVICE}.", + "nothingIsSelectedErrorText": "Ничего не выбрано!", + "numberText": "${NUMBER}", + "offText": "Выкл", + "okText": "Oк", + "onText": "Вкл", + "oneMomentText": "Один момент…", + "onslaughtRespawnText": "${PLAYER} возродится в ${WAVE} волне", + "orText": "${A} или ${B}", + "otherText": "Другие...", + "outOfText": "(${RANK} из ${ALL})", + "ownFlagAtYourBaseWarning": "Чтобы набрать очки, ваш собственный\nфлаг должен быть на вашей базе!", + "packageModsEnabledErrorText": "Сетевая игра запрещена, когда включены моды локального пакета (см. Настройки->Дополнительно)", + "partyWindow": { + "chatMessageText": "Сообщение чата", + "emptyText": "Ваше лобби пустое", + "hostText": "(хост)", + "sendText": "Отправить", + "titleText": "Ваше лобби" + }, + "pausedByHostText": "(остановлено хостом)", + "perfectWaveText": "Идеальная волна!", + "pickUpBoldText": "ПОДНЯТЬ", + "pickUpText": "Поднять", + "playModes": { + "coopText": "Кооператив", + "freeForAllText": "Каждый сам за себя", + "multiTeamText": "Мультикомандный", + "singlePlayerCoopText": "Одиночная игра / Кооператив", + "teamsText": "Команды" + }, + "playText": "Играть", + "playWindow": { + "coopText": "Кооператив", + "freeForAllText": "Каждый за себя", + "oneToFourPlayersText": "1-4 игрока", + "teamsText": "Команды", + "titleText": "Играть", + "twoToEightPlayersText": "2-8 игроков" + }, + "playerCountAbbreviatedText": "${COUNT}и", + "playerDelayedJoinText": "${PLAYER} присоединится в следующем раунде.", + "playerInfoText": "Об игроке", + "playerLeftText": "${PLAYER} покинул игру.", + "playerLimitReachedText": "Достигнут лимит в ${COUNT} игроков. Больше добавить нельзя.", + "playerLimitReachedUnlockProText": "Обновитесь до \"${PRO}\" в магазине чтобы играть с более чем ${COUNT} игроками.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Вы не можете удалить профиль аккаунта.", + "deleteButtonText": "Удалить\nпрофиль", + "deleteConfirmText": "Удалить '${PROFILE}'?", + "editButtonText": "Изменить\nпрофиль", + "explanationText": "(настраивайте имена и внешний вид игрока)", + "newButtonText": "Новый\nпрофиль", + "titleText": "Профили игроков" + }, + "playerText": "Игрок", + "playlistNoValidGamesErrorText": "Этот плейлист содержит неоткрытые игры.", + "playlistNotFoundText": "плей-лист не найден", + "playlistText": "Плей-лист", + "playlistsText": "Плей-листы", + "pleaseRateText": "Если вам нравится ${APP_NAME}, пожалуйста, подумайте о том,\nчтобы оценить ее или написать рецензию. Это обеспечивает полезную\nобратную связь и помогает поддержать дальнейшую разработку.\n\nСпасибо!\n- Эрик", + "pleaseWaitText": "Пожалуйста, подождите...", + "pluginClassLoadErrorText": "Ошибка при попытке загрузить класс плагина '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Ошибка при инициализации плагина '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Настройки плагина", + "pluginsAutoEnableNewText": "Автоматически включать плагины", + "pluginsDetectedText": "Обнаружены новые плагины! Перезапустите игру, чтобы активировать их, или настройте их в настройках.", + "pluginsDisableAllText": "Выключить все плагины", + "pluginsEnableAllText": "Включить все плагины", + "pluginsRemovedText": "${NUM} плагин(ов) больше не найдены.", + "pluginsText": "Плагины", + "practiceText": "Тренировка", + "pressAnyButtonPlayAgainText": "Нажмите любую кнопку чтобы играть снова...", + "pressAnyButtonText": "Нажмите любую кнопку чтобы продолжить...", + "pressAnyButtonToJoinText": "нажмите любую кнопку чтобы присоединиться...", + "pressAnyKeyButtonPlayAgainText": "Нажмите любую клавишу/кнопку чтобы играть снова...", + "pressAnyKeyButtonText": "Нажмите любую клавишу/кнопку чтобы продолжить...", + "pressAnyKeyText": "Нажмите любую клавишу...", + "pressJumpToFlyText": "** Чтобы лететь, быстро нажимайте прыжок **", + "pressPunchToJoinText": "нажмите УДАР чтобы присоединиться...", + "pressToOverrideCharacterText": "нажмите ${BUTTONS} чтобы переопределить своего персонажа", + "pressToSelectProfileText": "Нажмите ${BUTTONS} чтобы выбрать игрока", + "pressToSelectTeamText": "нажмите ${BUTTONS} чтобы выбрать команду", + "profileInfoText": "Создайте профили для себя и своих друзей, чтобы\nнастроить ваши имена, цвета и персонажей.", + "promoCodeWindow": { + "codeText": "Код", + "codeTextDescription": "Промо-код", + "enterText": "Отправить" + }, + "promoSubmitErrorText": "Ошибка отправки кода, проверьте своё интернете соединение", + "ps3ControllersWindow": { + "macInstructionsText": "Выключите питание на задней панели PS3, убедитесь, что Bluetooth\nвключен на вашем компьютере, а затем подключите геймпад к Mac\nс помощью кабеля USB для синхронизации. Теперь можно использовать\nкнопку геймпад 'PS' чтобы подключить его к Mac\nв проводном (USB) или беспроводном (Bluetooth) режиме.\n\nНа некоторых системах Mac при синхронизации может потребоваться код доступа.\nВ этом случае обратитесь к следующей инструкции (или к Google).\n\n\n\n\nГеймпады PS3, связанные по беспроводной сети, должны появиться\nв списке устройств в Настройках системы -> Bluetooth. Возможно, вам придется\nудалить их из этого списка, если вы хотите снова использовать их с PS3.\n\nТакже всегда отключайте их от Bluetooth, когда он не используется,\nиначе будут садиться батарейки.\n\nBluetooth должен обрабатывать до 7 подключенных устройств,\nхотя у вас может получиться по-другому.", + "ouyaInstructionsText": "Чтобы использовать геймпад PS3 с OUYA, просто подключите его один раз\nс помощью кабеля USB для синхронизации. Это может отключить другие\nгеймпады, тогда нужно перезагрузить OUYA и отсоединить кабель USB.\n\nПосле этого можно использовать кнопку 'PS' геймпада для беспроводного\nподключения. После игры нажмите и удерживайте кнопку 'PS' в течение\n10 секунд чтобы выключить геймпад, в противном случае он может\nостаться включенным и разрядит батарейки.", + "pairingTutorialText": "видео по связыванию", + "titleText": "Использование геймпада PS3 с ${APP_NAME}:" + }, + "publicBetaText": "ОТКРЫТАЯ БЕТА-ВЕРСИЯ", + "punchBoldText": "УДАР", + "punchText": "Ударить", + "purchaseForText": "Купить за ${PRICE}", + "purchaseGameText": "Купить игру", + "purchasingText": "Покупка...", + "quitGameText": "Выйти из ${APP_NAME}?", + "quittingIn5SecondsText": "Выход через 5 секунд...", + "randomPlayerNamesText": "Дима, Кузя, Вован, Маха, Русский, Какуля, Бибер, Борька, Няшка, Толян, Ержан, Дибисяра, Вася, Морген, Серёга, Ваня, Кеша, Жорик, Стёпа, Эдгар, Цыган, Олег, Егор, Ёршик", + "randomText": "Случайный", + "rankText": "Ранг", + "ratingText": "Рейтинг", + "reachWave2Text": "Достигните второй волны, чтобы получить ранг.", + "readyText": "готов", + "recentText": "Последний", + "remainingInTrialText": "осталось в пробной версии", + "remoteAppInfoShortText": "Играть в ${APP_NAME} с семьей или друзьями гораздо веселее.\nПодключите один или несколько джойстиков или установите\n${REMOTE_APP_NAME} на свои устройства, чтобы использовать\nих в качестве джойстиков.", + "remote_app": { + "app_name": "Пульт BombSquad", + "app_name_short": "Пульт BS", + "button_position": "Положение кнопки", + "button_size": "Размер кнопки", + "cant_resolve_host": "Сервер не найден.", + "capturing": "Слушаю...", + "connected": "Соединено.", + "description": "Используйте Ваш телефон или планшет как контроллер BombSquad.\nДо 8 устройств могут быть одновременно подключены для эпических битв в мультиплеере на одном ТВ или планшете.", + "disconnected": "Выброшен сервером.", + "dpad_fixed": "неподвижный", + "dpad_floating": "плавающий", + "dpad_position": "Расположение D-Pad", + "dpad_size": "Размер D-Pad", + "dpad_type": "Тип D-Pad", + "enter_an_address": "Введите адрес", + "game_full": "Комната заполнена или соединения не принимаются.", + "game_shut_down": "Сервер отключился.", + "hardware_buttons": "Аппаратные кнопки", + "join_by_address": "Присоединиться по адресу...", + "lag": "Лаг: ${SECONDS} секунд", + "reset": "Сброс", + "run1": "Бег 1", + "run2": "Бег 2", + "searching": "Ищем игры BombSquad...", + "searching_caption": "Нажмите на название игры для входа.\nУбедитесь, что вы находитесь в той же сети, что и игра.", + "start": "Старт", + "version_mismatch": "Несовпадение версий.\nУбедитесь, что BombSquad и контроллер BombSquad\nобновлены до последней версии и повторите попытку." + }, + "removeInGameAdsText": "Разблокируйте \"${PRO}\" в магазине, чтобы убрать рекламу в игре.", + "renameText": "Переименовать", + "replayEndText": "Завершить просмотр записи", + "replayNameDefaultText": "Запись последней игры", + "replayReadErrorText": "Ошибка чтения файла записи.", + "replayRenameWarningText": "Переименуйте запись \"${REPLAY}\" чтобы ее сохранить; иначе она будет перезаписана.", + "replayVersionErrorText": "К сожалению, эта запись была сделана в другой\nверсии игры и не может быть использована.", + "replayWatchText": "Смотреть запись", + "replayWriteErrorText": "Ошибка записи файла записи.", + "replaysText": "Записи", + "reportPlayerExplanationText": "Пожалуйтесь по этому адресу на читеров, грубиянов или кто плохо себя ведет.\nОпишите чем недовольны:", + "reportThisPlayerCheatingText": "Нечестный игрок", + "reportThisPlayerLanguageText": "Грубиян", + "reportThisPlayerReasonText": "На что хотите пожаловаться?", + "reportThisPlayerText": "Жалоба на Игрока", + "requestingText": "Запрос данных...", + "restartText": "Начать заново", + "retryText": "Повтор", + "revertText": "Восстановить", + "runText": "Бежать", + "saveText": "Сохранить", + "scanScriptsErrorText": "Ошибка(и) сканирования скриптов; посмотри лог для подробностей.", + "scoreChallengesText": "Медали за очки", + "scoreListUnavailableText": "Список очков недоступен.", + "scoreText": "Очки", + "scoreUnits": { + "millisecondsText": "Миллисекунды", + "pointsText": "Очки", + "secondsText": "Секунды" + }, + "scoreWasText": "(было ${COUNT})", + "selectText": "Выбрать", + "seriesWinLine1PlayerText": "ПОБЕДИЛ В", + "seriesWinLine1TeamText": "ПОБЕДИЛИ В", + "seriesWinLine1Text": "ПОБЕДИЛ В", + "seriesWinLine2Text": "СЕРИИ!", + "settingsWindow": { + "accountText": "Аккаунт", + "advancedText": "Дополнительно", + "audioText": "Аудио", + "controllersText": "Контроллеры", + "graphicsText": "Графика", + "playerProfilesMovedText": "Примечание: Профили игроков были перемещены в окно Аккаунты в главном меню.", + "playerProfilesText": "Профили игроков", + "titleText": "Настройки" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(простая, удобная для контроллера виртуальная клавиатура для ввода текста)", + "alwaysUseInternalKeyboardText": "Всегда использовать встроенную клавиатуру", + "benchmarksText": "Тест производительности и тест-нагрузка", + "disableCameraGyroscopeMotionText": "Отключить движение камеры с помощью гироскопа", + "disableCameraShakeText": "Отключить тряску камеры", + "disableThisNotice": "(вы можете отключить это уведомление в настройках)", + "enablePackageModsDescriptionText": "(позволяет дополнительные возможности для моддинга, но отключает сетевую игру)", + "enablePackageModsText": "Включить моды локального пакета", + "enterPromoCodeText": "Введите промо-код", + "forTestingText": "Примечание: эти значения используются только для тестирования и будут потеряны, когда приложение завершит работу.", + "helpTranslateText": "Переводы игры ${APP_NAME} с английского совершён общественными\nусилиями. Если вы хотите предложить или исправить\nперевод, следуйте по ссылке ниже. Заранее спасибо!", + "kickIdlePlayersText": "Выкидывать бездействующих игроков", + "kidFriendlyModeText": "Семейный режим (меньше насилия, и т.д.)", + "languageText": "Язык", + "moddingGuideText": "Руководство по моддингу", + "mustRestartText": "Необходимо перезапустить игру, чтобы изменения вступили в силу.", + "netTestingText": "Тестирование сети", + "resetText": "Сбросить", + "showBombTrajectoriesText": "Показывать траекторию бомбы", + "showInGamePingText": "Показать Ping", + "showPlayerNamesText": "Показывать имена игроков", + "showUserModsText": "Показать папку модов", + "titleText": "Дополнительно", + "translationEditorButtonText": "Редактор перевода ${APP_NAME}", + "translationFetchErrorText": "статус перевода недоступен", + "translationFetchingStatusText": "проверка статуса перевода...", + "translationInformMe": "Сообщите мне, если мой язык нуждается в обновлениях", + "translationNoUpdateNeededText": "данный язык полностью обновлен, ура!", + "translationUpdateNeededText": "** данный язык нуждается в обновлениях!! **", + "vrTestingText": "Тестирование VR" + }, + "shareText": "Поделиться", + "sharingText": "Делимся...", + "showText": "Показать", + "signInForPromoCodeText": "Вы должны войти в аккаунт для активации кода.", + "signInWithGameCenterText": "Чтобы использовать аккаунт GameCenter,\nвойдите через GameCenter.", + "singleGamePlaylistNameText": "Просто ${GAME}", + "singlePlayerCountText": "1 игрок", + "soloNameFilterText": "${NAME} соло", + "soundtrackTypeNames": { + "CharSelect": "Выбор персонажа", + "Chosen One": "Избранный", + "Epic": "Игры в эпическом режиме", + "Epic Race": "Эпическая гонка", + "FlagCatcher": "Захват флага", + "Flying": "Счастливые мысли", + "Football": "Регби", + "ForwardMarch": "Нападение", + "GrandRomp": "Завоевание", + "Hockey": "Хоккей", + "Keep Away": "Не подходить!", + "Marching": "Манёвр", + "Menu": "Главное меню", + "Onslaught": "Атака", + "Race": "Гонка", + "Scary": "Царь горы", + "Scores": "Счетное табло", + "Survival": "Ликвидация", + "ToTheDeath": "Смертельный бой", + "Victory": "Табло финального счета" + }, + "spaceKeyText": "пробел", + "statsText": "Статистика", + "storagePermissionAccessText": "Это требует доступа к хранилищу", + "store": { + "alreadyOwnText": "У вас уже есть ${NAME}!", + "bombSquadProDescriptionText": "• Удваивает билеты заработанные за достижения\n• Убирает внутриигровую рекламу\n• Включает ${COUNT} бонусных билетов\n• +${PERCENT}% дополнительных очков лиги\n• Разблокировывает '${INF_ONSLAUGHT}' и\n '${INF_RUNAROUND}' кооперативные уровни", + "bombSquadProFeaturesText": "Особенности:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "- Убирает рекламу\n- Откроет мини-игры\n- Также включает:", + "buyText": "Купить", + "charactersText": "Персонажи", + "comingSoonText": "Скоро…", + "extrasText": "Дополнительно", + "freeBombSquadProText": "BombSquad теперь бесплатная игра, но если вы приобрели ее ранее, то вы\nполучаете обновление BombSquad Pro и ${COUNT} билетов в качестве благодарности.\nНаслаждайтесь новыми возможностями, и спасибо за вашу поддержку! \n-Эрик", + "gameUpgradesText": "Обновления игры", + "getCoinsText": "Купить монеты", + "holidaySpecialText": "Праздничная акция", + "howToSwitchCharactersText": "(Зайдите в \"${SETTINGS} -> ${PLAYER_PROFILES}\", чтобы выбрать и изменить персонажей)", + "howToUseIconsText": "(создайте глобальные профили игроков (в окне аккаунт) чтобы использовать это)", + "howToUseMapsText": "(используйте эти карты в ваших собственных командных/все-против-всех плейлистах)", + "iconsText": "Иконки", + "loadErrorText": "Не удается загрузить страницу.\nПроверьте подключение к Интернету.", + "loadingText": "загрузка", + "mapsText": "Карты", + "miniGamesText": "Мини-игры", + "oneTimeOnlyText": "(только один раз)", + "purchaseAlreadyInProgressText": "Эта покупка уже выполняется.", + "purchaseConfirmText": "Купить ${ITEM}?", + "purchaseNotValidError": "Покупка недействительна.\nЕсли это ошибка, обратитесь к ${EMAIL}.", + "purchaseText": "Купить", + "saleBundleText": "Распродажа в комплекте!", + "saleExclaimText": "Распродажа!", + "salePercentText": "(Скидка ${PERCENT}%)", + "saleText": "СКИДКА", + "searchText": "Поиск", + "teamsFreeForAllGamesText": "Командные игры / Каждый сам за себя", + "totalWorthText": "*** ${TOTAL_WORTH} значение! ***", + "upgradeQuestionText": "Обновить?", + "winterSpecialText": "Зимняя акция", + "youOwnThisText": "- у вас это уже есть -" + }, + "storeDescriptionText": "Игровое безумие с 8 игроками!\n\nВзрывайте своих друзей (или ботов) в турнире взрывных мини-игр, таких как Захват флага и Эпический смертельный бой замедленного действия!\n\nС простым управлением и расширенной поддержкой контроллеров 8 человек могут присоединиться к действию, можно даже использовать мобильные устройства как контроллеры через бесплатное приложение 'BombSquad Remote'!\n\nВ атаку!\n\nСм. www.froemling.net/BombSquad для дополнительной информации.", + "storeDescriptions": { + "blowUpYourFriendsText": "Взорви друзей.", + "competeInMiniGamesText": "Соревнуйтесь в мини-играх от гонок до левитации.", + "customize2Text": "Настройка персонажей, мини-игр и даже саундтрека.", + "customizeText": "Настройка персонажей и создание своих собственных плей-листов мини-игр.", + "sportsMoreFunText": "Спорт веселее со взрывчаткой.", + "teamUpAgainstComputerText": "Команды против компьютера." + }, + "storeText": "Магазин", + "submitText": "Отправить", + "submittingPromoCodeText": "Активация кода....", + "teamNamesColorText": "имена/цвета команд", + "teamsText": "Команды", + "telnetAccessGrantedText": "Доступ Telnet включен.", + "telnetAccessText": "Обнаружен доступ Telnet. Разрешить?", + "testBuildErrorText": "Эта версия устарела, пожалуйста, проверьте обновления.", + "testBuildText": "Тестовая версия", + "testBuildValidateErrorText": "Не удается проверить тестовую сборку. (нет соединения с сетью?)", + "testBuildValidatedText": "Тестовая сборка проверена. Наслаждайтесь!", + "thankYouText": "Спасибо за вашу поддержку! Веселой игры!!", + "threeKillText": "ТРЕХ ЗА РАЗ!!", + "timeBonusText": "Бонус времени", + "timeElapsedText": "Прошло времени", + "timeExpiredText": "Время вышло", + "timeSuffixDaysText": "${COUNT}д", + "timeSuffixHoursText": "${COUNT}ч", + "timeSuffixMinutesText": "${COUNT}м", + "timeSuffixSecondsText": "${COUNT}с", + "tipText": "Подсказка", + "titleText": "BombSquad", + "titleVRText": "BombSquad ВР", + "topFriendsText": "Топ друзей", + "tournamentCheckingStateText": "Проверка статуса турнира, пожалуйста, подождите...", + "tournamentEndedText": "Турнир закончился. Скоро начнется новый.", + "tournamentEntryText": "Вход в турнир", + "tournamentResultsRecentText": "Последние Результаты турнира", + "tournamentStandingsText": "Позиции в турнире", + "tournamentText": "Турнир", + "tournamentTimeExpiredText": "Время турнира истекло", + "tournamentsDisabledWorkspaceText": "Турниры заблокированы пока рабочие пространства включены.\nДля включения турниров, отключите рабочие места и перезапустите игру.", + "tournamentsText": "Турниры", + "translations": { + "characterNames": { + "Agent Johnson": "Агент Джонсон", + "B-9000": "B-9000", + "Bernard": "Бернард", + "Bones": "Костяшка", + "Butch": "Силач", + "Easter Bunny": "Пасхальный кролик", + "Flopsy": "Флопси", + "Frosty": "Снежный", + "Gretel": "Гретель", + "Grumbledorf": "Грамблдорф", + "Jack Morgan": "Джек Морган", + "Kronk": "Кронк", + "Lee": "Ли", + "Lucky": "Счастливчик", + "Mel": "Мэл", + "Middle-Man": "Средняк", + "Minimus": "Минимус", + "Pascal": "Паскаль", + "Pixel": "Пиксель", + "Sammy Slam": "Сэмми Слэм", + "Santa Claus": "Санта Клаус", + "Snake Shadow": "Тень Змеи", + "Spaz": "Спаз", + "Taobao Mascot": "Талисман Таобао", + "Todd": "Тодд", + "Todd McBurton": "Тодд МакБартон", + "Xara": "Ксара", + "Zoe": "Зои", + "Zola": "Зола" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Бесконечная\nатака", + "Infinite\nRunaround": "Бесконечный\nманевр", + "Onslaught\nTraining": "Атака:\nтренировка", + "Pro\nFootball": "Регби\nпрофи", + "Pro\nOnslaught": "Атака\nпрофи", + "Pro\nRunaround": "Манёвр\nпрофи", + "Rookie\nFootball": "Регби\nдля новичков", + "Rookie\nOnslaught": "Атака\nдля новичков", + "The\nLast Stand": "Последний\nрубеж", + "Uber\nFootball": "Убер\nрегби", + "Uber\nOnslaught": "Убер\nатака", + "Uber\nRunaround": "Убер\nманёвр" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME}: тренировка", + "Infinite ${GAME}": "Бесконечный уровень ${GAME}", + "Infinite Onslaught": "Бесконечная атака", + "Infinite Runaround": "Бесконечная беготня", + "Onslaught": "Бесконечная атака", + "Onslaught Training": "Атака: тренировка", + "Pro ${GAME}": "${GAME} профи", + "Pro Football": "Регби профи", + "Pro Onslaught": "Атака профи", + "Pro Runaround": "Беготня профи", + "Rookie ${GAME}": "${GAME} для новичков", + "Rookie Football": "Регби для новичков", + "Rookie Onslaught": "Атака для новичков", + "Runaround": "Бесконечный манёвр", + "The Last Stand": "Последний рубеж", + "Uber ${GAME}": "Убер ${GAME}", + "Uber Football": "Убер регби", + "Uber Onslaught": "Убер атака", + "Uber Runaround": "Убер беготня" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Чтобы победить, стань избранным на некоторое время.\nЧтобы стать избранным, убей избранного.", + "Bomb as many targets as you can.": "Взорвите столько мишеней, сколько сможете.", + "Carry the flag for ${ARG1} seconds.": "Пронесите флаг в течение ${ARG1} секунд.", + "Carry the flag for a set length of time.": "Пронесите флаг в течение заданного времени.", + "Crush ${ARG1} of your enemies.": "Разбейте ${ARG1} врагов.", + "Defeat all enemies.": "Победите всех врагов.", + "Dodge the falling bombs.": "Увернитесь от падающих бомб.", + "Final glorious epic slow motion battle to the death.": "Финальная эпическая смертельная битва в замедленном действии.", + "Gather eggs!": "Соберите яйца!", + "Get the flag to the enemy end zone.": "Отнесите флаг в зону защиты противника.", + "How fast can you defeat the ninjas?": "Как быстро вы сможете победить ниндзя?", + "Kill a set number of enemies to win.": "Убейте заданное число врагов, чтобы выиграть.", + "Last one standing wins.": "Побеждает последний живой игрок.", + "Last remaining alive wins.": "Побеждает последний живой игрок.", + "Last team standing wins.": "Побеждает последняя живая команда.", + "Prevent enemies from reaching the exit.": "Не дайте врагам дойти до выхода.", + "Reach the enemy flag to score.": "Доберитесь до вражеского флага чтобы набрать очки.", + "Return the enemy flag to score.": "Принесите вражеский флаг на базу, чтобы набрать очки.", + "Run ${ARG1} laps.": "Пробегите ${ARG1} кругов.", + "Run ${ARG1} laps. Your entire team has to finish.": "Пробегите ${ARG1} кругов. Финишировать должна вся команда.", + "Run 1 lap.": "Пробегите 1 круг.", + "Run 1 lap. Your entire team has to finish.": "Пробегите 1 круг. Финишировать должна вся команда.", + "Run real fast!": "Бегите очень быстро!", + "Score ${ARG1} goals.": "Забейте ${ARG1} голов.", + "Score ${ARG1} touchdowns.": "Сделайте ${ARG1} тачдауна.", + "Score a goal": "Забейте гол", + "Score a goal.": "Забейте гол.", + "Score a touchdown.": "Сделайте тачдаун.", + "Score some goals.": "Забейте несколько голов.", + "Secure all ${ARG1} flags.": "Захватите все флаги: ${ARG1}.", + "Secure all flags on the map to win.": "Захватите все флаги на карте, чтобы выиграть.", + "Secure the flag for ${ARG1} seconds.": "Захватите флаг на ${ARG1} секунд.", + "Secure the flag for a set length of time.": "Захватите флаг на определенное время.", + "Steal the enemy flag ${ARG1} times.": "Украдите вражеский флаг ${ARG1} раз.", + "Steal the enemy flag.": "Украдите вражеский флаг.", + "There can be only one.": "Может быть только один.", + "Touch the enemy flag ${ARG1} times.": "Коснитесь вражеского флага ${ARG1} раз.", + "Touch the enemy flag.": "Коснитесь вражеского флага.", + "carry the flag for ${ARG1} seconds": "пронесите флаг в течение ${ARG1} секунд", + "kill ${ARG1} enemies": "убейте ${ARG1} врагов", + "last one standing wins": "побеждает последний живой игрок", + "last team standing wins": "побеждает последняя живая команда", + "return ${ARG1} flags": "принесите ${ARG1} флагов на базу", + "return 1 flag": "принесите 1 флаг на базу", + "run ${ARG1} laps": "пробегите ${ARG1} кругов", + "run 1 lap": "пробегите 1 круг", + "score ${ARG1} goals": "забейте ${ARG1} голов", + "score ${ARG1} touchdowns": "сделайте ${ARG1} тачдауна", + "score a goal": "забейте гол", + "score a touchdown": "сделайте тачдаун", + "secure all ${ARG1} flags": "захватите все флаги: ${ARG1}", + "secure the flag for ${ARG1} seconds": "захватите флаг на ${ARG1} секунд", + "touch ${ARG1} flags": "коснитесь ${ARG1} флагов", + "touch 1 flag": "коснитесь 1 флага" + }, + "gameNames": { + "Assault": "Нападение", + "Capture the Flag": "Захват флага", + "Chosen One": "Избранный", + "Conquest": "Завоевание", + "Death Match": "Смертельный бой", + "Easter Egg Hunt": "Сбор пасхальных яиц", + "Elimination": "Ликвидация", + "Football": "Регби", + "Hockey": "Хоккей", + "Keep Away": "Не подходить!", + "King of the Hill": "Царь горы", + "Meteor Shower": "Метеоритный дождь", + "Ninja Fight": "Бой с ниндзя", + "Onslaught": "Атака", + "Race": "Гонка", + "Runaround": "Обход", + "Target Practice": "Стрельба по мишеням", + "The Last Stand": "Последний рубеж" + }, + "inputDeviceNames": { + "Keyboard": "Клавиатура", + "Keyboard P2": "Клавиатура игрока 2" + }, + "languages": { + "Arabic": "Арабский", + "Belarussian": "Белорусский", + "Chinese": "Китайский упрощенный", + "ChineseTraditional": "Китайский традиционный", + "Croatian": "Хорватский", + "Czech": "Чешский", + "Danish": "Датский", + "Dutch": "Голландский", + "English": "Английский", + "Esperanto": "Эсперанто", + "Filipino": "Филипинский", + "Finnish": "Финский", + "French": "Французский", + "German": "Немецкий", + "Gibberish": "Чепухейский", + "Greek": "Греческий", + "Hindi": "Хинди", + "Hungarian": "Венгерский", + "Indonesian": "Индонезийский", + "Italian": "Итальянский", + "Japanese": "Японский", + "Korean": "Корейский", + "Malay": "Малайский", + "Persian": "Персидский", + "Polish": "Польский", + "Portuguese": "Португальский", + "Romanian": "Румынский", + "Russian": "Русский", + "Serbian": "Сербский", + "Slovak": "Словацкий", + "Spanish": "Испанский", + "Swedish": "Шведский", + "Tamil": "Тамильский", + "Thai": "Тайский", + "Turkish": "Турецкий", + "Ukrainian": "Украинский", + "Venetian": "Венецианский", + "Vietnamese": "Вьетнамский" + }, + "leagueNames": { + "Bronze": "Бронзовая", + "Diamond": "Бриллиантовая", + "Gold": "Золотая", + "Silver": "Серебряная" + }, + "mapsNames": { + "Big G": "Большая G", + "Bridgit": "Мостики", + "Courtyard": "Внутренний двор", + "Crag Castle": "Замок на скале", + "Doom Shroom": "Роковой гриб", + "Football Stadium": "Стадион регби", + "Happy Thoughts": "Счастливые мысли", + "Hockey Stadium": "Хоккейный стадион", + "Lake Frigid": "Ледяное озеро", + "Monkey Face": "Обезьяна", + "Rampage": "Беспредел", + "Roundabout": "Кольцевая", + "Step Right Up": "Проходите", + "The Pad": "Подушка", + "Tip Top": "Тип-топ", + "Tower D": "Башня D", + "Zigzag": "Зигзаг" + }, + "playlistNames": { + "Just Epic": "Только эпический", + "Just Sports": "Только спорт" + }, + "promoCodeResponses": { + "invalid promo code": "недействительный промо-код" + }, + "scoreNames": { + "Flags": "Флаги", + "Goals": "Голы", + "Score": "Очки", + "Survived": "Выжил", + "Time": "Время", + "Time Held": "Время удержания" + }, + "serverResponses": { + "A code has already been used on this account.": "Код уже был активирован на этом аккаунте.", + "A reward has already been given for that address.": "Эта награда уже была выдана на этот IP-адрес", + "Account linking successful!": "Аккаунт успешно привязан!", + "Account unlinking successful!": "Аккаунт успешно отвязан!", + "Accounts are already linked.": "Аккаунты уже привязаны.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Просмотр рекламы не удалось проверить.\nПожалуйста, убедитесь, что вы используете официальную и актуальную версию игры.", + "An error has occurred; (${ERROR})": "Произошла ошибка; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "произошла ошибка;Пожалуйста обратитесь в службу поддержки. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Произошла ошибка; пожалуйста, свяжитесь с support@froemling.net.", + "An error has occurred; please try again later.": "Произошла ошибка, пожалуйста, повторите попытку позже.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Точно хотите связать аккаунты?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nОтменить будет нельзя!", + "BombSquad Pro unlocked!": "BombSquad Pro разблокирован!", + "Can't link 2 accounts of this type.": "Невозможно связать 2 аккаунта этого типа.", + "Can't link 2 diamond league accounts.": "Невозможно связать 2 аккаунта бриллиантовой лиги.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Невозможно связать; будет превышен максимум ${COUNT} связанных аккаунтов.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Ах ты, читер; Очки и награды заморожены на ${COUNT} дней.", + "Could not establish a secure connection.": "Не удалось установить безопасное соединение.", + "Daily maximum reached.": "Хватит на сегодня.", + "Entering tournament...": "Вход в турнир...", + "Invalid code.": "Неверный код.", + "Invalid payment; purchase canceled.": "Что-то пошло не так. Покупка отменена.", + "Invalid promo code.": "Неверный промо-код.", + "Invalid purchase.": "Ошибка транзакции.", + "Invalid tournament entry; score will be ignored.": "Неверная заявка на турнир; счет будет проигнорирован.", + "Item unlocked!": "Предмет разблокирован!!!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "СВЯЗКА ЗАПРЕЩЕНА. ${ACCOUNT} содержит \nважные данные, которые БУДУТ ПОТЕРЯНЫ.\nВы можете связать в обратном порядке\n(и потерять данные ЭТОГО аккаунта)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Связать этот ${ACCOUNT} аккаунт с этим?\nВсе существующие данные на ${ACCOUNT} будут потеряны.\nЭто действие не может быть отменено. Вы уверены?", + "Max number of playlists reached.": "Достигнуто максимальное количество плейлистов.", + "Max number of profiles reached.": "Достигнуто максимальное количество профилей.", + "Maximum friend code rewards reached.": "Достигнут лимит кодов.", + "Message is too long.": "Сообщение слишком длинное.", + "No servers are available. Please try again soon.": "Нет доступных серверов. Пожалуйста попробуйте позднее.", + "Profile \"${NAME}\" upgraded successfully.": "Профиль \"${NAME}\" обновлен успешно.", + "Profile could not be upgraded.": "Профиль не может быть обновлен.", + "Purchase successful!": "Успешная транзакция!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Получено ${COUNT} билетов за вход.\nПриходите завтра, чтобы получить ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Функциональность сервера больше не поддерживается в этой версии игры;\nПожалуйста обновите игру.", + "Sorry, there are no uses remaining on this code.": "Упс, код больше не может быть активирован.", + "Sorry, this code has already been used.": "Упс, этот код уже использован.", + "Sorry, this code has expired.": "Упс, время действия кода истекло.", + "Sorry, this code only works for new accounts.": "Упс, этот код работает только для новых аккаунтов.", + "Still searching for nearby servers; please try again soon.": "Ведётся поиск ближайших серверов; пожалуйста попробуйте позднее.", + "Temporarily unavailable; please try again later.": "Временно недоступно; Пожалуйста, повторите попытку позже.", + "The tournament ended before you finished.": "Турнир закончился прежде, чем вы закончили.", + "This account cannot be unlinked for ${NUM} days.": "Этот аккаунт невозможно отвязать в течение ${NUM} дней.", + "This code cannot be used on the account that created it.": "Этот код не может быть использован его создателем.", + "This is currently unavailable; please try again later.": "В настоящее время он недоступен; пожалуйста, повторите попытку позже", + "This requires version ${VERSION} or newer.": "Для этого необходима версия ${VERSION} или новее.", + "Tournaments disabled due to rooted device.": "Турниры отключены из-за рутированного устройства.", + "Tournaments require ${VERSION} or newer": "Для турниров требуется версия ${VERSION} или выше.", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Отвязать ${ACCOUNT} от этого аккаунта?\nВсе данные на ${ACCOUNT} будут сброшены.\n(за исключением достижений в некоторых случаях)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ПРЕДУПРЕЖДЕНИЕ: жалобы на хакерство были выданы на вашу учетную запись.\nУчетные записи, которые считаются взломанными, будут заблокированы. Пожалуйста, играйте честно.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Желаете связать аккаунт устройства вот c этим?\n\nАккаунт устройства ${ACCOUNT1}\nТекущий аккаунт ${ACCOUNT2}\n\nЭто позволит сохранить ваши нынешние достижения.\nВнимание: отмена невозможна!", + "You already own this!": "Вы это уже приобрели!", + "You can join in ${COUNT} seconds.": "Ты можешь войти через ${COUNT} секунд", + "You don't have enough tickets for this!": "У вас недостаточно билетов для этой покупки!", + "You don't own that.": "У вас этого нету.", + "You got ${COUNT} tickets!": "Вы получили ${COUNT} билетов!", + "You got a ${ITEM}!": "Вы получили ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Вас повысили и перевели в новую лигу; поздравляем!", + "You must update to a newer version of the app to do this.": "Чтобы это сделать, вы должны обновить приложение.", + "You must update to the newest version of the game to do this.": "Вы должны обновиться до новейшей версии игры, чтобы сделать это.", + "You must wait a few seconds before entering a new code.": "Подождите несколько секунд, прежде чем вводить новый код.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ваш ранг в последнем турнире: ${RANK}! Спасибо за игру!", + "Your account was rejected. Are you signed in?": "Ваш аккаунт отклонён. Вы вошли в систему?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ваша версия игры была модифицирована.\nУберите все изменения и попробуйте снова.", + "Your friend code was used by ${ACCOUNT}": "Ваш код был использован ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 минута", + "1 Second": "1 секунда", + "10 Minutes": "10 минут", + "2 Minutes": "2 минуты", + "2 Seconds": "2 секунды", + "20 Minutes": "20 минут", + "4 Seconds": "4 секунды", + "5 Minutes": "5 минут", + "8 Seconds": "8 секунд", + "Allow Negative Scores": "Разрешить отрицательный счет", + "Balance Total Lives": "Распределять оставшиеся жизни", + "Bomb Spawning": "Появление бомб", + "Chosen One Gets Gloves": "Избранный получает перчатки", + "Chosen One Gets Shield": "Избранный получает щит", + "Chosen One Time": "Время избранного", + "Enable Impact Bombs": "Включить ударные бомбы", + "Enable Triple Bombs": "Включить тройные бомбы", + "Entire Team Must Finish": "Вся команда должна финишировать", + "Epic Mode": "Эпический режим", + "Flag Idle Return Time": "Время возврата брошенного флага", + "Flag Touch Return Time": "Время захвата флага", + "Hold Time": "Время удержания", + "Kills to Win Per Player": "Убийств на игрока до победы", + "Laps": "Круги", + "Lives Per Player": "Жизней на игрока", + "Long": "Долго", + "Longer": "Дольше", + "Mine Spawning": "Минирование", + "No Mines": "Без мин", + "None": "Нет", + "Normal": "Норм.", + "Pro Mode": "Профессиональный режим", + "Respawn Times": "Время до воскрешения", + "Score to Win": "Очков для победы", + "Short": "Коротк.", + "Shorter": "Короче", + "Solo Mode": "Режим соло", + "Target Count": "Количество целей", + "Time Limit": "Лимит времени" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} дисквалифицирована потому что ${PLAYER} вышел", + "Killing ${NAME} for skipping part of the track!": "Ликвидация ${NAME} за срезание трассы!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Предупреждение для ${NAME}: за турбо / быстрое повторное нажатие кнопки можно вырубится." + }, + "teamNames": { + "Bad Guys": "Негодяи", + "Blue": "Синие", + "Good Guys": "Добряки", + "Red": "Красные" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Идеально выполненная последовательность бег-прыжок-поворот-удар может убить\nодним ударом и заработать вам пожизненное уважение друзей.", + "Always remember to floss.": "Не забывайте пользоваться зубной нитью.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Создайте профили игроков для себя и своих друзей с собственными\nименами и внешностью вместо случайных.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Ящики с проклятием превращают вас в тикающую бомбу.\nЕдинственное лекарство - быстро схватить аптечку.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Независимо от внешности, способности всех персонажей идентичны,\nтак что просто выбирайте того, на кого вы больше похожи.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Не зазнавайтесь с этим энергетическим щитом, вас все еще могут сбросить с обрыва.", + "Don't run all the time. Really. You will fall off cliffs.": "Не бегай все время. Серьезно. Свалишься с обрыва.", + "Don't spin for too long; you'll become dizzy and fall.": "Не крутись долго; у тебя закружится голова и ты упадёшь.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Для бега нажмите и держите любую кнопку. (Для этого удобны триггеры, если они есть)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Для бега удерживайте любую кнопку. Бегать, конечно, быстрее,\nзато труднее поворачивать, так что не забывайте про обрывы.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ледяные бомбы не очень мощные, но они замораживают\nвсех вокруг, оставляя их хрупкими и беззащитными.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Если кто-то вас схатил, бейте, и вас отпустят.\nВ реальной жизни это тоже работает.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Если вам не хватает контроллеров, установите приложение '${REMOTE_APP_NAME}' \nна ваши мобильные устройства, чтобы использовать их в качестве контроллеров.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Если не хватает контроллеров, установите приложение 'BombSquad Remote' на\nустройства iOS или Android, чтобы использовать их в качестве контроллеров.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Если к вам прилипла липкая бомба, прыгайте и крутитесь. Может повезет\nстряхнуть бомбу или, на худой конец, повеселить окружающих.", + "If you kill an enemy in one hit you get double points for it.": "Если убиваешь врага с одного удара, то получаешь двойные очки.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Если подхватили проклятие, то единственная надежда на выживание\n- это найти аптечку в ближайшие несколько секунд.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Не стой на месте – помрешь. Беги и уворачивайся чтобы выжить..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Если у вас много игроков, которые приходят и уходят, включите \"автоматически выкидывать\nбездействующих игроков\" в настройках на случай, если кто-то забудет выйти из игры.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Если ваше устройство нагревается или вы хотите сохранить заряд батареи,\nуменьшите \"Визуальные эффекты\" или \"Разрешение\" в Настройки->Графика", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Если картинка прерывистая, попробуйте уменьшить разрешение\nили визуальные эффекты в настройках графики в игре.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "В Захвате флага, чтобы набрать очки, свой собственный флаг должен быть на базе.\nЕсли другая команда вот-вот забьет, можно украсть их флаг, чтобы их остановить.", + "In hockey, you'll maintain more speed if you turn gradually.": "В хоккее можно поддерживать более высокую скорость, если поворачивать постепенно.", + "It's easier to win with a friend or two helping.": "Выиграть легче всего с помощью друга или двух.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Прыгни прямо перед броском, чтобы забросить бомбу как можно выше.", + "Land-mines are a good way to stop speedy enemies.": "Мины - неплохой способ остановить быстроногих врагов.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Можно много чего поднять и бросить, включая других игроков. Швыряние врагов\nс обрыва бывает эффективной и бодрящей стратегией.", + "No, you can't get up on the ledge. You have to throw bombs.": "Нет, вы не сможете залезть на выступ. Бросайте бомбы.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Игроки могут присоединяться и уходить посреди игры,\nтакже можно подключать и отключать контроллеры прямо на лету.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Игроки могут присоединяться и выходить в середине большинства игр,\nтакже можно подключать и отключать геймпады на лету.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Усилители ограничены по времени только в кооперативных играх.\nВ команых играх и 'каждый за себя' они ваши пожизненно.", + "Practice using your momentum to throw bombs more accurately.": "Тренируйтесь использовать инерцию для более точных бросков.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Удары наносят тем больше ущерба, чем быстрее двигаются кулаки,\nтак что старайтесь бегать, прыгать и крутиться, как ненормальные.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Пробегитесь туда-обратно перед броском, чтобы\n'подкрутить' бомбу и бросить ее дальше.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Сметите группу врагов, взорвав\nбомбу возле коробки TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Голова - самое уязвимое место, так что липкая бомба\nпо чайнику, как правило, означает капут.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Этот уровень бесконечен, но высокие очки здесь\nзаработают вам вечное уважение во всем мире.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Сила броска зависит от направления, которое нажато. Чтобы аккуратно\nбросить что-то прямо перед собой, не нажимайте ни в каком направлении.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Надоел саундтрек? Замените его собственным!\nСмотрите Настройки->Аудио->Саундтрек", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Попробуйте 'подогреть' бомбы секунду или две, прежде чем их бросить.", + "Try tricking enemies into killing eachother or running off cliffs.": "Попробуйте обмануть врагов, чтобы они убили друг друга или прыгнули с обрыва.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Используйте кнопку выбора (треугольник), чтобы схватить флаг < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Взмахни туда-сюда, чтобы забросить подальше..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Вы можете 'нацеливать' удары, крутясь влево или вправо.\nЭто полезно для сталкивания плохих парней с края или для голов в хоккее.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Когда взорвется бомба можно судить по цвету искр фитиля:\nжелтый..оранжевый..красный..БАБАХ.", + "You can throw bombs higher if you jump just before throwing.": "Бомбу можно бросить выше, если подпрыгнуть прямо перед броском.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Чтобы поменять персонажа не обязательно редактировать ​профиль. Просто нажмите\nверхнюю кнопку (подобрать) при вступлении в игру чтобы сменить персонажа.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Вы получаете повреждения, когда ударяетесь головой,\nтак что берегите голову.", + "Your punches do much more damage if you are running or spinning.": "От ударов гораздо больше вреда, когда бежишь или крутишься." + } + }, + "trialPeriodEndedText": "Ваш пробный период закончился. Хотите приобрести\nBombSquad и продолжать играть?", + "trophiesRequiredText": "Для этого надо минимум ${NUMBER} трофеев.", + "trophiesText": "Трофеев", + "trophiesThisSeasonText": "Трофеи за этот Сезон", + "tutorial": { + "cpuBenchmarkText": "Прогон тьюториала на безумной скорости (проверяет скорость процессора)", + "phrase01Text": "Привет!", + "phrase02Text": "Добро пожаловать в ${APP_NAME}!", + "phrase03Text": "Несколько советов по управлению персонажем:", + "phrase04Text": "Многое в ${APP_NAME} основано на законах ФИЗИКИ.", + "phrase05Text": "Например, при ударе кулаком..", + "phrase06Text": "..повреждения зависят от скорости кулака.", + "phrase07Text": "Видите? Мы не двигались, поэтому ${NAME} почти в полном порядке.", + "phrase08Text": "Теперь подпрыгнем и крутанемся для скорости.", + "phrase09Text": "Ага, так-то лучше.", + "phrase10Text": "Бег тоже помогает.", + "phrase11Text": "Для бега удерживайте любую кнопку.", + "phrase12Text": "Для супер-крутых ударов попробуйте бежать и крутиться.", + "phrase13Text": "Упс.. Извини, ${NAME}.", + "phrase14Text": "Можно поднимать и бросать вещи, например флаги.. или ${NAME}.", + "phrase15Text": "И, наконец, бомбы.", + "phrase16Text": "Бросание бомб требует тренировки.", + "phrase17Text": "Ай! Не очень хороший бросок.", + "phrase18Text": "В движении бросок получается дальше.", + "phrase19Text": "В прыжке бросок выше.", + "phrase20Text": "\"Раскрученные\" бомбы летят еще дальше.", + "phrase21Text": "\"Подогревать\" бомбы довольно сложно.", + "phrase22Text": "Чёрт.", + "phrase23Text": "Попробуйте \"подогреть\" фитиль секунду или две.", + "phrase24Text": "Ура! Хорошо подогрето.", + "phrase25Text": "Ну на этом, пожалуй, всё.", + "phrase26Text": "Вперед, к победе!", + "phrase27Text": "Не забывай эти советы, и ТОЧНО вернешься живым!", + "phrase28Text": "...может быть...", + "phrase29Text": "Удачи!", + "randomName1Text": "Вася", + "randomName2Text": "Петя", + "randomName3Text": "Иннокентий", + "randomName4Text": "Шурик", + "randomName5Text": "Виталик", + "skipConfirmText": "Пропустить тьюториал? Коснитесь или нажмите кнопку для подтверждения.", + "skipVoteCountText": "${COUNT}/${TOTAL} голосов за пропуск", + "skippingText": "пропуск обучения...", + "toSkipPressAnythingText": "(коснитесь или нажмите что-нибудь чтобы пропустить тьюториал)" + }, + "twoKillText": "ДВОИХ ЗА РАЗ!", + "unavailableText": "недоступно", + "unconfiguredControllerDetectedText": "Обнаружен ненастроенный геймпад:", + "unlockThisInTheStoreText": "Это должно быть разблокировано в магазине.", + "unlockThisProfilesText": "Чтобы создать более ${NUM} профиль, Вам необходимо:", + "unlockThisText": "Чтобы разблокировать это, вам нужно:", + "unsupportedHardwareText": "К сожалению, это оборудование не поддерживается в этой сборке игры.", + "upFirstText": "Для начала:", + "upNextText": "Далее в игре ${COUNT}:", + "updatingAccountText": "Обновление вашего аккаунта", + "upgradeText": "Обновление", + "upgradeToPlayText": "Разблокируйте \"${PRO}\" в магазине что-бы играть в это.", + "useDefaultText": "Использовать стандартные", + "usesExternalControllerText": "Эта игра может использовать внешний контроллер для управления.", + "usingItunesText": "Использование музыкального приложения для саундтрека...", + "usingItunesTurnRepeatAndShuffleOnText": "Убедитесь, что в iTunes включен случайный порядок, и повтор установлен на 'все'.", + "v2AccountLinkingInfoText": "Чтобы обьединить старый и новый аккаунты, используйте кнопку 'Обьединить аккаунты'", + "validatingBetaText": "Валидация бета-версии...", + "validatingTestBuildText": "Проверка тестовой сборки...", + "victoryText": "Победа!", + "voteDelayText": "Невозможно начать новое голосование еще ${NUMBER} секунд", + "voteInProgressText": "Голосование уже в процессе.", + "votedAlreadyText": "Вы уже проголосовали", + "votesNeededText": "Нужно ${NUMBER} голосов", + "vsText": "против", + "waitingForHostText": "(ожидание ${HOST} чтобы продолжить)", + "waitingForLocalPlayersText": "ожидание локальных игроков...", + "waitingForPlayersText": "ожидание присоединения игроков...", + "waitingInLineText": "Подожди немного (комната заполнена)...", + "watchAVideoText": "Смотреть видео", + "watchAnAdText": "Смотреть рекламу", + "watchWindow": { + "deleteConfirmText": "Удалить \"${REPLAY}\"?", + "deleteReplayButtonText": "Удалить\nзапись", + "myReplaysText": "Мои записи", + "noReplaySelectedErrorText": "Запись не выбрана", + "playbackSpeedText": "Скорость воспроизведения: ${SPEED}", + "renameReplayButtonText": "Переименовать\nзапись", + "renameReplayText": "Переименовать \"${REPLAY}\" на:", + "renameText": "Переименовать", + "replayDeleteErrorText": "Ошибка удаления записи.", + "replayNameText": "Имя записи", + "replayRenameErrorAlreadyExistsText": "Запись с таким именем уже существует.", + "replayRenameErrorInvalidName": "Невозможно переименовать запись; неверное имя.", + "replayRenameErrorText": "Ошибка переименования записи.", + "sharedReplaysText": "Общие записи", + "titleText": "Смотреть", + "watchReplayButtonText": "Смотреть\nзапись" + }, + "waveText": "Волна", + "wellSureText": "Сойдет!", + "whatIsThisText": "Что это?", + "wiimoteLicenseWindow": { + "titleText": "Авторские права DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "Ожидание контроллеров Wii...", + "pressText": "Нажмите кнопки 1 и 2 на Wiimote одновременно.", + "pressText2": "На новых контроллерах Wiimote со встроенным Motion Plus нажмите красную кнопку 'sync' на задней части." + }, + "wiimoteSetupWindow": { + "copyrightText": "Авторские права DarwiinRemote", + "listenText": "Слушать", + "macInstructionsText": "Убедитесь, что ваш Wii выключен, а на вашем Маке включен\nBluetooth, затем нажмите 'Слушать'. Поддержка контроллеров Wii\nбывает немного капризна, так что, возможно, придется\nпопробовать несколько раз, пока получится подсоединиться. \n\nBluetooth должен обрабатывать до 7 подключенных устройств,\nхотя всякое бывает.\n\nBombSquad поддерживает оригинальные контроллеры Wiimote, \nнунчаки и классические контроллеры. \nТакже теперь работает и новый Wii Remote Plus,\nправда, без аксессуаров.", + "thanksText": "Это стало возможным благодаря\nкоманде DarwiinRemote.", + "titleText": "Настройка контроллера Wii" + }, + "winsPlayerText": "Победил ${NAME}!", + "winsTeamText": "Победили ${NAME}!", + "winsText": "${NAME} выиграл!", + "workspaceSyncErrorText": "Ошибка при попытке синхронизации ${WORKSPACE}. Посмотрите лог для информации.", + "workspaceSyncReuseText": "Не получается синхронизировать ${WORKSPACE}. Используется прошлая синхронизация.", + "worldScoresUnavailableText": "Мировые результаты недоступны.", + "worldsBestScoresText": "Лучшие в мире очки", + "worldsBestTimesText": "Лучшее в мире время", + "xbox360ControllersWindow": { + "getDriverText": "Скачать драйвер", + "macInstructions2Text": "Для использования контроллеров по беспроводной связи, вам также\nпотребуется ресивер, который поставляется с \"беспроводным геймпадом\nXbox 360 для Windows\". Один ресивер позволяет подключить до 4 контроллеров.\n\nВнимание: ресиверы сторонних производителей не будут работать с этим драйвером,\nубедитесь, что на вашем ресивере написано \"Microsoft\", а не \"XBOX 360\".\nMicrosoft больше не продает их отдельно, так что вам нужно будет найти\nресивер в комплекте с геймпадом, либо искать на ebay.\n\nЕсли вы считаете это полезным, можете отправить денег разработчику\nдрайвера на его сайте.", + "macInstructionsText": "Для использования геймпада Xbox 360 необходимо\nустановить драйвер Mac, доступный по ссылке ниже.\nОн работает и с проводными и беспроводными геймпадами.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Для использования проводных контроллеров Xbox 360 в BombSquad,\nпросто подключите их к USB-порту вашего устройства. Для нескольких\nконтроллеров можно использовать концентратор USB.\n\nДля использования беспроводных контроллеров вам понадобится беспроводной\nресивер который поставляется в наборе \"беспроводного геймпада Xbox 360\nдля Windows\" или продается отдельно. Каждый ресивер подключается\nк порту USB и позволяет подключать до 4 беспроводных контроллеров.", + "titleText": "Использование контроллеров Xbox 360 в ${APP_NAME}:" + }, + "yesAllowText": "Да, разрешить!", + "yourBestScoresText": "Ваши лучшие очки", + "yourBestTimesText": "Ваше лучшее время" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/serbian.json b/dist/ba_data/data/languages/serbian.json new file mode 100644 index 0000000..2ea8600 --- /dev/null +++ b/dist/ba_data/data/languages/serbian.json @@ -0,0 +1,1880 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Име налога не сме садржати смајлије и друге специјалне симболе", + "accountProfileText": "Profilno ime", + "accountsText": "Налози", + "achievementProgressText": "Достигнућа: ${COUNT} од ${TOTAL}", + "campaignProgressText": "Напредак [Тежак]: ${PROGRESS}", + "changeOncePerSeason": "Ово можеш променити само једном током сезоне.", + "changeOncePerSeasonError": "Мораш сачекати следећу сезону да би ово опет променио (${NUM} дан/а)", + "customName": "Сопствено име", + "linkAccountsEnterCodeText": "Унеси код", + "linkAccountsGenerateCodeText": "Генериши код", + "linkAccountsInfoText": "(подели напредак на више резличитих уређаја)", + "linkAccountsInstructionsNewText": "Да би спојио два налога, генериши код на првом и\nунеси тај код на други. Подаци са другог налога ће\nсе појавити на оба налога. (Подаци са првог налога\nће бити изгубљени)\n\nМожеш да повежеш највише ${COUNT} налога.\n\nВАЖНО: спајај само оне налоге које ти поседујеш;\nАко спојиш налог са налогом од пријатеља нећете\nмоћи да играте на мрежи у исто време.", + "linkAccountsInstructionsText": "Da povežeš dva profila, generiši kod sa jednog \nod njih i unesi kod na drugi.\nNapredak i inventar će biti spojeni.\nMožeš povezati najviše ${COUNT} profila.\n\nPAŽNJA:Samo poveži naloge koje poseduješ!\nAko povežeš naloge sa prijateljima onda\nnećeš biti u mogućnosti da igraš u isto vreme!\n\nVAŽNO:Ovo se trenutno ne može poništiti, zato budi pažljiv!", + "linkAccountsText": "Повежи налоге", + "linkedAccountsText": "Повезани налози:", + "nameChangeConfirm": "Промени име налога у ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Ово ће твој кооперативни напредак и локалне \nрекорде вратити на почетак (али не и тикете).\nОво се не може поништити. Да ли си сигуран?", + "resetProgressConfirmText": "Ово ће твој кооперативни напредак,\nдостигнућа и локалне рекорде (али не\nи тикете) вратити на почетак. Ово се\nне може поништити. Да ли си сигуран?", + "resetProgressText": "Ресетуј напредак", + "setAccountName": "Промени име налога", + "setAccountNameDesc": "Изабери име које ће се приказивати на твом налогу.\nМожеш користити име са једног од твоји повезаних\nналога или направити ново јединствено име.", + "signInInfoText": "Пријави се да зарађујеш тикете, такмичиш на мрежи\nи делиш напредак на више различитих уређаја.", + "signInText": "Пријави се", + "signInWithDeviceInfoText": "(аутоматски налог достпупан једино са овог уређаја)", + "signInWithDeviceText": "Пријави се налогом уређаја", + "signInWithGameCircleText": "Пријави се преко Гејм Сркла.", + "signInWithGooglePlayText": "Пријави се преко Гугл Плеја", + "signInWithTestAccountInfoText": "(налог за тестирање нових ствари које ће ускоро изаћи)", + "signInWithTestAccountText": "Пријави се са тест профилом", + "signInWithV2InfoText": "(налог који функционише на свим платформама)", + "signInWithV2Text": "Улогуј се помоћу Bombsquad налога", + "signOutText": "Одјави се", + "signingInText": "Пријављивање...", + "signingOutText": "Одјављивање...", + "testAccountWarningOculusText": "Upozorenje: ulogujes se sa \"test\" adresom.\nOvo ce se promjeniti sa \"pravom\" adresom kasnije ove\ngodine ce se ponuditi kupovanje tiketi i ostale stvari.\n\n\nOd sada ces morati osvajati tiketi u igru.", + "testAccountWarningText": "Upozorenje: ulogujes se sa \"test\" adresom.\nOva adresa je ista sa ovim uredjajom i\nmoze se resetovati povremeno. (zato molim vas ne\ntrosite vremena kupovati/otkrivati stvari)", + "ticketsText": "Тикети: ${COUNT}", + "titleText": "Налог", + "unlinkAccountsInstructionsText": "Изабери налог за раздвајање", + "unlinkAccountsText": "Раздвоји налоге", + "v2LinkInstructionsText": "Искористи овај линк да направиш налог или да се улогујеш.", + "viaAccount": "(преко налога ${NAME})", + "youAreSignedInAsText": "Пријављен си као:" + }, + "achievementChallengesText": "Изазови", + "achievementText": "Достигнуће", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Убиј 3 непријатеља са динамитом", + "descriptionComplete": "Убио си 3 непријатеља са динамитом", + "descriptionFull": "Убиј 3 непријатеља са динамитом на мапи ${LEVEL}", + "descriptionFullComplete": "Убио си 3 непријатеља са динамитом на мапи ${LEVEL}", + "name": "Динамит је експлодирао" + }, + "Boxer": { + "description": "Победи без коришћења бомби", + "descriptionComplete": "Победио си без коришћења бомби", + "descriptionFull": "Победи на мапи ${LEVEL} без коришћења бомби", + "descriptionFullComplete": "Победио си на мапи ${LEVEL} без коришћења бомби", + "name": "Боксер" + }, + "Dual Wielding": { + "descriptionFull": "Повежи 2 контролера (уређај или апликацију)", + "descriptionFullComplete": "Повезао си 2 контролера (уређаја или апликације)", + "name": "Заједничко руковање" + }, + "Flawless Victory": { + "description": "Победи нетакнут", + "descriptionComplete": "Победио си нетакнут", + "descriptionFull": "Победи на мапи ${LEVEL} нетакнут", + "descriptionFullComplete": "Победио си на мапи ${LEVEL} нетакнут", + "name": "Савршена победа" + }, + "Free Loader": { + "descriptionFull": "Започни \"Свако за себе\" игру са 2+ играча", + "descriptionFullComplete": "Започео си \"Свако за себе\" игру са 2 или више играча", + "name": "Мали администратор" + }, + "Gold Miner": { + "description": "Убиј 6 непријатеља минама", + "descriptionComplete": "Убио си 6 непријатеља минама", + "descriptionFull": "Убиј 6 непријатеља минама на мапи ${LEVEL}", + "descriptionFullComplete": "Убио си 6 непријатеља минама на мапи ${LEVEL}", + "name": "Миноловци" + }, + "Got the Moves": { + "description": "Победи без коришћења удараца или бомби", + "descriptionComplete": "Победио си без коришћења удараца или бомби", + "descriptionFull": "Победи на мапи ${LEVEL} без коришћења удараца иии бомби", + "descriptionFullComplete": "Победио си на мапи ${LEVEL} без коришћења бомби или удараца", + "name": "Спретно кретање" + }, + "In Control": { + "descriptionFull": "Повежи контролер (уређај или апликацију)", + "descriptionFullComplete": "Повезао си контролер (уређај или апликацију)", + "name": "Контролисан" + }, + "Last Stand God": { + "description": "Освоји 1000 поена", + "descriptionComplete": "Освојио си 1000 поена", + "descriptionFull": "Освоји 1000 поена на мапи ${LEVEL}", + "descriptionFullComplete": "Освојио си 1000 поена на мапи ${LEVEL}", + "name": "${LEVEL} Бог" + }, + "Last Stand Master": { + "description": "Освоји 250 поена", + "descriptionComplete": "Освојио си 250 поена", + "descriptionFull": "Освоји 250 поена на мапи ${LEVEL}", + "descriptionFullComplete": "Освојио си 250 поена на мапи ${LEVEL}", + "name": "${LEVEL} мајстор" + }, + "Last Stand Wizard": { + "description": "Освоји 500 поена", + "descriptionComplete": "Освојио си 500 поена", + "descriptionFull": "Освоји 500 поена на мапи ${LEVEL}", + "descriptionFullComplete": "Освојио си 500 поена на мапи ${LEVEL}", + "name": "${LEVEL} научник" + }, + "Mine Games": { + "description": "Убиј 3 непријатеља минама", + "descriptionComplete": "Убио си 3 непријатеља минама", + "descriptionFull": "Убиј 3 непријатеља минама на мапи ${LEVEL}", + "descriptionFullComplete": "Убио си 3 непријатеља минама на мапи ${LEVEL}", + "name": "Игра мина" + }, + "Off You Go Then": { + "description": "Баци 3 непријатеља са мапе", + "descriptionComplete": "Бацио си 3 непријатеља са мапе", + "descriptionFull": "Баци 3 непријатеља са мапе ${LEVEL}", + "descriptionFullComplete": "Бацио си 3 непријатеља са мапе ${LEVEL}", + "name": "Оде са платформе" + }, + "Onslaught God": { + "description": "Освоји 5000 поена", + "descriptionComplete": "Освојио си 5000 поена", + "descriptionFull": "Освоји 5000 поена на мапи ${LEVEL}", + "descriptionFullComplete": "Освојио си 5000 поена на мапи ${LEVEL}", + "name": "${LEVEL} Бог" + }, + "Onslaught Master": { + "description": "Освоји 500 поена", + "descriptionComplete": "Освојио си 500 поена", + "descriptionFull": "Освоји 500 поена на мапи ${LEVEL}", + "descriptionFullComplete": "Освојио си 500 поена на мапи ${LEVEL}", + "name": "${LEVEL} мајстор" + }, + "Onslaught Training Victory": { + "description": "Победи све рунде", + "descriptionComplete": "Победио си све рунде", + "descriptionFull": "Победи све рунде на мапи ${LEVEL}", + "descriptionFullComplete": "Победио си све рунде на мапи ${LEVEL}", + "name": "${LEVEL} победник" + }, + "Onslaught Wizard": { + "description": "Освоји 1000 поена", + "descriptionComplete": "Освојио си 1000 поена", + "descriptionFull": "Освоји 1000 поена на мапи ${LEVEL}", + "descriptionFullComplete": "Освојио си 1000 поена на мапи ${LEVEL}", + "name": "${LEVEL} научник" + }, + "Precision Bombing": { + "description": "Победи без коришћења супер моћи", + "descriptionComplete": "Победио си без коришћења супер моћи", + "descriptionFull": "Победи на мапи ${LEVEL} без коришћења супер моћи", + "descriptionFullComplete": "Победио си на мапи ${LEVEL} без коришћења супер моћи", + "name": "Прецизне бомбе" + }, + "Pro Boxer": { + "description": "Победи без коришћења бомби", + "descriptionComplete": "Победио си без коришћења бомби", + "descriptionFull": "Победи на мапи ${LEVEL}без коршћења бомби", + "descriptionFullComplete": "Победио си на мапи ${LEVEL} без коришћења бомби", + "name": "Професионални боксер" + }, + "Pro Football Shutout": { + "description": "Победи без примљених голова од стране непријатеља", + "descriptionComplete": "Победио си без примљених голова од стране непријатеља", + "descriptionFull": "Победи на мапи ${LEVEL} без примљених голова од стране непријатеља", + "descriptionFullComplete": "Победио си на мапи ${LEVEL} без примљених голова од стране непријатеља", + "name": "${LEVEL} дриблер" + }, + "Pro Football Victory": { + "description": "Победи утакмицу", + "descriptionComplete": "Победио си утакмицу", + "descriptionFull": "Победи утакмицу на мапи ${LEVEL}", + "descriptionFullComplete": "Победио си утакмицу на мапи ${LEVEL}", + "name": "${LEVEL} победник" + }, + "Pro Onslaught Victory": { + "description": "Победи све рунде", + "descriptionComplete": "Победио си све рунде", + "descriptionFull": "Победи све рунде на мапи ${LEVEL}", + "descriptionFullComplete": "Победио си све рунде на мапи ${LEVEL}", + "name": "${LEVEL} победник" + }, + "Pro Runaround Victory": { + "description": "Заврши све рунде", + "descriptionComplete": "Завршио си све рунде", + "descriptionFull": "Заврши све рунде на мапи ${LEVEL}", + "descriptionFullComplete": "Завршио си све рунде на мапи ${LEVEL}", + "name": "${LEVEL} победник" + }, + "Rookie Football Shutout": { + "description": "Победи без примљеих голова од стране непријатеља", + "descriptionComplete": "Победио си без примљених голова од стране непријатеља", + "descriptionFull": "Победи на мапи ${LEVEL} без примљених голова од стране непријатеља", + "descriptionFullComplete": "Победио си на мапи ${LEVEL} без примљених голова од стране непријатеља", + "name": "${LEVEL} дриблер" + }, + "Rookie Football Victory": { + "description": "Победи утакмицу", + "descriptionComplete": "Победио си утакмицу", + "descriptionFull": "Победи утакмицу на мапи ${LEVEL}", + "descriptionFullComplete": "Победио си утакмицу на мапи ${LEVEL}", + "name": "${LEVEL} победник" + }, + "Rookie Onslaught Victory": { + "description": "Победи све рунде", + "descriptionComplete": "Победио си све рунде", + "descriptionFull": "Победи све рунде на мапи ${LEVEL}", + "descriptionFullComplete": "Победио си све рунде на мапи ${LEVEL}", + "name": "${LEVEL} победник" + }, + "Runaround God": { + "description": "Освоји 2000 поена", + "descriptionComplete": "Освојио си 2000 поена", + "descriptionFull": "Освоји 2000 поена на мапи ${LEVEL}", + "descriptionFullComplete": "Освојио си 2000 поена на мапи ${LEVEL}", + "name": "${LEVEL} Бог" + }, + "Runaround Master": { + "description": "Освоји 500 поена", + "descriptionComplete": "Освојио си 500 поена", + "descriptionFull": "Освоји 500 поена на мапи ${LEVEL}", + "descriptionFullComplete": "Освојио си 500 поена на мапи ${LEVEL}", + "name": "${LEVEL} мајстор" + }, + "Runaround Wizard": { + "description": "Освоји 1000 поена", + "descriptionComplete": "Освојио си 1000 поена", + "descriptionFull": "Освоји 1000 поена на мапи ${LEVEL}", + "descriptionFullComplete": "Освојио си 1000 поена на мапи ${LEVEL}", + "name": "${LEVEL} научник" + }, + "Sharing is Caring": { + "descriptionFull": "Успешно позови пријатеља да игра игру", + "descriptionFullComplete": "Успешно си позвао пријатеља да игра игру", + "name": "Заједно је забавније" + }, + "Stayin' Alive": { + "description": "Победи без умирања", + "descriptionComplete": "Победио си без умирања", + "descriptionFull": "Победи на мапи ${LEVEL} без умирања", + "descriptionFullComplete": "Победио си на мапи ${LEVEL} без умирања", + "name": "Преживели" + }, + "Super Mega Punch": { + "description": "Нанеси 100% штете једним ударцем", + "descriptionComplete": "Нанео си 100% штете једним ударцем", + "descriptionFull": "Нанеси 100% штете једним ударцем на мапи ${LEVEL}", + "descriptionFullComplete": "Нанео си 100% штете једним ударцем на мапи ${LEVEL}", + "name": "Мега супер ударац" + }, + "Super Punch": { + "description": "Нанеси 50% штете једним ударцем", + "descriptionComplete": "Нанео си 50% штете једним ударцем", + "descriptionFull": "Нанеси 50% штете једним ударцем на мапи ${LEVEL}", + "descriptionFullComplete": "Нанео си 50% штете једним удрацем на мапи ${LEVEL}", + "name": "Супер ударац" + }, + "TNT Terror": { + "description": "Убиј 6 непријатеља са динамитом", + "descriptionComplete": "Убио си 6 непријатеља са динамитом", + "descriptionFull": "Убиј 6 непријатеља са динамитом на мапи ${LEVEL}", + "descriptionFullComplete": "Убио си 6 непријатеља са динамитом на мапи ${LEVEL}", + "name": "Терориста" + }, + "Team Player": { + "descriptionFull": "Започни тимску игру са 4 или више играча", + "descriptionFullComplete": "Започео си тимску игру са 4 или више играча", + "name": "Тимски играч" + }, + "The Great Wall": { + "description": "Заустави све непријатеље", + "descriptionComplete": "Зауставио си све непријатеље", + "descriptionFull": "Заустави све непријатеље на мапи ${LEVEL}", + "descriptionFullComplete": "Зауставио си све непријатеље на мапи ${LEVEL}", + "name": "Велики зид" + }, + "The Wall": { + "description": "Заустави све непријатеље", + "descriptionComplete": "Зауставио си све непријатеље", + "descriptionFull": "Заустави све непријатеље на мапи ${LEVEL}", + "descriptionFullComplete": "Зауставио си све напријатеље на мапи ${LEVEL}", + "name": "Зид" + }, + "Uber Football Shutout": { + "description": "Победи без примљених голова од стране непријатеља", + "descriptionComplete": "Победио си без примљених голова од стране непријатеља", + "descriptionFull": "Победи на мапи ${LEVEL} без примљених голова од стране непријатеља", + "descriptionFullComplete": "Победио си на мапи ${LEVEL} без примљених голова од стране непријатеља", + "name": "${LEVEL} дриблер" + }, + "Uber Football Victory": { + "description": "Победи утакмицу", + "descriptionComplete": "Победио си утакмицу", + "descriptionFull": "Победи утакмицу на мапи ${LEVEL}", + "descriptionFullComplete": "Победио си утакмицу на мапи ${LEVEL}", + "name": "${LEVEL} победник" + }, + "Uber Onslaught Victory": { + "description": "Победи све рунде", + "descriptionComplete": "Победио си све рунде", + "descriptionFull": "Победи све рунде на мапи ${LEVEL}", + "descriptionFullComplete": "Победио си све рунде на мапи ${LEVEL}", + "name": "${LEVEL} победник" + }, + "Uber Runaround Victory": { + "description": "Заврши све рунде", + "descriptionComplete": "Завршио си све рунде", + "descriptionFull": "Заврши све рунде на мапи ${LEVEL}", + "descriptionFullComplete": "Завршио си све рунде на мапи ${LEVEL}", + "name": "${LEVEL} победник" + } + }, + "achievementsRemainingText": "Неизвршена достигнућа:", + "achievementsText": "Достигнућа", + "achievementsUnavailableForOldSeasonsText": "Извини, информације нису доступне за старије сезоне.", + "activatedText": "${THING} Активиран", + "addGameWindow": { + "getMoreGamesText": "Додај више игри...", + "titleText": "Додај игру" + }, + "allowText": "Дозволи", + "alreadySignedInText": "Овај налог је тренутно пријављен на другом уређају;\nмолимо вас да замените налог или искључите игру на\nдругом уређају и покушате поново.", + "apiVersionErrorText": "Не можемо учитати мод ${NAME}; он тражи верзију ${VERSION_USED}; ми користимо ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Аутоматски\" активира само када су прикључене слушалице)", + "headRelativeVRAudioText": "Виртуелни аудио у простору", + "musicVolumeText": "Јачина музике", + "soundVolumeText": "Јачина звука", + "soundtrackButtonText": "Музичке траке", + "soundtrackDescriptionText": "(додај своју сопствену музику која ће се пуштати)", + "titleText": "Аудио" + }, + "autoText": "Аутоматски", + "backText": "Назад", + "banThisPlayerText": "Забрани овог играча", + "bestOfFinalText": "Први до ${COUNT} победник", + "bestOfSeriesText": "Први до ${COUNT} серије:", + "bestOfUseFirstToInstead": 1, + "bestRankText": "Твоје најбоље место је #${RANK}", + "bestRatingText": "Твоја најбоља оцена је ${RATING}", + "bombBoldText": "БОМБА", + "bombText": "Бомба", + "boostText": "Појачај", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} је подешен у апликацији.", + "buttonText": "дугме", + "canWeDebugText": "Да ли желиш да игра аутоматски шање извештај о кваровима,\nгрешкама и основним информацијама о коришћењу девелоперу?\n\nОви подаци не садрже личне податке и помоћи\nће да игра ради глатко и без кварова.", + "cancelText": "Откажи", + "cantConfigureDeviceText": "Извини, ${DEVICE} није подесив.", + "challengeEndedText": "Овај изазов је завршен.", + "chatMuteText": "Искључи ћаскање", + "chatMutedText": "Ћаскање искључено", + "chatUnMuteText": "Укључи ћаскање", + "choosingPlayerText": "<бира играча>", + "completeThisLevelToProceedText": "Мораш прво завршити\nовај ниво да наставиш!", + "completionBonusText": "Бонус за завршетак", + "configControllersWindow": { + "configureControllersText": "Подеси контролере", + "configureKeyboard2Text": "Подеси тастатуру П2", + "configureKeyboardText": "Подеси тастатуру", + "configureMobileText": "Мобилни уређаји као контролери", + "configureTouchText": "Подеси екран", + "ps3Text": "ПС3 контролери", + "titleText": "Контролери", + "wiimotesText": "Вимоутс", + "xbox360Text": "Иксбокс 360 контролери" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Обавштење: прилагођавање контролера варира у зависности од уређаја и Андроид верзије.", + "pressAnyButtonText": "Притисни било које дугме на контролеру\n које желиш да подесиш...", + "titleText": "Подеси контролере" + }, + "configGamepadWindow": { + "advancedText": "Напредно", + "advancedTitleText": "Напредно подешавање контролера", + "analogStickDeadZoneDescriptionText": "(упали ово уколико твој лик \"проклизава\" и након отпуштања дугмета)", + "analogStickDeadZoneText": "Мртва зона аналогног дугмета", + "appliesToAllText": "(примењује се на све контролере ове врсте)", + "autoRecalibrateDescriptionText": "(укључи ово ако се твој лик не креће пуном брзином)", + "autoRecalibrateText": "Аутоматски рекалибрирај аналогно дугме", + "axisText": "оса", + "clearText": "очисти", + "dpadText": "окидач", + "extraStartButtonText": "Додатно стартно дугме", + "ifNothingHappensTryAnalogText": "Ако се ништа не деси, пробај да \"упослиш\" анлогно дугме уместо тога.", + "ifNothingHappensTryDpadText": "Ако се ништа не дешава, пробај да \"упослиш\" окидач уместо тога.", + "ignoreCompletelyDescriptionText": "(спречи да овај контролер утиче на игру или мени)", + "ignoreCompletelyText": "Игнориши у потпуности", + "ignoredButton1Text": "Игнорисано дугме 1", + "ignoredButton2Text": "Игнорисано дугме 2", + "ignoredButton3Text": "Игнорисано дугме 3", + "ignoredButton4Text": "Игнорисано дугме 4", + "ignoredButtonDescriptionText": "(користи ово да спречиш дугмад \"кућа\" и \"синхронизација\" да утичу на екран)", + "pressAnyAnalogTriggerText": "Притисни неки аналогни окидач...", + "pressAnyButtonOrDpadText": "Притисни неко дугме или окидач...", + "pressAnyButtonText": "Притисни неко дугме...", + "pressLeftRightText": "Притисни лево или десно...", + "pressUpDownText": "Притисни горе или доле...", + "runButton1Text": "Дугме трчања 1", + "runButton2Text": "Дугме трчања 2", + "runTrigger1Text": "Окидач трчања 1", + "runTrigger2Text": "Окидач трчања 2", + "runTriggerDescriptionText": "(аналогни окидачи дозвољавају ти да трчиш у променљивим брзинама)", + "secondHalfText": "Користи ово да подесиш другу половину\n\"2 у 1\" контролера уређаја који се\nпоказује као посебан контролер.", + "secondaryEnableText": "Омогућено", + "secondaryText": "Секундарни контролер", + "startButtonActivatesDefaultDescriptionText": "(упали ово ако је твоје стартно дугме више од \"мени\" дугмета)", + "startButtonActivatesDefaultText": "Стартно дугме активира уобичајене пречице", + "titleText": "Подешавање контролера", + "twoInOneSetupText": "Подешавање 2 у 1 контролера", + "uiOnlyDescriptionText": "(спречи да уз помоћ овог контролера улазиш у игру)", + "uiOnlyText": "Ограничи коришћење менија", + "unassignedButtonsRunText": "Трчање свим дугмадима без додељене команде", + "unsetText": "<неподешено>", + "vrReorientButtonText": "Дугме виртуелног преусмеравања" + }, + "configKeyboardWindow": { + "configuringText": "Конфигурисање ${DEVICE}", + "keyboard2NoteText": "Обавештење: Већина тастатура може да региструје само неколико\nпритиска одједном, зато ако имаш другу тастатуру играч би можда\nбоље радио ако би посебна тастатура била укључена да би је он\nкористио. Обавештење које ти такође треба јесте да и у том\nслучају упослиш различитe тастере за два играча." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Величина контроле акције", + "actionsText": "Акција", + "buttonsText": "дугмад", + "dragControlsText": "< вуци контроле да их помераш >", + "joystickText": "џојстик", + "movementControlScaleText": "Величина контроле кретања", + "movementText": "Кретање", + "resetText": "Ресетуј", + "swipeControlsHiddenText": "Сакриј контроле на повлачење", + "swipeInfoText": "Стил контрола на повлачење захтева искуство за коришћење\nали омогућава лакшу игру без гледања у контроле.", + "swipeText": "превуци", + "titleText": "Подеси екран" + }, + "configureItNowText": "Подеси их сад?", + "configureText": "Подеси", + "connectMobileDevicesWindow": { + "amazonText": "Амазон продавница", + "appStoreText": "Епл продавница", + "bestResultsScale": 0.65, + "bestResultsText": "За најбоље резултате треба ти интернет без кочења. Можеш\nсмањити кочења тако што ћеш искључити остале бежичне уређаје,\nиграти близу твог интернет рутера или конектовати се на игру\nкоја је направљена директно са интернета који ти користиш.", + "explanationText": "Да би користио паметни телефон или таблет као бежични контролер,\nинталирај \"${REMOTE_APP_NAME}\" апликацију на њега. Било који број уређаја\nможеш повезати на \"${APP_NAME}\" игру преко интернета, и то бесплатно!", + "forAndroidText": "за Андроид:", + "forIOSText": "за Еплов ОС:", + "getItForText": "Преузми \"${REMOTE_APP_NAME}\" за Еплов ОС преко Епл\nпродавнице или за Андроид у Гугловој или Амазон продавници", + "googlePlayText": "Гугл", + "titleText": "Коришћење мобилних уређаја као контролера:" + }, + "continuePurchaseText": "Настави за ${PRICE}?", + "continueText": "Настави", + "controlsText": "Контроле", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Ово се неће применити на укупну табелу.", + "activenessInfoText": "Овај множилац расте сваког дана када ти\nиграш и опада сваког дана када не играш.", + "activityText": "Активност", + "campaignText": "Напредак", + "challengesInfoText": "Освајај награде приликом завршавања мини-игри.\n\nНаграде и тежина нивоа се повећавају\nсваки пута када је изазов завршен и\nсмањују се кад изазов истекне или одустанеш.", + "challengesText": "Изазови", + "currentBestText": "Тренутно најбољи", + "customText": "Намештен", + "entryFeeText": "Уђи", + "forfeitConfirmText": "Одустани од изазова?", + "forfeitNotAllowedYetText": "Још увек не можеш да одустанеш од овог изазова.", + "forfeitText": "Одустани", + "multipliersText": "Множилац", + "nextChallengeText": "Следећи изазов", + "nextPlayText": "Следећи улазак", + "ofTotalTimeText": "од ${TOTAL}", + "playNowText": "Играј одмах", + "pointsText": "Поени", + "powerRankingFinishedSeasonUnrankedText": "(сезона завршена без ранка)", + "powerRankingNotInTopText": "(ниси у топ ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} поен/а", + "powerRankingPointsMultText": "(x ${NUMBER} поен/а)", + "powerRankingPointsText": "${NUMBER} поен/а", + "powerRankingPointsToRankedText": "(${CURRENT} од ${REMAINING} поена)", + "powerRankingText": "Бодовање", + "prizesText": "Награде", + "proMultInfoText": "Играчи са \"${PRO}\" надоградњом\nдобијају ${PERCENT}% поена више.", + "seeMoreText": "Више...", + "skipWaitText": "Прескочи чекање", + "timeRemainingText": "Преостало време", + "toRankedText": "да добијеш ранк", + "totalText": "укупно", + "tournamentInfoText": "Такмичи се за најбољи резултат са\nосталим играчима у твојој лиги.\n\nНаграде ће бити додељене играчима са најбољим\nрезултатом када време за турнир истекне.", + "welcome1Text": "Добродошао у лигу \"${LEAGUE}\". Можеш повећати свој\nранк у лиги освајајући звездице, зевршавајући\nзадатке и освајајући трофеје на турнирима.", + "welcome2Text": "Тикете можеш освојити у много раличитих активности.\nТикете можеш да користиш да би откључао нове ликове, \nмапе и мини-игре, да уђеш на турнир и остало.", + "yourPowerRankingText": "Твој ранк:" + }, + "copyOfText": "Копирај \"${NAME}\"", + "copyText": "Копирај", + "createEditPlayerText": "<Направи/измени играча>", + "createText": "Направи", + "creditsWindow": { + "additionalAudioArtIdeasText": "Додатни аудио, илустрације и идеје су од ${NAME}", + "additionalMusicFromText": "Додатна музика је од ${NAME}", + "allMyFamilyText": "Сви моји пријатељи и фамилија који су помогли при тестирању", + "codingGraphicsAudioText": "Кодирање, графике и аудио су од ${NAME}", + "languageTranslationsText": "Преводили су: (за српски - Игор М. (Чачак))", + "legalText": "Права:", + "publicDomainMusicViaText": "Музика јавног домена од ${NAME}", + "softwareBasedOnText": "Овај софтвер је делимићно базиран на раду од ${NAME}", + "songCreditText": "${TITLE} је изведен од стране ${PERFORMER}\nСастављено од стране ${COMPOSER}, уређено од стране ${ARRANGER}\nобјављено од стране ${PUBLISHER}, учтиво од ${SOURCE}", + "soundAndMusicText": "Звук и музика:", + "soundsText": "Звукови (${SOURCE}):", + "specialThanksText": "Специјална захвалност:", + "thanksEspeciallyToText": "Поготову се захваљујемо ${NAME}", + "titleText": "\"${APP_NAME}\" заслуге", + "whoeverInventedCoffeeText": "Ко год да је измислио кафу" + }, + "currentStandingText": "Твоје тренутно место је #${RANK}", + "customizeText": "Прилагоди...", + "deathsTallyText": "${COUNT} смрт/и", + "deathsText": "Смрти", + "debugText": "уклони грешке", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Обавештење: препоручује се да наместиш Подешавања->Графике->Текстуре на \"Висока\" док тестираш ово.", + "runCPUBenchmarkText": "Уради тест процесора", + "runGPUBenchmarkText": "Уради тест оптимизације", + "runMediaReloadBenchmarkText": "Уради тест учитавања медија", + "runStressTestText": "Уради тест оптерећења", + "stressTestPlayerCountText": "Број играча", + "stressTestPlaylistDescriptionText": "Листа игара на тесту", + "stressTestPlaylistNameText": "Име листе игара", + "stressTestPlaylistTypeText": "Тип листе игара", + "stressTestRoundDurationText": "Трајање рунде", + "stressTestTitleText": "Тест оптерећења", + "titleText": "Провере и тестови телефона", + "totalReloadTimeText": "Време учитавања: ${TIME} (погледај дневник за информације)" + }, + "defaultGameListNameText": "Уобичајена \"${PLAYMODE}\" листа игара", + "defaultNewGameListNameText": "Моја \"${PLAYMODE}\" листа игара", + "deleteText": "Обриши", + "demoText": "Проба", + "denyText": "Одбиј", + "desktopResText": "Рез. екрана", + "difficultyEasyText": "Лако", + "difficultyHardOnlyText": "Само на тешком моду", + "difficultyHardText": "Тешко", + "difficultyHardUnlockOnlyText": "Овај ниво може да се откључа само на тешком моду.\nДа ли мислиш да си спреман за то!?!?!", + "directBrowserToURLText": "Молимо вас усмерите интернет претарживач на следећи URL:", + "disableRemoteAppConnectionsText": "Онемогући повезивање додатне апликације", + "disableXInputDescriptionText": "Дозвољава више од 4 контролера али су могући проблеми.", + "disableXInputText": "Онемогући Икс-контролере", + "doneText": "Заврши", + "drawText": "Нерешено", + "duplicateText": "Дуплирај", + "editGameListWindow": { + "addGameText": "Додај\nигру", + "cantOverwriteDefaultText": "Не можеш променити уобичајену листу игара!", + "cantSaveAlreadyExistsText": "Листа игара са тим именом већ постоји!", + "cantSaveEmptyListText": "Не можеш сачувати празну листу игара!", + "editGameText": "Измени\nигру", + "listNameText": "Име листе игара", + "nameText": "Име", + "removeGameText": "Обриши\nигру", + "saveText": "Сачувај листу", + "titleText": "Мењање листе игара" + }, + "editProfileWindow": { + "accountProfileInfoText": "Овај специјални профил има име и \nиконицу базирану на твом налогу.\n\n${ICONS}\n\nНаправи прилагођене профиле да их користиш\nса различитим именима или иконицама.", + "accountProfileText": "(профил налога)", + "availableText": "Име \"${NAME}\" је доступно.", + "characterText": "лик", + "checkingAvailabilityText": "Проверавање доступности \"${NAME}\"...", + "colorText": "боја", + "getMoreCharactersText": "Набави више ликова...", + "getMoreIconsText": "Набави више иконица...", + "globalProfileInfoText": "Профили глобалних играча загарантовано имају јединствена \nимена широм света. Они такође укључују иконице.", + "globalProfileText": "(глобални профил)", + "highlightText": "сјај", + "iconText": "иконица", + "localProfileInfoText": "Профили локалних играча немају иконице и није загарантовано\nда ће њихова имена бити јединствена. Угради га на глобални \nпрофил да резервишеш јединствено име и додаш иконице.", + "localProfileText": "(локални профил)", + "nameDescriptionText": "Име играча", + "nameText": "Име", + "randomText": "насумично", + "titleEditText": "Измени профил", + "titleNewText": "Нови профил", + "unavailableText": "\"${NAME}\" није доступно; пробај друго име.", + "upgradeProfileInfoText": "Ово ће резервисати твоје име широм света и \nдозволиће ти да додаш иконицу на њега.", + "upgradeToGlobalProfileText": "Угради глобални профил" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Не можеш обрисати подразумевану листу звукова.", + "cantEditDefaultText": "Не можеш измењивати подразумевану листу звукова. Удвсотручи је или направи нову.", + "cantOverwriteDefaultText": "Не можеш мењати подразумевану листу звукова", + "cantSaveAlreadyExistsText": "Листа звукова са тим именом већ постоји!", + "defaultGameMusicText": "<подразумевана музика у игри>", + "defaultSoundtrackNameText": "Подразумевана листа звукова", + "deleteConfirmText": "Обриши листу звукова?\n\n\"${NAME}\"?", + "deleteText": "Обриши\nлисту звукова", + "duplicateText": "Удвостручи\nлисту звукова", + "editSoundtrackText": "Уређивање листе звукова", + "editText": "Измени\nлисту звукова", + "fetchingITunesText": "преузимање музичке листе из апликације", + "musicVolumeZeroWarning": "Пажња: јачина музике је подешена на 0", + "nameText": "Име", + "newSoundtrackNameText": "Моја листа звукова ${COUNT}", + "newSoundtrackText": "Нова листа звукова:", + "newText": "Нова\nлиста звукова", + "selectAPlaylistText": "Изабери листу музике", + "selectASourceText": "Извор музике", + "testText": "тест", + "titleText": "Листа звукова", + "useDefaultGameMusicText": "Подразумевана музика у игри", + "useITunesPlaylistText": "Листа музике из апликације", + "useMusicFileText": "Музички фајл", + "useMusicFolderText": "Фолдер са музичким фајловима" + }, + "editText": "Измени", + "endText": "Крај", + "enjoyText": "Уживај!", + "epicDescriptionFilterText": "${DESCRIPTION} у епско успореној игри.", + "epicNameFilterText": "Епски ${NAME}", + "errorAccessDeniedText": "приступ одбијен", + "errorDeviceTimeIncorrectText": "Време на твом уређају је нетачно за ${HOURS} сати.\nОво може изазвати проблеме.\nМолимо вас проверите подешавања времена и временску зону.", + "errorOutOfDiskSpaceText": "нема места на диску", + "errorSecureConnectionFailText": "Немогуће успоставити везу са клаудом; функција мреже може престати.", + "errorText": "Грешка", + "errorUnknownText": "непозната грешка", + "exitGameText": "Изађи из \"${APP_NAME}\"?", + "exportSuccessText": "\"${NAME}\" извезено.", + "externalStorageText": "Спољна меморија", + "failText": "Неуспешно", + "fatalErrorText": "Ух ох; нешто недостаје или је покварено.\nМолимо вас пробајте да опет инсталирате апликацију\nили контактирате ${EMAIL} за помоћ.", + "fileSelectorWindow": { + "titleFileFolderText": "Изабери фајл или фолдер", + "titleFileText": "Изабери фајл", + "titleFolderText": "Изабери фолдер", + "useThisFolderButtonText": "Користи овај фолдер" + }, + "filterText": "Филтер", + "finalScoreText": "Коначни резултат", + "finalScoresText": "Коначни резултати", + "finalTimeText": "Коначно време", + "finishingInstallText": "Завршавање инсталација; сачекајте моменат...", + "fireTVRemoteWarningText": "* За боље искуство, користите\nконтролере или инсталирајте \n\"${REMOTE_APP_NAME}\" апликацију\nна своје телефоне или таблете.", + "firstToFinalText": "\"Први до ${COUNT}\" резултат", + "firstToSeriesText": "\"Први до ${COUNT}\" серије", + "fiveKillText": "ПЕТОСТРУКО УБИСТВO!!!", + "flawlessWaveText": "Беспрекорна рунда!", + "fourKillText": "ЧЕТВОРОСТРУКО УБИСТВО!!!", + "friendScoresUnavailableText": "Резултати пријатеља недоступни.", + "gameCenterText": "Гејм Сентр", + "gameCircleText": "Гејм сркл", + "gameLeadersText": "Лидери ${COUNT} игре", + "gameListWindow": { + "cantDeleteDefaultText": "Не можеш да обришеш уобичајену листу игара.", + "cantEditDefaultText": "Не можеш да измениш уобичајену листу игара! Удвостручи је или направи нову.", + "cantShareDefaultText": "Не можеш да делиш уобичајену листу игара.", + "deleteConfirmText": "Обрисати \"${LIST}\"?", + "deleteText": "Обриши\nлисту игара", + "duplicateText": "Дуплирај\nлисту игара", + "editText": "Измени\nлисту игара", + "newText": "Нова\nлиста игара", + "showTutorialText": "Прикажи туториал", + "shuffleGameOrderText": "Насумичне игре", + "titleText": "Прилагоди \"${TYPE}\" листе игара" + }, + "gameSettingsWindow": { + "addGameText": "Додај игру" + }, + "gamesToText": "${WINCOUNT} према ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Запамти: било који уређај у заједници може да има\nвише од једног играча ако има довољно контролера.", + "aboutDescriptionText": "Користи ово да организујеш заједницу.\n\nЗаједнице ти пружају могућност да играш игре и\nтурнире са твојим пријатељима преко различитих уређаја.\n\nКористи ${PARTY} дугме у горњем десном углу да\nразговараш са играчима у заједници.\n(на контролеру, притисни ${BUTTON} док си у менију)", + "aboutText": "О заједници", + "addressFetchErrorText": "<грешка при преузимању адреса>", + "appInviteMessageText": "${NAME} ти је послао ${COUNT} тикета у \"${APP_NAME}\" игри", + "appInviteSendACodeText": "Пошаљи им код", + "appInviteTitleText": "${APP_NAME} позив за апликацију", + "bluetoothAndroidSupportText": "(ради са било којим Андроид уређајом који подржава блутуф)", + "bluetoothDescriptionText": "Буди домаћин/придружи се заједници преко блутуфа:", + "bluetoothHostText": "Буди домаћин преко блутуфа", + "bluetoothJoinText": "Придружи се преко блутуфа", + "bluetoothText": "Блутуф", + "checkingText": "проверавање...", + "copyCodeConfirmText": "Код копиран у привременој меморији.", + "copyCodeText": "Копирај код", + "dedicatedServerInfoText": "За најбоље резултате постави наменски сервер. Погледај bombsquadgame.com/server да сазнаш како.", + "disconnectClientsText": "Ово ће уклонити ${COUNT} играч/а из твоје\nзаједнице. Да ли си сигуран?", + "earnTicketsForRecommendingAmountText": "Пријатељи ће добити ${COUNT} тикета ако пробају игру\n(и ти ћеш освојити ${YOU_COUNT} за сваког који проба)", + "earnTicketsForRecommendingText": "Подели игру за \nбесплатне тикете...", + "emailItText": "Пошаљи Email", + "favoritesSaveText": "Додај као омиљено", + "favoritesText": "Омиљено", + "freeCloudServerAvailableMinutesText": "Следећи бесплатан сервер ће бити доступан за ${MINUTES} минута.", + "freeCloudServerAvailableNowText": "Бесплатан севрер је спреман!", + "freeCloudServerNotAvailableText": "Нема доступних бесплатних сервера.", + "friendHasSentPromoCodeText": "Добио си ${COUNT} \"${APP_NAME}\" тикета од играча \"${NAME}\"", + "friendPromoCodeAwardText": "Добићеш ${COUNT} тикета сваки пут када буде искоришћен.", + "friendPromoCodeExpireText": "Код ће истећи за ${EXPIRE_HOURS} сати и важи само за нове играче.", + "friendPromoCodeInstructionsText": "Да би га искористио, отвори \"${APP_NAME}\" и иди у \"Подешавања->Напредно->\nУнеси код\". Погледај bombsquadgame.com да преузмеш линк за све подржане платформе.", + "friendPromoCodeRedeemLongText": "Може се искористити за ${COUNT} бесплатних тикета од стране ${MAX_USES} људи.", + "friendPromoCodeRedeemShortText": "Може се искористити за ${COUNT} тикета у игри.", + "friendPromoCodeWhereToEnterText": "(у Подешавања->Напредно->Унеси код\")", + "getFriendInviteCodeText": "Узми позивни код за пријатеља", + "googlePlayDescriptionText": "Позови Гугл Плеј играче у твоју заједницу:", + "googlePlayInviteText": "Позови", + "googlePlayReInviteText": "У твојој заједници је ${COUNT} играч/а који ће\nизгубити конекцију ако пошаљеш нови позив. Убаци\nи њих у нови позив за игру да их вратиш назад.", + "googlePlaySeeInvitesText": "Погледај позиве", + "googlePlayText": "Гугл Плеј", + "googlePlayVersionOnlyText": "(Андроид / Гугл Плеј верзија)", + "hostPublicPartyDescriptionText": "Буди домаћин заједнице", + "hostingUnavailableText": "Недоступно", + "inDevelopmentWarningText": "Обавештење:\n\nМрежна игра је нова ствар и још увек се поправља.\nЗа сада је препоручљиво да сви играчи\nбуду на истој интернет мрежи.", + "internetText": "Интернет", + "inviteAFriendText": "Твоји пријатељи још увек немају игру? Позови их\nда пробају игру и добиће ${COUNT} бесплатних тикета.", + "inviteFriendsText": "Позови пријатеље", + "joinPublicPartyDescriptionText": "Придружи се заједници", + "localNetworkDescriptionText": "Придружи се заједници у близини (ЛРМ, Блутуф, итд...)", + "localNetworkText": "Локална мрежа", + "makePartyPrivateText": "Начини моју заједницу приватном", + "makePartyPublicText": "Начини моју заједницу јавном", + "manualAddressText": "Адреса", + "manualConnectText": "Повежи се", + "manualDescriptionText": "Придружи се заједници преко адресе:", + "manualJoinSectionText": "Придружи се преко адресе", + "manualJoinableFromInternetText": "Да ли доступан преко интернета?:", + "manualJoinableNoWithAsteriskText": "НЕ*", + "manualJoinableYesText": "ДА", + "manualRouterForwardingText": "*да поправиш ово, покушај да наместиш свој рутер да проследи порт ${PORT} на твоју локалну адресу", + "manualText": "Ручно", + "manualYourAddressFromInternetText": "Твоја интернет адреса:", + "manualYourLocalAddressText": "Твоја локална адреса:", + "nearbyText": "У близини", + "noConnectionText": "<без конекције>", + "otherVersionsText": "(остале верзије)", + "partyCodeText": "Код заједнице", + "partyInviteAcceptText": "Прихвати", + "partyInviteDeclineText": "Одбиј", + "partyInviteGooglePlayExtraText": "(погледај \"Гугл Плеј\" одељак у прозору \"Окупљање\")", + "partyInviteIgnoreText": "Игнориши", + "partyInviteText": "${NAME} те је позвао да се\nпридружиш њиховој заједници!", + "partyNameText": "Име заједнице", + "partyServerRunningText": "Твој сервер тренутно ради.", + "partySizeText": "величина заједнице", + "partyStatusCheckingText": "проверавање статуса...", + "partyStatusJoinableText": "могуће је придружити се твојој заједници преко интернета", + "partyStatusNoConnectionText": "није могуће повезивање на сервер", + "partyStatusNotJoinableText": "није могуће придружити се твојој заједници преко интернета", + "partyStatusNotPublicText": "твоја зеједница није јавна", + "pingText": "пинг", + "portText": "Прикључак", + "privatePartyCloudDescriptionText": "Приватне заједнице раде на серверима; није потребно подешавање рутера.", + "privatePartyHostText": "Направи приватну заједницу", + "privatePartyJoinText": "Придружи се заједници", + "privateText": "Приватно", + "publicHostRouterConfigText": "Ово ће можда требати додатно подешавање твог рутера. Лакша опција је да направиш приватну заједницу.", + "publicText": "Јавно", + "requestingAPromoCodeText": "Тражење кода...", + "sendDirectInvitesText": "Пошаљи директне позиве", + "shareThisCodeWithFriendsText": "Подели овај код са пријатељима:", + "showMyAddressText": "Прикажи моју адресу", + "startHostingPaidText": "Направи сада за ${COST}", + "startHostingText": "Направи", + "startStopHostingMinutesText": "Можеш бесплатно започети или зауставити сервер наредних ${MINUTES} минута.", + "stopHostingText": "Заустави сервер", + "titleText": "Окупљање", + "wifiDirectDescriptionBottomText": "Ако сви уређаји имају \"Вај-фај директ\", они би могли то икористити да нађу једни\nдруге и да се повежу. Када су сви уређаји повезани, овде можеш направити\nзаједнице користећи \"Локална мрежа\" одељак, исто као и са регуларном интернет мрежом.\n\nЗа најбоље резултате, \"Вај-фај директ\" домаћин би такође требало да буде домаћин \"${APP_NAME}\" заједнице.", + "wifiDirectDescriptionTopText": "\"Вај-фај директ\" се може користити да се директно повежу Андроид уређаји\nбез интернет мреже. Ово најбоље ради на Андроид 4.2 или новијим верзијама.\n\nДа би користио ово, отвори интернет подешавања и потражи \"Вај-фај директ\" у менију.", + "wifiDirectOpenWiFiSettingsText": "Отвори интернет подешавања", + "wifiDirectText": "Вај-фај директ", + "worksBetweenAllPlatformsText": "(ради између свих платформи)", + "worksWithGooglePlayDevicesText": "(ради са уређајима који имају Гугл Плеј (андроид) верзију игре)", + "youHaveBeenSentAPromoCodeText": "Послао си \"${APP_NAME}\" промо код:" + }, + "getTicketsWindow": { + "freeText": "БЕСПЛАТНО!", + "freeTicketsText": "Бесплатни тикети", + "inProgressText": "Трансакција је у току; молимо вас покушајте касније.", + "purchasesRestoredText": "Куповине обновљене.", + "receivedTicketsText": "Добио си ${COUNT} тикета!", + "restorePurchasesText": "Обнови куповине", + "ticketPack1Text": "Мали пакет тикета", + "ticketPack2Text": "Средњи пакет тикета", + "ticketPack3Text": "Велики пакет тикета", + "ticketPack4Text": "Огромни пакет тикета", + "ticketPack5Text": "Џиновски пакет тикета", + "ticketPack6Text": "Ултимативни пакет тикета", + "ticketsFromASponsorText": "Узми ${COUNT} тикета\nод спонзора", + "ticketsText": "${COUNT} тикета", + "titleText": "Узми тикете", + "unavailableLinkAccountText": "Извињавамо се, куповина није доступна на овој платформи.\nКао решење, можеш повезати налог на налог на другој\nплатформи и ту изведеш куповину.", + "unavailableTemporarilyText": "Ово тренутно није доступно; молимо вас покушајте касније.", + "unavailableText": "Извињавамо се, ово није доступно.", + "versionTooOldText": "Извињавамо се, ова верзија игре је превише стара; молимо вас унапредите је на новију.", + "youHaveShortText": "имаш ${COUNT}", + "youHaveText": "имаш ${COUNT} тикета" + }, + "googleMultiplayerDiscontinuedText": "Извињавам се, Гуглов сервис више није доступан.\nРадимо на замени што је пре могуће.\nДо тада, покушајте другу методу повезивања.\n-Ерик", + "googlePlayText": "Гугл Плеј", + "graphicsSettingsWindow": { + "alwaysText": "Увек", + "fullScreenCmdText": "Цео екран (Cmd-F)", + "fullScreenCtrlText": "Цео екран (Ctrl-F)", + "gammaText": "Осветљење", + "highText": "Високо", + "higherText": "Веома високо", + "lowText": "Ниско", + "mediumText": "Средње", + "neverText": "Никад", + "resolutionText": "Резолуција", + "showFPSText": "Прикажи БСС", + "texturesText": "Текстуре", + "titleText": "Графике", + "tvBorderText": "ТВ оквир", + "verticalSyncText": "Вертикална синхронизација", + "visualsText": "Детаљи" + }, + "helpWindow": { + "bombInfoText": "- Бомба -\nЈача од удараца, али може\nдовести до самоповређивања.\nЗа најбоље резултате, бацити је испред\nнепријатеља пре него што фитиљ изгори.", + "bombInfoTextScale": 0.6, + "canHelpText": "\"${APP_NAME}\" ти може помоћи.", + "controllersInfoText": "Можеш да играш \"${APP_NAME}\" са пријатељима преко мреже, или \nможете играти на истом уређају ако имате довољно контролера.\n\"${APP_NAME}\" подржава доста њих; можете чак користити и \nтелефоне као контролере уз помоћ бесплатне \"${REMOTE_APP_NAME}\"\nапликације. Погледај Подешавања->Контролери за више информација.", + "controllersInfoTextRemoteOnly": "Можете да играте ${APP_NAME} са пријатељима преко мреже или са вама\nсви могу да се играју на истом уређају користећи телефоне као\nконтролери путем бесплатне апликације „${REMOTE_APP_NAME}“.", + "controllersText": "Контролери", + "controlsSubtitleText": "Твој пријатељ из \"${APP_NAME}\" игре има неколико основних акција:", + "controlsText": "Контроле", + "devicesInfoText": "Виртуелна верзија ${APP_NAME} може да се игра преко мреже са регуларном\nверзијом, зато извадите ваше додатне телефоне, таблете и компјутере\nи упалите вашу игру. Такође може бити корисно да повежете регуларну\nверзију игре на VR верзију само да би дозволили људима споља да\nгледају акцију.", + "devicesText": "Уређаји", + "friendsGoodText": "Ово је добро да имаш. \"${APP_NAME}\" је најзабавнији са неколико\nиграча а може да подржи и до 8 у исто време, што нас води ка:", + "friendsText": "Пријатељи", + "jumpInfoText": "- Скок -\nСкочи да пређеш мале рупе,\nда бациш ствари даље, и да\nизразиш осећања радости.", + "jumpInfoTextScale": 0.6, + "orPunchingSomethingExtraSpace": 0, + "orPunchingSomethingText": "Или да удараш некога, бациш га са литице и разносиш га са лепљивом бомбом док пада у провалију.", + "pickUpInfoText": "- Покупи -\nУзми заставе, непријатеље или било\nшта друго што није причвршћено за\nземљу. Притисни опет да бациш то.", + "pickUpInfoTextScale": 0.6, + "powerupBombDescriptionText": "Дозвољава ти да бациш три бомбе\nза редом уместо само једне.", + "powerupBombNameText": "Троструке бомбе", + "powerupCurseDescriptionText": "Вероватно желиш да избегнеш ово.\n ...или можда не?", + "powerupCurseNameText": "Клетва", + "powerupHealthDescriptionText": "Враћа цело твоје здравље.\nНикад не би погодио.", + "powerupHealthNameText": "Прва помоћ", + "powerupIceBombsDescriptionText": "Слабије него нормалне бомбе\nали оставља твоје непријатеље\nзалеђене и посебно ломљиве.", + "powerupIceBombsNameText": "Ледене бомбе", + "powerupImpactBombsDescriptionText": "Мало слабије него нормалне\nбомбе, али експлодирају на додир.", + "powerupImpactBombsNameText": "Бомбе на додир", + "powerupLandMinesDescriptionText": "Долазе у паковању од 3;\nКорисне за одбрану базе\nи заустављање брзих људи.", + "powerupLandMinesNameText": "Мине", + "powerupPunchDescriptionText": "Ојачава, убрзава и\nпобољшава твоје ударце.", + "powerupPunchNameText": "Боксерске рукавице", + "powerupShieldDescriptionText": "Прима део штете да\nти не би морао.", + "powerupShieldNameText": "Енергетски штит", + "powerupStickyBombsDescriptionText": "Залепи се за све што додирне.\nХитно реаговати!", + "powerupStickyBombsNameText": "Лепљива бомба", + "powerupsSubtitleText": "Наравно, ниједна игра није поптуна спцијалних моћи:", + "powerupsSubtitleTextScale": 0.8, + "powerupsText": "Специјалне моћи", + "punchInfoText": "- Ударац -\nУдарци праве више штете\nако се брже крећеш, тако да\nтрчи и врти се као лудак.", + "punchInfoTextScale": 0.6, + "runInfoText": "- Трчање -\nДржи БИЛО КОЈЕ дугме да трчиш. Дугмад на повлачење или права раде боље ако их имате.\nТрчање ће ти помоћи да стигнеш на неко место брже али се теже окрећеш, зато пази на ивице.", + "runInfoTextScale": 0.6, + "someDaysExtraSpace": 0, + "someDaysText": "Неким данима се осећаш као да би моаго јако да удараш у нешто. Или да разносиш нешто у ваздух.", + "titleText": "\"${APP_NAME}\" помоћ", + "toGetTheMostText": "Да би извукао највише из ове игре, требаће ти:", + "welcomeText": "Добродошао у \"${APP_NAME}\"!" + }, + "holdAnyButtonText": "<држи било које дугме>", + "holdAnyKeyText": "<држи било који тастер>", + "hostIsNavigatingMenusText": "- ${HOST} управља менијем као неки шеф -", + "importPlaylistCodeInstructionsText": "Користи следећи код да увезеш ову листу музике негде:", + "importPlaylistSuccessText": "\"${TYPE}\" листа пуштања увежена (\"${NAME})", + "importText": "Увези", + "importingText": "Увожење...", + "inGameClippedNameText": "у игри ће бити\n\"${NAME}\"", + "installDiskSpaceErrorText": "ГРЕШКА: Немогуће да се заврши инсталација.\nМожда си остао без простора на уређају.\nОслободи мало простора и покушај опет.", + "internal": { + "arrowsToExitListText": "притисни ${LEFT} или ${RIGHT} да изађеш са листе", + "buttonText": "дугме", + "cantKickHostError": "Не можеш да избациш домаћина.", + "chatBlockedText": "${NAME} не може да ћаска наредних ${TIME} секунди.", + "connectedToGameText": "Придружио си серверу \"${NAME}\"", + "connectedToPartyText": "Ушао си у ${NAME} заједницу!", + "connectingToPartyText": "Повезивање...", + "connectionFailedHostAlreadyInPartyText": "Конекција неуспела; домаћин је у другој заједници.", + "connectionFailedPartyFullText": "Конекција неуспела; заједница је пуна.", + "connectionFailedText": "Конекција неуспела.", + "connectionFailedVersionMismatchText": "Конекција неуспела; домаћин користи другу верзију игре.\nПровери да ли користиш најновију верзију и пробај опет.", + "connectionRejectedText": "Конекција одбијена.", + "controllerConnectedText": "${CONTROLLER} је повезан.", + "controllerDetectedText": "1 контролер пронађен.", + "controllerDisconnectedText": "${CONTROLLER} више није повезан.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} није повезан. Молимо вас покушајте опет.", + "controllerForMenusOnlyText": "Овај контролер не може послужити за игру, већ само за управљање менијем.", + "controllerReconnectedText": "${CONTROLLER} је поново повезан.", + "controllersConnectedText": "${COUNT} контролера је повезано.", + "controllersDetectedText": "${COUNT} контролера је повезано.", + "controllersDisconnectedText": "${COUNT} контролера више није повезано.", + "corruptFileText": "Пронађен претећи фајл/ови. Покушај да поново инсталираш игру или пошаљи поруку на ${EMAIL}", + "errorPlayingMusicText": "Грешка при пуштању музике: ${MUSIC}", + "errorResettingAchievementsText": "Немогуће рестартовање интернет достигнућа; молимо вас покушајте касније.", + "hasMenuControlText": "${NAME} има контролу над менијем.", + "incompatibleNewerVersionHostText": "Домаћин користи новију верзију игре.\nАжурирај на последњу верзију и покушај опет.", + "incompatibleVersionHostText": "Домаћин користи другу верзију игре. Провери да ли\nсте обојица усклађени са верзијама и покушај опет.", + "incompatibleVersionPlayerText": "${NAME} користи другу верзију игре. Провери да ли\nсте обојица усклађени са верзијама и покушај опет.", + "invalidAddressErrorText": "Грешка: неважећа адреса.", + "invalidNameErrorText": "Грешка: неважеће име.", + "invalidPortErrorText": "Грешка: неважећи прикључак.", + "invitationSentText": "Позивница послата.", + "invitationsSentText": "${COUNT} позивница послато.", + "joinedPartyInstructionsText": "Неко се придружио твојој заједници.\nИди на \"Играј\" да стартујеш игру.", + "keyboardText": "Тастатура", + "kickIdlePlayersKickedText": "Избачен ${NAME} због неактивности.", + "kickIdlePlayersWarning1Text": "${NAME} ће бити избачен за ${COUNT} секунди ако остане неактиван.", + "kickIdlePlayersWarning2Text": "(ово можеш да искључиш у Подешавања -> Напредно)", + "leftGameText": "${NAME} је изашао.", + "leftPartyText": "Изашао си из заједнице играча ${NAME}.", + "noMusicFilesInFolderText": "Фолдер не садржи музичке фајлове.", + "playerJoinedPartyText": "${NAME} се придружио заједници!", + "playerLeftPartyText": "${NAME} је напустио заједницу.", + "rejectingInviteAlreadyInPartyText": "Одбијање позива (већ је у заједници).", + "serverRestartingText": "Сервер се рестартује. Молимо вас уђите опет за који моменат...", + "serverShuttingDownText": "Сервер се гаси...", + "signInErrorText": "Грешка при пријављивању.", + "signInNoConnectionText": "Немогуће пријављивање. (нема интернет конекције?)", + "telnetAccessDeniedText": "ГРЕШКА: корисник нема одобрен приступ.", + "timeOutText": "(време истиче за ${TIME} секунду/и)", + "touchScreenJoinWarningText": "Придружили сте се уређајом са екраном на додир.\nАко је ово била грешка, клкни на \"Мени->Напусти игру\" са њим.", + "touchScreenText": "Екран на додир", + "unableToResolveHostText": "Грешка: немогуће препознавање домаћина.", + "unavailableNoConnectionText": "Ово тренутно није доступно (нема интернет конекције?)", + "vrOrientationResetCardboardText": "Користи ово да рестартујеш виртуелну оријентацију.\nДа би играо игру требаће ти спољни контролер.", + "vrOrientationResetText": "Виртуелна оријентација рестартована.", + "willTimeOutText": "(време ће му истећи ако је неактиван)" + }, + "jumpBoldText": "СКОК", + "jumpText": "Скок", + "keepText": "Задржи", + "keepTheseSettingsText": "Задржи ова подешавања?", + "keyboardChangeInstructionsText": "Притисни \"размак\" два пута да промениш тастатуре.", + "keyboardNoOthersAvailableText": "Нема доступних тастатура.", + "keyboardSwitchText": "Мењање тастатуре на \"${NAME}\".", + "kickOccurredText": "${NAME} је избачен.", + "kickQuestionText": "Избацити ${NAME}?", + "kickText": "Избаци", + "kickVoteCantKickAdminsText": "Админи не могу бити избачени.", + "kickVoteCantKickSelfText": "Не можеш избацити себе.", + "kickVoteFailedNotEnoughVotersText": "Нема довољно играча за гласање.", + "kickVoteFailedText": "Неуспешно гласање за ибацивање.", + "kickVoteStartedText": "Гласање за избацивање играча \"${NAME}\" је стартовано.", + "kickVoteText": "Гласај за избацивање.", + "kickVotingDisabledText": "Гласања за избацивање искључена.", + "kickWithChatText": "Напиши \"${YES}\" у ћаскању за избацивање и \"${NO}\" за против.", + "killsTallyText": "${COUNT} убиства", + "killsText": "Убиства", + "kioskWindow": { + "easyText": "Лако", + "epicModeText": "Епски мод", + "fullMenuText": "Пун мени", + "hardText": "Тешко", + "mediumText": "Средње", + "singlePlayerExamplesText": "Соло игра / кооперативни примери", + "versusExamplesText": "Примери борбе у 2 тима..." + }, + "languageSetText": "Тренутни језик је ${LANGUAGE}.", + "lapNumberText": "Круг ${CURRENT}/${TOTAL}", + "lastGamesText": "(последњих ${COUNT} игара)", + "leaderboardsText": "Табеле", + "league": { + "allTimeText": "Укупно", + "currentSeasonText": "Тренутна сезона (${NUMBER})", + "leagueFullText": "Лига \"${NAME}\"", + "leagueRankText": "Ранк у лиги", + "leagueText": "Лига", + "rankInLeagueText": "#${RANK}, Лига \"${NAME}\"${SUFFIX}", + "seasonEndedDaysAgoText": "Сезона завршена пре ${NUMBER} дана.", + "seasonEndsDaysText": "Сезона се завршава за ${NUMBER} дана.", + "seasonEndsHoursText": "Сезона се завршава за ${NUMBER} сати.", + "seasonEndsMinutesText": "Сезона се завршава за ${NUMBER} минута.", + "seasonText": "Сезона ${NUMBER}", + "tournamentLeagueText": "Мораш достићи лигу \"${NAME}\" да уђеш у овај турнир.", + "trophyCountsResetText": "Број трофеја ће се рестартовати следеће сезоне." + }, + "levelBestScoresText": "Најбољи резултати на нивоу \"${LEVEL}\"", + "levelBestTimesText": "Најбоља времена на нивоу \"${LEVEL}\"", + "levelIsLockedText": "Ниво \"${LEVEL}\" је закључан.", + "levelMustBeCompletedFirstText": "Прво мора бити завршен ниво \"${LEVEL}\".", + "levelText": "Ниво ${NUMBER}", + "levelUnlockedText": "Ниво откључан!", + "livesBonusText": "Бонус животи", + "loadingText": "учитавање", + "loadingTryAgainText": "Учитавање; покушај за који моменат...", + "macControllerSubsystemBothText": "Оба (није препоручљиво)", + "macControllerSubsystemClassicText": "Класични", + "macControllerSubsystemDescriptionText": "(покушај да промениш ово ако ти контролери не раде)", + "macControllerSubsystemMFiNoteText": "Ај-Оу-Ес (iOS)/Мек контролери су пронађени;\nМожда желиш да их омогућиш у Подешавања -> Контролери", + "macControllerSubsystemMFiText": "Ај-Оу-Ес (iOS)/Мек", + "macControllerSubsystemTitleText": "Подешавање контролера", + "mainMenu": { + "creditsText": "Заслуге", + "demoMenuText": "Демо мени", + "endGameText": "Заврши игру", + "exitGameText": "Изађи из игре", + "exitToMenuText": "Изађи на мени?", + "howToPlayText": "Како играти", + "justPlayerText": "(Само ${NAME})", + "leaveGameText": "Напусти игру", + "leavePartyConfirmText": "Стварно хоћеш да напустиш заједницу?", + "leavePartyText": "Напусти заједницу", + "quitText": "Изађи", + "resumeText": "Настави", + "settingsText": "Подешавања" + }, + "makeItSoText": "Нека буде тако", + "mapSelectGetMoreMapsText": "Набави више мапа...", + "mapSelectText": "Изабери...", + "mapSelectTitleText": "\"${GAME}\" мапе", + "mapText": "Мапа", + "maxConnectionsText": "Максимално конекција", + "maxPartySizeText": "Максимална величина заједнице", + "maxPlayersText": "Максимално играча", + "modeArcadeText": "Аркадни мод", + "modeClassicText": "Класични мод", + "modeDemoText": "Тест мод", + "mostValuablePlayerText": "Највреднији играч", + "mostViolatedPlayerText": "Најповређиванији играч", + "mostViolentPlayerText": "Најнасилнији играч", + "moveText": "Кретање", + "multiKillText": "${COUNT} УБИСТВА!!!", + "multiPlayerCountText": "${COUNT} играча", + "mustInviteFriendsText": "Обавештење: мораш да позовеш пријатеље\nу \"${GATHER}\" прозору или да прикључиш\nконтролере како би играо са више играча.", + "nameBetrayedText": "${NAME} је издао играча ${VICTIM}.", + "nameDiedText": "${NAME} је умро.", + "nameKilledText": "${NAME} је убио играча ${VICTIM}.", + "nameNotEmptyText": "Име не може бити празно!", + "nameScoresText": "${NAME} је постигао поен!", + "nameSuicideKidFriendlyText": "${NAME} је случајно умро.", + "nameSuicideText": "${NAME} је починио самоубиство.", + "nameText": "Име", + "nativeText": "Урођена", + "newPersonalBestText": "Нови лични рекорд!", + "newTestBuildAvailableText": "Новији систем за тестирање је доступан! (${VERSION} тест ${BUILD}).\nНабави је овде: ${ADDRESS}", + "newText": "Ново", + "newVersionAvailableText": "Новија верзија \"${APP_NAME}\" игре је доступна! (${VERSION})", + "nextAchievementsText": "Следећа достигнћа:", + "nextLevelText": "Следећи ниво", + "noAchievementsRemainingText": "- ниједан", + "noContinuesText": "(без наставака)", + "noExternalStorageErrorText": "Није нађена спољна меморија на овом уреају", + "noGameCircleText": "Грешка: ниси пријавњен на Гејм Сркл", + "noScoresYetText": "Још увек нема резултата.", + "noThanksText": "Не, хвала", + "noTournamentsInTestBuildText": "УПОЗОРЕЊЕ: Резултати са турнира у тест верзији игре се не рачунају.", + "noValidMapsErrorText": "Није пронађена важећа мапа за овај тип игре.", + "notEnoughPlayersRemainingText": "Није остало довољно играча; изађи и започни нову игру.", + "notEnoughPlayersText": "Требаш најмање ${COUNT} играча да започнеш игру!", + "notNowText": "Не сада", + "notSignedInErrorText": "Мораш бити пријављен да радиш ово.", + "notSignedInGooglePlayErrorText": "Мораш бити пријавњен на Гугл Плеј да радиш ово.", + "notSignedInText": "ниси пријављен", + "nothingIsSelectedErrorText": "Ништа није изабрано!", + "numberText": "#${NUMBER}", + "offText": "Искључи", + "okText": "Окej", + "onText": "Укључи", + "oneMomentText": "Један моменат...", + "onslaughtRespawnText": "${PLAYER} ће оживети у рунди ${WAVE}", + "orText": "${A} или ${B}", + "otherText": "Друго...", + "outOfText": "(#${RANK} од ${ALL})", + "ownFlagAtYourBaseWarning": "Твоја застава мора бити у\nбази да би освојио поен!", + "packageModsEnabledErrorText": "Мрежна игра није дозвољена док је локални пакет модова искључен (погледај Подешавања->Напредно)", + "partyWindow": { + "chatMessageText": "Порука за заједницу", + "emptyText": "Твоја заједница је празна", + "hostText": "(домаћин)", + "sendText": "Пошаљи", + "titleText": "Твоја заједница" + }, + "pausedByHostText": "(паузирано од стране домаћина)", + "perfectWaveText": "Перфектна рунда!", + "pickUpText": "Покупи", + "playModes": { + "coopText": "Кооперативно", + "freeForAllText": "Свако за себе", + "multiTeamText": "Мањи тимови", + "singlePlayerCoopText": "Соло игра / Кооперативно", + "teamsText": "Тимови" + }, + "playText": "Играј", + "playWindow": { + "oneToFourPlayersText": "1-4 играча", + "titleText": "Играј", + "twoToEightPlayersText": "2-8 играча" + }, + "playerCountAbbreviatedText": "${COUNT} иг.", + "playerDelayedJoinText": "${PLAYER} ће ући на старту следеће рунде.", + "playerInfoText": "Информације играча", + "playerLeftText": "${PLAYER} је напустио игру.", + "playerLimitReachedText": "Лимит од ${COUNT} играча је достигнут; забрањен улаз новим играчима.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Не можеш да обришеш профил твог налога.", + "deleteButtonText": "Обриши\nпрофил", + "deleteConfirmText": "Обрисати \"${PROFILE}\"?", + "editButtonText": "Измени\nпрофил", + "explanationText": "(сопствена имена играча и изгледи за овај налог)", + "newButtonText": "Нови\nпрофил", + "titleText": "Профили играча" + }, + "playerText": "Играч", + "playlistNoValidGamesErrorText": "Ова листа игара садржи игре које нису откључане.", + "playlistNotFoundText": "није нађена листа игара", + "playlistText": "Листа игара", + "playlistsText": "Листе игара", + "pleaseRateText": "Ако уживате у \"${APP_NAME}\" игри, молимо вас да издвојите\nмало времена да оцените апликацију или напишете коментар.\nОво нам даје корисне информације и помаже у будућем развоју.\n\nХвала!\n-Ерик", + "pleaseWaitText": "Молимо вас сачекајте...", + "pluginClassLoadErrorText": "Грешка учитавања плугина класе '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Грешка иницијације плугина '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Нови додатак/ци пронађени. Рестартуј да их активираш,или конфигуришеш у подешавањима.", + "pluginsRemovedText": "${NUM} додатак/ више не постоје.", + "pluginsText": "Додаци", + "practiceText": "Вежбање", + "pressAnyButtonPlayAgainText": "Притисни било које дугме да одиграш опет...", + "pressAnyButtonText": "Притисни било које дугме да наставиш...", + "pressAnyButtonToJoinText": "притисни било које дугме да се придружиш...", + "pressAnyKeyButtonPlayAgainText": "Притисни било који тастер/дугме да одиграш опет...", + "pressAnyKeyButtonText": "Притисни било који тастер/дугме да наставиш...", + "pressAnyKeyText": "Притисни било који тастер...", + "pressJumpToFlyText": "** Притискај \"Скок\" изнова и изнова да полетиш **", + "pressPunchToJoinText": "притисни \"Ударац\" да се придружиш...", + "pressToOverrideCharacterText": "притисни ${BUTTONS} да промениш свог лика", + "pressToSelectProfileText": "притисни ${BUTTONS} да изабереш играча", + "pressToSelectTeamText": "притисни ${BUTTONS} да изабереш тим", + "promoCodeWindow": { + "codeText": "Код", + "enterText": "Уђи" + }, + "promoSubmitErrorText": "Грешка при прихватању кода; провери своју интенет конекцију", + "ps3ControllersWindow": { + "macInstructionsText": "Искључи напајање са задње стране ПС3, буди сигуран да је\nблутуф омогућен на твом Мек уређају, онда повежи контролер\nна Мек преко кабла да упариш ова два. Сада можеш да\nискористиш стартно дугме контролера да га повежеш на Mac\nили преко кабла или бежично (блутуф).\n\nНа неким Мек уређајима можете бити упитани за шифру током упаривања.\nАко се ово деси погледај следећи туториал или Гугл за помоћ.\n\n\n\n\nПС3 контролери конектовани бежично би требали бити приказани на\nлисти урађаја у Поставке система->Блутуф. Можда ћеш требати да их\nуклониш са те листа када хоћеш да их поново користиш на твом PS3.\n\nТакође буди сигуран да више нису повезани на блутуф када их не\nкористиш или ће батерија наставити да се троши.\n\nБлутуф би требало да издржи 7 повезаних уређаја, мада може да\nварира.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "Да користиш ПС3 контролер са твојим \"OУЈА\", једноставно их повежи са каблом\nда их упариш. Радећи ово остали контролери можда више неће бити\nконектовани, зато би требало да растартујеш \"ОУЈА\" и извадиш кабл.\n\nСада би требао да можеш да искористиш дугме \"кућа\" на контролеру дугме да\nих конектујеш бежично. Када завршиш са играњем, држи дугме \"кућа\" 10\nсекунди да искључиш контролер; иначе ако остану укључени трошиће батерију\nна уређају.", + "ouyaInstructionsTextScale": 0.74, + "pairingTutorialText": "видео-туториал за упаривање", + "titleText": "Користи ПС3 контролер са \"${APP_NAME}\" игром:" + }, + "punchBoldText": "УДАРАЦ", + "punchText": "Ударац", + "purchaseForText": "Купи за ${PRICE}", + "purchaseGameText": "Купи игру", + "purchasingText": "Куповина...", + "quitGameText": "Изађи из \"${APP_NAME}\" игре?", + "quittingIn5SecondsText": "Излажење за 5 секунди...", + "randomPlayerNamesText": "Боб, Неца, Маре, Џони, Цане, Мики, Змај, Ноле, Перо, Ацо, Каћа, Нина, Мина, Маки, Сташа, Маја, Тања, Теа, Тина, Ема, Лаки, Лара, Уна, Лена, Реља", + "randomText": "Насумично", + "rankText": "Ранк", + "ratingText": "Оцена", + "reachWave2Text": "Стигни до 2. рунде да добијеш ранк.", + "readyText": "спреман", + "recentText": "Скорије", + "remoteAppInfoShortText": "\"${APP_NAME}\" игра је најзабавнија када се игра са породицом\nили пријатељима. Повежи један или више контролера и инсталирај\n\"${REMOTE_APP_NAME}\" апликацију на телефоне или таблете да би\nих користио као контролере.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Позиција дугмади", + "button_size": "Вечичина дугмета", + "cant_resolve_host": "Не може да се пронађе домаћин.", + "capturing": "Чекање…", + "connected": "Повезано.", + "description": "Користи свој телефон или таблет као контролер за BombSquad игру.\nДо 8 уређаја може да се повеже у исто време на ТВ или таблет за праву играчку лудницу.", + "disconnected": "Ниси више повезан на сервер.", + "dpad_fixed": "фиксирано", + "dpad_floating": "покретно", + "dpad_position": "Позиција окидача", + "dpad_size": "Величина окидача", + "dpad_type": "Тип окидача", + "enter_an_address": "Унеси адресу", + "game_full": "Игра је пуна или не прихвата конекције.", + "game_shut_down": "Игра је угашена.", + "hardware_buttons": "Хардверска дугмад", + "join_by_address": "Придружи се преко адресе...", + "lag": "Кашњење: ${SECONDS} секунди", + "reset": "Врати на подразумевано", + "run1": "Трчање 1", + "run2": "Трчање 2", + "searching": "Тражење \"BombSquad\" игара...", + "searching_caption": "Притисни на име игре да се придружиш.\nБуди сигуран да си на истој Wi-Fi мрежи као и игра.", + "start": "Стартуј", + "version_mismatch": "Верзије се не подударају.\nБуди сигуран да су \"BombSquad\" игра и \"BombSquad\nRemote\" на последњој верзији и покушај опет." + }, + "removeInGameAdsText": "Откључај \"${PRO}\" у продавници да уклониш рекламе из игре.", + "renameText": "Промени име", + "replayEndText": "Прекини гледање", + "replayNameDefaultText": "Снимак последње игре", + "replayReadErrorText": "Грешка при пуштању снимка.", + "replayRenameWarningText": "Промени име \"${REPLAY}\" после игре ако хоћеш да сачуваш; у другом случају ће бити избрисан.", + "replayVersionErrorText": "Извињавамо се, овај снимак је направљен у \nдругој верзији игре и више не може да се гледа.", + "replayWatchText": "Погледај снимак", + "replayWriteErrorText": "Грешка при прављењу снимка.", + "replaysText": "Снимци игре", + "reportPlayerExplanationText": "Корсти ову пошту да пријавиш играча за варање, неприкладан говор или друго лоше\nпонашање. Молимо вас опишите испод:", + "reportThisPlayerCheatingText": "Варање", + "reportThisPlayerLanguageText": "Неприкладан говор", + "reportThisPlayerReasonText": "За шта хоћеш да га пријавиш?", + "reportThisPlayerText": "Пријави овог играча", + "requestingText": "Узимање...", + "restartText": "Рестарт", + "retryText": "Покушај опет", + "revertText": "Врати", + "runText": "Трчање", + "saveText": "Сачувај", + "scanScriptsErrorText": "Грешка/е у скенирању скрипти; видети дневник за детаље.", + "scoreChallengesText": "Резултати изазова", + "scoreListUnavailableText": "Листа резултата недоступна.", + "scoreText": "Резултат", + "scoreUnits": { + "millisecondsText": "Милисекунди", + "pointsText": "Поени", + "secondsText": "Секунди" + }, + "scoreWasText": "(био је ${COUNT})", + "selectText": "Изабери", + "seriesWinLine1PlayerText": "ЈЕ ПОБЕДИО", + "seriesWinLine1TeamText": "ЈЕ ПОБЕДИО", + "seriesWinLine1Text": "ЈЕ ПОБЕДИО", + "seriesWinLine2Text": "СЕРИЈУ ИГАРА!", + "settingsWindow": { + "accountText": "Налог", + "advancedText": "Напредно", + "audioText": "Аудио", + "controllersText": "Контролери", + "graphicsText": "Графика", + "playerProfilesMovedText": "Обавештење: Профили играча су померени у прозор \"Налог\" у главном менију.", + "titleText": "Подешавања" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(једноставна, уграђена тастатура не екрану за уређивање текста)", + "alwaysUseInternalKeyboardText": "Увек користи интерну тастатуру", + "benchmarksText": "Провере и тестови оптерећења", + "disableCameraGyroscopeMotionText": "Онемогући кретање жироскопа камере", + "disableCameraShakeText": "Исључи дрмање камере", + "disableThisNotice": "(можеш да искључиш ова обавештења у напредним подешавањима)", + "enablePackageModsDescriptionText": "(омогућива убацивања додатних модова али онемогућава игра на мрежи)", + "enablePackageModsText": "Омогући локални пакет модова", + "enterPromoCodeText": "Унеси код", + "forTestingText": "Обавештење: ове вредности су само за тестирање и биће обрисане када се изађе из апликације.", + "helpTranslateText": "\"${APP_NAME}\" језички преводи су рад играча. Ако би желео\nда учествујеш у преводу или да измениш превод прати линк\nиспод. Користите само ако сте познавалац језика. Хвала унапред!", + "kickIdlePlayersText": "Избаци неактивне играче", + "kidFriendlyModeText": "Дечији мод (умањено насиље и сл.)", + "languageText": "Језици", + "moddingGuideText": "Водич за модове", + "mustRestartText": "Мораш да рестартујеш игру да би се ово применило.", + "netTestingText": "Тестирање мреже", + "resetText": "Ресетуј", + "showBombTrajectoriesText": "Приказуј путању бомби", + "showPlayerNamesText": "Приказуј имена играча", + "showUserModsText": "Покажи фолдер са модовима", + "titleText": "Напредно", + "translationEditorButtonText": "\"${APP_NAME}\" измењивање превода", + "translationFetchErrorText": "недоступан статус превода", + "translationFetchingStatusText": "проверавање статуса превода...", + "translationInformMe": "Обавести ме када мом језику требају нове измене", + "translationNoUpdateNeededText": "тренутни језик је завршен са превођењем; јуупии!", + "translationUpdateNeededText": "** тренутни језик треба додатне измене!! **", + "vrTestingText": "Тестирање ВР" + }, + "shareText": "Подели", + "sharingText": "Дељење...", + "showText": "Прикажи", + "signInForPromoCodeText": "Мораш бити пријавњен на налог да би кодови имали ефекта.", + "signInWithGameCenterText": "Да би користио Гејм Сентр налог,\nпријави се преко Гејм Сентр апликације.", + "singleGamePlaylistNameText": "Само \"${GAME}\"", + "singlePlayerCountText": "1 играч", + "soloNameFilterText": "Соло \"${NAME}\"", + "soundtrackTypeNames": { + "CharSelect": "Бирање лика", + "Chosen One": "Одабран", + "Epic": "Епски мод игре", + "Epic Race": "Епска трка", + "FlagCatcher": "Укради заставу", + "Flying": "Лепи снови", + "Football": "Фудбал", + "ForwardMarch": "Јуриш", + "GrandRomp": "Освајање", + "Hockey": "Хокеј", + "Keep Away": "Бежање", + "Marching": "Јурцање", + "Menu": "Главни мени", + "Onslaught": "Нападање", + "Race": "Трка", + "Scary": "Краљ брда", + "Scores": "Екран са резултатима", + "Survival": "Елиминација", + "ToTheDeath": "Смртна борба", + "Victory": "Екран са финалним резултатима" + }, + "spaceKeyText": "размак", + "statsText": "Статистике", + "storagePermissionAccessText": "Ово треба дозволу за коришћење меморије.", + "store": { + "alreadyOwnText": "Већ поседујеш \"${NAME}\"!", + "bombSquadProNameText": "Професионални \"${APP_NAME}\"", + "bombSquadProNewDescriptionText": "• Уклања рекламе и поруке за куповину пуне верзије\n• Откључава више подешавања игре\n• Такође укључује:", + "buyText": "Купи", + "charactersText": "Ликови", + "comingSoonText": "Долази ускоро...", + "extrasText": "Додаци", + "freeBombSquadProText": "\"BombSquad\" игра је сада бесплатна, али пошто си је већ платио добићеш\nпрофесионалну BombSquad надоградњу и ${COUNT} тикета за захвалност.\nУживај у новим стварима и хвала ти за подршку!\n-Ерик", + "holidaySpecialText": "Празнични специјал", + "howToSwitchCharactersText": "(иди у \"${SETTINGS} -> ${PLAYER_PROFILES}\" да одобриш и прилагодиш лика)", + "howToUseIconsText": "(направи глобални профил играча (у прозору за налоге) да користиш ово)", + "howToUseMapsText": "(користи ове мапе у својим сопственим \"Свако за себе\"/тимским листама игара)", + "iconsText": "Иконице", + "loadErrorText": "Не може да се учита страница.\nПровери своју интернет конекцију.", + "loadingText": "учитавање", + "mapsText": "Мапе", + "miniGamesText": "Мини игре", + "oneTimeOnlyText": "(јединствена прилика)", + "purchaseAlreadyInProgressText": "Коповина ове ставке је већ у процесу.", + "purchaseConfirmText": "Купити \"${ITEM}\"?", + "purchaseNotValidError": "Куповина није важећа.\nКонтактирај ${EMAIL} ако је ово грешка.", + "purchaseText": "Купи", + "saleBundleText": "Попуст за комплет!", + "saleExclaimText": "Попуст!", + "salePercentText": "(${PERCENT}% снижено)", + "saleText": "ПОПУСТ", + "searchText": "Тражи", + "teamsFreeForAllGamesText": "\"Свако за себе\" / тимске игре", + "totalWorthText": "*** вредност од ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Надогради?", + "winterSpecialText": "Зимски специјал", + "youOwnThisText": "- поседујеш ово -" + }, + "storeDescriptionText": "Лудница за заједницу од 8 играча!\n\nРазнеси своје пријатеље (или компјутер) у турнирима експлозивних мини игара као на пример: \"Узми заставу\", \"Експлозивни хокеј\" и \"Епски успорена смртна борба\"!\n\nЈедноставне контроле и широк обим подршке контролера праве ову игру лаку за до 8 играча у акцији; можеш чак користити и мобилне уређаје каи контролере преко \"BombSquad Remote\" апликације!\n\nБаци бомбе!\n\nПровери www.froemling.net/bombsquad за више информација.", + "storeDescriptions": { + "blowUpYourFriendsText": "Разнеси своје пријатеље.", + "competeInMiniGamesText": "Такмичи се у мини играма које обухватају све од тркања до летења.", + "customize2Text": "Прилагоди ликове, мини игре, па чак и листу звукова.", + "customizeText": "Прилагоди ликове и направи своје сопствене листе мини игара.", + "sportsMoreFunText": "Спортови су забавнији са ексползијама.", + "teamUpAgainstComputerText": "Удружите се против компјутера." + }, + "storeText": "Продавница", + "submitText": "Унеси", + "submittingPromoCodeText": "Уношење кода...", + "teamNamesColorText": "Тимска имена/боје...", + "telnetAccessGrantedText": "Телнет приступ одбијен.", + "telnetAccessText": "Телнет приступ примећен; дозволи?", + "testBuildErrorText": "Овај систем за тестирање више није доступан; молимо вас надоградите на најновију верзију.", + "testBuildText": "Систем за тестирање", + "testBuildValidateErrorText": "Није могуће одобрити систем за тестирање. (нема интернет конекције?)", + "testBuildValidatedText": "Систем за тестирање валидан; уживај!", + "thankYouText": "Хвала на подршци! Уживај у игри!!", + "threeKillText": "ТРОСТРУКО УБИСТВО!!", + "timeBonusText": "Додатно време", + "timeElapsedText": "Истекло време", + "timeExpiredText": "Истекло време", + "timeSuffixDaysText": "${COUNT}д", + "timeSuffixHoursText": "${COUNT}с", + "timeSuffixMinutesText": "${COUNT}м", + "timeSuffixSecondsText": "${COUNT}сeк", + "tipText": "Савет", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Топ пријатељи", + "tournamentCheckingStateText": "Провера статуса турнира; молимо вас сачекајте...", + "tournamentEndedText": "Овај турнир се завршио. Нови ће почети ускоро.", + "tournamentEntryText": "Улазак на турнир", + "tournamentResultsRecentText": "Скорашњи резултати турнира", + "tournamentStandingsText": "Табела турнира", + "tournamentText": "Турнир", + "tournamentTimeExpiredText": "Време за турнир истекло", + "tournamentsText": "Турнири", + "translations": { + "characterNames": { + "Agent Johnson": "Агент Џонсон", + "B-9000": "Б-9000", + "Bernard": "Медведић", + "Bones": "Костурко", + "Butch": "Џон", + "Easter Bunny": "Ускршњи зека", + "Flopsy": "Зечић", + "Frosty": "Снешко", + "Gretel": "Гретела", + "Grumbledorf": "Гандалф", + "Jack Morgan": "Џек Морган", + "Kronk": "Кронк", + "Lee": "Леа", + "Lucky": "Срећко", + "Mel": "Кувар", + "Middle-Man": "Супермен", + "Minimus": "Минимус", + "Pascal": "Жиле", + "Pixel": "Звончица", + "Sammy Slam": "Боксер", + "Santa Claus": "Деда Мраз", + "Snake Shadow": "Хитра Сенка", + "Spaz": "Валтер", + "Taobao Mascot": "Таубау Маскота", + "Todd McBurton": "Рамбо", + "Zoe": "Зои", + "Zola": "Зола" + }, + "coopLevelNames": { + "${GAME} Training": "\"${GAME}\" тренинг", + "Infinite ${GAME}": "Бесконачна \"${GAME}\"", + "Infinite Onslaught": "Бесконачна инвазија", + "Infinite Runaround": "Бесконачнo јурцање", + "Onslaught Training": "Тренинг инвазије", + "Pro ${GAME}": "Професионална \"${GAME}\"", + "Pro Football": "Професионални фудбал", + "Pro Onslaught": "Професионална инвазија", + "Pro Runaround": "Професионално јурцање", + "Rookie ${GAME}": "Почетничка \"${GAME}\"", + "Rookie Football": "Почетнички фудбал", + "Rookie Onslaught": "Почетничка инвазија", + "The Last Stand": "Последњи преживели", + "Uber ${GAME}": "Легендарна ${GAME}", + "Uber Football": "Легендарни фудбал", + "Uber Onslaught": "Легендарна инвазија", + "Uber Runaround": "Легендарно јурцање" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Буди означен на одређено време да победиш.\nУбиј означеног да постанеш он.", + "Bomb as many targets as you can.": "Бомбардуј што више мета можеш.", + "Carry the flag for ${ARG1} seconds.": "Носи заставу ${ARG1} секунди.", + "Carry the flag for a set length of time.": "Носи заставу одређен временски период.", + "Crush ${ARG1} of your enemies.": "Разбиј ${ARG1} својих непријатеља.", + "Defeat all enemies.": "Порази све непријатеље.", + "Dodge the falling bombs.": "Избегни падајуће бомбе.", + "Final glorious epic slow motion battle to the death.": "Финална славна епско успорена битка до смрти.", + "Gather eggs!": "Сакупи јаја!", + "Get the flag to the enemy end zone.": "Однеси заставу до непријатељске завршне зоне.", + "How fast can you defeat the ninjas?": "Колико брзо можеш поразити нинџе?", + "Kill a set number of enemies to win.": "Убиј одређен број непријатеља за победу.", + "Last one standing wins.": "Последњи на ногама побеђује.", + "Last remaining alive wins.": "Последњи који остане жив побеђује.", + "Last team standing wins.": "Последњи тим на ногама побеђује.", + "Prevent enemies from reaching the exit.": "Спречи непријатеље да дођу до излаза.", + "Reach the enemy flag to score.": "Дођи до непријатељске заставе да постигнеш поен.", + "Return the enemy flag to score.": "Врати непријатељску заставу да постигнеш поен.", + "Run ${ARG1} laps.": "Истрчи ${ARG1} круга.", + "Run ${ARG1} laps. Your entire team has to finish.": "Истрчи ${ARG1} круга. Цео твој тим мора да заврши.", + "Run 1 lap.": "Истрчи 1 круг.", + "Run 1 lap. Your entire team has to finish.": "Истрчи 1 круг. Цео твој тим мора да заврши.", + "Run real fast!": "Трчи баш брзо!", + "Score ${ARG1} goals.": "Постигни ${ARG1} гола.", + "Score ${ARG1} touchdowns.": "Постигни ${ARG1} гола.", + "Score a goal.": "Постигни гол.", + "Score a touchdown.": "Постигни гол.", + "Score some goals.": "Постигни неколико голова.", + "Secure all ${ARG1} flags.": "Осигурај све ${ARG1} заставе.", + "Secure all flags on the map to win.": "Осигурај све заставе на мапи за победу.", + "Secure the flag for ${ARG1} seconds.": "Осигурај заставу на ${ARG1} секунди.", + "Secure the flag for a set length of time.": "Осигурај заставу на одређени временски период.", + "Steal the enemy flag ${ARG1} times.": "Укради непријатељску заставу ${ARG1} пута.", + "Steal the enemy flag.": "Укради непријатељску заставу.", + "There can be only one.": "Овде може бити само један.", + "Touch the enemy flag ${ARG1} times.": "Додирни непријатељску заставу ${ARG1} пута.", + "Touch the enemy flag.": "Додирни непријатељску заставу.", + "carry the flag for ${ARG1} seconds": "носи заставу ${ARG1} секунди", + "kill ${ARG1} enemies": "убиј ${ARG1} непријатеља", + "last one standing wins": "последњи на ногама побеђује", + "last team standing wins": "последњи тим на ногама побеђује", + "return ${ARG1} flags": "врати ${ARG1} заставе", + "return 1 flag": "врати 1 заставу", + "run ${ARG1} laps": "истрчи ${ARG1} круга", + "run 1 lap": "истрчи 1 круг", + "score ${ARG1} goals": "постигни ${ARG1} гола", + "score ${ARG1} touchdowns": "постигни ${ARG1} гола", + "score a goal": "постигни гол", + "score a touchdown": "постигни гол", + "secure all ${ARG1} flags": "осигурај све ${ARG1} заставе", + "secure the flag for ${ARG1} seconds": "осигурај заставу на ${ARG1} секунди", + "touch ${ARG1} flags": "додирни ${ARG1} заставе", + "touch 1 flag": "додирни 1 заставу" + }, + "gameNames": { + "Assault": "Напад", + "Capture the Flag": "Узми заставу", + "Chosen One": "Одабрани", + "Conquest": "Освајање", + "Death Match": "Битка до смрти", + "Easter Egg Hunt": "Лов на ускршња јаја", + "Elimination": "Елиминација", + "Football": "Фудбал", + "Hockey": "Хокеј", + "Keep Away": "Држи подаље", + "King of the Hill": "Краљ брда", + "Meteor Shower": "Киша метеора", + "Ninja Fight": "Битка са нинџама", + "Onslaught": "Инвазија", + "Race": "Трка", + "Runaround": "Јурцање", + "Target Practice": "Гађање мете", + "The Last Stand": "Последњи преживели" + }, + "inputDeviceNames": { + "Keyboard": "Тастатура", + "Keyboard P2": "Тастатура И2" + }, + "languages": { + "Arabic": "Арапски", + "Belarussian": "Белоруски", + "Chinese": "Кинески (поједностављен)", + "ChineseTraditional": "Кинески (традиционални)", + "Croatian": "Хрватски", + "Czech": "Чешки", + "Danish": "Дански", + "Dutch": "Холандски", + "English": "Енглески", + "Esperanto": "Есперантски", + "Filipino": "филипински", + "Finnish": "Фински", + "French": "Француски", + "German": "Немачки", + "Gibberish": "Џиберски", + "Greek": "Грчки", + "Hindi": "Хинди", + "Hungarian": "Мађарски", + "Indonesian": "Индонежански", + "Italian": "Италијански", + "Japanese": "Јапански", + "Korean": "Корејски", + "Persian": "Персијски", + "Polish": "Пољски", + "Portuguese": "Португалски", + "Romanian": "Румунски", + "Russian": "Руски", + "Serbian": "Српски", + "Slovak": "Словачки", + "Spanish": "Шпански", + "Swedish": "Шведски", + "Tamil": "тамилски", + "Thai": "Тхаи", + "Turkish": "Турски", + "Ukrainian": "Украјински", + "Venetian": "Венецијански", + "Vietnamese": "Вијетнамски" + }, + "leagueNames": { + "Bronze": "Бронза", + "Diamond": "Дијамант", + "Gold": "Златo", + "Silver": "Сребрo" + }, + "mapsNames": { + "Big G": "Велико С", + "Bridgit": "Мост", + "Courtyard": "Игралиште", + "Crag Castle": "Две тврђаве", + "Doom Shroom": "Зла печурка", + "Football Stadium": "Фудбалски стадион", + "Happy Thoughts": "Лепи снови", + "Hockey Stadium": "Хокејашки стадион", + "Lake Frigid": "Ледено језеро", + "Monkey Face": "Лице мајмуна", + "Rampage": "Пирамида", + "Roundabout": "Кружни ток", + "Step Right Up": "Степенице", + "The Pad": "Платформа", + "Tip Top": "Црни врх", + "Tower D": "Торањ", + "Zigzag": "Цик-цак" + }, + "playlistNames": { + "Just Epic": "Само епско", + "Just Sports": "Само спортови" + }, + "scoreNames": { + "Flags": "Заставе", + "Goals": "Голови", + "Score": "Резултат", + "Survived": "Преживео", + "Time": "Време", + "Time Held": "Времена издржано" + }, + "serverResponses": { + "A code has already been used on this account.": "Код је већ искоришћен на овом налогу.", + "A reward has already been given for that address.": "Награда је већ предата за ту адресу.", + "Account linking successful!": "Повезивање налога успешно!", + "Account unlinking successful!": "Растављање налога успешно!", + "Accounts are already linked.": "Налози су већ повезани.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Реклама није могла бити верификована.\nМолимо вас да будете сигурни да сте на официјалној и најновијој верзији игре.", + "An error has occurred; (${ERROR})": "Дошло је до грешке; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Дошло је до грешке; молимо вас обратите се подршци. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Дошло је до грешке; молимо контактирајте support@froemling.net.", + "An error has occurred; please try again later.": "Дошло је до грешке; молимо вас покушајте поново касније.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Да ли сте сигурни да желите да повежете ове налоге?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nОво се не може вратити!", + "BombSquad Pro unlocked!": "Професионални BombSquad откључан!", + "Can't link 2 accounts of this type.": "Не могу да се повежу 2 налога овог типа.", + "Can't link 2 diamond league accounts.": "Не могу бити повезана 2 налога дијамантске лиге.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Немогуће повезати; превазишао си максимум од ${COUNT} повезаних налога.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Примећено је варање; резултати и награде су суспендовани на ${COUNT} дана.", + "Could not establish a secure connection.": "Немогуће успоставити безбедну конекцију.", + "Daily maximum reached.": "Дневни максимум достигнут.", + "Entering tournament...": "Улажење на турнир...", + "Invalid code.": "Неважећи код.", + "Invalid payment; purchase canceled.": "Неважећа уплата; куповина отказана.", + "Invalid promo code.": "Неважећи промо код.", + "Invalid purchase.": "Неважећа куповина.", + "Invalid tournament entry; score will be ignored.": "Неважећи улазак на турнир; резултат ће бити игнорисан.", + "Item unlocked!": "Ствар откључана!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "ПОВЕЗИВАЊЕ ОДБИЈЕНО. ${ACCOUNT} садржи\nзначајне податке и СВИ ЋЕ БИТИ ИЗГУБЉЕНИ.\nМожеш повезати у супротном смеру ако желите\n(и изгубити податке са ОВОГ налога)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Повежи налог ${ACCOUNT} са овим налогом?\nСви постојећи подаци на ${ACCOUNT} ће бити изгубљени.\nОво се не може вратити. Да ли си сигуран?", + "Max number of playlists reached.": "Максималан број листи играња достигнут.", + "Max number of profiles reached.": "Максималан број профила достигнут.", + "Maximum friend code rewards reached.": "Максималан број награда од пријатељских кодова достигнут.", + "Message is too long.": "Порука је предугачка.", + "No servers are available. Please try again soon.": "Нема доступних сервера. Пробај опет касније.", + "Profile \"${NAME}\" upgraded successfully.": "Профил \"${NAME}\" је успешно надограђен.", + "Profile could not be upgraded.": "Профил не може бити надограђен.", + "Purchase successful!": "Куповина успешна!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Примљено ${COUNT} тикета за пријављивање.\nВрати се сутра да добијеш ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Фукционалност сервера више није подржана на овај верзији игре;\nМолимо вас надоградите на новију верзију.", + "Sorry, there are no uses remaining on this code.": "Извињавамо се, овај код више не може да се користи.", + "Sorry, this code has already been used.": "Извињавамо се, овај код је већ употребљен.", + "Sorry, this code has expired.": "Извињавамо се, код је истекао.", + "Sorry, this code only works for new accounts.": "Извињавамо се, овај код ради само за нове налоге.", + "Still searching for nearby servers; please try again soon.": "Тражење сервера у близини још увек траје; покушај касније.", + "Temporarily unavailable; please try again later.": "Привремено недоступно; молимо вас покушајте поново касније.", + "The tournament ended before you finished.": "Турнир се завршио пре него што си завршио.", + "This account cannot be unlinked for ${NUM} days.": "Овај налог не може бити растављен још ${NUM} дана.", + "This code cannot be used on the account that created it.": "Овај код не може бити употребљен на налогу који га је направио.", + "This is currently unavailable; please try again later.": "Ово тренутно није доступно; молимо вас покушајте касније.", + "This requires version ${VERSION} or newer.": "Ово захтева верзију ${VERSION} или новију.", + "Tournaments disabled due to rooted device.": "Турнири су онемогућени због рутованог уређаја.", + "Tournaments require ${VERSION} or newer": "За турнир ти треба ${VERSION} или новија", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Растави ${ACCOUNT} од овог налога?\nСви подаци са ${ACCOUNT} ће бити рестартовани.\n(осим достигнућа у неким случајевима)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "УПОЗОРЕЊЕ: жалбе за варање су поднете против твог налога.\nНалозима код којих се установи да варају биће забрањен приступ. Молимо вас играјте поштено.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Да ли би желеo да повежеш налог на твом уређају са овим?\n\nНалог на твом уређају је ${ACCOUNT1}\nОвај налог је ${ACCOUNT2}\n\nОво ће ти омогућити да задржиш постојећи напредак.\nУпозорење: ово се не може вратити!", + "You already own this!": "Већ поседујеш ово!", + "You can join in ${COUNT} seconds.": "Можеш се придружити за ${COUNT} секунди.", + "You don't have enough tickets for this!": "Немаш довољно тикета за ово!", + "You don't own that.": "Не поседујеш ово.", + "You got ${COUNT} tickets!": "Добио си ${COUNT} тикета!", + "You got a ${ITEM}!": "Добио си ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Унапређен си у нову лигу; честитамо!", + "You must update to a newer version of the app to do this.": "Мораш надоградити на новију верзију апликације да урадиш ово.", + "You must update to the newest version of the game to do this.": "Мораш надоградити на најновију верзију игре да урадиш ово.", + "You must wait a few seconds before entering a new code.": "Мораш чекати неколико секунди пре него што унесеш нови код.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Рангиран си #${RANK} на последњем турниру. Хвала на игрању!", + "Your account was rejected. Are you signed in?": "Твој налог је одбијен. Да ли си пријављен?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Твоја копија игре је модификована. Молимо\nвас вратите неке промене и покушајте поново.", + "Your friend code was used by ${ACCOUNT}": "Твој код за пријатеља је искоришћен од стране ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 минут", + "1 Second": "1 секунда", + "10 Minutes": "10 минута", + "2 Minutes": "2 минута", + "2 Seconds": "2 секунде", + "20 Minutes": "20 минута", + "4 Seconds": "4 секунде", + "5 Minutes": "5 минута", + "8 Seconds": "8 секунди", + "Allow Negative Scores": "Дозволи негативне поене", + "Balance Total Lives": "Балансирај број укупних живота", + "Bomb Spawning": "Стварање бомби", + "Chosen One Gets Gloves": "Одабрани добија рукавице", + "Chosen One Gets Shield": "Одабрани добија штит", + "Chosen One Time": "Време за одабраног", + "Enable Impact Bombs": "Омогући бомбе на додир", + "Enable Triple Bombs": "Омогући троструке бомбе", + "Entire Team Must Finish": "Цео тим мора да заврши", + "Epic Mode": "Епски мод", + "Flag Idle Return Time": "Време повратка испуштене заставе", + "Flag Touch Return Time": "Време повратка заставе од додира", + "Hold Time": "Време задржавања", + "Kills to Win Per Player": "Убистава за победу по играчу", + "Laps": "Кругови", + "Lives Per Player": "Животи по играчу", + "Long": "Дуго", + "Longer": "Дуже", + "Mine Spawning": "Стварање мина", + "No Mines": "Без мина", + "None": "Ниједан", + "Normal": "Нормално", + "Pro Mode": "Професионални мод", + "Respawn Times": "Време оживљавања", + "Score to Win": "Поени за победу", + "Short": "Кратко", + "Shorter": "Краће", + "Solo Mode": "Соло мод", + "Target Count": "Број мета", + "Time Limit": "Временско ограничење" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} је дисквалификован јер је ${PLAYER} напустио игру", + "Killing ${NAME} for skipping part of the track!": "Убијање ${NAME} због прескакања дела стазе!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Упозорење за ${NAME}: турбо / непрестано притискање те избацује." + }, + "teamNames": { + "Bad Guys": "Лоши момци", + "Blue": "Плави", + "Good Guys": "Добри момци", + "Red": "Црвени" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Перфектно усклађен ударац из залета са скоком вртећи се успут може убити\nједним ударцем и зарадити вам доживотно поштовање пријатеља.", + "Always remember to floss.": "Увек се сети да опереш зубе.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Направите профиле играча за себе и своје пријатеље са\nжељеним именима и изгледом уместо да користите насумично одабране.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Уклете кутије те претварају у темпирану бомбу.\nЈедини лек је да брзо зграбиш прву помоћ.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Упркос њиховом изгледу, све способности ликова су идентичне,\nзато само изабери оног који највише личи на тебе.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Немој да се превише опустиш са штитом; и даље можеш да паднеш са мапе.", + "Don't run all the time. Really. You will fall off cliffs.": "Не трчи све време. Озбиљно. Пашћеш са мапе.", + "Don't spin for too long; you'll become dizzy and fall.": "Не врти се предуго; почеће да ти се врти у глави и пашћеш.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Држи било које дугме за трчање. (Окидачи добро раде ако их имаш)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Држи било које дугме за трчање. Стићи ћеш на места брже\nали нећеш скретати баш добро, зато се пази ивица.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ледене бомбе нису много јаке, али оне заледе\nсве које закаче, остављајући их подложне ломљењу.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Ако те неко ухвати, ударај га и испустиће те.\nОво такође ради и у стварном животу.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Ако сте танки са контролерима, преузмите \"${REMOTE_APP_NAME}\" апликацију\nна мобилне уређаје и користите их као контролере.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Ако добијеш лепљиву бомбу залепњену за тебе, скачи унаоколо и врти се у круг. Можда\nћеш отрести бомбу са себе, или ако ништа барем ће твоји последњи тренуци бити забавни.", + "If you kill an enemy in one hit you get double points for it.": "Ако убијеш непријатеља једним ударцом добијаш двоструке поене за то.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Ако покупиш клетву, твоја једина нада за преживљавање\nје да нађеш прву помоћ у следећих неколико секунди.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Ако стојиш у једном месту, ти си мртав. Трчи и избегавај да преживиш..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Ако имаш много играча који долазе и одлазе, укључи \"аутоматски избаци неактивне играче\"\nу подешавањима у случају да неко заборави да напусти игру.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Ако уређај постаје врућ или желиш да сачуваш батерију,\nсмањи детаље или резолуцију у Подешавања->Графике", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Ако ти је слика сецка, покушај да смањиш резолуцију\nили детаље у подешавањима графика у игри.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "У игри \"Узми заставу\", твоја властита застава мора бити у бази да би постигао поен. Ако је\nдруги тим близу постизања поена, крађа њихове заставе може бити добар начин да их зауставите.", + "In hockey, you'll maintain more speed if you turn gradually.": "У хокеју, одржаћеш више брзине ако скрећеш постепено.", + "It's easier to win with a friend or two helping.": "Лакше је победити са пријатељем или два у помоћи.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Скочи у тренутку бацања бомбе да би је бацио на вишу тачку.", + "Land-mines are a good way to stop speedy enemies.": "Мине су добар начин да се зауставе брзи непријатељи.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Многе ствари могу бити подигнуте и бачене, укључујући друге играче. Бацање\nнепријатеља са литице може бити ефективна али и емоционално задовољавајућа стратегија.", + "No, you can't get up on the ledge. You have to throw bombs.": "Не, не можеш само стајати на ивици. Мораш да бацаш бомбе.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Играчи се могу придружити и напустити у сред већине игара,\nтакође и контролери се могу укључити и искључити у лету.", + "Practice using your momentum to throw bombs more accurately.": "Вежбај коришћење залета да бациш бомбу прецизније.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Ударци наносе више штете ако се твоје песнице крећу,\nзато пробај трчање, скакање, и вртење као да си луд.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Трчи напред и назад пре бацања бомбе\nда је завртиш и бациш даље.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Уништи групу непријатеља активирајући\nбомбу близу кутије са динамитом.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Глава је најрањивији део, зато лепљива бомба\nна глави обично значи крај живота.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Овај ниво нема крај, али високи резултат овде\nзарадиће ти вечно поштовање широм света.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Снага бацања је базирана на страни коју држиш на контролеру.\nДа бациш нешто нежно испред себе, не држи ни једну страну.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Досадила ти је листа звукова? Замени је својом!\nВиди Подешавања->Аудио->Листа звукова", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Пробај да \"пржиш\" бомбе секунду или две пре него што их бацаш.", + "Try tricking enemies into killing eachother or running off cliffs.": "Пробај да завараш непријатеље да се међусобно убију или падну са ивице.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Користи дугме за подизање да узмеш заставу < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Окрећи се напред-назад да добијеш већу даљину када бацаш.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Можеш да \"нациљаш\" ударце окретањем лево или десно.\nОво је корисно за бацање лоших момака са ивица или за постизање поена у хокеју.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Можеш да процениш када ће бомба да експлодира гледајући на\nбоју варница са фитиља: жуте..наранџасте..црвене..БУМ.", + "You can throw bombs higher if you jump just before throwing.": "Можеш да бациш бомбе више ако поскочиш само трен пре бацања.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Добијаш штету када удариш главом у нешто, зато\nпокушај да не удараш главом о ствари.", + "Your punches do much more damage if you are running or spinning.": "Твоји ударци наносе више штете ако трчиш или се окрећеш." + } + }, + "trophiesRequiredText": "Ово захтева барем ${NUMBER} трофеја.", + "trophiesText": "Трофеји", + "trophiesThisSeasonText": "Трофеји ове сезоне", + "tutorial": { + "cpuBenchmarkText": "Покретање туториала на смешним брзинама (најпре тестира брзину процесора)", + "phrase01Text": "Хеј ти!", + "phrase02Text": "Добродошао у \"${APP_NAME}\"!", + "phrase03Text": "Ево неколико савета како да контролишеш твог лика:", + "phrase04Text": "Много ствари у \"${APP_NAME}\" је засновано на ФИЗИЦИ.", + "phrase05Text": "На пример, када удариш,..", + "phrase06Text": "..штета је заснована на брзини твојих песница.", + "phrase07Text": "Видиш? Нисмо се кретали, ${NAME} је ово једва осетио.", + "phrase08Text": "Хајде сада да скочимо и да се завртимо за већу брзину.", + "phrase09Text": "Ах, то је боље.", + "phrase10Text": "Трчање такође помаже.", + "phrase11Text": "Држи БИЛО КОЈЕ дугме за трчање.", + "phrase12Text": "За супер-екстра ударце, пробај трчање И вртење.", + "phrase13Text": "Упс; ${NAME}, извини за ово.", + "phrase14Text": "Многе ствари можеш покупити и бацити као што су заставе.. или ${NAME}.", + "phrase15Text": "На крају, ту су бомбе.", + "phrase16Text": "Бацање бомби захтева вежбу.", + "phrase17Text": "Аућ! Не баш добро бацање.", + "phrase18Text": "Кретање ти помаже да бациш даље.", + "phrase19Text": "Скакање ти помаже да бациш више.", + "phrase20Text": "\"Заврти\" твоје бомбе за још даље бацање.", + "phrase21Text": "Темпирање бомби може бити изазовно.", + "phrase22Text": "Јој.", + "phrase23Text": "Пробај да \"пржиш\" фитиљ секунду или две.", + "phrase24Text": "Опа! Лепо испржено.", + "phrase25Text": "Паа, то је отприлике то.", + "phrase26Text": "Сада иди и направи ме поносним, лаве!", + "phrase27Text": "Запамти свој тренинг, и ВРАТИЋЕШ се жив!", + "phrase28Text": "...па, можда...", + "phrase29Text": "Срећно!", + "randomName1Text": "Чода", + "randomName2Text": "Иван", + "randomName3Text": "Мили", + "randomName4Text": "Лука", + "randomName5Text": "Фићо", + "skipConfirmText": "Озбиљно желиш да прескочиш туториал? Додирни или притисни да наставиш.", + "skipVoteCountText": "${COUNT}/${TOTAL} гласова за прескакање", + "skippingText": "прескакање туториала...", + "toSkipPressAnythingText": "(додирни или притисни било шта да прескочиш туторијал)" + }, + "twoKillText": "ДВОСТРУКО УБИСТВО!", + "unavailableText": "недоступно", + "unconfiguredControllerDetectedText": "Неподешен контролер откривен:", + "unlockThisInTheStoreText": "Ово мора бити откључано у продавници.", + "unlockThisProfilesText": "Да направиш више од ${NUM} профила, треба да:", + "unlockThisText": "Да откључаш ово, треба да:", + "unsupportedHardwareText": "Извињавамо се, овај хардвер није подржан од стране игре.", + "upFirstText": "Прво на реду:", + "upNextText": "Следећа игра на реду ${COUNT}:", + "updatingAccountText": "Ажурирање твог налога...", + "upgradeText": "Надогради", + "upgradeToPlayText": "Откључај \"${PRO}\" у продавници игре да играш ово.", + "useDefaultText": "Користи подразумевано", + "usesExternalControllerText": "Ова игра користи спољашњи контролер за унос.", + "usingItunesText": "Коришћење музичке апликације за листу звукова...", + "validatingTestBuildText": "Потврђивање система за тестирање...", + "victoryText": "Победа!", + "voteDelayText": "Не можеш почети ново гласање још ${NUMBER} секунди", + "voteInProgressText": "Гласање је већ у току.", + "votedAlreadyText": "Већ си гласао", + "votesNeededText": "${NUMBER} гласова потребно", + "vsText": "против", + "waitingForHostText": "(чекање ${HOST} да настави)", + "waitingForPlayersText": "чекање играча да се придруже...", + "waitingInLineText": "Чекање у реду (заједница је пуна)...", + "watchAVideoText": "Погледај видео", + "watchAnAdText": "Погледај рекламу", + "watchWindow": { + "deleteConfirmText": "Избриши \"${REPLAY}\"?", + "deleteReplayButtonText": "Избриши\nснимак", + "myReplaysText": "Моји снимци", + "noReplaySelectedErrorText": "Нема изабраних снимака", + "playbackSpeedText": "Брзина пуштања: ${SPEED}", + "renameReplayButtonText": "Преименуј\nснимак", + "renameReplayText": "Преименуј \"${REPLAY}\" у:", + "renameText": "Преименуј", + "replayDeleteErrorText": "Грешка при брисању снимка.", + "replayNameText": "Име снимка", + "replayRenameErrorAlreadyExistsText": "Снимак са тим именом већ постоји.", + "replayRenameErrorInvalidName": "Немогуће преименовати снимак; неважеће име.", + "replayRenameErrorText": "Грешка при преименовању снимка.", + "sharedReplaysText": "Дељени снимци", + "titleText": "Гледај", + "watchReplayButtonText": "Погледај\nснимак" + }, + "waveText": "Рунда", + "wellSureText": "Наравно!", + "wiimoteLicenseWindow": { + "titleText": "Дарвин Римоут права задржана" + }, + "wiimoteListenWindow": { + "listeningText": "Ослушкивање за Вимоутс...", + "pressText": "Притисните истовремено дугмад 1 и 2 на Вимоуту.", + "pressText2": "На новијим Вимоут са уграђеним плус покретима, позади притисни црвено дугме \"синхронизација\"." + }, + "wiimoteSetupWindow": { + "copyrightText": "Дарвин Римоут права задржана", + "listenText": "Слушај", + "macInstructionsText": "Буди сигуран да је твој Ви искључен и да је блутуф\nомогућен на твом Мек уређају, онда притисни \"Слушај\".\nВимоут подршка може бити помало непоуздана, па ћеш можда\nморати да покушаш неколико пута пре него што се повежеш.\n\nБлутуф би требао да подржи до 7 повезаних уређаја,\nмада може да варира.\n\nИгра подржава оригинални Вимоутс, Нанчакс,\nкао и класичне контролере.\nНовији 'Ви ремоут плус' сада ради такође\nали не са додацима.", + "thanksText": "Хвала Дарвин Ремоут тиму\nшто је ово омогућио.", + "titleText": "Вимоут подешавања" + }, + "winsPlayerText": "${NAME} је победио!", + "winsTeamText": "${NAME} је победио!", + "winsText": "${NAME} је победио!", + "workspaceSyncErrorText": "Грешка синхронизовања ${WORKSPACE}. Погледајте лог за више детаља.", + "workspaceSyncReuseText": "Синхронизовање ${WORKSPACE} неуспешно. Коришћење претходно синхронизоване верзије.", + "worldScoresUnavailableText": "Светски резултати недоступни.", + "worldsBestScoresText": "Најбољи резултати на свету", + "worldsBestTimesText": "Најбоља времена на свету", + "xbox360ControllersWindow": { + "getDriverText": "Набави драјвер", + "macInstructions2Text": "Да користиш контролере бежично, треба ти ресивер који долази са\n\"Иксбокс 360 безични контролери за Виндовс\". Један ресивер\nдозвољава повезивање до 4 контролера.\n\nВажно: ресивери треће стране неће радити са овим драјвером;\nбуди сигуран да ресивер има \"Мајкрософт\" на себи, не \"Иксбокс\n360\". Мајкрософт ово више не продаје одвојено, па ћете морати\nда га набавите заједно са контролером или потражите на и-бају.\n\nАко вам ово помогне, молимо вас размототрите донирање\nдивелоперу драјвера на његовом сајту.", + "macInstructionsText": "Да користиш Иксбокс 360 контролере, биће ти потребно\nда инсталираш Мек драјвер доступан на линку испод.\nРади и са жичаним и са бежичним контролерима.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Да користиш жичане Иксбокс 360 контролере са \"BombSquad\",\nједноставно их укључи у USB прикључак вашег уређаја. Можеш\nкористити USB адаптер да повежеш више контролера.\n\nЗа коришћење бежичних управљача биће ти потребан бежични ресивер,\nдоступан као део \"Иксбокс 360 бежичних контролера за Виндовс\"\nпакета или продат посебно. Сваки ресивер се прикључује на USB\nприкључак и омогућава повезивање до 4 бежична управљача.", + "titleText": "Коришћење Иксбокс 360 управљача са \"${APP_NAME}\":" + }, + "yesAllowText": "Да, дозволи!", + "yourBestScoresText": "Твоји најбољи резултати", + "yourBestTimesText": "Твоја најбоља времена" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/slovak.json b/dist/ba_data/data/languages/slovak.json new file mode 100644 index 0000000..8acf13b --- /dev/null +++ b/dist/ba_data/data/languages/slovak.json @@ -0,0 +1,1875 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Mená účtov nemôžu obsahovať emoji alebo špeciálne znaky", + "accountProfileText": "Profil konta", + "accountsText": "Účty", + "achievementProgressText": "Achievementy: ${COUNT} z ${TOTAL}", + "campaignProgressText": "Priebeh kampane [Hard] : ${PROGRESS}", + "changeOncePerSeason": "Toto môžete zmeniť len raz za sezónu.", + "changeOncePerSeasonError": "Musíte počkať do ďalšej sezóny aby ste mohli toto znova zmeniť (${NUM} days)", + "customName": "Vlastný názov", + "linkAccountsEnterCodeText": "Vložte kód", + "linkAccountsGenerateCodeText": "Vygenerovať kód", + "linkAccountsInfoText": "(zdielajte postup medzi rôznymi platformami)", + "linkAccountsInstructionsNewText": "Pre prepojenie dvoch účtov, vygenerujte kód na prvom \na vložte ten kód na druhom. Dáta z \ndruhého účtu budú zdieľané medzi nimi.\n (Dáta z prvého účtu budú stratené)\n\nMôžete prepojiť až ${COUNT} účtov.\n\nDÔLEŽITÉ: prepájajte len účty ktoré vlastníte;\nak prepojíte účty priateľov, nebudete \nschopní hrať online naraz.", + "linkAccountsInstructionsText": "Abyste mohli pripojiť dva účty, vygenerujte na prvom kód,\nktorý následne vložte na účte druhom.\nPostup a inventár sa skombinujú.\nMôžete spojiť až ${COUNT} účtov.", + "linkAccountsText": "Pripojené účty", + "linkedAccountsText": "Spojené účty:", + "manageAccountText": "Spravovať Účet", + "nameChangeConfirm": "Zmeniť vás účet na ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Týmto zresetuješ progres v tímovej hre\na všetky dosiahnuté skóre (tikety ostanú). Nedá sa \nto vrátiť späť. Pokračovať?", + "resetProgressConfirmText": "Týmto zresetuješ progres v tímovej hre,\nvšetky úspechy a dosiahnuté skóre\n(tikety ostanú). \nNedá sa to vrátiť späť. \nPokračovať?", + "resetProgressText": "Zresetovať progres", + "setAccountName": "Nastavte meno účtu", + "setAccountNameDesc": "Vyberte meno, ktoré sa bude zobrazovať na vašom účte.\nMôžete použiť meno jedného zo svojich prepojených \núčtov alebo si vytvorte svoje vlastné meno.", + "signInInfoText": "Prihláste sa, abyste zbierali tickety, dokončite online \na zdielajte postup medzi zariadeními.", + "signInText": "Prihlasujem", + "signInWithDeviceInfoText": "(iba automatický účet je dostupný pre toto zariadenie)", + "signInWithDeviceText": "Prihláste sa s účtom na zariadení", + "signInWithGameCircleText": "Prihlásiť sa s Game Circle", + "signInWithGooglePlayText": "Príhlásit sa s Google Play", + "signInWithTestAccountInfoText": "(starý typ účtu; v budúcnosti používajte účty zariadení)", + "signInWithTestAccountText": "Prihlásit sa s testovacím účtom", + "signInWithV2InfoText": "(účet, ktorý funguje na všetkých platformách)", + "signInWithV2Text": "Prihláste sa pomocou účtu BombSquad", + "signOutText": "Odhlasujem", + "signingInText": "Prihlasujem", + "signingOutText": "Odhlasujem", + "testAccountWarningOculusText": "Upozornenie: ak ste prihlásení s \" test \" účtom .\nBude nahradený \"skutočný \" účet v priebehu tohto\nroku , ktorý ponúkne nákup vstupeniek a ďalšie funkcie .\nTeraz budete musieť získať všetky lístky v hre .\n( Tie sa však dostanete pre BombSquad aktualizáciou zdarma )", + "testAccountWarningText": "VAROVANIE : ste prihlásení s \" test \" účtu .\nTento účet je viazaný na tejto konkrétne zariadenie a\nmôže dôjsť k vynulovanie pravidelne . ( Takže nie je dôvod míňať\nveľa času a zneškodnenia / odomknutie veci pre neho )\nPrevádzkujeme predajnej verzii hry používať \" skutočné \"\núčtu ( Game - Center , Google Plus , atď ) To tiež\numožňuje uložiť svoj ​​postup v cloude a podielu\nže medzi rôznymi zariadeniami .", + "ticketsText": "Tikety: ${COUNT}", + "titleText": "Konto", + "unlinkAccountsInstructionsText": "Vyberte účet, s ktorým chcete zrušiť prepojenie", + "unlinkAccountsText": "Zrušiť prepojenie účtov", + "v2LinkInstructionsText": "Pomocou tohto odkazu si vytvorte účet alebo sa prihláste.", + "viaAccount": "(cez účet ${NAME})", + "youAreLoggedInAsText": "Si prihlásený ako:", + "youAreSignedInAsText": "Si prihlásený ako:" + }, + "achievementChallengesText": "Achievementy", + "achievementText": "Achievement", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Zabi 3 nepriateľov pomocou TNT", + "descriptionComplete": "Zabití 3 nepriatelia pomocou TNT", + "descriptionFull": "Zabi 3 nepriateľov pomocou TNT v ${LEVEL}", + "descriptionFullComplete": "Zabití 3 nepriatelia pomocou TNT v ${LEVEL}", + "name": "Bombastická trojka" + }, + "Boxer": { + "description": "Vyhraj bez použitia bômb", + "descriptionComplete": "Výhra bez použitia bômb", + "descriptionFull": "Vyhraj ${LEVEL} bez použitia bômb", + "descriptionFullComplete": "Výhra v ${LEVEL} bez použitia bômb", + "name": "Boxér" + }, + "Dual Wielding": { + "descriptionFull": "Pripoj 2 ovládače (hardware alebo aplikácia)", + "descriptionFullComplete": "Pripojené 2 ovládače (hardware alebo aplikácia)", + "name": "Dvojité Ovládanie" + }, + "Flawless Victory": { + "description": "Vyhraj bez zranenia", + "descriptionComplete": "Výhra bez zranenia", + "descriptionFull": "Vyhraj ${LEVEL} bez zranenia", + "descriptionFullComplete": "Výhra v ${LEVEL} bez zranenia", + "name": "Bez Škrabanca" + }, + "Free Loader": { + "descriptionFull": "Začni hru Všetci-proti-Všetkým s 2+ hráčmi", + "descriptionFullComplete": "Začatá hra Všetci-proti-Všetkým s 2+ hráčmi", + "name": "Boj Začal" + }, + "Gold Miner": { + "description": "Zabi 6 nepriateľov pomocou mín", + "descriptionComplete": "Zabití 6 nepriatelia pomocou mín", + "descriptionFull": "Zabi 6 nepriateľov pomocou mín v ${LEVEL}", + "descriptionFullComplete": "Zabití 6 nepriatelia pomocou mín v ${LEVEL}", + "name": "Zlatokop" + }, + "Got the Moves": { + "description": "Vyhraj bez použitia úderov a bômb", + "descriptionComplete": "Výhra bez použitia úderov a bômb", + "descriptionFull": "Vyhraj ${LEVEL} bez použitia úderov a bômb", + "descriptionFullComplete": "Výhra v ${LEVEL} bez použitia úderov a bômb", + "name": "Tancuj, tancuj, vykrúcaj!" + }, + "In Control": { + "descriptionFull": "Pripoj ovládač (hardware alebo aplikácia)", + "descriptionFullComplete": "Pripojený ovládač (hardware alebo aplikácia)", + "name": "Všetko pod Kontrolou" + }, + "Last Stand God": { + "description": "Nahraj 1000 bodov", + "descriptionComplete": "Nahraných 1000 bodov", + "descriptionFull": "Nahraj 1000 bodov v ${LEVEL}", + "descriptionFullComplete": "Nahraných 1000 bodov v ${LEVEL}", + "name": "${LEVEL} Boh" + }, + "Last Stand Master": { + "description": "Nahraj 250 bodov", + "descriptionComplete": "Nahraných 250 bodov", + "descriptionFull": "Nahraj 250 bodov v ${LEVEL}", + "descriptionFullComplete": "Nahraných 250 bodov v ${LEVEL}", + "name": "${LEVEL} Majster" + }, + "Last Stand Wizard": { + "description": "Nahraj 500 bodov", + "descriptionComplete": "Nahraných 500 bodov", + "descriptionFull": "Nahraj 500 bodov v ${LEVEL}", + "descriptionFullComplete": "Nahraných 500 bodov v ${LEVEL}", + "name": "${LEVEL} Čarodej" + }, + "Mine Games": { + "description": "Zabi 3 nepriateľov pomocou mín", + "descriptionComplete": "Zabití 3 nepriatelia pomocou mín", + "descriptionFull": "Zabi 3 nepriateľov pomocou mín v ${LEVEL}", + "descriptionFullComplete": "Zabití 3 nepriatelia pomocou mín v ${LEVEL}", + "name": "Mínové Hry" + }, + "Off You Go Then": { + "description": "Zhoď 3 nepriateľov z mapy", + "descriptionComplete": "Zhodení 3 nepriatelia z mapy", + "descriptionFull": "Zhoď 3 nepriateľov z mapy v ${LEVEL}", + "descriptionFullComplete": "Zhodení 3 nepriatelia z mapy v ${LEVEL}", + "name": "Leť!" + }, + "Onslaught God": { + "description": "Nahraj 5000 bodov", + "descriptionComplete": "Nahraných 5000 bodov", + "descriptionFull": "Nahraj 5000 bodov v ${LEVEL}", + "descriptionFullComplete": "Nahraných 5000 bodov v ${LEVEL}", + "name": "${LEVEL} Boh" + }, + "Onslaught Master": { + "description": "Nahraj 500 bodov", + "descriptionComplete": "Nahraných 500 bodov", + "descriptionFull": "Nahraj 500 bodov v ${LEVEL}", + "descriptionFullComplete": "Nahraných 500 bodov v ${LEVEL}", + "name": "${LEVEL} Majster" + }, + "Onslaught Training Victory": { + "description": "Poraz všetky vlny", + "descriptionComplete": "Porazené všetky vlny", + "descriptionFull": "Poraz všetky vlny v ${LEVEL}", + "descriptionFullComplete": "Porazené všetky vlny v ${LEVEL}", + "name": "${LEVEL} Víťazstvo" + }, + "Onslaught Wizard": { + "description": "Nahraj 1000 bodov", + "descriptionComplete": "Nahraných 1000 bodov", + "descriptionFull": "Nahraj 1000 bodov v ${LEVEL}", + "descriptionFullComplete": "Nahraných 1000 bodov v ${LEVEL}", + "name": "${LEVEL} Čarodej" + }, + "Precision Bombing": { + "description": "Vyhraj bez schopností", + "descriptionComplete": "Výhra bez schopností", + "descriptionFull": "Vyhraj ${LEVEL} bez schopností", + "descriptionFullComplete": "Výhra v ${LEVEL} bez schopností", + "name": "Rozhodnutie Bombardovať" + }, + "Pro Boxer": { + "description": "Vyhraj bez použitia bômb", + "descriptionComplete": "Výhra bez použitia bômb", + "descriptionFull": "Vyhraj ${LEVEL} bez použitia bômb", + "descriptionFullComplete": "Výhra v ${LEVEL} bez použitia bômb", + "name": "Pro Boxér" + }, + "Pro Football Shutout": { + "description": "Vyhraj bez toho aby protivník skóroval", + "descriptionComplete": "Výhra bez toho aby protivník skóroval", + "descriptionFull": "Vyhraj bez toho aby protivník skóroval v ${LEVEL}", + "descriptionFullComplete": "Výhra bez toho aby protivník skóroval v ${LEVEL}", + "name": "${LEVEL} Vypínak" + }, + "Pro Football Victory": { + "description": "Vyhraj zápas", + "descriptionComplete": "Vyhratý zápas", + "descriptionFull": "Vyhraj zápas v ${LEVEL}", + "descriptionFullComplete": "Vyhratý zápas v ${LEVEL}", + "name": "${LEVEL} Víťazstvo" + }, + "Pro Onslaught Victory": { + "description": "Poraz všetky vlny", + "descriptionComplete": "Porazené všetky vlny", + "descriptionFull": "Poraz všetky vlny v ${LEVEL}", + "descriptionFullComplete": "Porazené všetky vlny v ${LEVEL}", + "name": "${LEVEL} Víťazstvo" + }, + "Pro Runaround Victory": { + "description": "Dokonči všetky vlny", + "descriptionComplete": "Dokončené všetky vlny", + "descriptionFull": "Dokonči všetky vlny v ${LEVEL}", + "descriptionFullComplete": "Dokončené všetky vlny v ${LEVEL}", + "name": "${LEVEL} Víťazstvo" + }, + "Rookie Football Shutout": { + "description": "Vyhraj bez toho aby protivníci skórovali", + "descriptionComplete": "Výhra bez toho aby protivníci skórovali", + "descriptionFull": "Vyhraj ${LEVEL} bez toho aby protivníci skórovali", + "descriptionFullComplete": "Výhra v ${LEVEL} bez toho aby protivníci skórovali", + "name": "${LEVEL} Vypínak" + }, + "Rookie Football Victory": { + "description": "Vyhraj hru", + "descriptionComplete": "Vyhraná hra", + "descriptionFull": "Vyhraj hru v ${LEVEL}", + "descriptionFullComplete": "Vyhraná hra v ${LEVEL}", + "name": "${LEVEL} Víťazstvo" + }, + "Rookie Onslaught Victory": { + "description": "Poraz všetky vlny", + "descriptionComplete": "Porazené všetky vlny", + "descriptionFull": "Poraz všetky vlny v ${LEVEL}", + "descriptionFullComplete": "Porazené všetky vlny v ${LEVEL}", + "name": "${LEVEL} Víťazstvo" + }, + "Runaround God": { + "description": "Nahraj 2000 bodov", + "descriptionComplete": "Nahraných 2000 bodov", + "descriptionFull": "Nahraj 2000 bodov v ${LEVEL}", + "descriptionFullComplete": "Nahraných 2000 bodov v ${LEVEL}", + "name": "${LEVEL} Boh" + }, + "Runaround Master": { + "description": "Nahraj 500 bodov", + "descriptionComplete": "Nahraných 500 bodov", + "descriptionFull": "Nahraj 500 bodov v ${LEVEL}", + "descriptionFullComplete": "Nahraných 500 bodov v ${LEVEL}", + "name": "${LEVEL} Majster" + }, + "Runaround Wizard": { + "description": "Nahraj 1000 bodov", + "descriptionComplete": "Nahraných 1000 bodov", + "descriptionFull": "Nahraj 1000 bodov na ${LEVEL}", + "descriptionFullComplete": "Nahraných 1000 bodov na ${LEVEL}", + "name": "${LEVEL} Čarodejník" + }, + "Sharing is Caring": { + "descriptionFull": "Zdieľaj hru s priateľom", + "descriptionFullComplete": "Zdieľaná hra s priateľom", + "name": "Hráč Plus" + }, + "Stayin' Alive": { + "description": "Vyhraj bez úmrtia", + "descriptionComplete": "Výhra bez úmrtia", + "descriptionFull": "Vyhraj ${LEVEL} bez úmrtia", + "descriptionFullComplete": "Výhra v ${LEVEL} bez úmrtia", + "name": "Stále Nažive" + }, + "Super Mega Punch": { + "description": "Spôsob 100% damageu jedným úderom", + "descriptionComplete": "Spôsobených 100% damageu jedným úderom", + "descriptionFull": "Spôsob 100% damageu jedným úderom v ${LEVEL}", + "descriptionFullComplete": "Spôsobených 100% damageu jedným úderom v ${LEVEL}", + "name": "Super Mega Úder" + }, + "Super Punch": { + "description": "Spôsob 50% damageu jedným úderom", + "descriptionComplete": "Spôsobených 50% damageu jedným úderom", + "descriptionFull": "Spôsob 50% damageu jedným úderom v ${LEVEL}", + "descriptionFullComplete": "Spôsobených 50% damageu jedným úderom v ${LEVEL}", + "name": "Super Úder" + }, + "TNT Terror": { + "description": "Zabi 6 protivníkov s TNT", + "descriptionComplete": "Zabitie 6 protivníkov s TNT", + "descriptionFull": "Zabi 6 protivníkov s TNT v ${LEVEL}", + "descriptionFullComplete": "Zabitie 6 protivníkov s TNT v ${LEVEL}", + "name": "Terorista s TNT" + }, + "Team Player": { + "descriptionFull": "Začnite hru na tímy s 4+ hráčmi", + "descriptionFullComplete": "Začatá hra na tímy s 4+ hráčmi", + "name": "Tímový Hráč" + }, + "The Great Wall": { + "description": "Zastav všetkých protivníkov", + "descriptionComplete": "Zastavenie všetkých protivníkov", + "descriptionFull": "Zastav všetkých protivníkov v ${LEVEL}", + "descriptionFullComplete": "Zastavenie všetkých protivníkov v ${LEVEL}", + "name": "Veľká Stena" + }, + "The Wall": { + "description": "Zastav všetkých protivníkov", + "descriptionComplete": "Zastavenie všetkých protivníkov", + "descriptionFull": "Zastav všetkých protivníkov v ${LEVEL}", + "descriptionFullComplete": "Zastavenie všetkých protivníkov v ${LEVEL}", + "name": "Stena" + }, + "Uber Football Shutout": { + "description": "Vyhraj bez toho aby protivníci skórovali", + "descriptionComplete": "Výhra bez toho aby protivníci skórovali", + "descriptionFull": "Vyhraj v ${LEVEL} bez toho aby protivníci skórovali", + "descriptionFullComplete": "Výhra v ${LEVEL} bez toho aby protivníci skórovali", + "name": "${LEVEL} Vypínak" + }, + "Uber Football Victory": { + "description": "Vyhraj hru", + "descriptionComplete": "Vyhraná hra", + "descriptionFull": "Vyhraj hru v ${LEVEL}", + "descriptionFullComplete": "Vyhraný hra v ${LEVEL}", + "name": "${LEVEL} Víťazstvo" + }, + "Uber Onslaught Victory": { + "description": "Poraz všetky vlny", + "descriptionComplete": "Porazenie všetkých vĺn", + "descriptionFull": "Poraz všetky vlny v ${LEVEL}", + "descriptionFullComplete": "Porazenie všetkých vĺn v ${LEVEL}", + "name": "${LEVEL} Víťazstvo" + }, + "Uber Runaround Victory": { + "description": "Dokonči všetky vlny", + "descriptionComplete": "Dokončené všetky vlny", + "descriptionFull": "Dokonči všetky vlny v ${LEVEL}", + "descriptionFullComplete": "Dokončené všetky vlny v ${LEVEL}", + "name": "${LEVEL} Víťazstvo" + } + }, + "achievementsRemainingText": "Zostávajúce Achievementy", + "achievementsText": "Achievementy", + "achievementsUnavailableForOldSeasonsText": "Prepáč, podrobnosti achievementov nie sú dostupné pre minulé sezóny.", + "activatedText": "${THING} aktivovaný.", + "addGameWindow": { + "getMoreGamesText": "Viac Hier...", + "titleText": "Pridať Hru" + }, + "allowText": "Povol", + "alreadySignedInText": "Tvoj účet je prihlásený z iného zariadenia;\nprosím prepni si účty alebo ukonči hru na\ntvojich ostatných zariadeniach a skús to znovu.", + "apiVersionErrorText": "Nemožno načítať modul ${NAME}; používa api-verziu ${VERSION_USED}; my potrebujeme ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Automatika\" toto povolí len keď sú slúchadlá zapojené)", + "headRelativeVRAudioText": "Head-Relative VR Audio", + "musicVolumeText": "Hlasitosť Hudby", + "soundVolumeText": "Hlasitosť Zvukov", + "soundtrackButtonText": "Soundtracky", + "soundtrackDescriptionText": "(nastav si vlastnú hudbu ktorá sa bude hrať počas hry)", + "titleText": "Audio" + }, + "autoText": "Auto", + "backText": "Späť", + "banThisPlayerText": "Zakážte prehrávač", + "bestOfFinalText": "Najlepší-z-${COUNT} Finále", + "bestOfSeriesText": "Najlepší z ${COUNT} sérií:", + "bestRankText": "Tvoj rekord je #${RANK}", + "bestRatingText": "Tvoje najlepšie hodnotenie je #${RATING}", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Pridať", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} je nastavené v aplikácii", + "buttonText": "tlačidlo", + "canWeDebugText": "Chcel by si, aby Bombsquad automaticky nahlasovalo\nbugy, crashe, a základné informácie o použití vývojárovi?\n\nToto data neobsahuje žiadne osobné informácie a pomáha\nnechávať hru bežať hladko a bez bugov.", + "cancelText": "Zrušiť", + "cantConfigureDeviceText": "Prepáč, ${DEVICE} nie je konfigurovateľný", + "challengeEndedText": "Táto challenge skončila.", + "chatMuteText": "Zablokovať Čet", + "chatMutedText": "Čet Zablokovaný", + "chatUnMuteText": "Odblokovať Čet", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Musíš dokončiť\ntento level pre postup!", + "completionBonusText": "Bonus za Dokončenie", + "configControllersWindow": { + "configureControllersText": "Prispôsobiť Ovládače", + "configureKeyboard2Text": "Prispôsobiť Klávesnicu P2", + "configureKeyboardText": "Prispôsobiť Klávesnicu", + "configureMobileText": "Mobil ako Ovládač", + "configureTouchText": "Prispôsobiť Obrazovku", + "ps3Text": "PS3 Ovládače", + "titleText": "Ovládače", + "wiimotesText": "Wiimotes", + "xbox360Text": "Xbox 360 Ovládače" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Poznámka: podpora ovládaču sa líši v závislosti od zariadenia a verzie Androidu.", + "pressAnyButtonText": "Stlač tlačidlo na ovládači,\nktoré chceš prispôsobiť...", + "titleText": "Prispôsobiť Ovládače" + }, + "configGamepadWindow": { + "advancedText": "Prokročilé", + "advancedTitleText": "Pokročilé Nastavenie Ovládača.", + "analogStickDeadZoneDescriptionText": "(zapni, pokiaľ tvoja postava \"driftuje\" keď pustíš joystick)", + "analogStickDeadZoneText": "Joystick Dead Zóna", + "appliesToAllText": "(aplikuje sa na všetky ovládače tohoto typu)", + "autoRecalibrateDescriptionText": "(zapni pokiaľ sa tvoja postava nehýbe v plnej rýchlosti)", + "autoRecalibrateText": "Auto-Recalibrovanie Joysticku", + "axisText": "os", + "clearText": "zmaž", + "dpadText": "dpad", + "extraStartButtonText": "Extra Štartovacie Tlačidlo", + "ifNothingHappensTryAnalogText": "Ak sa nič nestane, skúste priradiť analógový kľúč.", + "ifNothingHappensTryDpadText": "Ak sa nič nestane, skús prideľiť k d-padu)", + "ignoreCompletelyDescriptionText": "(zamedz tento ovládač od ovplyvňovania hry alebo menu)", + "ignoreCompletelyText": "Kompletne Ignoruj", + "ignoredButton1Text": "Ignorované Tlačidlo 1", + "ignoredButton2Text": "Ignorované Tlačidlo 2", + "ignoredButton3Text": "Ignorované Tlačidlo 3", + "ignoredButton4Text": "Ignorované Tlačidlo 4", + "ignoredButtonDescriptionText": "(toto použi pre zabránenie \"home\" alebo \"sync\" tlačidiel od ovplyvnenia UI)", + "pressAnyAnalogTriggerText": "Stlač joystick...", + "pressAnyButtonOrDpadText": "Stlač tlačidlo alebo dpad...", + "pressAnyButtonText": "Stlač akékolvek tlačidlo.", + "pressLeftRightText": "Stlač vpravo alebo vlavo...", + "pressUpDownText": "Stlač hore alebo dole...", + "runButton1Text": "Beh Tlačidlo 1", + "runButton2Text": "Beh Tlačidlo 2", + "runTrigger1Text": "Beh Spúšťač 1", + "runTrigger2Text": "Beh Spúšťač 2", + "runTriggerDescriptionText": "(spúšťače ti dovoľujú behať v rôznych rýchlostiach)", + "secondHalfText": "Použi pre nastavenie druhej polovice\n2-v-1 zariadenia, ktoré sa javí \nako jedno zariadenie.", + "secondaryEnableText": "Povoliť", + "secondaryText": "Druhý Ovládač", + "startButtonActivatesDefaultDescriptionText": "(toto vypni ak je tvoje štartovacie tlačidlo skôr tlačidlo menu", + "startButtonActivatesDefaultText": "Štartovacie Tlačidlo Aktivuje Predvolený Prístroj", + "titleText": "Nastavenie Ovládača", + "twoInOneSetupText": "Nastavenia Ovládača 2-v-1", + "uiOnlyDescriptionText": "(zabrániť tomuto ovládaču pripojiť sa do hry)", + "uiOnlyText": "Limitovať Použitie Menu", + "unassignedButtonsRunText": "Všetky Nenastavené Tlačidla sú Beh", + "unsetText": "", + "vrReorientButtonText": "VR Reorientovacie Tlačidlo" + }, + "configKeyboardWindow": { + "configuringText": "Konfigurujem ${DEVICE}", + "keyboard2NoteText": "Poznámka: veľa klávesníc môžu registrovať iba nekoľko \nstlačení naraz, takže mať klávesnicu pre druhého hráča\nby malo fungovať lepšie pokiaľ je osobitná klávesnica\npre nich zapojená. Pamätaj že stále budeš musieť nastaviť\nklávesy pre dvoch hráčov." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Veľkosť Akčných Tlačidiel", + "actionsText": "Akcie", + "buttonsText": "tlačidlá", + "dragControlsText": "< ťahaj ovládače pre ich rozmiestnenie >", + "joystickText": "joystick", + "movementControlScaleText": "Veľkosť Panelu pre Pohyb", + "movementText": "Pohyb", + "resetText": "Reset", + "swipeControlsHiddenText": "Skryť Ťahacie ikony", + "swipeInfoText": "Na \"posúvací\" štýl ovládania si musíte trochu zvyknúť ale\nľahšie sa s nimi hrá lebo sa na ne nemusíte pozerať.", + "swipeText": "posúvanie", + "titleText": "Konfigurovať Obrazovku" + }, + "configureItNowText": "Konfigurovať teraz?", + "configureText": "Konfigurovať", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Pre najlepšie výsledky budeš potrebovať bez-lagovú wifi. Môžeš\nzmenšiť wifi lagovanie tým že vypneš iné bezdrôtové zariadenia,\nhraním blízko wifi routera a pripojením sa na game host rovno\nna network cez ethernet.", + "explanationText": "Ak chceš používať smart-phone alebo tablet ako bezdrôtový \novládač, nainštaluj na ňom \"${REMOTE_APP_NAME}\" aplikáciu. \nHocijaký počet sa môže pripojiť do ${APP_NAME} hry cez Wi-Fi, zadarmo!", + "forAndroidText": "pre Android:", + "forIOSText": "pre iOS:", + "getItForText": "Zožeň ${REMOTE_APP_NAME} pre iOS na Apple App Store\nalebo pre Android na Google Play Store alebo Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Používanie Mobilov ako Ovládače:" + }, + "continuePurchaseText": "Pokračovať za ${PRICE}?", + "continueText": "Pokračovať", + "controlsText": "Ovládanie", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Toto sa neaplikuje do all-time rebríčku.", + "activenessInfoText": "Tento multiplier rastie na dňoch keď\nhráš a znižuje sa keď nehráš.", + "activityText": "Aktivita", + "campaignText": "Campaign", + "challengesInfoText": "Získavaj ceny za dokončovanie minihier.\n\nCeny a levely obtiažnosti rastú vždy\nkeď je challenge dokončená a znižuje\nkeď jedna vyprší alebo prepadne.", + "challengesText": "Challenge", + "currentBestText": "Rekord", + "customText": "Vlastné", + "entryFeeText": "Vstupné", + "forfeitConfirmText": "Vzdať sa tejto challenge?", + "forfeitNotAllowedYetText": "Tu sa ešte nemôžte vzdať.", + "forfeitText": "Vzdať sa", + "multipliersText": "Multiplikátory", + "nextChallengeText": "Ďalšia challenge", + "nextPlayText": "Ďalšia Hra", + "ofTotalTimeText": "z ${TOTAL}", + "playNowText": "Hrať", + "pointsText": "Body", + "powerRankingFinishedSeasonUnrankedText": "(neumiestnili ste sa v tejto sezóne)", + "powerRankingNotInTopText": "(nie ste v top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} bodov", + "powerRankingPointsMultText": "(x ${NUMBER} bodov)", + "powerRankingPointsText": "${NUMBER} bodov", + "powerRankingPointsToRankedText": "(${CURRENT} z ${REMAINING} bodov)", + "powerRankingText": "Umiestnenie", + "prizesText": "Ceny", + "proMultInfoText": "Hráči s ${PRO} vylepšením\ndostávajú ${PERCENT}% bodový boost.", + "seeMoreText": "Viac...", + "skipWaitText": "Preskočiť Čakanie", + "timeRemainingText": "Zostávajúci Čas", + "toRankedText": "Do Umiestnenia", + "totalText": "spolu", + "tournamentInfoText": "Súťažte o rekordy s ostatnými\nhráčmi v tvojej lige.\n\nCeny dostanú najlepší hráči keď\nturnaj skončí.", + "welcome1Text": "Vitaj v ${LEAGUE}. Môžeš zlepšovať svoj\nrank získavaním hviezd, plnením achievementov,\na vyhrávaním trofejí v turnajoch.", + "welcome2Text": "Taktiež môžeš získavať tikety z veľa aktivít. Tikety sa \nmôžu používať na odomknutie nových charakterov, máp, \nminihier, ako vstupné do turnajov, a viac.", + "yourPowerRankingText": "Tvoje Umiestnenie:" + }, + "copyConfirmText": "Skopírované do schránky.", + "copyOfText": "${NAME} Kópia", + "copyText": "Kopírovať", + "createEditPlayerText": "", + "createText": "Vytvoriť", + "creditsWindow": { + "additionalAudioArtIdeasText": "Dodatočné Audio, Predčasné Maľby a Nápady sú od ${NAME}", + "additionalMusicFromText": "Dodatočná hudba od ${NAME}", + "allMyFamilyText": "Všetci kamaráti a rodina ktorá pomohla hrať test", + "codingGraphicsAudioText": "Kódovanie, Grafika a Audio sú od ${NAME}", + "languageTranslationsText": "Preklad:", + "legalText": "Legál:", + "publicDomainMusicViaText": "Public-domain hudba cez ${NAME}", + "softwareBasedOnText": "Tento softvér je založený z časti na práci ${NAME}", + "songCreditText": "${TITLE} Performed by ${PERFORMER}\nComposed by ${COMPOSER}, Arranged by ${ARRANGER}, Published by ${PUBLISHER},\nCourtesy of ${SOURCE}", + "soundAndMusicText": "Zvuk & Hudba:", + "soundsText": "Zvuky (${SOURCE}):", + "specialThanksText": "Špeciálna Vďaka:", + "thanksEspeciallyToText": "Vďaka hlavne ${NAME}", + "titleText": "${APP_NAME} Credits", + "whoeverInventedCoffeeText": "Kto vymyslel kávu" + }, + "currentStandingText": "Tvoje postavenie je #${RANK}", + "customizeText": "Upraviť...", + "deathsTallyText": "${COUNT} úmrtí", + "deathsText": "Úmrtia", + "debugText": "debug", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Poznámka: je odporúčané aby si nastavil Nastavenia->Grafika->Textúry na \"Vysoké\" pri tomto testovaní.", + "runCPUBenchmarkText": "Spustiť CPU Benchmark", + "runGPUBenchmarkText": "Spustiť GPU Benchmark", + "runMediaReloadBenchmarkText": "Spustiť Media-Reload Benchmark", + "runStressTestText": "Spustiť stres test", + "stressTestPlayerCountText": "Počet Hráčov", + "stressTestPlaylistDescriptionText": "Stres Test Playlist", + "stressTestPlaylistNameText": "Meno Playlistu", + "stressTestPlaylistTypeText": "Typ Playlistu", + "stressTestRoundDurationText": "Dĺžka Kola", + "stressTestTitleText": "Stres Test", + "titleText": "Benchmarky & Atres Tasty", + "totalReloadTimeText": "Reload Time Spolu: ${TIME} (pozri zápis pre detaily)" + }, + "defaultGameListNameText": "Predvolený ${PLAYMODE} Playlist", + "defaultNewGameListNameText": "Môj ${PLAYMODE} Playlist", + "deleteText": "Vymazať", + "demoText": "Demo", + "denyText": "odmietnuť", + "desktopResText": "Desktop Res", + "difficultyEasyText": "Jednoduchá", + "difficultyHardOnlyText": "Len Ťažký Mód", + "difficultyHardText": "Ťažké", + "difficultyHardUnlockOnlyText": "Tento level môže byť odomknutý len v ťažkom móde.\nMyslíš že máš čo ti na to treba!?!?!", + "directBrowserToURLText": "Prosím zadajte do prehliadača následujúcu URL:", + "disableRemoteAppConnectionsText": "Zakázať Remote-App Pripojenia", + "disableXInputDescriptionText": "Povolí viac ako 4 ovládače ale nemusí fungovať dobre.", + "disableXInputText": "Zakázať XInput", + "doneText": "Hotovo", + "drawText": "Remíza", + "duplicateText": "Duplikovať", + "editGameListWindow": { + "addGameText": "Pridať\nHru", + "cantOverwriteDefaultText": "Nemožno prepísať štandartný playlist!", + "cantSaveAlreadyExistsText": "Playlist s takým menom už existuje!", + "cantSaveEmptyListText": "Nemožno uložiť prázdny playlist!", + "editGameText": "Upraviť\nHru", + "listNameText": "Meno Playlistu", + "nameText": "Meno", + "removeGameText": "Odstrániť\nHru", + "saveText": "Uložiť List", + "titleText": "Playlist Editor" + }, + "editProfileWindow": { + "accountProfileInfoText": "Tento špeciálny profil má meno\na ikonu založenú na tvojom účte.\n\n${ICONS}\n\nVytvor si vlastný profil aby si\nmohol použiť iné mená a vlastné icony", + "accountProfileText": "(profil účtu)", + "availableText": "Meno \"${NAME}\" je dostupné.", + "characterText": "charakter", + "checkingAvailabilityText": "Kontrolujem dostupnosť pre \"${NAME}\"...", + "colorText": "farba", + "getMoreCharactersText": "Získať Viac Charakterov...", + "getMoreIconsText": "Získať Viac Ikon...", + "globalProfileInfoText": "Globálne profily majú jedinečné celosvetové názvy.\nVlastnia tiež vlastné ikony.", + "globalProfileText": "(globálny profil)", + "highlightText": "zvýraznenie", + "iconText": "ikona", + "localProfileInfoText": "Lokálne profily nemajú ikonu a ich mená nemajú garanciu\njedinečného mena. Upgradni profil na globálny aby ste\nsi vyhradili jedinečné meno a vlastnú ikonu.", + "localProfileText": "(lokálny profil)", + "nameDescriptionText": "Meno Hráča", + "nameText": "Meno", + "randomText": "náhodne", + "titleEditText": "Upraviť Profil", + "titleNewText": "Nový Profil", + "unavailableText": "\"${NAME}\" nie je dostupné; skús iné meno.", + "upgradeProfileInfoText": "Toto vyhradí tvoje meno hráča celosvetovo a \ndovolí ti priradiť k nemu vlastnú ikonu.", + "upgradeToGlobalProfileText": "Upgradenuť na Globálny Profil" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Nemôžeš vymazať štandartný soundtrack.", + "cantEditDefaultText": "Nemožno upraviť štandartný soundtrack. Duplikuj ho alebo vytvor nový.", + "cantOverwriteDefaultText": "Nemožno prepísať štandartný soundtrack.", + "cantSaveAlreadyExistsText": "Soundtrack s takým menom už existuje!", + "defaultGameMusicText": "<štandartná hudba hry>", + "defaultSoundtrackNameText": "Štandartný Soundtrack", + "deleteConfirmText": "Vymazať Soundtrack:\n\n\"${NAME}\"?", + "deleteText": "Vymazať\nSoundtrack", + "duplicateText": "Duplikovať\nSoundtrack", + "editSoundtrackText": "Soundtrack Editor", + "editText": "Upraviť\nSoundtrack", + "fetchingITunesText": "načítavam Music App playlisty...", + "musicVolumeZeroWarning": "Varovanie: hlasitosť hudby je nastavená na 0", + "nameText": "Meno", + "newSoundtrackNameText": "Môj Soundtrack ${COUNT}", + "newSoundtrackText": "Nový Soundtrack:", + "newText": "Nový\nSoundtrack", + "selectAPlaylistText": "Vybrať Playlist", + "selectASourceText": "Zdroj Hudby", + "testText": "test", + "titleText": "Soundtracky", + "useDefaultGameMusicText": "Štandartná Hudba Hry", + "useITunesPlaylistText": "Music App Playlist", + "useMusicFileText": "Súbor Hudby (mp3, atď)", + "useMusicFolderText": "Zložka Súborov Hudby" + }, + "editText": "Upraviť", + "endText": "Ukončiť", + "enjoyText": "Užite si to!", + "epicDescriptionFilterText": "${DESCRIPTION} Spomalene.", + "epicNameFilterText": "Epic ${NAME}", + "errorAccessDeniedText": "prístup odmietnutý", + "errorDeviceTimeIncorrectText": "Čas vášho zariadenia je nesprávny o ${HOURS} hodín.\nToto môže spôsobiť problémy.\nProsím skontrolujte vaše nastavenia času a časových zón.", + "errorOutOfDiskSpaceText": "žiadne miesto na disku", + "errorSecureConnectionFailText": "Nebolo možné vyrvoriť bezpečné cloudové pripojenie; funkčnosť siete môže zlyhať.", + "errorText": "Chyba", + "errorUnknownText": "neznámy error", + "exitGameText": "Ukončiť ${APP_NAME}?", + "exportSuccessText": "\"${NAME}\" exportovaný.", + "externalStorageText": "Externé Úložisko", + "failText": "Zlyhanie", + "fatalErrorText": "Ups; niečo chýba alebo je niečo rozbité.\nProsím skús reinštalovať aplikáciu\nalebo kontaktuj ${EMAIL} pre pomoc.", + "fileSelectorWindow": { + "titleFileFolderText": "Vyber Súbor alebo Zložku", + "titleFileText": "Vybrať Súbor", + "titleFolderText": "Vybrať Zložku", + "useThisFolderButtonText": "Použiť Túto Zložku" + }, + "filterText": "Filter", + "finalScoreText": "Finálne Skóre", + "finalScoresText": "Finálne Skóre", + "finalTimeText": "Finálny Čas", + "finishingInstallText": "Dokončujem inštaláciu; moment...", + "fireTVRemoteWarningText": "* pre lepšiu skúsenosť, použi\nHerné Ovládače alebo nainštaluj\n\"${REMOTE_APP_NAME}\" aplikáciu\nna mobily alebo tablety.", + "firstToFinalText": "Prvý-u-${COUNT} Finále", + "firstToSeriesText": "Prvý-u-${COUNT} Séria", + "fiveKillText": "PENTAKILL!!!", + "flawlessWaveText": "Bezchybná vlna!", + "fourKillText": "QUADKILL!!", + "friendScoresUnavailableText": "Skóre kamarátov nedostupné.", + "gameCenterText": "Herné centrum", + "gameCircleText": "GameCircle", + "gameLeadersText": "Leadery Hry ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "Nemôžeš vymazať štandartný playlist.", + "cantEditDefaultText": "Nemôžeš upraviť štandartný playlist! Duplikuj ho alebo si vytvor nový.", + "cantShareDefaultText": "Nemôžeš zdieľať štandartný playlist", + "deleteConfirmText": "Vymazať \"${LIST}\"?", + "deleteText": "Vymazať\nPlaylist", + "duplicateText": "Duplikovať\nPlaylist", + "editText": "Upraviť\nPlaylist", + "newText": "Nový\nPlaylist", + "showTutorialText": "Ukázať Tutoriál", + "shuffleGameOrderText": "Náhodné Poradie Hier", + "titleText": "Upraviť ${TYPE} Playlisty" + }, + "gameSettingsWindow": { + "addGameText": "Pridať Hru" + }, + "gamesToText": "${WINCOUNT} hier ku ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Pamätaj: hocijaké zariadenie v párty môže mať\nviac hráčov pokiaľ máš dosť ovládačov.", + "aboutDescriptionText": "Použi tieto tabuľky pre vytvorenie párty.\n\nPárty ti dovoľujú hrať hry a turnaje s\ntvojimi kamarátmi cez iné zariadenia.\n\nStlač ${PARTY} tlačidlo v pravo hore pre\nchatovanie a narábanie s párty.\n(na ovládači, stlač ${BUTTON} keď si v menu)", + "aboutText": "Informácie", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} ti poslal ${COUNT} tiketov v hre ${APP_NAME}", + "appInviteSendACodeText": "Poslať Im Kód", + "appInviteTitleText": "${APP_NAME} Pozvánka", + "bluetoothAndroidSupportText": "(funguje na všetkých Android zariadeniach podporujúce Bluetooth)", + "bluetoothDescriptionText": "Hostovať/Pripojiť sa na párty cez Bluetooth", + "bluetoothHostText": "Hostovať párty cez Bluetooth", + "bluetoothJoinText": "Pripojiť sa cez Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "kontrolujem...", + "copyCodeConfirmText": "Kód bol skopírovaný do schránky.", + "copyCodeText": "Kopírovať kód", + "dedicatedServerInfoText": "Pre najlepšie výsledky, nastav si dedikovaný server. Pozri bombsquadgame.com/server a nauč sa ako.", + "disconnectClientsText": "Toto odpojí ${COUNT} hráča/hráčov v tvojej\npárty. Si si istý?", + "earnTicketsForRecommendingAmountText": "Kamaráti dostanú ${COUNT} tiketov a si hru vyskúšajú (a\nza každého kto tak urobí dostaneš ${YOU_COUNT} tiketov)", + "earnTicketsForRecommendingText": "Zdieľaj hru pre\ntikety zadarmo...", + "emailItText": "Poslať Emailom", + "favoritesSaveText": "Uložiť ako obľúbené", + "favoritesText": "Obľúbené", + "freeCloudServerAvailableMinutesText": "Ďalší bezplatný cloudový server bude k dispozícii o ${MINUTES} minút.", + "freeCloudServerAvailableNowText": "K dispozícii je bezplatný cloudový server!", + "freeCloudServerNotAvailableText": "Nie sú k dispozícii žiadne bezplatné cloudové servery.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} tiketov od ${NAME}", + "friendPromoCodeAwardText": "Dostaneš ${COUNT} tiketov každý raz keď sa použie.", + "friendPromoCodeExpireText": "Kód vyprší za ${EXPIRE_HOURS} hodín a funguje len pre nové účty.", + "friendPromoCodeInstructionsText": "Ak ho chceš použiť, otvor ${APP_NAME} a choď do \"Settings->Advanced->Enter Code\".\nPozri bombsquadgame.com pre download linky pre všetky podporované platformy.", + "friendPromoCodeRedeemLongText": "Môže byť uplatnený za ${COUNT} tiketov až pre ${MAX_USES} ľudí.", + "friendPromoCodeRedeemShortText": "Môže byť uplatnený za ${COUNT} tiketov v hre.", + "friendPromoCodeWhereToEnterText": "(v časti „Nastavenia-> Pokročilé-> Zadať kód“)", + "getFriendInviteCodeText": "Zohnať Pozvánku", + "googlePlayDescriptionText": "Pozvi Google Play hráčov do párty:", + "googlePlayInviteText": "Pozvať", + "googlePlayReInviteText": "Je tu ${COUNT} Google Play hráč(ov) v tvojej párty\nktorí budú odpojený ak pošleš novú pozvánku.\nPošli im novú aby si ich dostal späť.", + "googlePlaySeeInvitesText": "Pozrieť Pozvánky", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play verzia)", + "hostPublicPartyDescriptionText": "Hostovať Verejnú Párty:", + "hostingUnavailableText": "Hosting nie je k dispozícii", + "inDevelopmentWarningText": "Poznámka:\n\nHra cez internet je nová a stále vylepšujúca sa\nvlastnosť. Zatiaľ, je vysoko odporúčané aby\nvšetci hráči boli na tej istej Wi-Fi.", + "internetText": "Internet", + "inviteAFriendText": "Priatelia nemajú hru? Pozvi ich nech si hru\nvyskúšajú a dostanú ${COUNT} tiketov.", + "inviteFriendsText": "Pozvať Kamarátov", + "joinPublicPartyDescriptionText": "Pripojiť sa na Verejnú Párty:", + "localNetworkDescriptionText": "Pripojte sa k skupine nablízku (LAN, Bluetooth, atď.)", + "localNetworkText": "Lokálny Internet", + "makePartyPrivateText": "Urobiť Moju Párty Verejnú", + "makePartyPublicText": "Urobiť Moju Párty Verejnú", + "manualAddressText": "Adresa", + "manualConnectText": "Pripojiť", + "manualDescriptionText": "Pripojiť sa na párty cez adresu:", + "manualJoinSectionText": "Pripojiť sa podľa adresy", + "manualJoinableFromInternetText": "Si pripojiteľný z internetu?:", + "manualJoinableNoWithAsteriskText": "NIE*", + "manualJoinableYesText": "ÁNO", + "manualRouterForwardingText": "*pre opravu, skús konfigurovať tvoj router na predný UDP port ${PORT} na svoju adresu", + "manualText": "Manuálne", + "manualYourAddressFromInternetText": "Tvoja adresa z internetu:", + "manualYourLocalAddressText": "Tvoja lokálna adresa:", + "nearbyText": "Neďaleko", + "noConnectionText": "<žiadne pripojenie>", + "otherVersionsText": "(ostatné verzie)", + "partyCodeText": "Párty kód", + "partyInviteAcceptText": "Potvrdiť", + "partyInviteDeclineText": "Odmietnuť", + "partyInviteGooglePlayExtraText": "(pozri \"Google Play\" tabuľku v \"Viac Hráčov\" okne)", + "partyInviteIgnoreText": "Ignorovať", + "partyInviteText": "${NAME} ťa pozval \ndo jeho/jej párty!", + "partyNameText": "Meno Párty", + "partyServerRunningText": "Váš server párty je spustený", + "partySizeText": "veľkosť párty", + "partyStatusCheckingText": "kontrolujem status...", + "partyStatusJoinableText": "tvoja párty je teraz pripojiteľná z internetu", + "partyStatusNoConnectionText": "nemožno sa pripojiť na server", + "partyStatusNotJoinableText": "tvoja párty nie je pripojiteľná z internetu", + "partyStatusNotPublicText": "tvoja párty nie je verejná", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Súkromné ​​párty bežia na vyhradených cloudových serveroch; nevyžaduje sa žiadna konfigurácia smerovača.", + "privatePartyHostText": "Usporiadajte súkromnú párty", + "privatePartyJoinText": "Pripojte sa k súkromnej párty", + "privateText": "Súkromné", + "publicHostRouterConfigText": "Môže to vyžadovať konfiguráciu presmerovania portov na vašom smerovači. Pre ľahšiu voľbu usporiadajte súkromný večierok.", + "publicText": "Verejné", + "requestingAPromoCodeText": "Získavam kód...", + "sendDirectInvitesText": "Poslať Pozvánku", + "shareThisCodeWithFriendsText": "Zdieľaj tento kód s kamarátmi:", + "showMyAddressText": "Ukáž Moju Adresu", + "startHostingPaidText": "Hostite teraz za ${COST}", + "startHostingText": "Hostiteľ", + "startStopHostingMinutesText": "Môžete začať a prestať hosťovať zadarmo na nasledujúcich ${MINUTES} minút.", + "stopHostingText": "Zastaviť hosťovanie", + "titleText": "Viac Hráčov", + "wifiDirectDescriptionBottomText": "Ak všetky zariadenia majú \"Wi-Fi Direct\" tabuľku, mali by byť schopní ho použiť\naby sa našli a pripojili medzi sebou. Keď budú všetky zariadenia pripojené,\nmôžeš formovať párty použitím tabuľky \"Lokálny Internet\" tak ako pri normálnej Wi-Fi.\n\nPre najlepšie výsledky, Wi-Fi Direct host by mal tiež byť ${APP_NAME} párty host.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct môže byť použitý na pripojenie Android zariadení bez\npoužitia Wi-Fi. Toto môže fungovať najlepšie na Androit 4.2 alebo novšom.\n\nPre jeho použitie, otvor Wi-Fi nastavenia a hľadaj \"Wi-Fi Direct\" v menu.", + "wifiDirectOpenWiFiSettingsText": "Otvoriť Wi-Fi Nastavenia", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(funguje medzi všetkými platformami)", + "worksWithGooglePlayDevicesText": "(funguje so zariadeniami, na ktorých beží Google Play (Android) verzia hry)", + "youHaveBeenSentAPromoCodeText": "Dostali ste ${APP_NAME} promo kód:" + }, + "getTicketsWindow": { + "freeText": "ZADARMO!", + "freeTicketsText": "Tikety Zadarmo", + "inProgressText": "Prebieha transakcia; prosím skús to znova neskôr", + "purchasesRestoredText": "Nákupy obnovené.", + "receivedTicketsText": "Dostal si ${COUNT} tiketov!", + "restorePurchasesText": "Obnoviť Nákupy", + "ticketPack1Text": "Malý Balíček Tiketov", + "ticketPack2Text": "Stredný Balíček Tiketov", + "ticketPack3Text": "Veľký Balíček Tiketov", + "ticketPack4Text": "Obrovský Balíček Tiketov", + "ticketPack5Text": "Gigantický Balíček Tiketov", + "ticketPack6Text": "Ultimátny Balíček Tiketov", + "ticketsFromASponsorText": "Pozri si reklamu\npre ${COUNT} tiketov", + "ticketsText": "${COUNT} Tiketov", + "titleText": "Dostať Tikety", + "unavailableLinkAccountText": "Prepáč, nákupy sú nedostupné na tejto platforme.\nAko riešenie, môžeš stále prepojiť tento účet s účtom na \ninej platforme a nakupovať.", + "unavailableTemporarilyText": "Toto aktuálne nie je dostupné; prosím skús to znova neskôr.", + "unavailableText": "Prepáč, toto nie je dostupné.", + "versionTooOldText": "Prepáč, táto verzia hry je moc stará; prosím nainštaluj novšiu verziu.", + "youHaveShortText": "máš ${COUNT}", + "youHaveText": "máš ${COUNT} tiketov" + }, + "googleMultiplayerDiscontinuedText": "Prepáč, Google multiplayer už viac nie je dostupný.\nSnažím sa to prehodiť čo najskôr. Dovtedy prosím\nskús inú metódu pripojenia.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Nákupy Google Play nie sú dostupné.\nAsi musíte aktualizovať svoju obchodnú aplikáciu.", + "googlePlayServicesNotAvailableText": "Služby Google Play nie sú dostupné.\nNiektoré funkčnosti aplikácie môžu byť vypnuté.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Stále", + "fullScreenCmdText": "Celá Obrazovka (Cmd+F)", + "fullScreenCtrlText": "Celá Obrazovka (Ctrl+F)", + "gammaText": "Gamma", + "highText": "Vysoko", + "higherText": "Vyššie", + "lowText": "Nízko", + "mediumText": "Stredne", + "neverText": "Nikdy", + "resolutionText": "Rozlíšenie", + "showFPSText": "Ukazuj FPS", + "texturesText": "Textúry", + "titleText": "Grafika", + "tvBorderText": "TV Okraj", + "verticalSyncText": "Vertikálna Synchronizácia", + "visualsText": "Vizualizácia" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nSilnejšia ako údery, ale\nmôže spôsobiť vážne zranenie.\nPre najlepšie výsledky ju hoď\nna nepriateľa skôr ako vybúchne.", + "canHelpText": "${APP_NAME} môže pomôcť.", + "controllersInfoText": "Môžeš hrať ${APP_NAME} s kamarátmi cez internet, alebo môžete\nvšetci hrať na jednom zariadení pokiaľ máte dosť ovládačov.\n${APP_NAME} podporuje veľa z nich; môžeš pokojne použiť mobily\nako ovládače cez \"${REMOTE_APP_NAME}\" aplikáciu.\nPozri Nastavenia->Ovládače pre viac info.", + "controllersInfoTextRemoteOnly": "Bombsquad môžete hrať s priateľmi prostredníctvom siete alebo vy\nvšetky je možné hrať na rovnakom zariadení pomocou telefónov ako\novládače prostredníctvom bezplatnej aplikácie Bombsquad Vr", + "controllersText": "Ovládače", + "controlsSubtitleText": "Tvoj ${APP_NAME} charakter má pár základných zručností:", + "controlsText": "Ovládanie", + "devicesInfoText": "VR verzia hry ${APP_NAME} sa môže hrať cez internet s \nnormálnou verziou, takže bež pre ďalšie mobily, tablety \na počítače a sťahuj hru. To môže byť užitočné pre pripojenie \nnormálnej verzie hry k VR verzii len pre to aby mohli ľudia \nvon sledovať akciu.", + "devicesText": "Zariadenia", + "friendsGoodText": "Tých je dobre mať. ${APP_NAME} je hlavne zábava s trocha \nhráčmi a môžeš hrať až s 8 hráčmi naraz, čo nás privádza k:", + "friendsText": "Kamaráti", + "jumpInfoText": "- Skok -\nSkáč aby si preskočil malé\nškáry alebo aby si vyhodil\nveci vyššie a zlepšil náladu.", + "orPunchingSomethingText": "Alebo mlátiť do niečoho, zhodiť dačo z útesu, a odpáliť to na ceste dole sticky bombou.", + "pickUpInfoText": "- Zobrať -\nZober vlajky, protivníkov, alebo\nhocičo čo nie je pripevnené k zemi.\nStlač znova a odhoď to.", + "powerupBombDescriptionText": "Dovolí ti vyhodiť tri bomby\nza sebou namiesto jednej.", + "powerupBombNameText": "Trojité-Bomby", + "powerupCurseDescriptionText": "Tomuto by si sa chcel radšej vyhnúť.\n... či?", + "powerupCurseNameText": "Zošalenie", + "powerupHealthDescriptionText": "Dá ti plné životy.\nTo si neočakával.", + "powerupHealthNameText": "Lekárnička", + "powerupIceBombsDescriptionText": "Slabšie ako normálne bomby\nale nechajú protivníkov zamrznutých\na krehkých.", + "powerupIceBombsNameText": "Ľadové Bomby", + "powerupImpactBombsDescriptionText": "Trocha slabšie ako normálne\nbomby, ale vybúchnu na dotyk.", + "powerupImpactBombsNameText": "Totykové Bomby", + "powerupLandMinesDescriptionText": "Tieto chodia dostaneš 3;\nUžitočné pre ochranu územia\nalebo zastavenie rýchlych protivníkov", + "powerupLandMinesNameText": "Míny", + "powerupPunchDescriptionText": "Robia tvoje údery ťažšie,\nrýchlejšie, lepšie, silnejšie.", + "powerupPunchNameText": "Boxérske Rukavice", + "powerupShieldDescriptionText": "Absorbuje trocha bolesti\ntakže ty nemusíš.", + "powerupShieldNameText": "Obrana", + "powerupStickyBombsDescriptionText": "Zalepia sa o hocičo čo trafia.\nNasleduje veselosť.", + "powerupStickyBombsNameText": "Sticky Bomby", + "powerupsSubtitleText": "Samozrejme, žiadna hra nie je hrou bez schopností:", + "powerupsText": "Schopnosti", + "punchInfoText": "- Úder -\nÚdery bolia viac keď sa tvoje\npäste hýbu, takže sa krúť a skáč\na bež ako šialenec.", + "runInfoText": "- Beh -\nAk chceš behať, podrž HOCIJAKÉ tlačidlo. Dobre fungujú aj bočné tlačidlá pokiaľ ich máš.\nBehom sa dostaneš na miesta rýchlejšie, ale budeš ťažšie zatáčať, takže bacha na útesy.", + "someDaysText": "Niektoré dni by si chcel do dačoho mlátiť. Alebo to odpáliť.", + "titleText": "${APP_NAME} Pomoc", + "toGetTheMostText": "Ak chceš z tejto hry vyšťaviť najviac, potrebuješ:", + "welcomeText": "Vitaj v hre ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} je teraz tvoj boss -", + "importPlaylistCodeInstructionsText": "Použi tento kód aby si mohol importovať tento playlist inam:", + "importPlaylistSuccessText": "Importovaný ${TYPE} playlist \"${NAME}\"", + "importText": "Importovať", + "importingText": "Importujem...", + "inGameClippedNameText": "v hre to bude\n\"${NAME}\"", + "installDiskSpaceErrorText": "ERROR: Nemožno dokončiť inštaláciu.\nAsi budeš mať málo miesta na úložisku.\nTrocha ho vyčisti a skús to znova.", + "internal": { + "arrowsToExitListText": "stlač ${LEFT} alebo ${RIGHT} pre zatvorenie listu", + "buttonText": "tlačidlo", + "cantKickHostError": "Nemôžeš odstrániť bossa.", + "chatBlockedText": "${NAME} má blokovaný chat na ${TIME} sekúnd.", + "connectedToGameText": "Pripojil si sa na \"${NAME}\"", + "connectedToPartyText": "Pripojil si sa párty hráča ${NAME}!", + "connectingToPartyText": "Pripájam sa...", + "connectionFailedHostAlreadyInPartyText": "Nemožno sa pripojiť; hráč je v inej párty.", + "connectionFailedPartyFullText": "Nemožno sa pripojiť; párty je plná.", + "connectionFailedText": "Nemožno sa pripojiť.", + "connectionFailedVersionMismatchText": "Nemožno sa pripojiť; hráč má spustenú inú verziu hry.\nUistite sa že máte obidvaja najnovšiu verziu hry a skús to znova.", + "connectionRejectedText": "Nemožno sa pripojiť.", + "controllerConnectedText": "${CONTROLLER} je pripojený.", + "controllerDetectedText": "Detekovaný 1 ovládač", + "controllerDisconnectedText": "${CONTROLLER} je odpojený.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} je odpojený. Skúste ho pripojiť znova.", + "controllerForMenusOnlyText": "Tento ovládač sa nepoužíva na hranie; len pre navigovanie menu.", + "controllerReconnectedText": "${CONTROLLER} je znova pripojený.", + "controllersConnectedText": "${COUNT} pripojených ovládačov.", + "controllersDetectedText": "${COUNT} ovládačov detekovaných.", + "controllersDisconnectedText": "${COUNT} ovládačov odpojených.", + "corruptFileText": "Rozbitý súbor detekovaný. Prosím skús reinštalovať hru alebo napíš na ${EMAIL}.", + "errorPlayingMusicText": "Error pri prehrávaní hudby: ${MUSIC}", + "errorResettingAchievementsText": "Nemožno resetovať online achievementy; prosím skús to neskôr.", + "hasMenuControlText": "${NAME} má kontrolu nad menu.", + "incompatibleNewerVersionHostText": "Hráč má novšiu verziu hry. Nainštaluj najnovšiu\nverziu hry a skús to neskôr.", + "incompatibleVersionHostText": "Hráč má inakšiu verziu hry. Uistite sa že máte\nobidvaja najnovšiu verziu hry skús to znova.", + "incompatibleVersionPlayerText": "${NAME} má inakšiu verziu hry. Uistite sa že máte\nobidvaja najnovšiu verziu hry a skús to znova.", + "invalidAddressErrorText": "Error: neplatná/zlá adresa.", + "invalidNameErrorText": "Error: neplatné meno.", + "invalidPortErrorText": "Error: neplatný port.", + "invitationSentText": "Pozvánka poslaná.", + "invitationsSentText": "${COUNT} pozvánok poslaných.", + "joinedPartyInstructionsText": "Niekto sa pripojil do tvojej párty.\nChoď do \"Hrať\" a začni hru.", + "keyboardText": "Klávesnica", + "kickIdlePlayersKickedText": "Vyhadzujem ${NAME} kvôli nečinnosti.", + "kickIdlePlayersWarning1Text": "${NAME} bude vyhodený za ${COUNT} sekúnd ak bude stále nečinný.", + "kickIdlePlayersWarning2Text": "(toto môžeš vypnúť v Nastavenia->Pokročilé", + "leftGameText": "\"${NAME}\" odišiel.", + "leftPartyText": "Odišiel si z párty hráča ${NAME}.", + "noMusicFilesInFolderText": "Zložka neobsahuje žiadne súbory.", + "playerJoinedPartyText": "${NAME} sa pripojil do párty!", + "playerLeftPartyText": "${NAME} odišiel z párty.", + "rejectingInviteAlreadyInPartyText": "Ruším pozvánku (hráč je už v párty).", + "serverRestartingText": "Server sa reštartuje. Pripojte sa prosím o chvíľu ...", + "serverShuttingDownText": "Server sa vypína...", + "signInErrorText": "Error pri prihlasovaní.", + "signInNoConnectionText": "Nemožno sa prihlásiť. (žiadny internet?)", + "telnetAccessDeniedText": "ERROR: účet nemá telnet povolenie.", + "timeOutText": "(vyprší za ${TIME} sekúnd)", + "touchScreenJoinWarningText": "Pripojil si sa na obrazovke.\nAk to bolo nechtiac, stlač na obrazovke Menu->Opustiť Hru.", + "touchScreenText": "Obrazovka", + "unableToResolveHostText": "Error: žiadny internet/zlé host meno.", + "unavailableNoConnectionText": "Toto nie je aktuálne dostupné (žiadny internet?)", + "vrOrientationResetCardboardText": "Toto použi pre resetovanie orientácie VR.\nAk chceš hrať, potrebuješ ovládač.", + "vrOrientationResetText": "Orientácia VR resetovaná.", + "willTimeOutText": "(ak bude nečinný, vyprší čas)" + }, + "jumpBoldText": "SKOČIŤ", + "jumpText": "Skočiť", + "keepText": "Ponechať", + "keepTheseSettingsText": "Ponechať tieto nastavenia?", + "keyboardChangeInstructionsText": "Dvojitým stlačením medzerníka zmeníte klávesnicu.", + "keyboardNoOthersAvailableText": "Nie sú k dispozícii žiadne ďalšie klávesnice.", + "keyboardSwitchText": "Prepína sa klávesnica na \"${NAME}\".", + "kickOccurredText": "${NAME} bol vyhodený.", + "kickQuestionText": "Vyhodiť ${NAME}?", + "kickText": "Vyhodiť", + "kickVoteCantKickAdminsText": "Správcov nemožno vyhodiť.", + "kickVoteCantKickSelfText": "Nemôžete sa vyhodiť.", + "kickVoteFailedNotEnoughVotersText": "Nie je dostatok hráčov pre hlasovanie.", + "kickVoteFailedText": "Hlasovanie pre vyhodenie zlyhalo.", + "kickVoteStartedText": "Hlasovanie pre vyhodenie začalo pre ${NAME}.", + "kickVoteText": "Hlasovať pre Vyhodenie", + "kickVotingDisabledText": "Vyhadzovacie hlasovanie je zakázané.", + "kickWithChatText": "Napíš ${YES} pre áno a ${NO} pre nie do chatu.", + "killsTallyText": "${COUNT} zabití.", + "killsText": "Zabitia", + "kioskWindow": { + "easyText": "Ľahké", + "epicModeText": "Spomalene", + "fullMenuText": "Celé Menu", + "hardText": "Ťažké", + "mediumText": "Stredné", + "singlePlayerExamplesText": "Jeden Hráč / Proti Počítaču Príklady", + "versusExamplesText": "Versus Príklady" + }, + "languageSetText": "Aktuálny jazyk je \"${LANGUAGE}\".", + "lapNumberText": "Kolo ${CURRENT}/${TOTAL}", + "lastGamesText": "(posledných ${COUNT} hier)", + "leaderboardsText": "Rebríčky", + "league": { + "allTimeText": "Celý Čas", + "currentSeasonText": "Aktuálna Sezóna (${NUMBER})", + "leagueFullText": "${NAME} Liga", + "leagueRankText": "Miesto v Lige", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "Sezóna skončila pred ${NUMBER} dňami.", + "seasonEndsDaysText": "Sezóna skončí za ${NUMBER} dní.", + "seasonEndsHoursText": "Sezóna skončí za ${NUMBER} hodín.", + "seasonEndsMinutesText": "Sezóna skončí za ${NUMBER} minút.", + "seasonText": "Sezóna ${NUMBER}", + "tournamentLeagueText": "Musíš dosiahnuť ${NAME} ligu aby si mohol hrať tento turnaj.", + "trophyCountsResetText": "Trofeje sa resetujú ďalšiu sezónu." + }, + "levelBestScoresText": "Najlepšie skóre na ${LEVEL}", + "levelBestTimesText": "Najlepšie časy na ${LEVEL}", + "levelIsLockedText": "${LEVEL} je zamknutý.", + "levelMustBeCompletedFirstText": "Najskôr musíš dokončiť ${LEVEL}.", + "levelText": "Level ${NUMBER}", + "levelUnlockedText": "Level Odomknutý.", + "livesBonusText": "Bonus za životy.", + "loadingText": "načítavam", + "loadingTryAgainText": "Načítavam; skús to znova za chvíľu...", + "macControllerSubsystemBothText": "Obidva (neodporúčané)", + "macControllerSubsystemClassicText": "Klasické", + "macControllerSubsystemDescriptionText": "(toto skús zmeniť ak ti ovládače nefungujú)", + "macControllerSubsystemMFiNoteText": "Detekovaný ovládač pre iOS/Mac;\nAsi ich budeš chcieť povoliť v Nastavenia -> Ovládače", + "macControllerSubsystemMFiText": "Vyrobené pre iOS/Mac", + "macControllerSubsystemTitleText": "Podporovanie Ovládačov", + "mainMenu": { + "creditsText": "Credits", + "demoMenuText": "Demo Menu", + "endGameText": "Ukončiť Hru", + "endTestText": "Ukončiť Test", + "exitGameText": "Uzavrieť Hru", + "exitToMenuText": "Odísť do menu?", + "howToPlayText": "Ako Hrať", + "justPlayerText": "(Len ${NAME})", + "leaveGameText": "Opustiť Hru", + "leavePartyConfirmText": "Vážne chceš opustiť hru?", + "leavePartyText": "Opustiť Párty", + "quitText": "Ukončiť", + "resumeText": "Pokračovať", + "settingsText": "Nastavenia" + }, + "makeItSoText": "Aplikuj", + "mapSelectGetMoreMapsText": "Zohnať Viac Máp...", + "mapSelectText": "Vybrať...", + "mapSelectTitleText": "${GAME} Mapy", + "mapText": "Mapa", + "maxConnectionsText": "Maximum Pripojení", + "maxPartySizeText": "Maximálna Veľkosť Párty", + "maxPlayersText": "Maximum Hráčov", + "modeArcadeText": "Arkádový režim", + "modeClassicText": "Klasický režim", + "modeDemoText": "Demo režim", + "mostValuablePlayerText": "Najcennejší Hráč", + "mostViolatedPlayerText": "Najzomierajúcejší Hráč", + "mostViolentPlayerText": "Najvražednejší Hráč", + "moveText": "Pohyb", + "multiKillText": "${COUNT}-KILL!!!", + "multiPlayerCountText": "${COUNT} hráčov", + "mustInviteFriendsText": "Poznámka: musíš pozvať kamarátov\nv \"${GATHER}\" paneli alebo zapojiť\novládače ak chceš hrať multiplayer.", + "nameBetrayedText": "${NAME} zradil ${VICTIM}.", + "nameDiedText": "${NAME} zomrel.", + "nameKilledText": "${NAME} zabil ${VICTIM}.", + "nameNotEmptyText": "Meno nemôže byť prázdne!", + "nameScoresText": "${NAME} Skóruje!", + "nameSuicideKidFriendlyText": "${NAME} nechtiac zomrel.", + "nameSuicideText": "${NAME} spáchal samovraždu.", + "nameText": "Meno", + "nativeText": "Prírodné", + "newPersonalBestText": "Nový osobný rekord!", + "newTestBuildAvailableText": "Novšia testovacia verzia je dostupná! (${VERSION} test ${BUILD}).\nZožeň ho na ${ADDRESS}", + "newText": "Nový", + "newVersionAvailableText": "Novšia verzia hry ${APP_NAME} je dostupná! (${VERSION})", + "nextAchievementsText": "Ďalšie Achievementy:", + "nextLevelText": "Ďalší Level", + "noAchievementsRemainingText": "- žiadne", + "noContinuesText": "(žiadne pokračovania)", + "noExternalStorageErrorText": "Žiadne úložisko sa v tomto zariadení nenašlo", + "noGameCircleText": "Error: nie si prihlásený do GameCircle", + "noScoresYetText": "Zatiaľ žiadne skóre.", + "noThanksText": "Nie Vďaka", + "noTournamentsInTestBuildText": "UPOZORNENIE: Výsledky turnajov z tejto testovacej zostavy budú ignorované.", + "noValidMapsErrorText": "Žiadne platné mapy sa pre tento typ hry nenašli.", + "notEnoughPlayersRemainingText": "Nedostatok hráčov; začni novú hru.", + "notEnoughPlayersText": "Potrebuješ aspoň ${COUNT} hráčov ak chceš toto hrať!", + "notNowText": "Teraz Nie", + "notSignedInErrorText": "Ak toto chceš urobiť, musíš sa prihlásiť.", + "notSignedInGooglePlayErrorText": "Ak chceš toto urobiť, musíš sa prihlásiť do Google Play.", + "notSignedInText": "nie si prihlásený", + "nothingIsSelectedErrorText": "Nič nie je vybraté!", + "numberText": "#${NUMBER}", + "offText": "Vypnúť", + "okText": "Ok", + "onText": "Zapnúť", + "oneMomentText": "Chvíľu...", + "onslaughtRespawnText": "${PLAYER} sa znova zjaví vo vlne ${WAVE}", + "orText": "${A} alebo ${B}", + "otherText": "Ďalšie...", + "outOfText": "(#${RANK} z ${ALL})", + "ownFlagAtYourBaseWarning": "Tvoja vlajka musí byť \nnamieste ak chceš skórovať!", + "packageModsEnabledErrorText": "Online hranie nie je povolené pokiaľ sú povolené local-package-módy (pozri Nastavenia->Pokročilé)", + "partyWindow": { + "chatMessageText": "Chat Správa", + "emptyText": "Tvoja párty je prázdna", + "hostText": "(host)", + "sendText": "Poslať", + "titleText": "Tvoja Párty" + }, + "pausedByHostText": "(pozastavené hostom)", + "perfectWaveText": "Perfektná Vlna!", + "pickUpText": "Zobrať", + "playModes": { + "coopText": "Proti Počítaču", + "freeForAllText": "Všetci-proti-Všetkým", + "multiTeamText": "Viacero Týmov", + "singlePlayerCoopText": "Jeden Hráč / Proti Počítaču", + "teamsText": "Tímy" + }, + "playText": "Hrať", + "playWindow": { + "oneToFourPlayersText": "1-4 hráčov", + "titleText": "Hrať", + "twoToEightPlayersText": "2-8 hráčov" + }, + "playerCountAbbreviatedText": "${COUNT} hráč", + "playerDelayedJoinText": "${PLAYER} bude hrať na začiatku ďalšieho kola.", + "playerInfoText": "Info Hráča", + "playerLeftText": "${PLAYER} opustil hru.", + "playerLimitReachedText": "Limit hráčov (${COUNT}) dosiahnutý; nedá sa pripojiť.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Nemôžeš odstrániť profil účtu.", + "deleteButtonText": "Odstrániť\nProfil", + "deleteConfirmText": "Odstrániť \"${PROFILE}\"?", + "editButtonText": "Upraviť\nProfil", + "explanationText": "(vlastné mená a zobrazenia hráča pre tento účet)", + "newButtonText": "Nový\nProfil", + "titleText": "Profily Hráča" + }, + "playerText": "Hráč", + "playlistNoValidGamesErrorText": "Tento playlist neobsahuje žiadne platné odomknuté hry.", + "playlistNotFoundText": "playlist sa nenašiel", + "playlistText": "Zoznam skladieb", + "playlistsText": "Playlisty", + "pleaseRateText": "Ak si ${APP_NAME} užívaš, prosím pouvažuj nad chvíľou\nohodnotenia a napísania recenzie. Toto poskytuje\nužitočnú spätnú väzbu a pomáha podporovať budúci rozvoj.\n\nvďaka!\n-Eric", + "pleaseWaitText": "Prosím počkaj...", + "pluginClassLoadErrorText": "Chyba pri načítaní triedy doplnku '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Chyba pri iniciovaní doplnku '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Bol zistený nový doplnok(ky). Reštartujte aby sa aktivovali, alebo ich nakonfigurte v nastaveniach.", + "pluginsRemovedText": "${NUM} doplnok(ky) nebol najdený.", + "pluginsText": "Pluginy", + "practiceText": "Tréning", + "pressAnyButtonPlayAgainText": "Stlač hocijaké tlačidlo ak chceš hrať znova...", + "pressAnyButtonText": "Stlač hocijaké tlačidlo ak chceš pokračovať...", + "pressAnyButtonToJoinText": "stlač hocijaké tlačidlo ak sa chceš pripojiť...", + "pressAnyKeyButtonPlayAgainText": "Stlač hocijakú klávesu/tlačidlo ak chceš hrať znova...", + "pressAnyKeyButtonText": "Stlač hocijakú klávesu/tlačidlo ak chceš pokračovať...", + "pressAnyKeyText": "Stlač hocijakú klávesu...", + "pressJumpToFlyText": "** Stláčaj Skok opakovane ak chceš lietať **", + "pressPunchToJoinText": "stlač ÚDER ak sa chceš pripojiť...", + "pressToOverrideCharacterText": "stlač ${BUTTONS} ak chceš zmeniť svoj charakter", + "pressToSelectProfileText": "stlač ${BUTTONS} ak si chceš zmeniť profil", + "pressToSelectTeamText": "stlač ${BUTTONS} ak si chceš zmeniť tím", + "promoCodeWindow": { + "codeText": "Kód", + "enterText": "Vložiť" + }, + "promoSubmitErrorText": "Error pri overovaní kódu; skontroluj svoj internet", + "ps3ControllersWindow": { + "macInstructionsText": "Vypni svoje PS3 vzadu, uisti sa že je že je Bluetooth\nna tvojom Mac-u zapnutý. Potom pripoj svoj ovládač \ndo svojho Mac-u a cez USB kábel ich spárujte. Odteraz\nmôžeš použiť home-button na ovládači a pripojiť sa na\nMac aj cez Bluetooth.\n\nNa niektorých Mac-och ťa pri párovaní môžu pýtať kód.\nAk sa to stane, pozri následujúci tutoriál alebo si \nvygoogli pomoc.\n\n\n\nPS3 ovládače pripojené cez Bluetooth by mali byť zobrazené\nv liste zariadení v Systémové Preferencie->Bluetooth. Mal\nby si ho z toho listu odstrániť a chceš ovládač znova použiť.\n\nTakisto sa uisti že si ich najskôr odpojil od Bluetoothu keď\nsa nepoužívajú lebo ich batéria sa bude stále používať.\n\nBluetooth by mal udržať max. 7 pripojených zariadení,\nto ale závisí na tom aké staré je zariadenie.", + "ouyaInstructionsText": "Ak chceš používať svoj PS3 ovládač na OUYA-e, jednoducho ich spoj USB káblom\na už sú spárované. Toto by malo odpojiť všetky ostatné zapojené ovládače, \npreto by si mal reštartovať OUYA-u a odpojiť USB kábel.\n\nOdteraz by si mal byť schopný použiť home button na ovládači pre bezdrôtové \npripojenie. Keď ťa to prestane baviť, podrž na ovládači home button na\n10 sekúnd ak chceš ovládač vypnúť; inak sa ti bude na nich míňať\nbaterka.", + "pairingTutorialText": "párujem tutoriálne video", + "titleText": "Používam PS3 ovládače s aplikáciou ${APP_NAME}:" + }, + "punchBoldText": "ÚDER", + "punchText": "Úder", + "purchaseForText": "Kúpiť za ${PRICE}", + "purchaseGameText": "Kúpiť Hru", + "purchasingText": "Kupujem...", + "quitGameText": "Ukončiť ${APP_NAME}?", + "quittingIn5SecondsText": "Ukončujem za 5 sekúnd..", + "randomPlayerNamesText": "VÝCHODNÉ_NÁZVY", + "randomText": "Náhodne", + "rankText": "Umiestnenie", + "ratingText": "Hodnotenie", + "reachWave2Text": "Dosiahni vlnu 2 pre umiestnenie.", + "readyText": "pripravený", + "recentText": "Nedávne", + "remoteAppInfoShortText": "${APP_NAME} je väčšia zábava s rodinou a kamarátmi.\nPripoj jeden alebo viac hardware ovládačov alebo si\nnainštaluj aplikáciu ${REMOTE_APP_NAME} na mobily a \ntablety a použi ich ako ovládače.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Pozícia Tlačidiel", + "button_size": "Veľkosť Tlačidiel", + "cant_resolve_host": "Nemožno nájsť hostiteľa.", + "capturing": "Potvrdujem...", + "connected": "Pripojené.", + "description": "Použi svoj mobil alebo tablet ako ovládač pre Bombsquad.\nNaraz sa môže pripojiť max. 8 zariadení na jedinej TV alebo tablete.", + "disconnected": "Odpojené serverom.", + "dpad_fixed": "stály", + "dpad_floating": "uvoľnený", + "dpad_position": "Pozícia D-Padu", + "dpad_size": "Veľkosť D-Padu", + "dpad_type": "Typ D-Padu", + "enter_an_address": "Pripojiť na Adresu", + "game_full": "Párty je plná alebo nepodporuje pripojenia.", + "game_shut_down": "Hra sa vypla.", + "hardware_buttons": "Hardwarové Tlačidlá", + "join_by_address": "Pripojiť sa na Adresu...", + "lag": "Lag: ${SECONDS} sekúnd", + "reset": "Resetovať na štandartné", + "run1": "Beh 1", + "run2": "Beh 2", + "searching": "Hľadám Bombsquad hry...", + "searching_caption": "Stlač meno hry aby si sa na ňu pripojil.\nUisti sa že ste na tej istej Wi-Fi ako hra.", + "start": "Začať", + "version_mismatch": "Nezhoda verzií.\nUisti sa že je Bombsquad aj BSRemote\nna najnovšej verzii." + }, + "removeInGameAdsText": "Odomkni si \"${PRO}\" v obchode pre odstránenie reklám.", + "renameText": "Premenovať", + "replayEndText": "Ukončiť Replay", + "replayNameDefaultText": "Replay Poslednej Hry", + "replayReadErrorText": "Error pri načítaní replay súboru.", + "replayRenameWarningText": "Premenuj \"${REPLAY}\" po hre ak si ho chceš uložiť; inak bude nahradený.", + "replayVersionErrorText": "Prepáč, tento replay bol vyrobený v inej\nverzii hry a nemôže byť použitý.", + "replayWatchText": "Pozrieť Replay", + "replayWriteErrorText": "Error pri písaní replay súboru.", + "replaysText": "Replaye", + "reportPlayerExplanationText": "Použi tento email pre nahlásenie podvodov, nevhodný jazyk, alebo iné zlé veci.\nProsím popíš nižšie:", + "reportThisPlayerCheatingText": "Podvod", + "reportThisPlayerLanguageText": "Nevhodný Jazyk", + "reportThisPlayerReasonText": "Čo chceš nahlásiť?", + "reportThisPlayerText": "Nahlásiť Hráča", + "requestingText": "Dostávam...", + "restartText": "Reštartovať", + "retryText": "Znova", + "revertText": "Späť", + "runText": "Bežať", + "saveText": "Uložiť", + "scanScriptsErrorText": "Error pri skenovaní skriptov; pozri zápis pre detaily.", + "scoreChallengesText": "Challenge pre Skóre", + "scoreListUnavailableText": "List pre skóre je nedostupné.", + "scoreText": "Skóre", + "scoreUnits": { + "millisecondsText": "Milisekúnd", + "pointsText": "Body", + "secondsText": "Sekúnd" + }, + "scoreWasText": "(predtým ${COUNT})", + "selectText": "Vybrať", + "seriesWinLine1PlayerText": "VYHRÁVA", + "seriesWinLine1TeamText": "VYHRÁVA", + "seriesWinLine1Text": "VYHRÁVA", + "seriesWinLine2Text": "SÉRIU!", + "settingsWindow": { + "accountText": "Účet", + "advancedText": "Pokročilé", + "audioText": "Audio", + "controllersText": "Ovládače", + "graphicsText": "Grafika", + "playerProfilesMovedText": "Poznámka: Profily Hráča sa premiestili do okna Účet v hlavnom menu.", + "titleText": "Nastavenia" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(jednoduchá, podporujúca-ovládač na-obrazovke-klávesnica pre písanie textu)", + "alwaysUseInternalKeyboardText": "Stále Používať Klávesnicu v Programe", + "benchmarksText": "Benchmarky & Stres-Testy", + "disableCameraGyroscopeMotionText": "Zakázať pohyb gyroskopu fotoaparátu", + "disableCameraShakeText": "Zakázať otrasy fotoaparátu", + "disableThisNotice": "(toto upozornenie môžeš vypnúť v Pokročilých nastaveniach)", + "enablePackageModsDescriptionText": "(povoľuje extra módovanie ale ruší hry na internete)", + "enablePackageModsText": "Povoliť Lokálny Balíček Módov", + "enterPromoCodeText": "Vložiť Kód", + "forTestingText": "Poznámka: tieto čísla sú len pre testovanie a budú stratené keď sa aplikácia vypne.", + "helpTranslateText": "${APP_NAME} podporuje aj iné jazyky ako Slovenský.\nAk chceš preložiť hru do iného jazyka alebo upraviť\npreklad, klikni na tlačidlo nižšie. Vďaka za pokrok!", + "kickIdlePlayersText": "Vyhodiť Nečinných Hráčov", + "kidFriendlyModeText": "Mód pre Deti (znížené násilie, atď.)", + "languageText": "Jazyk", + "moddingGuideText": "Tutoriál pre Módovanie", + "mustRestartText": "Ak chceš toto nastavenie použiť, musíš reštartovať hru.", + "netTestingText": "Testovanie Internetu", + "resetText": "Resetovať", + "showBombTrajectoriesText": "Ukázovať Trajektóriu Bomby", + "showPlayerNamesText": "Ukazovať Mená Hráčov", + "showUserModsText": "Ukázať Zložku pre Módy", + "titleText": "Pokročilé", + "translationEditorButtonText": "${APP_NAME} Preklad", + "translationFetchErrorText": "status pre jazyk nedostupný", + "translationFetchingStatusText": "kontrolujem status jazyka...", + "translationInformMe": "Informuj ma keď môj jazyk potrebuje vylepšiť", + "translationNoUpdateNeededText": "Slovenčina je celá preložená, jupiii!", + "translationUpdateNeededText": "** Slovenčina potrebuje dokončiť!! **", + "vrTestingText": "VR Testovanie" + }, + "shareText": "Zdieľať", + "sharingText": "Zdieľam...", + "showText": "Ukazujem", + "signInForPromoCodeText": "Musíš sa prihlásiť ak chceš použiť kód.", + "signInWithGameCenterText": "Ak chceš použiť GameCircle účet,\nprihlás sa s Game Center aplikáciou.", + "singleGamePlaylistNameText": "Len ${GAME}", + "singlePlayerCountText": "1 hráč", + "soloNameFilterText": "Sólo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Výber Charakteru", + "Chosen One": "Vyvolený", + "Epic": "Spomalené Hry", + "Epic Race": "Spomalené Preteky", + "FlagCatcher": "Capture the Flag", + "Flying": "Štastné myšlienky", + "Football": "Futbal", + "ForwardMarch": "Prepad", + "GrandRomp": "Dobytie", + "Hockey": "Hokej", + "Keep Away": "Únos", + "Marching": "Obeh", + "Menu": "Hlavné Menu", + "Onslaught": "Útok", + "Race": "Preteky", + "Scary": "Kráľ Hory", + "Scores": "Obrazovka so Skóre", + "Survival": "Eliminácia", + "ToTheDeath": "Zápas na život a na smrť", + "Victory": "Obrazovka s Finálovým Skóre" + }, + "spaceKeyText": "medzerník", + "statsText": "Štatistiky", + "storagePermissionAccessText": "Na toto potrebuješ povolenie k úložisku", + "store": { + "alreadyOwnText": "Už vlastníš ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Odstráni reklamy,\n• Odomkne viac nastavení,\n• A k tomu ešte dostaneš:", + "buyText": "Kúpiť", + "charactersText": "Charaktery", + "comingSoonText": "Už čoskoro...", + "extrasText": "Extra", + "freeBombSquadProText": "Bombsquad je teraz zadarmo, ale preto že si si ho predtým kúpil dostávaš\nBombsquad Pro zadarmo a ${COUNT} tiketov ako vďaku. Uži si nové vylepšenia\na vďaka za podporu!\n-Eric", + "holidaySpecialText": "Sviatočný Špeciál", + "howToSwitchCharactersText": "(choď do \"${SETTINGS} -> ${PLAYER_PROFILES}\" a nastav si a uprav charakter)", + "howToUseIconsText": "(vytvor si globálny profil (v okne Konto) ak ich chceš použiť)", + "howToUseMapsText": "(použi tieto mapy v tvojom všetci-proti-všetkým/tímovom playliste)", + "iconsText": "Ikony", + "loadErrorText": "Nemožno načítať stránku.\nSkontroluj internet.", + "loadingText": "načítavam", + "mapsText": "Mapy", + "miniGamesText": "MiniHry", + "oneTimeOnlyText": "(len jeden krát)", + "purchaseAlreadyInProgressText": "Už kupovanie tohoto predmetu prebieha.", + "purchaseConfirmText": "Kúpiť ${ITEM}?", + "purchaseNotValidError": "Objednávka nie je platná.\nKontaktuj ${EMAIL}, ak sa jedná o chybu. .", + "purchaseText": "Kúpiť", + "saleBundleText": "Zľava na Bundle!", + "saleExclaimText": "Zľava!", + "salePercentText": "(${PERCENT}% zľava)", + "saleText": "ZĽAVA", + "searchText": "Hľadať", + "teamsFreeForAllGamesText": "Hry na Tímy / Všetci-proti-Všetkým", + "totalWorthText": "*** Cena ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Vylepšiť?", + "winterSpecialText": "Zimný Špeciál", + "youOwnThisText": "- toto už vlastníš -" + }, + "storeDescriptionText": "Zábava pre ôsmich hráčov!\n\nOdpáľ svojich kamarátov (alebo počítač) v turnajoch v explozívnych minihrách ako napríklad Capture-the-Flag, Hokej a Spomalený-Death-Match!\n\nJednoduché ovládanie a ovládač hru robia veľmi ľahkú na ovládanie až pre 8 hráčov! Môžeš pokojne použiť aj mobilné zariadenia ako ovládače cez aplikáciu \"BombSquad Remote\" zadarmo!\n\nVidíme sa v hre!\n\nPozri www.froemling.net/bombsquad pre viac info.", + "storeDescriptions": { + "blowUpYourFriendsText": "Odpáľ kamarátov.", + "competeInMiniGamesText": "Súťažte v minihrách siahajúce od pretekov po lietanie.", + "customize2Text": "Nastav si charakter, minihry, alebo aj soundtrack.", + "customizeText": "Nastav si charakter a vytvor svoj vlastný playlist pre minihry.", + "sportsMoreFunText": "Športy sú viac zábavne s výbuchmi.", + "teamUpAgainstComputerText": "Spojte sa proti počítaču." + }, + "storeText": "Obchod", + "submitText": "Poslať", + "submittingPromoCodeText": "Overujem Kód...", + "teamNamesColorText": "Mená/Farby tímov", + "telnetAccessGrantedText": "Telnet povolené.", + "telnetAccessText": "Telnet detekovaný; povoliť?", + "testBuildErrorText": "Táto testovacia verzia už viac nie je aktívna; prosím obzri sa pre novú verziu.", + "testBuildText": "Testovacia Verzia", + "testBuildValidateErrorText": "Nemožno uplatniť testovaciu verziu. (žiadny internet?)", + "testBuildValidatedText": "Testovacia Verzia Platná; Uži si to!", + "thankYouText": "Vďaka za podporu! Uži si hru!!", + "threeKillText": "TRIPLE-KILL!!!", + "timeBonusText": "Časový Bonus", + "timeElapsedText": "Čas Uplynul", + "timeExpiredText": "Čas Uplynul", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Tip", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Top Kamaráti", + "tournamentCheckingStateText": "Kontrolujem štádium turnaju; prosím počkaj...", + "tournamentEndedText": "Tento turnaj skončil. Nový začne o chvíľu.", + "tournamentEntryText": "Vstupné", + "tournamentResultsRecentText": "Nedávne Výsledky Turnaja", + "tournamentStandingsText": "Postavenie v Turnaji", + "tournamentText": "Turnaj", + "tournamentTimeExpiredText": "Čas v Turnaji Vypršal", + "tournamentsDisabledWorkspaceText": "Turnaje sú zakázané keď pracoviská sú aktívne.\nAby sa znova povolili turnaje, vypnite svoje pracovisko a reštartujte.", + "tournamentsText": "Turnaje", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Bonesy", + "Butch": "Butch", + "Easter Bunny": "Easter Bunny", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Middle-Man", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Santa Claus", + "Snake Shadow": "Snake Shadow", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao Mascot", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Tréning", + "Infinite ${GAME}": "Nekonečný ${GAME}", + "Infinite Onslaught": "Nekonečný Útok", + "Infinite Runaround": "Nekonečný Obeh", + "Onslaught Training": "Útok Tréning", + "Pro ${GAME}": "Pro ${GAME}", + "Pro Football": "Pro Futbal", + "Pro Onslaught": "Pro Útok", + "Pro Runaround": "Pro Obeh", + "Rookie ${GAME}": "Pokročilý ${GAME}", + "Rookie Football": "Pokročilý Futbal", + "Rookie Onslaught": "Pokročilý Útok", + "The Last Stand": "Posledný vzdor", + "Uber ${GAME}": "Extrémny ${GAME}", + "Uber Football": "Extrémny Futbal", + "Uber Onslaught": "Extrémny Útok", + "Uber Runaround": "Extrémny Obeh" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Buď vyvolený na určitý čas aby si vyhral.\nZabi vyvoleného sa staň sa vyvoleným.", + "Bomb as many targets as you can.": "Traf čo najviac terčov.", + "Carry the flag for ${ARG1} seconds.": "Drž vlajku na ${ARG1} sekúnd.", + "Carry the flag for a set length of time.": "Drž vlajku na určitú dobu.", + "Crush ${ARG1} of your enemies.": "Zabi ${ARG1} protivníkov.", + "Defeat all enemies.": "Zabi všetkých protivníkov.", + "Dodge the falling bombs.": "Vyhni sa padajúcim bombám.", + "Final glorious epic slow motion battle to the death.": "Finálna spomalená bitka na život a na smrť.", + "Gather eggs!": "Zbieraj vajíčka!", + "Get the flag to the enemy end zone.": "Zober vlajku do protivníkovej konečnej zóny.", + "How fast can you defeat the ninjas?": "Ako rýchlo dokážeš poraziť ninjov?", + "Kill a set number of enemies to win.": "Zabi určitý počet protivníkov.", + "Last one standing wins.": "Posledný na nohách vyhráva.", + "Last remaining alive wins.": "Posledný nažive vyhráva.", + "Last team standing wins.": "Posledný tím nažive vyhráva.", + "Prevent enemies from reaching the exit.": "Zabráň protivníkom dosiahnúť východ.", + "Reach the enemy flag to score.": "Dotkni sa protivníkovej vlajky a skóruj.", + "Return the enemy flag to score.": "Ukradni protivníkovu vlajku a skóruj.", + "Run ${ARG1} laps.": "Obehni ${ARG1} kolá.", + "Run ${ARG1} laps. Your entire team has to finish.": "Obehni ${ARG1} kolá. Tvoj celý tím musí dokončiť.", + "Run 1 lap.": "Obehni 1 kolo.", + "Run 1 lap. Your entire team has to finish.": "Obehni 1 kolo. Tvoj celý tím musí dokončiť.", + "Run real fast!": "3..2..1..BEŽ!", + "Score ${ARG1} goals.": "Skóruj ${ARG1} góly.", + "Score ${ARG1} touchdowns.": "Skóruj ${ARG1} gólov.", + "Score a goal.": "Skóruj gól.", + "Score a touchdown.": "Skóruj gól.", + "Score some goals.": "Skóruj niekoľko gólov.", + "Secure all ${ARG1} flags.": "Obráň všetky ${ARG1} vlajky.", + "Secure all flags on the map to win.": "Obráň všetky vlajky na mape a vyhraj.", + "Secure the flag for ${ARG1} seconds.": "Buď pri vlajke ${ARG1} sekúnd.", + "Secure the flag for a set length of time.": "Buď pri vlajke určitý čas.", + "Steal the enemy flag ${ARG1} times.": "Ukradni vlajku nepriateľa ${ARG1} razy.", + "Steal the enemy flag.": "Ukradni nepriateľovu vlajku.", + "There can be only one.": "Môže byť len jeden.", + "Touch the enemy flag ${ARG1} times.": "Dotkni sa nepriateľovej vlajky ${ARG1} krát.", + "Touch the enemy flag.": "Dotkni sa nepriateľovej vlajky", + "carry the flag for ${ARG1} seconds": "drž vlajku na ${ARG1} sekúnd", + "kill ${ARG1} enemies": "zabi ${ARG1} protivníkov", + "last one standing wins": "posledný na nohách vyhráva", + "last team standing wins": "posledný tím nažive vyhráva", + "return ${ARG1} flags": "ukradni ${ARG1} vlajky", + "return 1 flag": "ukradni 1 vlajku", + "run ${ARG1} laps": "obehni ${ARG1} kolá", + "run 1 lap": "obehni 1 kolo", + "score ${ARG1} goals": "skóruj ${ARG1} góly", + "score ${ARG1} touchdowns": "skóruj ${ARG1} gólov", + "score a goal": "skóruj gól", + "score a touchdown": "skóruj gól", + "secure all ${ARG1} flags": "obráň všetky ${ARG1} vlajky", + "secure the flag for ${ARG1} seconds": "buď pri vlajke ${ARG1} sekúnd", + "touch ${ARG1} flags": "dotkni sa ${ARG1} vlajok", + "touch 1 flag": "dotkni sa 1 vlajky" + }, + "gameNames": { + "Assault": "Prepad", + "Capture the Flag": "Krádež", + "Chosen One": "Vyvolený", + "Conquest": "Dobytie", + "Death Match": "Death Match", + "Easter Egg Hunt": "Zber Vajíčok", + "Elimination": "Eliminácia", + "Football": "Futbal", + "Hockey": "Hokej", + "Keep Away": "Drž sa ďalej", + "King of the Hill": "Kráľ Hory", + "Meteor Shower": "Sprcha Meteorov", + "Ninja Fight": "Ninja Boj", + "Onslaught": "Útok", + "Race": "Preteky", + "Runaround": "Obeh", + "Target Practice": "Tréning Mierenia", + "The Last Stand": "Posledný na nohách" + }, + "inputDeviceNames": { + "Keyboard": "Klávesnica", + "Keyboard P2": "Klávesnica Hráč 2" + }, + "languages": { + "Arabic": "Arabčina", + "Belarussian": "Bieloruština", + "Chinese": "Zjednodušená Čínština", + "ChineseTraditional": "Tradičná Čínština", + "Croatian": "Chorváčtina", + "Czech": "Čeština", + "Danish": "Dánčina", + "Dutch": "Holandčina", + "English": "Angličtina", + "Esperanto": "Esperanto", + "Filipino": "Filipínsky", + "Finnish": "Fínčina", + "French": "Francúžtina", + "German": "Nemčina", + "Gibberish": "Somarina", + "Greek": "Gréčtina", + "Hindi": "Hindčina", + "Hungarian": "Maďarčina", + "Indonesian": "Indonézčina", + "Italian": "Taliančina", + "Japanese": "Japončina", + "Korean": "Kórejčina", + "Persian": "Perzština", + "Polish": "Poľština", + "Portuguese": "Portugálčina", + "Romanian": "Rumunčina", + "Russian": "Ruština", + "Serbian": "Srbčina", + "Slovak": "Slovenčina", + "Spanish": "Španielčina", + "Swedish": "Švédčina", + "Tamil": "Tamilčina", + "Thai": "Thajské", + "Turkish": "Turečtina", + "Ukrainian": "Ukrainčina", + "Venetian": "Benátske", + "Vietnamese": "Vietnamčina" + }, + "leagueNames": { + "Bronze": "Bronzová", + "Diamond": "Diamantová", + "Gold": "Zlatá", + "Silver": "Strieborná" + }, + "mapsNames": { + "Big G": "Veľké G", + "Bridgit": "Most", + "Courtyard": "Nádvorie", + "Crag Castle": "Hrad Crag", + "Doom Shroom": "Hríb", + "Football Stadium": "Futbalové Ihrisko", + "Happy Thoughts": "Sen", + "Hockey Stadium": "Hokejové Ihrisko", + "Lake Frigid": "Zmrznuté Jazero", + "Monkey Face": "Tvár Opice", + "Rampage": "Rampa", + "Roundabout": "Roundabout", + "Step Right Up": "Schody", + "The Pad": "Plošina", + "Tip Top": "Hora", + "Tower D": "Tower D", + "Zigzag": "ZigZag" + }, + "playlistNames": { + "Just Epic": "Len Spomalené", + "Just Sports": "Len Športy" + }, + "scoreNames": { + "Flags": "Vlajky", + "Goals": "Góly", + "Score": "Skóre", + "Survived": "Prežil", + "Time": "Čas", + "Time Held": "Čas Držania" + }, + "serverResponses": { + "A code has already been used on this account.": "Kód už bol na tomto zariadení použitý.", + "A reward has already been given for that address.": "Za túto adresu už odmena bola daná.", + "Account linking successful!": "Prepojenie prebehlo úspešne!", + "Account unlinking successful!": "Odpojenie prebehlo úspešne!", + "Accounts are already linked.": "Účty už sú prepojené.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Zobrazenie reklamy nebolo možné overiť.\nUistite sa, že máte spustenú oficiálnu a aktuálnu verziu hry.", + "An error has occurred; (${ERROR})": "Došlo k chybe; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Došlo k chybe; prosím kontaktujte podporu. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Došlo k chybe; prosím kontaktujte support@froemling.net.", + "An error has occurred; please try again later.": "Došlo k chybe; skúste to neskôr prosím.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Ste si istý že chcete prepojiť účty?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nToto nemôže byť odvolané!", + "BombSquad Pro unlocked!": "Bombsquad Pro odomknuté!", + "Can't link 2 accounts of this type.": "Nemožno prepojiť 2 účty tohoto typu.", + "Can't link 2 diamond league accounts.": "Nemožno prepojiť 2 účty s Diamantovou ligou.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Nemožno prepojiť; prekročilo by to maximum prepojených účtov (${COUNT}).", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Zachytili sme podvod; skóre a ceny nedostupné na ${COUNT} dni.", + "Could not establish a secure connection.": "Nepodarilo sa vytvoriť zabezpečené pripojenie.", + "Daily maximum reached.": "Denný maximum dosiahnutý.", + "Entering tournament...": "Vstupujem do turnaja...", + "Invalid code.": "Nesprávny kód.", + "Invalid payment; purchase canceled.": "Neplatná platba; nákup zrušený.", + "Invalid promo code.": "Nesprávny promo kód.", + "Invalid purchase.": "Neplatný nákup.", + "Invalid tournament entry; score will be ignored.": "Neplatný vstup do turnaja; skóre bude ignorované.", + "Item unlocked!": "Item odomkutý!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "PREPOJENIE RUŠENÉ. ${ACCOUNT} obsahuje\nvzácne dáta ktoré bude STRATENÉ.\nMôžeš prepojiť \"opačne\" ak chceš\n(a stratiť dáta na TOMTO účte).", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Prepojiť účet ${ACCOUNT} s týmto účtom?\nVšetky dáta na účte ${ACCOUNT} bude stratené.\nToto nemôžeš odvolať. Si si istý?", + "Max number of playlists reached.": "Maximálny počet playlistov dosiahnutý.", + "Max number of profiles reached.": "Maximálny počet profilov dosiahnutý.", + "Maximum friend code rewards reached.": "Maximálny počet odmien za nových hráčov dosiahnutý.", + "Message is too long.": "Správa je príliš dlhá.", + "No servers are available. Please try again soon.": "K dispozícii nie sú žiadne servery. Skúste to znova čoskoro.", + "Profile \"${NAME}\" upgraded successfully.": "Profil \"${NAME}\" bol úspešne vylepšený.", + "Profile could not be upgraded.": "Profil nemožno vylepšiť.", + "Purchase successful!": "Nákup prebehol úspešne!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Dostal si ${COUNT} tiketov za prihlásenie.\nPríď zase zajtra a dostaň ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Funkčnosť servera už nie je podporovaná na tejto verzii hry;\nProsím nainštaluj novšiu verziu.", + "Sorry, there are no uses remaining on this code.": "Prepáč, maximálne použitia na tomto kóde dosiahnuté.", + "Sorry, this code has already been used.": "Prepáč, tento kód už bol použitý.", + "Sorry, this code has expired.": "Prepáč, platnosť kódu vypršala.", + "Sorry, this code only works for new accounts.": "Prepáč, tento kód funguje len pre nové účty.", + "Still searching for nearby servers; please try again soon.": "Still searching for nearby servers; please try again soon.", + "Temporarily unavailable; please try again later.": "Dočasne nedostupné; prosím skús to znova neskôr.", + "The tournament ended before you finished.": "Turnaj sa skončil predtým ako si ho dokončil.", + "This account cannot be unlinked for ${NUM} days.": "Tento účet nemôže byť odpojený v podobu ${NUM} dní.", + "This code cannot be used on the account that created it.": "Tento kód nemôže byť použitý na účte ktorý ho vytvoril.", + "This is currently unavailable; please try again later.": "Táto položka momentálne nie je k dispozícii; prosím skúste neskôr prosím.", + "This requires version ${VERSION} or newer.": "Toto požaduje verziu ${VERSION} alebo novšiu.", + "Tournaments disabled due to rooted device.": "Turnaje zrušené kvôli \"root-nutemu\" zariadeniu.", + "Tournaments require ${VERSION} or newer": "Turnaje vyžadujú ${VERSION} alebo novšiu.", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Odpojiť ${ACCOUNT} z tohoto zariadenia?\nVšetky dáta na ${ACCOUNT} sa resetujú.\n(okrem achievementov pri niektorých prípadoch)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "Varovanie: našli sa náznaky podvádzania na tomto účte.\nÚčty ktoré podvádzajú budú zabanované. Prosím hraj férovo.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Chcel by si prepojiť tvoj účet zariadenia na tento účet?\n\nTvoj účet zariadenia je {ACCOUNT1}\nTento účet je ${ACCOUNT2}\n\nToto ti povolí ponechať tvoje pokroky.\nVarovanie: toto nejde vrátiť!", + "You already own this!": "Toto už vlastníš!", + "You can join in ${COUNT} seconds.": "Môžeš sa pripojiť za ${COUNT} sekúnd.", + "You don't have enough tickets for this!": "Na toto nemáš tikety!", + "You don't own that.": "Toto ešte nevlastníš.", + "You got ${COUNT} tickets!": "Máš ${COUNT} tiketov!", + "You got a ${ITEM}!": "Máš ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Bol si povýšený na vyššiu ligu; gratulujeme!", + "You must update to a newer version of the app to do this.": "Musíš nainštalovať novšiu verziu hry ak chceš toto spraviť.", + "You must update to the newest version of the game to do this.": "Musíš nainštalovať najnovšiu verziu hry ak chceš toto spraviť.", + "You must wait a few seconds before entering a new code.": "Musíš počkať pár sekúnd predtým ako vložíš nový kód.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Umiestnil si sa na #${RANK} mieste v turnaji. Vďaka za hranie!", + "Your account was rejected. Are you signed in?": "Tvoj účet nebol prijatý. Si prihlásený?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Tvoja kópia hry je modifikovaná.\nProsím vráť späť všetky zmeny a skús to znova.", + "Your friend code was used by ${ACCOUNT}": "Tvoj kód bol použitý hráčom ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minúta", + "1 Second": "1 Sekunda", + "10 Minutes": "10 Minút", + "2 Minutes": "2 Minúty", + "2 Seconds": "2 Sekundy", + "20 Minutes": "20 Minút", + "4 Seconds": "4 Sekundy", + "5 Minutes": "5 Minút", + "8 Seconds": "8 Sekúnd", + "Allow Negative Scores": "Mínusové Skóre", + "Balance Total Lives": "Vybalancovať Životy", + "Bomb Spawning": "Zjavovanie Bômb", + "Chosen One Gets Gloves": "Vyvolený Dostane Rukavice", + "Chosen One Gets Shield": "Vyvolený Dostane Štít", + "Chosen One Time": "Čas Vyvoleného", + "Enable Impact Bombs": "Povoliť Dotykové Bomby", + "Enable Triple Bombs": "Povoliť Trojité Bomby", + "Entire Team Must Finish": "Celý Tím Musí Dokončiť", + "Epic Mode": "Spomalene", + "Flag Idle Return Time": "Čas Vrátenia \"Neaktívnej\" Vlajky", + "Flag Touch Return Time": "Čas Vrátenia Vlajky Na Dotyk", + "Hold Time": "Čas Držania", + "Kills to Win Per Player": "Zabitia pre Výhru Na Hráča", + "Laps": "Kolá", + "Lives Per Player": "Životy Na Hráča", + "Long": "Dlhý", + "Longer": "Dlhší", + "Mine Spawning": "Zjavovanie Mín", + "No Mines": "Žiadne Míny", + "None": "Žiadny", + "Normal": "Normálny", + "Pro Mode": "Pro Mód", + "Respawn Times": "Čas Respawnu", + "Score to Win": "Výherné Skóre", + "Short": "Krátky", + "Shorter": "Kratší", + "Solo Mode": "Sólo Mód", + "Target Count": "Počet Terčov", + "Time Limit": "Časový Limit" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "Tím ${TEAM} je diskvalifikovaný lebo hráč ${PLAYER} odišiel", + "Killing ${NAME} for skipping part of the track!": "Zabitý hráč ${NAME} pre preskočenie časti trate!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Varovanie pre hráča ${NAME}: turbo stláčanie tlačidiel ťa zabije." + }, + "teamNames": { + "Bad Guys": "Protivníkov Tím", + "Blue": "Modrí", + "Good Guys": "Tvoj Tím", + "Red": "Červení" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Perfektne načasovaný skákajúci-bežiaci-točiaci-úder môže hráča zabiť\nna jednu ranu a získaš od kamarátov doživotný rešpekt.", + "Always remember to floss.": "Môžeš prosím ťa konečne začať hru?", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Vytvor nové profily per seba a tvojich kamarátov s vašimi\nvlastnými menami namiesto toho aby si používal náhodné.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Zošalenie ťa premení na časovanú bombu.\nAk nechceš vybúchnuť, nájdi lekárničku.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Napriek ich vzhľadu, sú schopnosti charakterov rovnaké,\ntakže si vyber, ktorý z nich sa ti najviac páči.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Nebuď moc drsný s tým štítom; stále ťa môžu zhodiť dole z útesu.", + "Don't run all the time. Really. You will fall off cliffs.": "Nebež celý čas. Vážne. Skončíš dole v útese.", + "Don't spin for too long; you'll become dizzy and fall.": "Netoč sa príliš dlho; inak odpadneš.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Drž hocijaké tlačidlo aby si behal. (Najlepšie fungujú bočné tlačidlá ak ich máš)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Drž hocijaké tlačidle aby si behal. Dostaneš sa na miesta \nrýchlejšie ale budeš zle zatáčať, takže bacha na útesy.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Ľadové bomby nie sú moc silné, ale zamrznú každého\nkoho trafia a nechajú ich ležať krehkých na zemi.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Ak vás niekto zdvihne, dajte mu päsť a on vás pustí. \n To funguje aj v reálnom živote.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Ak máš málo ovládačov, nainštaluj si aplikáciu \"${REMOTE_APP_NAME}\"\nna mobiloch a použi ich ako ovládače.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Ak sa na teba zalepí sticky-bomba, skáč a toč sa v kruhoch. Mala by sa od teba\nodlepiť a ak nie, uži si posledné sekundy života.", + "If you kill an enemy in one hit you get double points for it.": "Ak zabiješ protivníka na jednu ranu dostaneš zaň dvojité body.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Ak zoberieš zošalenie, tvoja jediná nádej je nájsť \nlekárničku počas ďalších pár sekúnd.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Ak budeš stáť na jednom mieste, budeš ako toast; čierny a asi aj mŕtvy.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Ak máš dosť veľa prichádzajúcich hráčov, zapni \"vyhadzovanie neaktívnych hráčov\"\nv nastaveniach v prípade že niekto zabudne opustiť hru.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Ak bude tvoje zariadenie horúce alebo si chceš šetriť baterku,\nzníž \"Vizualizáciu\" alebo \"Rozlíšenie\" v Nastavenia->Grafika.", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Ak sú tvoje FPS-ka biedne, skús znížiť \"Vizualizáciu\"\nalebo \"Rozlíšenie\" v Nastavenia->Grafika.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "V Capture-the-Flag, tvoja vlajka musí byť namieste ak chceš skórovať, ak druhý \ntím ide skórovať, ukradnutie ich vlajky môže byť dobrá cesta ako ich zastaviť.", + "In hockey, you'll maintain more speed if you turn gradually.": "V hokeji naberieš väčšiu rýchlosť ak sa budeš točiť v oblúkoch.", + "It's easier to win with a friend or two helping.": "Je ľahšie vyhrať keď ti pomáha kamarát alebo aj dvaja.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Ak skočíš hneď pred vyhodením bomby, hodíš ju vyššie.", + "Land-mines are a good way to stop speedy enemies.": "Míny sú dobrá cesta ako zastaviť rýchlych protivníkov.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Veľa vecí môžeš zobrať a zahodiť, takisto aj iných hráčov. Zhodením protivníka \nz útesu môže byť dobrá a zároveň emocionálna stratégia.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nie, nedočiahneš tam hore. Použi bombu.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Hráči sa môžu pripájať a odpájať aj v strede hry. Takisto\nmôžeš zapájať a odpájať ovládače počas hry.", + "Practice using your momentum to throw bombs more accurately.": "Trénuj mierenie a čas vyhodenia s bombami.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Údery bolia viac keď sa päste viac hýbu. Preto sa hýb,\ntoč, skáč ako šialenec.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Bež dozadu a dopredu pred odhodením bomby \naby si ju zahodil ďalej.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Odpáľ skupinu protivníkov tak\nže položíš bombu blízko TNT-čka.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Hlava je najbolestivejšie miesto, takže sticky-bomba \ndo hlavy často znamená okamžitá smrť.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Tento level nikdy nekončí, ale pokiaľ tu nahráš\nveľké skóre, dostaneš rešpekt od mnoho ľudí.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Sila zahodenia je založená na smere akým sa krútiš.\nAk chceš dačo hodiť pred seba, netoč sa nijako.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Unavený zo soundtracku? Nahraď ho vlastným!\nPozri Nastavenia->Audio->Soundtrack.", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Skús počkať sekundu alebo dve predtým ako bombu zahodíš.", + "Try tricking enemies into killing eachother or running off cliffs.": "Skús prekabátiť protivníkov aby sa zabili navzájom alebo spadli z útesu.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Použi tlačidlo pre zobratie aby si vlajku zobral < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Choď dozadu a naspäť aby si niečo zahodil ďalej.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Môžeš \"namieriť\" svoje údery tak že sa budeš točiť doľava\nalebo doprava. Toto môže byť užitočné pri hokeji.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Môžeš predpokladať kedy bomba vybúchne na farbách\niskier: žltá..oranžová..červená..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Môžeš hodiť bomby vyššie tak že pred ich vyhodením skočíš.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Môžeš sa zraniť ak sa budeš búchať o hlavu;\ntak sa skús nebúchať o hlavu.", + "Your punches do much more damage if you are running or spinning.": "Tvoje údery bolia viacej ak bežíš alebo sa točíš." + } + }, + "trophiesRequiredText": "Na toto potrebuješ aspoň ${NUMBER} trofejí.", + "trophiesText": "Trofeje", + "trophiesThisSeasonText": "Trofeje Tejto Sezóny", + "tutorial": { + "cpuBenchmarkText": "Púšťam tutoriál na neuveriteľnej rýchlosti (patrí k testu CPU rýchlosti)", + "phrase01Text": "Čau!", + "phrase02Text": "Vitaj v hre ${APP_NAME}!", + "phrase03Text": "Tu sú nejaké tipy ako ovládať svoj charakter:", + "phrase04Text": "Veľa vecí v hre ${APP_NAME} sú založené na FYZIKE.", + "phrase05Text": "Napríklad, keď dakoho udrieš,...", + "phrase06Text": "Bolesť je založená na rýchlosti tvojich pästí.", + "phrase07Text": "Vidíš? Nepohybujem sa, takže to ${NAME}a vôbec nebolí.", + "phrase08Text": "Teraz poďme skákať a točiť sa aby sme nabrali rýchlosť.", + "phrase09Text": "No, to je lepšie.", + "phrase10Text": "Beh pomáha tiež.", + "phrase11Text": "Podrž HOCIJAKÉ tlačidlo ak chceš bežať.", + "phrase12Text": "Pre úžasné údery, skús behať A točiť sa.", + "phrase13Text": "Ups; prepáč ${NAME}.", + "phrase14Text": "Môžeš brať a zahadzovať veci, vlajky, bomby... alebo ${NAME}a.", + "phrase15Text": "A nakoniec sú tu bomby.", + "phrase16Text": "Hádzanie bômb si vyžaduje tréning.", + "phrase17Text": "Jau! Nie veľmi dobrý hod.", + "phrase18Text": "Pohyb ti ju pomáha hodiť ďalej.", + "phrase19Text": "Skok ti ju pomáha hodiť vyššie.", + "phrase20Text": "\"Roztoč\" svoju bombu pre ešte dlhšie hody.", + "phrase21Text": "Načasovanie môže byť zložité.", + "phrase22Text": "Kurňa.", + "phrase23Text": "Skús ju \"upiecť\" sekundu alebo dve pred vyhodením.", + "phrase24Text": "Hurá! Pekne upečená.", + "phrase25Text": "No, to je asi všetko.", + "phrase26Text": "Teraz choď na nich!", + "phrase27Text": "A nezabudni piecť!", + "phrase28Text": "...ale nie veľmi dlho...", + "phrase29Text": "Veľa Šťastia!", + "randomName1Text": "Maroš", + "randomName2Text": "Erik", + "randomName3Text": "Baltazár", + "randomName4Text": "Denis", + "randomName5Text": "Laura", + "skipConfirmText": "Vážne chceš preskočiť tutoriál? Stlač znova pre potvrdenie.", + "skipVoteCountText": "${COUNT} z ${TOTAL} hráčov chcú tutoriál preskočiť", + "skippingText": "preskakujem tutoriál...", + "toSkipPressAnythingText": "(stlač dačo pre preskočenie tutoriálu)" + }, + "twoKillText": "DOUBLE-KILL!", + "unavailableText": "nedostupné", + "unconfiguredControllerDetectedText": "Nenastavený ovládač detekovaný:", + "unlockThisInTheStoreText": "Toto musí byť odomknuté v obchode.", + "unlockThisProfilesText": "Ak chceš vytvoriť viac ako ${NUM} profilov, potrebuješ:", + "unlockThisText": "Ak chceš toto odomknúť, potrebuješ:", + "unsupportedHardwareText": "Prepáč, tento hardware nie je podporovaný pre túto verziu hry.", + "upFirstText": "Ako prvé ide:", + "upNextText": "Ďalej v hre ${COUNT}:", + "updatingAccountText": "Vylepšujem účet...", + "upgradeText": "Vylepšiť", + "upgradeToPlayText": "Odomkni \"${PRO}\" v obchode (v hre) ak toto chceš hrať.", + "useDefaultText": "Použiť Štandartné", + "usesExternalControllerText": "Táto hra používa ako vstup externý ovládač.", + "usingItunesText": "Používam Music App ako soundtrack...", + "validatingTestBuildText": "Overujem Testovaciu Verziu...", + "victoryText": "Výhra!", + "voteDelayText": "Nemôžeš začať ďalšie hlasovanie v podobe ${NUMBER} sekúnd", + "voteInProgressText": "Hlasovanie už prebieha.", + "votedAlreadyText": "Už si hlasoval", + "votesNeededText": "Je treba ${NUMBER} hlasov", + "vsText": "vs", + "waitingForHostText": "(čakám na príkazy hráča ${HOST})", + "waitingForPlayersText": "čakám na hráčov aby sa pripojili...", + "waitingInLineText": "Čakám v rade (párty je plná)...", + "watchAVideoText": "Pozrieť Video", + "watchAnAdText": "Pozrieť Reklamu", + "watchWindow": { + "deleteConfirmText": "Vymazať \"${REPLAY}\"?", + "deleteReplayButtonText": "Vymazať\nReplay", + "myReplaysText": "Moje Replaye", + "noReplaySelectedErrorText": "Nie Je Vybratý Žiadny Replay", + "playbackSpeedText": "Rýchlosť Prehrávania: ${SPEED}", + "renameReplayButtonText": "Premenovať\nReplay", + "renameReplayText": "Premenovať \"${REPLAY}\" na:", + "renameText": "Premenovať", + "replayDeleteErrorText": "Chyba pri vymazávaní replayu.", + "replayNameText": "Meno Replayu", + "replayRenameErrorAlreadyExistsText": "Replay s takým menom už existuje.", + "replayRenameErrorInvalidName": "Nemožno premenovať replay; neplatné meno.", + "replayRenameErrorText": "Chyba pri premenovaní replayu.", + "sharedReplaysText": "Zdieľané Replaye", + "titleText": "Pozerať", + "watchReplayButtonText": "Pozrieť\nReplay" + }, + "waveText": "Vlna", + "wellSureText": "Jasné!", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Počúvam Wiimotes...", + "pressText": "Stlač Wiimote tlačidlá 1 a 2 naraz.", + "pressText2": "Na novších Wiimotes so zabudovaným Motion Plus, stlač červené \"sync\" tlačidlo vzadu." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Copyright", + "listenText": "Počúvať", + "macInstructionsText": "Uisti sa že tvoj Wii je vypnutý a bluetooth je zapnutý\nna tvojom Mac-u, potom stlač \"Počúvať\". Wiimote podpora \nmôže byť trocha zbláznená, preto by si to mal skúsiť\nviac krát pred tým ako sa to pripojí.\n\nBluetooth by mal uniesť až 7 pripojených zariadení,\nto záleží na tom, aké staré je zariadenie.\n\nBombsquad podporuje originálne Wiimotes, Nunchucky,\na klasický ovládač.\nNovšie Wii Remote Plus už funguje tiež ale nie\ns prídavnými zariadeniami.", + "thanksText": "Vďaka DarwiinRemote tímu\nza toto uskutočnenie.", + "titleText": "Wiimote Setup" + }, + "winsPlayerText": "${NAME} Vyhráva!", + "winsTeamText": "${NAME} Vyhráva!", + "winsText": "${NAME} Vyhráva!", + "workspaceSyncErrorText": "Chyba pri synchronizácii ${WORKSPACE}. Pozri log pre detaily.", + "workspaceSyncReuseText": "Nemožno synchronizovať ${WORKSPACE}. Znovu-využitie predošlej synchronizovanej verzie.", + "worldScoresUnavailableText": "Svetové skóre nedostupné.", + "worldsBestScoresText": "Svetovo Najlepšie Skóre", + "worldsBestTimesText": "Svetovo Najlepšie Časy", + "xbox360ControllersWindow": { + "getDriverText": "Zohnať Driver", + "macInstructions2Text": "Ak chceš použiť ovládače bezdrôtovo, budeš potrebovať receiver\nktorý by mal prísť s \"Xbox 360 Wireless Controller for Windows\".\nJeden \"receiver\" ti povoľuje pripojiť až 4 vládače.\n\nDôležité: \"3rd-party receiver\" nebude fungovať s týmto driverom;\nuisti sa že tvoj receiver má na sebe \"Microsoft\", nie \"XBOX 360\".\nMicrosoft ich už Nepredáva osobitne, takže budeš musieť zohnať\njeden pribalený s ovládačom alebo ho vyhľadať na ebay.\n\nAk si myslíš že to je užitočné, skús porozmýšľať nad donácii \ndriver vývojárovi na jeho stránke.", + "macInstructionsText": "Ak chceš použiť Xbox 360 ovládače, budeš musieť \nnainštalovať Mac driver dostupný v linku nižšie.\nToto platí pre káblové aj bezdrôtové ovládače.", + "ouyaInstructionsText": "Ak chceš použiť káblový Xbox ovládač na Bombsquade, jednoducho\nich zapoj do do USB portu. Môžeš použiť USB hub pre pripojenie\nviacerých ovládačov.\n\nAk chceš použiť bezdrôtový ovládač, potrebuješ receiver,\ndostupný ako časť \"Xbox 360 wireless Controller for Windows\"\nbalíku alebo kúpený osobitne. Každý receiver sa zapája do USB\nportu a povoľuje ti zapojiť až 4 ovládače.", + "titleText": "Používam Xbox 360 Ovládače s hrou ${APP_NAME}:" + }, + "yesAllowText": "Áno, Povoliť!", + "yourBestScoresText": "Tvoje Najlepšie Skóre", + "yourBestTimesText": "Tvoje Najlepšie Časy" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/spanish.json b/dist/ba_data/data/languages/spanish.json new file mode 100644 index 0000000..c2f9bb0 --- /dev/null +++ b/dist/ba_data/data/languages/spanish.json @@ -0,0 +1,2008 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Los nombres no deben contener emojis o caracteres especiales", + "accountProfileText": "(Perfil de la cuenta)", + "accountsText": "Cuentas", + "achievementProgressText": "Logros: ${COUNT} de ${TOTAL}", + "campaignProgressText": "Progreso de campaña [Difícil]: ${PROGRESS}", + "changeOncePerSeason": "Solamente puedes cambiarlo una vez por temporada.", + "changeOncePerSeasonError": "Debes esperar hasta la siguiente temporada para cambiarlo de nuevo (en ${NUM} día/s)", + "customName": "Nombre personalizado", + "deviceSpecificAccountText": "Actualmente usando una cuenta específica de dispositivo: ${NAME}", + "googlePlayGamesAccountSwitchText": "Si quieres cambiar a otra cuenta de Google,\nusa Google Play para cambiar tu cuenta.", + "linkAccountsEnterCodeText": "Registrar Código", + "linkAccountsGenerateCodeText": "Generar Código", + "linkAccountsInfoText": "(compartir progreso a través de diferentes plataformas)", + "linkAccountsInstructionsNewText": "Para enlazar dos cuentas, genera un código en la primera cuenta\ne introduce el código en la segunda. \nLos datos de la segunda cuenta serán compartidos con la primera.\n\n(Los datos de la primera cuenta se perderán).\n\nPuedes vincular hasta ${COUNT} cuentas.\n\nIMPORTANTE: enlaza cuentas tuyas;\nSi enlazas cuentas de tus amigos, no podrán jugar online al mismo tiempo.", + "linkAccountsInstructionsText": "Para enlazar dos cuentas, genera un código en una\n de ellas y escribe el código en la otra.\nEl progreso e accesorios se combinarán.\nPuedes enlazar hasta ${COUNT} cuentas. \n\nIMPORTANTE: Solo enlaza cuentas tuyas!\n\nSi enlazas cuentas con tus amigos no podrán jugar al mismo tiempo!\n\nTambién: esto no se puede deshacer actualmente, así que se cuidadoso!", + "linkAccountsText": "Enlazar Cuentas", + "linkedAccountsText": "Cuentas enlazadas:", + "manageAccountText": "Administrar Cuenta", + "nameChangeConfirm": "¿Cambiar tu nombre a ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Esto reiniciará tu progreso en el modo\ncooperativo y tus puntajes (A excepción de tus tickets).\nNo podrás recuperar los cambios. ¿Estás seguro?", + "resetProgressConfirmText": "Esto reiniciará tus logros, récords\ny progreso en el modo cooperativo.\nLos cambios no se pueden deshacer.\n¿Estás seguro?", + "resetProgressText": "Reiniciar progreso", + "setAccountName": "Establecer nombre de la cuenta", + "setAccountNameDesc": "Selecciona el nombre a mostrar para tu cuenta. \nPuedes usar el nombre de tu cuenta asociada\no crear un nombre personalizado.", + "signInInfoText": "Inicia sesión para obtener tickets, competir en línea\ny compartir tu progreso en otras plataformas.", + "signInText": "Iniciar sesión", + "signInWithDeviceInfoText": "(una cuenta automática disponible únicamente en este dispositivo)", + "signInWithDeviceText": "Iniciar sesión con cuenta del dispositivo", + "signInWithGameCircleText": "Iniciar sesión con Game Circle", + "signInWithGooglePlayText": "Iniciar sesión con Google Play", + "signInWithTestAccountInfoText": "(Cuenta de prueba, usa la cuenta del dispositivo para avanzar)", + "signInWithTestAccountText": "Registrarse con una Cuenta de Prueba", + "signInWithV2InfoText": "(una cuenta que funciona en todas las plataformas)", + "signInWithV2Text": "Inicia sesión con tu cuenta de BombSquad", + "signOutText": "Cerrar Sesión", + "signingInText": "Iniciando sesión...", + "signingOutText": "Cerrando sesión...", + "testAccountWarningCardboardText": "Advertencia: inicias sesión con una cuenta \"de prueba\".\nSerá reemplazada por una cuenta Google una \nvez sea soportada en cardboard apps.\n\nPor ahora tendrás que ganar todos los tickets en el juego.\n(hazlo ,sin embargo, puedes obtener BombSquad Pro upgrade gratis)", + "testAccountWarningOculusText": "Cuidado: Está ingresando con una cuenta \"De prueba\".\nEsta será reemplazada con su cuenta Oculus más adelante\nen este año, lo cual ofrecerá compra de tiquetes y otras opciones.\n\nPor ahora tendrá que ganarse todos los tiquetes en-juego.\n(Sin embargo, puedes obtener BombSquad Pro gratis)", + "testAccountWarningText": "Advertencia: te estás registrando con una cuenta de\nprueba. Esta cuenta está vinculada a este dispositivo y\npuede que se reinicie periódicamente. (Así que no\ngastes mucho tiempo coleccionando/desbloqueando objetos)\n\nJuega una versión pública del juego y usa una \"cuenta real\"\n(Game-Center, Google Plus, etc.) Esto también te dejará\nguardar tu progreso en la nube y poder compartirlo con\ndiferentes dispositivos.", + "ticketsText": "Boletos: ${COUNT}", + "titleText": "Cuenta", + "unlinkAccountsInstructionsText": "Selecciona una cuenta para dejar de enlazar con ella", + "unlinkAccountsText": "Desenlazar Cuentas", + "unlinkLegacyV1AccountsText": "Desvincular Cuenta Heredada (V1)", + "v2LinkInstructionsText": "Usa este enlace para crearte una cuenta o para iniciar sesión", + "viaAccount": "(por cuenta ${NAME})", + "youAreLoggedInAsText": "Estás conectado como:", + "youAreSignedInAsText": "Has iniciado sesión como:" + }, + "achievementChallengesText": "Logros de desafíos", + "achievementText": "Logro", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Elimina 3 enemigos con una caja de TNT", + "descriptionComplete": "Eliminaste a 3 enemigos con una caja de TNT", + "descriptionFull": "Elimina 3 enemigos con una caja de TNT en ${LEVEL}", + "descriptionFullComplete": "Eliminaste 3 enemigos con una caja de TNT en ${LEVEL}", + "name": "La dinamita hace Boom!" + }, + "Boxer": { + "description": "Gana sin usar bombas", + "descriptionComplete": "Ganaste sin usar ninguna bomba", + "descriptionFull": "Completa ${LEVEL} sin usar bombas", + "descriptionFullComplete": "Completaste ${LEVEL} sin usar bombas", + "name": "Boxeador" + }, + "Dual Wielding": { + "descriptionFull": "Conecta 2 controles (de hardware o de aplicación)", + "descriptionFullComplete": "2 controles conectados (de hardware o de aplicación)", + "name": "Juego Doble" + }, + "Flawless Victory": { + "description": "Gana sin haber recibido ningún golpe", + "descriptionComplete": "Ganaste sin ser golpeado", + "descriptionFull": "Gana ${LEVEL} sin ser golpeado", + "descriptionFullComplete": "Ganaste ${LEVEL} sin ser golpeado", + "name": "Victoria Perfecta" + }, + "Free Loader": { + "descriptionFull": "Empieza un juego de Todos-Contra-Todos con 2 o más jugadores", + "descriptionFullComplete": "Has empezado un juego de Todos-Contra-Todos con 2 o más jugadores", + "name": "Cargador Libre" + }, + "Gold Miner": { + "description": "Elimina 6 enemigos con minas", + "descriptionComplete": "Eliminaste 6 enemigos con minas", + "descriptionFull": "Elimina 6 enemigos con minas en ${LEVEL}", + "descriptionFullComplete": "Eliminaste 6 enemigos con minas en ${LEVEL}", + "name": "Minero de Oro" + }, + "Got the Moves": { + "description": "Gana sin usar golpes o bombas", + "descriptionComplete": "Ganaste sin usar golpes o bombas", + "descriptionFull": "Gana ${LEVEL} sin usar golpes o bombas", + "descriptionFullComplete": "Ganaste ${LEVEL} sin usar golpes o bombas", + "name": "Tú si sabes como moverte!" + }, + "In Control": { + "descriptionFull": "Conecta un control (de hardware o de aplicación)", + "descriptionFullComplete": "Conectado un control (de hardware o de aplicación)", + "name": "En Control" + }, + "Last Stand God": { + "description": "Anota 1000 puntos", + "descriptionComplete": "Anotaste 1000 puntos", + "descriptionFull": "Anota 1000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotaste 1000 puntos en ${LEVEL}", + "name": "Dios del ${LEVEL}" + }, + "Last Stand Master": { + "description": "Anota 250 puntos", + "descriptionComplete": "Anotaste 250 puntos", + "descriptionFull": "Anota 250 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotaste 250 puntos en ${LEVEL}", + "name": "Maestro de ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Anota 500 puntos", + "descriptionComplete": "Anotaste 500 puntos", + "descriptionFull": "Anota 500 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotaste 500 puntos en ${LEVEL}", + "name": "Mago de ${LEVEL}" + }, + "Mine Games": { + "description": "Elimina 3 enemigos con minas", + "descriptionComplete": "Eliminaste 3 enemigos con minas", + "descriptionFull": "Elimina 3 enemigos con minas en ${LEVEL}", + "descriptionFullComplete": "Eliminaste 3 enemigos con minas en ${LEVEL}", + "name": "Juegos de minas" + }, + "Off You Go Then": { + "description": "Arroja 3 enemigos al precipicio", + "descriptionComplete": "Arrojaste 3 enemigos al precipicio", + "descriptionFull": "Arroja 3 enemigos al precipicio en ${LEVEL}", + "descriptionFullComplete": "Arrojaste 3 enemigos al precipicio en ${LEVEL}", + "name": "Te vas abajo entonces" + }, + "Onslaught God": { + "description": "Anota 5000 puntos", + "descriptionComplete": "Anotaste 5000 puntos", + "descriptionFull": "Anota 5000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotaste 5000 puntos en ${LEVEL}", + "name": "Dios de ${LEVEL}" + }, + "Onslaught Master": { + "description": "Anota 500 puntos", + "descriptionComplete": "Anotaste 500 puntos", + "descriptionFull": "Anota 500 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotaste 500 puntos en ${LEVEL}", + "name": "Maestro de ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Vence todas las hordas", + "descriptionComplete": "Venciste todas las hordas", + "descriptionFull": "Vence todas las hordas en ${LEVEL}", + "descriptionFullComplete": "Venciste todas las hordas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Anota 1000 puntos", + "descriptionComplete": "Anotaste 1000 puntos", + "descriptionFull": "Anota 1000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotaste 1000 puntos en ${LEVEL}", + "name": "Mago de ${LEVEL}" + }, + "Precision Bombing": { + "description": "Gana sin usar poderes", + "descriptionComplete": "Ganaste sin usar poderes", + "descriptionFull": "Gana ${LEVEL} sin usar poderes", + "descriptionFullComplete": "Ganaste ${LEVEL} sin usar poderes", + "name": "Bombardeo preciso" + }, + "Pro Boxer": { + "description": "Gana sin usar bombas", + "descriptionComplete": "Ganaste sin usar bombas", + "descriptionFull": "Completa ${LEVEL} sin usar bombas", + "descriptionFullComplete": "Completaste ${LEVEL} sin usar bombas", + "name": "Boxeador Pro" + }, + "Pro Football Shutout": { + "description": "Gana sin que los enemigos anoten", + "descriptionComplete": "Ganaste sin que los enemigos anotaran", + "descriptionFull": "Gana ${LEVEL} sin que los enemigos anoten", + "descriptionFullComplete": "Ganaste ${LEVEL} sin que los enemigos anotaran", + "name": "Balón de oro en ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Gana el partido", + "descriptionComplete": "Ganaste el partido", + "descriptionFull": "Gana el partido en ${LEVEL}", + "descriptionFullComplete": "Ganaste el partido en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Vence todas las hordas", + "descriptionComplete": "Venciste todas las hordas", + "descriptionFull": "Vence todas las hordas de ${LEVEL}", + "descriptionFullComplete": "Venciste todas las hordas de ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Supera todas las hordas", + "descriptionComplete": "Superaste a todas las hordas", + "descriptionFull": "Supera todas las hordas en ${LEVEL}", + "descriptionFullComplete": "Supera todas las hordas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Gana sin que los enemigos anoten", + "descriptionComplete": "Ganaste sin que los enemigos anotaran", + "descriptionFull": "Gana ${LEVEL} sin que los enemigos anoten", + "descriptionFullComplete": "Ganaste ${LEVEL} sin que los enemigos anotaran", + "name": "Balón de oro en ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Gana el partido", + "descriptionComplete": "Ganaste el partido", + "descriptionFull": "Gana el partido en ${LEVEL}", + "descriptionFullComplete": "Ganaste el partido en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Vence todas las hordas", + "descriptionComplete": "Venciste todas las hordas", + "descriptionFull": "Vence todas las hordas en ${LEVEL}", + "descriptionFullComplete": "Venciste todas las hordas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Runaround God": { + "description": "Anota 2000 puntos", + "descriptionComplete": "Anotaste 2000 puntos", + "descriptionFull": "Anota 2000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotaste 2000 puntos en ${LEVEL}", + "name": "Dios de ${LEVEL}" + }, + "Runaround Master": { + "description": "Anota 500 puntos", + "descriptionComplete": "Anotaste 500 puntos", + "descriptionFull": "Anota 500 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotaste 500 puntos en ${LEVEL}", + "name": "Maestro de ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Anota 1000 puntos", + "descriptionComplete": "Anotaste 1000 puntos", + "descriptionFull": "Anota 1000 puntos en ${LEVEL}", + "descriptionFullComplete": "Anotaste 1000 puntos en ${LEVEL}", + "name": "Gran Sabio de ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Comparte exitosamente el juego con un amigo", + "descriptionFullComplete": "Compartido exitosamente el juego con un amigo", + "name": "Compartir es Amar" + }, + "Stayin' Alive": { + "description": "Gana sin ser eliminado", + "descriptionComplete": "Ganaste sin ser eliminado", + "descriptionFull": "Gana ${LEVEL} sin ser eliminado", + "descriptionFullComplete": "Ganaste ${LEVEL} sin ser eliminado", + "name": "¡Sobreviviendo!" + }, + "Super Mega Punch": { + "description": "Inflige 100% de daño con un solo golpe", + "descriptionComplete": "Infligiste 100% de daño con un solo golpe", + "descriptionFull": "Inflige 100% de daño con un solo golpe en ${LEVEL}", + "descriptionFullComplete": "Infligiste 100% de daño con un solo golpe en ${LEVEL}", + "name": "¡Súper mega golpe!" + }, + "Super Punch": { + "description": "Inflige 50% de daño con un solo golpe", + "descriptionComplete": "Infligiste 50% de daño con un solo golpe", + "descriptionFull": "Inflige 50% de daño con un solo golpe en ${LEVEL}", + "descriptionFullComplete": "Infligiste 50% de daño con un solo golpe en ${LEVEL}", + "name": "¡Super golpe!" + }, + "TNT Terror": { + "description": "Elimina 6 enemigos con TNT", + "descriptionComplete": "Eliminaste 6 enemigos con TNT", + "descriptionFull": "Elimina 6 enemigos con TNT en ${LEVEL}", + "descriptionFullComplete": "Eliminaste 6 enemigos con TNT en ${LEVEL}", + "name": "¡Pirómano!" + }, + "Team Player": { + "descriptionFull": "Empieza un juego de Equipos con 4 o más jugadores", + "descriptionFullComplete": "Has empezado un juego de Equipos con 4 o más jugadores", + "name": "Jugador de Equipo" + }, + "The Great Wall": { + "description": "Detén todos los enemigos", + "descriptionComplete": "Detuviste todos los enemigos", + "descriptionFull": "Detén todos los enemigos en ${LEVEL}", + "descriptionFullComplete": "Detuviste todos los enemigos en ${LEVEL}", + "name": "La Gran Muralla" + }, + "The Wall": { + "description": "Detén a todos los enemigos", + "descriptionComplete": "Detuviste a todos los enemigos", + "descriptionFull": "Detén a todos los enemigos en ${LEVEL}", + "descriptionFullComplete": "Detuviste a todos los enemigos en ${LEVEL}", + "name": "La Muralla" + }, + "Uber Football Shutout": { + "description": "Gana sin que los enemigos anoten", + "descriptionComplete": "Ganaste sin que los enemigos anotaran", + "descriptionFull": "Gana ${LEVEL} sin que los enemigos anoten", + "descriptionFullComplete": "Ganaste ${LEVEL} sin que los enemigos anotaran", + "name": "Balón de oro ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Gana el partido", + "descriptionComplete": "Ganaste el partido", + "descriptionFull": "Gana el partido en ${LEVEL}", + "descriptionFullComplete": "Ganaste el partido en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Vence todas las hordas", + "descriptionComplete": "Venciste todas las hordas", + "descriptionFull": "Vence todas las hordas en ${LEVEL}", + "descriptionFullComplete": "Venciste todas las hordas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Vence a todas las hordas", + "descriptionComplete": "Terminaste con todas las hordas", + "descriptionFull": "Vence a todas las hordas en ${LEVEL}", + "descriptionFullComplete": "Terminaste con todas las hordas en ${LEVEL}", + "name": "Victoria en ${LEVEL}" + } + }, + "achievementsRemainingText": "Logros pendientes:", + "achievementsText": "Logros", + "achievementsUnavailableForOldSeasonsText": "Lo sentimos, los logros específicos no están disponibles para temporadas anteriores.", + "activatedText": "${THING} activado.", + "addGameWindow": { + "getMoreGamesText": "Más Juegos...", + "titleText": "Agregar Juego" + }, + "allowText": "Permitir", + "alreadySignedInText": "Tu cuenta está registrada en otro dispositivo;\npor favor cambia de cuentas o cierra el juego en tu \notro dispositivo e inténtalo de nuevo.", + "apiVersionErrorText": "No se puede cargar el módulo ${NAME}; se dirige a la versión-api ${VERSION_USED}; necesitamos la ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" se activa solo si tiene audífonos conectados)", + "headRelativeVRAudioText": "Audio VR de Cabeza", + "musicVolumeText": "Volumen de la Música", + "soundVolumeText": "Volumen del Sonido", + "soundtrackButtonText": "Canciones de fondo/Bandas Sonoras", + "soundtrackDescriptionText": "(usa tu propia música para reproducir durante los juegos)", + "titleText": "Sonido" + }, + "autoText": "Auto", + "backText": "Atrás", + "banThisPlayerText": "Expulsar a Este Jugador", + "bestOfFinalText": "El mejor de ${COUNT}", + "bestOfSeriesText": "Mejor serie de ${COUNT}:", + "bestOfUseFirstToInstead": 0, + "bestRankText": "Tu mejor clasificación es #${RANK}", + "bestRatingText": "Tu mejor clasificación es ${RATING}", + "betaErrorText": "Esta versión beta está caducada, por favor actualizala.", + "betaValidateErrorText": "Imposible validar beta. (¿Tienes conexión a internet?)", + "betaValidatedText": "Beta Validada; ¡disfruta!", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Potenciar", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} se configura en la propia aplicación.", + "buttonText": "botón", + "canWeDebugText": "¿Te gustaría que BombSquad enviara errores, accidentes, e\ninformación de uso básico al desarrollador de forma automática?\n\nLa información no contendrá datos personales y ayudará a\nmantener el juego funcionando sin errores y libre de problemas.", + "cancelText": "Cancelar", + "cantConfigureDeviceText": "Perdón, pero ${DEVICE} no es configurable.", + "challengeEndedText": "Este desafío ha terminado.", + "chatMuteText": "Silenciar Chat", + "chatMutedText": "Chat Silenciado", + "chatUnMuteText": "Desmutear Chat", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "¡Debes completar\neste nivel para avanzar!", + "completionBonusText": "Bono extra por Acabar", + "configControllersWindow": { + "configureControllersText": "Configuración de Controles", + "configureGamepadsText": "Configurar controles", + "configureKeyboard2Text": "Configurar Teclado P2", + "configureKeyboardText": "Configurar Teclado", + "configureMobileText": "Dispositivos Móviles como Controles", + "configureTouchText": "Configurar Pantalla Táctil", + "ps3Text": "Controles de PS3", + "titleText": "Controles", + "wiimotesText": "Wii Remotes", + "xbox360Text": "Controles de Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Nota: el soporte de controles varía según el dispositivo y la versión de Android.", + "pressAnyButtonText": "Pulsa cualquier botón del control\n que desees configurar...", + "titleText": "Configurar tu control" + }, + "configGamepadWindow": { + "advancedText": "Avanzado", + "advancedTitleText": "Configuración Avanzada del Control", + "analogStickDeadZoneDescriptionText": "(súbele si tu personaje 'derrapa' cuando sueltas la palanca)", + "analogStickDeadZoneText": "Zona Muerta del Stick Analógico", + "appliesToAllText": "(aplica a todos los controles de este tipo)", + "autoRecalibrateDescriptionText": "(habilita esta opción si tu personaje no se mueve a toda velocidad)", + "autoRecalibrateText": "Auto-Calibrar Stick Analógico", + "axisText": "eje", + "clearText": "vaciar", + "dpadText": "DPad", + "extraStartButtonText": "Botón Extra de Inicio", + "ifNothingHappensTryAnalogText": "Si no ocurre nada, intenta asignar al stick analógico.", + "ifNothingHappensTryDpadText": "Si no ocurre nada, intenta asignar al DPad.", + "ignoreCompletelyDescriptionText": "(evita que este controlador impacte el juego y/o menus)", + "ignoreCompletelyText": "Ignorar Completamente", + "ignoredButton1Text": "Botón 1 Ignorado", + "ignoredButton2Text": "Botón 2 ignorado", + "ignoredButton3Text": "Botón 3 Ignorado", + "ignoredButton4Text": "Botón 4 Ignorado", + "ignoredButtonDescriptionText": "(usa esto para prevenir que los botones de 'inicio' o 'sincronización' afecten la interfaz visual)", + "ignoredButtonText": "Botón de inicio", + "pressAnyAnalogTriggerText": "Pulsa cualquier gatillo analógico...", + "pressAnyButtonOrDpadText": "Pulsa cualquier botón o DPad...", + "pressAnyButtonText": "Pulsa cualquier botón...", + "pressLeftRightText": "Pulsa izquierda o derecha...", + "pressUpDownText": "Pulsa arriba o abajo...", + "runButton1Text": "Botón para Correr 1", + "runButton2Text": "Botón para Correr 2", + "runTrigger1Text": "Gatillo para Correr 1", + "runTrigger2Text": "Gatillo para Correr 2", + "runTriggerDescriptionText": "(Los gatillos analógicos te dejan correr a velocidades distintas)", + "secondHalfText": "Utiliza esta opción para configurar\nla segunda mitad de un control 2 en 1\nque se muestre como un solo control.", + "secondaryEnableText": "Habilitar", + "secondaryText": "Control Secundario", + "startButtonActivatesDefaultDescriptionText": "(desactívalo si tu botón de inicio es más bien un botón de 'menú')", + "startButtonActivatesDefaultText": "El botón de inicio activa la función por defecto", + "titleText": "Configurar Control", + "twoInOneSetupText": "Configuración de Controles 2 en 1", + "uiOnlyDescriptionText": "(evitar que este control se una a un juego)", + "uiOnlyText": "Limitar a Uso en Menú", + "unassignedButtonsRunText": "Todos los Botones sin Asignar Corren", + "unassignedButtonsRunTextScale": 0.8, + "unsetText": "", + "vrReorientButtonText": "Boton de Reorientación VR" + }, + "configKeyboardWindow": { + "configuringText": "Configurando ${DEVICE}", + "keyboard2NoteScale": 0.7, + "keyboard2NoteText": "Nota: la mayoría de teclados sólo pueden registrar algunas\npulsaciones a la vez, así que tener un segundo teclado puede\nfuncionar mejor que un teclado compartido por los 2 jugadores.\nTen en cuenta que todavía necesitas asignar teclas únicas a los\ndos jugadores incluso en ese caso." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Tamaño de \"Acciones\"", + "actionsText": "Acciones", + "buttonsText": "botones", + "dragControlsText": "", + "joystickText": "palanca", + "movementControlScaleText": "Tamaño de \"Movimiento\"", + "movementText": "Movimiento", + "resetText": "Reiniciar", + "swipeControlsHiddenText": "Ocultar Icono \"Deslizante\"", + "swipeInfoText": "Controles de estilo 'deslizante' toman un poco de practica, pero\nhacen que sea más fácil jugar sin mirar a los controles.", + "swipeText": "deslizar", + "titleText": "Configura la Pantalla Táctil", + "touchControlsScaleText": "Ampliador de controles táctiles" + }, + "configureItNowText": "Configurar ahora?", + "configureText": "Configurar", + "connectMobileDevicesWindow": { + "amazonText": "Appstore de Amazon", + "appStoreText": "App Store", + "bestResultsScale": 0.65, + "bestResultsText": "Para mejores resultados necesitas una red inalámbrica rápida. Puedes\nreducir el retraso wifi apagando otros dispositivos inalámbricos,\njugando cerca de tu router inalámbrico, y conectando el\njuego anfitrión directamente a la red a través del cable Ethernet.", + "explanationScale": 0.8, + "explanationText": "Para utilizar tus dispositivos móviles como controles, \ninstala la app \"${REMOTE_APP_NAME}\" en ellos. Conecta todos\ntus dispositivos con ${APP_NAME} a través de tu red Wi-fi, ¡es gratis!.", + "forAndroidText": "para Android:", + "forIOSText": "para iOS:", + "getItForText": "Consigue ${REMOTE_APP_NAME} para iOS en el App Store de Apple\no para Android en la Tienda Google Play o Appstore de Amazon", + "googlePlayText": "Google Play", + "titleText": "Utilizando Dispositivos como Controles:" + }, + "continuePurchaseText": "¿Continuar por ${PRICE}?", + "continueText": "Continuar", + "controlsText": "Controles", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Esto no aplica en los rankings de 'Todo el tiempo'.", + "activenessInfoText": "Este multiplicador aumenta en los días que juegas\ny disminuye cuando no juegas.", + "activityText": "Actividad", + "campaignText": "Campaña", + "challengesInfoText": "Gana premios por completar los mini-juegos.\n\nLos premios y la dificultad de los niveles incrementa\ncada vez que se completa y\ndecrece cuando uno expira o no se cumple.", + "challengesText": "Desafíos", + "currentBestText": "Mejor del Momento", + "customText": "Personalizado", + "entryFeeText": "Precio", + "forfeitConfirmText": "¿Renunciar a este desafío?", + "forfeitNotAllowedYetText": "Todavía no puedes abandonar este desafío.", + "forfeitText": "Abandonar", + "multipliersText": "Multiplicadores", + "nextChallengeText": "Siguiente Desafío", + "nextPlayText": "Siguiente Juego", + "ofTotalTimeText": "de ${TOTAL}", + "playNowText": "Juega Ahora", + "pointsText": "Puntos", + "powerRankingFinishedSeasonUnrankedText": "(temporada terminada sin clasificar)", + "powerRankingNotInTopText": "(fuera del top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} pts)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} de ${REMAINING} pts)", + "powerRankingText": "Clasificación de Poder", + "prizesText": "Premios", + "proMultInfoText": "Los jugadores con la mejora ${PRO}\nreciben una bonificación del ${PERCENT}% de puntos.", + "seeMoreText": "Ver más...", + "skipWaitText": "Saltar la Espera", + "timeRemainingText": "Tiempo Restante", + "titleText": "Modo cooperativo", + "toRankedText": "Para Clasificar", + "totalText": "total", + "tournamentInfoText": "Compite por puntajes altos con\notros jugadores en tu liga.\n\nLos premios los obtienen los jugadores\ncon mejor puntaje al acabarse el torneo.", + "welcome1Text": "Bienvenido/a a ${LEAGUE}. Puedes mejorar tu\nposición en la liga ganando estrellas, completando\nlogros, y ganando trofeos en desafíos.", + "welcome2Text": "También puedes ganar tickets desde varias actividades similares.\nLos tickets pueden ser usados para desbloquear nuevos personajes,\nmapas y mini juegos, entrar a torneos, y más.", + "yourPowerRankingText": "Tu Clasificación de Poder:" + }, + "copyConfirmText": "Copiado al portapapeles.", + "copyOfText": "${NAME} Copiar", + "copyText": "Copiar", + "createAPlayerProfileText": "¿Crear un perfil?", + "createEditPlayerText": "", + "createText": "Crear", + "creditsWindow": { + "additionalAudioArtIdeasText": "Audio Adicional, arte Inicial, e Ideas por ${NAME}", + "additionalMusicFromText": "Música adicional de ${NAME}", + "allMyFamilyText": "Mis amigos y mi familia que ayudaron con las pruebas", + "codingGraphicsAudioText": "Código, gráficas y audio por ${NAME}", + "languageTranslationsText": "Traducciones:", + "legalText": "Legal:", + "publicDomainMusicViaText": "Música de dominio público a través de ${NAME}", + "softwareBasedOnText": "Este software está basado parcialmente en el trabajo de ${NAME}", + "songCreditText": "${TITLE} interpretada por ${PERFORMER}\nCompuesta por ${COMPOSER}, arreglos por ${ARRANGER}, publicada por ${PUBLISHER},\nCortesía de ${SOURCE}", + "soundAndMusicText": "Sonido y música:", + "soundsText": "Sonidos (${SOURCE}):", + "specialThanksText": "Agradecimientos Especiales:", + "thanksEspeciallyToText": "Gracias especialmente a ${NAME}", + "titleText": "Créditos de ${APP_NAME}", + "whoeverInventedCoffeeText": "A quien haya inventado el café" + }, + "currentStandingText": "Tu puesto actual es #${RANK}", + "customizeText": "Personalizar...", + "deathsTallyText": "${COUNT} muertes", + "deathsText": "Muertes", + "debugText": "depurar", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Nota: Es recomendable poner Ajustes->Gráficos->Texturas en 'Alto' al probar esto.", + "runCPUBenchmarkText": "Ejecutar Punto de Referencia del CPU", + "runGPUBenchmarkText": "Ejecutar Punto de Referencia del GPU", + "runMediaReloadBenchmarkText": "Ejecutar Punto de Referencia del Media-Reload", + "runStressTestText": "Ejecutar prueba de resistencia", + "stressTestPlayerCountText": "Conteo de jugadores", + "stressTestPlaylistDescriptionText": "Prueba de Resistencia de Lista de Audio", + "stressTestPlaylistNameText": "Nombre de lista", + "stressTestPlaylistTypeText": "Tipo de lista", + "stressTestRoundDurationText": "Redondear duración", + "stressTestTitleText": "Prueba de resistencia", + "titleText": "Pruebas de Resistencia y Rendimiento.", + "totalReloadTimeText": "Tiempo total de recarga: ${TIME} (Ver log para detalles)", + "unlockCoopText": "Desbloquear niveles cooperativos" + }, + "defaultFreeForAllGameListNameText": "Pelea libre (predeterminado)", + "defaultGameListNameText": "Lista ${PLAYMODE} por Defecto", + "defaultNewFreeForAllGameListNameText": "Mis Matanzas Libres", + "defaultNewGameListNameText": "Mi lista ${PLAYMODE}", + "defaultNewTeamGameListNameText": "Mis Juegos en equipo", + "defaultTeamGameListNameText": "Juego en equipo (predeterminado)", + "deleteText": "Borrar", + "demoText": "Versión de prueba", + "denyText": "Rechazar", + "deprecatedText": "Obsoleto", + "desktopResText": "Resolución del escritorio", + "deviceAccountUpgradeText": "Advertencia:\nEstás conectado con una cuenta de dispositivo\n(${NAME}).\nLas cuentas de dispositivo serán removidas en una próxima actualización", + "difficultyEasyText": "Fácil", + "difficultyHardOnlyText": "Solo Modo Difícil", + "difficultyHardText": "Difícil", + "difficultyHardUnlockOnlyText": "Este nivel solo puede ser desbloqueado en modo difícil.\n¡¿¡¿¡Piensas tener lo que se necesita!?!?!", + "directBrowserToURLText": "Por favor abre la siguiente URL en tu navegador:", + "disableRemoteAppConnectionsText": "Desactivar conexiones remotas de aplicación", + "disableXInputDescriptionText": "Permite más de 4 controladores pero puede que no funcione bien.", + "disableXInputText": "Desactivar XInput", + "doneText": "Hecho", + "drawText": "Empate", + "duplicateText": "Duplicar", + "editGameListWindow": { + "addGameText": "Añadir\nJuego", + "cantOverwriteDefaultText": "¡No puedes sobrescribir la lista predeterminada!", + "cantSaveAlreadyExistsText": "¡Ya existe una lista con ese nombre!", + "cantSaveEmptyListText": "¡No puedes guardar una lista vacía!", + "editGameText": "Editar\nJuego", + "gameListText": "Lista de juegos", + "listNameText": "Nombre de Lista", + "nameText": "Nombre", + "removeGameText": "Remover\nJuego", + "saveText": "Guardar", + "titleText": "Editor de Listas" + }, + "editProfileWindow": { + "accountProfileInfoText": "Este perfil de jugador especial tiene un nombre\ny un icono basado en tu cuenta.\n\n${ICONS}\n\nCrea perfiles personalizados si quieres usar\ndiferentes nombres o iconos personalizados.", + "accountProfileText": "(perfil de cuenta)", + "availableText": "El nombre \"${NAME}\" está disponible.", + "changesNotAffectText": "Nota: los cambios no afectaran los personajes dentro del juego", + "characterText": "personaje", + "checkingAvailabilityText": "Revisando la disponibilidad para \"${NAME}\"...", + "colorText": "color", + "getMoreCharactersText": "Consigue Más Personajes...", + "getMoreIconsText": "Conseguir Más Iconos...", + "globalProfileInfoText": "Los perfiles globales tienen un nombre único\na nivel mundial. También tienen iconos personalizados.", + "globalProfileText": "(perfil global)", + "highlightText": "resalte", + "iconText": "icono", + "localProfileInfoText": "Los perfiles locales no tienen iconos y no hay garantía\nque los nombres sean únicos. Obtén un perfil global\npara reservar un nombre único y tengas un icono personalizado.", + "localProfileText": "(perfil local)", + "nameDescriptionText": "Nombre de Jugador", + "nameText": "Nombre", + "randomText": "aleatorio", + "titleEditText": "Editar Perfil", + "titleNewText": "Nuevo Perfil", + "unavailableText": "\"${NAME}\" no está disponible; intenta otro nombre.", + "upgradeProfileInfoText": "Esto reservará tu nombre de jugador a nivel mundial\ny podrás asignarle un icono personalizado.", + "upgradeToGlobalProfileText": "Actualizar a Perfil Global" + }, + "editProfilesAnyTimeText": "(edita tu perfil en cualquier momento bajo 'ajustes')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "No puedes eliminar la pista de audio predeterminada.", + "cantEditDefaultText": "No puedes editar la pista de audio predeterminada. Duplica o crea una nueva.", + "cantEditWhileConnectedOrInReplayText": "No puedes editar listas de audio mientras juegas con alguien o en repeticiones.", + "cantOverwriteDefaultText": "No puedes sobreescribir la pista de audio predeterminada", + "cantSaveAlreadyExistsText": "¡Ya existe una banda sonora con ese nombre!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Pista de Audio Predeterminada", + "deleteConfirmText": "Eliminar pista de audio:\n\n'${NAME}'?", + "deleteText": "Eliminar\nPista de Audio", + "duplicateText": "Duplicar\nPista de Audio", + "editSoundtrackText": "Editor de Pistas de Audio", + "editText": "Editar\nPista de Audio", + "fetchingITunesText": "buscando listas de reproducción de aplicaciones de música...", + "musicVolumeZeroWarning": "Advertencia: el volumen de la música está en 0", + "nameText": "Nombre", + "newSoundtrackNameText": "Mi Lista de Audio ${COUNT}", + "newSoundtrackText": "Nueva Pista de Audio:", + "newText": "Nueva\nPista de Audio", + "selectAPlaylistText": "Elige una Lista de Reproducción", + "selectASourceText": "Fuente de la Música", + "soundtrackText": "pista de audio", + "testText": "escuchar", + "titleText": "Pistas de Audio", + "useDefaultGameMusicText": "Música por Defecto", + "useITunesPlaylistText": "Lista de reproducción de la aplicación de música", + "useMusicFileText": "Archivo de Audio (MP3, etc)", + "useMusicFolderText": "Carpeta de Archivos de Audio" + }, + "editText": "Editar", + "endText": "Fin", + "enjoyText": "Diviértete!", + "epicDescriptionFilterText": "${DESCRIPTION} En cámara lenta épica.", + "epicNameFilterText": "${NAME} - Modo épico", + "errorAccessDeniedText": "acceso negado", + "errorDeviceTimeIncorrectText": "La hora actual de tu dispositivo está incorrecta por ${HOURS} horas.\nEsto podría causar problemas.\nPor favor verifica la hora y zona horaria en ajustes.", + "errorOutOfDiskSpaceText": "insuficiente espacio en disco", + "errorSecureConnectionFailText": "No se puede establecer una conexión segura en la nube; La red podría estar fallando", + "errorText": "Error", + "errorUnknownText": "error desconocido", + "exitGameText": "¿Salir de ${APP_NAME}?", + "exportSuccessText": "'${NAME}' exportado.", + "externalStorageText": "Almacenamiento Externo", + "failText": "Fallaste", + "fatalErrorText": "Uh oh, ¡algo está mal por aquí!\nPor favor intenta reinstalar la app o\ncontacta a ${EMAIL} para ayuda.", + "fileSelectorWindow": { + "titleFileFolderText": "Elige un Archivo o Carpeta", + "titleFileText": "Elige un Archivo", + "titleFolderText": "Elige una Carpeta", + "useThisFolderButtonText": "Usar Esta Carpeta" + }, + "filterText": "Filtro", + "finalScoreText": "Puntaje Final", + "finalScoresText": "Puntajes Finales", + "finalTimeText": "Tiempo final", + "finishingInstallText": "Instalación casi lista; espera un momento...", + "fireTVRemoteWarningText": "* Para una mejor experiencia, \nutiliza controles o instala la\napp '${REMOTE_APP_NAME}' en tus\ndispositivos móviles.", + "firstToFinalText": "Primero de ${COUNT} Final", + "firstToSeriesText": "Primero de ${COUNT} Serie", + "fiveKillText": "¡¡¡COMBO QUÍNTUPLE!!!", + "flawlessWaveText": "¡Horda perfecta!", + "fourKillText": "¡¡¡COMBO CUÁDRUPLE!!!", + "freeForAllText": "Pelea libre", + "friendScoresUnavailableText": "Puntaje no disponible.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Líderes del juego ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "No puedes eliminar la lista predeterminada.", + "cantEditDefaultText": "¡No puedes editar la lista predeterminada! Duplicala o crea una nueva.", + "cantShareDefaultText": "No puedes compartir la lista de reproducción por defecto", + "deleteConfirmText": "¿Borrar \"${LIST}\"?", + "deleteText": "Borrar\nLista", + "duplicateText": "Duplicar\nLista", + "editText": "Editar\nLista", + "gameListText": "Lista de juego", + "newText": "Nueva\nLista", + "showTutorialText": "Ver Tutorial", + "shuffleGameOrderText": "Orden de juego al azar", + "titleText": "Personaliza listas de ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "Agrega juego" + }, + "gamepadDetectedText": "1 control detectado.", + "gamepadsDetectedText": "${COUNT} controles detectados.", + "gamesToText": "${WINCOUNT} juegos a ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Recuerda: cualquier dispositivo en la fiesta puede\ntener más de un jugador si tienen controles suficientes.", + "aboutDescriptionText": "Usa estas pestañas para crear una fiesta.\n\nLas fiestas te permiten jugar y competir con\ntus amigos con sus propios dispositivos.\n\nUsa el botón ${PARTY} en la parte superior\nderecha para chatear e interactuar con tu fiesta.\n(En el control, presiona ${BUTTON} mientras estés en el menú)", + "aboutText": "Acerca de", + "addressFetchErrorText": "", + "appInviteInfoText": "Invita amigos a probar BombSquad y recibirán\n${COUNT} ticketes gratis. Tu obtendrás\n${YOU_COUNT} por cada amigo que acepte.", + "appInviteMessageText": "${NAME} te envió ${COUNT} boletos en ${APP_NAME}", + "appInviteSendACodeText": "Enviales un código", + "appInviteTitleText": "Invitación de ${APP_NAME}", + "bluetoothAndroidSupportText": "(Funciona con cualquier dispositivo Android con Bluetooth)", + "bluetoothDescriptionText": "Crea/únete a una fiesta vía Bluetooth:", + "bluetoothHostText": "Crea vía Bluetooth", + "bluetoothJoinText": "Únete vía Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "revisando...", + "copyCodeConfirmText": "Se ha copiado en el portapapeles.", + "copyCodeText": "Copiar", + "dedicatedServerInfoText": "Para mejores resultados, crea un servidor dedicado. Visita bombsquadgame.com/server para aprender cómo hacerlo", + "disconnectClientsText": "Esto desconectará a ${COUNT} jugador(es) de\ntu fiesta. ¿Estás seguro?", + "earnTicketsForRecommendingAmountText": "Tus amigos recibirán ${COUNT} boletos si prueban el juego\n(Y recibirás ${YOU_COUNT} boletos por cada amigo que pruebe el juego)", + "earnTicketsForRecommendingText": "Comparte el juego\na cambio de boletos gratis...", + "emailItText": "Enviar correo", + "favoritesSaveText": "Guardar como favorito", + "favoritesText": "Favoritos", + "freeCloudServerAvailableMinutesText": "El siguiente server estara disponible en ${MINUTES} minutos", + "freeCloudServerAvailableNowText": "Servidor gratuito disponible!", + "freeCloudServerNotAvailableText": "No hay servidores gratis disponibles ahora", + "friendHasSentPromoCodeText": "Recibiste ${COUNT} boletos ${APP_NAME} de ${NAME}", + "friendPromoCodeAwardText": "Recibirás ${COUNT} boletos cada vez que lo uses.", + "friendPromoCodeExpireText": "El código expirará en ${EXPIRE_HOURS} horas y solo lo podrán usar jugadores nuevos.", + "friendPromoCodeInstructionsText": "Para usarlo, abre ${APP_NAME} y ve a \"Ajustes-> Avanzado-> Ingresar código\"\nVisita bombsquadgame.com para enlaces de descarga de todas las plataformas disponibles.", + "friendPromoCodeRedeemLongText": "Se puede canjear por ${COUNT} boletos gratis hasta ${MAX_USES} personas.", + "friendPromoCodeRedeemShortText": "Puede ser canjeado por ${COUNT} boletos en el juego.", + "friendPromoCodeWhereToEnterText": "(en \"Configuración-> Avanzado-> Introducir código\")", + "getFriendInviteCodeText": "Genera código para un amigo", + "googlePlayDescriptionText": "Invita a jugadores de Google Play a tu fiesta:", + "googlePlayInviteText": "Invitar", + "googlePlayReInviteText": "Hay ${COUNT} jugadores de Google Play en tu fiesta\nque se desconectarán si creas una nueva invitación.\nInclúyelos en la nueva invitación para tenerlos de vuelta.", + "googlePlaySeeInvitesText": "Ver invitaciones", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Versión Android / Google Play)", + "hostPublicPartyDescriptionText": "Crear una Fiesta Pública", + "hostingUnavailableText": "Alojamiento No Disponible", + "inDevelopmentWarningText": "Nota:\n\nJugar en Red es una función todavía en desarrollo.\nPor ahora, es altamente recomendado que todos\nlos jugadores estén en la misma red Wi-Fi", + "internetText": "Internet", + "inviteAFriendText": "¿Tus amigos no tienen el juego? Invítalos a\nprobarlo y recibirán ${COUNT} boletos gratis.", + "inviteFriendsText": "Invita a amigos", + "joinPublicPartyDescriptionText": "Entrar en una fiesta publica", + "localNetworkDescriptionText": "Unirse a una fiesta en tu red", + "localNetworkText": "Red Local", + "makePartyPrivateText": "Crea mi Fiesta Privada", + "makePartyPublicText": "Crea mi Fiesta Pública", + "manualAddressText": "Dirección", + "manualConnectText": "Conectar", + "manualDescriptionText": "Únete a una fiesta usando la dirección IP:", + "manualJoinSectionText": "Unirse por dirección", + "manualJoinableFromInternetText": "¿Se te pueden unir vía Internet?", + "manualJoinableNoWithAsteriskText": "NO*", + "manualJoinableYesText": "SI", + "manualRouterForwardingText": "*para arreglarlo, configura en tu router que redireccione el puerto UDP ${PORT} a tu dirección local", + "manualText": "Manual", + "manualYourAddressFromInternetText": "Tu dirección desde internet:", + "manualYourLocalAddressText": "Tu dirección local:", + "nearbyText": "Cerca", + "noConnectionText": "", + "otherVersionsText": "(Otras versiones)", + "partyCodeText": "Código de fiesta", + "partyInviteAcceptText": "Aceptar", + "partyInviteDeclineText": "Denegar", + "partyInviteGooglePlayExtraText": "(Busca la pestaña 'Google Play' en la ventana 'Reúne'", + "partyInviteIgnoreText": "Ignorar", + "partyInviteText": "${NAME} te ha invitado\na unirse a su fiesta!", + "partyNameText": "Nombre de la fiesta", + "partyServerRunningText": "Tu servidor de fiesta está en línea", + "partySizeText": "Tamaño de la fiesta", + "partyStatusCheckingText": "Comprobando estado...", + "partyStatusJoinableText": "ya se pueden conectar a tu fiesta por internet", + "partyStatusNoConnectionText": "Incapaz de conectar al servidor", + "partyStatusNotJoinableText": "No se van a poder conectar a tu fiesta por internet", + "partyStatusNotPublicText": "Tu fiesta no es publica", + "pingText": "Ping", + "portText": "Puerto", + "privatePartyCloudDescriptionText": "Fiestas privadas se ejecutan en la nube; no requiere configuración del router.", + "privatePartyHostText": "Hacer una Fiesta privada", + "privatePartyJoinText": "Únete a una fiesta privada", + "privateText": "Privado", + "publicHostRouterConfigText": "Está opción requiere una configuración de puerto en tu router para una opción más fácil crea una fiesta privada", + "publicText": "Publico", + "requestingAPromoCodeText": "Pidiendo código...", + "sendDirectInvitesText": "Enviar directamente la invitación", + "shareThisCodeWithFriendsText": "Comparte este código con tus amigos:", + "showMyAddressText": "Mostrar mi dirección", + "startHostingPaidText": "Anfitrión Ahora Por ${COST}", + "startHostingText": "Anfitrión", + "startStopHostingMinutesText": "Puede iniciar y detener el alojamiento de forma gratuita durante los próximos ${MINUTES} minutos.", + "stopHostingText": "Dejar de alojar", + "titleText": "Reúne", + "wifiDirectDescriptionBottomText": "Si todo los dispositivos disponen de 'Wi-fi Directo', deberían poder utilizarlo para\nencontrar y conectarse entre ellos. Cuando todos estén conectados, puedes formar \nfiestas, usando la pestaña 'Red Local', como si estuvieran en la misma red Wi-fi.\n\nPara mejores resultados, el host de Wi-fi Directo también debe de ser el host de la fiesta en ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Directo puede ser utilizado para conectar dispositivos Android sin\ntener que utilizar una red Wi-Fi. Esto funciona mejor de Android 4.2 o mas nuevo.\n\nPara utilizarlo, abre los ajustes de Wi-Fi y busca 'Wi-Fi Directo' en el menú.", + "wifiDirectOpenWiFiSettingsText": "Abrir Ajustes Wi-Fi", + "wifiDirectText": "Wi-Fi Directo", + "worksBetweenAllPlatformsText": "(funciona con todas las plataformas)", + "worksWithGooglePlayDevicesText": "(funciona con dispositivos que corran la versión Google Play (Android) del juego)", + "youHaveBeenSentAPromoCodeText": "Has enviado un código de ${APP_NAME}:" + }, + "getCoinsWindow": { + "coinDoublerText": "Duplicador de monedas", + "coinsText": "${COUNT} monedas", + "freeCoinsText": "Monedas gratis", + "restorePurchasesText": "Reestablecer compras", + "titleText": "Obtener monedas" + }, + "getTicketsWindow": { + "freeText": "¡GRATIS!", + "freeTicketsText": "Tickets Gratis", + "inProgressText": "Ya hay una transacción en progreso; por favor inténtalo mas tarde.", + "purchasesRestoredText": "Compras Restauradas.", + "receivedTicketsText": "¡${COUNT} boletos recibidos!", + "restorePurchasesText": "Restaurar Compras", + "ticketDoublerText": "Duplicador de Tiquetes", + "ticketPack1Text": "Paquete de Boletos Pequeño", + "ticketPack2Text": "Paquete de Boletos Mediano", + "ticketPack3Text": "Paquete de Boletos Grande", + "ticketPack4Text": "Paquete de Boletos Jumbo", + "ticketPack5Text": "Paquete de Boletos Mamut", + "ticketPack6Text": "Paquete de Boletos Supremo", + "ticketsFromASponsorText": "Obtén ${COUNT} boletos\nde un patrocinador", + "ticketsText": "${COUNT} Boletos", + "titleText": "Obtén Boletos", + "unavailableLinkAccountText": "Lo sentimos, las compras no están disponibles en esta plataforma.\nComo una solución, puedes enlazar esta cuenta a otra\nplataforma y hacer tus compras desde ahí.", + "unavailableTemporarilyText": "No disponible por el momento; por favor inténtalo más tarde.", + "unavailableText": "Lo sentimos, no se encuentra disponible.", + "versionTooOldText": "Lo sentimos, esta versión está demasiado atrasada; por favor actualiza el juego.", + "youHaveShortText": "tienes ${COUNT}", + "youHaveText": "tienes ${COUNT} boletos" + }, + "googleMultiplayerDiscontinuedText": "Lo siento, Google's multijugador servicio ya no esta mas disponible.\nEstoy trabajando en un reemplazo lo mas rapido posible.\nHasta entonces, por favor intente con otro metodo de conexión.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Las compras de Google Play no están disponibles.\nEs posible que deba actualizar la aplicación de su tienda.", + "googlePlayServicesNotAvailableText": "Servicios de Google Play no disponibles.\nAlgunas funciones de la aplicación pueden estar deshabilitadas.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Siempre", + "fullScreenCmdText": "Pantalla completa (Cmd-F)", + "fullScreenCtrlText": "Pantalla completa (Ctrl-F)", + "gammaText": "Gamma", + "highText": "Alta", + "higherText": "Superior", + "lowText": "Baja", + "mediumText": "Mediana", + "neverText": "Nunca", + "resolutionText": "Resolución", + "showFPSText": "Mostrar FPS", + "texturesText": "Texturas", + "titleText": "Gráficos", + "tvBorderText": "Marco de TV", + "verticalSyncText": "Sincronización vertical", + "visualsText": "Visuales" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nMas fuerte que los golpes, pero puede\nresultar en auto-lesiones bastante graves.\nPara mejores resultados, tírala hacia tus\noponentes antes de que explote.", + "bombInfoTextScale": 0.57, + "canHelpText": "${APP_NAME} te puede ayudar.", + "controllersInfoText": "Puedes jugar ${APP_NAME} con tus amigos en una red, o todos pueden\njugar en el mismo dispositivo si se tienen varios controles.\n${APP_NAME} soporta una gran variedad de ellos; incluso puedes utilizar\ntus dispositivos móviles como controles instalando la app '${REMOTE_APP_NAME}'.\nVe a 'Ajustes-> Controles' para más información.", + "controllersInfoTextFantasia": "Un jugador puede usar el mando a distancia para jugar, pero\nse recomienda usar gamepads. También puedes usar dispositivos\niOS o Android como controles con la app \"BombSquad Remote\".\nRevisa la sección \"Controles\" en los Ajustes para más información.", + "controllersInfoTextMac": "Uno o dos jugadores pueden usar el teclado, pero BombSquad es mejor\ncon controles. BombSquad puede usar controles USB, controles de PS3,\ncontroles de Xbox 360, controles Wii y dispositivos iOS/Android para\ncontrolar los personajes. Espero que tengas algunos de ellos a la mano. \nConsulta 'Controles' bajo 'Ajustes' para más información.", + "controllersInfoTextOuya": "Puedes usar controles OUYA, controles de PS3, controles de Xbox\n360, y muchos de otros controles USB y Bluetooth con BombSquad.\nPuedes usar también dispositivos iOS/Android como controles con la aplicación \n'BombSquad Remote'. Consulta 'Controles' bajo 'Ajustes' para más información.", + "controllersInfoTextRemoteOnly": "Tu puedes jugar ${APP_NAME} con tus amigos en la red, o pueden\njugar todos en el mismo dispositivo usando los teléfonos\ncomo controles libres con la aplicación '${REMOTE_APP_NAME}'", + "controllersText": "Controles", + "controllersTextScale": 0.67, + "controlsSubtitleText": "Tu personaje de ${APP_NAME} tiene algunas acciones básicas:", + "controlsSubtitleTextScale": 0.7, + "controlsText": "Controles", + "controlsTextScale": 1.4, + "devicesInfoText": "La version VR de ${APP_NAME} se puede jugar en red con la versión \nregular, así que saca tus celulares, tablets y PCs extra y que \nempieze el juego. Es muy útil conectar un dispositivo con la versión\nregular a uno con la versión VR para que todos los que esten fuera\npuedan ver la acción.", + "devicesText": "Dispositivos", + "friendsGoodText": "Cuantos más, mejor. ${APP_NAME} es más divertido con muchos \namigos y soporta hasta 8 a la vez, lo que nos lleva a:", + "friendsGoodTextScale": 0.62, + "friendsText": "Amigos", + "friendsTextScale": 0.67, + "jumpInfoText": "- Salto -\nSalta para cruzar pequeños\nespacios, tirar cosas más lejos,\ny para expresar alegría.", + "jumpInfoTextScale": 0.6, + "orPunchingSomethingText": "O golpear algo, tirarlo por un precipicio, y explotarlo en plena caída con una bomba pegajosa.", + "orPunchingSomethingTextScale": 0.51, + "pickUpInfoText": "- Levanta -\nAlza banderas, enemigos, o cualquier\notra cosa no atornillada al suelo.\nPulsa de nuevo para lanzar.", + "pickUpInfoTextScale": 0.6, + "powerupBombDescriptionText": "Te permite sacar tres bombas\nen una fila en lugar de solo una.", + "powerupBombNameText": "Bombas Triples", + "powerupCurseDescriptionText": "Probablemente quieras evitar estos.\n ...¿o quizás tú?", + "powerupCurseNameText": "Maldición", + "powerupHealthDescriptionText": "Te restaura a la salud completa.\nNunca lo habrías adivinado.", + "powerupHealthNameText": "Botiquín", + "powerupIceBombsDescriptionText": "Más débiles que las bombas normales\npero dejan a tus enemigos congelados\ny particularmente frágiles.", + "powerupIceBombsNameText": "Bombas de Hielo", + "powerupImpactBombsDescriptionText": "Levemente más débiles que las bombas\nregulares, pero explotan al impacto.", + "powerupImpactBombsNameText": "Bombas de Gatillo", + "powerupLandMinesDescriptionText": "Estas vienen en grupos de 3;\nSon buenas para defensa territorial\no para detener enemigos veloces.", + "powerupLandMinesNameText": "Minas Terrestres", + "powerupPunchDescriptionText": "Hacen que tus golpes sean más duros,\nmás rápidos, mejores, y más fuertes.", + "powerupPunchNameText": "Guantes de Boxeo", + "powerupShieldDescriptionText": "Absorbe un poco de daño\npara que no tengas que hacerlo.", + "powerupShieldNameText": "Escudo de Energía", + "powerupStickyBombsDescriptionText": "Se adhieren a cualquier cosa.\nProducen hilaridad.", + "powerupStickyBombsNameText": "Bombas Pegajosas", + "powerupsSubtitleText": "Por supuesto, ningún juego está completo sin potenciadores:", + "powerupsSubtitleTextScale": 0.8, + "powerupsText": "Potenciadores", + "powerupsTextScale": 1.4, + "punchInfoText": "- Golpe -\nEntre más rápido te muevas más\nimpacto causan tus golpes, así que\ncorre, salta y da vueltas como loco.", + "punchInfoTextScale": 0.6, + "runInfoText": "- Correr -\nSostén CUALQUIER botón para correr. Los botones gatillos o traseros funcionan bien si los tienes.\nCorrer te hace llegar más rápido pero es más difícil girar, así que ten cuidado con los barrancos.", + "runInfoTextScale": 0.6, + "someDaysText": "Hay días cuando sientes ganas de romper algo. O explotarlo.", + "someDaysTextScale": 0.66, + "titleText": "Ayuda ${APP_NAME}", + "toGetTheMostText": "Para sacar el máximo partido a este juego, necesitas:", + "toGetTheMostTextScale": 1.0, + "welcomeText": "¡Bienvenido a ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} navega los menús como todo un pro -", + "importPlaylistCodeInstructionsText": "Usa el siguiente código para importar esta lista de reproducción en otra parte", + "importPlaylistSuccessText": "Lista de reproducción '${NAME}' importada ${TYPE}", + "importText": "Importar", + "importingText": "Importando...", + "inGameClippedNameText": "en el juego será\n\"${NAME}\"", + "installDiskSpaceErrorText": "ERROR: Incapaz de completar la instalación\nPuede que te hayas quedado sin espacio.\nLibera un poco de tu espacio e intenta de nuevo.", + "internal": { + "arrowsToExitListText": "pulsa ${LEFT} o ${RIGHT} para salir de la lista", + "buttonText": "botón", + "cantKickHostError": "No puedes expulsar al host", + "chatBlockedText": "A ${NAME} le hemos bloqueado el chat por ${TIME} segundos.", + "connectedToGameText": "'${NAME}' se unió", + "connectedToPartyText": "¡Unido a la fiesta de ${NAME}!", + "connectingToPartyText": "Conectando...", + "connectionFailedHostAlreadyInPartyText": "Conexión fallida; Host esta en otra fiesta.", + "connectionFailedPartyFullText": "Conexión fallida; la fiesta está llena.", + "connectionFailedText": "Conexión fallida.", + "connectionFailedVersionMismatchText": "Conexión fallida; Host corre una versión diferente del juego.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", + "connectionRejectedText": "Conexión rechazada.", + "controllerConnectedText": "${CONTROLLER} conectado.", + "controllerDetectedText": "1 control detectado.", + "controllerDisconnectedText": "${CONTROLLER} desconectado.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} desconectado. Intenta conectarlo de nuevo.", + "controllerForMenusOnlyText": "Este control no puede ser usado para jugar; solo para navegar por menus.", + "controllerReconnectedText": "${CONTROLLER} reconectado.", + "controllersConnectedText": "${COUNT} controles conectados.", + "controllersDetectedText": "${COUNT} controles detectados.", + "controllersDisconnectedText": "${COUNT} controles desconectados.", + "corruptFileText": "Archivos corruptos detectados. Por favor reinstala el juego o contacta ${EMAIL}", + "errorPlayingMusicText": "Error al reproducir música: ${MUSIC}", + "errorResettingAchievementsText": "No se pudieron reiniciar los logros; por favor inténtalo de nuevo.", + "hasMenuControlText": "${NAME} Tiene control del menú.", + "incompatibleNewerVersionHostText": "El host está corriendo una versión nueva del juego.\nActualiza a la última versión y vuelve a intentarlo.", + "incompatibleVersionHostText": "Host corre una versión diferente del juego; imposible conectar.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", + "incompatibleVersionPlayerText": "${NAME} está corriendo una versión diferente del juego y no se ha podido conectar.\nAsegúrese de que ambos están actualizados y vuelva a intentar.", + "invalidAddressErrorText": "Error: Dirección inválida.", + "invalidNameErrorText": "Error: Nombre invalido", + "invalidPortErrorText": "Error: Puerto inválido.", + "invitationSentText": "Invitación enviada.", + "invitationsSentText": "${COUNT} invitaciones enviadas.", + "joinedPartyInstructionsText": "Alguien se ha unido a tu fiesta\nVe a 'Jugar' para iniciar el juego", + "keyboardText": "Teclado", + "kickIdlePlayersKickedText": "Sacando a ${NAME} por no mostrar movimiento.", + "kickIdlePlayersWarning1Text": "${NAME} será sacado en ${COUNT} segundos si no presenta movimiento.", + "kickIdlePlayersWarning2Text": "(puedes apagar esto en Ajustes -> Avanzado)", + "leftGameText": "'${NAME}' salió", + "leftPartyText": "Dejó la fiesta de ${NAME}.", + "noMusicFilesInFolderText": "La carpeta no contiene archivos de audio.", + "playerJoinedPartyText": "¡${NAME} se unió a la fiesta!", + "playerLeftPartyText": "${NAME} se fue de la fiesta.", + "rejectingInviteAlreadyInPartyText": "Rechazando invitación (Ya en una fiesta).", + "serverRestartingText": "El servidor se está reiniciando. Conéctese en un momento...", + "serverShuttingDownText": "El servidor está fuera de servicio...", + "signInErrorText": "Error iniciando sesión.", + "signInNoConnectionText": "Imposible iniciar sesión (¿No hay conexión a internet?)", + "teamNameText": "Equipo ${NAME}", + "telnetAccessDeniedText": "ERROR: El usuario no concedió acceso telnet.", + "timeOutText": "(tiempo fuera en ${TIME} segundos)", + "touchScreenJoinWarningText": "Te uniste con la pantalla táctil.\nSi este fue un error, presiona 'Menú->Dejar juego' con ella.", + "touchScreenText": "Pantalla táctil", + "trialText": "prueba", + "unableToResolveHostText": "Error: no se ha podido resolver el host", + "unavailableNoConnectionText": "No disponible por el momento (¿No tienes conexión a internet?)", + "vrOrientationResetCardboardText": "Usa esto para reiniciarr la orientación del VR.\nPara jugar el juego necesitarás un control externo.", + "vrOrientationResetText": "Orientación VR reseteada.", + "willTimeOutText": "(caducará si está inactivo)" + }, + "jumpBoldText": "SALTA", + "jumpText": "Brinca", + "keepText": "Mantener", + "keepTheseSettingsText": "¿Mantener estos ajustes?", + "keyboardChangeInstructionsText": "Presiona dos veces el espacio para cambiar los teclados.", + "keyboardNoOthersAvailableText": "No hay más teclados disponibles.", + "keyboardSwitchText": "Cambiando teclado a \"${NAME}\".", + "kickOccurredText": "${NAME} ha sido expulsado.", + "kickQuestionText": "¿Expulsar a ${NAME}?", + "kickText": "Expulsar", + "kickVoteCantKickAdminsText": "El administrador no puede ser expulsado", + "kickVoteCantKickSelfText": "No puedes expulsarte a ti mismo", + "kickVoteFailedNotEnoughVotersText": "No hay suficientes jugadores para votar.", + "kickVoteFailedText": "Votación de expulsión fallida", + "kickVoteStartedText": "Han iniciado una votación para expulsar a '${NAME}'.", + "kickVoteText": "Vota para expulsar", + "kickVotingDisabledText": "El voto para expulsar no está disponible", + "kickWithChatText": "Escribe ${YES} en el chat para \"Si\" y ${NO} para \"No\".", + "killsTallyText": "eliminó ${COUNT}", + "killsText": "Víctimas", + "kioskWindow": { + "easyText": "Fácil", + "epicModeText": "Modo Épico", + "fullMenuText": "Menú Completo", + "hardText": "Difícil", + "mediumText": "Medio", + "singlePlayerExamplesText": "Ejemplos 1 Jugador / Varios jugadores", + "versusExamplesText": "Ejemplos Versus" + }, + "languageSetText": "El lenguaje es ahora \"${LANGUAGE}\".", + "lapNumberText": "Vuelta ${CURRENT}/${TOTAL}", + "lastGamesText": "(últimos ${COUNT} juegos)", + "leaderboardsText": "Clasificaciones", + "league": { + "allTimeText": "De todo el tiempo", + "currentSeasonText": "Temporada en curso (${NUMBER})", + "leagueFullText": "Liga ${NAME}", + "leagueRankText": "Liga Rank", + "leagueText": "Liga", + "rankInLeagueText": "#${RANK}, ${NAME} Liga${SUFFIX}", + "seasonEndedDaysAgoText": "La temporada terminó hace ${NUMBER} día(s).", + "seasonEndsDaysText": "La temporada termina en ${NUMBER} día(s).", + "seasonEndsHoursText": "La temporada termina en ${NUMBER} hora(s).", + "seasonEndsMinutesText": "La temporada termina en ${NUMBER} minuto(s).", + "seasonText": "Temporada ${NUMBER}", + "tournamentLeagueText": "Debes alcanzar la liga ${NAME} para entrar a este torneo.", + "trophyCountsResetText": "El conteo de trofeos se reiniciará la próxima temporada." + }, + "levelBestScoresText": "Mejores puntajes en ${LEVEL}", + "levelBestTimesText": "Mejores tiempos en ${LEVEL}", + "levelFastestTimesText": "Mejores tiempos en ${LEVEL}", + "levelHighestScoresText": "Puntajes más altos en ${LEVEL}", + "levelIsLockedText": "${LEVEL} está bloqueado.", + "levelMustBeCompletedFirstText": "${LEVEL} debe completarse primero.", + "levelText": "Nivel ${NUMBER}", + "levelUnlockedText": "¡Nivel desbloqueado!", + "livesBonusText": "Bono de vidas", + "loadingText": "cargando", + "loadingTryAgainText": "Cargando; vuelve a intentarlo en un momento...", + "macControllerSubsystemBothText": "Ambos (no recomendado)", + "macControllerSubsystemClassicText": "Clásico", + "macControllerSubsystemDescriptionText": "(Intenta cambiar esto si tus controladores no están funcionando)", + "macControllerSubsystemMFiNoteText": "Control hecho para iOS/Mac detectado;\nTal vez quieras activar esto en Configuracion -> Controles", + "macControllerSubsystemMFiText": "Creado-para-iOS/Mac", + "macControllerSubsystemTitleText": "Soporte de controladores", + "mainMenu": { + "creditsText": "Créditos", + "demoMenuText": "Menú Demo", + "endGameText": "Salir del juego", + "endTestText": "Prueba final", + "exitGameText": "Salir del juego", + "exitToMenuText": "¿Salir al menú?", + "howToPlayText": "Cómo jugar", + "justPlayerText": "(Solo ${NAME})", + "leaveGameText": "Dejar Juego", + "leavePartyConfirmText": "¿Seguro que deseas dejar la fiesta?", + "leavePartyText": "Dejar Fiesta", + "leaveText": "Abandonar", + "quitText": "Salir", + "resumeText": "Reanudar", + "settingsText": "Ajustes" + }, + "makeItSoText": "Que así sea", + "mapSelectGetMoreMapsText": "Conseguir más Mapas...", + "mapSelectText": "Seleccionar…", + "mapSelectTitleText": "Pistas: ${GAME}", + "mapText": "Pista", + "maxConnectionsText": "Conexiones máximas", + "maxPartySizeText": "Capacidad máxima de la fiesta", + "maxPlayersText": "Jugadores máximos", + "merchText": "Mercado!", + "modeArcadeText": "Modo Arcade", + "modeClassicText": "Modo Clásico", + "modeDemoText": "Modo De Demostración", + "mostValuablePlayerText": "Jugador más Valorado", + "mostViolatedPlayerText": "Jugador más Violado", + "mostViolentPlayerText": "Jugador más Matador", + "moveText": "Mover", + "multiKillText": "¡¡¡${COUNT}-COMBO!!!", + "multiPlayerCountText": "${COUNT} jugadores", + "mustInviteFriendsText": "Nota: debes invitar a tus amigos en\nel panel \"${GATHER}\" o conectar\ncontroles para jugar multijugador.", + "nameBetrayedText": "${NAME} traicionó a ${VICTIM}.", + "nameDiedText": "${NAME} ha muerto.", + "nameKilledText": "${NAME} mató a ${VICTIM}.", + "nameNotEmptyText": "¡El nombre no puede quedar vacío!", + "nameScoresText": "¡${NAME} anotó!", + "nameSuicideKidFriendlyText": "${NAME} murió por accidente.", + "nameSuicideText": "${NAME} se a suicidado.", + "nameText": "Nombre", + "nativeText": "Nativo", + "newPersonalBestText": "¡Nuevo récord personal!", + "newTestBuildAvailableText": "¡Una nueva build de prueba está disponible! (${VERSION} build ${BUILD}).\nObténla en ${ADDRESS}", + "newText": "Nuevo", + "newVersionAvailableText": "¡Una nueva version de ${APP_NAME} está disponible! (${VERSION})", + "nextAchievementsText": "Siguientes Logros:", + "nextLevelText": "Próximo nivel", + "noAchievementsRemainingText": "- ninguno", + "noContinuesText": "(sin re-intentos)", + "noExternalStorageErrorText": "No se encontraron almacenamientos externos en este dispositivo", + "noGameCircleText": "Error: No has autenticado con GameCircle", + "noJoinCoopMidwayText": "Jugadores no pueden unirse en mitad de un juego.", + "noProfilesErrorText": "No haz creado ningún perfil, por lo que tendrás que llamarte '${NAME}'.\nVe a Ajustes>Perfiles para que te hagas un perfil.", + "noScoresYetText": "Sin puntuaciones aún.", + "noThanksText": "No gracias", + "noTournamentsInTestBuildText": "ADVERTENCIA: los puntajes de los torneos en esta versión de prueba serán ignorados.", + "noValidMapsErrorText": "No hay pistas para este tipo de juego.", + "notEnoughPlayersRemainingText": "Cantidad necesaria de jugadores no coincide; inicia un juego nuevo.", + "notEnoughPlayersText": "¡Necesitas por lo menos ${COUNT} jugadores para comenzar!", + "notNowText": "Ahora no", + "notSignedInErrorText": "Necesitas registrarte para hacer esto.", + "notSignedInGooglePlayErrorText": "Debes iniciar sesión con Google Play para hacer esto.", + "notSignedInText": "No registrado", + "notUsingAccountText": "Nota: ignorando su cuenta de ${SERVICE}.\nVaya a 'Cuenta -> Ingresar con ${SERVICE}' si quieres usarla", + "nothingIsSelectedErrorText": "¡No hay nada seleccionado!", + "numberText": "#${NUMBER}", + "offText": "Apagado", + "okText": "Aceptar", + "onText": "Encendido", + "oneMomentText": "Un momento...", + "onslaughtRespawnText": "${PLAYER} reaparecerá en la horda ${WAVE}", + "orText": "${A} o ${B}", + "otherText": "Otros...", + "outOfText": "(#${RANK} de ${ALL})", + "ownFlagAtYourBaseWarning": "Tu misma bandera debe estar\nen su lugar para anotar!", + "packageModsEnabledErrorText": "Juegos de red no están permitidos mientras paquetes modificadores estén habilitados (ver Ajustes->Avanzado)", + "partyWindow": { + "chatMessageText": "Mensaje del Chat", + "emptyText": "Tu fiesta está vacía", + "hostText": "(host)", + "sendText": "Enviar", + "titleText": "Tu Fiesta" + }, + "pausedByHostText": "(pausado por host)", + "perfectWaveText": "¡Horda perfecta!", + "pickUpBoldText": "LEVANTAR", + "pickUpText": "Levantar", + "playModes": { + "coopText": "Cooperativo", + "freeForAllText": "Todos contra Todos", + "multiTeamText": "Múltiples Equipos", + "singlePlayerCoopText": "Solo un Jugador / Co-op", + "teamsText": "Equipos" + }, + "playText": "Jugar", + "playWindow": { + "coopText": "Cooperativo", + "freeForAllText": "Pelea libre", + "oneToFourPlayersText": "1-4 jugadores", + "teamsText": "Equipos", + "titleText": "Jugar", + "twoToEightPlayersText": "2-8 jugadores" + }, + "playerCountAbbreviatedText": "${COUNT}j", + "playerDelayedJoinText": "${PLAYER} entrará al comienzo de la siguiente ronda.", + "playerInfoText": "Información del Jugador", + "playerLeftText": "${PLAYER} abandonó la partida", + "playerLimitReachedText": "Límite de ${COUNT} jugadores alcanzado; no se permiten más.", + "playerLimitReachedUnlockProText": "Mejora a \"${PRO}\" en la tienda para jugar con más de ${COUNT} jugadores.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "No puedes borrar el perfil de tu cuenta.", + "deleteButtonText": "Borrar\nPerfil", + "deleteConfirmText": "Borrar '${PROFILE}'?", + "editButtonText": "Editar\nPerfil", + "explanationText": "(nombres de jugadores personalizados y apariencias para esta cuenta)", + "newButtonText": "Nuevo\nPerfil", + "titleText": "Perfil de jugadores" + }, + "playerText": "Jugador", + "playlistNoValidGamesErrorText": "Esta lista de juegos contiene juegos desbloqueables no válidos.", + "playlistNotFoundText": "lista no encontrada", + "playlistText": "Lista de reproducción", + "playlistsText": "Listas de Juego", + "pleaseRateText": "Si te gusta ${APP_NAME}, por favor tomate un momento\npara calificar o escribir una reseña. Esto proporcionará\ninformación útil y ayuda al soporte del futuro desarrollo del juego.\n\n¡gracias!\n-eric", + "pleaseWaitText": "Por favor, espera...", + "pluginClassLoadErrorText": "Error al cargar la clase del plugin '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Error al iniciar el plugin '${PLUGIN}': ${ERROR}", + "pluginSettingsText": "Ajustes del Plugin", + "pluginsAutoEnableNewText": "Activar Plugins automáticamente", + "pluginsDetectedText": "Nuevos complemento(s) detectados. Reinicie para activarlos, o configúrelos en la configuración", + "pluginsDisableAllText": "Desactivar todos los Plugins", + "pluginsEnableAllText": "Activar todos los Plugins", + "pluginsRemovedText": "${NUM} plugin(s) ya no se encuentran.", + "pluginsText": "Plugins", + "practiceText": "Práctica", + "pressAnyButtonPlayAgainText": "Oprime cualquier botón jugar de nuevo...", + "pressAnyButtonText": "Oprime cualquier botón para continuar...", + "pressAnyButtonToJoinText": "Oprime cualquier botón para unirse al juego...", + "pressAnyKeyButtonPlayAgainText": "Oprime cualquier botón/tecla para jugar de nuevo...", + "pressAnyKeyButtonText": "Oprime cualquier botón/tecla para continuar...", + "pressAnyKeyText": "Oprime cualquier tecla...", + "pressJumpToFlyText": "** Salta repetidamente para volar **", + "pressPunchToJoinText": "Pulsa GOLPE para unirse al juego...", + "pressToOverrideCharacterText": "Presiona ${BUTTONS} para cambiar de personaje", + "pressToSelectProfileText": "Presiona ${BUTTONS} para seleccionar tu perfil", + "pressToSelectTeamText": "Presiona ${BUTTONS} para seleccionar un equipo", + "profileInfoText": "Crear perfiles para ti y tus amigos para que\npersonalices sus nombres, personajes y colores.", + "promoCodeWindow": { + "codeText": "Código", + "codeTextDescription": "Código promocional", + "enterText": "Ingresar" + }, + "promoSubmitErrorText": "Error al enviar código; comprueba tu conexión a Internet", + "ps3ControllersWindow": { + "macInstructionsText": "Apaga tu PS3, asegúrate que el Bluetooth esté activado en\ntu Mac, a continuación, conecta el control a tu Mac a través \nde un cable USB para sincronizarlo. A partir de entonces, se \npuede utilizar el botón de inicio del control para conectarlo con\ntu Mac ya sea por cable (USB) o el modo inalámbrico (Bluetooth).\n\nEn algunos Macs es posible que te pida una contraseña al momento de sincronizar.\nSi esto ocurre, consulta la siguiente tutoría o busca en google para obtener ayuda.\n\n\n\n\nLos controles de PS3 conectados inalámbricamente deberían de aparecer en la lista de\ndispositivos en Preferencias de Sistema->Bluetooth. Puede que tengas que eliminarlos\nde esa lista cuando quieras utilizarlos de nuevo con tu PS3.\n\nAsimismo, asegúrate de desconectarlos del Bluetooth cuando no los estés\nusando o las baterías se quedarán sin energía.\n\nEL Bluetooth puede procesar hasta 7 dispositivos,\naunque tu kilometraje puede variar.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "Para usar un control de PS3 con tu OUYA, tienes que conectar lo una sola vez con\nun cable USB para sincronizarlo. AL hacer esto se pueden desconectar los otros\ncontroles, por lo que debes reiniciar el OUYA y desconectar el cable USB.\n\nA partir de entonces deberías ser capaz de usar el botón INICIO para conectarte de\nforma inalámbrica. Cuando hayas terminado de jugar, mantén pulsado el botón INICIO\ndurante 10 segundos para apagar el control, de lo contrario puede permanecer encendido\ny gastar las baterías.", + "ouyaInstructionsTextScale": 0.74, + "pairingTutorialText": "video tutorial", + "titleText": "Para usar controles de PS3 con ${APP_NAME}:" + }, + "publicBetaText": "BETA PUBLICA", + "punchBoldText": "GOLPE", + "punchText": "Golpe", + "purchaseForText": "Comprar por este precio : ${PRICE}", + "purchaseGameText": "Comprar Juego", + "purchasingText": "Comprando...", + "quitGameText": "¿Cerrar ${APP_NAME}?", + "quittingIn5SecondsText": "Abandonando en 5 segundos...", + "randomPlayerNamesText": "DEFAULT_NAMES, Pablo, Fulanito, Menganita, Martín, Franco, Pancho, Tomás, Bruno, Federico, Juan, Joaquín, Huevoduro", + "randomText": "Generar", + "rankText": "Rango", + "ratingText": "Valoración", + "reachWave2Text": "Llega hasta la segunda horda\npara clasificar.", + "readyText": "listo", + "recentText": "Reciente", + "remainingInTrialText": "permaneciendo en prueba", + "remoteAppInfoShortText": "${APP_NAME} es más divertido cuando se juega con la familia y amigos .\nPuede conectar uno o más controladores de hardware o instalar el\n${REMOTE_APP_NAME} aplicación en los teléfonos o tabletas de usarlos\ncomo controladores en el juego.", + "remote_app": { + "app_name": "Control Remoto BombSquad", + "app_name_short": "BSRemoto", + "button_position": "Posición de los botones", + "button_size": "Tamaño de los botones", + "cant_resolve_host": "No se encuentra el host.", + "capturing": "Captando...", + "connected": "Conectado.", + "description": "Usa tu teléfono o tableta como control para BombSquad.\nHasta 8 dispositivos pueden conectarse a la vez para un épico caos multijugador local en un solo TV o tableta", + "disconnected": "Desconectado por el servidor.", + "dpad_fixed": "Fijo", + "dpad_floating": "Flotante", + "dpad_position": "Posición del D-Pad", + "dpad_size": "Tamaño del D-Pad", + "dpad_type": "Tipo de D-Pad", + "enter_an_address": "Ingresa una dirección", + "game_full": "El juego está lleno o no acepta conexiones.", + "game_shut_down": "El juego se ha cerrado.", + "hardware_buttons": "Botones de Hardware", + "join_by_address": "Unirse por dirección...", + "lag": "Lag: ${SECONDS} segundos", + "reset": "Reestablecer a predeterminado", + "run1": "Ejecutar 1", + "run2": "Ejecutar 2", + "searching": "Buscando partidas de BombSquad...", + "searching_caption": "Toca el nombre de la partida para unirte.\nTen en cuenta que debes estar en la misma conexión Wi-Fi de la partida.", + "start": "Empezar", + "version_mismatch": "Las versiones no coinciden.\nAsegurate que BombSquad y BombSquad Remote\nestán actuizados e intenta de nuevo." + }, + "removeInGameAdsText": "Desbloquea \"${PRO}\" en la tienda para quitar la publicidad del juego.", + "renameText": "Renombrar", + "replayEndText": "Terminar Repetición", + "replayNameDefaultText": "Repetición Último Juego", + "replayReadErrorText": "Error leyendo archivo de repetición.", + "replayRenameWarningText": "Renombra \"${REPLAY}\" despues de un juego si quieres quedarte con el; o sino será reemplazado.", + "replayVersionErrorText": "Lo sentimos, esta repetición fue hecha en una\nversión diferente del juego y no se puede usar.", + "replayWatchText": "Ver Repetición", + "replayWriteErrorText": "Error creando archivo de repetición", + "replaysText": "Repeticiones", + "reportPlayerExplanationText": "Usa este email para reportar trampas, lenguaje ofensivo, u otro mal comportamiento.\nPor favor, describelo aquí abajo:", + "reportThisPlayerCheatingText": "Trampas", + "reportThisPlayerLanguageText": "Lenguaje Inapropiado", + "reportThisPlayerReasonText": "¿Qué vas a reportar?", + "reportThisPlayerText": "Reportar Este Jugador", + "requestingText": "Solicitando...", + "restartText": "Reiniciar", + "retryText": "Reintentar", + "revertText": "Deshacer", + "runText": "Correr", + "saveText": "Guardar", + "scanScriptsErrorText": "Error (s) escaneando scripts; ver el registro para más detalles.", + "scoreChallengesText": "Desafíos de Puntuación", + "scoreListUnavailableText": "La lista de puntuaciones no está disponible.", + "scoreText": "Puntuación", + "scoreUnits": { + "millisecondsText": "Milisegundos", + "pointsText": "Puntos", + "secondsText": "Segundos" + }, + "scoreWasText": "(era ${COUNT})", + "selectText": "Elegir", + "seriesWinLine1PlayerText": "GANA LA", + "seriesWinLine1TeamText": "GANA LA", + "seriesWinLine1Text": "¡GANA LA", + "seriesWinLine2Text": "SERIE!", + "settingsWindow": { + "accountText": "Cuenta", + "advancedText": "Avanzado", + "audioText": "Sonido", + "controllersText": "Controles", + "graphicsText": "Gráficas", + "playerProfilesMovedText": "Nota: Los Perfiles de Jugadores se han movido a la ventana de Cuenta en el menú principal", + "playerProfilesText": "Perfiles", + "titleText": "Ajustes" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(un teclado simple y amigable con controles para editar textos)", + "alwaysUseInternalKeyboardText": "Siempre Usar el Teclado Interno", + "benchmarksText": "Puntos de Referencia y Pruebas de Resistencia", + "disableCameraGyroscopeMotionText": "Desactivar el movimiento giróscopico de la cámara", + "disableCameraShakeText": "Desactivar el temblor de la cámara", + "disableThisNotice": "(Puedes desactivar este aviso en configuraciones avanzadas)", + "enablePackageModsDescriptionText": "(enciende modificaciones pero apaga juegos vía red)", + "enablePackageModsText": "Encender Modificaciones Locales", + "enterPromoCodeText": "Ingresar Código", + "forTestingText": "Notas: estos datos son solo para pruebas y se reiniciarán cuando se abra la app de nuevo.", + "helpTranslateText": "Las traducciones de ${APP_NAME} son un esfuerzo\napoyado por la comunidad. Si deseas aportar o corregir una\ntraducción, utiliza el siguiente enlace. ¡Gracias de antemano!", + "helpTranslateTextScale": 1.0, + "kickIdlePlayersText": "Expulsar Jugadores Inactivos", + "kidFriendlyModeText": "Modo Niños (reduce violencia, etc)", + "languageText": "Idioma", + "languageTextScale": 1.0, + "moddingGuideText": "Guía de Mods", + "mustRestartText": "Tienes que reiniciar el juego para que tome efecto.", + "netTestingText": "Prueba de Red", + "resetText": "Reiniciar", + "showBombTrajectoriesText": "Mostrar trayectorias", + "showInGamePingText": "Visualizar Ping en el juego", + "showPlayerNamesText": "Mostrar Nombres de los Jugadores", + "showUserModsText": "Mostrar Carpeta de Mods", + "titleText": "Avanzado", + "translationEditorButtonText": "Editor de Traducción de ${APP_NAME}", + "translationFetchErrorText": "estado de traducción no disponible", + "translationFetchingStatusText": "viendo estado de traducción...", + "translationInformMe": "Informarme cuando mi idioma necesite actualizaciones.", + "translationNoUpdateNeededText": "el idioma actual está actualizado; woohoo!", + "translationUpdateNeededText": "** ¡¡el idioma actual necesita actualizarse!! **", + "vrTestingText": "Prueba VR" + }, + "shareText": "Compartir", + "sharingText": "Compartiendo...", + "showText": "Mostrar", + "signInForPromoCodeText": "Debes iniciar sesión con tu cuenta para que el código funcione.", + "signInWithGameCenterText": "Para usar una cuenta de Game Center,\ningresa con la aplicación Game Center.", + "singleGamePlaylistNameText": "Solo ${GAME}", + "singlePlayerCountText": "1 jugador", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Selección de Personajes", + "Chosen One": "El Elegido", + "Epic": "Juegos Épicos", + "Epic Race": "Carrera Épica", + "FlagCatcher": "Captura la Bandera", + "Flying": "Sueños Dulces", + "Football": "Fútbol", + "ForwardMarch": "Carnicería", + "GrandRomp": "Conquista", + "Hockey": "Hockey", + "Keep Away": "Aléjate", + "Marching": "Evasiva", + "Menu": "Menú Principal", + "Onslaught": "Matanza", + "Race": "Carrera", + "Scary": "Rey de la Colina", + "Scores": "Pantalla de Puntuaciones", + "Survival": "Eliminación", + "ToTheDeath": "Combate Mortal", + "Victory": "Pantalla de Puntuaciones Finales" + }, + "spaceKeyText": "espacio", + "statsText": "Estad.", + "storagePermissionAccessText": "Esto requiere acceso de almacenamiento", + "store": { + "alreadyOwnText": "¡Ya compraste ${NAME}!", + "bombSquadProDescriptionText": "• Doble de tickets recibidos en el juego.\n• Remueve los anuncios del juego.\n• Incluye ${COUNT} tickets de bonus.\n• +${PERCENT}% de bonus en la puntuación de la liga.\n• Desbloquea los niveles cooperativos ${INF_ONSLAUGHT}\n y ${INF_RUNAROUND}. ", + "bombSquadProFeaturesText": "Características:", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "•Quita los anuncios y las pantallas molestas\n•Desbloquea más opciones de juego\n•También incluye:", + "buyText": "Comprar", + "charactersText": "Personajes", + "comingSoonText": "Próximamente...", + "extrasText": "Extras", + "freeBombSquadProText": "BombSquad ahora es gratis, pero ya que compraste el juego recibirás\nla mejora de BombSquad Pro y ${COUNT} tickets como agradecimiento.\n¡Disfruta de las nuevas funciones, y gracias por tu soporte!\n-Eric", + "gameUpgradesText": "Mejoras", + "getCoinsText": "Obtén monedas", + "holidaySpecialText": "¡Especial de Temporada!", + "howToSwitchCharactersText": "(ve a \"${SETTINGS} -> ${PLAYER_PROFILES}\" para asignar y personalizar avatares)", + "howToUseIconsText": "(crea perfiles globales de jugador (en la ventana de cuenta) para usarlos)", + "howToUseMapsText": "(usa estos mapas en tus listas de juego por equipos y todos contra todos)", + "iconsText": "Iconos", + "loadErrorText": "No se pudo cargar la página.\nRevisa tu conexión de internet.", + "loadingText": "cargando", + "mapsText": "Mapas", + "miniGamesText": "MiniJuegos", + "oneTimeOnlyText": "(solo una vez)", + "purchaseAlreadyInProgressText": "Una compra de este artículo se encuentra en progreso.", + "purchaseConfirmText": "¿Comprar ${ITEM}?", + "purchaseNotValidError": "Compra inválida.\nContacte ${EMAIL} si esto es un error.", + "purchaseText": "Comprar", + "saleBundleText": "¡Paquete en Oferta!", + "saleExclaimText": "¡Oferta!", + "salePercentText": "(${PERCENT}% menos)", + "saleText": "OFERTA", + "searchText": "Buscar", + "teamsFreeForAllGamesText": "En Equipos / Todos contra Todos", + "totalWorthText": "*** ¡${TOTAL_WORTH} de valor! ***", + "upgradeQuestionText": "¿Comprar BombSquad Pro?", + "winterSpecialText": "Especial de Invierno", + "youOwnThisText": "- ya posees esto -" + }, + "storeDescriptionText": "¡Juego en grupo de 8 jugadores!\n\n¡Revienta a tus amigos (o a la computadora) en un torneo de minijuegos explosivos como Captura la Bandera, Hockey-Bomba, y Combate Mortal Épico en cámara lenta!\n\nControles sencillos y un amplio apoyo de controles hacen que sea fácil que 8 personas entren en la acción; ¡incluso puedes usar tus dispositivos móviles como controles a través de la aplicación gratuita 'BombSquad Remote'!\n\n¡Bombas fuera!\n\nEcha un vistazo en www.froemling.net/bombsquad para más información.", + "storeDescriptions": { + "blowUpYourFriendsText": "Revienta a tus amigos.", + "competeInMiniGamesText": "Compite en juegos de carreras, vuelo y mucho más.", + "customize2Text": "Modifica personajes, mini-juegos, e incluso la banda sonora.", + "customizeText": "Modifica personajes y crea tus propias listas de mini-juegos.", + "sportsMoreFunText": "Los deportes son más divertidos con minas.", + "teamUpAgainstComputerText": "Sobrevive contra la computadora." + }, + "storeText": "Tienda", + "submitText": "Enviar", + "submittingPromoCodeText": "Enviando Código...", + "teamNamesColorText": "Nombres de equipo/colores...", + "teamsText": "Equipos", + "telnetAccessGrantedText": "Acceso a Telnet activado.", + "telnetAccessText": "Acceso a Telnet detectado; ¿permitir?", + "testBuildErrorText": "Esta versión de prueba ya no es activa; busca una versión más nueva.", + "testBuildText": "Versión de Prueba", + "testBuildValidateErrorText": "Imposible validar esta versión de prueba (¿no tienes conexión a internet?)", + "testBuildValidatedText": "Versión de Prueba Validada; ¡Disfruta!", + "thankYouText": "¡Gracias por tu ayuda! ¡¡Disfruta el juego!!", + "threeKillText": "¡¡¡Triple Combo!!!", + "timeBonusText": "Bono de Tiempo", + "timeElapsedText": "Tiempo Transcurrido", + "timeExpiredText": "Se Acabó el Tiempo", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Sugerencia", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Mejores Amigos", + "tournamentCheckingStateText": "Buscando estado del campeonato; espere por favor...", + "tournamentEndedText": "Este torneo ha acabado. Uno nuevo comenzará pronto.", + "tournamentEntryText": "Inscripción al Torneo", + "tournamentResultsRecentText": "Resultados Torneos Recientes", + "tournamentStandingsText": "Puestos del Torneo", + "tournamentText": "Torneo", + "tournamentTimeExpiredText": "Tiempo del Torneo Expirado", + "tournamentsDisabledWorkspaceText": "Los torneos están deshabilitados cuando los espacios de trabajo están activos.\nPara volver a habilitar los torneos, deshabilite su espacio de trabajo y reinicie el juego.", + "tournamentsText": "Torneos", + "translations": { + "characterNames": { + "Agent Johnson": "Agente Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Huesos", + "Butch": "Butch", + "Easter Bunny": "Conejo de Pascua", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Intermediario", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Papá Noel", + "Snake Shadow": "Serpiente Sombría", + "Spaz": "Spaz", + "Taobao Mascot": "Mascota Taobao", + "Todd": "Todd", + "Todd McBurton": "Todd McBurton", + "Xara": "Xara", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopIconNames": { + "Infinite\nOnslaught": "Matanza\nInfinita", + "Infinite\nRunaround": "Evasiva\nInfinita", + "Onslaught\nTraining": "Entrenamiento\nMatanza", + "Pro\nFootball": "Fútbol\nPro", + "Pro\nOnslaught": "Matanza\nPro", + "Pro\nRunaround": "Evasiva\nPro", + "Rookie\nFootball": "Fútbol\nNovato", + "Rookie\nOnslaught": "Matanza\nNovato", + "The\nLast Stand": "La\nBatalla Final", + "Uber\nFootball": "Fútbol\nUltra", + "Uber\nOnslaught": "Matanza\nUltra", + "Uber\nRunaround": "Evasiva\nUltra" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Entrenamiento", + "Infinite ${GAME}": "${GAME} Infinito/a", + "Infinite Onslaught": "Matanza Infinita", + "Infinite Runaround": "Evasiva Infinita", + "Onslaught": "Matanza Infinita", + "Onslaught Training": "Entrenamiento de Matanza", + "Pro ${GAME}": "Pro ${GAME}", + "Pro Football": "Fútbol Pro", + "Pro Onslaught": "Matanza Pro", + "Pro Runaround": "Evasiva Pro", + "Rookie ${GAME}": "Novato ${GAME}", + "Rookie Football": "Fútbol Novato", + "Rookie Onslaught": "Matanza Novato", + "Runaround": "Evasiva Infinita", + "The Last Stand": "Batalla Final", + "Uber ${GAME}": "Uber ${GAME}", + "Uber Football": "Fútbol Ultra", + "Uber Onslaught": "Matanza Ultra", + "Uber Runaround": "Evasiva Ultra" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Sé el elegido durante el tiempo designado para ganar.\nElimina al Elegido para convertirte en El Elegido.", + "Bomb as many targets as you can.": "Lanza bombas a tantos blancos como puedas.", + "Carry the flag for ${ARG1} seconds.": "Carga la bandera por ${ARG1} segundos.", + "Carry the flag for a set length of time.": "Carga la bandera por un determinado tiempo.", + "Crush ${ARG1} of your enemies.": "Elimina ${ARG1} de tus enemigos.", + "Defeat all enemies.": "Elimina todos los enemigos.", + "Dodge the falling bombs.": "Esquiva las bombas.", + "Final glorious epic slow motion battle to the death.": "Gloriosa batalla final en cámara lenta épica.", + "Gather eggs!": "¡Recolecta huevos!", + "Get the flag to the enemy end zone.": "Lleva la bandera enemiga a tu zona.", + "How fast can you defeat the ninjas?": "¿Cuán rápido puedes derrotar a los ninjas?", + "Kill a set number of enemies to win.": "Elimina a un número determinado \nde enemigos para ganar.", + "Last one standing wins.": "El último de pie gana.", + "Last remaining alive wins.": "El último en quedar vivo gana.", + "Last team standing wins.": "El último equipo en pie gana.", + "Prevent enemies from reaching the exit.": "Evita que los enemigos lleguen a la salida.", + "Reach the enemy flag to score.": "Toca la bandera enemiga para anotar.", + "Return the enemy flag to score.": "Devuelve la bandera enemiga para anotar.", + "Run ${ARG1} laps.": "Da ${ARG1} vueltas.", + "Run ${ARG1} laps. Your entire team has to finish.": "Da ${ARG1} vueltas. Todo tu equipo debe cruzar la meta.", + "Run 1 lap.": "Da 1 vuelta.", + "Run 1 lap. Your entire team has to finish.": "Da 1 vuelta. Todo tu equipo debe cruzar la meta.", + "Run real fast!": "¡Corre muy rápido!", + "Score ${ARG1} goals.": "Anota ${ARG1} goles.", + "Score ${ARG1} touchdowns.": "Anota ${ARG1} touchdowns.", + "Score a goal.": "Anota un gol.", + "Score a touchdown.": "Anota un touchdown.", + "Score some goals.": "Anota unos goles.", + "Secure all ${ARG1} flags.": "Asegura todas la ${ARG1} banderas.", + "Secure all flags on the map to win.": "Asegura todas las banderas en el mapa para ganar.", + "Secure the flag for ${ARG1} seconds.": "Asegura la bandera por ${ARG1} segundos.", + "Secure the flag for a set length of time.": "Asegura la bandera por un tiempo determinado.", + "Steal the enemy flag ${ARG1} times.": "Roba la bandera del enemigo ${ARG1} veces.", + "Steal the enemy flag.": "Roba la bandera del enemigo.", + "There can be only one.": "Solo puede haber uno.", + "Touch the enemy flag ${ARG1} times.": "Toca la bandera del enemigo ${ARG1} veces.", + "Touch the enemy flag.": "Toca la bandera del enemigo.", + "carry the flag for ${ARG1} seconds": "carga la bandera por ${ARG1} segundos.", + "kill ${ARG1} enemies": "elimina a ${ARG1} enemigos", + "last one standing wins": "el último en pie gana", + "last team standing wins": "el último equipo en caer gana", + "return ${ARG1} flags": "devuelve ${ARG1} banderas", + "return 1 flag": "devuelve 1 bandera", + "run ${ARG1} laps": "da ${ARG1} vueltas", + "run 1 lap": "da 1 vuelta", + "score ${ARG1} goals": "anota ${ARG1} goles", + "score ${ARG1} touchdowns": "anota ${ARG1} touchdowns", + "score a goal": "anota un gol", + "score a touchdown": "anota un touchdown", + "secure all ${ARG1} flags": "asegura todas las ${ARG1} banderas", + "secure the flag for ${ARG1} seconds": "asegura la bandera por ${ARG1} segundos", + "touch ${ARG1} flags": "toca ${ARG1} banderas", + "touch 1 flag": "toca 1 bandera" + }, + "gameNames": { + "Assault": "Asalto", + "Capture the Flag": "Captura la Bandera", + "Chosen One": "El Elegido", + "Conquest": "Conquista", + "Death Match": "Combate Mortal", + "Easter Egg Hunt": "Búsqueda de Huevos de Pascua", + "Elimination": "Eliminación", + "Football": "Fútbol", + "Hockey": "Hockey", + "Keep Away": "Aléjate", + "King of the Hill": "Rey de la Colina", + "Meteor Shower": "Lluvia de Meteoritos", + "Ninja Fight": "Pelea Ninja", + "Onslaught": "Matanza", + "Race": "Carrera", + "Runaround": "Evasiva", + "Target Practice": "Blanco de Práctica", + "The Last Stand": "Batalla Final" + }, + "inputDeviceNames": { + "Keyboard": "Teclado", + "Keyboard P2": "Teclado P2" + }, + "languages": { + "Arabic": "Árabe", + "Belarussian": "Bielorruso", + "Chinese": "Chino Simplificado", + "ChineseTraditional": "Chino Tradicional", + "Croatian": "Croata", + "Czech": "Checo", + "Danish": "Danés", + "Dutch": "Holandés", + "English": "Inglés", + "Esperanto": "Esperanto", + "Filipino": "filipino", + "Finnish": "Finlandés", + "French": "Francés", + "German": "Alemán", + "Gibberish": "Algarabía", + "Greek": "Griego", + "Hindi": "Hindi", + "Hungarian": "Húngaro", + "Indonesian": "Indonesio", + "Italian": "Italiano", + "Japanese": "Japonés", + "Korean": "Coreano", + "Malay": "Malayo", + "Persian": "Persa", + "Polish": "Polaco", + "Portuguese": "Portugués", + "Romanian": "Rumano", + "Russian": "Ruso", + "Serbian": "Serbio", + "Slovak": "Eslovaco", + "Spanish": "Español", + "Swedish": "Sueco", + "Tamil": "Tamil", + "Thai": "Tailandés", + "Turkish": "Turco", + "Ukrainian": "Ucraniano", + "Venetian": "Veneciana", + "Vietnamese": "Vietnamita" + }, + "leagueNames": { + "Bronze": "Bronce", + "Diamond": "Diamante", + "Gold": "Oro", + "Silver": "Plata" + }, + "mapsNames": { + "Big G": "Gran G", + "Bridgit": "Puentecito", + "Courtyard": "Patio Real", + "Crag Castle": "Castillo del Risco", + "Doom Shroom": "Hongo de la Muerte", + "Football Stadium": "Estadio de Fútbol", + "Happy Thoughts": "Pensamientos Felices", + "Hockey Stadium": "Estadio de Hockey", + "Lake Frigid": "Lago Frígido", + "Monkey Face": "Cara de Mono", + "Rampage": "Rampa", + "Roundabout": "Rotonda", + "Step Right Up": "Paso al Frente", + "The Pad": "La Plataforma", + "Tip Top": "Punta Superior", + "Tower D": "Torre D", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Solo Épico", + "Just Sports": "Solo Deportes" + }, + "promoCodeResponses": { + "invalid promo code": "Código promocional inválido" + }, + "scoreNames": { + "Flags": "Banderas", + "Goals": "Goles", + "Score": "Puntuación", + "Survived": "Sobrevivió", + "Time": "Tiempo", + "Time Held": "Tiempo Mantenido" + }, + "serverResponses": { + "A code has already been used on this account.": "Este código ya ha sido usado en esta cuenta", + "A reward has already been given for that address.": "Ya se le ha dado una recompensa a esa dirección.", + "Account linking successful!": "¡Enlace de Cuenta exitoso!", + "Account unlinking successful!": "¡Desenlace de cuenta realizado!", + "Accounts are already linked.": "Las cuentas ya se encuentran enlazadas.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "No se pudo verificar la vista del anuncio. \nPor favor asegúrese de estar ejecutando una versión oficial y actualizada del juego.", + "An error has occurred; (${ERROR})": "Se ha producido un error; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Se ha producido un error; por favor contácte con soporte. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Ha ocurrido un error; contacta a support@froemling.net.", + "An error has occurred; please try again later.": "Un error ha ocurrido; por favor intenta más tarde.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "¿Quieres enlazar estas cuentas?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n¡Esto no se puede deshacer!", + "BombSquad Pro unlocked!": "¡BombSquad Pro desbloqueado!", + "Can't link 2 accounts of this type.": "No puedes enlazar dos cuentas de este tipo.", + "Can't link 2 diamond league accounts.": "No pueden enlazar dos cuentas de liga diamante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "No se pudo enlazar; sobrepasaría el máximo de ${COUNT} cuentas enlazadas.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Trampa detectada; puntajes y premios suspendidos por ${COUNT} días.", + "Could not establish a secure connection.": "No se pudo establecer una conexión segura.", + "Daily maximum reached.": "Máximo diario conseguido.", + "Entering tournament...": "Entrando a torneo...", + "Invalid code.": "Código inválido.", + "Invalid payment; purchase canceled.": "Pago inválido; compra cancelada.", + "Invalid promo code.": "Código promocional inválido.", + "Invalid purchase.": "Compra inválida.", + "Invalid tournament entry; score will be ignored.": "Entrada de torneo inválida; el puntaje será ignorado.", + "Item unlocked!": "¡Objeto desbloqueado!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "VINCULACÍON DENEGADO. ${ACCOUNT} contiene\ndatos significativos que TODOS SERÍAN PERDIDOS.\nPuede vincular en el orden opuesto si lo desea\n(y pierda los datos de ESTA cuenta en su lugar)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "¿Enlazar ${ACCOUNT} a esta cuenta?\nTodos los datos en ${ACCOUNT} desaparecerán.\nEsto no se puede deshacer. ¿Estás seguro?", + "Max number of playlists reached.": "Número máximo de listas de reproducción alcanzado.", + "Max number of profiles reached.": "Número máximo de perfiles alcanzado.", + "Maximum friend code rewards reached.": "Máximo de premios por códigos de amigos alcanzado.", + "Message is too long.": "El Mensaje es muy largo.", + "No servers are available. Please try again soon.": "Sin servidores disponibles. Por favor intenta después.", + "Profile \"${NAME}\" upgraded successfully.": "El perfil \"${NAME}\" se ha mejorado satisfactoriamente.", + "Profile could not be upgraded.": "El perfil no pudo ser mejorado.", + "Purchase successful!": "¡Compra exitosa!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Has recibido ${COUNT} tickets recibidos por iniciar sesión.\nRegresa mañana para recibir ${TOMORROW_COUNT} tickets.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "La funcionalidad del servidor ya no es compatible en esta versión del juego;\nActualiza a una versión más reciente.", + "Sorry, there are no uses remaining on this code.": "Perdón, pero no quedan usos disponibles de este código.", + "Sorry, this code has already been used.": "Perdón, este código ya ha sido usado.", + "Sorry, this code has expired.": "Perdón, este código ha expirado.", + "Sorry, this code only works for new accounts.": "Este código solo sirve para cuentas nuevas.", + "Still searching for nearby servers; please try again soon.": "Todavía buscando por servidores cercanos; intente de nuevo más tarde.", + "Temporarily unavailable; please try again later.": "Temporalmente desactivado; por favor, inténtalo luego.", + "The tournament ended before you finished.": "El torneo terminó antes de que terminaras.", + "This account cannot be unlinked for ${NUM} days.": "Esta cuenta no puede ser desenlazada por ${NUM} días.", + "This code cannot be used on the account that created it.": "Este código no puede ser usado en la misma cuenta que ha sido creado.", + "This is currently unavailable; please try again later.": "Esto Está No Disponible actualmente; por favor inténtelo más tarde", + "This requires version ${VERSION} or newer.": "Esto requiere la versión ${VERSION} o una más nueva.", + "Tournaments disabled due to rooted device.": "Los torneos han sido desactivados debido a que tu dispositivo es root", + "Tournaments require ${VERSION} or newer": "El torneo requiere la versión ${VERSION} o versiones recientes", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "¿Desenlazar ${ACCOUNT} de esta cuenta?\nTodos los datos en ${ACCOUNT} se reiniciarán\n(excepto los logros en algunos casos).", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ADVERTENCIA: se han emitido reclamaciones de piratería contra tu cuenta.\nLas cuentas que se encuentren pirateadas serán prohibidas. Por favor, juega limpio.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "¿Quieres enlazar tu cuenta de dispositivo a esta otra?\n\nTu cuenta de dispositivo es ${ACCOUNT1}\nEsta cuenta es ${ACCOUNT2}\n\nEsto permitirá guardar tu progreso actual.\nAdvertencia: ¡Esto no se puede deshacer!", + "You already own this!": "¡Ya posees esto!", + "You can join in ${COUNT} seconds.": "Puedes unirte en ${COUNT} segundos.", + "You don't have enough tickets for this!": "¡No tienes suficientes tickets para esto!", + "You don't own that.": "No tienes eso.", + "You got ${COUNT} tickets!": "¡Obtuviste ${COUNT} tickets!", + "You got a ${ITEM}!": "¡Recibiste un ${ITEM}!", + "You have been promoted to a new league; congratulations!": "¡Has sido ascendido a una nueva liga! ¡Felicidades!", + "You must update to a newer version of the app to do this.": "Debes actualizar la aplicación a una versión más reciente para hacer esto.", + "You must update to the newest version of the game to do this.": "Necesitas actualizar a la versión más reciente del juego para hacer esto.", + "You must wait a few seconds before entering a new code.": "Debes esperar unos segundos antes de ingresar un código nuevo.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Quedaste en la posición #${RANK} en el campeonato. ¡Gracias por jugar!", + "Your account was rejected. Are you signed in?": "Tu cuenta fue rechazada. ¿Estas registrado?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Tu copia del juego fue modificada.\nPor favor revierte estos cambios e intenta de nuevo", + "Your friend code was used by ${ACCOUNT}": "Tu código de amigo fue usado por ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minuto", + "1 Second": "1 Segundo", + "10 Minutes": "10 Minutos", + "2 Minutes": "2 Minutos", + "2 Seconds": "2 Segundos", + "20 Minutes": "20 Minutos", + "4 Seconds": "4 Segundos", + "5 Minutes": "5 Minutos", + "8 Seconds": "8 Segundos", + "Allow Negative Scores": "Permitir Puntajes Negativos", + "Balance Total Lives": "Repartir Vidas Totales", + "Bomb Spawning": "Aparición de Bombas", + "Chosen One Gets Gloves": "El Elegido Tiene Guantes de Boxeo", + "Chosen One Gets Shield": "El Elegido Tiene Electro-Escudo", + "Chosen One Time": "Tiempo Del Elegido", + "Enable Impact Bombs": "Permitir Impacto de Bombas", + "Enable Triple Bombs": "Permitir Bombas Triples", + "Entire Team Must Finish": "Todo el Equipo Debe Terminar", + "Epic Mode": "Modo Épico", + "Flag Idle Return Time": "Tiempo de Regreso de Bandera Inactiva", + "Flag Touch Return Time": "Tiempo de Bandera Sin Tocar", + "Hold Time": "Retención", + "Kills to Win Per Player": "Víctimas por Jugador", + "Laps": "Vueltas", + "Lives Per Player": "Vidas por Jugador", + "Long": "Largo", + "Longer": "Más Largo", + "Mine Spawning": "Regenerar Minas", + "No Mines": "Sin Minas", + "None": "Ninguno", + "Normal": "Normal", + "Pro Mode": "Modo Pro", + "Respawn Times": "Tiempo de Reaparición", + "Score to Win": "Puntos para Ganar", + "Short": "Corto", + "Shorter": "Más Corto", + "Solo Mode": "Modo de Un Jugador", + "Target Count": "Número de Objetivos", + "Time Limit": "Límite de Tiempo" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "El equipo ${TEAM} ha sido descalificado porque ${PLAYER} se ha ido.", + "Killing ${NAME} for skipping part of the track!": "¡Matando a ${NAME} por saltarse un pedazo de la pista!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Advertencia para ${NAME}: turbo / El spameo de botones te noqueará." + }, + "teamNames": { + "Bad Guys": "Chicos Malos", + "Blue": "Azul", + "Good Guys": "Chicos Buenos", + "Red": "Rojo" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Un 'corre-salta-gira-golpea' puede destrozar de un solo impacto\ny ganarte el respeto de tus amigos para toda la vida.", + "Always remember to floss.": "Siempre acuérdate de cepillar tus dientes.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Crea perfiles para ti y tus amigos con nombres\ny colores personalizados en vez de usar aleatorios.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Las cajas de maldición te convierten en una bomba de tiempo.\nLa única cura es agarrar rápidamente un botiquín.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "A pesar de su apariencia, las habilidades de todos los personajes\nson idénticas, así que escoge el que más se parezca a ti.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "No te pongas demasiado engreído(a) con ese escudo de energía; todavía puedes caerte de un acantilado.", + "Don't run all the time. Really. You will fall off cliffs.": "No corras todo el tiempo. En serio. Te vas a caer.", + "Don't spin for too long; you'll become dizzy and fall.": "No gires por un largo tiempo; puedes marearte y caer.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Sostén cualquier botón para correr. (Los botones de gatillo son para eso)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Mantén pulsado cualquier botón para correr. Llegarás a lugares rápido\npero no girarás muy bien, así que ten cuidado con los acantilados.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Las Bombas de hielo no son muy potentes, pero congelan lo\nque toquen, dejando a tus enemigos vulnerables a romperse.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Si alguien te levanta, golpéalos y ellos te soltarán.\nTambién funciona en la vida real.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Si no tienes suficientes controles, instala la aplicación '${REMOTE_APP_NAME}'\nen tus dispositivos móviles para utilizarlos como controles.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Te faltan controles? Instala la aplicación 'BombSquad Remote'\nen tu dispositivo iOS o Android para usarlo como control.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Si te adhieres a una bomba pegajosa, salta y da muchas vueltas. Es posible que sacudas\nla bomba pegada, o sin nada más, tus últimos momentos serán entretenidos.", + "If you kill an enemy in one hit you get double points for it.": "Si matas a un enemigo de un solo golpe obtendrás puntos dobles.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Si tomaste una maldición, tu única esperanza es\nencontrar un botiquín en tus últimos segundos.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Si te quedas quieto, estás frito. Corre y esquiva para sobrevivir...", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Si tienes muchos jugadores yendo y viniendo, activa 'expulsar jugadores inactivos'\nen ajustes en caso de que alguien se olvide de abandonar el juego.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Si tu dispositivo se pone caliente o te gustaría conservar batería,\nbaja los \"Visuales\" o \"Resolución\" en configuración->Gráficos", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Si la imagen va lenta, intenta reducir la resolución\no los visuales en los ajustes gráficos del juego.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "En Captura la Bandera, la tuya debe estar en tu base para que anotes.\nSi el otro equipo está a punto de anotar, el arrebatar su bandera evitará que lo hagan.", + "In hockey, you'll maintain more speed if you turn gradually.": "En hockey, mantendrás tu impulso si giras gradualmente.", + "It's easier to win with a friend or two helping.": "Es más fácil ganar con un amigo.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Salta antes de lanzar una bomba para que alcance lugares altos.", + "Land-mines are a good way to stop speedy enemies.": "Las minas terrestres son una buena manera para detener a los enemigos veloces.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Muchas cosas se pueden recoger y lanzar, incluyendo a otros jugadores.\nArroja a tus enemigos por los precipicios. Te sentirás mejor.", + "No, you can't get up on the ledge. You have to throw bombs.": "No, no puedes subir a la cornisa. Tienes que lanzar bombas.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Jugadores pueden unirse e irse en medio de casi todos los juegos,\ntambién puedes poner o quitar controles en cualquier momento.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Los jugadores pueden unirse y abandonar en el transcurso del juego,\ny también puedes conectar y desconectar controles cuando quieras.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Los poderes sólo tienen tiempo límite en juego cooperativo.\nEn los equipos y Pelea libre son tuyos hasta que seas eliminado.", + "Practice using your momentum to throw bombs more accurately.": "Practica con tu impulso para lanzar bombas con más precisión.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Tus golpes harán más daño dependiendo de que tan rápido tus puños se muevan,\nasí que intenta correr, saltar, y girar como un loco.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Corre de un lado a otro antes de lanzar una\nbomba de 'latigazo' para lanzarla lejos.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Elimina un gran cantidad de enemigos\nal detonar una bomba cerca de una caja TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "La cabeza es la zona más vulnerable, una bomba pegajosa\na la cabeza usualmente significa game-over.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Este nivel no tiene fin, pero un alto puntaje aquí\nte hará ganar el respeto eterno por todo el mundo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "La fuerza de tiro se basa en la dirección que estás sosteniendo.\nPara arrojar algo justo delante de ti, no sostengas ninguna dirección.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "¿Cansado de la pista de audio? ¡Reemplázala con tu música!\nVe a Ajustes->Audio->Banda Sonora", + "Try 'Cooking off' bombs for a second or two before throwing them.": "'Cocina tus Bombas' por un segundo o dos antes de tirarlas.", + "Try tricking enemies into killing eachother or running off cliffs.": "Engaña a tus enemigos para que se eliminen entre sí o para que corran a los acantilados.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Usa el botón de 'levantar' para llevar la bandera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Bate de un lado a otro para tirar las bombas más lejos..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Puedes 'dirigir' tus golpes girando a la izquierda o derecha. Esto\nes útil para tirar a los enemigos al vacío o para anotar en el hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Puedes juzgar si una bomba va a explotar según el color de\nlas chispas de la mecha: amarillo...naranja...rojo...¡BUM!", + "You can throw bombs higher if you jump just before throwing.": "Puedes lanzar bombas más alto si saltas justo antes de tirarlas.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "No necesitas editar tu perfil para cambiar de personaje; sólo presiona el botón\nsuperior (levantar) cuando te unas a un partido para cambiar el predeterminado.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Te haces daño si golpeas tu cabeza contra cosas, así\nque trata de no golpear tu cabeza contra cosas.", + "Your punches do much more damage if you are running or spinning.": "Tus golpes harán mucho más impacto si estás corriendo o girando." + } + }, + "trialPeriodEndedText": "Tu periodo de prueba se terminó. ¿Deseas\ncomprar BombSquad y seguir jugando?", + "trophiesRequiredText": "Esto requiere al menos ${NUMBER} trofeos.", + "trophiesText": "Trofeos", + "trophiesThisSeasonText": "Trofeos Esta Temporada", + "tutorial": { + "cpuBenchmarkText": "Corriendo tutorial en velocidad ridícula (pruebas de velocidad de CPU)", + "phrase01Text": "¡Hey, hola!", + "phrase02Text": "¡Bienvenido a ${APP_NAME}!", + "phrase03Text": "Aquí van unos consejos para manejar a tu personaje:", + "phrase04Text": "Muchas cosas en ${APP_NAME} se basan en FÍSICAS.", + "phrase05Text": "Por ejemplo, cuando pegas un puñetazo...", + "phrase06Text": "...el daño se basa en la velocidad de tus puños.", + "phrase07Text": "¿Has visto? No nos estábamos moviendo, por eso casi \nno hemos hecho daño a ${NAME}.", + "phrase08Text": "Ahora, saltemos y giremos para conseguir más velocidad.", + "phrase09Text": "Ah, eso está mejor.", + "phrase10Text": "Correr también ayuda.", + "phrase11Text": "Mantén pulsado CUALQUIER botón para correr.", + "phrase12Text": "Para dar superpuñetazos, prueba a correr Y girar.", + "phrase13Text": "¡Ups! Lo siento por eso, ${NAME}.", + "phrase14Text": "Puedes coger y lanzar cosas como banderas... o ${NAME}s.", + "phrase15Text": "Por último, hay bombas.", + "phrase16Text": "Tirar bombas bien requiere práctica.", + "phrase17Text": "¡Vaya! No ha llegado muy lejos.", + "phrase18Text": "Moverte ayuda a lanzarlas más lejos.", + "phrase19Text": "Saltar te permitirá lanzarlas más alto.", + "phrase20Text": "Girar también te permitirá hacer lanzamientos más lejanos.", + "phrase21Text": "Hacer que exploten donde tú quieres puede ser complicado.", + "phrase22Text": "Vaya...", + "phrase23Text": "Probemos a 'cocinarla' dos segundos antes de lanzarla...", + "phrase24Text": "¡Toma ya! Así es como se hace.", + "phrase25Text": "Bueno, eso es todo.", + "phrase26Text": "Ahora, ¡a por ellos, campeón!", + "phrase27Text": "Recuerda tu entrenamiento, ¡y volverás con vida!", + "phrase28Text": "...o a lo mejor...", + "phrase29Text": "¡Buena suerte!", + "randomName1Text": "Fred", + "randomName2Text": "Javi", + "randomName3Text": "Carlos", + "randomName4Text": "Pablo", + "randomName5Text": "Nerea", + "skipConfirmText": "¿Realmente quieres saltar el tutorial? Toca o presiona para confirmar.", + "skipVoteCountText": "votos para saltarnos el tutorial ${COUNT}/${TOTAL}", + "skippingText": "saltándonos el tutorial...", + "toSkipPressAnythingText": "(pulsa cualquier botón para saltarte el tutorial)" + }, + "twoKillText": "¡¡Doble Combo!!", + "unavailableText": "no disponible", + "unconfiguredControllerDetectedText": "Control desconfigurado detectado:", + "unlockThisInTheStoreText": "Esto debe ser desbloqueado en la tienda.", + "unlockThisProfilesText": "Para crear más de ${NUM} cuentas, necesitas:", + "unlockThisText": "Para desbloquear esto, tú necesitas:", + "unsupportedHardwareText": "Lo sentimos, este dispositivo no soporta esta versión del juego.", + "upFirstText": "A continuación:", + "upNextText": "A continuación en juego ${COUNT}:", + "updatingAccountText": "Actualizando tu cuenta...", + "upgradeText": "Mejorar", + "upgradeToPlayText": "Desbloquea \"${PRO}\" en la tienda para jugar esto.", + "useDefaultText": "Usar botón por defecto", + "usesExternalControllerText": "Este juego usa un control externo como entrada.", + "usingItunesText": "Usando la aplicación de música para la banda sonora...", + "usingItunesTurnRepeatAndShuffleOnText": "Asegúrate de que mezclar esté ENCENDIDO y repetir TODOS esté activado en iTunes.", + "v2AccountLinkingInfoText": "Para vincular las cuentas V2, utilice el botón \"Administrar cuenta\".", + "validatingBetaText": "Validando Beta…", + "validatingTestBuildText": "Validando versión de prueba...", + "victoryText": "¡Victoria!", + "voteDelayText": "No puedes iniciar otra votación por ${NUMBER} segundos.", + "voteInProgressText": "Ya hay una votación en progreso.", + "votedAlreadyText": "Ya has votado.", + "votesNeededText": "Se requiere ${NUMBER} votos", + "vsText": "vs.", + "waitingForHostText": "(esperando a que ${HOST} continúe)", + "waitingForLocalPlayersText": "Esperando jugadores locales...", + "waitingForPlayersText": "esperando a jugadores para unirse...", + "waitingInLineText": "Esperando en línea (la fiesta está llena)...", + "watchAVideoText": "Ver un Vídeo", + "watchAnAdText": "Mira un Anuncio", + "watchWindow": { + "deleteConfirmText": "¿Borrar \"${REPLAY}\"?", + "deleteReplayButtonText": "Borrar\nRepetición", + "myReplaysText": "Mis Repeticiones", + "noReplaySelectedErrorText": "Ninguna Repetición Seleccionada", + "playbackSpeedText": "Velocidad de reproducción: ${SPEED}", + "renameReplayButtonText": "Renombrar\nRepetición", + "renameReplayText": "Renombrar \"${REPLAY}\" a:", + "renameText": "Renombrar", + "replayDeleteErrorText": "Error borrando la repetición.", + "replayNameText": "Nombre de la Repetición", + "replayRenameErrorAlreadyExistsText": "Una repetición con ese nombre ya existe.", + "replayRenameErrorInvalidName": "No se puede renombrar la repetición: Nombre inválido.", + "replayRenameErrorText": "Error renombrando repetición.", + "sharedReplaysText": "Repeticiones Compartidas", + "titleText": "Ver", + "watchReplayButtonText": "Ver\nRepetición" + }, + "waveText": "Horda", + "wellSureText": "¡Pues claro!", + "whatIsThisText": "Qué es esto?", + "wiimoteLicenseWindow": { + "titleText": "Marca registrada DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "Esperando controles Wii...", + "pressText": "Presiona los botones 1 y 2 simultáneamente.", + "pressText2": "En controles Wii más nuevos con Motion Plus integrado, pulsa mejor el botón 'sinc' rojo en la parte trasera.", + "pressText2Scale": 0.55, + "pressTextScale": 1.0 + }, + "wiimoteSetupWindow": { + "copyrightText": "Marca registrada DarwiinRemote", + "copyrightTextScale": 0.6, + "listenText": "Escuchar", + "macInstructionsText": "Asegúrate de que tu Wii esté apagado y el Bluetooth esté activado en\ntu Mac, a continuación, pulsa 'Escuchar'. El Soporte para controles\nWii puede ser un poco extraño, así que puede que tengas que\nprobar un par de veces antes de obtener una conexión.\n\nEl Bluetooth puede procesar hasta 7 dispositivos conectados,\naunque tu kilometraje puede variar.\n\nBombSquad es compatible con los Controles Wii originales,\nNunchuks, y el Control Clásico.\nEl nuevo Control Wii Plus también funciona\npero sin accesorios.", + "macInstructionsTextScale": 0.7, + "thanksText": "Gracias al equipo DarwiinRemote\nPor hacer esto posible.", + "thanksTextScale": 0.8, + "titleText": "Configuración Wii" + }, + "winsPlayerText": "¡${NAME} Gana!", + "winsTeamText": "¡${NAME} Gana!!", + "winsText": "¡${NAME} Gana!", + "workspaceSyncErrorText": "Error al sincronizar ${WORKSPACE}. Mira el registro para más detalles.", + "workspaceSyncReuseText": "No se puede sincronizar ${WORKSPACE}. Reusando la versión sincronizada anterior.", + "worldScoresUnavailableText": "Puntuaciones globales no disponibles.", + "worldsBestScoresText": "Mejores puntuaciones Mundiales", + "worldsBestTimesText": "Mejores tiempos Mundiales", + "xbox360ControllersWindow": { + "getDriverText": "Obtener Driver", + "macInstructions2Text": "Para usar controles inalámbricos, necesitarás el receptor que\nviene con el 'Control de Xbox 360 para Windows'.\nUn receptor te permite conectar hasta cuatro controles.\n\nImportante: Receptores de tercera mano no funcionarán con este controlador;\nasegúrate de que tu receptor tenga el logo de 'Microsoft', no 'XBOX 360'.\nMicrosoft ya no vende receptores por separado, por lo que necesitarás\nel que venía con el control, o si no tendrás que buscar uno por internet.\n\nSi encuentras que esto fue útil, por favor considera donar\nal desarrollador del controlador en su sitio de internet.", + "macInstructions2TextScale": 0.76, + "macInstructionsText": "Para usar controles de Xbox 360, necesitarás instalar\nel controlador para Mac disponible en el siguiente enlace.\nFunciona con controles con cable e inalámbricos.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "Para usar controles con cable de Xbox 360 con BombSquad, simplemente\nconéctalos al puerto USB de tu dispositivo. Puedes usar un conector USB\npara conectar múltiples controles.\n\nPara usar controles inalámbricos, necesitarás un receptor inalámbrico,\ndisponible como parte del paquete “Xbox 360 wireless Controller for\nWindows”, o vendido por separado. Cada receptor se conecta a un puerto\nUSB y permite que conectes hasta cuatro controles inalámbricos.", + "ouyaInstructionsTextScale": 0.8, + "titleText": "Controles de Xbox 360 con ${APP_NAME}:" + }, + "yesAllowText": "¡Sí, permítelo!", + "yourBestScoresText": "Tus Mejores Puntuaciones", + "yourBestTimesText": "Tus Mejores Tiempos" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/swedish.json b/dist/ba_data/data/languages/swedish.json new file mode 100644 index 0000000..6590ae5 --- /dev/null +++ b/dist/ba_data/data/languages/swedish.json @@ -0,0 +1,1756 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Kontonamn kan inte innehålla emojis eller andra specialsymboler", + "accountProfileText": "(användarprofil)", + "accountsText": "Konton", + "achievementProgressText": "Prestationer: ${COUNT} avklarade av ${TOTAL}", + "campaignProgressText": "Kampanjutveckling: [svår] ${PROGRESS}", + "changeOncePerSeason": "Du kan enbart ändra detta en gång per säsong.", + "changeOncePerSeasonError": "Du måste vänta tills nästa säsong för att ändra detta igen (${NUM} days)", + "customName": "Anpassat Namn", + "googlePlayGamesAccountSwitchText": "Om du vill använda ett annat Google-konto,\nanvänd appen Google Play Spel för att byta.", + "linkAccountsEnterCodeText": "Skriv in kod", + "linkAccountsGenerateCodeText": "Generera kod", + "linkAccountsInfoText": "(dela framsteg över olika plattformar)", + "linkAccountsInstructionsNewText": "För att länka två konton, generera en kod på den första\noch skriv in koden på den andra. Data från det\nandra kontot kommer att delas mellan båda.\n(Data på det första kontot kommer att försvinna)\n\nDu kan länka upp till ${COUNT} konton.\n\nVIKTIGT: länka endast konton du äger;\nOm du länkar med en väns konto kan ni inte\nspela online samtidigt.", + "linkAccountsInstructionsText": "För att länka ihop två konton, generera en kod på\nett av dem och skriv in den på det andra. Framsteg\noch samlingar kommer att föras samman. Du kan länka \nupp till ${COUNT} konton.\n\nVar försiktig, detta kan inte ångras! ", + "linkAccountsText": "Länka konton", + "linkedAccountsText": "Länkade konton:", + "manageAccountText": "Hantera konto", + "nameChangeConfirm": "Ändra nanmnet på ditt konto till ${NAME}?", + "notLoggedInText": "", + "resetProgressConfirmNoAchievementsText": "Detta kommer att återställa co-op spel och \npoäng (men inte dina värdekuponger). Kan ej ångras.\nÄr du säker?", + "resetProgressConfirmText": "Detta kommer att återställa din co-op kampanj,\nprestationer och poäng (men inte dina värdekuponger).\nDetta kan ej ångras.\nÄr du säker?", + "resetProgressText": "Återställ Framsteg", + "setAccountName": "Välj Konto Namn", + "setAccountNameDesc": "Välj ett namn att visa för ditt konto.\nDu kan använda användarnamnet från något av dina länkade konton eller skapa ett unikt namn.", + "signInInfoText": "Logga in för att samla värdekuponger, tävla \non-line och dela framsteg över olika enheter.", + "signInText": "Logga In", + "signInWithDeviceInfoText": "(endast ett automatiskt konto finns på denna enhet)", + "signInWithDeviceText": "Logga in med ett enhetskonto", + "signInWithGameCircleText": "Logga in med Spel Cirkel", + "signInWithGooglePlayText": "Logga in med Google Play", + "signInWithTestAccountInfoText": "(allmän konto typ; använd enhets konton för att fortsätta)", + "signInWithTestAccountText": "Logga in med ett testkonto", + "signInWithV2InfoText": "(ett konto som fungerar på alla plattformar)", + "signInWithV2Text": "Logga in med ett BombSquad-konto", + "signOutText": "Logga Ut", + "signingInText": "Loggar in...", + "signingOutText": "Loggar ut...", + "testAccountWarningCardboardText": "Varning : du loggar in med ett konto \"test\" .\nDessa kommer att ersättas med Google-konton en gång\nde blir stöds i papp appar .\n\nFör nu måste du tjäna alla biljetter i spelet .\n( du gör dock få BombSquad Pro uppgradering gratis )", + "testAccountWarningOculusText": "Varning: du loggar in med ett konto \"test\".\nDessa kommer att ersättas med Oculus konton senare i\n\når som kommer att erbjuda biljettinköp och andra funktioner.\n\nFör nu måste du tjäna alla biljetter i spelet.", + "testAccountWarningText": "Varning: du loggar på med ett \"test\" konto.\nKontot är knutet till en specifik enhet och kan\nkomma att nollställas ibland. (så lägg inte ner\nmycket tid på att samla/låsa upp saker med kontot)\n\nAnvänd betalversionen av spelet för att använda ett\n\"riktigt\" konto (Game-Center, Google Plus, etc.) \nDetta gör även att dina framsteg lagras i molnet \noch delas mellan olika enheter.", + "ticketsText": "Värdekuponger: ${COUNT}", + "titleText": "Konto", + "unlinkAccountsInstructionsText": "Välj ett konto att avlänka", + "unlinkAccountsText": "Avlänka Konton", + "v2LinkInstructionsText": "Använd den här länken för att skapa ett konto eller logga in.", + "viaAccount": "(via konto ${NAME})", + "youAreLoggedInAsText": "Du är inloggad som:", + "youAreSignedInAsText": "Du är inloggad som:" + }, + "achievementChallengesText": "Prestationsutmaningar", + "achievementText": "Prestation", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Döda 3 fiender med TNT", + "descriptionComplete": "Dödade 3 fiender med TNT", + "descriptionFull": "Döda 3 fiender med TNT på ${LEVEL}", + "descriptionFullComplete": "Dödade 3 fiender med TNT på ${LEVEL}", + "name": "Pang säger dynamiten" + }, + "Boxer": { + "description": "Vinn utan att använda några bomber", + "descriptionComplete": "Vann utan att använda några bomber", + "descriptionFull": "Klara ${LEVEL} utan att använda bomber", + "descriptionFullComplete": "Klarade ${LEVEL} utan att använda bomber", + "name": "Boxare" + }, + "Dual Wielding": { + "descriptionFull": "Koppla 2 kontroller (hårdvara eller app)", + "descriptionFullComplete": "Kopplade 2 kontroller (hårdvara eller app)", + "name": "Dubbel Hantering" + }, + "Flawless Victory": { + "description": "Vinn utan att bli skadad", + "descriptionComplete": "Vann utan att bli skadad", + "descriptionFull": "Vinn ${LEVEL} utan att träffas", + "descriptionFullComplete": "Vann ${LEVEL} utan att bli träffad", + "name": "Perfekt Vinst" + }, + "Free Loader": { + "descriptionFull": "Starta ett Alla-Mot-Alla spel med 2+ spelare", + "descriptionFullComplete": "Börjat ett Alla-Mot-Alla spel med 2+ spelare", + "name": "Gratis Laddare" + }, + "Gold Miner": { + "description": "Döda 6 fiender med landminor", + "descriptionComplete": "Dödade 6 fiender med landminor", + "descriptionFull": "Döda 5 fiender med landminor på ${LEVEL}", + "descriptionFullComplete": "Dödade 6 fiender med landminor i ${LEVEL}", + "name": "Guldgrävare" + }, + "Got the Moves": { + "description": "Vinn utan att använda slag eller bomber", + "descriptionComplete": "Vann utan att använda slag eller bomber", + "descriptionFull": "Vinn ${LEVEL} utan slag eller bomber", + "descriptionFullComplete": "Vann ${LEVEL} utan slag eller bomber", + "name": "Har svinget" + }, + "In Control": { + "descriptionFull": "Ansut en kontroll (Hårdvara eller app)", + "descriptionFullComplete": "Anslöt en kontroll (Hårdvara eller app)", + "name": "I kontroll" + }, + "Last Stand God": { + "description": "Nå 1000 poäng", + "descriptionComplete": "Nådde 1000 poäng", + "descriptionFull": "Få 1000 poäng på ${LEVEL}", + "descriptionFullComplete": "Nådde 1000 poäng i ${LEVEL}", + "name": "${LEVEL} Gud" + }, + "Last Stand Master": { + "description": "Nå 250 poäng", + "descriptionComplete": "Nådde 250 poäng", + "descriptionFull": "Nå 250 poäng på ${LEVEL}", + "descriptionFullComplete": "Nådde 250 poäng i ${LEVEL}", + "name": "${LEVEL} Mästare" + }, + "Last Stand Wizard": { + "description": "Nå 500 poäng", + "descriptionComplete": "Nådde 500 poäng", + "descriptionFull": "Nå 500 poäng i ${LEVEL}", + "descriptionFullComplete": "Nådde 500 poäng i ${LEVEL}", + "name": "${LEVEL} magiker" + }, + "Mine Games": { + "description": "Döda 3 fiender med landminor", + "descriptionComplete": "Dödade 3 fiender med landminor", + "descriptionFull": "Döda 3 fiender med landminor på ${LEVEL}", + "descriptionFullComplete": "Dödade 3 fiender med landminor på ${LEVEL}", + "name": "Minspel" + }, + "Off You Go Then": { + "description": "Kasta ut 3 fiender från kartan", + "descriptionComplete": "Kastade ut 3 fiender från kartan", + "descriptionFull": "Kasta ut 3 fiender från kartan i ${LEVEL}", + "descriptionFullComplete": "Kastade ut 3 fiender från kartan i ${LEVEL}", + "name": "Adjöss med dig" + }, + "Onslaught God": { + "description": "Nå 5000 poäng", + "descriptionComplete": "Nådde 5000 poäng", + "descriptionFull": "Nådde 5000 poäng i ${LEVEL}", + "descriptionFullComplete": "Nådde 5000 poäng i ${LEVEL}", + "name": "${LEVEL} Gud" + }, + "Onslaught Master": { + "description": "Nå 500 poäng", + "descriptionComplete": "Nådde 500 poäng", + "descriptionFull": "Nå 500 poäng på ${LEVEL}", + "descriptionFullComplete": "Nådde 500 poäng i ${LEVEL}", + "name": "${LEVEL} Mästare" + }, + "Onslaught Training Victory": { + "description": "Besegra alla vågor", + "descriptionComplete": "Besegrade alla vågor", + "descriptionFull": "Besegra alla vågor i ${LEVEL}", + "descriptionFullComplete": "Besegrade alla vågor i ${LEVEL}", + "name": "Vinnare av ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Nå 1000 poäng", + "descriptionComplete": "Nådde 1000 poäng", + "descriptionFull": "Nå 1000 poäng i ${LEVEL}", + "descriptionFullComplete": "Nådde 1000 poäng i ${LEVEL}", + "name": "${LEVEL} magiker" + }, + "Precision Bombing": { + "description": "Vinn utan några powerups", + "descriptionComplete": "Vann utan några powerups", + "descriptionFull": "Vinn ${LEVEL} utan några powerups", + "descriptionFullComplete": "Vann ${LEVEL} utan några power-ups", + "name": "Precisionsbombning" + }, + "Pro Boxer": { + "description": "Vinn utan att använda några bomber", + "descriptionComplete": "Vann utan att använda några bomber", + "descriptionFull": "Klara av ${LEVEL} utan att använda några bomber", + "descriptionFullComplete": "Klarade ${LEVEL} utan att använda bomber", + "name": "Proffsboxare" + }, + "Pro Football Shutout": { + "description": "Vinn utan att låta fienden göra mål", + "descriptionComplete": "Vann utan att låta fienden få poäng", + "descriptionFull": "Vinn ${LEVEL} utan att låta fienden få poäng", + "descriptionFullComplete": "Vann ${LEVEL} utan att fienden fick poäng", + "name": "${LEVEL} Shutout" + }, + "Pro Football Victory": { + "description": "Vinn matchen", + "descriptionComplete": "Vann matchen", + "descriptionFull": "Vinn matchen i ${LEVEL}", + "descriptionFullComplete": "Vann matchen i ${LEVEL}", + "name": "Vinnare i ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Klara av alla waves", + "descriptionComplete": "Klarade av alla waves", + "descriptionFull": "Döda alla vågor av ${LEVEL}", + "descriptionFullComplete": "Besegrade alla vågor i ${LEVEL}", + "name": "${LEVEL} Vinst" + }, + "Pro Runaround Victory": { + "description": "Alla vågor avklarade", + "descriptionComplete": "Klarade av alla vågor", + "descriptionFull": "Klarade av alla vågor i ${LEVEL}", + "descriptionFullComplete": "Klarade av alla vågor på ${LEVEL}", + "name": "${LEVEL} Vinst" + }, + "Rookie Football Shutout": { + "description": "Vinn utan att låta fienden få poäng", + "descriptionComplete": "Vann utan att låta fienden få poäng", + "descriptionFull": "Vinn ${LEVEL} utan att låta fienden få poäng", + "descriptionFullComplete": "Vann ${LEVEL} utan att låta fienden få poäng", + "name": "Höll nollan på ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Vinn matchen", + "descriptionComplete": "Vann matchen", + "descriptionFull": "Vinn matchen i ${LEVEL}", + "descriptionFullComplete": "Vann matchen i ${LEVEL}", + "name": "${LEVEL} Vinst" + }, + "Rookie Onslaught Victory": { + "description": "Besegra alla vågor", + "descriptionComplete": "Besegrade alla vågor", + "descriptionFull": "Besegra alla vågor i ${LEVEL}", + "descriptionFullComplete": "Besegrade alla vågor i ${LEVEL}", + "name": "${LEVEL} Vinst" + }, + "Runaround God": { + "description": "Få 2000 poäng", + "descriptionComplete": "Fick 2000 poäng", + "descriptionFull": "Få 2000 poäng i ${LEVEL}", + "descriptionFullComplete": "Fick 2000 poäng i ${LEVEL}", + "name": "${LEVEL}gud" + }, + "Runaround Master": { + "description": "Få 500 poäng", + "descriptionComplete": "Fick 500 poäng", + "descriptionFull": "Få 500 poäng i ${LEVEL}", + "descriptionFullComplete": "Fick 500 poäng i ${LEVEL}", + "name": "Mästare av ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Få 1000 poäng", + "descriptionComplete": "Fick 1000 poäng", + "descriptionFull": "Få 1000 poäng i ${LEVEL}", + "descriptionFullComplete": "Fick 1000 poäng i ${LEVEL}", + "name": "${LEVEL} Magiker" + }, + "Sharing is Caring": { + "descriptionFull": "Lyckas dela spelet med en vän", + "descriptionFullComplete": "Lyckats dela spelet med en vän", + "name": "Att dela är att Bry sig" + }, + "Stayin' Alive": { + "description": "Vinn utan att dö", + "descriptionComplete": "Vann utan att dö", + "descriptionFull": "Vinn ${LEVEL} utan att dö", + "descriptionFullComplete": "Vann ${LEVEL} utan att dö", + "name": "Stayin' Alive" + }, + "Super Mega Punch": { + "description": "Orsaka 100% skada med ett slag", + "descriptionComplete": "Orsakade 100% skada med ett slag", + "descriptionFull": "Orsaka 100% skada med ett slag i ${LEVEL}", + "descriptionFullComplete": "Orsakade 100% skada med ett slag i ${LEVEL}", + "name": "Super Mega Slag" + }, + "Super Punch": { + "description": "Orsaka 50% skada med ett slag", + "descriptionComplete": "Orsakade 50% skada med ett slag", + "descriptionFull": "Orsaka 50% skada med ett slag i ${LEVEL}", + "descriptionFullComplete": "Orsakade 50% skada med ett slag i ${LEVEL}", + "name": "Super Slag" + }, + "TNT Terror": { + "description": "Döda 6 fiender med TNT", + "descriptionComplete": "Dödade 6 fiender med TNT", + "descriptionFull": "Döda 6 fiender med TNT i ${LEVEL}", + "descriptionFullComplete": "Dödade 6 fiender med TNT i ${LEVEL}", + "name": "TNT Terror" + }, + "Team Player": { + "descriptionFull": "Starta ett Team spel med 4+ spelare", + "descriptionFullComplete": "Startade ett Team spel med 4+ spelare", + "name": "Lag Spelare" + }, + "The Great Wall": { + "description": "Stoppa varenda fiende", + "descriptionComplete": "Stoppade varenda fiende", + "descriptionFull": "Stoppa varenda fiende i ${LEVEL}", + "descriptionFullComplete": "Stoppade varenda fiende i ${LEVEL}", + "name": "Den Stora Muren" + }, + "The Wall": { + "description": "Stoppa varenda fiende", + "descriptionComplete": "Stoppade varenda fiende", + "descriptionFull": "Stoppa varenda fiende i ${LEVEL}", + "descriptionFullComplete": "Stoppade varenda fiende i ${LEVEL}", + "name": "Väggen" + }, + "Uber Football Shutout": { + "description": "Vinn utan att låta fienden få poäng", + "descriptionComplete": "Vann utan att låta fienden få poäng", + "descriptionFull": "Vinn ${LEVEL} utan att låta fienden få poäng", + "descriptionFullComplete": "Vann ${LEVEL} utan att låta fienden få poäng", + "name": "Nollan i ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Vinn matchen", + "descriptionComplete": "Vann matchen", + "descriptionFull": "Vinn matchen i ${LEVEL}", + "descriptionFullComplete": "Vann matchen i ${LEVEL}", + "name": "Vinst i ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Besegra alla vågor", + "descriptionComplete": "Besegrade alla vågor", + "descriptionFull": "Besegra alla vågor i ${LEVEL}", + "descriptionFullComplete": "Besegrade alla vågor i ${LEVEL}", + "name": "${LEVEL} Vinst" + }, + "Uber Runaround Victory": { + "description": "Klara av alla vågor", + "descriptionComplete": "Alla vågor avklarade", + "descriptionFull": "Klara av alla vågor på ${LEVEL}", + "descriptionFullComplete": "Alla vågor på ${LEVEL} avklarade", + "name": "${LEVEL} Vinst" + } + }, + "achievementsRemainingText": "Prestationer som återstår:", + "achievementsText": "Prestationer", + "achievementsUnavailableForOldSeasonsText": "Tyvärr, prestation detaljerna är inte tillgängliga för gamla säsonger.", + "addGameWindow": { + "getMoreGamesText": "Hämta Fler Spel...", + "titleText": "Lägg till Spel" + }, + "allowText": "Tillåt", + "alreadySignedInText": "Ditt konto är redan inloggat på en annan enhet;\nvar god byt konto eller stäng spelet på dina\nandra enheter och försök igen.", + "apiVersionErrorText": "Kan inte öppna ${NAME}; den änvänder api-version ${VERSION_USED}; det krävs dock ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Auto\" aktiverar endast detta när hörlurar är inkopplade)", + "headRelativeVRAudioText": "Huvud-Relativt VR Audio", + "musicVolumeText": "Musik Volym", + "soundVolumeText": "Ljud Volym", + "soundtrackButtonText": "Soundtrack", + "soundtrackDescriptionText": "(Lägg till egen musik att lyssna på i spelet)", + "titleText": "Audio" + }, + "autoText": "Automatiskt", + "backText": "Tillbaka", + "banThisPlayerText": "Banna Denna Spelare", + "bestOfFinalText": "Bäst-av-${COUNT} Final", + "bestOfSeriesText": "Bäst av ${COUNT} serier:", + "bestRankText": "Din bästa placering är #${RANK}", + "bestRatingText": "Din bästa rating är ${RATING}", + "betaErrorText": "Denna beta är inte längre aktiv; var snäll kolla efter en ny version.", + "betaValidateErrorText": "Det går inte att validera betan. (Ingen Internetuppkoppling?)", + "betaValidatedText": "Beta Validerad; Njut av spelet!", + "bombBoldText": "BOMB", + "bombText": "Bomb", + "boostText": "Höj", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} är konfigurerad i appen själv.", + "buttonText": "Knapp", + "canWeDebugText": "Vill du att BombSquad automatiskt ska skicka bug, - och crashrapporter och grundläggande användarinfo till utvecklaren?\n\nDenna data innehåller ingen personlig information och\nhjälper till med att låta spelet flyta jämnt och felfritt.", + "cancelText": "Avbryt", + "cantConfigureDeviceText": "Tyvärr, ${DEVICE} är inte konfigurerbar", + "challengeEndedText": "Denna utmaning är avslutad.", + "chatMuteText": "Stänga av chatten", + "chatMutedText": "Chatt dämpad", + "chatUnMuteText": "Avsluta chatt", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Du måste klara\ndenna nivå för att fortsätta!", + "completionBonusText": "Slutbonus", + "configControllersWindow": { + "configureControllersText": "Konfigurera Styrenheter", + "configureGamepadsText": "Konfigurera Gamepads", + "configureKeyboard2Text": "Konfigurera Tangentbord P2", + "configureKeyboardText": "Konfigurera Tangentbord", + "configureMobileText": "Mobila Enheter som Styrenheter", + "configureTouchText": "Konfigurera Touchskärm", + "ps3Text": "PS3 Kontroller", + "titleText": "Kontroller", + "wiimotesText": "Wiimotes", + "xbox360Text": "Xbox 360 Kontroller" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Notera: styrenhetsstöd varierar med enhet och Androidversion.", + "pressAnyButtonText": "Tryck valfri knapp på den styrenhet\nsom du vill konfigurera...", + "titleText": "Konfigurera Styrenheter" + }, + "configGamepadWindow": { + "advancedText": "Avancerat", + "advancedTitleText": "Avancerade Inställningar För Styrenheter", + "analogStickDeadZoneDescriptionText": "(öka denna om spelaren 'glider' när du släpper spaken)", + "analogStickDeadZoneText": "Analog spak Dead Zone", + "appliesToAllText": "(gäller alla styrenheter av denna typ)", + "autoRecalibrateDescriptionText": "(slå på denna om din spelare inte springer med full hastighet)", + "autoRecalibrateText": "Autokalibrera analog spak", + "axisText": "axel", + "clearText": "rensa", + "dpadText": "dpad", + "extraStartButtonText": "Extra Start Knapp", + "ifNothingHappensTryAnalogText": "Om ingenting händer, försök tilldela analog spak istället.", + "ifNothingHappensTryDpadText": "Om ingenting händer, försök tilldela dpad istället.", + "ignoreCompletelyDescriptionText": "(förhindra den här kontrollen från att påverka både spelet och menyerna)", + "ignoreCompletelyText": "Ignorera Fullständigt", + "ignoredButton1Text": "Ignorerad Knapp 1", + "ignoredButton2Text": "Ignorerad Knapp 2", + "ignoredButton3Text": "Ignorerad Knapp 3", + "ignoredButton4Text": "Ignorerad Knapp 4", + "ignoredButtonDescriptionText": "(använd denna för att förhindra 'home' och 'sync' knappar från att påverka UI)", + "ignoredButtonText": "Ignorerad Knapp", + "pressAnyAnalogTriggerText": "Tryck på valfri analog trigger", + "pressAnyButtonOrDpadText": "Tryck på valfri knapp eller dpad...", + "pressAnyButtonText": "Tryck på valfri knapp...", + "pressLeftRightText": "Tryck vänster eller höger...", + "pressUpDownText": "Tryck upp eller ned...", + "runButton1Text": "Springknapp 1", + "runButton2Text": "Springknapp 2", + "runTrigger1Text": "Springavtryckare 1", + "runTrigger2Text": "Springavtryckare 2", + "runTriggerDescriptionText": "(analoga avtryckare låter dig springa med varierande hastighet)", + "secondHalfText": "Använd denna för att konfigurera\nandra halvan av 2-i-1 styrenhet\nsom visas som en styrenhet.", + "secondaryEnableText": "Tillåt", + "secondaryText": "Andra Styrenhet", + "startButtonActivatesDefaultDescriptionText": "(stäng av om startknappen är mer som en menyknapp)", + "startButtonActivatesDefaultText": "Startknapp aktiverar standardwidget", + "titleText": "Inställningar För Styrenheter", + "twoInOneSetupText": "Inställningar för 2-i-1 styrenhet", + "uiOnlyDescriptionText": "(förhindra den här kontrollen från att delta i ett spel)", + "uiOnlyText": "Begränsa till Menyer", + "unassignedButtonsRunText": "Alla icke tilldelade knappar - Spring", + "unsetText": "", + "vrReorientButtonText": "VR Omorienterings Knapp" + }, + "configKeyboardWindow": { + "configuringText": "Konfigurerar ${DEVICE}", + "keyboard2NoteText": "Notera: de flesta tangentbord kan endast registrera några få\ntangenttryckningar på en gång. Att låta en andra spelare\nanvända ett separat tangentbord kan fungera bättre. \nNotera att separata knappar måste tilldelas för de bägge\nspelarna även med dubbla tangentbord." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Handlings Kontroll Skala", + "actionsText": "Handlingar", + "buttonsText": "knappar", + "dragControlsText": "< dra kontroller för att återpositionera dem >", + "joystickText": "joystick", + "movementControlScaleText": "Rörelse Kontroll Skala", + "movementText": "Rörelse", + "resetText": "Återställ", + "swipeControlsHiddenText": "Dölj Swipe Ikoner", + "swipeInfoText": "'Swipe' kontroller tar lite tid att vänja sig vid, \nmen gör det lättare att spela utan att titta på skärmen.", + "swipeText": "swipe", + "titleText": "Konfigurera touchscreen", + "touchControlsScaleText": "Touchkontroll skalning" + }, + "configureItNowText": "Konfigurera nu?", + "configureText": "Konfigurera", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "För bästa resultat behöver du ett responsivt wifinätverk.\nDu kan förbättra spelupplevelsen genom att stäng av\nandra wifi-enheter eller spela nära din wifi-router.\nDu kan också koppla upp spelet direkt via ethernet.", + "explanationText": "För att använda en smartphone eller tablet som styrenhet,\ninstallera appen \"${REMOTE_APP_NAME}\". Obegränsat antal enheter \nkan anslutas för ${APP_NAME} spel över wifi, och det är gratis!", + "forAndroidText": "för Android:", + "forIOSText": "för iOS:", + "getItForText": "Hämta ${REMOTE_APP_NAME} för iOS i Apple App Store\neller för Android i Google Play Store eller Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Använder Mobila Enheter som Styrenheter" + }, + "continuePurchaseText": "Fortsätt i ${PRICE}?", + "continueText": "fortsätta", + "controlsText": "Styrenhet", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Detta gäller inte för alla-time ranking.", + "activenessInfoText": "Denna multiplikator stiger på dagar när du\nspela och droppar på dagar när du inte gör det.", + "activityText": "Aktivitet", + "campaignText": "Kampanj", + "challengesInfoText": "Samla priser för avslutade mini-spel\n\nPriser och svårighetsgraden ökar varje \ngång en utmaning slutförs och minskar \nnär den förfaller eller förverkats.", + "challengesText": "Utmaningar", + "currentBestText": "Nuvarande Rekord", + "customText": "Anpassad", + "entryFeeText": "Avgift", + "forfeitConfirmText": "Ge upp denna utmaning?", + "forfeitNotAllowedYetText": "Denna utmaning kan inte förverkas än", + "forfeitText": "Ge upp", + "multipliersText": "Multiplikatorer", + "nextChallengeText": "Nästa utmaning", + "nextPlayText": "Nästa spel", + "ofTotalTimeText": "av ${TOTAL}", + "playNowText": "Spela nu", + "pointsText": "Poäng", + "powerRankingFinishedSeasonUnrankedText": "(Icke rankad avslutad säsong)", + "powerRankingNotInTopText": "(inte i top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} poäng", + "powerRankingPointsMultText": "(x ${NUMBER} poäng)", + "powerRankingPointsText": "${NUMBER} pts", + "powerRankingPointsToRankedText": "(${CURRENT} på ${REMAINING} pts)", + "powerRankingText": "Spelar Rankning", + "prizesText": "Priser", + "proMultInfoText": "Spelare med ${PRO} uppgradering\nfå en ${PERCENT}% punkt uppsving här.", + "seeMoreText": "Mer...", + "skipWaitText": "Skippa väntetiden", + "timeRemainingText": "Tid Kvar", + "titleText": "Co-op", + "toRankedText": "Till Rankat", + "totalText": "totalt", + "tournamentInfoText": "Tävla om att få högsta poäng\nmot andra spelare i din liga.\n\nPriser tilldelas de spelare med högst \npoäng när tiden för turneringen runnit ut.", + "welcome1Text": "Välkommen till ${LEAGUE}. Du kan förbättra din\nTabellplacering genom att tjäna stjärnklassificeringar , slutföra\nprestationer , och vinnande troféer i turneringar .", + "welcome2Text": "Du kan också tjäna biljetter från många av samma verksamhet .\nBiljetter kan användas för att låsa upp nya karaktärer, kartor och\nmini -spel , att delta i turneringar och mycket mer .", + "yourPowerRankingText": "Din Spelar Rankning" + }, + "copyOfText": "${NAME} Kopia", + "copyText": "Kopiera", + "createAPlayerProfileText": "Skapa en spelarprofil?", + "createEditPlayerText": "", + "createText": "Skapa", + "creditsWindow": { + "additionalAudioArtIdeasText": "Tilläggsmusik, tidig grafik och idéer av ${NAME}", + "additionalMusicFromText": "Tilläggsmusik från ${NAME}", + "allMyFamilyText": "Alla mina vänner och familj som hjälpte till att testa", + "codingGraphicsAudioText": "Programmering, grafik och ljud av ${NAME}", + "languageTranslationsText": "Språköversättning:", + "legalText": "Rättsligt:", + "publicDomainMusicViaText": "Public domain musik via ${NAME}", + "softwareBasedOnText": "Denna mjukvara är delvis baserad på verk av ${NAME}", + "songCreditText": "${TITLE} Framförd av ${PERFORMER}\nKomponerad av ${COMPOSER}. Arrangerad av ${ARRANGER}. Publiserad av ${PUBLISHER}.\nMed tillstånd av ${SOURCE}", + "soundAndMusicText": "Ljud och musik:", + "soundsText": "Ljud (${SOURCE}):", + "specialThanksText": "Särskilda tack:", + "thanksEspeciallyToText": "Tack, särskilt, till ${NAME}", + "titleText": "${APP_NAME} Eftertexter", + "whoeverInventedCoffeeText": "Den som uppfann kaffe" + }, + "currentStandingText": "Din nuvarande ställning är #${RANK}", + "customizeText": "Redigera...", + "deathsTallyText": "Dödad ${COUNT} gånger", + "deathsText": "Dödad", + "debugText": "debug", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Notering: rekommendetionen är att man ställer Inställningar->Grafik->Texturer till 'Hög' innan testet körs.", + "runCPUBenchmarkText": "Kör CPU Benchmark", + "runGPUBenchmarkText": "Kör GPU Benchmark", + "runMediaReloadBenchmarkText": "Kör Media-Omladdning Benchmark", + "runStressTestText": "Kör stresstest", + "stressTestPlayerCountText": "Antal spelare", + "stressTestPlaylistDescriptionText": "Stresstest Spelarlista", + "stressTestPlaylistNameText": "Spellista namn", + "stressTestPlaylistTypeText": "Spellista typ", + "stressTestRoundDurationText": "Rundans varaktighet", + "stressTestTitleText": "Stresstest", + "titleText": "Benchmark och Stress Tester", + "totalReloadTimeText": "Total omladdnings tid: ${TIME} (se loggen för detaljer)", + "unlockCoopText": "Lås up co-op nivåer" + }, + "defaultFreeForAllGameListNameText": "Standard fritt-för-alla Spel", + "defaultGameListNameText": "Standard ${PLAYMODE} Spellista", + "defaultNewFreeForAllGameListNameText": "Mina Free-for-All Spel", + "defaultNewGameListNameText": "Min ${PLAYMODE} Spellista", + "defaultNewTeamGameListNameText": "Mina Lagspel", + "defaultTeamGameListNameText": "Standard Lagspel", + "deleteText": "Radera", + "demoText": "Demo", + "denyText": "Neka", + "desktopResText": "Skrivbordsupplösning", + "difficultyEasyText": "Lätt", + "difficultyHardOnlyText": "Endast Svårt Läge", + "difficultyHardText": "Svår", + "difficultyHardUnlockOnlyText": "Denna bana kan bara låsas up i svårt läge.\nTror du att du har det som krävs!?!?!", + "directBrowserToURLText": "Var god besök följande URL med en webbläsare:", + "disableRemoteAppConnectionsText": "Inaktivera Fjärrapps-Anslutningar", + "disableXInputDescriptionText": "Tillåter mer än 4 kontroller men kanske inte funkar så bra.", + "disableXInputText": "Inaktivera XInput", + "doneText": "Klar", + "drawText": "Oavgjort", + "duplicateText": "Fördubbla", + "editGameListWindow": { + "addGameText": "Lägg till\nSpel", + "cantOverwriteDefaultText": "Kan inte skriva över standardspellistan!", + "cantSaveAlreadyExistsText": "En spellista med det namnet finns redan!", + "cantSaveEmptyListText": "Kan inte spara en tom spellista!", + "editGameText": "Redigera\nSpel", + "gameListText": "Spellista", + "listNameText": "Spellistnamn", + "nameText": "Namn", + "removeGameText": "Ta Bort\nSpel", + "saveText": "Spara lista", + "titleText": "Spelliste Editor" + }, + "editProfileWindow": { + "accountProfileInfoText": "Den här speciella profilen har ett namn\noch en icon baserat på ditt konto.\n\n${ICONS}\n\nSkapa en anpassad profil för att använda\nolika namn eller anpassade ikoner.", + "accountProfileText": "(Kontoprofil)", + "availableText": "Namnet \"${NAME}\" är tillgängligt.", + "changesNotAffectText": "Notera: ändringar påverkar inte spelare inne i ett spel", + "characterText": "karaktär", + "checkingAvailabilityText": "Kontrollerar tillgängligheten för \"${NAME}\"...", + "colorText": "färg", + "getMoreCharactersText": "Skaffa fler karaktärer...", + "getMoreIconsText": "Skaffa fler ikoner...", + "globalProfileInfoText": "Globala spelarprofiler är garanterade att ha unika, \nvärldsomspännande namn. De inkluderar också specialikoner.", + "globalProfileText": "(global profil)", + "highlightText": "highlight", + "iconText": "ikon", + "localProfileInfoText": "Lokala spelarprofiler har inga ikoner och namnet är \ninte garanterat att vara unikt. Uppdatera till en global \nprofil för att kunna använda ett unikt namn och ikon.", + "localProfileText": "(lokal profil)", + "nameDescriptionText": "Spelarnamn", + "nameText": "Namn", + "randomText": "slumpvis", + "titleEditText": "Redigera Profil", + "titleNewText": "Ny Profil", + "unavailableText": "\"${NAME}\" är upptaget; försök med ett annat namn.", + "upgradeProfileInfoText": "Det här kommer att skydda ditt spelar namn världen över \nsamt låta dig tilldela en specialikon till profilen.", + "upgradeToGlobalProfileText": "Uppgradera till en global profil" + }, + "editProfilesAnyTimeText": "(du kan redigera profiler när du vill under 'inställningar')", + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Du kan inte ta bort standardsoundtracket.", + "cantEditDefaultText": "Kan inte redigera standardsoundtrack. Duplicera eller skapa ett nytt.", + "cantOverwriteDefaultText": "Kan inte skriva över standardsoundtrack", + "cantSaveAlreadyExistsText": "Ett soundtrack med det namnet finns redan!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Standardsoundtrack", + "deleteConfirmText": "Ta bort soundtrack:\n'${NAME}'?", + "deleteText": "Ta Bort\nSoundtrack", + "duplicateText": "Duplicera\nSoundtrack", + "editSoundtrackText": "Soundtrack Editor", + "editText": "Redigera\nSoundtrack", + "fetchingITunesText": "hämtar spellistor från Music App...", + "musicVolumeZeroWarning": "Varning: Musikvolym är satt till 0", + "nameText": "Namn", + "newSoundtrackNameText": "Mitt Soundtrack ${COUNT}", + "newSoundtrackText": "Nytt Soundtrack:", + "newText": "Ny\nSoundtrack", + "selectAPlaylistText": "Välj en Spellista", + "selectASourceText": "Musikkälla", + "soundtrackText": "Ljudspår", + "testText": "test", + "titleText": "Soundtrack", + "useDefaultGameMusicText": "Standard Spelmusik", + "useITunesPlaylistText": "Musik-app spellista", + "useMusicFileText": "Musikfil (mp3, etc)", + "useMusicFolderText": "Mappnamn för Musikfiler" + }, + "editText": "Redigera", + "endText": "slut", + "enjoyText": "Ha det så roligt!", + "epicDescriptionFilterText": "${DESCRIPTION} i episk slow moition.", + "epicNameFilterText": "Episk ${NAME}", + "errorAccessDeniedText": "åtkomst nekad", + "errorOutOfDiskSpaceText": "slut på diskutrymme", + "errorText": "Fel", + "errorUnknownText": "okänt fel", + "exitGameText": "Avsluta ${APP_NAME}?", + "exportSuccessText": "'${NAME}' exporterad.", + "externalStorageText": "Extern Lagring", + "failText": "Misslyckades", + "fatalErrorText": "Hoppsan; något saknas eller är trasigt.\nVänligen försök att ominstallera appen\neller kontakta ${EMAIL} för hjälp.", + "fileSelectorWindow": { + "titleFileFolderText": "Välj en Fil eller Mapp", + "titleFileText": "Välj en Fil", + "titleFolderText": "Välj en Mapp", + "useThisFolderButtonText": "Använd Denna Mapp" + }, + "filterText": "Filter", + "finalScoreText": "Slutgiltig Poäng", + "finalScoresText": "Slutgiltiga Poäng", + "finalTimeText": "Slutgiltig Tid", + "finishingInstallText": "Slutför installationen; ett ögonblick...", + "fireTVRemoteWarningText": "* För en bättre upplevelse, använd\nSpelkontroller eller installera\n'${REMOTE_APP_NAME}' appen på din\ntelefon och surfplatta.", + "firstToFinalText": "Först-till-${COUNT} Final", + "firstToSeriesText": "Först-till-${COUNT} Serie", + "fiveKillText": "FIVE KILL!!!", + "flawlessWaveText": "Felfri Våg", + "fourKillText": "QUAD KILL!!!", + "freeForAllText": "Free-for-All", + "friendScoresUnavailableText": "Vänners poäng otillgängligt", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Spel ${COUNT} Ledare", + "gameListWindow": { + "cantDeleteDefaultText": "Det går inte att ta bort standardspellistan!", + "cantEditDefaultText": "Kan inte redigera standardspellistan! Duplicera eller skapa en ny.", + "cantShareDefaultText": "Du kan inte dela standard spellistan.", + "deleteConfirmText": "Ta Bort \"${LIST}\"?", + "deleteText": "Ta Bort\nSpellista", + "duplicateText": "Duplicera\nSpellista", + "editText": "Redigera\nSpellista", + "gameListText": "Spellista", + "newText": "Ny\nSpellista", + "showTutorialText": "Visa Handledning", + "shuffleGameOrderText": "Blanda spel-ordning", + "titleText": "Redigera ${TYPE} Spellistor" + }, + "gameSettingsWindow": { + "addGameText": "Lägg till spel" + }, + "gamepadDetectedText": "1 gamepad upptäckt.", + "gamepadsDetectedText": "${COUNT} gamepads upptäckta", + "gamesToText": "${WINCOUNT} spel mot ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Kom ihåg: enheter anslutna till ett sällskap kan ha mer \nän en spelare om det finns tillräckligt med styrenheter.", + "aboutDescriptionText": "Använd dessa flikar för att samla ett sällskap.\n\nSällskap gör det möjligt att spela spel och \nturneringar med dina vänner på olika enheter.\n\nAnvänd ${PARTY} knappen i övre högra hörnet \nför att chatta och interagera med sällskapet.\n(på en styrenhet, tryck ${BUTTON} medan en meny visas)", + "aboutText": "Om", + "addressFetchErrorText": "", + "appInviteInfoText": "Bjud in vänner att prova BombSquad så får de \n${COUNT} gratis biljetter och du får ${YOU_COUNT} \nför varje vän som gör det. ", + "appInviteMessageText": "${NAME} skickade ${COUNT} biljetter till dig i ${APP_NAME}", + "appInviteSendACodeText": "Skicka en kod till dem..", + "appInviteTitleText": "Inbjudan att ladda ner ${APP_NAME}", + "bluetoothAndroidSupportText": "(fungerar med alla Android enheter som stöder Bluetooth)", + "bluetoothDescriptionText": "Agera värd/anslut till sällskap över Bluetooth:", + "bluetoothHostText": "Aggera värd över Bluetooth", + "bluetoothJoinText": "Anslut över Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "kontrollerar...", + "copyCodeConfirmText": "Koden har kopierats till urklipp.", + "copyCodeText": "Kopiera kod", + "dedicatedServerInfoText": "För bästa resultat, skapa en dedikerad server. Gå till bombsquadgame.com/server för att lära dig hur.", + "disconnectClientsText": "Detta gör att ${COUNT} spelare kopplas \nifrån ditt sällskap. Är du säker?", + "earnTicketsForRecommendingAmountText": "Vänner kommer få ${COUNT} biljetter om dom testar spelet\n(och du kommer få ${YOU_COUNT} för varje person som testar)", + "earnTicketsForRecommendingText": "Dela spelet med andra\nOch få fribiljetter...", + "emailItText": "Mejla Det", + "favoritesSaveText": "Spara som favorit", + "favoritesText": "Favoriter", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME}-biljetter från ${NAME}", + "friendPromoCodeAwardText": "Du kommer få ${COUNT} biljetter varje gång den används.", + "friendPromoCodeExpireText": "Den här koden kommer sluta fungera om ${EXPIRE_HOURS} timmar och fungerar bara för nya spelare.", + "friendPromoCodeInstructionsText": "För att använda den, öppna ${APP_NAME} och gå till \"Inställningar->Avancerat->Skriv in Promo Kod\".\nBesök bombsquadgame.com för nerladdnings-länkar till alla platformar som stöds.", + "friendPromoCodeRedeemLongText": "Den kan lösas in mot ${COUNT} gratis biljetter för upp till ${MAX_USES} personer.", + "friendPromoCodeRedeemShortText": "Den kan lösas in för ${COUNT} biljetter i spelet.", + "friendPromoCodeWhereToEnterText": "(i \"Inställningar->Avancerat->Skriv Promo Kod\")", + "getFriendInviteCodeText": "Få Inbjudnings-Kod för Vänner", + "googlePlayDescriptionText": "Bjud in Google Play spelare till ditt sällskap:", + "googlePlayInviteText": "Bjud In", + "googlePlayReInviteText": "Det finns ${COUNT} Google Play spelare i ditt sällskap\nsom kommer att kopplas ifrån om du gör en ny inbjudan.\nInkludera dem i nya inbjudan för att ha dem kvar.", + "googlePlaySeeInvitesText": "Se Inbjudningar", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play version)", + "hostPublicPartyDescriptionText": "Var värd för Offentligt Spel:", + "inDevelopmentWarningText": "Notera:\n\nSällskap är en ny och ofärdig funktionalitet.\nFör tillfället är det rekommenderat att alla\nspelare är på samma Wi-Fi nätverk.", + "internetText": "Internet", + "inviteAFriendText": "Har dina vänner inte spelet? Bjud in dem att\nprova så får de ${COUNT} fribiljetter.", + "inviteFriendsText": "Bjud in vänner", + "joinPublicPartyDescriptionText": "Anslut till Offentligt Spel:", + "localNetworkDescriptionText": "Anslut till ett sällskap på ditt nätverk:", + "localNetworkText": "Lokalt Nätverk", + "makePartyPrivateText": "Gör Mitt Spel Privat", + "makePartyPublicText": "Gör Mitt Spel Offentligt", + "manualAddressText": "Adress", + "manualConnectText": "Anslut", + "manualDescriptionText": "Anslut till sällskap via adress:", + "manualJoinableFromInternetText": "Kan man ansluta till dig via internet?:", + "manualJoinableNoWithAsteriskText": "NEJ*", + "manualJoinableYesText": "JA", + "manualRouterForwardingText": "*för att åtgärda detta, konfigurera routern så att den vidarebefordrar UDP port ${PORT} till din lokala adress", + "manualText": "Manuellt", + "manualYourAddressFromInternetText": "Din publika internet adress:", + "manualYourLocalAddressText": "Din lokala adress:", + "noConnectionText": "", + "otherVersionsText": "(andra versioner)", + "partyInviteAcceptText": "Acceptera", + "partyInviteDeclineText": "Neka", + "partyInviteGooglePlayExtraText": "(Se 'Google Play' fliken i 'Samla' fönstret)", + "partyInviteIgnoreText": "Ignorera", + "partyInviteText": "${NAME} har bjudit in \ndig till sitt sällskap!", + "partyNameText": "Spelnamn", + "partySizeText": "antal spelare", + "partyStatusCheckingText": "kontrollerar status...", + "partyStatusJoinableText": "ditt spel kan nu anslutas till från internet", + "partyStatusNoConnectionText": "kunde inte koppla till server", + "partyStatusNotJoinableText": "ditt spel kan inte anslutas till från internet", + "partyStatusNotPublicText": "ditt spel är inte offentligt", + "pingText": "ping", + "portText": "Port", + "requestingAPromoCodeText": "Efterfrågar en kod...", + "sendDirectInvitesText": "Skicka inbjudningar direkt", + "sendThisToAFriendText": "Skicka denna koden till en vän:", + "shareThisCodeWithFriendsText": "Dela den här koden med vänner:", + "showMyAddressText": "Visa Min Adress", + "titleText": "Samla", + "wifiDirectDescriptionBottomText": "Om alla enheter har en 'Wi-Fi Direct' panel, borde de kunna använda den för att hitta\noch ansluta till varandra. När alla enheter är anslutna, kan man skapa näverksspel\nhär genom att använda fliken 'Lokalt Nätverk' precis som med ett vanligt Wi-Fi nätverk.\n\nFör bästa resultat bör Wi-Fi Direct värden även vara ${APP_NAME} sällskapsvärd.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct kan användas för att ansluta Android enheter direkt utan\nett Wi-Fi nätverk. Detta funkar bäst på Android 4.2 eller senare.\n\nAktivera genom att öppna Wi-Fi inställingar och hitta 'Wi-Fi Direct' i menyn.", + "wifiDirectOpenWiFiSettingsText": "Öppna Wi-Fi Inställnigar", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(fungerar mellan alla plattformar)", + "worksWithGooglePlayDevicesText": "(fungerar med alla enheter som kör Google Play (android) version av spelet)", + "youHaveBeenSentAPromoCodeText": "Du har fått en promo kod för ${APP_NAME}:" + }, + "getCoinsWindow": { + "coinDoublerText": "Myntfördubblare", + "coinsText": "${COUNT} mynt", + "freeCoinsText": "Gratis Mynt", + "restorePurchasesText": "Återställ Köp", + "titleText": "Skaffa Mynt" + }, + "getTicketsWindow": { + "freeText": "GRATIS!", + "freeTicketsText": "Gratis Värdekuponger", + "inProgressText": "En transaktion är pågående; försök igen om en stund.", + "purchasesRestoredText": "Inköp återställts.", + "receivedTicketsText": "Du har fått ${COUNT} värdekuponger!", + "restorePurchasesText": "Återställ Köp", + "ticketDoublerText": "Värdekupongsdubblerare", + "ticketPack1Text": "Värdekupongspaket - Liten", + "ticketPack2Text": "Värdekupongspaket - Mellan", + "ticketPack3Text": "Värdekupongspaket - Stor", + "ticketPack4Text": "Värdekupongspaket - Jumbo", + "ticketPack5Text": "Värdekupongspaket - Mammut", + "ticketPack6Text": "Ultimata Värdekupongspaketet", + "ticketsFromASponsorText": "Få ${COUNT} värdekuponger\nfrån en sponsor", + "ticketsText": "${COUNT} Värdekuponger", + "titleText": "Skaffa Värdekuponger", + "unavailableLinkAccountText": "Tyvärr, köp är inte tillgängliga på den här plattformen.\nSom en lösning kan du länka detta konto till ett konto på\nen annan plattform och gör inköp där.", + "unavailableTemporarilyText": "Detta är inte tillgänglig för tillfället; försök igen senare.", + "unavailableText": "Tyvärr, detta är inte tillgängligt.", + "versionTooOldText": "Tyvärr, denna version av spelet är för gammalt; vänligen uppgradera till en nyare.", + "youHaveShortText": "du har ${COUNT}", + "youHaveText": "du har ${COUNT} värdekuponger" + }, + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Alltid", + "fullScreenCmdText": "Fullskärm (Cmd-F)", + "fullScreenCtrlText": "Fullskärm (Ctrl-F)", + "gammaText": "Gamma", + "highText": "Hög", + "higherText": "Högre", + "lowText": "Låg", + "mediumText": "Medium", + "neverText": "Aldrig", + "resolutionText": "Upplösning", + "showFPSText": "Visa FPS", + "texturesText": "Texturer", + "titleText": "Grafik", + "tvBorderText": "TV-kant", + "verticalSyncText": "Vertical Sync", + "visualsText": "Visuellt" + }, + "helpWindow": { + "bombInfoText": "- Bomb -\nKraftfullare än slag, men \nkastaren riskerar svåra skador\nFör bästa resultat, kasta mot \nfienden innan stubinen brunnit ut.", + "canHelpText": "${APP_NAME} kan hjälpa.", + "controllersInfoText": "Du kan spela ${APP_NAME} med vänner över nätverk, eller så\nkan alla spela på samma enhet om du har tillräckligt med styrenheter.\n${APP_NAME} stöder en uppsjö av dem; du kan till och med använda\nmobiler som enheter via gratisappen '${REMOTE_APP_NAME}'.\nSe Inställningar->Styrenheter för mer info.", + "controllersInfoTextFantasia": "En spelare kan använda fjärrkontrollen som styrenhet, men\ngamepads rekommenderas starkt. Du kan också använda dina\nmobila enheter som styrenheter via appen 'BombSquad Remote'\nsom är gratis. Se 'Styrenheter' under 'Inställningar' för mer info.", + "controllersInfoTextMac": "En eller två spelare kan använda tangentbordet men BombSquad är bäst med gamepads.\nBombSquad kan använda USB gamepads, PS3- eller Xbox 360 styrenheter,\nWiimotes och iOS-/Androidenheter för att kontrollera spelaren. Förhoppningsvis har du \nnågon av dessa att tillgå. Se 'Styrenheter' under 'Inställningar' för mer info.", + "controllersInfoTextOuya": "Du kan använda OUYA kontroller, PS3 kontroller, Xbox 360 kontroller \noch många andra USB och Bluetooth kontroller med BombSquad. \nDu kan även använda iOS och Android enheter som kontroll via \ngratis-appen 'BombSquad Remote'. Se 'Kontroller' under 'Inställningar' för mer info.", + "controllersText": "Styrenheter", + "controlsSubtitleText": "Din vänliga ${APP_NAME}-karaktär har några grundläggande handlingar:", + "controlsText": "Kontroller", + "devicesInfoText": "VR versionen av ${APP_NAME} kan spelas över nätverk med en vanlig\nversion, så ta fram dina extra mobiler, surfplattor och datorer\noch sätt igång. Det kan även vara användbart att koppla upp en \nvanlig version av spelet till VR versionen så att andra kan \nfå se vad som händer i spelet.", + "devicesText": "Enheter", + "friendsGoodText": "Dessa är bra att ha. ${APP_NAME} är roligast med flera spelare\noch stöder upp till åtta åt gången, vilket osökt leder oss till:", + "friendsText": "Vänner", + "jumpInfoText": "- Hoppa -\nHoppa mellan små luckor,\nför att kasta högre och för \natt uttrycka lyckokänslor.", + "orPunchingSomethingText": "Eller slå på någonting, kasta det över kanten eller spräng det på vägen ner med en klisterbomb.", + "pickUpInfoText": "- Plocka upp -\nLyft upp flaggor, fiender eller vad \nsom helst som inte är fastspikat.\nTryck igen för att kasta.", + "powerupBombDescriptionText": "Låter dig kasta ut tre bomber på raken \nistället för bara en i taget.", + "powerupBombNameText": "Tripplebomber", + "powerupCurseDescriptionText": "Du vill antagligen undvika dessa.\n...eller?", + "powerupCurseNameText": "Förbannelse", + "powerupHealthDescriptionText": "Återställer dig till full hälsa.\nDet kunde du inte gissa.", + "powerupHealthNameText": "Första hjälpen", + "powerupIceBombsDescriptionText": "Svagare än vanliga bomber\nmen fryser dina fiender och \ngör dem väldigt sköra", + "powerupIceBombsNameText": "Isbomber", + "powerupImpactBombsDescriptionText": "Något svagare än vanliga bomber,\nmen exploderar vid träff.", + "powerupImpactBombsNameText": "Utlösningbomber", + "powerupLandMinesDescriptionText": "Dessa kommer i trepack;\nAnvändbart för försvar eller\nför att stoppa snabba fiender.", + "powerupLandMinesNameText": "Landminor", + "powerupPunchDescriptionText": "Gör din slag hårdare,\nsnabbare, bättre, starkare.", + "powerupPunchNameText": "Boxarhandskar", + "powerupShieldDescriptionText": "Absorberar lite skada,\nså att du slipper.", + "powerupShieldNameText": "Energisköld", + "powerupStickyBombsDescriptionText": "Fastnar på vad de än träffar.\nFestligheter blir följden.", + "powerupStickyBombsNameText": "Klisterbomber", + "powerupsSubtitleText": "Självklart, inget spel är komplett utan power-ups:", + "powerupsText": "Power-ups", + "punchInfoText": "- Slå -\nSlag gör mer skada ju snabbare\ndina knytnävar rör sig, så\nspring och snurra som en galning", + "runInfoText": "- Spring -\nHåll in VALFRI knapp för att springa. Avtryckare och sidoknappar fungerar också om du har det.\nAtt springa tar dig fram snabbare men gör det svårare att svänga, så akta dig för stupen.", + "someDaysText": "Vissa dagar känner man för att slå något. Eller för att spränga något.", + "titleText": "BombSquad Hjälp", + "toGetTheMostText": "För att få ut mest av detta spel behöver du:", + "welcomeText": "Välkommen till ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} navigerar nu menyerna som chefen -", + "importPlaylistCodeInstructionsText": "Använd följande kod för att importera den här spellistan någon annanstans:", + "importPlaylistSuccessText": "Importerade ${TYPE} spellistan '${NAME}'", + "importText": "Importera", + "importingText": "Importerar...", + "inGameClippedNameText": "i-spel namn kommer att vara\n\"${NAME}\"", + "installDiskSpaceErrorText": "Fel: Kunde inte slutföra installationen.\nDet kan vara slut på utrymme på din enhet.\nFrigör utrymme och försök igen.", + "internal": { + "arrowsToExitListText": "tryck ${LEFT} eller ${RIGHT} för att avsluta listan", + "buttonText": "knapp", + "cantKickHostError": "Du kan inte sparka ut värden.", + "connectedToPartyText": "Ansluten till ${NAME}s sällskap!", + "connectingToPartyText": "Ansluter...", + "connectionFailedHostAlreadyInPartyText": "Anslutning misslyckades; värden är ansluten till annat sällskap.", + "connectionFailedPartyFullText": "Gick inte att ansluta; sällskapet är fullt.", + "connectionFailedText": "Anslutning misslyckades.", + "connectionFailedVersionMismatchText": "Anslutning misslyckades; värden kör en annan version av spelet.\nKontrollera att ni båda har senaste versionen och försök igen.", + "connectionRejectedText": "Anslutning avvisad.", + "controllerConnectedText": "${CONTROLLER} ansluten.", + "controllerDetectedText": "1 kontroll upptäckt.", + "controllerDisconnectedText": "${CONTROLLER} frånkopplad.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} frånkopplad. Försök anslut igen.", + "controllerForMenusOnlyText": "Denna kontrollen kan inte användas för spel;\nenbart för att navigera i menyer.", + "controllerReconnectedText": "${CONTROLLER} återansluten.", + "controllersConnectedText": "${COUNT} kontroller anslutna.", + "controllersDetectedText": "${COUNT} kontroller upptäckta.", + "controllersDisconnectedText": "${COUNT} kontroller frånkopplade.", + "corruptFileText": "Korrupta fil(er) detekterade. Vänligen installera om eller maila ${EMAIL}", + "errorPlayingMusicText": "Fel vid uppspelning av musik: ${MUSIC}", + "errorResettingAchievementsText": "Kunde inte återställa online-prestationer; försök igen senare.", + "hasMenuControlText": "${NAME} har menykontrollen.", + "incompatibleVersionHostText": "Värden kör en annan version av spelet.\nKontrollera att ni båda har senaste versionen.", + "incompatibleVersionPlayerText": "${NAME} kör en annan version av spelet.\nKontrollera att ni båda har senaste versionen och försök igen.", + "invalidAddressErrorText": "Fel: ogiltig adress.", + "invitationSentText": "Inbjudan skickad.", + "invitationsSentText": "${COUNT} inbjudan skickade.", + "joinedPartyInstructionsText": "En vän har anslutit till ditt sällskap.\nGå till 'Spela' för att starta spelet.", + "keyboardText": "Tangentbord", + "kickIdlePlayersKickedText": "Sparkar ${NAME} för att vara inaktiv.", + "kickIdlePlayersWarning1Text": "${NAME} kommer bli sparkad om ${COUNT} sekunder om fortfarande inaktiv.", + "kickIdlePlayersWarning2Text": "(Du kan stänga av detta i Inställningar -> Avancerat)", + "leftPartyText": "Lämnat ${NAME}s sällskap.", + "noMusicFilesInFolderText": "Mappen innehåller ingen musikfil.", + "playerJoinedPartyText": "${NAME} anslöt till sällskapet!", + "playerLeftPartyText": "${NAME} lämnade sällskapet.", + "rejectingInviteAlreadyInPartyText": "Avvisar inbjudan (redan ansluten till ett sällskap).", + "signInErrorText": "Kunde inte logga in.", + "signInNoConnectionText": "Kunde inte logga in. (ingen internet anslutning?)", + "teamNameText": "Lag ${NAME}", + "telnetAccessDeniedText": "ERROR: användare har inte godkänt telnet-åtkomst.", + "timeOutText": "(tiden går ut om ${TIME} sekunder)", + "touchScreenJoinWarningText": "Du har anslutit med touchscreen.\nOm detta var ett misstag, tryck 'Meny->Lämna Spel'.", + "touchScreenText": "Pekskärm", + "trialText": "test", + "unavailableNoConnectionText": "Det är otillgängligt för tillfället (ingen internet anslutning?)", + "vrOrientationResetCardboardText": "Använd detta för att återställa VR orientering.\nFör att spela spelet behöver du en extern styrenhet .", + "vrOrientationResetText": "VR orientering nollställd.", + "willTimeOutText": "(kommer att time:a ut om inaktiv)" + }, + "jumpBoldText": "HOPPA", + "jumpText": "Hoppa", + "keepText": "Behåll", + "keepTheseSettingsText": "Behåll dessa inställningar?", + "killsTallyText": "${COUNT} dödade", + "killsText": "Dödade", + "kioskWindow": { + "easyText": "Lätt", + "epicModeText": "Episkt Läge", + "fullMenuText": "Full Meny", + "hardText": "Svår", + "mediumText": "Medium", + "singlePlayerExamplesText": "En spelar / Co-op Exempel", + "versusExamplesText": "Versus Exempel" + }, + "languageSetText": "Språket är nu \"${LANGUAGE}\".", + "lapNumberText": "Varv ${CURRENT}/${TOTAL}", + "lastGamesText": "(sista ${COUNT} spelen)", + "leaderboardsText": "Ledartavlor", + "league": { + "allTimeText": "All Time", + "currentSeasonText": "Nuvarande säsong (${NUMBER})", + "leagueFullText": "${NAME} League", + "leagueRankText": "League Rank", + "leagueText": "League", + "rankInLeagueText": "#${RANK}, ${NAME} League${SUFFIX}", + "seasonEndedDaysAgoText": "Säsong slutade ${NUMBER} dagar sedan.", + "seasonEndsDaysText": "Säsong slutar i ${NUMBER} dagar.", + "seasonEndsHoursText": "Säsong slutar i ${NUMBER} timmar.", + "seasonEndsMinutesText": "Säsongen slutar i ${NUMBER} minuter.", + "seasonText": "Säsong ${NUMBER}", + "tournamentLeagueText": "Du måste nå ${NAME} ligan att gå in här turneringen.", + "trophyCountsResetText": "Trophy räknas återställs nästa säsong." + }, + "levelFastestTimesText": "Bästa tiderna på ${LEVEL}", + "levelHighestScoresText": "Högsta poäng på ${LEVEL}", + "levelIsLockedText": "${LEVEL} är låst.", + "levelMustBeCompletedFirstText": "${LEVEL} måste klaras av först.", + "levelText": "Nivå ${NUMBER}", + "levelUnlockedText": "Nivå upplåst!", + "livesBonusText": "Livbonus", + "loadingText": "laddar", + "mainMenu": { + "creditsText": "Eftertexter", + "demoMenuText": "Demo Meny", + "endGameText": "Avbryt Spel", + "exitGameText": "Avsluta Spel", + "exitToMenuText": "Återgå till menyn?", + "howToPlayText": "Hur man Spelar", + "justPlayerText": "(Endast ${NAME})", + "leaveGameText": "Lämna Spel", + "leavePartyConfirmText": "Vill du verkligen lämna sällskapet?", + "leavePartyText": "Lämna Sällskap", + "leaveText": "Lämna", + "quitText": "Avsluta", + "resumeText": "Återuppta", + "settingsText": "Inställningar" + }, + "makeItSoText": "Kör hårt", + "mapSelectGetMoreMapsText": "Hämta Fler Banor...", + "mapSelectText": "Välj...", + "mapSelectTitleText": "${GAME} Kartor", + "mapText": "Karta", + "mostValuablePlayerText": "Mest värdefulla spelare", + "mostViolatedPlayerText": "Mest kränkt spelare", + "mostViolentPlayerText": "Mest våldsam spelare", + "moveText": "Flytta", + "multiKillText": "${COUNT}-DÖDA!", + "multiPlayerCountText": "${COUNT} spelare", + "mustInviteFriendsText": "Notera: du måste bjud in vänner i\n\"${GATHER}\" panelen eller ansluta\nstyrenheter för multiplayerspel.", + "nameBetrayedText": "${NAME} svek ${VICTIM}", + "nameDiedText": "${NAME} dog.", + "nameKilledText": "${NAME} dödade ${VICTIM}.", + "nameNotEmptyText": "Namn kan inte vara tomt!", + "nameScoresText": "${NAME} gör mål!", + "nameSuicideKidFriendlyText": "${NAME} dog oavsiktligt.", + "nameSuicideText": "${NAME} begick självmord.", + "nativeText": "Ursprunglig upplösning", + "newPersonalBestText": "Nytt personbästa!", + "newTestBuildAvailableText": "Ett nyare bygge är tillgängligt! (${VERSION} bygge ${BUILD}).\nHämta på ${ADDRESS}", + "newVersionAvailableText": "En nyare version av BombSquad är tillgänglig! (${VERSION})", + "nextLevelText": "Nästa Nivå", + "noAchievementsRemainingText": "- ingen", + "noContinuesText": "(nr fortsätter)", + "noExternalStorageErrorText": "Ingen extern lagring hittad på denna enhet", + "noGameCircleText": "Fel: inte inloggad i GameCircle", + "noJoinCoopMidwayText": "Kan inte ansluta i pågående co-op spel.", + "noProfilesErrorText": "Du har inga spelarprofiler, so du är fast med '${NAME}'.\nGå till Inställningar->Spelarprofiler för att skapa en profil.", + "noScoresYetText": "Inga poäng än.", + "noThanksText": "Nej Tack", + "noValidMapsErrorText": "Ingen giltig karta hittades för denna speltyp.", + "notEnoughPlayersRemainingText": "Otillräckligt antal spelare kvar; avsluta och starta nytt spel.", + "notEnoughPlayersText": "Du behöver minst ${COUNT} spelare för att starta spelet!", + "notNowText": "Inte Nu", + "notSignedInErrorText": "Du måste logga in för att kunna göra det här.", + "notSignedInGooglePlayErrorText": "Du måste logga in på Google Play för att kunna göra det här.", + "notSignedInText": "Inte inloggad", + "nothingIsSelectedErrorText": "Inget är valt!", + "numberText": "#${NUMBER}", + "offText": "Av", + "okText": "Ok", + "onText": "På", + "onslaughtRespawnText": "${PLAYER} återskapas i våg ${WAVE}", + "orText": "${A} eller ${B}", + "outOfText": "(#${RANK} av ${ALL})", + "ownFlagAtYourBaseWarning": "Din flagga måste vara i \ndin bas för poäng!", + "packageModsEnabledErrorText": "Nätverksspel är inte tillåtet medan lokala moddar är aktiverade (se Settings->Avancerat)", + "partyWindow": { + "chatMessageText": "Chat Meddelande", + "emptyText": "Ditt sällskap är tomt", + "hostText": "(värd)", + "sendText": "Skicka", + "titleText": "Ditt Sällskap" + }, + "pausedByHostText": "(pausad av värden)", + "perfectWaveText": "Perfekt Våg!", + "pickUpBoldText": "HÄMTA UPP", + "pickUpText": "Hämta Upp", + "playModes": { + "coopText": "Kooperativt", + "freeForAllText": "Alla mot alla", + "multiTeamText": "Flerlagsspel", + "singlePlayerCoopText": "Single Player / Co - op", + "teamsText": "Lagspel" + }, + "playText": "Spela", + "playWindow": { + "coopText": "Co-op", + "freeForAllText": "Fritt-för-alla", + "oneToFourPlayersText": "1-4 spelare", + "teamsText": "Lag", + "titleText": "Spela", + "twoToEightPlayersText": "2-8 spelare" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} kommer att vara med nästa runda", + "playerInfoText": "Spelar info.", + "playerLeftText": "${PLAYER} lämnade spelet.", + "playerLimitReachedText": "Spelargräns på ${COUNT} uppnått; inga fler får ansluta.", + "playerLimitReachedUnlockProText": "Uppgradera till \"${PRO}\" i butiken för att spela med fler än ${COUNT} spelare.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Du kan inte ta bort din kontoprofil.", + "deleteButtonText": "Ta Bort\nProfil", + "deleteConfirmText": "Ta bort '${PROFILE}'?", + "editButtonText": "Redigera\nProfil", + "explanationText": "(Skräddarsy namn och utseende för spelare på denna enhet)", + "newButtonText": "Ny\nProfil", + "titleText": "Spelarprofiler" + }, + "playerText": "Spelare", + "playlistNoValidGamesErrorText": "Denna spellista innehåller inga giltiga olåsta spel.", + "playlistNotFoundText": "spellista hittades inte", + "playlistsText": "Spellistor", + "pleaseRateText": "Om du gillar BombSquad, är vi tacksamma om du\ntar dig tid att ranka spelet eller skriva en recension. \nDetta ger värdefull feedback och hjälper framtida utveckling.\n\nTack på förhand!", + "pressAnyButtonPlayAgainText": "Tryck på valfri knapp för att spela igen...", + "pressAnyButtonText": "Tryck på valfri knapp för att fortsätta...", + "pressAnyButtonToJoinText": "tryck på valfri knapp för att ansluta...", + "pressAnyKeyButtonPlayAgainText": "Tryck på valfri knapp för att spela igen...", + "pressAnyKeyButtonText": "Tryck på valfri knapp för att fortsätta...", + "pressAnyKeyText": "Tryck på valfri knapp...", + "pressJumpToFlyText": "** Tryck upprepat på hoppa för att flyga **", + "pressPunchToJoinText": "tryck SLÅ för att ansluta...", + "pressToOverrideCharacterText": "tryck ${BUTTONS} för att åsidosätta din spelkaraktär", + "pressToSelectProfileText": "tryck ${BUTTONS} för att välja profil", + "pressToSelectTeamText": "tryck ${BUTTONS} för att välja lag", + "profileInfoText": "Skapa profiler för dig och dina vänner för att\nskräddarsy namn, spelkaraktärer och färger.", + "promoCodeWindow": { + "codeText": "Kod", + "codeTextDescription": "Kampanjkod", + "enterText": "Ange" + }, + "promoSubmitErrorText": "Kunde inte skicka in kampanjkod; kontrollera internetförbindelse", + "ps3ControllersWindow": { + "macInstructionsText": "Stäng av strömmen på baksidan av din PS3, säkerställ att \nBluetooth är påslaget på din Mac, anslut sedan din styrenhet \ntill din Mac via USB-kabel för att para ihop dem. Därefter kan du \nanvända din styrenhets hemknapp för att koppla till din Mac\ni antingen trådat (USB) eller trådlöst (Bluetooth) läge.\n\nPå några Macar kan du bli frågad om en passkod.\nOm detta händer, se följande handledning eller google för hjälp.\n\n\n\n\nPS3 styrenheter kopplade trådlöst bör visas i enhetslistan i \nSystem Preferences -> Bluetooth. Du kan behöva ta bort dem\nfrån listan för att använda dem med din PS3 igen.\n\nKoppla ned dem från Bluetooth när du inte använder dem för att \ninte batterierna skall ta slut.\n\nBluetooth bör hantera upp till sju anslutna enheter, men det kan \nvariera något.", + "ouyaInstructionsText": "För att använda PS3 styrenhet med din OUYA, koppla endast in USB kabeln.\nDetta kan få andra styrenheter att koppla ifrån. Då bör du starta om din OUYA\noch koppla ur USB kabeln.\n\nDärefter kan du använda hem knappen för att koppla upp trådlöst. När du \nspelat klart, håll inne hemknappen i 10 sekunder för att stänga av styrenheten.\nI annat fall kan batterierna snabbt ta slut.", + "pairingTutorialText": "handledningsvideo i parkoppling", + "titleText": "Använd PS3-styrenhet med BombSquad:" + }, + "publicBetaText": "PUBLIC BETA", + "punchBoldText": "SLÅ", + "punchText": "Slå", + "purchaseForText": "Köp för ${PRICE}", + "purchaseGameText": "Köp Spel", + "purchasingText": "Köper...", + "quitGameText": "Avsluta BombSquad?", + "quittingIn5SecondsText": "Avslutar om 5 sekunder...", + "randomText": "Slumpad", + "rankText": "Rang", + "ratingText": "Rating", + "reachWave2Text": "Nå våg 2 för att få rank.", + "readyText": "redo", + "recentText": "Senaste", + "remainingInTrialText": "återstår i trial", + "removeInGameAdsText": "Lås up \"${PRO}\" i butiken för att ta bort reklam.", + "renameText": "Döp Om", + "replayEndText": "Avsluta Repris", + "replayNameDefaultText": "Senaste matchens inspelning", + "replayReadErrorText": "Fel vid läsning av reprisfil.", + "replayRenameWarningText": "Döp om \"${REPLAY}\" efter ett spel om du vill behålla det; annars skrivs det över.", + "replayVersionErrorText": "Tyvärr, denna repris skapades med en annan\nversion av spelet och kan inte visas.", + "replayWatchText": "Se inspelning", + "replayWriteErrorText": "Fel vid skrivning av reprisfil.", + "replaysText": "Inspelade matcher", + "reportPlayerExplanationText": "Använd den här e-post adressen för att rapportera fusk, olämpligt språk \neller annat dåligt uppträdande. Vänligen beskriv nedan:", + "reportThisPlayerCheatingText": "Fusk", + "reportThisPlayerLanguageText": "Olämpligt språk", + "reportThisPlayerReasonText": "Vad vill du rapportera?", + "reportThisPlayerText": "Anmäl denna spelare", + "requestingText": "Begäran ...", + "restartText": "Starta om", + "retryText": "Försök Igen", + "revertText": "Återställ", + "runText": "Spring", + "saveText": "Spara", + "scoreChallengesText": "Poängutmaningar", + "scoreListUnavailableText": "Poänglista är otillgänglig", + "scoreText": "Poäng", + "scoreUnits": { + "millisecondsText": "Millisekunder", + "pointsText": "Poäng", + "secondsText": "Sekunder" + }, + "scoreWasText": "(var ${COUNT})", + "selectText": "Välj", + "seriesWinLine1PlayerText": "VINNER", + "seriesWinLine1TeamText": "VINNER", + "seriesWinLine1Text": "VINNER", + "seriesWinLine2Text": "SERIEN!", + "settingsWindow": { + "accountText": "Konto", + "advancedText": "Avancerat", + "audioText": "Ljud", + "controllersText": "Styrenheter", + "graphicsText": "Grafik", + "playerProfilesText": "Spelarprofiler", + "titleText": "Inställningar" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(ett enkelt styrenhetsvänlig skärmtangentbord för text redigering)", + "alwaysUseInternalKeyboardText": "Använd Alltid Inbyggda Tangetbordet", + "benchmarksText": "Benchmarks & Stress Tester", + "enablePackageModsDescriptionText": "(aktiverar moddningsmöjligheter men inaktiverar nätverksspel)", + "enablePackageModsText": "Aktivera Lokala Moddar", + "enterPromoCodeText": "Skriv in Promo Kod", + "forTestingText": "Notera: dessa värden är endast testvärden och återställs när programmet avslutas.", + "helpTranslateText": "BombSquad's språköversättningar skapas gemensamt i\nett community. Om du vill bidra eller rätta en översättning,\nfölj länken nedan. Tack på förhand!", + "kickIdlePlayersText": "Kasta ut inaktiva spelare", + "kidFriendlyModeText": "Barnvänligt Läge (mindre våld, etc)", + "languageText": "Språk", + "moddingGuideText": "Modifieringsguide", + "mustRestartText": "Du måste starta om för att ändringen ska träda i kraft.", + "netTestingText": "Nätverkstester", + "resetText": "Återställ", + "showPlayerNamesText": "Visa spelarnamn", + "showUserModsText": "Visa modifieringsmapp", + "titleText": "Avancerat", + "translationEditorButtonText": "BombSquad Översättningseditor", + "translationFetchErrorText": "översättnings status otillgängligt", + "translationFetchingStatusText": "Kontrollerar översättningsstatus...", + "translationNoUpdateNeededText": "valt språk är up to date; woohoo!", + "translationUpdateNeededText": "** valt språk behöver uppdateras!! **", + "vrTestingText": "VR Tester" + }, + "showText": "Visa", + "signInForPromoCodeText": "Du måste logga in på ett konto för att promotion koder ska aktiveras.", + "signInWithGameCenterText": "För att använda ett Game Center konto, \nlogga in via Game Center appen.", + "singleGamePlaylistNameText": "Endast ${GAME}", + "singlePlayerCountText": "1 spelare", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Val av spelarkaraktär", + "Chosen One": "Den Utvalde", + "Epic": "Episka Spel", + "Epic Race": "Episk kapplöpning", + "FlagCatcher": "Fånga Flaggan", + "Flying": "Glada Tankar", + "Football": "Fotboll", + "ForwardMarch": "Stormning", + "GrandRomp": "Erövring", + "Hockey": "Hockey", + "Keep Away": "Håll dig Borta", + "Marching": "Undanflykt", + "Menu": "Huvudmeny", + "Onslaught": "Anfall", + "Race": "Kapplöpning", + "Scary": "Härre på Täppan", + "Scores": "Poängskärm", + "Survival": "Eliminering", + "ToTheDeath": "Death Match", + "Victory": "Slutpoängsskärm" + }, + "spaceKeyText": "mellanslag", + "store": { + "alreadyOwnText": "Du äger redan ${NAME}!", + "bombSquadProDescriptionText": "Dubblar dina \"achievement ticket rewards\"\n\nTar bort \"in-game\" annonser\n\nInkluderar ${COUNT} bonusbiljetter\n\n+${PERCENT}% ligapoäng bonus\n\nLåser upp \"${INF_ONSLAUGHT}' och\n  \"${INF_RUNAROUND}' co-op nivåer", + "bombSquadProFeaturesText": "Funktionalitet:", + "bombSquadProNameText": "BombSquad Pro", + "buyText": "Köp", + "charactersText": "Karaktärer", + "comingSoonText": "Kommer snart...", + "extrasText": "Extra", + "freeBombSquadProText": "BombSquad är nu gratis, men eftersom du tidigare köpt spelet får du\nBombSquad Pro uppgraderingen och ${COUNT} värdekuponger som tack.\nHoppas du gläds åt all ny funktionalitet, och tack för ditt stöd!\n-Eric", + "gameUpgradesText": "Speluppgraderingar", + "getCoinsText": "Få Mynt", + "holidaySpecialText": "Helgspecial", + "howToSwitchCharactersText": "(Gå till \"${SETTINGS} -> ${PLAYER_PROFILES}\" för att tilldela och anpassa tecken)", + "howToUseIconsText": "(skapa globala spelarprofiler i \"${SETTINGS} -> ${PLAYER_PROFILES}\" för att använda dessa)", + "howToUseMapsText": "(använd dessa kartor i dina egna spellistor för \"lag/alla-mot-alla\")", + "iconsText": "Ikoner", + "loadErrorText": "Kunde inte ladda sida.\nVänligen kontrollera internetförbindelse.", + "loadingText": "Laddar", + "mapsText": "Kartor", + "miniGamesText": "Minispel", + "oneTimeOnlyText": "(endast en gång)", + "purchaseAlreadyInProgressText": "Ett köp av den här produkten är redan påbörjat.", + "purchaseConfirmText": "Bara ${ITEM}?", + "purchaseNotValidError": "Köpet är inte giltigt.\nKontakta ${EMAIL} om du ser detta felmeddelande.", + "purchaseText": "bara", + "saleBundleText": "Paket- försäljning!", + "saleExclaimText": "Rea!", + "salePercentText": "(${PERCENT}% off)", + "saleText": "REA", + "searchText": "Sök", + "teamsFreeForAllGamesText": "Lag / \"Alla mot alla\" Spel", + "winterSpecialText": "Vinterspecial", + "youOwnThisText": "- du äger detta -" + }, + "storeDescriptionText": "Partyspelsgalenskap för åtta spelare!\n\nSpräng dina vänner (eller datorn) i en turnering av exposiva minispel så som Fånga flaggan, Bombarhockey och Episk-Slowmotion-Death-Match!\n\nEnkla kontroller och omfattande stöd för styrenheter gör det enkelt för upp till åtta personer att ta del av all action. Du kan till och med använda dina mobila enheter som styrenheter \nvia gratisappen 'BombSquad Remote' app!\n\nLåt bomberna regna!\n\nKolla in www.froemling.net/bombsquad för mer info.", + "storeDescriptions": { + "blowUpYourFriendsText": "Spräng dina fiender", + "competeInMiniGamesText": "Tävla i minispel - allt från kapplöpning till flygning.", + "customize2Text": "Skräddarsy spelkaraktärer, minispel och soundtracket.", + "customizeText": "Skräddarsy spelkaraktärer och skapa din egen minispel spellista.", + "sportsMoreFunText": "Sport är alltid roligare med sprängdeg.", + "teamUpAgainstComputerText": "Samarbeta mot datorn" + }, + "storeText": "Affär", + "submittingPromoCodeText": "Laddar promotion kod....", + "teamsText": "Lag", + "telnetAccessGrantedText": "Telnetaccess aktiverad", + "telnetAccessText": "Telnetaccess upptäckt; tillåt?", + "testBuildErrorText": "Denna testversion är inte längre aktivt; vänligen kolla om det finns en ny version.", + "testBuildText": "Testversion", + "testBuildValidateErrorText": "Kunde inte validera testversionen. (ingen internet anslutning?)", + "testBuildValidatedText": "Testversion Validerad; Ha Det Så Kul!", + "thankYouText": "Tack för ditt stöd! Ha det så kul!!", + "threeKillText": "TRE DÖDA!", + "timeBonusText": "Tidbonus", + "timeElapsedText": "Förfluten tid", + "timeExpiredText": "Tiden är slut", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}t", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Tips", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Bästa Vänner", + "tournamentCheckingStateText": "Kontrollerar status på turnering; vänligen vänta...", + "tournamentEndedText": "Denna turnering är avslutad. En ny börjar inom kort.", + "tournamentEntryText": "Turneringsavgift", + "tournamentResultsRecentText": "Senaste turneringsresultat", + "tournamentStandingsText": "Turneringsställningar", + "tournamentText": "Turnering", + "tournamentTimeExpiredText": "Turneringstiden Är Slut", + "tournamentsText": "Turneringar", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Bones", + "Butch": "Butch", + "Easter Bunny": "Påskharen", + "Flopsy": "Floppy", + "Frosty": "Frostig", + "Gretel": "Greta", + "Middle-Man": "Mellanhand", + "Pixel": "Pixel", + "Santa Claus": "Jultomten", + "Snake Shadow": "Ormskugga", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao maskot", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Övning", + "Infinite ${GAME}": "Oändlig ${GAME}", + "Infinite Onslaught": "Oändligt Anfall", + "Infinite Runaround": "Oändlig Undanflykt", + "Onslaught Training": "Anfallsträning", + "Pro ${GAME}": "Proffs ${GAME}", + "Pro Football": "Proffsfotboll", + "Pro Onslaught": "Proffsanfall", + "Pro Runaround": "Proffsundanflykt", + "Rookie ${GAME}": "Nybörjar ${GAME}", + "Rookie Football": "Nybörjarfotboll", + "Rookie Onslaught": "Nybörjaranfall", + "The Last Stand": "Sista utposten", + "Uber ${GAME}": "Über ${GAME}", + "Uber Football": "Überfotboll", + "Uber Onslaught": "Überanfall", + "Uber Runaround": "Überundanflykt" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Var den utvalde under en tid för att vinna..\nDöda den utvalde för att själv bli utvald.", + "Bomb as many targets as you can.": "Bomba så många mål som möjligt.", + "Bomb as many targets as you can.\n": "Bomba så många mål som möjligt.", + "Carry the flag for ${ARG1} seconds.": "Bär flaggan i ${ARG1} sekunder.", + "Carry the flag for a set length of time.": "Bär flaggan i en viss tid.", + "Crush ${ARG1} of your enemies.": "Krossa ${ARG1} av dina fiender.", + "Defeat all enemies.": "Besegra alla fiender.", + "Dodge the falling bombs.": "Undvik de fallande bomberna.", + "Final glorious epic slow motion battle to the death.": "Slutlig ärofull episk slow motion dödsstrid.", + "Gather eggs!": "Samla ägg!", + "Get the flag to the enemy end zone.": "Få flaggan till fiendens slutzon.", + "How fast can you defeat the ninjas?": "Hur fort kan du besegra ninjorna?", + "Kill a set number of enemies to win.": "Döda ett visst antal fiender för att vinna", + "Last one standing wins.": "Den sista som står upp vinner.", + "Last remaining alive wins.": "Den sista vid liv vinner.", + "Last team standing wins.": "Sista laget som står upp vinner.", + "Prevent enemies from reaching the exit.": "Hindra fienden från att nå utgången.", + "Reach the enemy flag to score.": "Nå fiendens flagga för att få poäng.", + "Return the enemy flag to score.": "Lämna fiendens flagga för att få poäng.", + "Run ${ARG1} laps.": "Spring ${ARG1} varv.", + "Run ${ARG1} laps. Your entire team has to finish.": "Spring ${ARG1} varv. Hela laget måste komma i mål.", + "Run 1 lap.": "Spring ett varv.", + "Run 1 lap. Your entire team has to finish.": "Spring ett varv. Hela laget måste komma i mål.", + "Run real fast!": "Spring riktigt fort!", + "Score ${ARG1} goals.": "Gör ${ARG1} mål.", + "Score ${ARG1} touchdowns.": "Gör ${ARG1} touchdowns.", + "Score a goal.": "Gör ett mål", + "Score a touchdown.": "Gör en touchdown.", + "Score some goals.": "Gör några mål", + "Secure all ${ARG1} flags.": "Säkra alla ${ARG1} flaggor.", + "Secure all flags on the map to win.": "Säkra alla flaggor på kartan för att vinna.", + "Secure the flag for ${ARG1} seconds.": "Säkra flaggan i ${ARG1} sekunder.", + "Secure the flag for a set length of time.": "Säkra flaggan under en viss tid.", + "Steal the enemy flag ${ARG1} times.": "Stjäl fiendens flagga ${ARG1} gånger", + "Steal the enemy flag.": "Stjäl fiendens flagga.", + "There can be only one.": "Det kan endast vara en.", + "Touch the enemy flag ${ARG1} times.": "Rör vid fiendens flagga ${ARG1} gånger", + "Touch the enemy flag.": "Vidrör fiendens flagga.", + "carry the flag for ${ARG1} seconds": "bär flaggen i ${ARG1} sekunder", + "kill ${ARG1} enemies": "Döda ${ARG1} fiender", + "last one standing wins": "den sista som står upp vinner", + "last team standing wins": "Sista laget som står upp vinner", + "return ${ARG1} flags": "lämna ${ARG1} flaggor", + "return 1 flag": "lämna 1 flagga", + "run ${ARG1} laps": "spring ${ARG1} varv", + "run 1 lap": "spring ett varv", + "score ${ARG1} goals": "gör ${ARG1} mål", + "score ${ARG1} touchdowns": "gör ${ARG1} touchdowns", + "score a goal": "Gör ett mål", + "score a touchdown": "Gör en touchdown", + "secure all ${ARG1} flags": "säkra alla ${ARG1} flaggor", + "secure the flag for ${ARG1} seconds": "säkra flaggan i ${ARG1} sekunder", + "touch ${ARG1} flags": "rör vid ${ARG1} flaggor", + "touch 1 flag": "rör en flagga" + }, + "gameNames": { + "Assault": "Angrepp", + "Capture the Flag": "Fånga Flaggan", + "Chosen One": "Den Utvalda", + "Conquest": "Erövring", + "Death Match": "Dödsmatch", + "Easter Egg Hunt": "Påskäggsjakt", + "Elimination": "Eliminering", + "Football": "Fotboll", + "Hockey": "Hockey", + "Keep Away": "Håll Avstånd", + "King of the Hill": "Herre på Täppan", + "Meteor Shower": "Meteorregn", + "Ninja Fight": "Ninja Fight", + "Onslaught": "Anfall", + "Race": "Kapplöpning", + "Runaround": "Undanflykt", + "Target Practice": "Träffövning", + "The Last Stand": "Sista utposten" + }, + "inputDeviceNames": { + "Keyboard": "Tangentbord", + "Keyboard P2": "Tangentbord P2" + }, + "languages": { + "Arabic": "Arabiska", + "Belarussian": "Vitryska", + "Chinese": "Kinesiska", + "Croatian": "Kroatiska", + "Czech": "Tjeckiska", + "Danish": "Danska", + "Dutch": "Holländska", + "English": "Engelska", + "Esperanto": "Esperanto", + "Finnish": "Finska", + "French": "Franska", + "German": "Tyska", + "Gibberish": "Gibberish", + "Hindi": "Hindi", + "Hungarian": "Ungerska", + "Italian": "Italienska", + "Japanese": "Japanska", + "Korean": "Koreanska", + "Persian": "Persiska", + "Polish": "Polska", + "Portuguese": "Portugisiska", + "Romanian": "Rumänska", + "Russian": "Ryska", + "Serbian": "Serbiska", + "Spanish": "Spanska", + "Swedish": "Svenska", + "Turkish": "Turkiska", + "Ukrainian": "Ukrainska" + }, + "leagueNames": { + "Bronze": "Brons", + "Diamond": "Diamant", + "Gold": "Guld", + "Silver": "Silver" + }, + "mapsNames": { + "Big G": "Big G", + "Bridgit": "Bridgit", + "Courtyard": "Courtyard", + "Crag Castle": "Crag Castle", + "Doom Shroom": "Doom Shroom", + "Football Stadium": "Footballs Stadium", + "Happy Thoughts": "Glada tankar", + "Hockey Stadium": "Hockey Stadium", + "Lake Frigid": "Lake Frigid", + "Monkey Face": "Apansikte", + "Rampage": "Framfart", + "Roundabout": "Rondell", + "Step Right Up": "Stig upp", + "The Pad": "The Pad", + "Tip Top": "Tip Top", + "Tower D": "Tower D", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Endast Episkt", + "Just Sports": "Endast Sport" + }, + "promoCodeResponses": { + "invalid promo code": "Ogiltig kampanjkod" + }, + "scoreNames": { + "Flags": "Flaggor", + "Goals": "Mål", + "Score": "Poäng", + "Survived": "Överlevde", + "Time": "Tid", + "Time Held": "Tid avklarad" + }, + "serverResponses": { + "A code has already been used on this account.": "En kod har redan använts på det här kontot.", + "An error has occurred; (${ERROR})": "Ett fel har uppstått; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Ett fel har uppstått, vänligen kontakta kundtjänst. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Ett fel har uppstått, vänligen kontakta support@froemling.net.", + "An error has occurred; please try again later.": "Ett fel har uppstått, försök igen senare.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Är du säker på att du vill slå ihop dessa konton?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nDetta kan inte ångras!", + "BombSquad Pro unlocked!": "BombSquad Pro upplåst!", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Fusk upptäckt; resultat och priser kommer att frysas i ${COUNT} dagar", + "Daily maximum reached.": "Dagligt maximum nått", + "Entering tournament...": "Ansluter till turnering...", + "Invalid code.": "Ogiltig kod", + "Invalid payment; purchase canceled.": "Ogiltig betalning, köp avbrutet.", + "Invalid promo code.": "Ogiltig rabbattkod.", + "Invalid purchase.": "Ogiltigt köp.", + "Max number of playlists reached.": "Max antal spellistor nåtts.", + "Max number of profiles reached.": "Max antal profiler nåtts.", + "Profile \"${NAME}\" upgraded successfully.": "Profilen \"${NAME}\" har uppgraderats.", + "Profile could not be upgraded.": "Profilen kunde tyvärr inte uppgraderas.", + "Purchase successful!": "Köp genomfört!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Mottagna ${COUNT} biljetter till att logga in.\nKom tillbaka i morgon för att få ${TOMORROW_COUNT}.", + "Sorry, there are no uses remaining on this code.": "Tyvärr, det finns inga gånger kvar med den här koden.", + "Sorry, this code has already been used.": "Tyvärr, den här koden har redan använts.", + "Sorry, this code has expired.": "Tyvärr, den här koden har gått ut.", + "Sorry, this code only works for new accounts.": "Tyvärr, den här koden fungerar bara för nya konton.", + "Temporarily unavailable; please try again later.": "Tillfälligt otillgängligt, försök igen senare.", + "The tournament ended before you finished.": "Turneringen slutade innan ditt resultat togs emot.", + "This code cannot be used on the account that created it.": "Den här koden kan inte användas i samma konto den skapades i.", + "This requires version ${VERSION} or newer.": "Detta kräver version ${VERSION} eller senare.", + "Tournaments disabled due to rooted device.": "Turnering avbruten på grund av rotad enhet.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Vill du slå ihop ditt enhets konto med detta?\n\nDitt enhets konto är ${ACCOUNT1} \nOch det här kontot är ${ACCOUNT2}\n\nDet här gör att du kan behålla dina framsteg. \nOBS! Detta kan inte ångras!", + "You already own this!": "Du äger redan detta!", + "You don't have enough tickets for this!": "Du har inte tillräckligt med värdekuponger!", + "You got ${COUNT} tickets!": "Du fick ${COUNT} värdekuponger!", + "You got a ${ITEM}!": "Du fick en ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Du har blivit befordrad till en ny liga; grattis!", + "You must update to a newer version of the app to do this.": "Du måste uppdatera till en nyare version av appen för att göra detta.", + "You must update to the newest version of the game to do this.": "Du måste uppdatera till den nyaste versionen av appen för att göra detta.", + "You must wait a few seconds before entering a new code.": "Du måste vänta några sekunder innan du anger en ny kod.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Du rankades #${RANK} i senaste turneringen. Tack för ditt deltagande!", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Din kopia av spelet har modifierats.\nÅterställ förändringarna och försök igen.", + "Your friend code was used by ${ACCOUNT}": "Din kompis-kod användes av ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Minut", + "1 Second": "1 Sekund", + "10 Minutes": "10 Minuter", + "2 Minutes": "2 Minuter", + "2 Seconds": "2 Sekunder", + "20 Minutes": "20 Minuter", + "4 Seconds": "4 Sekunder", + "5 Minutes": "5 Minuter", + "8 Seconds": "8 Sekunder", + "Allow Negative Scores": "Tillåt Negativa Resultat", + "Balance Total Lives": "Balansera totala antalet liv", + "Chosen One Gets Gloves": "Den Utvalda Får Boxningshandskar", + "Chosen One Gets Shield": "Den Utvalda Får Sköld", + "Chosen One Time": "Den Utvalde Tid", + "Enable Impact Bombs": "Aktivera Impact bomber", + "Enable Triple Bombs": "Aktivera Triple bomber", + "Epic Mode": "Episkt Läge", + "Flag Idle Return Time": "Tid innan inaktiv flagga återlämnas", + "Flag Touch Return Time": "Tid innan vidrörd flagga återlämnas", + "Hold Time": "Uthållen tid", + "Kills to Win Per Player": "Antalet döda för att vinna per spelare", + "Laps": "Varv", + "Lives Per Player": "Liv Per Spelare", + "Long": "Lång", + "Longer": "Längre", + "Mine Spawning": "Återkommande minor", + "No Mines": "Inga minor", + "None": "Ingen", + "Normal": "Normal", + "Respawn Times": "Återfödelsetid", + "Score to Win": "Poäng för att vinna", + "Short": "Kort", + "Shorter": "Kortare", + "Solo Mode": "Sololäge", + "Target Count": "Målsumma", + "Time Limit": "Tidsgräns" + }, + "statements": { + "Killing ${NAME} for skipping part of the track!": "Dödar ${NAME} för att hen tog en genväg!" + }, + "teamNames": { + "Bad Guys": "De Onda", + "Blue": "Blå", + "Good Guys": "De Goda", + "Red": "Röd" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "En perfekt timad spring-hopp-spin-slag kan döda i ett enda slag\noch ge dig livslång respekt av dina vänner.", + "Always remember to floss.": "Glöm inte att använda tandtråd.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Skapa spelarprofiler till dig själv och dina vänner med \nförvalda namn och utseenden istället för slumpvalda.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Förbannelse-lådan förvandlar dig till en tickande bomb.\nDet enda botemedlet är att få tag i en hälsolåda.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Oavsett utseendet är alla karaktärers förmågor identiska,\nså välj vilken som än liknar dig mest.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Bli inte för kaxig med den där energiskölden, du kan fortfarande trilla ned för ett stup.", + "Don't run all the time. Really. You will fall off cliffs.": "Spring inte hela tiden. Seriöst. Du kommer att ramla av ett stup.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Håll inne valfri knapp för att springa. (Avtryckarknappar fungerar bra om du har dessa)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Håll ned valfri knapp för att springa. Du tar dig snabbare fram \nmen har svårare att svänga, så se upp för stup.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Isbomber är inte särskilt kraftfulla, men de fryser den som\nträffas och lämnar dem sårbara för förödelse.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Om någon plockar upp dig, slå dem så släpper de taget.\nDetta fungerar i verkliga livet också.", + "If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "Om du inte har tillräckligt med kontroller kan du installera 'BombSquad Remote' appen\npå din iOS eller Android enhet och använd dem som kontroller.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Om en klisterbomb fastnar på dig, hoppa runt i cirklar.\nDu kanske kan skaka av dig bomben, om inte annat är det kul.", + "If you kill an enemy in one hit you get double points for it.": "Om du dödar en fiende med en träff får du dubbla poäng för det.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Om du tar upp en förbannelse, är ditt enda hopp för att överleva\natt du plockar upp en hälso-powerup inom de närmsta sekunderna.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Om du står på ett ställe är du körd. Spring runt och hoppa undan för att överleva..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Om det är många spelare som ansluter och slutar, ställ in 'kasta ut inaktiva spelare'\nunder inställningar ifall någon glömmer att lämna spelet.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Om din enhet blir för varm eller om du vill spara på batteri,\nvrid ner \"Visuellt\" eller \"Upplösning\" under Inställningar->Grafik", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Om din framerate hoppar, försök sänka upplösningen\neller grafiken i spelet grafikinställningar.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "I Fånga Flaggan måste din egen flagga vara vid basen för att kunna göra poäng, om \nmotståndarna är påväg att göra mål kan ett bra sätt att stoppa dem vara att ta deras flagga.", + "In hockey, you'll maintain more speed if you turn gradually.": "I hockey bibehåller du mer fart om du svänger sakta.", + "It's easier to win with a friend or two helping.": "Det är lättare att vinna med en vän eller två som hjälper till.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Hoppa precis när du kastar en bomb för att få upp den på högre platser.", + "Land-mines are a good way to stop speedy enemies.": "Landminor är ett bra sätt att stoppa snabba fiender.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Många saker kan plockas upp och kastas, inklusive andra spelare. Att kasta dina \nfiender över ett stup kan vara en effektiv och emotionellt tillfredställande strategi.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nej, du kan inte komma upp på avsatsen. Du måste kasta bomber.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Spelare kan ansluta eller lämna mitt i de flesta speltyperna,\noch man kan även koppla i eller ur styrenheter närsomhelst.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug gamepads on the fly.": "Spelare kan ansluta och lämna mitt i de flesta spel\noch du kan koppla in och ur gamepads under spel.", + "Powerups only have time limits in co-op games.\nIn teams and free-for-all they're yours until you die.": "Powerups har endast tidsbegränsning i co-op spel.\nI lag och free-for-all behålls de tills du dör.", + "Practice using your momentum to throw bombs more accurately.": "Öva använda momentum för att kasta bomber mer träffsäkert.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Slag gör mer skada ju snabbare nävarna rör sig,\nså försök springa, hoppa och snurra som en galning.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Spring fram och tillbak innan du kastar en bomb\nför att 'piska' den och kasta längre.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Slå ut en grupp fiender genom att\nspränga en bomb nära en TNT låda.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Huvudet är det mest känsliga området, så en klisterbomb\nmot skallen betyder oftast Game-Over.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Denna nivå tar aldrig slut, men ett high score här\nger dig evig respekt över hela världen.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Kaststryka baseras på den riktning du trycker.\nFör att humpa någonting kort framför dig,\ntryck inte i någon riktning.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Trött på soundtracket? Ersätt den med din egna!\nSe Inställningar->Audio->Soundtrack", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Försök 'bränna av' bombens stubin i några sekunder innan du kastar dem.", + "Try tricking enemies into killing eachother or running off cliffs.": "Försök få fiender att döda varandra eller springa ut ur banan", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Använd plocka-upp knappen för att ta tag i flaggan < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Piska fram och tillbak för att få mer distans i dina kast..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Du kan 'sikta' dina slag genom att snurra till vänster och höger.\nDetta är användbart för att slå ut fiender över kanten eller för att göra mål i hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Du kan avgöra när en bomb kommer smälla beroende på\nfärgen på stubintråden: gul..orange..röd..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Du kan kasta bomber högre om du hoppar precis innan du kastar.", + "You don't need to edit your profile to change characters; Just press the top\nbutton (pick-up) when joining a game to override your default.": "Du behöver inte redigera din profil för att byta spelkaraktär. Tryck bara på \növersta knappen (plocka upp) när du ansluter till ett spel för att byta ut standardinställningen.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Du tar skada när du slår huvudet i saker, \nså försök att inte slå huvudet i saker.", + "Your punches do much more damage if you are running or spinning.": "Dina slag gör mycket mer skada om du springer eller snurrar." + } + }, + "trialPeriodEndedText": "Din testperiod har tagit slut. Skulle du vilja köpa BombSquad och fortsätta spela?", + "trophiesText": "Troféer", + "trophiesThisSeasonText": "Denna säsongs troféer", + "tutorial": { + "cpuBenchmarkText": "Kör handledning vid galen hastighet (främst för att testa processorns hastighet)", + "phrase01Text": "Hejsan!", + "phrase02Text": "Välkommen till BombSquad!", + "phrase03Text": "Här kommer några tips för att kontrollera din spelkaraktär:", + "phrase04Text": "Mycket i ${APP_NAME} är FYSIK baserade.", + "phrase05Text": "Till exempel, när du slår,..", + "phrase06Text": "..skada baseras på hastigheten på dina nävar.", + "phrase07Text": "Ser du? Vi stod nästan stilla, och gjorde knappt illa ${NAME}.", + "phrase08Text": "Låt oss hoppa och snurra för att få mer fart.", + "phrase09Text": "Aha, det var bättre.", + "phrase10Text": "Att springa hjälper också.", + "phrase11Text": "Håll valfri knapp intryckt för att springa.", + "phrase12Text": "För extra feta slag, försök springa OCH snurra.", + "phrase13Text": "Hoppsan, ledsen för det där ${NAME}.", + "phrase14Text": "Du kan plocka upp och kasta saker såsom flaggor.. eller ${NAME}.", + "phrase15Text": "Slutligen finns det bomber.", + "phrase16Text": "Att kasta bomber kräver övning.", + "phrase17Text": "Attans! Ett mindre lyckat kast.", + "phrase18Text": "Att röra sig hjälper till att kasta längre.", + "phrase19Text": "Kasta högre genom att hoppa.", + "phrase20Text": "Piska iväg dina bomber för ännu längre kast.", + "phrase21Text": "Timing av bomber kan vara svårt.", + "phrase22Text": "Dang.", + "phrase23Text": "Försök låta stubinen brinna en sekund eller två.", + "phrase24Text": "Hurra! Snyggt!", + "phrase25Text": "Det var det.", + "phrase26Text": "På dem, tiger!", + "phrase27Text": "Kom ihåg vad du lärt dig så kommer du att överleva!", + "phrase28Text": "...hmm, kanske...", + "phrase29Text": "Lycka till!", + "randomName1Text": "Marina", + "randomName2Text": "Johan", + "randomName3Text": "Kalle", + "randomName4Text": "Nisse", + "randomName5Text": "Anna", + "skipConfirmText": "Hoppa över handledningen? Tryck igen för att bekräfta.", + "skipVoteCountText": "${COUNT}/${TOTAL} röster att hoppa över", + "skippingText": "Hoppar över tutorial...", + "toSkipPressAnythingText": "(tryck på någon knapp för att hoppa över tutorial)" + }, + "twoKillText": "DOUBLE KILL!", + "unavailableText": "Otillgänglig", + "unconfiguredControllerDetectedText": "Okonfigurerad styrenhet upptäckt:", + "unlockThisInTheStoreText": "Detta måste låsas up i butiken.", + "unlockThisText": "För att låsa upp det här behöver du:", + "unsupportedHardwareText": "Tyvärr, hårdvaran stöds inte av detta bygge av spelet.", + "upFirstText": "Först på tur:", + "upNextText": "Nästa på tur i spel ${COUNT}:", + "updatingAccountText": "Uppdaterar ditt konto...", + "upgradeText": "Uppgradera", + "upgradeToPlayText": "Lås \"${PRO}\" i butiken i spelet för att spela detta.", + "useDefaultText": "Använd Standard", + "usesExternalControllerText": "Detta spel använder en extern styrenhet för inmatning.", + "usingItunesText": "Använder iTunes till musik...", + "usingItunesTurnRepeatAndShuffleOnText": "Säkerställ att 'shuffle' är ON och 'repeat' är ALL i iTunes.", + "validatingBetaText": "Bekräftar Beta...", + "validatingTestBuildText": "Validerar Testversionen...", + "victoryText": "Vinst", + "vsText": "vs.", + "waitingForHostText": "(väntar på ${HOST} för att fortsätta)", + "waitingForLocalPlayersText": "väntar på lokala spelare...", + "waitingForPlayersText": "väntar på att spelare ska ansluta...", + "watchAnAdText": "Se en annons", + "watchWindow": { + "deleteConfirmText": "Ta bort \"${REPLAY}\"?", + "deleteReplayButtonText": "Radera\nRepris", + "myReplaysText": "Mina Repriser", + "noReplaySelectedErrorText": "Ingen Repris Markerad", + "renameReplayButtonText": "Döp Om\nRepris", + "renameReplayText": "Döp om från \"${REPLAY}\" till:", + "renameText": "Döp Om", + "replayDeleteErrorText": "Kunde inte radera repris.", + "replayNameText": "Repris Namn", + "replayRenameErrorAlreadyExistsText": "En repris med samma namn finns redan.", + "replayRenameErrorInvalidName": "Kan inte byta namn på repris; ogiltigt namn.", + "replayRenameErrorText": "Fel vid namnändring av repris.", + "sharedReplaysText": "Delade repriser", + "titleText": "Titta", + "watchReplayButtonText": "Se\nRepris" + }, + "waveText": "Våg", + "wellSureText": "Jajamän!", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Copyright" + }, + "wiimoteListenWindow": { + "listeningText": "Lyssnar efter Wiimotes...", + "pressText": "Tryck på knapp 1 och 2 samtidigt på din Wiimote.", + "pressText2": "På nyare Wiimotes med Motion Plus inbyggt, tryck på den lilla röda syncknappen på baksidan istället." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote Upphovsrätt", + "listenText": "Lyssna", + "macInstructionsText": "Se till att din Wii är avstäng och Bluetooth är aktiverad \npå din Mac. Tryck sedan på 'Lyssna'. Wiimote support kan \nvara ganska krånglig så du kan behöva försöka ett par gånger\ninnan du får en anslutning.\n\nBluetooth ska kunna hantera upp till 7 anslutna enheter,\nmen det kan variera.\n\nBombSquad stödjer äkta Wiimote, Nunchuks \noch den Klassiska Kontrollen.\nDen nya Wii Remote Plus fungerar nu också\nmen inte med tillbehör.", + "thanksText": "Tack till DarwiinRemote team\nFör att ha gjort detta möjligt.", + "titleText": "Wiimote Inställningar" + }, + "winsPlayerText": "Vinnare är ${NAME}!", + "winsTeamText": "${NAME} Vinner!", + "winsText": "${NAME} Vinner!", + "worldScoresUnavailableText": "Världsmästarpoäng ej tillgängligt.", + "worldsBestScoresText": "Världsmästarpoäng", + "worldsBestTimesText": "Världsmästartider", + "xbox360ControllersWindow": { + "getDriverText": "Skaffa Drivrutin", + "macInstructions2Text": "För att använda kontrollen trådlöst behöver du en mottagare \nsom kommer med 'Xbox 360 kontrollen för Windows'\nEn mottagare gör det möjligt för up till 4 kontroller.\n\nViktigt: 3:e part mottagare fungerar ej med denna drivrutin;\nse till att det står 'Microsoft', inte 'XBOX 360' på mottagaren.\nMicrosoft säljer inte längre dessa separat, så du behöver köpa\nen kontroll eller söka efter en på Ebay.\n\nOm du finner detta användbart, överväg gärna att donera till\nutvecklaren av drivrutinen på hans sida.", + "macInstructionsText": "För att använda Xbox 360 kontroller behöver du\ninstallera Mac drivrutinen som är tillgänglig via\nlänken nedanför. Den fungerar både med och utan sladd", + "ouyaInstructionsText": "Allt du behöver göra för att använda trådade Xbox 360-kontroller är att \nkoppla in dem i USB-porten. Du kan använda en USB-hub \nför att koppla in fler kontroller.\n\nFör att använda trådlösa kontroller behöver du en trådlös mottagare, \ndessa ingår om man köper en \"Xbox 360 Wireless Controller for Windows\" \nmen säljs också separat. Varje mottagare kopplas in i en USB-port \noch möjliggör användandet av upp till fyra stycken trådlösa kontroller.", + "titleText": "Använda Xbox 360-kontroller med ${APP_NAME}:" + }, + "yesAllowText": "Ja, Tillåt!", + "yourBestScoresText": "Dina Bästa Poäng", + "yourBestTimesText": "Dina Bästa Tider" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/tamil.json b/dist/ba_data/data/languages/tamil.json new file mode 100644 index 0000000..1ca6ed3 --- /dev/null +++ b/dist/ba_data/data/languages/tamil.json @@ -0,0 +1,1883 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "கணக்கு பெயர் தனித்துவமான எழுத்துக்களையோ எமோஜிக்களையோ கொண்டிருக்க முடியாது", + "accountsText": "கணக்குகள்", + "achievementProgressText": "சாதனைகள்: ${TOTAL} இல் ${COUNT}", + "campaignProgressText": "பிரச்சார முன்னேற்றம் [கடினமானது] : ${PROGRESS}", + "changeOncePerSeason": "ஒரு பருவத்திற்கு ஒரு முறை மட்டுமே இதை மாற்ற முடியும்.", + "changeOncePerSeasonError": "இதை மீண்டும் மாற்ற அடுத்த சீசன் வரை நீங்கள் காத்திருக்க வேண்டும் (${NUM} நாட்கள்)", + "customName": "தனிப்பயன் பெயர்", + "googlePlayGamesAccountSwitchText": "நீங்கள் வேறு Google கணக்கைப் பயன்படுத்த விரும்பினால்,\nமாறுவதற்கு Google Play கேம்ஸ் பயன்பாட்டைப் பயன்படுத்தவும்.", + "linkAccountsEnterCodeText": "குறியீட்டை உள்ளிடவும்", + "linkAccountsGenerateCodeText": "குறியீட்டை உருவாக்கவும்", + "linkAccountsInfoText": "வெவ்வேறு தளங்களில் முன்னேற்றத்தைப் பகிரலாம்", + "linkAccountsInstructionsNewText": "இரண்டு கணக்குகளை இணைக்க, முதலில் ஒரு குறியீட்டை உருவாக்கவும்\nஇரண்டாவது குறியீட்டை உள்ளிடவும். \n இலிருந்து தரவு\nஇரண்டாவது கணக்கு பின்னர் இருவருக்கும் இடையே பகிரப்படும். \n(முதல் கணக்கிலிருந்து தரவு இழக்கப்படும்)\n\nநீங்கள் ${COUNT} கணக்குகள் வரை இணைக்க முடியும்.\n\nமுக்கியம்: உங்களுக்கு சொந்தமான கணக்குகளை மட்டுமே இணைக்கவும்;\nநண்பர்களின் கணக்குகளுடன் நீங்கள் இணைத்தால் நீங்கள் ஒரே நேரத்தில் ஆன்லைனில் விளையாட முடியாது.", + "linkAccountsText": "கணக்குகளை இணைக்கவும்", + "linkedAccountsText": "இணைக்கப்பட்ட கணக்குகள்:", + "manageAccountText": "கணக்கை நிர்வகி", + "nameChangeConfirm": "உங்கள் கணக்கின் பெயரை ${NAME}க்கு மாற்ற", + "resetProgressConfirmNoAchievementsText": "இது உங்கள் கூட்டு முன்னேற்றங்கள் மற்றும் கருவி உயர்மதிப்பெண்கள் ஆகியவற்றை அழிக்கும் (ஆனால் உங்கள் சீட்டுகள் அல்ல).\nஇச்செயலை பின்வாங்க முடியாது.\nஉறுதியா?", + "resetProgressConfirmText": "இது உங்கள் கூட்டு முன்னேற்றங்கள், சாதனைகள், மற்றும் கருவி உயர்மதிப்பெண்கள் ஆகியவற்றை அழிக்கும் \n(ஆனால் உங்கள் சீட்டுகள் அல்ல).\nஇச்செயலை பின்வாங்க முடியாது.\nஉறுதியா?", + "resetProgressText": "முன்னேற்றங்களை அழி", + "setAccountName": "கணக்கு பெயர் வைக்க", + "setAccountNameDesc": "உங்கள் கணக்குக்கு காட்ட வேண்டிய பெயரை தேர்வு செய்யவும். \nஉங்கள் இணைக்கப்பட்ட கணக்குகளிலிருந்து ஒரு பெயரை தேர்வு செய்யலாம் \nஅல்லது புதிய பெயரை உருவாக்கலாம்.", + "signInInfoText": "சீட்டுகள் சேர்க்க, இணையத்தில் போட்டியிட,\nமுன்னேற்றங்களை பகிர, புகுபதிவு செய்யவும்.", + "signInText": "புகுபதிகை", + "signInWithDeviceInfoText": "(இந்த சாதனத்திலிருந்து ஒரு தானியங்கி கணக்கு மட்டுமே கிடைக்கும்)", + "signInWithDeviceText": "சாதனக் கணக்கில் உள்நுழைக", + "signInWithGameCircleText": "Game Circle மூலம் உள்நுழைக", + "signInWithGooglePlayText": "Google Play உடன் உள்நுழைக", + "signInWithTestAccountInfoText": "(மரபு கணக்கு வகை; முன்னோக்கி செல்லும் சாதனக் கணக்குகளைப் பயன்படுத்தவும்)", + "signInWithTestAccountText": "சோதனைக் கணக்கில் உள்நுழைக", + "signInWithV2InfoText": "(அனைத்து தளங்களிலும் செயல்படும் கணக்கு)", + "signInWithV2Text": "BombSquad கணக்கில் உள்நுழையவும்", + "signOutText": "வெளியேறு", + "signingInText": "புகுபதிகை நடைபெறுகிறது...", + "signingOutText": "விடுபதிகை நடைபெறுகிறது...", + "ticketsText": "டிக்கெட்: ${COUNT}", + "titleText": "கணக்கு", + "unlinkAccountsInstructionsText": "இணைப்பை நீக்குவதற்கான கணக்கைத் தேர்ந்தெடுக்கவும்", + "unlinkAccountsText": "கணக்கை நீக்க", + "unlinkLegacyV1AccountsText": "மரபு (V1) கணக்குகளின் இணைப்பை நீக்கு", + "v2LinkInstructionsText": "கணக்கை உருவாக்க அல்லது உள்நுழைய இந்த இணைப்பைப் பயன்படுத்தவும்.", + "viaAccount": "${NAME} கணக்கின் வழியாக", + "youAreSignedInAsText": "நீங்கள் உள்நுழைந்துள்ளீர்கள்" + }, + "achievementChallengesText": "சாதனை சவால்கள்", + "achievementText": "சாதனை", + "achievements": { + "Boom Goes the Dynamite": { + "description": "டிஎன்டி மூலம் 3 கெட்டவர்களைக் கொல்லுங்கள்", + "descriptionComplete": "TNT உடன் 3 கெட்டவர்களைக் கொன்றது", + "descriptionFull": "TNT உடன் 3 கெட்டவர்களை ${LEVEL} இல் கொல்லுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் TNT உடன் 3 கெட்டவர்களைக் கொன்றது", + "name": "பூம் டைனமைட்டுக்கு செல்கிறது" + }, + "Boxer": { + "description": "எந்த குண்டுகளையும் பயன்படுத்தாமல் வெற்றி பெறுங்கள்", + "descriptionComplete": "எந்த குண்டுகளையும் பயன்படுத்தாமல் வெற்றி பெற்றது", + "descriptionFull": "எந்த குண்டுகளையும் பயன்படுத்தாமல் ${LEVEL} ஐ முடிக்கவும்", + "descriptionFullComplete": "எந்த வெடிகுண்டையும் பயன்படுத்தாமல் ${LEVEL} ஐ நிறைவு செய்தது", + "name": "பாக்சர்" + }, + "Dual Wielding": { + "descriptionFull": "2 கட்டுப்படுத்திகளை இணைக்கவும் (வன்பொருள் அல்லது செயலி)", + "descriptionFullComplete": "இணைக்கப்பட்ட 2 கட்டுப்படுத்திகள் (வன்பொருள் அல்லது செயலி)", + "name": "இரட்டை வீல்டிங்" + }, + "Flawless Victory": { + "description": "அடிபடாமல் வெற்றி பெரு", + "descriptionComplete": "அடிபடாமல் வென்றது", + "descriptionFull": "அடிபடாமல் ${LEVEL} ஐ வெற்றி பெறு", + "descriptionFullComplete": "அடிபடாமல் ${LEVEL} வென்றது", + "name": "குறைபாடற்ற வெற்றி" + }, + "Free Loader": { + "descriptionFull": "2+ பிளேயர்களுடன் அனைவருக்கும் இலவச விளையாட்டைத் தொடங்கவும்", + "descriptionFullComplete": "2+ பிளேயர்களுடன் அனைவருக்கும் இலவச விளையாட்டைத் தொடங்கியது", + "name": "இலவச ஏற்றி" + }, + "Gold Miner": { + "description": "நிலக் கண்ணிவெடிகளால் 6 கெட்டவர்களைக் கொல்லுங்கள்", + "descriptionComplete": "கண்ணிவெடிகளால் 6 கெட்டவர்களைக் கொன்றது", + "descriptionFull": "${LEVEL} இல் கண்ணிவெடிகளுடன் 6 கெட்டவர்களைக் கொல்லுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் கண்ணிவெடிகளுடன் 6 கெட்டவர்களைக் கொன்றது", + "name": "தங்க சுரங்கத் தொழிலாளி" + }, + "Got the Moves": { + "description": "குத்து அல்லது குண்டுகளைப் பயன்படுத்தாமல் வெற்றி பெறுங்கள்", + "descriptionComplete": "குத்துக்கள் அல்லது குண்டுகளைப் பயன்படுத்தாமல் வென்றது", + "descriptionFull": "குத்துக்கள் அல்லது குண்டுகள் இல்லாமல் ${LEVEL} ஐ வெற்றி பெரு", + "descriptionFullComplete": "குத்துக்கள் அல்லது குண்டுகள் இல்லாமல் ${LEVEL} வென்றது", + "name": "நகர்வுகள் கிடைத்தன" + }, + "In Control": { + "descriptionFull": "ஒரு கட்டுப்படுத்தியை இணைக்கவும் (வன்பொருள் அல்லது செயலி)", + "descriptionFullComplete": "ஒரு கட்டுப்படுத்தி இணைக்கப்பட்டுள்ளது (வன்பொருள் அல்லது செயலி)", + "name": "கட்டுப்பாட்டில் உள்ளது" + }, + "Last Stand God": { + "description": "1000 புள்ளிகளைப் பெறுங்கள்", + "descriptionComplete": "1000 புள்ளிகள் பெற்றுள்ளார்", + "descriptionFull": "${LEVEL} இல் 1000 புள்ளிகளைப் பெறுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் 1000 புள்ளிகளைப் பெற்றுள்ளது", + "name": "${LEVEL} கடவுள்" + }, + "Last Stand Master": { + "description": "250 புள்ளிகளைப் பெறுங்கள்", + "descriptionComplete": "250 புள்ளிகள் பெற்றுள்ளார்", + "descriptionFull": "${LEVEL} இல் 250 புள்ளிகளைப் பெறுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் 250 புள்ளிகளைப் பெற்றுள்ளார்", + "name": "${LEVEL} குரு" + }, + "Last Stand Wizard": { + "description": "500 புள்ளிகளைப் பெறுங்கள்", + "descriptionComplete": "500 புள்ளிகள் பெற்றுள்ளது", + "descriptionFull": "${LEVEL} இல் 500 புள்ளிகளைப் பெறுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் 500 புள்ளிகளைப் பெற்றுள்ளது", + "name": "${LEVEL} மந்திரவாதி" + }, + "Mine Games": { + "description": "நிலக் கண்ணிவெடிகளால் 3 கெட்டவர்களைக் கொல்லுங்கள்", + "descriptionComplete": "கண்ணிவெடிகளால் 3 கெட்டவர்களைக் கொன்றது", + "descriptionFull": "${LEVEL} இல் நிலக் கண்ணிவெடிகளுடன் 3 கெட்டவர்களைக் கொல்லுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் கண்ணிவெடிகளுடன் 3 கெட்டவர்களைக் கொன்றது", + "name": "நில-சுரங்க விளையாட்டுகள்" + }, + "Off You Go Then": { + "description": "3 கெட்டவர்களை இடத்திலிருந்து தூக்கி எறியுங்கள்", + "descriptionComplete": "அந்த இடத்திலிருந்து 3 கெட்டவர்கள் வீசப்பட்டனர்", + "descriptionFull": "${LEVEL} இல் 3 கெட்டவர்களை இடத்திலிருந்து தூக்கி எறியுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் அந்த இடத்திலிருந்து 3 கெட்டவர்கள் வீசப்பட்டனர்", + "name": "புறப்படுங்கள் பிறகு" + }, + "Onslaught God": { + "description": "5000 புள்ளிகளைப் பெறுங்கள்", + "descriptionComplete": "5000 புள்ளிகள் பெற்றுள்ளது", + "descriptionFull": "${LEVEL} இல் 5000 புள்ளிகளைப் பெறுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் 5000 புள்ளிகளைப் பெற்றுள்ளது", + "name": "${LEVEL} கடவுள்" + }, + "Onslaught Master": { + "description": "500 புள்ளிகளைப் பெறுங்கள்", + "descriptionComplete": "500 புள்ளிகள் பெற்றுள்ளது", + "descriptionFull": "${LEVEL} இல் 500 புள்ளிகளைப் பெறுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் 500 புள்ளிகளைப் பெற்றுள்ளது", + "name": "${LEVEL} குரு" + }, + "Onslaught Training Victory": { + "description": "அனைத்து அலைகளையும் தோற்கடிக்கவும்", + "descriptionComplete": "அனைத்து அலைகளையும் தோற்கடித்தது", + "descriptionFull": "அனைத்து அலைகளையும் ${LEVEL} இல் தோற்கடிக்கவும்", + "descriptionFullComplete": "${LEVEL} இல் அனைத்து அலைகளையும் தோற்கடித்தது", + "name": "${LEVEL} வெற்றி" + }, + "Onslaught Wizard": { + "description": "1000 புள்ளிகளைப் பெறுங்கள்", + "descriptionComplete": "1000 புள்ளிகளைப் பெற்றுள்ளார்", + "descriptionFull": "${LEVEL} இல் 1000 புள்ளிகளைப் பெறுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் 1000 புள்ளிகளைப் பெற்றுள்ளது", + "name": "${LEVEL} மந்திரவாதி" + }, + "Precision Bombing": { + "description": "எந்த சக்தியும் இல்லாமல் வெற்றி பெரு", + "descriptionComplete": "எந்த சக்தியும் இல்லாமல் வெற்றி பெற்றது", + "descriptionFull": "எந்த பவர் அப்களையும் பயன்படுத்தாமல் ${LEVEL} ஐ வெல்லுங்கள்", + "descriptionFullComplete": "எந்த பவர் அப்களையும் பயன்படுத்தாமல் ${LEVEL} வெற்றி பெற்றது", + "name": "துல்லியமான குண்டுவீச்சு" + }, + "Pro Boxer": { + "description": "எந்த குண்டுகளையும் பயன்படுத்தாமல் வெற்றி பெரு", + "descriptionComplete": "எந்த குண்டுகளையும் பயன்படுத்தாமல் வெற்றி பெற்றார்", + "descriptionFull": "எந்த குண்டுகளையும் பயன்படுத்தாமல் ${LEVEL} ஐ முடிக்கவும்", + "descriptionFullComplete": "எந்த வெடிகுண்டையும் பயன்படுத்தாமல் ${LEVEL} ஐ முடித்தார்", + "name": "ப்ரோ பாக்ஸர்" + }, + "Pro Football Shutout": { + "description": "கெட்டவர்கள் மதிப்பெண் பெறாமல் வெற்றி பெரு", + "descriptionComplete": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் வெற்றி பெட்ரார்", + "descriptionFull": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் ${LEVEL} வெற்றி பெரு", + "descriptionFullComplete": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் ${LEVEL} வெற்றி", + "name": "${LEVEL} பணிநிறுத்தம்" + }, + "Pro Football Victory": { + "description": "விளையாட்டை வெற்றி பெரு", + "descriptionComplete": "விளையாட்டை வென்றது", + "descriptionFull": "${LEVEL} இல் விளையாட்டை வெல்லுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் விளையாட்டை வென்றது", + "name": "${LEVEL} வெற்றி" + }, + "Pro Onslaught Victory": { + "description": "அனைத்து அலைகளையும் தோற்கடிக்கவும்", + "descriptionComplete": "அனைத்து அலைகளையும் தோற்கடித்தது", + "descriptionFull": "${LEVEL} இன் அனைத்து அலைகளையும் தோற்கடிக்கவும்", + "descriptionFullComplete": "${LEVEL} இன் அனைத்து அலைகளையும் தோற்கடித்தது", + "name": "${LEVEL} வெற்றி" + }, + "Pro Runaround Victory": { + "description": "அனைத்து அலைகளையும் முடிக்கவும்", + "descriptionComplete": "அனைத்து அலைகளையும் முடிகப்பட்டது", + "descriptionFull": "அனைத்து அலைகளையும் ${LEVEL} இல் முடிக்கவும்", + "descriptionFullComplete": "அனைத்து அலைகளையும் ${LEVEL} இல் முடிக பட்டது", + "name": "${LEVEL} வெற்றி" + }, + "Rookie Football Shutout": { + "description": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் வெற்றி பெரு", + "descriptionComplete": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் வெற்றி பெட்ரது", + "descriptionFull": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் ${LEVEL} வெல்லுங்கள்", + "descriptionFullComplete": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் ${LEVEL} வென்றது", + "name": "${LEVEL} பணிநிறுத்தம்" + }, + "Rookie Football Victory": { + "description": "விளையாட்டை வெற்றி பெரு", + "descriptionComplete": "விளையாட்டை வென்றது", + "descriptionFull": "${LEVEL} இல் விளையாட்டை வெல்லுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் விளையாட்டை வென்றது", + "name": "${LEVEL} வெற்றி" + }, + "Rookie Onslaught Victory": { + "description": "அனைத்து அலைகளையும் தோற்கடிக்கவும்", + "descriptionComplete": "அனைத்து அலைகளையும் தோற்கடித்தது", + "descriptionFull": "அனைத்து அலைகளையும் ${LEVEL} இல் தோற்கடிக்கவும்", + "descriptionFullComplete": "அனைத்து அலைகளையும் ${LEVEL} இல் தோற்கடித்தது", + "name": "${LEVEL} வெற்றி" + }, + "Runaround God": { + "description": "2000 புள்ளிகளைப் பெறுங்கள்", + "descriptionComplete": "2000 புள்ளிகளைப் பெற்றார்", + "descriptionFull": "${LEVEL} இல் 2000 புள்ளிகளைப் பெறுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் 2000 புள்ளிகளைப் பெற்றார்", + "name": "${LEVEL} கடவுள்" + }, + "Runaround Master": { + "description": "500 புள்ளிகளைப் பெறுங்கள்", + "descriptionComplete": "500 புள்ளிகளைப் பெற்றார்", + "descriptionFull": "${LEVEL} இல் 500 புள்ளிகளைப் பெறுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் 500 புள்ளிகளைப் பெற்றார்", + "name": "${LEVEL} தலைவன்" + }, + "Runaround Wizard": { + "description": "1000 புள்ளிகளைப் பெறுங்கள்", + "descriptionComplete": "1000 புள்ளிகளைப் பெற்றார்", + "descriptionFull": "${LEVEL} இல் 1000 புள்ளிகளைப் பெறுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் 1000 புள்ளிகளைப் பெற்றார்", + "name": "${LEVEL} மந்திரவாதி" + }, + "Sharing is Caring": { + "descriptionFull": "விளையாட்டை வெற்றிகரமாக நண்பருடன் பகிர்ந்து கொள்ளுங்கள்", + "descriptionFullComplete": "வெற்றிகரமாக ஒரு நண்பருடன் விளையாட்டை பகிர்ந்து கொண்டார்", + "name": "பகிர்தலே அக்கறை காட்டுதல்" + }, + "Stayin' Alive": { + "description": "இறக்காமல் வெற்றி பெரு", + "descriptionComplete": "இறக்காமல் வென்றது", + "descriptionFull": "இறக்காமல் ${LEVEL} வெல்லுங்கள்", + "descriptionFullComplete": "இறக்காமல் ${LEVEL} வென்றது", + "name": "உயிருடன் இருங்கள்" + }, + "Super Mega Punch": { + "description": "ஒரு குத்து மூலம் 100% சேதத்தை ஏற்படுத்தும்", + "descriptionComplete": "ஒரு குத்து மூலம் 100% சேதத்தை ஏற்படுத்தியது", + "descriptionFull": "${LEVEL} இல் ஒரு குத்து மூலம் 100% சேதத்தை ஏற்படுத்தவும்", + "descriptionFullComplete": "${LEVEL} இல் ஒரு குத்து மூலம் 100% சேதத்தை ஏற்படுத்தியது", + "name": "சூப்பர் மெகா குத்து" + }, + "Super Punch": { + "description": "ஒரு குத்து மூலம் 50% சேதத்தை ஏற்படுத்தவும்", + "descriptionComplete": "ஒரு குத்து மூலம் 50% சேதத்தை ஏற்படுத்தியது", + "descriptionFull": "${LEVEL} இல் ஒரு குத்து மூலம் 50% சேதத்தை ஏற்படுத்தவும்", + "descriptionFullComplete": "${LEVEL} இல் ஒரு குத்து மூலம் 50% சேதத்தை ஏற்படுத்தியது", + "name": "சூப்பர் குத்து" + }, + "TNT Terror": { + "description": "TNT மூலம் 6 கெட்டவர்களைக் கொல்லுங்கள்", + "descriptionComplete": "TNT ஆல் 6 கெட்டவர்களைக் கொன்றது", + "descriptionFull": "TNT உடன் 6 கெட்டவர்களை ${LEVEL} இல் கொல்லுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் TNT உடன் 6 கெட்டவர்களைக் கொன்றது", + "name": "TNT பயங்கரவாதம்" + }, + "Team Player": { + "descriptionFull": "4+ வீரர்களுடன் குழு விளையாட்டைத் தொடங்குங்கள்", + "descriptionFullComplete": "4+ வீரர்களுடன் ஒரு குழு விளையாட்டைத் தொடங்கினார்", + "name": "அணி வீரர்" + }, + "The Great Wall": { + "description": "ஒவ்வொரு கெட்டவரையும் நிறுத்துங்கள்", + "descriptionComplete": "ஒவ்வொரு கெட்டவரையும் நிறுத்தியது", + "descriptionFull": "ஒவ்வொரு கெட்டவரையும் ${LEVEL} இல் நிறுத்துங்கள்", + "descriptionFullComplete": "ஒவ்வொரு கெட்டவரையும் ${LEVEL} இல் நிறுத்தியது", + "name": "பெருஞ்சுவர்" + }, + "The Wall": { + "description": "ஒவ்வொரு கெட்டவரையும் நிறுத்துங்கள்", + "descriptionComplete": "ஒவ்வொரு கெட்டவரையும் நிறுத்தியது", + "descriptionFull": "ஒவ்வொரு கெட்டவரையும் ${LEVEL} இல் நிறுத்துங்கள்", + "descriptionFullComplete": "ஒவ்வொரு கெட்டவரையும் ${LEVEL} இல் நிறுத்தியது", + "name": "சுவர்" + }, + "Uber Football Shutout": { + "description": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் வெற்றி பெறுங்கள்", + "descriptionComplete": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் வென்றது", + "descriptionFull": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் ${LEVEL} வெல்லுங்கள்", + "descriptionFullComplete": "கெட்டவர்களை மதிப்பெண் பெற விடாமல் ${LEVEL} வென்றது", + "name": "${LEVEL} பணிநிறுத்தம்" + }, + "Uber Football Victory": { + "description": "விளையாட்டை வெற்றி பெரு", + "descriptionComplete": "விளையாட்டை வென்றது", + "descriptionFull": "${LEVEL} இல் விளையாட்டை வெல்லுங்கள்", + "descriptionFullComplete": "${LEVEL} இல் விளையாட்டை வென்றது", + "name": "${LEVEL} வெற்றி" + }, + "Uber Onslaught Victory": { + "description": "அனைத்து அலைகளையும் தோற்கடிக்கவும்", + "descriptionComplete": "அனைத்து அலைகளையும் தோற்கடித்தது", + "descriptionFull": "அனைத்து அலைகளையும் ${LEVEL} இல் தோற்கடிக்கவும்", + "descriptionFullComplete": "${LEVEL} இல் அனைத்து அலைகளையும் தோற்கடித்தது", + "name": "${LEVEL} வெற்றி" + }, + "Uber Runaround Victory": { + "description": "அனைத்து அலைகளையும் முடிக்கவும்", + "descriptionComplete": "அனைத்து அலைகளையும் முடித்தது", + "descriptionFull": "அனைத்து அலைகளையும் ${LEVEL} இல் முடிக்கவும்", + "descriptionFullComplete": "அனைத்து அலைகளையும் ${LEVEL} இல் முடித்தது", + "name": "${LEVEL} வெற்றி" + } + }, + "achievementsRemainingText": "மீதமுள்ள சாதனைகள்:", + "achievementsText": "சாதனைகள்", + "achievementsUnavailableForOldSeasonsText": "மன்னிக்கவும், சாதனை விவரங்கள் பழைய பருவங்களுக்கு கிடைக்கவில்லை.", + "activatedText": "${THING} செயல்படுத்தப்பட்டது.", + "addGameWindow": { + "getMoreGamesText": "மேலும் விளையாட்டுகளைப் பெறுங்கள்...", + "titleText": "விளையாட்டைச் சேர்" + }, + "allowText": "அனுமதி", + "alreadySignedInText": "உங்கள் கணக்கு மற்றொரு சாதனத்திலிருந்து உள்நுழைந்துள்ளது;\nதயவுசெய்து கணக்குகளை மாற்றவும் அல்லது விளையாட்டை மூடவும்\nபிற சாதனங்கள் மற்றும் மீண்டும் முயற்சிக்கவும்.", + "apiVersionErrorText": "${NAME} தொகுதியை ஏற்ற முடியவில்லை; இது api-version ${VERSION_USED} ஐ குறிவைக்கிறது; எங்களுக்கு ${VERSION_REQUIRED} தேவைப்படுகிறது.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(ஹெட்ஃபோன்கள் செருகப்படும்போது மட்டுமே \"ஆட்டோ\" இதை இயக்குகிறது)", + "headRelativeVRAudioText": "தலை-உறவினர் VR ஆடியோ", + "musicVolumeText": "இசை ஒலி அளவு", + "soundVolumeText": "ஒலி அளவு", + "soundtrackButtonText": "ஒலிப்பதிவுகள்", + "soundtrackDescriptionText": "(விளையாட்டுகளின் போது விளையாட உங்கள் சொந்த இசையை ஒதுக்குங்கள்)", + "titleText": "ஒலி அமைவு" + }, + "autoText": "Auto", + "backText": "பின்னால்", + "banThisPlayerText": "இந்த பிளேயரை தடை செய்யவும்", + "bestOfFinalText": "சிறந்த-${COUNT} இறுதி", + "bestOfSeriesText": "${COUNT} தொடரின் சிறந்தவை:", + "bestOfUseFirstToInstead": 0, + "bestRankText": "உங்கள் சிறந்த #${RANK}", + "bestRatingText": "உங்கள் சிறந்த மதிப்பீடு ${RATING}", + "bombBoldText": "வெடி குண்டு", + "bombText": "வெடிகுண்டு", + "boostText": "ஊக்குவிக்கவும்", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} பயன்பாட்டில் உள்ளமைக்கப்பட்டுள்ளது.", + "buttonText": "பொத்தானை", + "canWeDebugText": "BombSquad தானாகப் புகாரளிக்க விரும்புகிறீர்களா?\nடெவலப்பருக்கு பிழைகள், செயலிழப்புகள் மற்றும் அடிப்படை பயன்பாட்டு தகவல்?\n\nஇந்தத் தரவில் தனிப்பட்ட தகவல் இல்லை மற்றும் உதவுகிறது\nவிளையாட்டை சீராக மற்றும் பிழையில்லாமல் வைத்துக்கொள்ளுங்கள்.", + "cancelText": "ரத்து", + "cantConfigureDeviceText": "மன்னிக்கவும்,${DEVICE} கட்டமைக்கப்படவில்லை.", + "challengeEndedText": "இந்த சவால் முடிந்தது.", + "chatMuteText": "அரட்டை முடக்கு", + "chatMutedText": "அரட்டை முடக்கப்பட்டது", + "chatUnMuteText": "அரட்டையை இயக்கு", + "choosingPlayerText": "<பிளேயரைத் தேர்ந்தெடுப்பது>", + "completeThisLevelToProceedText": "தொடர நீங்கள்\n இந்த நிலையை முடிக்க வேண்டும்!", + "completionBonusText": "நிறைவு போனஸ்", + "configControllersWindow": { + "configureControllersText": "கட்டுப்பாட்டாளர்களை உள்ளமைக்கவும்", + "configureKeyboard2Text": "விசைப்பலகை P2 ஐ உள்ளமைக்கவும்", + "configureKeyboardText": "விசைப்பலகையை உள்ளமைக்கவும்", + "configureMobileText": "கட்டுப்பாட்டாளர்களாக மொபைல் சாதனங்கள்", + "configureTouchText": "தொடுதிரையை உள்ளமைக்கவும்", + "ps3Text": "PS3 கட்டுப்பாட்டாளர்கள்", + "titleText": "கட்டுப்பாட்டாளர்கள்", + "wiimotesText": "விமோட்ஸ்", + "xbox360Text": "Xbox 360 கட்டுப்பாட்டாளர்கள்" + }, + "configGamepadSelectWindow": { + "androidNoteText": "குறிப்பு: கட்டுப்படுத்தி ஆதரவு சாதனம் மற்றும் ஆண்ட்ராய்டு பதிப்பைப் பொறுத்து மாறுபடும்.", + "pressAnyButtonText": "கட்டுப்படுத்தியின் எந்த பொத்தானையும் அழுத்தவும்\nநீங்கள் கட்டமைக்க விரும்புகிறீர்கள்...", + "titleText": "கட்டுப்பாட்டாளர்களை உள்ளமைக்கவும்" + }, + "configGamepadWindow": { + "advancedText": "உயர்தரமான", + "advancedTitleText": "மேம்பட்ட கட்டுப்படுத்தி அமைப்பு", + "analogStickDeadZoneDescriptionText": "(நீங்கள் குச்சியை வெளியிடும் போது உங்கள் எழுத்து 'திசைதிருப்பினால்' இதை இயக்கவும்)", + "analogStickDeadZoneText": "அனலாக் ஸ்டிக் டெட் மண்டலம்", + "appliesToAllText": "(இந்த வகை அனைத்து கட்டுப்படுத்திகளுக்கும் பொருந்தும்)", + "autoRecalibrateDescriptionText": "(உங்கள் எழுத்து முழு வேகத்தில் நகரவில்லை என்றால் இதை இயக்கவும்)", + "autoRecalibrateText": "அனலாக் குச்சியை தானாக மறுபரிசீலனை செய்யுங்கள்", + "axisText": "அச்சு", + "clearText": "தெளிந்த", + "dpadText": "dpad", + "extraStartButtonText": "கூடுதல் தொடக்க பட்டன்", + "ifNothingHappensTryAnalogText": "எதுவும் நடக்கவில்லை என்றால், அதற்கு பதிலாக அனலாக் ஸ்டிக்கிற்கு ஒதுக்க முயற்சிக்கவும்.", + "ifNothingHappensTryDpadText": "எதுவும் நடக்கவில்லை என்றால், அதற்கு பதிலாக D-pad டிற்கு ஒதுக்க முயற்சிக்கவும்.", + "ignoreCompletelyDescriptionText": "(இந்த கட்டுப்படுத்தி விளையாட்டு அல்லது மெனுக்களை பாதிக்காமல் தடுக்கவும்)", + "ignoreCompletelyText": "முற்றிலும் புறக்கணிக்கவும்", + "ignoredButton1Text": "புறக்கணிக்கப்பட்ட பட்டன் 1", + "ignoredButton2Text": "புறக்கணிக்கப்பட்ட பட்டன் 2", + "ignoredButton3Text": "புறக்கணிக்கப்பட்ட பட்டன் 3", + "ignoredButton4Text": "புறக்கணிக்கப்பட்ட பட்டன் 4", + "ignoredButtonDescriptionText": "('முகப்பு' அல்லது 'ஒத்திசைவு' பொத்தான்கள் UI ஐ பாதிக்காமல் தடுக்க இதைப் பயன்படுத்தவும்)", + "pressAnyAnalogTriggerText": "எந்த அனலாக் தூண்டுதலையும் அழுத்தவும்...", + "pressAnyButtonOrDpadText": "எந்த பட்டன் அல்லது dpad ஐ அழுத்தவும்...", + "pressAnyButtonText": "எந்த பட்டனையும் அழுத்தவும்...", + "pressLeftRightText": "இடது அல்லது வலது அழுத்தவும்...", + "pressUpDownText": "மேலே அல்லது கீழ் அழுத்தவும்...", + "runButton1Text": "ரன் பட்டன் 1", + "runButton2Text": "ரன் பட்டன் 2", + "runTrigger1Text": "இயக்க தூண்டுதல் 1", + "runTrigger2Text": "இயக்க தூண்டுதல் 2", + "runTriggerDescriptionText": "(அனலாக் தூண்டுதல்கள் உங்களை மாறி வேகத்தில் இயக்க அனுமதிக்கின்றன)", + "secondHalfText": "இரண்டாவது பாதியை உள்ளமைக்க இதைப் பயன்படுத்தவும்\n2-கட்டுப்படுத்திகள்-இன் -1 சாதனத்தின்\nஒற்றை கட்டுப்பாட்டாளராகக் காட்டுகிறது.", + "secondaryEnableText": "இயக்கு", + "secondaryText": "இரண்டாம் நிலை கட்டுப்பாட்டாளர்", + "startButtonActivatesDefaultDescriptionText": "(உங்கள் தொடக்க பொத்தானை 'மெனு' பொத்தானை விட அதிகமாக இருந்தால் இதை அணைக்கவும்)", + "startButtonActivatesDefaultText": "தொடக்க பட்டன் இயல்புநிலை விட்ஜெட்டை செயல்படுத்துகிறது", + "titleText": "கட்டுப்படுத்தி அமைப்பு", + "twoInOneSetupText": "2-in-1 கட்டுப்படுத்தி அமைப்பு", + "uiOnlyDescriptionText": "(இந்த கட்டுப்படுத்தி உண்மையில் ஒரு விளையாட்டில் சேர்வதைத் தடுக்கவும்)", + "uiOnlyText": "மெனு உபயோகத்திற்கு வரம்பு", + "unassignedButtonsRunText": "ஒதுக்கப்படாத அனைத்து பட்டன் இயங்குகின்றன", + "unsetText": "<அமைக்கப்படவில்லை>", + "vrReorientButtonText": "VR மறுசீரமைப்பு பட்டன்" + }, + "configKeyboardWindow": { + "configuringText": "${DEVICE} ஐ உள்ளமைக்கிறது", + "keyboard2NoteText": "குறிப்பு: பெரும்பாலான விசைப்பலகைகள் ஒரு சில விசை அழுத்தங்களை மட்டுமே பதிவு செய்ய முடியும்\nஒரு முறை, அதனால் இரண்டாவது விசைப்பலகை பிளேயர் இருந்தால் நன்றாக வேலை செய்யலாம்\nஅவர்கள் பயன்படுத்த தனி விசைப்பலகை இணைக்கப்பட்டிருந்தால்.\nநீங்கள் இன்னும் தனிப்பட்ட விசைகளை ஒதுக்க வேண்டும் என்பதை நினைவில் கொள்க\nஅந்த வழக்கில் கூட இரண்டு வீரர்கள்." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "நடவடிக்கை கட்டுப்பாட்டு அளவு", + "actionsText": "செயல்கள்", + "buttonsText": "பட்டன்கள்", + "dragControlsText": "<கட்டுப்பாடுகளை இடமாற்றம் செய்ய இழுக்கவும்>", + "joystickText": "ஜாய்ஸ்டிக்", + "movementControlScaleText": "இயக்கக் கட்டுப்பாட்டு அளவு", + "movementText": "இயக்கம்", + "resetText": "மீட்டமை", + "swipeControlsHiddenText": "ஸ்வைப் ஐகான்களை மறைக்கவும்", + "swipeInfoText": "'ஸ்வைப்' பாணி கட்டுப்பாடுகள் கொஞ்சம் பழகிவிடும் ஆனால்\nகட்டுப்பாடுகளை பார்க்காமல் விளையாடுவதை எளிதாக்குங்கள்.", + "swipeText": "ஸ்வைப்", + "titleText": "தொடுதிரையை உள்ளமைக்கவும்" + }, + "configureItNowText": "இப்போது அதை உள்ளமைக்கவா?", + "configureText": "உள்ளமை", + "connectMobileDevicesWindow": { + "amazonText": "அமேசான் ஆப்ஸ்டோர்", + "appStoreText": "ஆப் ஸ்டோர்", + "bestResultsScale": 0.65, + "bestResultsText": "சிறந்த முடிவுகளுக்கு உங்களுக்கு பின்னடைவு இல்லாத வைஃபை நெட்வொர்க் தேவை. உன்னால் முடியும்\nமற்ற வயர்லெஸ் சாதனங்களை அணைப்பதன் மூலம் வைஃபை லேக்கை குறைக்கவும்\nஉங்கள் வைஃபை திசைவிக்கு அருகில் விளையாடி, மற்றும் இணைப்பதன் மூலம்\nஈதர்நெட் வழியாக கேம் ஹோஸ்ட் நேரடியாக நெட்வொர்க்கிற்கு.", + "explanationText": "வயர்லெஸ் கன்ட்ரோலராக ஸ்மார்ட் போன் அல்லது டேப்லெட்டைப் பயன்படுத்த,\n\"${REMOTE_APP_NAME}\" பயன்பாட்டை நிறுவவும். எந்த எண்ணிக்கையிலான சாதனங்கள்\nWi-Fi மூலம் ${APP_NAME} கேமுடன் இணைக்க முடியும், அது இலவசம்!", + "forAndroidText": "Android க்கான:", + "forIOSText": "iOS க்கு:", + "getItForText": "ஆப்பிள் ஆப் ஸ்டோரில் iOS க்கு ${REMOTE_APP_NAME} ஐப் பெறுங்கள்\nஅல்லது Google Play Store அல்லது Amazon Appstore இல் Android க்காக", + "googlePlayText": "கூகிள் பிலே", + "titleText": "மொபைல் சாதனங்களை கட்டுப்படுத்திகளாகப் பயன்படுத்துதல்:" + }, + "continuePurchaseText": "${PRICE} க்கு தொடரவா?", + "continueText": "தொடரவும்", + "controlsText": "கட்டுப்பாடுகள்", + "coopSelectWindow": { + "activenessAllTimeInfoText": "இது எல்லா நேர தரவரிசைகளுக்கும் பொருந்தாது.", + "activenessInfoText": "நீங்கள் இருக்கும் நாட்களில் இந்த பெருக்கி உயரும்\nநீங்கள் விளையாடாத நாட்களில் விளையாடுங்கள் மற்றும் குறையுங்கள்.", + "activityText": "செயல்பாடு", + "campaignText": "பிரச்சாரம்", + "challengesInfoText": "மினி-கேம்களை முடித்ததற்காக பரிசுகளைப் பெறுங்கள்.\n\nபரிசுகள் மற்றும் சிரம நிலைகள் அதிகரிக்கும்\nஒவ்வொரு முறையும் ஒரு சவால் நிறைவடைகிறது மற்றும்\nகாலாவதியாகும் போது அல்லது இழக்கப்படும் போது குறையும்.", + "challengesText": "சவால்கள்", + "currentBestText": "தற்போதைய சிறந்தது", + "customText": "தனிப்பயன்", + "entryFeeText": "நுழைவு", + "forfeitConfirmText": "இந்த சவாலை இழந்தீர்களா?", + "forfeitNotAllowedYetText": "இந்த சவாலை இன்னும் இழக்க முடியாது.", + "forfeitText": "இழப்பு", + "multipliersText": "பெருக்கிகள்", + "nextChallengeText": "அடுத்த சவால்", + "nextPlayText": "அடுத்த விளையாட்டு", + "ofTotalTimeText": "${TOTAL} இல்", + "playNowText": "இப்பொழுதே விளையாடு", + "pointsText": "புள்ளிகள்", + "powerRankingFinishedSeasonUnrankedText": "(சீசன் முடிவடையவில்லை)", + "powerRankingNotInTopText": "(மேல் ${NUMBER} இல் இல்லை)", + "powerRankingPointsEqualsText": "= ${NUMBER} pts", + "powerRankingPointsMultText": "(x ${NUMBER} புள்ளிகள்)", + "powerRankingPointsText": "${NUMBER} புள்ளிகள்", + "powerRankingPointsToRankedText": "(${REMAINING} புள்ளிகளில் ${CURRENT})", + "powerRankingText": "சக்தி தரவரிசை", + "prizesText": "பரிசுகள்", + "proMultInfoText": "${PRO} மேம்படுத்தப்பட்ட வீரர்கள்\nஇங்கே ${PERCENT}% புள்ளியைப் பெறுக.", + "seeMoreText": "மேலும்...", + "skipWaitText": "காத்திருப்பைத் தவிர்க்கவும்", + "timeRemainingText": "மீதியுள்ள நேரம்", + "toRankedText": "தரவரிசைக்கு", + "totalText": "மொத்தம்", + "tournamentInfoText": "அதிக மதிப்பெண்களுடன் போட்டியிடவும்\nஉங்கள் லீக்கில் உள்ள மற்ற வீரர்கள்.\n\nஅதிக மதிப்பெண் பெற்றவர்களுக்கு பரிசுகள் வழங்கப்படுகின்றன\nபோட்டி நேரம் முடிவடையும் போது வீரர்கள்.", + "welcome1Text": "${LEAGUE} க்கு வரவேற்கிறோம். நீங்கள் உங்கள் மேம்படுத்த முடியும்\nநட்சத்திர மதிப்பீடுகளை சம்பாதிப்பதன் மூலம் லீக் தரவரிசை, முடித்தல்\nசாதனைகள், மற்றும் போட்டிகளில் கோப்பைகளை வென்றது.", + "welcome2Text": "இதே போன்ற பல செயல்களில் இருந்து நீங்கள் டிக்கெட்டுகளைப் பெறலாம்.\nபுதிய எழுத்துக்கள், வரைபடங்கள் மற்றும் பலவற்றைத் திறக்க டிக்கெட்டுகளைப் பயன்படுத்தலாம்\nசிறு விளையாட்டுகள், போட்டிகளில் நுழைய, மற்றும் பல.", + "yourPowerRankingText": "உங்கள் சக்தி தரவரிசை:" + }, + "copyConfirmText": "கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது.", + "copyOfText": "${NAME} பிரதி", + "copyText": "நகல்", + "createEditPlayerText": "<பிளேயரை உருவாக்கவும்/திருத்தவும்>", + "createText": "உருவாக்கு", + "creditsWindow": { + "additionalAudioArtIdeasText": "கூடுதல் ஆடியோ, ஆரம்ப கலைப்படைப்பு மற்றும் யோசனைகள் ${NAME}", + "additionalMusicFromText": "${NAME} இலிருந்து கூடுதல் இசை", + "allMyFamilyText": "என் நண்பர்கள் மற்றும் குடும்பத்தினர் அனைவரும் டெஸ்ட் விளையாட உதவினார்கள்", + "codingGraphicsAudioText": "கோடிங், கிராபிக்ஸ் மற்றும் ஆடியோ: ${NAME}", + "languageTranslationsText": "மொழி மொழிபெயர்ப்புகள்:", + "legalText": "சட்ட:", + "publicDomainMusicViaText": "${NAME} வழியாக பொது டொமைன் இசை", + "softwareBasedOnText": "இந்த மென்பொருள் ${NAME} இன் பணியை அடிப்படையாகக் கொண்டது", + "songCreditText": "${TITLE} ${PERFORMER} ஆல் நிகழ்த்தப்பட்டது\n${COMPOSER} ஆல் இயற்றப்பட்டது, ${ARRANGER} ஆல் ஏற்பாடு செய்யப்பட்டது, ${PUBLISHER} ஆல் வெளியிடப்பட்டது,\nமரியாதை ${SOURCE}", + "soundAndMusicText": "ஒலி மற்றும் இசை:", + "soundsText": "ஒலிகள் (${SOURCE}):", + "specialThanksText": "சிறப்பு நன்றி:", + "thanksEspeciallyToText": "குறிப்பாக ${NAME} க்கு நன்றி", + "titleText": "${APP_NAME} வரவுகள்", + "whoeverInventedCoffeeText": "காபியை கண்டுபிடித்தவர்" + }, + "currentStandingText": "உங்கள் தற்போதைய நிலை #${RANK}", + "customizeText": "தனிப்பயனாக்கலாம்...", + "deathsTallyText": "${COUNT} உயிரிழப்புகள்", + "deathsText": "உயிரிழப்புகள்", + "debugText": "பிழைத்திருத்தம்", + "debugWindow": { + "reloadBenchmarkBestResultsText": "குறிப்பு: இதைச் சோதிக்கும்போது அமைப்புகள்-> கிராபிக்ஸ்-> அமைப்புகளை 'உயர்' என அமைக்க பரிந்துரைக்கப்படுகிறது.", + "runCPUBenchmarkText": "CPU பெஞ்ச்மார்க்கை இயக்கவும்", + "runGPUBenchmarkText": "GPU பெஞ்ச்மார்க்கை இயக்கவும்", + "runMediaReloadBenchmarkText": "மீடியா-ரீலோட் பெஞ்ச்மார்க்கை இயக்கவும்", + "runStressTestText": "மன அழுத்த சோதனையை இயக்கவும்", + "stressTestPlayerCountText": "பிளேயர் எண்ணிக்கை", + "stressTestPlaylistDescriptionText": "மன அழுத்த சோதனை பிளேலிஸ்ட்", + "stressTestPlaylistNameText": "பிளேலிஸ்ட் பெயர்", + "stressTestPlaylistTypeText": "பிளேலிஸ்ட் வகை", + "stressTestRoundDurationText": "சுற்று நேரம்", + "stressTestTitleText": "அழுத்த சோதனை", + "titleText": "வரையறைகள் மற்றும் அழுத்த சோதனைகள்", + "totalReloadTimeText": "மொத்த மறுஏற்றம் நேரம்: ${TIME} (விவரங்களுக்கு பதிவைப் பார்க்கவும்)" + }, + "defaultGameListNameText": "இயல்புநிலை ${PLAYMODE} பிளேலிஸ்ட்", + "defaultNewGameListNameText": "எனது ${PLAYMODE} பிளேலிஸ்ட்", + "deleteText": "அழி", + "demoText": "டெமோ", + "denyText": "மறுக்க", + "deprecatedText": "நிராகரிக்கப்பட்டது", + "desktopResText": "டெஸ்க்டாப் ரெஸ்", + "deviceAccountUpgradeText": "எச்சரிக்கை:\nசாதனக் கணக்கில் (${NAME}) உள்நுழைந்துள்ளீர்கள்.\nஎதிர்கால புதுப்பிப்பில் சாதன கணக்குகள் அகற்றப்படும்.\nஉங்கள் முன்னேற்றத்தைத் தொடர விரும்பினால், V2 கணக்கிற்கு மேம்படுத்தவும்.", + "difficultyEasyText": "சுலபம்", + "difficultyHardOnlyText": "கடினமான முறை மட்டுமே", + "difficultyHardText": "கடினமான", + "difficultyHardUnlockOnlyText": "இந்த நிலை கடினமான முறையில் மட்டுமே திறக்க முடியும்.\nஉங்களுக்கு என்ன தேவை என்று நீங்கள் நினைக்கிறீர்களா!?!?!", + "directBrowserToURLText": "தயவுசெய்து பின்வரும் URL க்கு ஒரு இணைய உலாவியை இயக்கவும்:", + "disableRemoteAppConnectionsText": "ரிமோட்-ஆப் இணைப்புகளை முடக்கு", + "disableXInputDescriptionText": "4 க்கும் மேற்பட்ட கட்டுப்பாட்டாளர்களை அனுமதிக்கிறது ஆனால் வேலை செய்யாமல் போகலாம்.", + "disableXInputText": "XInput ஐ முடக்கு", + "doneText": "முடிந்தது", + "drawText": "டிரா", + "duplicateText": "நகல்எடுத்தல்", + "editGameListWindow": { + "addGameText": "கூட்டு\nவிளையாட்டு", + "cantOverwriteDefaultText": "இயல்புநிலை பிளேலிஸ்ட்டை மேலெழுத முடியாது!", + "cantSaveAlreadyExistsText": "அந்த பெயருடன் ஒரு பிளேலிஸ்ட் ஏற்கனவே உள்ளது!", + "cantSaveEmptyListText": "வெற்று பிளேலிஸ்ட்டைச் சேமிக்க முடியவில்லை!", + "editGameText": "தொகு\nவிளையாட்டு", + "listNameText": "பிளேலிஸ்ட் பெயர்", + "nameText": "பெயர்", + "removeGameText": "அகற்று\nவிளையாட்டு", + "saveText": "பட்டியலைச் சேமிக்கவும்", + "titleText": "பிளேலிஸ்ட் எடிட்டர்" + }, + "editProfileWindow": { + "accountProfileInfoText": "இந்த சிறப்பு சுயவிவரத்திற்கு ஒரு பெயர் உள்ளது\nமற்றும் உங்கள் கணக்கை அடிப்படையாகக் கொண்ட ஐகான்.\n\n${ICONS}\n\nபயன்படுத்த தனிப்பயன் சுயவிவரங்களை உருவாக்கவும்\nவெவ்வேறு பெயர்கள் அல்லது தனிப்பயன் சின்னங்கள்.", + "accountProfileText": "(கணக்கு விவரம்)", + "availableText": "\"${NAME}\" என்ற பெயர் உள்ளது.", + "characterText": "குணம்", + "checkingAvailabilityText": "\"${NAME}\" க்கான இருப்பைச் சரிபார்க்கிறது...", + "colorText": "நிறம்", + "getMoreCharactersText": "அதிக கதாபாத்திரங்களைப் பெறுங்கள்...", + "getMoreIconsText": "மேலும் சின்னங்களைப் பெறுங்கள்...", + "globalProfileInfoText": "உலகளாவிய பிளேயர் சுயவிவரங்கள் தனித்துவமானவை என்று உத்தரவாதம் அளிக்கப்படுகின்றன\nஉலகளாவிய பெயர்கள். அவற்றில் தனிப்பயன் சின்னங்களும் அடங்கும்.", + "globalProfileText": "(உலக சுயவிவரம்)", + "highlightText": "முன்னிலைப்படுத்த", + "iconText": "ஐகான்", + "localProfileInfoText": "உள்ளூர் பிளேயர் சுயவிவரங்களுக்கு ஐகான்கள் இல்லை மற்றும் அவற்றின் பெயர்கள் உள்ளன\nதனிப்பட்டதாக உத்தரவாதம் இல்லை. உலகளாவிய சுயவிவரத்திற்கு மேம்படுத்தவும்\nதனித்துவமான பெயரை முன்பதிவு செய்து தனிப்பயன் ஐகானைச் சேர்க்கவும்.", + "localProfileText": "(உள்ளூர் சுயவிவரம்)", + "nameDescriptionText": "வீரரின் பெயர்", + "nameText": "பெயர்", + "randomText": "சீரற்ற", + "titleEditText": "சுயவிவரத்தைத் திருத்து", + "titleNewText": "புதிய சுயவிவரம்", + "unavailableText": "\"${NAME}\" கிடைக்கவில்லை; மற்றொரு பெயரை முயற்சிக்கவும்.", + "upgradeProfileInfoText": "இது உலகம் முழுவதும் உங்கள் பிளேயர் பெயரை முன்பதிவு செய்யும்\nமற்றும் தனிப்பயன் ஐகானை ஒதுக்க உங்களை அனுமதிக்கிறது.", + "upgradeToGlobalProfileText": "உலகளாவிய சுயவிவரத்திற்கு மேம்படுத்தவும்" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "இயல்புநிலை ஒலிப்பதிவை நீங்கள் நீக்க முடியாது.", + "cantEditDefaultText": "இயல்புநிலை ஒலிப்பதிவை திருத்த முடியாது. அதை நகலெடுக்கவும் அல்லது புதிய ஒன்றை உருவாக்கவும்.", + "cantOverwriteDefaultText": "இயல்புநிலை ஒலிப்பதிவை மேலெழுத முடியாது", + "cantSaveAlreadyExistsText": "அந்த பெயருடன் ஒரு ஒலிப்பதிவு ஏற்கனவே உள்ளது!", + "defaultGameMusicText": "<இயல்பான விளையாட்டு இசை>", + "defaultSoundtrackNameText": "இயல்பு ஒலிப்பதிவு", + "deleteConfirmText": "ஒலிப்பதிவை நீக்கு:\n\n'${NAME}'?", + "deleteText": "அழி\nஒலிப்பதிவு", + "duplicateText": "நகல்\nஒலிப்பதிவு", + "editSoundtrackText": "ஒலிப்பதிவு எடிட்டர்", + "editText": "தொகு\nஒலிப்பதிவு", + "fetchingITunesText": "மியூசிக் ஆப் பிளேலிஸ்ட்களைப் பெறுகிறது...", + "musicVolumeZeroWarning": "எச்சரிக்கை: இசை அளவு 0 ஆக அமைக்கப்பட்டுள்ளது", + "nameText": "பெயர்", + "newSoundtrackNameText": "எனது ஒலிப்பதிவு ${COUNT}", + "newSoundtrackText": "புதிய ஒலிப்பதிவு:", + "newText": "புதிய\nஒலிப்பதிவு", + "selectAPlaylistText": "ஒரு பிளேலிஸ்ட்டைத் தேர்ந்தெடுக்கவும்", + "selectASourceText": "இசை ஆதாரம்", + "testText": "சோதனை", + "titleText": "ஒலிப்பதிவுகள்", + "useDefaultGameMusicText": "இயல்புநிலை விளையாட்டு இசை", + "useITunesPlaylistText": "இசை ஆப் பிளேலிஸ்ட்", + "useMusicFileText": "இசை கோப்பு (mp3, போன்றவை)", + "useMusicFolderText": "இசை கோப்புகளின் கோப்புறை" + }, + "editText": "மாற்று", + "endText": "முற்று", + "enjoyText": "மகிழ்!", + "epicDescriptionFilterText": "${DESCRIPTION} காவிய மெதுவான இயக்கத்தில்.", + "epicNameFilterText": "காவியம் ${NAME}", + "errorAccessDeniedText": "அணுகல் மறுக்கப்பட்டது", + "errorDeviceTimeIncorrectText": "உங்கள் சாதனத்தின் நேரம் ${HOURS} மணிநேரம் தவறாக உள்ளது.\nஇதனால் பிரச்னைகள் ஏற்பட வாய்ப்புள்ளது.\nஉங்கள் நேரம் மற்றும் நேர மண்டல அமைப்புகளைச் சரிபார்க்கவும்.", + "errorOutOfDiskSpaceText": "வட்டு இடத்திற்கு வெளியே", + "errorSecureConnectionFailText": "பாதுகாப்பான கிளவுட் இணைப்பை நிறுவ முடியவில்லை; பிணைய செயல்பாடு தோல்வியடையலாம்.", + "errorText": "பிழை", + "errorUnknownText": "அறியப்படாத பிழை", + "exitGameText": "${APP_NAME} இலிருந்து வெளியேறவா?", + "exportSuccessText": "'${NAME}' ஏற்றுமதி செய்யப்பட்டது.", + "externalStorageText": "வெளிப்புற சேமிப்பு", + "failText": "தோல்வி", + "fatalErrorText": "அட டா; ஏதாவது காணவில்லை அல்லது உடைந்திருக்கிறது.\nதயவுசெய்து பயன்பாட்டை மீண்டும் நிறுவ முயற்சிக்கவும் அல்லது\nஉதவிக்கு ${EMAIL} ஐ தொடர்பு கொள்ளவும்.", + "fileSelectorWindow": { + "titleFileFolderText": "ஒரு கோப்பு அல்லது கோப்புறையைத் தேர்ந்தெடுக்கவும்", + "titleFileText": "ஒரு கோப்பைத் தேர்ந்தெடுக்கவும்", + "titleFolderText": "ஒரு கோப்புறையைத் தேர்ந்தெடுக்கவும்", + "useThisFolderButtonText": "இந்த கோப்புறையைப் பயன்படுத்தவும்" + }, + "filterText": "வடிகட்டி", + "finalScoreText": "இறுதி மதிப்பெண்", + "finalScoresText": "இறுதி மதிப்பெண்கள்", + "finalTimeText": "இறுதி நேரம்", + "finishingInstallText": "நிறுவலை முடித்தல்; ஒரு நிமிடம்...", + "fireTVRemoteWarningText": "* சிறந்த அனுபவத்திற்கு, பயன்படுத்தவும்\nவிளையாட்டு கட்டுப்பாட்டாளர்கள் அல்லது நிறுவ\nஉங்கள் '${REMOTE_APP_NAME}' பயன்பாடு\nதொலைபேசிகள் இன்ஸ்டால் செய்யவும்", + "firstToFinalText": "முதலில்-${COUNT} இறுதி", + "firstToSeriesText": "முதல்-${COUNT} தொடர்", + "fiveKillText": "ஐந்து கொலை!!!", + "flawlessWaveText": "குறைபாடற்ற அலை!", + "fourKillText": "நான்கு கொலை!!!", + "friendScoresUnavailableText": "நண்பர் மதிப்பெண்கள் கிடைக்கவில்லை.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "விளையாட்டு ${COUNT} தலைவர்கள்", + "gameListWindow": { + "cantDeleteDefaultText": "இயல்புநிலை பிளேலிஸ்ட்டை நீங்கள் நீக்க முடியாது.", + "cantEditDefaultText": "இயல்புநிலை பிளேலிஸ்ட்டைத் திருத்த முடியாது! அதை நகலெடுக்கவும் அல்லது புதிய ஒன்றை உருவாக்கவும்.", + "cantShareDefaultText": "இயல்புநிலை பிளேலிஸ்ட்டை நீங்கள் பகிர முடியாது.", + "deleteConfirmText": "\"${LIST}\" ஐ நீக்கவா?", + "deleteText": "நீக்கு\nபிளேலிஸ்ட்", + "duplicateText": "நகல்எடு்\nபிளேலிஸ்ட்", + "editText": "தொகு\nபிளேலிஸ்ட்", + "newText": "புதிய\nபிளேலிஸ்ட்", + "showTutorialText": "டுடோரியலைக் காட்டு", + "shuffleGameOrderText": "விளையாட்டு ஆர்டரை கலக்கவும்", + "titleText": "${TYPE} பிளேலிஸ்ட்களைத் தனிப்பயனாக்கவும்" + }, + "gameSettingsWindow": { + "addGameText": "விளையாட்டைச் சேர்க்கவும்" + }, + "gamesToText": "${WINCOUNT} விளையாட்டுகள் ${LOSECOUNT} க்கு", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "நினைவில் கொள்ளுங்கள்: ஒரு பார்ட்டியின் எந்த சாதனமும் அதிகமாக இருக்கலாம்\nஉங்களிடம் போதுமான கட்டுப்படுத்திகள் இருந்தால் ஒரு வீரரை விட.", + "aboutDescriptionText": "ஒரு பார்ட்டியைக் கூட்ட இந்த தாவல்களைப் பயன்படுத்தவும்\n\nவிளையாட்டுகள் மற்றும் போட்டிகளில் விளையாட பார்ட்டிகளை உங்களை அனுமதிக்கின்றன\nவெவ்வேறு சாதனங்களில் உங்கள் நண்பர்களுடன்.\n\nமேல் வலதுபுறத்தில் உள்ள ${PARTY} பொத்தானைப் பயன்படுத்தவும்\nஉங்கள் பார்ட்டி உடன் அரட்டையடிக்கவும் தொடர்பு கொள்ளவும்.\n(ஒரு கட்டுப்படுத்தியில், ஒரு மெனுவில் இருக்கும்போது ${BUTTON} ஐ அழுத்தவும்)", + "aboutText": "இது பற்றி", + "addressFetchErrorText": "<முகவரிகளைப் பெறுவதில் பிழை>", + "appInviteMessageText": "${NAME} உங்களுக்கு ${APP_NAME} இல் ${COUNT} டிக்கெட்டுகளை அனுப்பியுள்ளார்", + "appInviteSendACodeText": "அவர்களுக்கு ஒரு குறியீட்டை அனுப்பவும்", + "appInviteTitleText": "${APP_NAME} ஆப் அழைப்பு", + "bluetoothAndroidSupportText": "(ப்ளூடூத்தை ஆதரிக்கும் எந்த ஆண்ட்ராய்டு சாதனத்திலும் வேலை செய்யும்)", + "bluetoothDescriptionText": "ப்ளூடூத் மூலம் ஒரு பார்ட்டி நடத்துங்கள்/சேருங்கள்:", + "bluetoothHostText": "ப்ளூடூத் மூலம் ஹோஸ்ட் செய்யவும்", + "bluetoothJoinText": "ப்ளூடூத் மூலம் சேரவும்", + "bluetoothText": "புளூடூத்", + "checkingText": "சரிபார்க்கிறது...", + "copyCodeConfirmText": "குறியீடு கிளிப்போர்டுக்கு நகலெடுக்கப்பட்டது.", + "copyCodeText": "நகல் குறியீடு", + "dedicatedServerInfoText": "சிறந்த முடிவுகளுக்கு, ஒரு பிரத்யேக சர்வரை அமைக்கவும். எப்படி என்பதை அறிய bombsquadgame.com/server ஐ பார்க்கவும்.", + "disconnectClientsText": "இது ${COUNT} பிளேயர் (களை) துண்டிக்கும்\nஉங்கள் கட்சியில். நீங்கள் சொல்வது உறுதியா?", + "earnTicketsForRecommendingAmountText": "அவர்கள் விளையாட்டை முயற்சித்தால் நண்பர்கள் ${COUNT} டிக்கெட்டுகளைப் பெறுவார்கள்\n(மேலும் ஒவ்வொருவருக்கும் நீங்கள் ${YOU_COUNT} பெறுவீர்கள்)", + "earnTicketsForRecommendingText": "விளையாட்டைப் பகிரவும்\nஇலவச டிக்கெட்டுகளுக்கு", + "emailItText": "அதை மின்னஞ்சல் செய்யவும்", + "favoritesSaveText": "பிடித்தவையாக சேமி", + "favoritesText": "பிடித்தவை", + "freeCloudServerAvailableMinutesText": "அடுத்த இலவச கிளவுட் சர்வர் ${MINUTES} நிமிடங்களில் கிடைக்கும்.", + "freeCloudServerAvailableNowText": "இலவச கிளவுட் சர்வர் கிடைக்கிறது!", + "freeCloudServerNotAvailableText": "இலவச கிளவுட் சேவையகங்கள் இல்லை.", + "friendHasSentPromoCodeText": "${NAME} இலிருந்து ${COUNT} ${APP_NAME} டிக்கெட்டுகள்", + "friendPromoCodeAwardText": "ஒவ்வொரு முறையும் நீங்கள் பயன்படுத்தும்போது ${COUNT} டிக்கெட்டுகளைப் பெறுவீர்கள்.", + "friendPromoCodeExpireText": "குறியீடு ${EXPIRE_HOURS} மணிநேரத்தில் காலாவதியாகும் மற்றும் புதிய பிளேயர்களுக்கு மட்டுமே வேலை செய்யும்.", + "friendPromoCodeInstructionsText": "இதைப் பயன்படுத்த, ${APP_NAME} ஐத் திறந்து \"அமைப்புகள்-> மேம்பட்ட-> குறியீட்டை உள்ளிடவும்\" என்பதற்குச் செல்லவும்.\nஆதரிக்கப்படும் அனைத்து தளங்களுக்கும் பதிவிறக்க இணைப்புகளுக்கு bombsquadgame.com ஐப் பார்க்கவும்.", + "friendPromoCodeRedeemLongText": "இதை ${MAX_USES} பேர் வரை ${COUNT} இலவச டிக்கெட்டுகளுக்கு மீட்டெடுக்கலாம்.", + "friendPromoCodeRedeemShortText": "விளையாட்டில் ${COUNT} டிக்கெட்டுகளுக்கு அதை மீட்டெடுக்கலாம்.", + "friendPromoCodeWhereToEnterText": "(\"அமைப்புகள்-> மேம்பட்ட-> குறியீட்டை உள்ளிடவும்\")", + "getFriendInviteCodeText": "நண்பர் அழைப்புக் குறியீட்டைப் பெறுங்கள்", + "googlePlayDescriptionText": "உங்கள் விருந்துக்கு Google Play பிளேயர்களை அழைக்கவும்:", + "googlePlayInviteText": "அழை", + "googlePlayReInviteText": "உங்கள் பார்ட்டியில் ${COUNT} Google Play பிளேயர் (கள்) உள்ளனர்\nநீங்கள் ஒரு புதிய அழைப்பைத் தொடங்கினால் யார் துண்டிக்கப்படுவார்கள்.\nஅவர்களை திரும்ப பெற புதிய அழைப்பிதழில் சேர்க்கவும்.", + "googlePlaySeeInvitesText": "அழைப்புகளைப் பார்க்கவும்", + "googlePlayText": "கூகிள் Play", + "googlePlayVersionOnlyText": "(Android / Google Play பதிப்பு)", + "hostPublicPartyDescriptionText": "ஒரு பொது பார்ட்டி நடத்துங்கள்", + "hostingUnavailableText": "ஹோஸ்டிங் கிடைக்கவில்லை", + "inDevelopmentWarningText": "குறிப்பு:\n\nநெட்வொர்க் ப்ளே ஒரு புதிய மற்றும் இன்னும் வளர்ந்து வரும் அம்சமாகும்.\nஇப்போதைக்கு, அனைவருக்கும் இது மிகவும் பரிந்துரைக்கப்படுகிறது\nபிளேயர்கள் ஒரே வைஃபை நெட்வொர்க்கில் இருக்க வேண்டும்.", + "internetText": "இணையதளம்", + "inviteAFriendText": "நண்பர்களுக்கு விளையாட்டு இல்லையா? அவர்களை அழைக்கவும்\nமுயற்சித்துப் பாருங்கள், அவர்கள் ${COUNT} இலவச டிக்கெட்டுகளைப் பெறுவார்கள்.", + "inviteFriendsText": "நண்பர்களை அழைக்க", + "joinPublicPartyDescriptionText": "பொது பார்ட்டியில் சேருங்கள்", + "localNetworkDescriptionText": "அருகிலுள்ள பார்ட்டியில் சேருங்கள் (LAN, ப்ளூடூத், முதலியன)", + "localNetworkText": "உள்ளூர் நெட்வொர்க்", + "makePartyPrivateText": "எனது பார்ட்டியை தனிப்பட்டதாக்குங்கள்", + "makePartyPublicText": "எனது பார்ட்டியை பகிரங்கப்படுத்துங்கள்", + "manualAddressText": "முகவரி", + "manualConnectText": "இணை", + "manualDescriptionText": "முகவரி மூலம் ஒரு பார்ட்டியில் சேருங்கள்:", + "manualJoinSectionText": "முகவரி மூலம் சேருங்கள்", + "manualJoinableFromInternetText": "நீங்கள் இணையத்தில் சேர முடியுமா?", + "manualJoinableNoWithAsteriskText": "இல்லை*", + "manualJoinableYesText": "ஆம்", + "manualRouterForwardingText": "*இதைச் சரிசெய்ய, உங்கள் உள்ளூர் முகவரிக்கு UDP போர்ட் ${PORT} ஐ அனுப்ப உங்கள் திசைவியை உள்ளமைக்க முயற்சிக்கவும்", + "manualText": "கையேடு", + "manualYourAddressFromInternetText": "இணையத்திலிருந்து உங்கள் முகவரி:", + "manualYourLocalAddressText": "உங்கள் உள்ளூர் முகவரி:", + "nearbyText": "அருகில்", + "noConnectionText": "<இணைப்பு இல்லை>", + "otherVersionsText": "(பிற பதிப்புகள்)", + "partyCodeText": "பார்ட்டி குறியீடு", + "partyInviteAcceptText": "ஏற்றுக்கொள்", + "partyInviteDeclineText": "மறு", + "partyInviteGooglePlayExtraText": "('கூடி' சாளரத்தில் 'Google Play' தாவலைப் பார்க்கவும்)", + "partyInviteIgnoreText": "புறக்கணிக்கவும்", + "partyInviteText": "${NAME} அழைத்துள்ளார்\nநீங்கள் அவர்களின் பார்ட்டியில் சேர!", + "partyNameText": "பார்ட்டி பெயர்", + "partyServerRunningText": "உங்கள் பார்ட்டி சர்வர் இயங்குகிறது.", + "partySizeText": "பார்ட்டி அளவு", + "partyStatusCheckingText": "நிலையை சரிபார்க்கிறது...", + "partyStatusJoinableText": "உங்கள் பார்ட்டி இப்போது இணையத்தில் சேரக்கூடியது", + "partyStatusNoConnectionText": "சேவையகத்துடன் இணைக்க முடியவில்லை", + "partyStatusNotJoinableText": "உங்கள் பார்ட்டி இணையத்தில் சேர முடியாது", + "partyStatusNotPublicText": "உங்கள் பார்ட்டி பொது அல்ல", + "pingText": "பிங்", + "portText": "போர்ட்", + "privatePartyCloudDescriptionText": "தனிப்பட்ட பார்ட்டிகள் பிரத்யேக கிளவுட் சேவையகங்களில் இயங்குகின்றன; திசைவி கட்டமைப்பு தேவையில்லை.", + "privatePartyHostText": "ஒரு தனியார் பார்ட்டி நடத்துங்கள்", + "privatePartyJoinText": "ஒரு தனியார் பார்ட்டியில் சேருங்கள்", + "privateText": "தனியார்", + "publicHostRouterConfigText": "இதற்கு உங்கள் ரூட்டரில் போர்ட்-ஃபார்வர்டிங் கட்டமைக்க வேண்டும். எளிதான விருப்பத்திற்கு, ஒரு தனியார் பார்ட்டி நடத்துங்கள்.", + "publicText": "பொது", + "requestingAPromoCodeText": "குறியீட்டைக் கோருகிறது...", + "sendDirectInvitesText": "நேரடி அழைப்புகளை அனுப்பவும்", + "shareThisCodeWithFriendsText": "இந்த குறியீட்டை நண்பர்களுடன் பகிர்ந்து கொள்ளுங்கள்:", + "showMyAddressText": "என் முகவரியை காட்டு", + "startHostingPaidText": "இப்போது ${COST} க்கு ஹோஸ்ட் செய்யுங்கள்", + "startHostingText": "ஹோஸ்ட்", + "startStopHostingMinutesText": "அடுத்த ${MINUTES} நிமிடங்களுக்கு நீங்கள் இலவசமாக ஹோஸ்டிங்கை ஆரம்பித்து நிறுத்தலாம்.", + "stopHostingText": "ஹோஸ்டிங்கை நிறுத்து", + "titleText": "சேகரிக்கவும்", + "wifiDirectDescriptionBottomText": "எல்லா சாதனங்களிலும் 'வைஃபை டைரக்ட்' பேனல் இருந்தால், அவற்றைக் கண்டுபிடிக்க அவற்றைப் பயன்படுத்த முடியும்\nமற்றும் ஒருவருக்கொருவர் இணைக்கவும். எல்லா சாதனங்களும் இணைக்கப்பட்டவுடன், நீங்கள் கட்சிகளை உருவாக்கலாம்\nஇங்கே 'உள்ளூர் நெட்வொர்க்' தாவலைப் பயன்படுத்தி, வழக்கமான Wi-Fi நெட்வொர்க்கைப் போலவே.\n\nசிறந்த முடிவுகளுக்கு, வைஃபை டைரக்ட் ஹோஸ்ட் ${APP_NAME} பார்ட்டி ஹோஸ்டாகவும் இருக்க வேண்டும்.", + "wifiDirectDescriptionTopText": "ஆண்ட்ராய்டு சாதனங்களை நேரடியாக இல்லாமல் இணைக்க வைஃபை டைரக்ட் பயன்படுத்தலாம்\nவைஃபை நெட்வொர்க் தேவை. இது Android 4.2 அல்லது புதியவற்றில் சிறப்பாகச் செயல்படும்.\n\nஇதைப் பயன்படுத்த, வைஃபை அமைப்புகளைத் திறந்து மெனுவில் 'வைஃபை டைரக்ட்' ஐப் பார்க்கவும்.", + "wifiDirectOpenWiFiSettingsText": "வைஃபை அமைப்புகளைத் திறக்கவும்", + "wifiDirectText": "வைஃபை நேரடி", + "worksBetweenAllPlatformsText": "(அனைத்து தளங்களுக்கும் இடையில் வேலை செய்கிறது)", + "worksWithGooglePlayDevicesText": "(விளையாட்டின் கூகிள் பிளே (ஆண்ட்ராய்டு) பதிப்பில் இயங்கும் சாதனங்களுடன் வேலை செய்கிறது)", + "youHaveBeenSentAPromoCodeText": "உங்களுக்கு ${APP_NAME} விளம்பர குறியீடு அனுப்பப்பட்டுள்ளது:" + }, + "getTicketsWindow": { + "freeText": "இலவசம்!", + "freeTicketsText": "இலவச டிக்கெட்டுகள்", + "inProgressText": "ஒரு பரிவர்த்தனை நடந்து கொண்டிருக்கிறது; சிறிது நேரத்தில் மீண்டும் முயற்சிக்கவும்.", + "purchasesRestoredText": "கொள்முதல் மீட்டெடுக்கப்பட்டது.", + "receivedTicketsText": "${COUNT} டிக்கெட்டுகள் பெறப்பட்டன!", + "restorePurchasesText": "கொள்முதலை திரும்பப்பெறு", + "ticketPack1Text": "சிறிய டிக்கெட் பேக்", + "ticketPack2Text": "நடுத்தர டிக்கெட் பேக்", + "ticketPack3Text": "பெரிய டிக்கெட் பேக்", + "ticketPack4Text": "ஜம்போ டிக்கெட் பேக்", + "ticketPack5Text": "மம்மத் டிக்கெட் பேக்", + "ticketPack6Text": "அல்டிமேட் டிக்கெட் பேக்", + "ticketsFromASponsorText": "ஒரு விளம்பரத்தைப் பார்த்து\n${COUNT} டிக்கெட்டுகளை பெறுங்கள்", + "ticketsText": "${COUNT} டிக்கெட்டுகள்", + "titleText": "டிக்கெட்டுகளைப் பெறுங்கள்", + "unavailableLinkAccountText": "மன்னிக்கவும், இந்த தளத்தில் கொள்முதல் கிடைக்கவில்லை.\nஒரு தீர்வாக, இந்தக் கணக்கை ஒரு கணக்குடன் இணைக்கலாம்\nமற்றொரு தளம் மற்றும் அங்கு கொள்முதல் செய்யுங்கள்.", + "unavailableTemporarilyText": "இது தற்போது கிடைக்கவில்லை; தயவுசெய்து பிறகு முயற்சிக்கவும்.", + "unavailableText": "மன்னிக்கவும், இது கிடைக்கவில்லை.", + "versionTooOldText": "மன்னிக்கவும், விளையாட்டின் இந்தப் பதிப்பு மிகவும் பழையது; தயவுசெய்து புதிய ஒன்றை புதுப்பிக்கவும்.", + "youHaveShortText": "உங்களிடம் ${COUNT} உள்ளது", + "youHaveText": "உங்களிடம் ${COUNT} டிக்கெட்டுகள் உள்ளன" + }, + "googleMultiplayerDiscontinuedText": "மன்னிக்கவும், கூகுளின் மல்டிபிளேயர் சேவை இனி கிடைக்காது.\nநான் முடிந்தவரை விரைவாக மாற்றுவதற்கு வேலை செய்கிறேன்.\nஅதுவரை, வேறு இணைப்பு முறையை முயற்சிக்கவும்.\n-எரிக்", + "googlePlayPurchasesNotAvailableText": "Google Play வாங்குதல்கள் கிடைக்கவில்லை.\nஉங்கள் ஸ்டோர் பயன்பாட்டைப் புதுப்பிக்க வேண்டியிருக்கலாம்.", + "googlePlayServicesNotAvailableText": "Google Play சேவைகள் கிடைக்கவில்லை.\nசில ஆப்ஸ் செயல்பாடுகள் முடக்கப்பட்டிருக்கலாம்.", + "googlePlayText": "கூகுள் பிளே", + "graphicsSettingsWindow": { + "alwaysText": "எப்போதும்", + "fullScreenCmdText": "முழுத்திரை (Cmd-F)", + "fullScreenCtrlText": "முழுத்திரை (Ctrl-F)", + "gammaText": "காமா", + "highText": "உயர்", + "higherText": "அதிக", + "lowText": "குறைந்த", + "mediumText": "நடுத்தர", + "neverText": "ஒருபோதும்", + "resolutionText": "பகுத்தல்", + "showFPSText": "FPS ஐக் காட்டு", + "texturesText": "இழைமங்கள்", + "titleText": "கிராபிக்ஸ்", + "tvBorderText": "டிவி பார்டர்", + "verticalSyncText": "செங்குத்தான ஒத்திசை", + "visualsText": "காட்சிகள்" + }, + "helpWindow": { + "bombInfoText": "- வெடிகுண்டு -\nகுத்துக்களை விட வலிமையானது, ஆனால்\nகடுமையான சுய காயம் ஏற்படலாம்.\nசிறந்த முடிவுகளுக்கு, நோக்கி எறியுங்கள்\nஉருகி முடிவதற்குள் எதிரி.", + "bombInfoTextScale": 0.6, + "canHelpText": "${APP_NAME} உதவலாம்.", + "controllersInfoText": "நெட்வொர்க் அல்லது நண்பர்களுடன் நீங்கள் ${APP_NAME} ஐ விளையாடலாம்\nஉங்களிடம் போதுமான கட்டுப்பாட்டாளர்கள் இருந்தால் அனைவரும் ஒரே சாதனத்தில் விளையாடலாம்.\n${APP_NAME} பல்வேறு வகைகளை ஆதரிக்கிறது; நீங்கள் தொலைபேசிகளைப் பயன்படுத்தலாம்\nஇலவச '${REMOTE_APP_NAME}' பயன்பாட்டின் மூலம் கட்டுப்படுத்திகளாக.\nமேலும் தகவலுக்கு அமைப்புகள்-> கட்டுப்பாட்டாளர்கள் பார்க்கவும்.", + "controllersInfoTextRemoteOnly": "நெட்வொர்க் அல்லது நண்பர்களுடன் நீங்கள் ${APP_NAME} ஐ விளையாடலாம்\nபோன்களை பயன்படுத்தி அனைவரும் ஒரே சாதனத்தில் விளையாடலாம்\nஇலவச '${REMOTE_APP_NAME}' பயன்பாட்டின் மூலம் கட்டுப்படுத்திகள்.", + "controllersText": "கட்டுப்பாட்டாளர்கள்", + "controlsSubtitleText": "உங்கள் நட்பான ${APP_NAME} எழுத்து சில அடிப்படை செயல்களைக் கொண்டுள்ளது:", + "controlsText": "கட்டுப்பாடுகள்", + "devicesInfoText": "நெட்வொர்க்கில் ${APP_NAME} இன் VR பதிப்பை இயக்கலாம்\nவழக்கமான பதிப்பு, எனவே உங்கள் கூடுதல் தொலைபேசிகள், மாத்திரைகள்,\nமற்றும் கணினிகள் மற்றும் உங்கள் விளையாட்டு கிடைக்கும். இது கூட பயனுள்ளதாக இருக்கும்\nவிளையாட்டின் வழக்கமான பதிப்பை விஆர் பதிப்போடு இணைக்கவும்\nவெளியில் உள்ளவர்களை செயலைப் பார்க்க அனுமதிக்கவும்.", + "devicesText": "சாதனங்கள்", + "friendsGoodText": "இவை இருப்பது நல்லது. ${APP_NAME} பலவற்றில் மிகவும் வேடிக்கையாக உள்ளது\nவீரர்கள் மற்றும் ஒரே நேரத்தில் 8 வரை ஆதரிக்க முடியும், இது எங்களை இட்டுச் செல்கிறது:", + "friendsText": "நண்பர்கள்", + "jumpInfoText": "- தாவு -\nசிறிய இடைவெளிகளைக் கடக்கச் செல்லவும்,\nபொருள்களை மேலே தூக்கி எறிய, மற்றும்\nமகிழ்ச்சியின் உணர்வுகளை வெளிப்படுத்த.", + "orPunchingSomethingText": "அல்லது எதையாவது குத்துவது, ஒரு குன்றிலிருந்து தூக்கி எறிவது, மற்றும் ஒட்டும் குண்டு மூலம் கீழே செல்லும் வழியில் அதை ஊதுவது.", + "pickUpInfoText": "- எடு -\nகொடிகள், எதிரிகள் அல்லது எதையும் பிடிக்கவும்\nமற்றபடி தரையில் ஒட்டப்படவில்லை.\nவீசுவதற்கு மீண்டும் அழுத்தவும்.", + "powerupBombDescriptionText": "நீங்கள் மூன்று குண்டுகளை வெளியேற்றலாம்\nஒன்றுக்கு பதிலாக ஒரு வரிசையில்.", + "powerupBombNameText": "மூன்று-குண்டுகள்", + "powerupCurseDescriptionText": "ஒருவேளை நீங்கள் இவற்றைத் தவிர்க்க விரும்புகிறீர்கள்.\n... அல்லது நீங்கள்?", + "powerupCurseNameText": "சாபம்", + "powerupHealthDescriptionText": "உங்களை முழு உயிர் மீட்டெடுக்கிறது.\nநீங்கள் ஒருபோதும் யூகித்திருக்க மாட்டீர்கள்.", + "powerupHealthNameText": "மெட்-பேக்", + "powerupIceBombsDescriptionText": "சாதாரண குண்டுகளை விட பலவீனமானது\nஆனால் உங்கள் எதிரிகளை உறைய விடவும்\nமற்றும் குறிப்பாக உடையக்கூடியது.", + "powerupIceBombsNameText": "பனி-குண்டுகள்", + "powerupImpactBombsDescriptionText": "வழக்கமானதை விட சற்று பலவீனமானது\nகுண்டுகள், ஆனால் அவை தாக்கத்தில் வெடிக்கின்றன.", + "powerupImpactBombsNameText": "தூண்டுதல்-குண்டுகள்", + "powerupLandMinesDescriptionText": "இவை 3 பொதிகளில் வருகின்றன;\nஅடிப்படை பாதுகாப்புக்கு அல்லது\nவிரைவான எதிரிகளை நிறுத்துதல்.", + "powerupLandMinesNameText": "நில-குண்டு", + "powerupPunchDescriptionText": "உங்கள் குத்துக்களை கடினமாக்குகிறது,\nவேகமான, சிறந்த, வலுவான.", + "powerupPunchNameText": "குத்துச்சண்டை-கையுறைகள்", + "powerupShieldDescriptionText": "சிறிது சேதத்தை உறிஞ்சுகிறது\nஎனவே நீங்கள் செய்ய வேண்டியதில்லை.", + "powerupShieldNameText": "ஆற்றல்-கவசம்", + "powerupStickyBombsDescriptionText": "அவர்கள் அடிக்கும் எதையும் ஒட்டிக்கொள்க.\nபெருங்களிப்பு ஏற்படுகிறது.", + "powerupStickyBombsNameText": "ஒட்டும்-குண்டுகள்", + "powerupsSubtitleText": "நிச்சயமாக, பவர்அப் இல்லாமல் எந்த விளையாட்டும் முழுமையடையாது:", + "powerupsText": "பவர்அப்ஸ்", + "punchInfoText": "- பஞ்ச் -\nகுத்துக்கள் அதிக சேதத்தை ஏற்படுத்துகின்றன\nஉங்கள் முஷ்டிகள் வேகமாக நகர்கின்றன, எனவே\nஒரு பைத்தியக்காரனைப் போல ஓடி சுழலும்.", + "runInfoText": "- ஓடு -\nஇயக்க எந்த பொத்தானையும் அழுத்தவும். தூண்டுதல்கள் அல்லது தோள்பட்டை பட்டன்கள் உங்களிடம் இருந்தால் நன்றாக வேலை செய்யும்.\nஓடுவது உங்கள் இடங்களை வேகமாகப் பெறுகிறது, ஆனால் திரும்புவதை கடினமாக்குகிறது, எனவே பாறைகளைக் கவனியுங்கள்.", + "someDaysText": "சில நாட்களில் நீங்கள் ஏதாவது குத்துவது போல் உணர்கிறீர்கள். அல்லது எதையாவது ஊதுவது.", + "titleText": "${APP_NAME} உதவி", + "toGetTheMostText": "இந்த விளையாட்டை அதிகம் பயன்படுத்த, உங்களுக்கு இது தேவைப்படும்:", + "welcomeText": "${APP_NAME} க்கு வரவேற்கிறோம்!" + }, + "holdAnyButtonText": "<எந்த பட்டனையும் பிடி>", + "holdAnyKeyText": "<எந்த விசையையும் பிடி>", + "hostIsNavigatingMenusText": "- ${HOST} மெனுக்களை ஒரு முதலாளியைப் போல வழிநடத்துகிறது -", + "importPlaylistCodeInstructionsText": "இந்த பிளேலிஸ்ட்டை வேறு இடத்தில் இறக்குமதி செய்ய பின்வரும் குறியீட்டைப் பயன்படுத்தவும்:", + "importPlaylistSuccessText": "இறக்குமதி செய்யப்பட்ட ${TYPE} பிளேலிஸ்ட் '${NAME}'", + "importText": "இறக்குமதி", + "importingText": "இறக்குமதி செய்கிறது...", + "inGameClippedNameText": "விளையாட்டில் இருக்கும்\n\"${NAME}\"", + "installDiskSpaceErrorText": "பிழை: நிறுவலை முடிக்க முடியவில்லை.\nஉங்கள் சாதனத்தில் இடம் இல்லாமல் இருக்கலாம்.\nசிறிது இடத்தை அழித்துவிட்டு மீண்டும் முயற்சிக்கவும்.", + "internal": { + "arrowsToExitListText": "பட்டியலில் இருந்து வெளியேற ${LEFT} அல்லது ${RIGHT} ஐ அழுத்தவும்", + "buttonText": "பட்டன்", + "cantKickHostError": "நீங்கள் ஹோஸ்டை வெளியேற முடியாது.", + "chatBlockedText": "${NAME} ${TIME} வினாடிகளுக்கு அரட்டை-தடுக்கப்பட்டது.", + "connectedToGameText": "${NAME} இல் சேர்ந்தது", + "connectedToPartyText": "${NAME} இன் பார்ட்டியில் சேர்ந்தது", + "connectingToPartyText": "இணைக்கிறது...", + "connectionFailedHostAlreadyInPartyText": "இணைப்பு தோல்வியடைந்தது; ஹோஸ்ட் மற்றொரு பார்ட்டியில் இருக்கிறார்.", + "connectionFailedPartyFullText": "இணைப்பு தோல்வியடைந்தது; பார்ட்டி நிரம்பியுள்ளது.", + "connectionFailedText": "இணைப்பு தோல்வியடைந்தது", + "connectionFailedVersionMismatchText": "இணைப்பு தோல்வியடைந்தது; ஹோஸ்ட் விளையாட்டின் வேறுபட்ட பதிப்பை இயக்குகிறார்.\nநீங்கள் இருவரும் புதுப்பித்த நிலையில் இருப்பதை உறுதிசெய்து மீண்டும் முயற்சிக்கவும்.", + "connectionRejectedText": "இணைப்பு நிராகரிக்கப்பட்டது.", + "controllerConnectedText": "${CONTROLLER} இணைக்கப்பட்டுள்ளது.", + "controllerDetectedText": "1 controller detected.", + "controllerDisconnectedText": "${CONTROLLER} துண்டிக்கப்பட்டது.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} துண்டிக்கப்பட்டது. மீண்டும் இணைக்க முயற்சிக்கவும்.", + "controllerForMenusOnlyText": "இந்த கட்டுப்படுத்தியை விளையாட பயன்படுத்த முடியாது; மெனுக்களில் செல்லவும்.", + "controllerReconnectedText": "${CONTROLLER} மீண்டும் இணைக்கப்பட்டது.", + "controllersConnectedText": "${COUNT} கட்டுப்படுத்திகள் இணைக்கப்பட்டுள்ளன.", + "controllersDetectedText": "${COUNT} கட்டுப்படுத்திகள் கண்டறியப்பட்டன.", + "controllersDisconnectedText": "${COUNT} கட்டுப்படுத்திகள் துண்டிக்கப்பட்டன.", + "corruptFileText": "ஊழல் கோப்பு (கள்) கண்டறியப்பட்டது. மீண்டும் நிறுவ முயற்சிக்கவும் அல்லது மின்னஞ்சல் ${EMAIL}", + "errorPlayingMusicText": "இசையை இயக்குவதில் பிழை: ${MUSIC}", + "errorResettingAchievementsText": "ஆன்லைன் சாதனைகளை மீட்டமைக்க முடியவில்லை; தயவுசெய்து பிறகு முயற்சிக்கவும்.", + "hasMenuControlText": "${NAME} மெனு கட்டுப்பாட்டைக் கொண்டுள்ளது.", + "incompatibleNewerVersionHostText": "ஹோஸ்ட் விளையாட்டின் புதிய பதிப்பை இயக்குகிறது.\nசமீபத்திய பதிப்பைப் புதுப்பித்து மீண்டும் முயற்சிக்கவும்.", + "incompatibleVersionHostText": "ஹோஸ்ட் விளையாட்டின் வேறுபட்ட பதிப்பை இயக்குகிறார்.\nநீங்கள் இருவரும் புதுப்பித்த நிலையில் இருப்பதை உறுதிசெய்து மீண்டும் முயற்சிக்கவும்.", + "incompatibleVersionPlayerText": "${NAME} விளையாட்டின் வேறு பதிப்பை இயக்குகிறார்.\nநீங்கள் இருவரும் புதுப்பித்த நிலையில் இருப்பதை உறுதிசெய்து மீண்டும் முயற்சிக்கவும்.", + "invalidAddressErrorText": "பிழை: தவறான முகவரி.", + "invalidNameErrorText": "பிழை: தவறான பெயர்.", + "invalidPortErrorText": "பிழை: தவறான போர்ட்.", + "invitationSentText": "அழைப்பு அனுப்பப்பட்டது.", + "invitationsSentText": "${COUNT} அழைப்புகள் அனுப்பப்பட்டன.", + "joinedPartyInstructionsText": "உங்கள் கட்சியில் ஒருவர் சேர்ந்துள்ளார்.\nவிளையாட்டைத் தொடங்க 'விளையாடு' என்பதற்குச் செல்லவும்.", + "keyboardText": "எழுத்துப்பலகை", + "kickIdlePlayersKickedText": "சும்மா இருப்பதற்காக ${NAME} ஐ வெளியேற்றப்பட்டது", + "kickIdlePlayersWarning1Text": "${NAME} சும்மா இருந்தால் ${COUNT} வினாடிகளில் வெளியேற்றப்படும்.", + "kickIdlePlayersWarning2Text": "(நீங்கள் இதை அமைப்புகள் -> மேம்பட்ட முறையில் அணைக்கலாம்)", + "leftGameText": "'${NAME}' வெளியேற பட்டது", + "leftPartyText": "${NAME} இன் பார்ட்டியை வெளியே விட்டு வந்தது.", + "noMusicFilesInFolderText": "போல்டரில் இசை இடம் இல்லை.", + "playerJoinedPartyText": "${NAME} பார்ட்டியில் சேர்ந்தார்!", + "playerLeftPartyText": "${NAME} பார்ட்டியில் விட்டு வெளியேறினார்.", + "rejectingInviteAlreadyInPartyText": "அழைப்பை நிராகரித்தல் (ஏற்கனவே ஒரு பார்ட்டியில் இருக்கிறீர்கள்).", + "serverRestartingText": "சர்வர் மறுதொடக்கம் செய்கிறது. தயவுசெய்து சிறிது நேரத்தில் மீண்டும் சேருங்கள்...", + "serverShuttingDownText": "சர்வர் முடக்கப்படுகிறது...", + "signInErrorText": "உள்நுழைவதில் பிழை.", + "signInNoConnectionText": "உள்நுழைய முடியவில்லை. (இணைய இணைப்பு இல்லையா?)", + "telnetAccessDeniedText": "பிழை: பயனர் டெல்நெட் அணுகலை வழங்கவில்லை.", + "timeOutText": "(${TIME} வினாடிகளில் வெளியேறும்)", + "touchScreenJoinWarningText": "நீங்கள் தொடுதிரையுடன் இணைந்துள்ளீர்கள்.\nஇது தவறு என்றால், அதனுடன் 'மெனு-> விளையாட்டிலிருந்து வெளியேறு' என்பதைத் தட்டவும்.", + "touchScreenText": "தொடு திரை", + "unableToResolveHostText": "பிழை: ஹோஸ்டை தீர்க்க முடியவில்லை.", + "unavailableNoConnectionText": "இது தற்போது கிடைக்கவில்லை (இணைய இணைப்பு இல்லையா?)", + "vrOrientationResetCardboardText": "VR நோக்குநிலையை மீட்டமைக்க இதைப் பயன்படுத்தவும்.\nவிளையாட்டை விளையாட உங்களுக்கு ஒரு வெளிப்புற கட்டுப்படுத்தி தேவை.", + "vrOrientationResetText": "VR நோக்குநிலை மீட்டமைப்பு.", + "willTimeOutText": "(சும்மா இருந்தால் நேரம் ஆகிவிடும்)" + }, + "jumpBoldText": "குதி", + "jumpText": "குதி", + "keepText": "வை", + "keepTheseSettingsText": "இந்த அமைப்புகளை வைத்திருக்கவா?", + "keyboardChangeInstructionsText": "விசைப்பலகைகளை மாற்ற இடத்தை இருமுறை அழுத்தவும்.", + "keyboardNoOthersAvailableText": "மற்ற விசைப்பலகைகள் இல்லை.", + "keyboardSwitchText": "விசைப்பலகையை \"${NAME}\" க்கு மாற்றுகிறது.", + "kickOccurredText": "${NAME} வெளியேற்றப்பட்டார்.", + "kickQuestionText": "${NAME} ஐ வெளியேற்றவா?", + "kickText": "அகற்று", + "kickVoteCantKickAdminsText": "நிர்வாகிகளை நீக்க முடியாது.", + "kickVoteCantKickSelfText": "உங்களை அகற்று முடியாது.", + "kickVoteFailedNotEnoughVotersText": "ஓட்டுக்கு போதுமான வீரர்கள் இல்லை.", + "kickVoteFailedText": "கிக்-ஓட்டு தோல்வியடைந்தது.", + "kickVoteStartedText": "${NAME} க்கு ஒரு கிக் வாக்களிப்பு தொடங்கப்பட்டது.", + "kickVoteText": "கிக் செய்ய வாக்களியுங்கள்", + "kickVotingDisabledText": "கிக் வாக்களிப்பு முடக்கப்பட்டுள்ளது.", + "kickWithChatText": "அரட்டையில் ஆம் என்று ${YES} என்றும் இல்லை என்பதற்கு ${NO} என்றும் தட்டச்சு செய்யவும்.", + "killsTallyText": "${COUNT} கொலைகள்", + "killsText": "கொலை", + "kioskWindow": { + "easyText": "சுலபம்", + "epicModeText": "காவிய முறை", + "fullMenuText": "முழு மெனு", + "hardText": "கடினமான", + "mediumText": "நடுத்தரமான", + "singlePlayerExamplesText": "ஒற்றை வீரர் / கூட்டுறவு உதாரணங்கள்", + "versusExamplesText": "வெர்சஸ் உதாரணங்கள்" + }, + "languageSetText": "மொழி இப்போது \"${LANGUAGE}\" இல் இருக்கிறது.", + "lapNumberText": "சுற்று ${CURRENT}/${TOTAL}", + "lastGamesText": "(கடைசி ${COUNT} விளையாட்டுகள்)", + "leaderboardsText": "லீடர்போர்டுகள்", + "league": { + "allTimeText": "எல்லா நேரமும்", + "currentSeasonText": "தற்போதைய பருவம் (${NUMBER})", + "leagueFullText": "${NAME} லீக்", + "leagueRankText": "லீக் ரேங்க்", + "leagueText": "லீக்", + "rankInLeagueText": "#${RANK}, ${NAME} லீக் ${SUFFIX}", + "seasonEndedDaysAgoText": "சீசன் ${NUMBER} நாட்களுக்கு முன்பு முடிந்தது.", + "seasonEndsDaysText": "சீசன் ${NUMBER} நாட்களில் முடிவடைகிறது.", + "seasonEndsHoursText": "சீசன் ${NUMBER} மணிநேரத்தில் முடிவடைகிறது.", + "seasonEndsMinutesText": "சீசன் ${NUMBER} நிமிடங்களில் முடிவடைகிறது.", + "seasonText": "சீசன் ${NUMBER}", + "tournamentLeagueText": "இந்த போட்டியில் நுழைய நீங்கள் ${NAME} லீக்கை அடைய வேண்டும்.", + "trophyCountsResetText": "அடுத்த சீசனில் கோப்பைகளின் எண்ணிக்கை மீட்டமைக்கப்படும்." + }, + "levelBestScoresText": "${LEVEL} இல் சிறந்த மதிப்பெண்கள்", + "levelBestTimesText": "${LEVEL} இல் சிறந்த நேரங்கள்", + "levelIsLockedText": "${LEVEL} லாக் செய்யப்பட்டது.", + "levelMustBeCompletedFirstText": "${LEVEL} முதலில் முடிக்கப்பட வேண்டும்.", + "levelText": "நிலை ${NUMBER}", + "levelUnlockedText": "நிலை திறக்கப்பட்டது!", + "livesBonusText": "லைவ் போனஸ்", + "loadingText": "ஏற்றுகிறது", + "loadingTryAgainText": "ஏற்றுகிறது; சிறிது நேரத்தில் மீண்டும் முயற்சி செய்...", + "macControllerSubsystemBothText": "இரண்டும் (பரிந்துரைக்கப்படவில்லை)", + "macControllerSubsystemClassicText": "தரமான", + "macControllerSubsystemDescriptionText": "(உங்கள் கட்டுப்படுத்திகள் வேலை செய்யவில்லை என்றால் இதை மாற்ற முயற்சிக்கவும்)", + "macControllerSubsystemMFiNoteText": "மேட்-ஃபார்-iOS/Mac கன்ட்ரோலர் கண்டறியப்பட்டது;\nநீங்கள் அமைப்புகள் -> கட்டுப்படுத்திகளில் இதைச் செயல்படுத்த விரும்பலாம்", + "macControllerSubsystemMFiText": "மேட்-ஃபார்-iOS/Mac", + "macControllerSubsystemTitleText": "கட்டுப்படுத்தி ஆதரவு", + "mainMenu": { + "creditsText": "வரவுகள்", + "demoMenuText": "டெமோ மெனு", + "endGameText": "விளையாட்டை வெளியேறு", + "endTestText": "முடிவு சோதனை", + "exitGameText": "விளையாட்டை வெளியேறு", + "exitToMenuText": "மெனுவிலிருந்து வெளியேறவா?", + "howToPlayText": "எப்படி விளையாடுவது", + "justPlayerText": "(வெறும் ${NAME})", + "leaveGameText": "விளையாட்டில் வெளியேறு", + "leavePartyConfirmText": "உண்மையிலேயே பார்ட்டியை விட்டு வெளியேறலாமா?", + "leavePartyText": "பார்ட்டியிலிருந்து வெளியேறு", + "quitText": "வெளியேறு", + "resumeText": "தொடரு", + "settingsText": "அமைப்புகள்" + }, + "makeItSoText": "அவ்வாரே செய்", + "mapSelectGetMoreMapsText": "மேலும் வரைபடங்களைப் பெறுங்கள்...", + "mapSelectText": "தேர்ந்தெடுக்கவும்...", + "mapSelectTitleText": "${GAME} வரைபடங்கள்", + "mapText": "வரைபடம்", + "maxConnectionsText": "அதிகபட்ச இணைப்புகள்", + "maxPartySizeText": "அதிகபட்ச பார்ட்டி அளவு", + "maxPlayersText": "அதிகபட்ச வீரர்கள்", + "merchText": "பொருட்கள்!", + "modeArcadeText": "ஆர்கேட் முறை", + "modeClassicText": "கிளாசிக் பயன்முறை", + "modeDemoText": "Demo Mode", + "mostValuablePlayerText": "மிகவும் மதிப்புமிக்க வீரர்", + "mostViolatedPlayerText": "மிகவும் மீறப்பட்ட வீரர்", + "mostViolentPlayerText": "மிகவும் வன்முறை வீரர்", + "moveText": "நகர்வு", + "multiKillText": "${COUNT}-கோலை!!!", + "multiPlayerCountText": "${COUNT} வீரர்கள்", + "mustInviteFriendsText": "குறிப்பு: நீங்கள் நண்பர்களை உள்ளே அழைக்க வேண்டும்\n\"${GATHER}\" பேனல் அல்லது இணைக்கவும்\nமல்டிபிளேயர் விளையாட கட்டுப்படுத்தி.", + "nameBetrayedText": "${NAME} ${VICTIM} ஐ துரோகம் செய்தார்.", + "nameDiedText": "${NAME} இறந்தார்.", + "nameKilledText": "${NAME} ${VICTIM} ஐக் கொன்றார்.", + "nameNotEmptyText": "பெயர் காலியாக இருக்க முடியாது!", + "nameScoresText": "${NAME} மதிப்பெண் பெற்றார்!", + "nameSuicideKidFriendlyText": "${NAME} தற்செயலாக இறந்தார்.", + "nameSuicideText": "${NAME} தற்கொலை செய்து கொண்டார்.", + "nameText": "பெயர்", + "nativeText": "பூர்வீகம்", + "newPersonalBestText": "புதிய தனிப்பட்ட சிறந்த!", + "newTestBuildAvailableText": "ஒரு புதிய சோதனை உருவாக்கம் கிடைக்கிறது! (${VERSION} உருவாக்க ${BUILD}).\n${ADDRESS} இல் பெறுங்கள்.", + "newText": "புதிய", + "newVersionAvailableText": "${APP_NAME} இன் புதிய பதிப்பு கிடைக்கிறது! (${VERSION})", + "nextAchievementsText": "அடுத்த சாதனைகள்:", + "nextLevelText": "அடுத்த நிலை", + "noAchievementsRemainingText": "- இல்லை", + "noContinuesText": "(தொடரும் இல்லை)", + "noExternalStorageErrorText": "இந்தச் சாதனத்தில் வெளிப்புறச் சேமிப்பு இல்லை", + "noGameCircleText": "பிழை: GameCircle இல் உள்நுழையவில்லை", + "noScoresYetText": "இன்னும் மதிப்பெண்கள் இல்லை.", + "noThanksText": "இல்லை, நன்றி!", + "noTournamentsInTestBuildText": "எச்சரிக்கை: இந்த சோதனை உருவாக்கத்தில் இருந்து போட்டியின் மதிப்பெண்கள் புறக்கணிக்கப்படும்.", + "noValidMapsErrorText": "இந்த விளையாட்டு வகைக்கு சரியான வரைபடங்கள் இல்லை.", + "notEnoughPlayersRemainingText": "போதுமான வீரர்கள் மீதமில்லை; வெளியேறி ஒரு புதிய விளையாட்டைத் தொடங்கவும்.", + "notEnoughPlayersText": "இந்த விளையாட்டைத் தொடங்க குறைந்தபட்சம் ${COUNT} வீரர்கள் தேவை!", + "notNowText": "இப்போது இல்லை", + "notSignedInErrorText": "இதைச் செய்ய நீங்கள் உள்நுழைய வேண்டும்.", + "notSignedInGooglePlayErrorText": "இதைச் செய்ய நீங்கள் Google Play இல் உள்நுழைய வேண்டும்.", + "notSignedInText": "உள்நுழையவில்லை", + "notUsingAccountText": "குறிப்பு: ${SERVICE} கணக்கைப் புறக்கணித்தல்.\nநீங்கள் அதைப் பயன்படுத்த விரும்பினால், 'கணக்கு -> ${SERVICE} உடன் உள்நுழையவும்' என்பதற்குச் செல்லவும்.", + "nothingIsSelectedErrorText": "எதுவும் தேர்ந்தெடுக்கப்படவில்லை!", + "numberText": "#${NUMBER}", + "offText": "ஆஃப்", + "okText": "சரி", + "onText": "வை", + "oneMomentText": "ஒரு நிமிடம்...", + "onslaughtRespawnText": "${PLAYER} அலை ${WAVE} இல் வருவார்", + "orText": "${A} அல்லது ${B}", + "otherText": "மற்ற...", + "outOfText": "(${ALL} இல்#${RANK})", + "ownFlagAtYourBaseWarning": "உங்கள் சொந்த கொடி இருக்க வேண்டும்\nஅடிப்பதற்கு உங்கள் அடித்தளத்தில்!", + "packageModsEnabledErrorText": "உள்ளூர்-பேக்கேஜ்-மோட்கள் இயக்கப்பட்டிருக்கும் போது நெட்வொர்க்-ப்ளே அனுமதிக்கப்படாது (அமைப்புகள்-> மேம்பட்டதைப் பார்க்கவும்)", + "partyWindow": { + "chatMessageText": "அரட்டை செய்தி", + "emptyText": "உங்கள் பார்ட்டி காலியாக உள்ளது", + "hostText": "(ஹோஸ்ட்)", + "sendText": "அனுப்பு", + "titleText": "உங்கள் பார்ட்டி" + }, + "pausedByHostText": "(தொகுப்பாளரால் இடைநிறுத்தப்பட்டது)", + "perfectWaveText": "சரியான அலை!", + "pickUpText": "எடு", + "playModes": { + "coopText": "கோ-ஓப்", + "freeForAllText": "பிரீ-போர்-ஆல்", + "multiTeamText": "பல-குழு", + "singlePlayerCoopText": "ஒற்றை வீரர் / கோ-ஓப்", + "teamsText": "குழுக்கள்" + }, + "playText": "விளையாடு", + "playWindow": { + "oneToFourPlayersText": "1-4 வீரர்கள்", + "titleText": "Play", + "twoToEightPlayersText": "2-8 வீரர்கள்" + }, + "playerCountAbbreviatedText": "${COUNT}ப", + "playerDelayedJoinText": "${PLAYER} அடுத்த சுற்றின் தொடக்கத்தில் நுழைவார்.", + "playerInfoText": "Player Info", + "playerLeftText": "${PLAYER} விளையாட்டை விட்டு வெளியேறினார்.", + "playerLimitReachedText": "பிளேயர் வரம்பு ${COUNT} ஐ எட்டியது; இணைந்தவர்கள் அனுமதிக்கப்படவில்லை.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "உங்கள் கணக்கு சுயவிவரத்தை நீக்க முடியாது.", + "deleteButtonText": "அழி\nசுயவிவரம்", + "deleteConfirmText": "'${PROFILE}' ஐ நீக்கவா?", + "editButtonText": "தொகு\nசுயவிவரம்", + "explanationText": "(இந்த கணக்கிற்கான தனிப்பயன் பிளேயர் பெயர்கள் மற்றும் தோற்றங்கள்)", + "newButtonText": "புதிய\nசுயவிவரம்", + "titleText": "பிளேயர் சுயவிவரங்கள்" + }, + "playerText": "பிளேயர்", + "playlistNoValidGamesErrorText": "இந்த பிளேலிஸ்ட்டில் சரியான திறக்கப்பட்ட கேம்கள் இல்லை.", + "playlistNotFoundText": "பிளேலிஸ்ட் கிடைக்கவில்லை", + "playlistText": "பிளேலிஸ்ட்", + "playlistsText": "பிளேலிஸ்ட்கள்", + "pleaseRateText": "நீங்கள் ${APP_NAME} ஐ அனுபவிக்கிறீர்கள் என்றால், தயவுசெய்து எடுப்பதைக் கவனியுங்கள்\nதருணம் மற்றும் மதிப்பிடுதல் அல்லது விமர்சனம் எழுதுதல். இது வழங்குகிறது\nபயனுள்ள கருத்து மற்றும் எதிர்கால வளர்ச்சிக்கு உதவுகிறது.\n\nநன்றி!\n-எரிக்", + "pleaseWaitText": "தயவுசெய்து காத்திருங்கள்...", + "pluginClassLoadErrorText": "செருகுநிரல் வகுப்பை ஏற்றுவதில் பிழை '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "'${PLUGIN}' செருகுநிரலைத் தொடங்குவதில் பிழை: ${ERROR}", + "pluginsDetectedText": "புதிய செருகுநிரல்(கள்) கண்டறியப்பட்டது. அவற்றைச் செயல்படுத்த மீண்டும் தொடங்கவும் அல்லது அமைப்புகளில் உள்ளமைக்கவும்.", + "pluginsRemovedText": "${NUM} செருகுநிரல்(கள்) இனி காணப்படவில்லை.", + "pluginsText": "செருகுநிரல்கள்", + "practiceText": "பயிற்சி", + "pressAnyButtonPlayAgainText": "மீண்டும் விளையாட எந்த பட்டனையும் அழுத்தவும்...", + "pressAnyButtonText": "தொடர எந்த பட்டனையும் அழுத்தவும்...", + "pressAnyButtonToJoinText": "சேர எந்த பட்டனையும் அழுத்தவும்...", + "pressAnyKeyButtonPlayAgainText": "மீண்டும் இயக்க எந்த விசையையும்/பட்டனையும் அழுத்தவும்...", + "pressAnyKeyButtonText": "தொடர எந்த விசையையும்/பட்டனையும் அழுத்தவும்...", + "pressAnyKeyText": "எந்த விசையையும் அழுத்தவும்...", + "pressJumpToFlyText": "** பறக்க மீண்டும் குதி பட்டனை அழுத்தவும் **", + "pressPunchToJoinText": "சேர, குத்து அழுத்தவும்...", + "pressToOverrideCharacterText": "உங்கள் குணசாலி மீற ${BUTTONS} ஐ அழுத்தவும்", + "pressToSelectProfileText": "பிளேயரைத் தேர்ந்தெடுக்க ${BUTTONS} ஐ அழுத்தவும்", + "pressToSelectTeamText": "ஒரு குழுவைத் தேர்ந்தெடுக்க ${BUTTONS} ஐ அழுத்தவும்", + "promoCodeWindow": { + "codeText": "குறியீடு", + "enterText": "நுழை" + }, + "promoSubmitErrorText": "குறியீட்டைச் சமர்ப்பிப்பதில் பிழை; உங்கள் இணைய இணைப்பைச் சரிபார்க்கவும்", + "ps3ControllersWindow": { + "macInstructionsText": "உங்கள் PS3 இன் பின்புறத்தில் உள்ள சக்தியை அணைக்கவும், உறுதி செய்யவும்\nஉங்கள் மேக்கில் புளூடூத் இயக்கப்பட்டது, பின்னர் உங்கள் கட்டுப்படுத்தியை இணைக்கவும்\nஇரண்டையும் இணைக்க யூ.எஸ்.பி கேபிள் வழியாக உங்கள் மேக்கில். அப்போதிருந்து, நீங்கள்\nஉங்கள் மேக் உடன் இணைக்க கட்டுப்படுத்தியின் முகப்பு பொத்தானைப் பயன்படுத்தலாம்\nகம்பி (USB) அல்லது வயர்லெஸ் (ப்ளூடூத்) முறையில்.\n\nசில மேக்ஸில் நீங்கள் இணைக்கும் போது ஒரு கடவுக்குறியீடு கேட்கப்படும்.\nஇது நடந்தால், உதவிக்கு பின்வரும் டுடோரியல் அல்லது கூகிளைப் பார்க்கவும்.\n\n\n\n\nவயர்லெஸ் இணைக்கப்பட்ட PS3 கட்டுப்படுத்திகள் சாதனத்தில் காட்டப்பட வேண்டும்\nகணினி விருப்பத்தேர்வுகள்-> ப்ளூடூத். நீங்கள் அவற்றை அகற்ற வேண்டியிருக்கலாம்\nஉங்கள் PS3 உடன் அவற்றை மீண்டும் பயன்படுத்த விரும்பும் போது அந்தப் பட்டியலில் இருந்து.\n\nப்ளூடூத் இல்லாத போது அவற்றைத் துண்டிக்க வேண்டும்\nபயன்பாடு அல்லது அவற்றின் பேட்டரிகள் தொடர்ந்து வெளியேறும்.\n\nபுளூடூத் 7 இணைக்கப்பட்ட சாதனங்களை கையாள வேண்டும்,\nஇருந்தாலும் உங்கள் மைலேஜ் மாறுபடலாம்.", + "macInstructionsTextScale": 0.74, + "ouyaInstructionsText": "உங்கள் OUYA உடன் PS3 கட்டுப்படுத்தியைப் பயன்படுத்த, அதை USB கேபிள் மூலம் இணைக்கவும்\nஒரு முறை அதை இணைக்க. இதைச் செய்வது உங்கள் மற்ற கட்டுப்படுத்திகளைத் துண்டிக்கக்கூடும்\nநீங்கள் உங்கள் OUYA ஐ மறுதொடக்கம் செய்து USB கேபிளை அகற்ற வேண்டும்.\n\nஅப்போதிலிருந்து நீங்கள் கட்டுப்படுத்தியின் வீட்டு பொத்தானைப் பயன்படுத்த முடியும்\nஅதை கம்பியில்லாமல் இணைக்கவும். நீங்கள் விளையாடி முடித்ததும், வீட்டு பொத்தானை அழுத்திப் பிடிக்கவும்\nகட்டுப்படுத்தியை அணைக்க 10 விநாடிகள்; இல்லையெனில் அது தொடர்ந்து இருக்கலாம்\nமற்றும் கழிவு பேட்டரிகள்.", + "ouyaInstructionsTextScale": 0.74, + "pairingTutorialText": "இணைத்தல் பயிற்சி வீடியோ", + "titleText": "${APP_NAME} உடன் PS3 கட்டுப்படுத்திகளைப் பயன்படுத்துதல்:" + }, + "punchBoldText": "குத்து", + "punchText": "குத்து", + "purchaseForText": "${PRICE} க்கு வாங்கு", + "purchaseGameText": "வாங்கு விளையாட்டு", + "purchasingText": "வாங்குகிறது...", + "quitGameText": "${APP_NAME} ஐ விட்டு வெளியேறவா?", + "quittingIn5SecondsText": "5 வினாடிகளில் வெளியேறும்...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "சீரற்ற", + "rankText": "ரேங்க்", + "ratingText": "மதிப்பீடு", + "reachWave2Text": "ரேங்க் செய்ய அலை 2 ஐ அடையுங்கள்.", + "readyText": "தயார்", + "recentText": "சமீபத்திய", + "remoteAppInfoShortText": "குடும்பம் & நண்பர்களுடன் விளையாடும்போது ${APP_NAME} மிகவும் வேடிக்கையாக உள்ளது.\nஒன்று அல்லது அதற்கு மேற்பட்ட வன்பொருள் கட்டுப்படுத்திகளை இணைக்கவும் அல்லது நிறுவவும்\nதொலைபேசிகள் அல்லது டேப்லெட்களில் அவற்றைப் பயன்படுத்த ${REMOTE_APP_NAME} பயன்பாடு\nகட்டுப்படுத்திகளாக.", + "remote_app": { + "app_name": "BombSquad ரிமோட்", + "app_name_short": "BSரிமோட்", + "button_position": "பட்டன் நிலை", + "button_size": "பட்டன் அளவு", + "cant_resolve_host": "புரவலரைத் தீர்க்க முடியவில்லை.", + "capturing": "பிடிக்கிறது...", + "connected": "இணைக்கப்பட்டது.", + "description": "உங்கள் தொலைபேசி அல்லது டேப்லெட்டை BombSquad உடன் கட்டுப்படுத்தியாகப் பயன்படுத்தவும்.\nஒரே டிவி அல்லது டேப்லெட்டில் உள்ள காவிய உள்ளூர் மல்டிபிளேயர் பைத்தியக்காரத்தனத்திற்கு 8 சாதனங்கள் வரை ஒரே நேரத்தில் இணைக்க முடியும்.", + "disconnected": "சேவையகத்தால் துண்டிக்கப்பட்டது.", + "dpad_fixed": "சரி செய்யப்பட்டது", + "dpad_floating": "மிதக்கும்", + "dpad_position": "D-Pad நிலை", + "dpad_size": "D-Pad அளவு", + "dpad_type": "D-Pad வகை", + "enter_an_address": "ஒரு முகவரியை உள்ளிடவும்", + "game_full": "விளையாட்டு நிரம்பியுள்ளது அல்லது இணைப்புகளை ஏற்கவில்லை.", + "game_shut_down": "விளையாட்டு மூடப்பட்டது.", + "hardware_buttons": "வன்பொருள் பட்டன்கள்", + "join_by_address": "முகவரி மூலம் சேருங்கள்...", + "lag": "பின்னடைவு: ${SECONDS} வினாடிகள்", + "reset": "இயல்புநிலைக்கு மீட்டமைக்கவும்", + "run1": "ரன் 1", + "run2": "ரன் 2", + "searching": "BombSquad கேம்களைத் தேடுகிறது...", + "searching_caption": "விளையாட்டில் சேர அதன் பெயரைத் தட்டவும்.\nவிளையாட்டின் அதே வைஃபை நெட்வொர்க்கில் நீங்கள் இருப்பதை உறுதிப்படுத்திக் கொள்ளுங்கள்.", + "start": "தொடங்கு", + "version_mismatch": "பதிப்பு பொருந்தவில்லை.\nBombSquad மற்றும் BombSquad ரிமோட்டை உறுதி செய்யவும்\nசமீபத்திய பதிப்புகள் மற்றும் மீண்டும் முயற்சிக்கவும்." + }, + "removeInGameAdsText": "விளையாட்டு விளம்பரங்களை அகற்ற ஸ்டோரில் \"${PRO}\" ஐத் வாங்கவும்.", + "renameText": "மறுபெயரிடு", + "replayEndText": "ரீப்ளேயிலிருந்து வெளியேறு", + "replayNameDefaultText": "கடைசி கேம் ரீப்ளே", + "replayReadErrorText": "ரீப்ளே கோப்பைப் படிப்பதில் பிழை.", + "replayRenameWarningText": "நீங்கள் ஒரு விளையாட்டை வைத்திருக்க விரும்பினால் \"${REPLAY}\" என்று மறுபெயரிடுங்கள்; இல்லையெனில் அது மேலெழுதப்படும்.", + "replayVersionErrorText": "மன்னிக்கவும், இந்த ரீப்ளே வேறு வகையில் செய்யப்பட்டது\nவிளையாட்டின் பதிப்பு மற்றும் பயன்படுத்த முடியாது.", + "replayWatchText": "ரீப்ளே பார்", + "replayWriteErrorText": "ரிப்ளே கோப்பை எழுதுவதில் பிழை.", + "replaysText": "ரீப்ளேகள்", + "reportPlayerExplanationText": "ஏமாற்றுதல், பொருத்தமற்ற மொழி அல்லது பிற கெட்ட நடத்தை குறித்து புகாரளிக்க இந்த மின்னஞ்சலைப் பயன்படுத்தவும்.\nதயவுசெய்து கீழே விவரிக்கவும்:", + "reportThisPlayerCheatingText": "ஏமாற்றுதல்", + "reportThisPlayerLanguageText": "பொருத்தமற்ற மொழி", + "reportThisPlayerReasonText": "நீங்கள் என்ன தெரிவிக்க விரும்புகிறீர்கள்?", + "reportThisPlayerText": "இந்த பிளேயரைப் புகாரளிக்கவும்", + "requestingText": "கோருகிறது...", + "restartText": "மறுதொடக்கம்", + "retryText": "மீண்டும் முயற்சிக்கவும்", + "revertText": "பின்செல்", + "runText": "ஓடு", + "saveText": "சேமி", + "scanScriptsErrorText": "ஸ்கிரிப்ட்களை ஸ்கேன் செய்வதில் பிழை (கள்); விவரங்களுக்கு பதிவைப் பார்க்கவும்.", + "scoreChallengesText": "ஸ்கோர் சவால்கள்", + "scoreListUnavailableText": "மதிப்பெண் பட்டியல் கிடைக்கவில்லை.", + "scoreText": "மதிப்பெண் பெரு", + "scoreUnits": { + "millisecondsText": "மில்லிவிநாடிகள்", + "pointsText": "புள்ளிகள்", + "secondsText": "வினாடிகள்" + }, + "scoreWasText": "(${COUNT} இருந்தது)", + "selectText": "தேர்ந்தெடு", + "seriesWinLine1PlayerText": "வெற்றி", + "seriesWinLine1TeamText": "வெற்றி", + "seriesWinLine1Text": "வெற்றி", + "seriesWinLine2Text": "தொடர்!", + "settingsWindow": { + "accountText": "கணக்கு", + "advancedText": "மேம்பட்ட அமைப்புகள்", + "audioText": "ஆடியோ", + "controllersText": "கட்டுப்பாட்டாளர்கள்", + "graphicsText": "கிராபிக்ஸ்", + "playerProfilesMovedText": "குறிப்பு: பிளேயர் சுயவிவரங்கள் பிரதான மெனுவில் உள்ள கணக்கு சாளரத்திற்கு நகர்த்தப்பட்டுள்ளன.", + "titleText": "அமைப்புகள்" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(உரை திருத்துவதற்கான ஒரு எளிய, கட்டுப்படுத்தி-நட்பு திரையில் விசைப்பலகை)", + "alwaysUseInternalKeyboardText": "எப்போதும் உள் விசைப்பலகையைப் பயன்படுத்தவும்", + "benchmarksText": "அளவுகோல்கள் மற்றும் மன அழுத்த சோதனைகள்", + "disableCameraGyroscopeMotionText": "கேமரா கைரோஸ்கோப் இயக்கத்தை முடக்கவும்", + "disableCameraShakeText": "கேமரா குலுக்கை முடக்கு", + "disableThisNotice": "(மேம்பட்ட அமைப்புகளில் இந்த அறிவிப்பை முடக்கலாம்)", + "enablePackageModsDescriptionText": "(கூடுதல் மோடிங் திறன்களை செயல்படுத்துகிறது ஆனால் நெட்-ப்ளேவை முடக்குகிறது)", + "enablePackageModsText": "உள்ளூர் தொகுப்பு முறைகளை இயக்கு", + "enterPromoCodeText": "குறியீட்டை உள்ளிடவும்", + "forTestingText": "குறிப்பு: இந்த மதிப்புகள் சோதனைக்கு மட்டுமே மற்றும் பயன்பாடு வெளியேறும் போது", + "helpTranslateText": "${APP_NAME} இன் ஆங்கிலம் அல்லாத மொழிபெயர்ப்புகள் ஒரு சமூகம்\nஆதரவான முயற்சி. நீங்கள் பங்களிக்க அல்லது திருத்த விரும்பினால்\nஒரு மொழிபெயர்ப்பு, கீழே உள்ள இணைப்பைப் பின்தொடரவும். முன்கூட்டியே நன்றி!", + "kickIdlePlayersText": "செயலற்ற வீரர்களை வெளியேற்றவும்", + "kidFriendlyModeText": "குழந்தை நட்பு முறை (குறைந்த வன்முறை போன்றவை)", + "languageText": "மொழி", + "moddingGuideText": "மோடிங் வழிகாட்டி", + "mustRestartText": "இது நடைமுறைக்கு வர நீங்கள் விளையாட்டை மறுதொடக்கம் செய்ய வேண்டும்.", + "netTestingText": "நெட்வொர்க் சோதனை", + "resetText": "மீட்டு", + "showBombTrajectoriesText": "வெடிகுண்டு பாதைகளைக் காட்டு", + "showPlayerNamesText": "பிளேயர் பெயர்களைக் காட்டு", + "showUserModsText": "மோட்ஸ் கோப்புறையைக் காட்டு", + "titleText": "மேம்பட்ட அமைப்புகள்", + "translationEditorButtonText": "${APP_NAME} மொழிபெயர்ப்பு எடிட்டர்", + "translationFetchErrorText": "மொழிபெயர்ப்பு நிலை கிடைக்கவில்லை", + "translationFetchingStatusText": "மொழிபெயர்ப்பு நிலையை சரிபார்க்கிறது...", + "translationInformMe": "எனது மொழிக்கு புதுப்பிப்புகள் தேவைப்படும்போது எனக்குத் தெரியப்படுத்துங்கள்", + "translationNoUpdateNeededText": "தற்போதைய மொழி புதுப்பித்த நிலையில் உள்ளது; வூஹூ!", + "translationUpdateNeededText": "** தற்போதைய மொழிக்கு புதுப்பிப்புகள் தேவை !! **", + "vrTestingText": "VR சோதனை" + }, + "shareText": "பகிர்", + "sharingText": "பகிர்வு...", + "showText": "காட்டு", + "signInForPromoCodeText": "குறியீடுகள் நடைமுறைக்கு வர நீங்கள் ஒரு கணக்கில் உள்நுழைய வேண்டும்.", + "signInWithGameCenterText": "Game Center கணக்கைப் பயன்படுத்த,\nGame Center ஆப் மூலம் உள்நுழையவும்.", + "singleGamePlaylistNameText": "வெறும் ${GAME}", + "singlePlayerCountText": "1 வீரர்", + "soloNameFilterText": "தனி ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "குணம் தேர்ந்தெடுத்தல்", + "Chosen One": "சொசன் ஒன்று", + "Epic": "காவிய முறை விளையாட்டுகள்", + "Epic Race": "காவிய ஓட்டப்பந்தயம்", + "FlagCatcher": "கொடியை கைப்பற்றவும்", + "Flying": "ஹாப்பி தோட்ஹ்ட்ஸ்", + "Football": "கால்பந்து", + "ForwardMarch": "தாக்குதல்", + "GrandRomp": "அடைப்படுத்தல்", + "Hockey": "ஹாக்கி", + "Keep Away": "ஒதுக்கி வைக்கவும்", + "Marching": "சுற்றி ஓடு", + "Menu": "முதன்மை பட்டியல்", + "Onslaught": "தாக்குதல்", + "Race": "பந்தயம்", + "Scary": "மலையின் அரசன்", + "Scores": "ஸ்கோர் ஸ்கிரீன்", + "Survival": "நீக்குதல்", + "ToTheDeath": "மரண விளையாட்டு", + "Victory": "இறுதி மதிப்பெண் திரை" + }, + "spaceKeyText": "இடஎல்லை", + "statsText": "புள்ளிவிவரங்கள்", + "storagePermissionAccessText": "இதற்கு சேமிப்பு அணுகல் தேவை", + "store": { + "alreadyOwnText": "நீங்கள் ஏற்கனவே ${NAME} ஐ வைத்திருக்கிறீர்கள்!", + "bombSquadProNameText": "${APP_NAME} ப்ரோ", + "bombSquadProNewDescriptionText": "• விளையாட்டு விளம்பரங்கள் மற்றும் நாக் திரைகளை நீக்குகிறது\n• மேலும் விளையாட்டு அமைப்புகளைத் திறக்கிறது\n• மேலும் உள்ளடக்கியது:", + "buyText": "வாங்கு", + "charactersText": "குணங்கள்", + "comingSoonText": "விரைவில் வரும்...", + "extrasText": "கூடுதல்", + "freeBombSquadProText": "BombSquad இப்போது இலவசம், ஆனால் நீங்கள் முதலில் அதை வாங்கியதிலிருந்து நீங்கள்\nBombSquad Pro மேம்படுத்தல் மற்றும் ${COUNT} டிக்கெட்டுகளை நன்றியுடன் பெறுதல்.\nபுதிய அம்சங்களை அனுபவிக்கவும், உங்கள் ஆதரவுக்கு நன்றி!\n-எரிக்", + "holidaySpecialText": "விடுமுறை சிறப்பு", + "howToSwitchCharactersText": "(குணங்களை ஒதுக்க & தனிப்பயனாக்க \"${SETTINGS} -> ${PLAYER_PROFILES}\" க்குச் செல்லவும்)", + "howToUseIconsText": "(உலகளாவிய பிளேயர் சுயவிவரங்களை உருவாக்கவும் (கணக்கு சாளரத்தில்) இவற்றைப் பயன்படுத்தவும்)", + "howToUseMapsText": "(இந்த வரைபடங்களை உங்கள் சொந்த அணிகளில் பயன்படுத்தவும்/இலவசமாக அனைவருக்கும் பிளேலிஸ்ட்கள்)", + "iconsText": "சின்னங்கள்", + "loadErrorText": "பக்கத்தை ஏற்ற முடியவில்லை.\nஉங்கள் இணைய இணைப்பைச் சரிபார்க்கவும்.", + "loadingText": "ஏற்றுகிறது", + "mapsText": "வரைபடங்கள்", + "miniGamesText": "மினிகேம்ஸ்", + "oneTimeOnlyText": "(ஒரு முறை மட்டும்)", + "purchaseAlreadyInProgressText": "இந்த பொருளை வாங்குவது ஏற்கனவே நடந்து கொண்டிருக்கிறது.", + "purchaseConfirmText": "${ITEM} வாங்கவா?", + "purchaseNotValidError": "கொள்முதல் செல்லுபடியாகாது.\nஇது பிழை என்றால் ${EMAIL} ஐ தொடர்பு கொள்ளவும்.", + "purchaseText": "வாங்கு", + "saleBundleText": "மூட்டை விற்பனை!", + "saleExclaimText": "விற்பனை!", + "salePercentText": "(${PERCENT}% தள்ளுபடி)", + "saleText": "விற்பனை", + "searchText": "தேடு", + "teamsFreeForAllGamesText": "அணிகள் / பிரீ-போர்-ஆல் விளையாட்டுகள்", + "totalWorthText": "*** ${TOTAL_WORTH} மதிப்பு! ***", + "upgradeQuestionText": "மேம்படுத்தல்?", + "winterSpecialText": "குளிர்கால சிறப்பு", + "youOwnThisText": "- இது உங்களுக்கு சொந்தமானது -" + }, + "storeDescriptionText": "8 பிளேயர் பார்டி விளையாட்டு பைத்தியம்!\n\nபிடிப்பு-கொடி, வெடிகுண்டு-ஹாக்கி மற்றும் காவிய-மெதுவான-இயக்கம்-இறப்பு-போட்டி போன்ற வெடிக்கும் மினி-கேம்களின் போட்டியில் உங்கள் நண்பர்களை (அல்லது கணினியை) வெடிக்கச் செய்யுங்கள்!\n\nஎளிய கட்டுப்பாடுகள் மற்றும் விரிவான கட்டுப்பாட்டாளர் ஆதரவு 8 பேர் வரை செயலில் இறங்குவதை எளிதாக்குகிறது; இலவச 'பாம்ப்ஸ்க்வாட் ரிமோட்' ஆப் மூலம் உங்கள் மொபைல் சாதனங்களை கட்டுப்படுத்திகளாகவும் பயன்படுத்தலாம்!\n\nவெடிகுண்டுகள்!\n\nமேலும் தகவலுக்கு www.froemling.net/bombsquad ஐ பார்க்கவும்.", + "storeDescriptions": { + "blowUpYourFriendsText": "உங்கள் நண்பர்களை வெடிக்கச் செய்யுங்கள்.", + "competeInMiniGamesText": "பந்தயத்தில் இருந்து பறக்கும் வரை மினி-கேம்களில் போட்டியிடவும்.", + "customize2Text": "குணங்கள், மினி-கேம்கள் மற்றும் ஒலிப்பதிவையும் தனிப்பயனாக்கவும்.", + "customizeText": "குணங்களைத் தனிப்பயனாக்கி உங்கள் சொந்த மினி-கேம் பிளேலிஸ்ட்களை உருவாக்கவும்.", + "sportsMoreFunText": "வெடிபொருட்களுடன் விளையாட்டு மிகவும் வேடிக்கையாக உள்ளது.", + "teamUpAgainstComputerText": "கணினிக்கு எதிராக அணிசேருங்கள்." + }, + "storeText": "ஸ்டோர்", + "submitText": "சமர்ப்பிக்கவும்", + "submittingPromoCodeText": "குறியீட்டைச் சமர்ப்பிக்கிறது...", + "teamNamesColorText": "அணியின் பெயர்கள்/நிறங்கள்...", + "telnetAccessGrantedText": "டெல்நெட் அணுகல் இயக்கப்பட்டது.", + "telnetAccessText": "டெல்நெட் அணுகல் கண்டறியப்பட்டது; அனுமதிக்கவா?", + "testBuildErrorText": "இந்த சோதனை உருவாக்கம் இனி செயலில் இல்லை; தயவுசெய்து புதிய பதிப்பைச் சரிபார்க்கவும்.", + "testBuildText": "சோதனை கட்டமைப்பு", + "testBuildValidateErrorText": "சோதனை கட்டமைப்பை சரிபார்க்க முடியவில்லை. (நெட் இணைப்பு இல்லையா?)", + "testBuildValidatedText": "சோதனை கட்டமைப்பு சரிபார்க்கப்பட்டது; மகிழுங்கள்!", + "thankYouText": "உங்கள் ஆதரவுக்கு நன்றி! ஆட்டத்தை ரசி!!", + "threeKillText": "மூன்று கொலை!!", + "timeBonusText": "நேரம் போனஸ்", + "timeElapsedText": "நேரம் கடந்துவிட்டது", + "timeExpiredText": "நேரம் காலாவதியானது", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}h", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "உதவிக்குறிப்பு", + "titleText": "பாம்ஸ்குவாட்", + "titleVRText": "பாம்ஸ்குவாட் VR", + "topFriendsText": "சிறந்த நண்பர்கள்", + "tournamentCheckingStateText": "போட்டி நிலையை சரிபார்க்கிறது; தயவுசெய்து காத்திருங்கள்...", + "tournamentEndedText": "இந்த போட்டி முடிந்தது. புதியது விரைவில் தொடங்கும்.", + "tournamentEntryText": "போட்டியின் நுழைவு", + "tournamentResultsRecentText": "சமீபத்திய போட்டி முடிவுகள்", + "tournamentStandingsText": "போட்டி நிலைகள்", + "tournamentText": "போட்டி", + "tournamentTimeExpiredText": "போட்டி நேரம் காலாவதியானது", + "tournamentsDisabledWorkspaceText": "பணியிடங்கள் செயலில் இருக்கும்போது போட்டிகள் முடக்கப்படும்.\nபோட்டிகளை மீண்டும் இயக்க, உங்கள் பணியிடத்தை முடக்கி மீண்டும் தொடங்கவும்.", + "tournamentsText": "போட்டிகள்", + "translations": { + "characterNames": { + "Agent Johnson": "ஏஜெண்ட் ஜான்சன்", + "B-9000": "பி-9000", + "Bernard": "பர்னார்ட்", + "Bones": "போன்ஸ்", + "Butch": "பட்ச்", + "Easter Bunny": "ஈஸ்டர் பண்ணி", + "Flopsy": "ப்லாப்சி", + "Frosty": "பிரோஸ்ட்டி", + "Gretel": "கிரெடெல்", + "Grumbledorf": "கிறம்பில் டோரப்", + "Jack Morgan": "ஜாக் மோர்கன்", + "Kronk": "க்றோங்க்", + "Lee": "லி", + "Lucky": "லக்கி", + "Mel": "மெல்", + "Middle-Man": "மிடில்-மண்", + "Minimus": "மினிமஸ்", + "Pascal": "பாஸ்கல்", + "Pixel": "பிக்ஸெல்", + "Sammy Slam": "சம்மி ஸ்லம்", + "Santa Claus": "சாண்டா கிளாஸ்", + "Snake Shadow": "பாம்பு நிழல்", + "Spaz": "ஸ்பாஸ்", + "Taobao Mascot": "தாவோபா மாஸ்காட்", + "Todd McBurton": "டாட் மக்பூர்டன்", + "Zoe": "ஜோய்", + "Zola": "ஜோலா" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} பயிற்சி", + "Infinite ${GAME}": "எல்லையற்ற ${GAME}", + "Infinite Onslaught": "எல்லையற்ற தாக்குதல்", + "Infinite Runaround": "எல்லையற்ற சுற்றி ஓடு", + "Onslaught Training": "தாக்குதல் பயிற்சி", + "Pro ${GAME}": "ப்ரோ ${GAME}", + "Pro Football": "ப்ரோ கால்பந்து", + "Pro Onslaught": "ப்ரோ தாக்குதல்", + "Pro Runaround": "ப்ரோ சுற்றி ஓடு", + "Rookie ${GAME}": "ரூகீ ${GAME}", + "Rookie Football": "ரூகீ கால்பந்து", + "Rookie Onslaught": "ரூகீ தாக்குதல்", + "The Last Stand": "தி கடைசி ஸ்டாண்ட்", + "Uber ${GAME}": "உபர் ${GAME}", + "Uber Football": "உபர் கால்பந்து", + "Uber Onslaught": "உபர் தாக்குதல்", + "Uber Runaround": "உபர் சுற்றி ஓடு" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "வெற்றிபெற நீண்ட நேரம் தேர்ந்தெடுக்கப்பட்டவராக இருங்கள்.\nதேர்ந்தெடுக்கப்பட்டவரை அதைக் கொல்லுங்கள்.", + "Bomb as many targets as you can.": "உங்களால் முடிந்தவரை பல இலக்குகளை வெடிக்கவும்.", + "Carry the flag for ${ARG1} seconds.": "கொடியை ${ARG1} வினாடிகளுக்கு எடுத்துச் செல்லவும்", + "Carry the flag for a set length of time.": "ஒரு குறிப்பிட்ட நேரத்திற்கு கொடியை எடுத்துச் செல்லவும்.", + "Crush ${ARG1} of your enemies.": "உங்கள் எதிரிகளின் ${ARG1} ஐ நசுக்கவும்.", + "Defeat all enemies.": "அனைத்து எதிரிகளையும் தோற்கடிக்கவும்.", + "Dodge the falling bombs.": "விழும் குண்டுகளைத் தள்ளிவிடுங்கள்.", + "Final glorious epic slow motion battle to the death.": "இறுதி புகழ்பெற்ற காவிய மெதுவான நகர்வு போர்.", + "Gather eggs!": "முட்டைகளை சேகரிக்கவும்!", + "Get the flag to the enemy end zone.": "எதிரியின் இறுதி மண்டலத்திற்கு கொடியைப் பெறுங்கள்.", + "How fast can you defeat the ninjas?": "நீங்கள் நிஞ்ஜாக்களை எவ்வளவு விரைவாக தோற்கடிக்க முடியும்?", + "Kill a set number of enemies to win.": "வெற்றிபெற ஒரு குறிப்பிட்ட எண்ணிக்கையிலான எதிரிகளைக் கொல்லுங்கள்.", + "Last one standing wins.": "கடைசியாக நின்றவர் வெற்றி பெறுகிறார்.", + "Last remaining alive wins.": "கடைசியாக எஞ்சியிருக்கும் வெற்றி.", + "Last team standing wins.": "கடைசி அணி வெற்றி பெருவார்", + "Prevent enemies from reaching the exit.": "எதிரிகள் வெளியேறுவதைத் தடுக்கவும்.", + "Reach the enemy flag to score.": "மதிப்பெண் பெற எதிரி கொடியை அடையுங்கள்.", + "Return the enemy flag to score.": "மதிப்பெண் பெற எதிரி கொடியை எடுத்து உங்கள் இடத்தில் வைக்கவும்.", + "Run ${ARG1} laps.": "${ARG1} சுற்றில் ஓடு.", + "Run ${ARG1} laps. Your entire team has to finish.": "${ARG1} சுற்றில் ஓடு. உங்கள் முழு அணியும் முடிக்க வேண்டும்.", + "Run 1 lap.": "1 சுற்று ஓடு.", + "Run 1 lap. Your entire team has to finish.": "1 சுற்று ஓடு. உங்கள் முழு அணியும் முடிக்க வேண்டும்.", + "Run real fast!": "மிக வேகமாக ஓடு!", + "Score ${ARG1} goals.": "${ARG1} கொள்களை பெரு.", + "Score ${ARG1} touchdowns.": "${ARG1} டச் டவுன்களை பெரு.", + "Score a goal.": "ஒரு கோளை பெரு.", + "Score a touchdown.": "ஒரு டச் டவுனை பெரு.", + "Score some goals.": "சில கோல்களை பெரு.", + "Secure all ${ARG1} flags.": "அனைத்து ${ARG1} கொடிகளையும் பாதுகாக்கவும்.", + "Secure all flags on the map to win.": "வெற்றி பெற வரைபடத்தில் உள்ள அனைத்து கொடிகளையும் பாதுகாக்கவும்.", + "Secure the flag for ${ARG1} seconds.": "கொடியை ${ARG1} வினாடிகளுக்கு பாதுகாக்கவும்.", + "Secure the flag for a set length of time.": "ஒரு குறிப்பிட்ட நேரத்திற்கு கொடியை பாதுகாக்கவும்.", + "Steal the enemy flag ${ARG1} times.": "எதிரி கொடியை ${ARG1} முறை திருடவும்.", + "Steal the enemy flag.": "எதிரி கொடியை திருடு.", + "There can be only one.": "ஒன்று மட்டுமே இருக்க முடியும்.", + "Touch the enemy flag ${ARG1} times.": "எதிரி கொடியை ${ARG1} முறை தொடவும்.", + "Touch the enemy flag.": "எதிரி கொடியை தொடவும்.", + "carry the flag for ${ARG1} seconds": "கொடியை ${ARG1} வினாடிகளுக்கு எடுத்துச் செல்லவும்", + "kill ${ARG1} enemies": "${ARG1} எதிரிகளை கொல்லுங்கள்", + "last one standing wins": "கடைசியாக நின்றவர் வெற்றி பெறுகிறது", + "last team standing wins": "கடைசியாக அணி வெற்றி பெருவார்", + "return ${ARG1} flags": "${ARG1} கொடிகளைத் திருப்பித் தரவும்", + "return 1 flag": "1 கொடி திரும்ப வைக்கவும்", + "run ${ARG1} laps": "${ARG1} சுற்றில் ஓடு", + "run 1 lap": "1 சுற்று ஓடு", + "score ${ARG1} goals": "${ARG1} கொல்களை பெரு", + "score ${ARG1} touchdowns": "${ARG1} டச் டவுன்களை பெரு", + "score a goal": "ஒரு கோளை பெரு", + "score a touchdown": "ஒரு டச் டவுனை பெரு", + "secure all ${ARG1} flags": "அனைத்து ${ARG1} கொடிகளையும் பாதுகாக்கவும்", + "secure the flag for ${ARG1} seconds": "கொடியை ${ARG1} வினாடிகளுக்கு பாதுகாக்கவும்", + "touch ${ARG1} flags": "${ARG1} கொடிகளைத் தொடவும்", + "touch 1 flag": "1 கொடியை தொடவும்" + }, + "gameNames": { + "Assault": "அஸ்ஸலட்", + "Capture the Flag": "காப்சர் தி பிளாக்", + "Chosen One": "சொசன் ஒன்று", + "Conquest": "கான்குஎஸ்த்", + "Death Match": "மரண விளையாட்டு", + "Easter Egg Hunt": "ஈஸ்டர் முட்டை வேட்டை", + "Elimination": "நீக்குதல்", + "Football": "கால்பந்து", + "Hockey": "ஹாக்கி", + "Keep Away": "ஒதுக்கி வைக்கவும்", + "King of the Hill": "மலையின் அரசன்", + "Meteor Shower": "எரிகல் பொழிவு", + "Ninja Fight": "நிஞ்ஜா சண்டை", + "Onslaught": "தாக்குதல்", + "Race": "ஓட்டப்பந்தயம்", + "Runaround": "சுற்றி ஓடு", + "Target Practice": "இலக்கு பயிற்சி", + "The Last Stand": "கடைசி நிலைபாடு" + }, + "inputDeviceNames": { + "Keyboard": "விசைப்பலகை", + "Keyboard P2": "விசைப்பலகை P2" + }, + "languages": { + "Arabic": "அரேபிக்", + "Belarussian": "பெளருஷ்ஷியன்", + "Chinese": "சைனீஸ் எளிமைப்படுத்தப்பட்டது", + "ChineseTraditional": "சைனீஸ் பாரம்பரியமான", + "Croatian": "கிரோட்டியன்", + "Czech": "சேக்", + "Danish": "டானிஷ்", + "Dutch": "டச்", + "English": "ஆங்கிலம்", + "Esperanto": "எசபராண்டோ", + "Filipino": "பிலிபினோ", + "Finnish": "பின்னிஷ்", + "French": "பிரெஞ்ச்", + "German": "ஜெர்மன்", + "Gibberish": "கிப்பேரிஷ்", + "Greek": "கிரீக்", + "Hindi": "ஹிந்தி", + "Hungarian": "ஹங்கரியன்", + "Indonesian": "இன்தோனேஷியன்", + "Italian": "இத்தாலியன்", + "Japanese": "ஜாபனீஸ்", + "Korean": "கொரியன்", + "Malay": "மலாய்", + "Persian": "பர்ஷியன்", + "Polish": "பலிஷ்", + "Portuguese": "போர்சுகிஸ்", + "Romanian": "ரோமானியன்", + "Russian": "ரஷ்யன்", + "Serbian": "சர்பியன்", + "Slovak": "ஸ்லோவக்", + "Spanish": "ஸ்பானிஷ்", + "Swedish": "ஸ்வீடிஷ்", + "Tamil": "தமிழ்", + "Thai": "தாய்", + "Turkish": "டர்கிஷ்", + "Ukrainian": "உக்ரைனியன்", + "Venetian": "வெனிசியன்", + "Vietnamese": "வியெட்னமீஸ்" + }, + "leagueNames": { + "Bronze": "பிரான்ஸ்", + "Diamond": "டைமன்ட்", + "Gold": "தங்கம்", + "Silver": "வெள்ளி" + }, + "mapsNames": { + "Big G": "பிக் சி", + "Bridgit": "பிரிட்சிட்", + "Courtyard": "கோர்ட்யார்ட்", + "Crag Castle": "கிரக் கோட்டை", + "Doom Shroom": "டூம் ஷரூம்", + "Football Stadium": "கால்பந்து அரங்கம்", + "Happy Thoughts": "ஹாப்பி தொட்ஸ்", + "Hockey Stadium": "ஹாக்கி ஸ்டேடியம்", + "Lake Frigid": "பிரிசித் ஏரி", + "Monkey Face": "குரங்கு முகம்", + "Rampage": "ராம்பேஜ்", + "Roundabout": "ரவுண்டபவுட்", + "Step Right Up": "ஸ்டெப் ரைட் அப்", + "The Pad": "தி பாட்", + "Tip Top": "டிப் டாப்", + "Tower D": "டவர் D", + "Zigzag": "ஜிக்ஜாக்" + }, + "playlistNames": { + "Just Epic": "வெறும் காவியம்", + "Just Sports": "வெறும் விளையாட்டு" + }, + "scoreNames": { + "Flags": "கொடிகள்", + "Goals": "கோள்கள்", + "Score": "மதிப்பெண்கள்", + "Survived": "உயிர் பிழைத்தது", + "Time": "நேரம்", + "Time Held": "நேரம் நடைபெற்றது" + }, + "serverResponses": { + "A code has already been used on this account.": "இந்தக் கணக்கில் ஏற்கனவே ஒரு குறியீடு பயன்படுத்தப்பட்டுள்ளது.", + "A reward has already been given for that address.": "அந்த முகவரிக்கு ஏற்கனவே வெகுமதி வழங்கப்பட்டுள்ளது.", + "Account linking successful!": "கணக்கு இணைப்பு வெற்றிகரமாக உள்ளது!", + "Account unlinking successful!": "கணக்கு இணைப்பு நீக்கப்பட்டது!", + "Accounts are already linked.": "கணக்குகள் ஏற்கனவே இணைக்கப்பட்டுள்ளன.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "விளம்பரக் காட்சியைச் சரிபார்க்க முடியவில்லை.\nநீங்கள் விளையாட்டின் அதிகாரப்பூர்வ மற்றும் புதுப்பித்த பதிப்பை இயக்குகிறீர்கள் என்பதை உறுதிப்படுத்திக் கொள்ளுங்கள்.", + "An error has occurred; (${ERROR})": "தவறு நிகழ்ந்துவிட்டது; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "தவறு நிகழ்ந்துவிட்டது; தயவுசெய்து ஆதரவைத் தொடர்பு கொள்ளவும். (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "தவறு நிகழ்ந்துவிட்டது; தயவுசெய்து support@froemling.net ஐ தொடர்பு கொள்ளவும்.", + "An error has occurred; please try again later.": "தவறு நிகழ்ந்துவிட்டது; தயவுசெய்து பிறகு முயற்சிக்கவும்.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "இந்தக் கணக்குகளை நிச்சயமாக இணைக்க விரும்புகிறீர்களா?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nஇதை முடிக்காமல் விட கூடாது!", + "BombSquad Pro unlocked!": "பாம்ஸ்குவாட் ப்ரோ அன்லாக் செய்யபட்தது!", + "Can't link 2 accounts of this type.": "இந்த வகை 2 கணக்குகளை இணைக்க முடியாது.", + "Can't link 2 diamond league accounts.": "2 வைர லீக் கணக்குகளை இணைக்க முடியாது.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "இணைக்க முடியவில்லை; அதிகபட்சமாக ${COUNT} இணைக்கப்பட்ட கணக்குகளை விட அதிகமாக இருக்கும்.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "மோசடி கண்டறியப்பட்டது; மதிப்பெண்கள் மற்றும் பரிசுகள் ${COUNT} நாட்களுக்கு நிறுத்தி வைக்கப்பட்டன.", + "Could not establish a secure connection.": "பாதுகாப்பான இணைப்பை நிறுவ முடியவில்லை.", + "Daily maximum reached.": "தினசரி அதிகபட்சம் அடைந்தது.", + "Entering tournament...": "போட்டியில் நுழைகிறது...", + "Invalid code.": "தவறான குறியீடு.", + "Invalid payment; purchase canceled.": "தவறான கட்டணம்; கொள்முதல் ரத்து செய்யப்பட்டது.", + "Invalid promo code.": "தவறான விளம்பர குறியீடு.", + "Invalid purchase.": "தவறான கொள்முதல்.", + "Invalid tournament entry; score will be ignored.": "தவறான போட்டி நுழைவு; மதிப்பெண் புறக்கணிக்கப்படும்.", + "Item unlocked!": "பொருள் அன்லோக் செய்யபட்தது", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "இணைத்தல் மறுக்கப்பட்டது. ${ACCOUNT} கொண்டுள்ளது\nஎல்லாவற்றையும் இழக்கும் குறிப்பிடத்தக்க தரவு.\nநீங்கள் விரும்பினால் எதிர் வரிசையில் இணைக்கலாம்\n(அதற்கு பதிலாக இந்த கணக்கின் தரவை இழக்கவும்)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "இந்தக் கணக்கிற்கு ${ACCOUNT} கணக்கை இணைக்கவா?\n${ACCOUNT} இல் இருக்கும் எல்லா தரவும் இழக்கப்படும்.\nஇதை முடிக்காமல் விட கூடாது. நீ சொல்வது உறுதியா?", + "Max number of playlists reached.": "அதிகபட்ச எண்ணிக்கையிலான பிளேலிஸ்ட்கள் எட்டப்பட்டுள்ளன.", + "Max number of profiles reached.": "அதிகபட்ச எண்ணிக்கையிலான சுயவிவரங்கள் எட்டப்பட்டுள்ளன.", + "Maximum friend code rewards reached.": "அதிகபட்ச நண்பர் குறியீடு வெகுமதிகளை அடைந்தது.", + "Message is too long.": "செய்தி மிக நீளமானது.", + "No servers are available. Please try again soon.": "சேவையகங்கள் இல்லை. தயவுசெய்து விரைவில் மீண்டும் முயற்சிக்கவும்.", + "Profile \"${NAME}\" upgraded successfully.": "சுயவிவரம் \"${NAME}\" வெற்றிகரமாக மேம்படுத்தப்பட்டது.", + "Profile could not be upgraded.": "சுயவிவரத்தை மேம்படுத்த முடியவில்லை.", + "Purchase successful!": "வாங்குதல் வெற்றிகரமாக உள்ளது!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "உள்நுழைவதற்கு ${COUNT} டிக்கெட்டுகள் கிடைத்தன.\n${TOMORROW_COUNT} பெற நாளை மீண்டும் வாருங்கள்.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "விளையாட்டின் இந்த பதிப்பில் சேவையக செயல்பாடு இனி ஆதரிக்கப்படாது;\nதயவுசெய்து புதிய பதிப்பிற்கு புதுப்பிக்கவும்.", + "Sorry, there are no uses remaining on this code.": "மன்னிக்கவும், இந்த குறியீட்டில் எந்த பயனும் இல்லை.", + "Sorry, this code has already been used.": "மன்னிக்கவும், இந்த குறியீடு ஏற்கனவே பயன்படுத்தப்பட்டுள்ளது.", + "Sorry, this code has expired.": "மன்னிக்கவும், இந்த குறியீடு காலாவதியாகிவிட்டது.", + "Sorry, this code only works for new accounts.": "மன்னிக்கவும், இந்தக் குறியீடு புதிய கணக்குகளுக்கு மட்டுமே வேலை செய்யும்.", + "Still searching for nearby servers; please try again soon.": "இன்னும் அருகிலுள்ள சேவையகங்களைத் தேடுகிறது; தயவுசெய்து விரைவில் மீண்டும் முயற்சிக்கவும்.", + "Temporarily unavailable; please try again later.": "தற்காலிகமாக இல்லை; தயவுசெய்து பிறகு முயற்சிக்கவும்.", + "The tournament ended before you finished.": "நீங்கள் முடிப்பதற்குள் போட்டி முடிந்தது.", + "This account cannot be unlinked for ${NUM} days.": "இந்தக் கணக்கை ${NUM} நாட்களுக்கு இணைக்க முடியவில்லை.", + "This code cannot be used on the account that created it.": "இந்தக் குறியீட்டை உருவாக்கிய கணக்கில் பயன்படுத்த முடியாது.", + "This is currently unavailable; please try again later.": "இது தற்போது கிடைக்கவில்லை; தயவுசெய்து பிறகு முயற்சிக்கவும்.", + "This requires version ${VERSION} or newer.": "இதற்கு ${VERSION} பதிப்பு அல்லது புதியது தேவை.", + "Tournaments disabled due to rooted device.": "வேரூன்றிய சாதனம் காரணமாக போட்டிகள் முடக்கப்பட்டுள்ளன.", + "Tournaments require ${VERSION} or newer": "போட்டிகளுக்கு ${VERSION} அல்லது புதியது தேவை", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "இந்தக் கணக்கிலிருந்து ${ACCOUNT} இணைப்பை நீக்கவா?\n${ACCOUNT} இல் உள்ள எல்லா தரவும் மீட்டமைக்கப்படும்.\n(சில சந்தர்ப்பங்களில் சாதனைகளைத் தவிர)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "எச்சரிக்கை: உங்கள் கணக்கிற்கு எதிராக ஹேக்கிங் புகார்கள் வழங்கப்பட்டுள்ளன.\nஹேக்கிங் செய்யப்பட்ட கணக்குகள் தடை செய்யப்படும். தயவுசெய்து நியாயமாக விளையாடுங்கள்.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "உங்கள் சாதனக் கணக்கை இதனுடன் இணைக்க விரும்புகிறீர்களா?\n\nஉங்கள் சாதனக் கணக்கு ${ACCOUNT1}\nஇந்தக் கணக்கு ${ACCOUNT2}\n\nஇது உங்கள் தற்போதைய முன்னேற்றத்தை வைத்திருக்க அனுமதிக்கும்.\nஎச்சரிக்கை: இதைச் செயல்தவிர்க்க முடியாது!", + "You already own this!": "நீங்கள் ஏற்கனவே இதை வைத்திருக்கிறீர்கள்!", + "You can join in ${COUNT} seconds.": "நீங்கள் ${COUNT} வினாடிகளில் சேரலாம்.", + "You don't have enough tickets for this!": "இதற்கு உங்களிடம் போதுமான டிக்கெட்டுகள் இல்லை!", + "You don't own that.": "உங்களுக்கு அது சொந்தமில்லை.", + "You got ${COUNT} tickets!": "நீங்கள் ${COUNT} டிக்கெட்டுகளைப் பெற்றுள்ளீர்கள்!", + "You got a ${ITEM}!": "உங்களுக்கு ${ITEM} கிடைத்துள்ளது!", + "You have been promoted to a new league; congratulations!": "நீங்கள் ஒரு புதிய லீக்கில் பதவி உயர்வு பெற்றுள்ளீர்கள்; வாழ்த்துக்கள்!", + "You must update to a newer version of the app to do this.": "இதைச் செய்ய நீங்கள் பயன்பாட்டின் புதிய பதிப்பைப் புதுப்பிக்க வேண்டும்.", + "You must update to the newest version of the game to do this.": "இதைச் செய்ய நீங்கள் விளையாட்டின் புதிய பதிப்பைப் புதுப்பிக்க வேண்டும்.", + "You must wait a few seconds before entering a new code.": "புதிய குறியீட்டை உள்ளிடுவதற்கு சில வினாடிகள் காத்திருக்க வேண்டும்.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "கடந்த போட்டியில் #${RANK} இடத்தைப் பிடித்தீர்கள். விளையாடியதற்கு நன்றி!", + "Your account was rejected. Are you signed in?": "உங்கள் கணக்கு நிராகரிக்கப்பட்டது. நீங்கள் உள்நுழைந்துள்ளீர்களா?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "விளையாட்டின் உங்கள் நகல் மாற்றப்பட்டது.\nதயவுசெய்து ஏதேனும் மாற்றங்களைச் செய்து, மீண்டும் முயற்சிக்கவும்.", + "Your friend code was used by ${ACCOUNT}": "உங்கள் நண்பர் குறியீடு ${ACCOUNT} ஆல் பயன்படுத்தப்பட்டது" + }, + "settingNames": { + "1 Minute": "1 நிமிடம்", + "1 Second": "1 வினாடி", + "10 Minutes": "10 நிமிடங்கள்", + "2 Minutes": "2 நிமிடங்கள்", + "2 Seconds": "2 வினாடிகள்", + "20 Minutes": "20 நிமிடங்கள்", + "4 Seconds": "4 வினாடிகள்", + "5 Minutes": "5 நிமிடங்கள்", + "8 Seconds": "8 வினாடிகள்", + "Allow Negative Scores": "எதிர்மறை மதிப்பெண்களை அனுமதிக்கவும்", + "Balance Total Lives": "இருப்பு மொத்த உயிர்கள்", + "Bomb Spawning": "வெடிகுண்டு முட்டையிடுதல்", + "Chosen One Gets Gloves": "தேர்ந்தெடுக்கப்பட்ட ஒருவர் கையுறைகளைப் பெறுகிறார்", + "Chosen One Gets Shield": "தேர்ந்தெடுக்கப்பட்ட ஒருவர் கேடயத்தைப் பெறுகிறார்", + "Chosen One Time": "தேர்ந்தெடுக்கப்பட்டது ஒன்றின் நேரம்", + "Enable Impact Bombs": "தாக்க குண்டுகளை இயக்கு", + "Enable Triple Bombs": "மூன்று குண்டுகளை இயக்கு", + "Entire Team Must Finish": "முழு குழுவும் முடிக்க வேண்டும்", + "Epic Mode": "காவிய முறை", + "Flag Idle Return Time": "கொடி சும்மா திரும்பும் நேரம்", + "Flag Touch Return Time": "கொடியைத் தொடும் நேரம்", + "Hold Time": "நேரத்தை பிடி", + "Kills to Win Per Player": "ஒரு வீரருக்கு வெல்ல பலி", + "Laps": "சுற்றுகள்", + "Lives Per Player": "ஒரு வீரருக்கு உயிர்கள்", + "Long": "பெரிய", + "Longer": "நீண்ட", + "Mine Spawning": "சின்ன குண்டு முட்டையிடும்", + "No Mines": "சின்ன குண்டுகள் இல்லை", + "None": "இல்லை", + "Normal": "சாதாரண", + "Pro Mode": "ப்ரோ முறை", + "Respawn Times": "ரேஸ்பான் நேரங்கள்", + "Score to Win": "மதிப்பெண் பெரு வெற்றி பெறுவாய்", + "Short": "சிறிய", + "Shorter": "குறுகிய", + "Solo Mode": "தனி முறை", + "Target Count": "இலக்கு எண்ணிக்கை", + "Time Limit": "நேரம் அளவு" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${PLAYER} வெளியேறியதால் ${TEAM} தகுதி நீக்கம் செய்யப்பட்டுள்ளது", + "Killing ${NAME} for skipping part of the track!": "பாதையின் ஒரு பகுதியைத் தவிர்த்ததற்காக ${NAME} ஐக் கொன்றது!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "${NAME}க்கு எச்சரிக்கை: டர்போ / பட்டன்-ஸ்பேமிங் உங்களைத் தாக்கும்." + }, + "teamNames": { + "Bad Guys": "கெட்டவர்கள்", + "Blue": "நீலம்", + "Good Guys": "நல்லவர்கள்", + "Red": "சிவப்பு" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "ஒரு சரியான நேர ஓட்டம்-ஜம்பிங்-ஸ்பின்-பஞ்ச் ஒரே வெற்றியில் கொல்லலாம்\nமற்றும் உங்கள் நண்பர்களிடமிருந்து உங்களுக்கு வாழ்நாள் முழுவதும் மரியாதை கிடைக்கும்.", + "Always remember to floss.": "எப்போதும் ஃப்ளோஸ் செய்ய நினைவில் கொள்ளுங்கள்.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "உங்களுக்கும் உங்கள் நண்பர்களுக்கும் பிளேயர் சுயவிவரங்களை உருவாக்கவும்\nசீரற்றவற்றைப் பயன்படுத்துவதற்குப் பதிலாக உங்கள் விருப்பமான பெயர்கள் மற்றும் தோற்றங்கள்.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "சாபப் பெட்டிகள் உங்களை ஒரு டிக்கிங் டைம் பாம்டாக மாற்றும்.\nஒரே ஒரு ஹெல்த் பேக் சீக்கிரம் பிடிப்பதுதான்.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "அவற்றின் தோற்றம் இருந்தபோதிலும், அனைத்து கதாபாத்திரங்களின் திறன்களும் ஒரே மாதிரியானவை,\nஎனவே நீங்கள் மிகவும் நெருக்கமாக ஒத்திருப்பதைத் தேர்ந்தெடுக்கவும்.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "அந்த ஆற்றல் கவசத்துடன் மிகவும் மெல்ல வேண்டாம்; நீங்கள் இன்னும் உங்களை ஒரு குன்றிலிருந்து தூக்கி எறியலாம்.", + "Don't run all the time. Really. You will fall off cliffs.": "எல்லா நேரமும் ஓடாதே. உண்மையில். நீங்கள் பாறைகளில் இருந்து விழுவீர்கள்.", + "Don't spin for too long; you'll become dizzy and fall.": "அதிக நேரம் சுற்ற வேண்டாம்; நீங்கள் மயக்கமடைந்து விழுவீர்கள்.", + "Hold any button to run. (Trigger buttons work well if you have them)": "ஓடதற்கு ஏதேனும் பட்டனை அழுத்திப் பிடிக்கவும். (தூண்டுதல் பட்டன்கள் உங்களிடம் இருந்தால் நன்றாக வேலை செய்யும்)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "ஓட எந்த பட்டனையும் அழுத்திப் பிடிக்கவும். நீங்கள் விரைவாக இடங்களைப் பெறுவீர்கள்\nஆனால் அது நன்றாக மாறாது, எனவே பாறைகளை கவனிக்கவும்.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "பனி குண்டுகள் மிகவும் சக்திவாய்ந்தவை அல்ல, ஆனால் அவை உறைகின்றன\nஅவர்கள் யாரை அடித்தாலும், அவர்களை நொறுக்குவதற்கு ஆளாக்கலாம்.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "யாராவது உங்களை அழைத்துச் சென்றால், அவர்களை குத்துங்கள், அவர்கள் விட்டுவிடுவார்கள்.\nஇது நிஜ வாழ்க்கையிலும் வேலை செய்கிறது.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "உங்களுக்கு கன்ட்ரோலர்கள் குறைவாக இருந்தால், '${REMOTE_APP_NAME}' பயன்பாட்டை நிறுவவும்\nஅவற்றை கட்டுப்படுத்திகளாகப் பயன்படுத்த உங்கள் மொபைல் சாதனங்களில்.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "உங்களிடம் ஒட்டும் வெடிகுண்டு சிக்கினால், சுற்றி குதித்து வட்டமாகச் சுழற்றுங்கள். நீங்கள் வேண்டுமானால்\nவெடிகுண்டை அசைக்கவும், அல்லது வேறு எதுவும் இல்லையென்றால் உங்கள் கடைசி தருணங்கள் பொழுதுபோக்காக இருக்கும்.", + "If you kill an enemy in one hit you get double points for it.": "ஒரே அடியில் எதிரியைக் கொன்றால் அதற்கு இரட்டைப் புள்ளிகள் கிடைக்கும்.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "நீங்கள் ஒரு சாபத்தைத் தேர்ந்தெடுத்தால், உங்கள் உயிர் பிழைப்பதற்கான ஒரே நம்பிக்கை\nஅடுத்த சில நொடிகளில் ஒரு ஹெல்த் சக்தியைக் கண்டறியவும்.", + "If you stay in one place, you're toast. Run and dodge to survive..": "நீங்கள் ஒரு இடத்தில் இருந்தாள், நீங்கள் சிற்றுண்டி. உயிர் பிழைக்க ஓடி ஓடிவிடு ..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "உங்களிடம் நிறைய வீரர்கள் வந்து செல்லும் போது, ​​'ஆட்டோ-கிக்-ஐடில்-பிளேயர்கள்' என்பதை இயக்கவும்\nயாராவது விளையாட்டை விட்டு வெளியேற மறந்தால் அமைப்புகளின் கீழ்.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "உங்கள் சாதனம் மிகவும் சூடாக இருந்தால் அல்லது நீங்கள் பேட்டரி சக்தியை சேமிக்க விரும்பினால்,\nஅமைப்புகள்-> கிராபிக்ஸில் \"காட்சிகள்\" அல்லது \"தீர்மானம்\" நிராகரிக்கவும்", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "உங்கள் ஃப்ரேம்ரேட் மோசமாக இருந்தால், தீர்மானத்தை நிராகரிக்க முயற்சிக்கவும்\nஅல்லது விளையாட்டின் கிராபிக்ஸ் அமைப்புகளில் காட்சிகள்.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Capture-the-Flag இல், உங்கள் சொந்தக் கொடி மற்றொன்று என்றால், மதிப்பெண் பெற, உங்கள் அடித்தளத்தில் இருக்க வேண்டும்\nஅணி கோல் அடிக்க உள்ளது, அவர்களின் கொடியை திருடுவது அவர்களை தடுக்க ஒரு நல்ல வழியாகும்.", + "In hockey, you'll maintain more speed if you turn gradually.": "ஹாக்கியில், நீங்கள் படிப்படியாகத் திரும்பினால் அதிக வேகத்தைப் பேணுவீர்கள்.", + "It's easier to win with a friend or two helping.": "ஒரு நண்பர் அல்லது இருவரின் உதவியால் வெற்றி பெறுவது எளிது.", + "Jump just as you're throwing to get bombs up to the highest levels.": "குண்டுகளை மிக உயர்ந்த நிலைக்கு எடுப்பதற்கு நீங்கள் எறிவது போல் குதிக்கவும்.", + "Land-mines are a good way to stop speedy enemies.": "சின்ன-குண்டுகள் வேகமான எதிரிகளை நிறுத்த ஒரு நல்ல வழி.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "மற்ற வீரர்கள் உட்பட பல பொருள்களை எடுத்து வீசலாம். தூக்கி எறிதல்\nபாறைகளில் இருந்து உங்கள் எதிரிகள் ஒரு பயனுள்ள மற்றும் உணர்வுபூர்வமாக நிறைவேற்றும் உத்தியாக இருக்கலாம்.", + "No, you can't get up on the ledge. You have to throw bombs.": "இல்லை, நீங்கள் லெட்ஜில் எழுந்திருக்க முடியாது. குண்டுகளை வீச வேண்டும்.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "பெரும்பாலான கேம்களின் நடுவில் வீரர்கள் சேரலாம் மற்றும் வெளியேறலாம்,\nமேலும் நீங்கள் பறக்கும்போது கட்டுப்படுத்திகளை செருகவும் மற்றும் அகற்றவும் முடியும்.", + "Practice using your momentum to throw bombs more accurately.": "வெடிகுண்டுகளை இன்னும் துல்லியமாக வீச உங்கள் வேகத்தைப் பயன்படுத்திப் பயிற்சி செய்யுங்கள்.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "உங்கள் கைமுட்டிகள் எவ்வளவு வேகமாக நகருகிறதோ, அந்த அளவுக்கு குத்துக்கள் அதிக சேதத்தை ஏற்படுத்தும்.\nஎனவே பைத்தியம் போல் ஓடவும், குதிக்கவும், சுழலவும் முயற்சிக்கவும்.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "வெடிகுண்டை வீசுவதற்கு முன் முன்னும் பின்னுமாக ஓடுங்கள்\nஅதை 'சவுக்கடி' செய்து தூர எறியுங்கள்.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "எதிரிகளின் குழுவை வெளியேற்றவும்\nTNT பெட்டிக்கு அருகில் வெடிகுண்டு வைப்பது.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "தலை மிகவும் பாதிக்கப்படக்கூடிய பகுதி, எனவே ஒரு ஒட்டும் குண்டு\nto the noggin பொதுவாக கேம்-ஓவர் என்று பொருள்.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "இந்த நிலை ஒருபோதும் முடிவடையாது, ஆனால் இங்கே அதிக மதிப்பெண்\nஉலகம் முழுவதும் உங்களுக்கு நித்திய மரியாதை கிடைக்கும்.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "வீசும் வலிமை நீங்கள் வைத்திருக்கும் திசையை அடிப்படையாகக் கொண்டது.\nஉங்கள் முன்னால் மெதுவாக எதையாவது தூக்கி எறிய, எந்த திசையையும் பிடிக்காதீர்கள்.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "ஒலிப்பதிவு சோர்வாக? அதை உங்கள் சொந்தமாக மாற்றவும்!\nஅமைப்புகள்->ஆடியோ->சவுண்ட்டிராக்கைப் பார்க்கவும்", + "Try 'Cooking off' bombs for a second or two before throwing them.": "குண்டுகளை வீசுவதற்கு முன் ஓரிரு வினாடிகளுக்கு 'குக்கிங் ஆஃப்' முயற்சி செய்யுங்கள்.", + "Try tricking enemies into killing eachother or running off cliffs.": "எதிரிகளை ஏமாற்றி ஒருவருக்கொருவர் கொல்ல அல்லது பாறைகளிலிருந்து ஓட முயற்சிக்கவும்.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "< ${PICKUP} > கொடியைப் பிடிக்க பிக்-அப் பொத்தானைப் பயன்படுத்தவும்", + "Whip back and forth to get more distance on your throws..": "உங்கள் வீசுதல்களில் அதிக தூரத்தைப் பெற முன்னும் பின்னுமாக அடிக்கவும்..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "உங்கள் குத்துக்களை இடது அல்லது வலது பக்கம் சுழற்றுவதன் மூலம் 'இலக்கு' செய்யலாம்.\nகெட்டவர்களை விளிம்பிலிருந்து தட்டுவதற்கு அல்லது ஹாக்கியில் அடிப்பதற்கு இது பயனுள்ளதாக இருக்கும்.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "ஒரு வெடிகுண்டு எப்போது வெடிக்கும் என்பதை நீங்கள் தீர்மானிக்க முடியும்\nஅதன் உருகியில் இருந்து தீப்பொறிகளின் நிறம்: மஞ்சள்..ஆரஞ்சு..சிவப்பு..பூம்.", + "You can throw bombs higher if you jump just before throwing.": "எறிவதற்கு சற்று முன் குதித்தால் குண்டுகளை உயரமாக வீசலாம்.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "விஷயங்களில் உங்கள் தலையை அசைக்கும்போது நீங்கள் சேதமடைகிறீர்கள்,\nஎனவே விஷயங்களில் உங்கள் தலையை அசைக்காமல் இருக்க முயற்சி செய்யுங்கள்.", + "Your punches do much more damage if you are running or spinning.": "நீங்கள் ஓடினால் அல்லது சுழன்று கொண்டிருந்தால் உங்கள் குத்துக்கள் அதிக சேதத்தை ஏற்படுத்தும்." + } + }, + "trophiesRequiredText": "இதற்கு குறைந்தபட்சம் ${NUMBER} கோப்பைகள் தேவை.", + "trophiesText": "கோப்பைகள்", + "trophiesThisSeasonText": "இந்த சீசனில் கோப்பைகள்", + "tutorial": { + "cpuBenchmarkText": "நகைச்சுவையான வேகத்தில் பயிற்சியை இயக்குதல் (முதன்மையாக CPU வேகத்தை சோதிக்கிறது)", + "phrase01Text": "வணக்கம்!", + "phrase02Text": "${APP_NAME} க்கு வரவேற்கிறோம்!", + "phrase03Text": "உங்கள் தன்மையைக் கட்டுப்படுத்த சில குறிப்புகள் இங்கே:", + "phrase04Text": "${APP_NAME} இல் உள்ள பல விஷயங்கள் PHYSICS அடிப்படையிலானவை.", + "phrase05Text": "உதாரணமாக, நீங்கள் குத்தும் போது,..", + "phrase06Text": "..சேதம் உங்கள் முஷ்டிகளின் வேகத்தை அடிப்படையாகக் கொண்டது.", + "phrase07Text": "பார்க்க? நாங்கள் நகரவில்லை, அதனால் ${NAME} ஐ காயப்படுத்தவில்லை.", + "phrase08Text": "இப்போது அதிக வேகத்தைப் பெற குதித்து சுழலலாம்.", + "phrase09Text": "ஆ, அது சிறந்தது.", + "phrase10Text": "ஓடுவதும் உதவுகிறது.", + "phrase11Text": "இயக்க எந்த பட்டனையும் அழுத்திப் பிடிக்கவும்.", + "phrase12Text": "கூடுதல் அற்புதமான குத்துகளுக்கு, ஓடவும் சுழலவும் முயற்சிக்கவும்.", + "phrase13Text": "அச்சச்சோ; ${NAME} பற்றி மன்னிக்கவும்.", + "phrase14Text": "கொடிகள் .. அல்லது ${NAME} போன்றவற்றை எடுத்து எறியலாம்.", + "phrase15Text": "கடைசியாக, குண்டுகள் உள்ளன.", + "phrase16Text": "வெடிகுண்டுகளை வீசுவது பயிற்சி தேவை.", + "phrase17Text": "அச்சச்சோ! மிகவும் நல்ல வீசுதல் அல்ல.", + "phrase18Text": "நகர்த்துவது தூரத்தை எறிய உதவுகிறது.", + "phrase19Text": "குதிப்பது உயரத்தை எறிய உதவுகிறது.", + "phrase20Text": "உங்கள் குண்டுகளை இன்னும் நீண்ட தூரத்திற்கு \"சவுக்கடி\".", + "phrase21Text": "உங்கள் குண்டுகளை டைமிங் செய்வது தந்திரமானதாக இருக்கலாம்.", + "phrase22Text": "அச்சச்சோ.", + "phrase23Text": "ஒன்றிரண்டு அல்லது இரண்டு நிமிடங்களுக்கு உருகி \"Cooking off\" முயற்சிக்கவும்.", + "phrase24Text": "ஹூரே! நன்றாக போடப்பட்டது", + "phrase25Text": "சரி, அது பற்றி தான்.", + "phrase26Text": "இப்போது அவர்களைப் போய் புடி புலியே!", + "phrase27Text": "உங்கள் பயிற்சியை நினைவில் கொள்ளுங்கள், நீங்கள் உயிருடன் திரும்பி வருவீர்கள்!", + "phrase28Text": "...நன்று,இருக்கலாம்...", + "phrase29Text": "நல்ல அதிர்ஷ்டம்!", + "randomName1Text": "ஃப்ரெட்", + "randomName2Text": "ஹரி", + "randomName3Text": "பில்", + "randomName4Text": "சக்", + "randomName5Text": "பில்", + "skipConfirmText": "டுடோரியலை உண்மையில் தவிர்க்க வேண்டுமா? உறுதிப்படுத்த தட்டவும் அல்லது அழுத்தவும்.", + "skipVoteCountText": "${COUNT}/${TOTAL} வாக்குகளை தவிர்க்கவும்", + "skippingText": "பயிற்சியைத் தவிர்க்கிறது...", + "toSkipPressAnythingText": "(பயிற்சியைத் தவிர்க்க எதையும் தட்டவும் அல்லது அழுத்தவும்)" + }, + "twoKillText": "இரட்டை கொலை!", + "unavailableText": "கிடைக்கவில்லை", + "unconfiguredControllerDetectedText": "கட்டமைக்கப்படாத கட்டுப்படுத்தி கண்டறியப்பட்டது:", + "unlockThisInTheStoreText": "இதை ஸ்டோரில் திறக்க வேண்டும்.", + "unlockThisProfilesText": "${NUM} க்கும் அதிகமான சுயவிவரங்களை உருவாக்க, உங்களுக்கு இது தேவை:", + "unlockThisText": "இதைத் திறக்க, உங்களுக்குத் தேவை:", + "unsupportedHardwareText": "மன்னிக்கவும், இந்த வன்பொருள் விளையாட்டின் உருவாக்கத்தால் ஆதரிக்கப்படவில்லை.", + "upFirstText": "முதலில் மேலே:", + "upNextText": "${COUNT} விளையாட்டில் அடுத்தது:", + "updatingAccountText": "உங்கள் கணக்கை புதுப்பிக்கிறது...", + "upgradeText": "மேம்படுத்தல்", + "upgradeToPlayText": "இதை விளையாட கேம் ஸ்டோரில் \"${PRO}\" ஐத் திறக்கவும்.", + "useDefaultText": "இயல்புநிலையைப் பயன்படுத்தவும்", + "usesExternalControllerText": "இந்த விளையாட்டு உள்ளீட்டிற்கு வெளிப்புற கட்டுப்படுத்தியைப் பயன்படுத்துகிறது.", + "usingItunesText": "ஒலிப்பதிவுக்காக மியூசிக் ஆப் பயன்படுத்துகிறது...", + "v2AccountLinkingInfoText": "V2 கணக்குகளை இணைக்க, 'கணக்கை நிர்வகி' பட்டனைப் பயன்படுத்தவும்.", + "validatingTestBuildText": "சோதனை கட்டத்தை சரிபார்க்கிறது...", + "victoryText": "வெற்றி!", + "voteDelayText": "நீங்கள் மற்றொரு வாக்கை ${NUMBER} வினாடிகளுக்குத் தொடங்க முடியாது", + "voteInProgressText": "வாக்கெடுப்பு ஏற்கனவே நடந்து கொண்டிருக்கிறது.", + "votedAlreadyText": "நீங்கள் ஏற்கனவே வாக்களித்துள்ளீர்கள்", + "votesNeededText": "${NUMBER} வாக்குகள் தேவை", + "vsText": "எதிராக.", + "waitingForHostText": "(${HOST} தொடர காத்திருக்கிறது)", + "waitingForPlayersText": "வீரர்கள் சேர காத்திருக்கிறார்கள்...", + "waitingInLineText": "வரிசையில் காத்திருக்கிறேன் (விருந்து நிரம்பியுள்ளது)...", + "watchAVideoText": "ஒரு வீடியோவைப் பாருங்கள்", + "watchAnAdText": "ஒரு விளம்பரத்தைப் பாருங்கள்", + "watchWindow": { + "deleteConfirmText": "\"${REPLAY}\" ஐ நீக்கவா?", + "deleteReplayButtonText": "நீக்கு\nமறு", + "myReplaysText": "என் ரீப்ளேஸ்", + "noReplaySelectedErrorText": "மறுபதிவு தேர்ந்தெடுக்கப்படவில்லை", + "playbackSpeedText": "பின்னணி வேகம்: ${SPEED}", + "renameReplayButtonText": "மறுபெயரிடு\nமறு", + "renameReplayText": "\"${REPLAY}\" என மறுபெயரிடுங்கள்:", + "renameText": "மறுபெயரிடு", + "replayDeleteErrorText": "ரீப்ளேயை நீக்குவதில் பிழை.", + "replayNameText": "ரீப்ளே பெயர்", + "replayRenameErrorAlreadyExistsText": "அந்த பெயரில் ஒரு ரீப்ளே ஏற்கனவே உள்ளது.", + "replayRenameErrorInvalidName": "மறுபடியும் மறுபெயரிட முடியாது; தவறான பெயர்.", + "replayRenameErrorText": "மறுபெயருக்கு மறுபெயரிடுவதில் பிழை.", + "sharedReplaysText": "பகிரப்பட்ட ரீப்ளேஸ்", + "titleText": "பார்க்க", + "watchReplayButtonText": "பார்க்க\nமறு" + }, + "waveText": "அலை", + "wellSureText": "சரி நிச்சயமாக!", + "whatIsThisText": "இது என்ன?", + "wiimoteLicenseWindow": { + "titleText": "டார்வின் ரிமோட் பதிப்புரிமை" + }, + "wiimoteListenWindow": { + "listeningText": "வைமோட்களைக் கேட்கிறது...", + "pressText": "வைமோட் பட்டன்கலை 1 மற்றும் 2 ஐ ஒரே நேரத்தில் அழுத்தவும்.", + "pressText2": "மோஷன் பிளஸ் உள்ளமைக்கப்பட்ட புதிய வைமோட்களில், அதற்குப் பின்னால் உள்ள சிவப்பு 'ஒத்திசைவு' பொத்தானை அழுத்தவும்." + }, + "wiimoteSetupWindow": { + "copyrightText": "டார்வின் ரிமோட் பதிப்புரிமை", + "listenText": "கேளுங்கள்", + "macInstructionsText": "உங்கள் வை முடக்கப்பட்டு, ப்ளூடூத் இயக்கப்பட்டிருப்பதை உறுதிசெய்க\nஉங்கள் மேக்கில், 'கேளுங்கள்' என்பதை அழுத்தவும். Wiimote ஆதரவு முடியும்\nசற்று மெல்லியதாக இருக்கும், எனவே நீங்கள் சில முறை முயற்சி செய்ய வேண்டியிருக்கும்\nநீங்கள் ஒரு இணைப்பைப் பெறுவதற்கு முன்.\n\nபுளூடூத் 7 இணைக்கப்பட்ட சாதனங்களை கையாள வேண்டும்,\nஇருந்தாலும் உங்கள் மைலேஜ் மாறுபடலாம்.\n\nBombSquad அசல் Wiimotes, Nunchuks ஐ ஆதரிக்கிறது,\nமற்றும் கிளாசிக் கன்ட்ரோலர்.\nபுதிய Wii ரிமோட் பிளஸ் இப்போது கூட வேலை செய்கிறது\nஆனால் இணைப்புகளுடன் அல்ல.", + "thanksText": "டார்வின் ரிமோட் குழுவுக்கு நன்றி\nஇதை சாத்தியப்படுத்தியதற்காக.", + "titleText": "விமோட் அமைப்பு" + }, + "winsPlayerText": "${NAME} வெற்றி!", + "winsTeamText": "${NAME} வெற்றி!", + "winsText": "${NAME} வெற்றி!", + "workspaceSyncErrorText": "${WORKSPACE} ஐ ஒத்திசைப்பதில் பிழை. விவரங்களுக்கு பதிவைப் பார்க்கவும்.", + "workspaceSyncReuseText": "${WORKSPACE} ஐ ஒத்திசைக்க முடியவில்லை. முந்தைய ஒத்திசைக்கப்பட்ட பதிப்பை மீண்டும் பயன்படுத்துகிறது.", + "worldScoresUnavailableText": "உலக ஸ்கோர் கிடைக்கவில்லை.", + "worldsBestScoresText": "உலகின் சிறந்த மதிப்பெண்கள்", + "worldsBestTimesText": "உலகின் சிறந்த நேரங்கள்", + "xbox360ControllersWindow": { + "getDriverText": "Driver ஐ பெரு", + "macInstructions2Text": "கட்டுப்படுத்திகளை கம்பியில்லாமல் பயன்படுத்த, உங்களுக்கு ரிசீவரும் தேவை\nவிண்டோஸிற்கான எக்ஸ்பாக்ஸ் 360 வயர்லெஸ் கன்ட்ரோலருடன் வருகிறது.\nஒரு ரிசீவர் உங்களை 4 கட்டுப்படுத்திகளை இணைக்க அனுமதிக்கிறது.\n\nமுக்கியமானது: 3 வது தரப்பு பெறுநர்கள் இந்த டிரைவருடன் வேலை செய்ய மாட்டார்கள்;\nஉங்கள் ரிசீவர் அதில் 'மைக்ரோசாப்ட்' என்று கூறுவதை உறுதி செய்து கொள்ளுங்கள், 'எக்ஸ்பாக்ஸ் 360' அல்ல.\nமைக்ரோசாப்ட் இனி தனித்தனியாக விற்காது, எனவே நீங்கள் பெற வேண்டும்\nகட்டுப்பாட்டாளருடன் தொகுக்கப்பட்ட ஒன்று அல்லது வேறு ஈபேயைத் தேடுங்கள்.\n\nஇது உங்களுக்கு பயனுள்ளதாக இருந்தால், தயவுசெய்து ஒரு நன்கொடையைக் கருத்தில் கொள்ளவும்\nஅவரது தளத்தில் டிரைவர் டெவலப்பர்.", + "macInstructionsText": "எக்ஸ்பாக்ஸ் 360 கட்டுப்படுத்திகளைப் பயன்படுத்த, நீங்கள் நிறுவ வேண்டும்\nமேக் டிரைவர் கீழே உள்ள இணைப்பில் கிடைக்கிறது.\nஇது கம்பி மற்றும் வயர்லெஸ் கட்டுப்படுத்திகளுடன் வேலை செய்கிறது.", + "ouyaInstructionsText": "BombSquad உடன் கம்பி எக்ஸ்பாக்ஸ் 360 கட்டுப்படுத்திகளைப் பயன்படுத்த, வெறுமனே\nஅவற்றை உங்கள் சாதனத்தின் USB போர்ட்டில் செருகவும். நீங்கள் ஒரு USB ஹப் பயன்படுத்தலாம்\nபல கட்டுப்படுத்திகளை இணைக்க.\n\nவயர்லெஸ் கன்ட்ரோலர்களைப் பயன்படுத்த உங்களுக்கு வயர்லெஸ் ரிசீவர் தேவை,\n\"விண்டோஸிற்கான எக்ஸ்பாக்ஸ் 360 வயர்லெஸ் கன்ட்ரோலர்\" இன் ஒரு பகுதியாக கிடைக்கிறது\nதொகுப்பு அல்லது தனித்தனியாக விற்கப்படுகிறது. ஒவ்வொரு ரிசீவரும் USB போர்ட்டில் செருகப்படுகிறது மற்றும்\n4 வயர்லெஸ் கட்டுப்படுத்திகளை இணைக்க உங்களை அனுமதிக்கிறது.", + "titleText": "${APP_NAME} உடன் எக்ஸ்பாக்ஸ் 360 கட்டுப்பாட்டுகளைப் பயன்படுத்துதல்:" + }, + "yesAllowText": "ஆம், அனுமதி!", + "yourBestScoresText": "உங்கள் சிறந்த மதிப்பெண்கள்", + "yourBestTimesText": "உங்கள் சிறந்த நேரங்கள்" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/thai.json b/dist/ba_data/data/languages/thai.json new file mode 100644 index 0000000..6f00632 --- /dev/null +++ b/dist/ba_data/data/languages/thai.json @@ -0,0 +1,1876 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "ชื่อบัญชีต้องไม่มีอิโมจิหรือตัวอักษรพิเศษอื่นๆ", + "accountsText": "บัญชี", + "achievementProgressText": "ผ่านความสำเร็จ: ${COUNT} จาก ${TOTAL}", + "campaignProgressText": "ความคืบหน้าในภารกิจ [ยาก]: ${PROGRESS}", + "changeOncePerSeason": "คุณสามารถเปลี่ยนได้เพียงครั้งเดียวต่อฤดูกาล", + "changeOncePerSeasonError": "คุณต้องรอจนกว่าฤดูกาลหน้าจะเปลี่ยนอีก (${NUM} days)", + "customName": "ชื่อที่กำหนดเอง", + "googlePlayGamesAccountSwitchText": "หากคุณต้องการใช้บัญชี Google อื่น\nใช้แอป Google Play Games เพื่อเปลี่ยน", + "linkAccountsEnterCodeText": "ใส่รหัส", + "linkAccountsGenerateCodeText": "สร้างรหัส", + "linkAccountsInfoText": "(ใช้ความคืบหน้าร่วมกันกับแพลตฟอร์มอื่นๆ)", + "linkAccountsInstructionsNewText": "หากต้องการเชื่อมโยงสองบัญชีให้สร้างรหัสในบัญชีแรกและป้อนรหัสนั้นในวินาที ข้อมูลจากบัญชีที่สองจะถูกแชร์ระหว่างทั้งสอง(ข้อมูลจากบัญชีแรกจะหายไป): ${COUNT} ** .", + "linkAccountsInstructionsText": "เพื่อที่จะผูกทั้งสองบัญชีเข้าด้วยกัน จะต้องสร้างรหัสรหัสหนึ่ง\nแล้วจะต้องใส่รหัสในบัญที่คุณต้องการจะเชื่อมโยงเข้าด้วยกัน\nความคืบหน้าและสิ่งของในคลังของทั้งสองบัญชีจะถูกรวมกัน\nคุณสามารถเชื่อมโยงได้ทั้งหมด ${COUNT} บัญชี\n\nระวัง! หลังจากผูกบัญชีแล้วจะไม่สามารถยกเลิกได้!", + "linkAccountsText": "ผูกบัญชี", + "linkedAccountsText": "บัญชีที่เชื่อมโยงแล้ว", + "manageAccountText": "จัดการบัญชี", + "nameChangeConfirm": "คุณต้องการเปลี่ยนชื่อบัญชีของคุณเป็น ${NAME} หรือไม่", + "resetProgressConfirmNoAchievementsText": "การทำสิ่งนี้จะรีเซ็ตความคืบหน้าต่างๆ ในโหมด co-op\nและคะแนนดีที่สุดในอุปกรณ์นี้ (แต่จะไม่รีเซ็ตตั๋วของคุณ) \nการทำสิ่งนี้ไม่สามารถยกเลิกได้! คุณแน่ใจหรือไม่?", + "resetProgressConfirmText": "การทำสิ่งนี้จะรีเซ็ตความคืบหน้าในโหมด co-op,\nความสำเร็จและคะแนนดีที่สุดในอุปกรณ์นี้\n(แต่จะไม่รีเซ็ตตั๋วของคุณ) การทำสิ่งนี้จะ\nไม่สามารถยกเลิกได้! คุณแน่ใจหรือไม่?", + "resetProgressText": "รีเซ็ตความคืบหน้า", + "setAccountName": "ตั้งชื่อบัญชี", + "setAccountNameDesc": "เลือกชื่อที่จะแสดงสำหรับบัญชีของคุณคุณสามารถใช้ชื่อจากหนึ่งในการเชื่อมโยงของคุณบัญชีหรือสร้างชื่อที่กำหนดเองที่ไม่ซ้ำกัน:{Thanakorn}", + "signInInfoText": "เข้าสู่ระบบเพื่อเก็บตั๋วในการเล่นแบบออนไลน์,\nและแบ่งปันความคืบหน้าของคุณกับอุปกรณ์อื่นๆ", + "signInText": "ลงชื่อเข้าใช้", + "signInWithDeviceInfoText": "(บัญชีอัตโนมัติที่ใช้ได้เฉพาะในอุปกรณ์นี้)", + "signInWithDeviceText": "เข้าสู่ระบบจากอุปกรณ์นี้", + "signInWithGameCircleText": "เข้าสู่ระบบด้วยบัญชี Game Circle", + "signInWithGooglePlayText": "ลงชื่อเข้าใช้ด้วยบัญชี Google Play", + "signInWithTestAccountInfoText": "(บัญชีทดลอง;เลือกตัวเลือกนี้เพื่อไปต่อ)", + "signInWithTestAccountText": "ลงชื่อเข้าใช้เพื่อทดลอง", + "signInWithV2InfoText": "(บัญชีที่ใช้งานได้กับทุกแพลตฟอร์ม)", + "signInWithV2Text": "ลงชื่อเข้าใช้ด้วยบัญชี BombSquad", + "signOutText": "ออกจากระบบ", + "signingInText": "กำลังลงชื่อเข้าใช้...", + "signingOutText": "กำลังออกจากระบบ...", + "ticketsText": "ตั๋ว: ${COUNT}", + "titleText": "บัญชี", + "unlinkAccountsInstructionsText": "เลือกบัญชีที่จะยกเลิกการเชื่อมโยง", + "unlinkAccountsText": "ยกเลิกการเชื่อมโยงบัญชี", + "v2LinkInstructionsText": "ใช้ลิงก์นี้เพื่อสร้างบัญชีหรือลงชื่อเข้าใช้", + "viaAccount": "ผ่านบัญชี ${NAME}", + "youAreSignedInAsText": "คุณลงชื่อเข้าใช้ในบัญชี:" + }, + "achievementChallengesText": "ท้าทายความสำเร็จ", + "achievementText": "ความสำเร็จ", + "achievements": { + "Boom Goes the Dynamite": { + "description": "ฆ่าศัตรู 3 คนด้วย TNT", + "descriptionComplete": "ฆ่าศัตรู 3 คนด้วย TNT แล้ว", + "descriptionFull": "ฆ่าศัตรู ${LEVEL} 3 คนด้วย TNT", + "descriptionFullComplete": "ฆ่าศัตรู 3 คน ด้วย TNT ใน ${LEVEL}", + "name": "ระเบิดดังสนั่นหวั่นไหวจากไดนาไมต์" + }, + "Boxer": { + "description": "ชนะโดยไม่ใช้ระเบิด", + "descriptionComplete": "ชนะโดยไม่ใช้ระเบิดแล้ว", + "descriptionFull": "ชนะ ${LEVEL} โดยไม่ใช้ระเบิด", + "descriptionFullComplete": "ชนะ ${LEVEL} โดยไม่ใช้ระเบิดแล้ว", + "name": "นักมวย" + }, + "Dual Wielding": { + "descriptionFull": "เชื่อมต่อกับคอนโทรลเลอร์สองตัว", + "descriptionFullComplete": "เชื่อมต่อกับคอนโทรลเลอร์สองตัวแล้ว", + "name": "ถนัดสองมือ" + }, + "Flawless Victory": { + "description": "ชนะโดยไม่ได้รับความเสียหายเลย", + "descriptionComplete": "ชนะแล้วโดยไม่ได้รับความเสียหายเลย", + "descriptionFull": "ชนะ ${LEVEL} โดยไม่ได้รับความเสียหายเลย", + "descriptionFullComplete": "ชนะ ${LEVEL} แล้วโดยไม่ได้รับความเสียหายเลย", + "name": "ชนะอย่างไร้ที่ติ" + }, + "Free Loader": { + "descriptionFull": "เริ่มเล่นโหมด Free-For-All กับผู้เล่นมากกว่า 2 คน", + "descriptionFullComplete": "เริ่มเล่นโหมด Free-For-All กับผู้เล่นมากกว่า 2 คนแล้ว", + "name": "เล่นเดี่ยว" + }, + "Gold Miner": { + "description": "ฆ่าศัตรู 6 คนด้วยกับระเบิด", + "descriptionComplete": "ฆ่าศัตรู 6 คนด้วยกับระเบิดแล้ว", + "descriptionFull": "ฆ่าศัตรู 6 คนด้วยกับระเบิดใน ${LEVEL}", + "descriptionFullComplete": "ฆ่าศัตรู 6 คนด้วยกับระเบิดใน ${LEVEL} แล้ว", + "name": "นักขุดเหมืองทอง" + }, + "Got the Moves": { + "description": "ชนะโดยไม่ต้องใช้หมัดหรือระเบิด", + "descriptionComplete": "ชนะโดยไม่ต้องใช้หมัดหรือระเบิดแล้ว", + "descriptionFull": "ชนะ ${LEVEL} โดยไม่ต้องใช้หมัดหรือระเบิด", + "descriptionFullComplete": "ชนะ ${LEVEL} โดยไม่ต้องใช้หมัดหรือระเบิดแล้ว", + "name": "เร่งรีบ" + }, + "In Control": { + "descriptionFull": "เชื่อมต่อกับคอนโทรลเลอร์", + "descriptionFullComplete": "เชื่อมต่อกับคอนโทรลเลอร์แล้ว", + "name": "อยู่ในการควบคุม" + }, + "Last Stand God": { + "description": "ทำคะแนน 1000 คะแนน", + "descriptionComplete": "ทำคะแนน 1000 คะแนนแล้ว", + "descriptionFull": "ทำคะแนน 1000 คะแนนใน ${LEVEL}", + "descriptionFullComplete": "ทำคะแนน 1000 คะแนนใน ${LEVEL} แล้ว", + "name": "เทพ ${LEVEL}" + }, + "Last Stand Master": { + "description": "ทำคะแนน 250 คะแนน", + "descriptionComplete": "ทำคะแนน 250 คะแนนแล้ว", + "descriptionFull": "ทำคะแนน 250 คะแนนใน ${LEVEL}", + "descriptionFullComplete": "ทำคะแนน 250 คะแนนใน ${LEVEL} แล้ว", + "name": "ผู้เชี่ยวชาญ ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "ทำคะแนน 500 คะแนน", + "descriptionComplete": "ทำคะแนน 500 คะแนนแล้ว", + "descriptionFull": "ทำคะแนน 500 คะแนนใน ${LEVEL}", + "descriptionFullComplete": "ทำคะแนน 500 คะแนนใน ${LEVEL} แล้ว", + "name": "ผู้วิเศษ ${LEVEL}" + }, + "Mine Games": { + "description": "ฆ่าศัตรู 3 คนด้วยกับระเบิด", + "descriptionComplete": "ฆ่าศัตรู 3 คนด้วยกับระเบิดแล้ว", + "descriptionFull": "ฆ่าศัตรู 3 คนด้วยกับระเบิดใน ${LEVEL}", + "descriptionFullComplete": "ฆ่าศัตรู 3 คนด้วยกับระเบิดใน ${LEVEL} แล้ว", + "name": "เกมกับระเบิด" + }, + "Off You Go Then": { + "description": "โยนศัตรู 3 คนลงออกจากแมพ", + "descriptionComplete": "โยนศัตรู 3 คนลงออกจากแมพแล้ว", + "descriptionFull": "โยนศัตรู 3 คนลงออกจากแมพใน ${LEVEL}", + "descriptionFullComplete": "โยนศัตรู 3 คนลงออกจากแมพใน ${LEVEL} แล้ว", + "name": "ออกไปให้พ้น" + }, + "Onslaught God": { + "description": "ทำคะแนน 5000 คะแนน", + "descriptionComplete": "ทำคะแนน 5000 คะแนนแล้ว", + "descriptionFull": "ทำคะแนน 5000 คะแนนใน ${LEVEL}", + "descriptionFullComplete": "ทำคะแนน 5000 คะแนนใน ${LEVEL} แล้ว", + "name": "เทพ ${LEVEL}" + }, + "Onslaught Master": { + "description": "ทำคะแนน 500 คะแนน", + "descriptionComplete": "ทำคะแนน 500 คะแนนแล้ว", + "descriptionFull": "ทำคะแนน 500 คะแนนใน ${LEVEL}", + "descriptionFullComplete": "ทำคะแนน 500 คะแนนใน ${LEVEL} แล้ว", + "name": "ผู้เชี่ยวชาญ ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "เอาชนะทุกรอบในด่าน", + "descriptionComplete": "เอาชนะทุกรอบในด่านแล้ว", + "descriptionFull": "เอาชนะทุกรอบใน ${LEVEL}", + "descriptionFullComplete": "เอาชนะทุกรอบใน ${LEVEL} แล้ว", + "name": "ชนะ ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "ทำคะแนน 1000 คะแนน", + "descriptionComplete": "ทำคะแนน 1000 คะแนนแล้ว", + "descriptionFull": "ทำคะแนน 1000 คะแนนใน ${LEVEL}", + "descriptionFullComplete": "ทำคะแนน 1000 คะแนนใน ${LEVEL} แล้ว", + "name": "ผู้วิเศษ ${LEVEL}" + }, + "Precision Bombing": { + "description": "ชนะโดยไม่เก็บไอเทมวิเศษ", + "descriptionComplete": "ชนะโดยไม่เก็บไอเทมวิเศษแล้ว", + "descriptionFull": "ชนะ ${LEVEL} โดยไม่เก็บไอเทมวิเศษ", + "descriptionFullComplete": "ชนะ ${LEVEL} โดยไม่เก็บไอเทมวิเศษแล้ว", + "name": "นักระเบิดที่แม่นยำ" + }, + "Pro Boxer": { + "description": "ชนะโดยไม่ใช้ระเบิด", + "descriptionComplete": "ชนะโดยไม่ใช้ระเบิดแล้ว", + "descriptionFull": "ชนะ ${LEVEL} โดยไม่ใช้ระเบิด", + "descriptionFullComplete": "ชนะ ${LEVEL} โดยไม่ใช้ระเบิดแล้ว", + "name": "นักมวยมือโปร" + }, + "Pro Football Shutout": { + "description": "ชนะโดยไม่ให้ศัตรูทำคะแนน", + "descriptionComplete": "ชนะโดยไม่ให้ศัตรูทำคะแนนแล้ว", + "descriptionFull": "ชนะ ${LEVEL} โดยไม่ให้ศัตรูทำคะแนน", + "descriptionFullComplete": "ชนะ ${LEVEL} โดยไม่ให้ศัตรูทำคะแนนแล้ว", + "name": "${LEVEL} ห้ามเข้า" + }, + "Pro Football Victory": { + "description": "ชนะเกม", + "descriptionComplete": "ชนะเกมแล้ว", + "descriptionFull": "ชนะเกมใน ${LEVEL}", + "descriptionFullComplete": "ชนะเกมใน ${LEVEL} แล้ว", + "name": "ชนะ ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "เอาชนะทุกรอบในด่าน", + "descriptionComplete": "เอาชนะทุกรอบในด่านแล้ว", + "descriptionFull": "เอาชนะทุกรอบใน ${LEVEL}", + "descriptionFullComplete": "เอาชนะทุกรอบใน ${LEVEL}", + "name": "ชนะ ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "เอาชนะทุกรอบในด่าน", + "descriptionComplete": "เอาชนะทุกรอบในด่านแล้ว", + "descriptionFull": "เอาชนะทุกรอบใน ${LEVEL}", + "descriptionFullComplete": "เอาชนะทุกรอบใน ${LEVEL} แล้ว", + "name": "ชนะ ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "ชนะโดยไม่ให้ศัตรูทำคะแนน", + "descriptionComplete": "ชนะโดยไม่ให้ศัตรูทำคะแนนแล้ว", + "descriptionFull": "ชนะ ${LEVEL} โดยไม่ให้ศัตรูทำคะแนน", + "descriptionFullComplete": "ชนะ ${LEVEL} โดยไม่ให้ศัตรูทำคะแนนแล้ว", + "name": "${LEVEL} ไม่ให้เข้า" + }, + "Rookie Football Victory": { + "description": "ชนะเกม", + "descriptionComplete": "ชนะเกมแล้ว", + "descriptionFull": "ชนะเกมใน ${LEVEL}", + "descriptionFullComplete": "ชนะเกมใน ${LEVEL} แล้ว", + "name": "ชนะ ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "เอาชนะทุกรอบในด่าน", + "descriptionComplete": "เอาชนะทุกรอบในด่านแล้ว", + "descriptionFull": "เอาชนะทุกรอบใน ${LEVEL}", + "descriptionFullComplete": "เอาชนะทุกรอบใน ${LEVEL} แล้ว", + "name": "ชนะ ${LEVEL}" + }, + "Runaround God": { + "description": "ทำคะแนน 2000 คะแนน", + "descriptionComplete": "ทำคะแนน 2000 คะแนนแล้ว", + "descriptionFull": "ทำคะแนน 2000 คะแนนใน ${LEVEL}", + "descriptionFullComplete": "ทำคะแนน 2000 คะแนนใน ${LEVEL} แล้ว", + "name": "เทพ ${LEVEL}" + }, + "Runaround Master": { + "description": "ทำคะแนน 500 คะแนน", + "descriptionComplete": "ทำคะแนน 500 คะแนนแล้ว", + "descriptionFull": "ทำคะแนน 500 คะแนนใน ${LEVEL}", + "descriptionFullComplete": "ทำคะแนน 500 คะแนนใน ${LEVEL} แล้ว", + "name": "ผู้เชี่ยวชาญ ${LEVEL}" + }, + "Runaround Wizard": { + "description": "ทำคะแนน 1000 คะแนน", + "descriptionComplete": "ทำคะแนน 1000 คะแนนแล้ว", + "descriptionFull": "ทำคะแนน 1000 คะแนนใน ${LEVEL}", + "descriptionFullComplete": "ทำคะแนน 1000 คะแนนใน ${LEVEL} แล้ว", + "name": "ผู้วิเศษ ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "แบ่งปันเกมกับเพื่อนสำเร็จ", + "descriptionFullComplete": "ได้แบ่งปันเกมกับเพื่อนสำเร็จแล้ว", + "name": "แบ่งปันคือการดูแล" + }, + "Stayin' Alive": { + "description": "ชนะโดยไม่ตายเลย", + "descriptionComplete": "ชนะโดยไม่ตายเลยแล้ว", + "descriptionFull": "ชนะ ${LEVEL} โดยไม่ตายเลย", + "descriptionFullComplete": "ชนะ ${LEVEL} โดยไม่ตายเลยแล้ว", + "name": "ยังมีชีวิตอยู่" + }, + "Super Mega Punch": { + "description": "ทำดาเมจ 100% ด้วยหมัดเดียว", + "descriptionComplete": "ทำดาเมจ 100% ด้วยหมัดเดียวแล้ว", + "descriptionFull": "ทำดาเมจ 100% ด้วยหมัดเดียวใน ${LEVEL}", + "descriptionFullComplete": "ทำดาเมจ 100% ด้วยหมัดเดียวใน ${LEVEL} แล้ว", + "name": "สุดยอดแห่งหมัด" + }, + "Super Punch": { + "description": "ทำดาเมจ 50% ด้วยหมัดเดียว", + "descriptionComplete": "ทำดาเมจ 50% ด้วยหมัดเดียวแล้ว", + "descriptionFull": "ทำดาเมจ 50% ด้วยหมัดเดียวใน ${LEVEL}", + "descriptionFullComplete": "ทำดาเมจ 50% ด้วยหมัดเดียวใน ${LEVEL} แล้ว", + "name": "หมัดที่รุนแรง" + }, + "TNT Terror": { + "description": "ฆ่าศัตรู 6 คนด้วย TNT", + "descriptionComplete": "ฆ่าศัตรู 6 คนด้วย TNT แล้ว", + "descriptionFull": "ฆ่าศัตรู 6 คนด้วย TNT ใน ${LEVEL}", + "descriptionFullComplete": "ฆ่าศัตรู 6 คนด้วย TNT ใน ${LEVEL} แล้ว", + "name": "นักวางระเบิด" + }, + "Team Player": { + "descriptionFull": "เริ่มเล่นเกมแบบทีมกับผู้เล่น 4 คนขึ้นไป", + "descriptionFullComplete": "เริ่มเล่นเกมแบบทีมกับผู้เล่น 4 คนขึ้นไปแล้ว", + "name": "เล่นเป็นทีม" + }, + "The Great Wall": { + "description": "หยุดศัตรูทุกคน", + "descriptionComplete": "หยุดศัตรูทุกคนแล้ว", + "descriptionFull": "หยุดศัตรูทุกคนใน ${LEVEL}", + "descriptionFullComplete": "หยุดศัตรูทุกคนใน ${LEVEL} แล้ว", + "name": "กำแพงที่แข็งแกร่ง" + }, + "The Wall": { + "description": "หยุดศัตรูทุกคน", + "descriptionComplete": "หยุดศัตรูทุกคนแล้ว", + "descriptionFull": "หยุดศัตรูทุกคนใน ${LEVEL}", + "descriptionFullComplete": "หยุดศัตรูทุกคนใน ${LEVEL} แล้ว", + "name": "กำแพง" + }, + "Uber Football Shutout": { + "description": "ชนะโดยไม่ให้ศัตรูทำคะแนน", + "descriptionComplete": "ชนะโดยไม่ให้ศัตรูทำคะแนนแล้ว", + "descriptionFull": "ชนะ ${LEVEL} โดยไม่ให้ศัตรูทำคะแนน", + "descriptionFullComplete": "ชนะ ${LEVEL} โดยไม่ให้ศัตรูทำคะแนนแล้ว", + "name": "${LEVEL} ไม่ให้เข้า" + }, + "Uber Football Victory": { + "description": "ชนะเกม", + "descriptionComplete": "ชนะเกมแล้ว", + "descriptionFull": "ชนะเกมใน ${LEVEL}", + "descriptionFullComplete": "ชนะเกมใน ${LEVEL} แล้ว", + "name": "ชนะ ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "เอาชนะทุกรอบในด่าน", + "descriptionComplete": "เอาชนะทุกรอบในด่านแล้ว", + "descriptionFull": "เอาชนะทุกรอบใน ${LEVEL}", + "descriptionFullComplete": "เอาชนะทุกรอบใน ${LEVEL} แล้ว", + "name": "ชนะ ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "เอาชนะทุกรอบในด่าน", + "descriptionComplete": "เอาชนะทุกรอบในด่านแล้ว", + "descriptionFull": "เอาชนะทุกรอบใน ${LEVEL}", + "descriptionFullComplete": "เอาชนะทุกรอบใน ${LEVEL} แล้ว", + "name": "ชนะ ${LEVEL}" + } + }, + "achievementsRemainingText": "ความสำเร็จที่ยังเหลืออยู่:", + "achievementsText": "ความสำเร็จ", + "achievementsUnavailableForOldSeasonsText": "ขออภัย, ความสำเร็จนี้ไม่ได้มีอยู่ในฤดูกาลเก่า", + "activatedText": "เปิดใช้งาน ${THING} แล้ว", + "addGameWindow": { + "getMoreGamesText": "รับเกมเพิ่มเติม", + "titleText": "เพิ่มเกม" + }, + "allowText": "ยอมรับ", + "alreadySignedInText": "บัญชีของคุณลงชื่อเข้าใช้จากอุปกรณ์อื่น\nโปรดเปลี่ยนบัญชีหรือปิดเกมของคุณ\nอุปกรณ์อื่นและลองอีกครั้ง", + "apiVersionErrorText": "ไม่สามารถโหลดโมดูล ${NAME} ได้; มันอยู่ในเวอร์ชั่น api ${VERSION_USED}; แต่เราต้องการเวอร์ชั่น ${VERSION_REQUIRED}", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"อัติโนมัติ\" เปิดสิ่งนี้เฉพาะตอนที่เสียบหูฟังอยู่เท่านั้น)", + "headRelativeVRAudioText": "ระดับเสียงเครื่องสวมหัว VR", + "musicVolumeText": "ระดับเสียงเพลง", + "soundVolumeText": "ระดับเสียงประกอบ", + "soundtrackButtonText": "เพลงประกอบ", + "soundtrackDescriptionText": "(นำเพลงของคุณเองมาใช้ในการเล่นเกม)", + "titleText": "การตั้งค่าเสียง" + }, + "autoText": "อัติโนมัติ", + "backText": "ย้อนกลับ", + "banThisPlayerText": "ผู้เล่นคนนี้โดนแบน", + "bestOfFinalText": "ดีที่สุดจาก ${COUNT} รอบ", + "bestOfSeriesText": "ดีที่สุดจาก ${COUNT} ฤดูกาล:", + "bestRankText": "อันดับที่ดีที่สุดของคุณคือ #${RANK}", + "bestRatingText": "เรตติ้งที่ดีที่สุดของคุณคือ ${RATING}", + "bombBoldText": "'ระเบิด'", + "bombText": "ระเบิด", + "boostText": "บูสท์", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} กำลังค่าในตัวแอพเอง", + "buttonText": "ปุ่ม", + "canWeDebugText": "คุณอยากให้ BombSquad แจ้งข้อผิดพลาด ปัญหา\nและข้อมูลการใช้งานทั่วไปกับผู้สร้างโดยอัติโนมัติหรือไม่?\n\nข้อมูลนี้จะไม่เกี่ยวข้องกับข้อมูลส่วนตัวและจะช่วยให้\nสามารถเล่นเกมได้อย่างราบรื่นและไม่มีข้อผิดพลาด", + "cancelText": "ยกเลิก", + "cantConfigureDeviceText": "ขออภัย, ${DEVICE} ไม่สามารถตั้งค่าได้", + "challengeEndedText": "การท้าทายนี้ได้จบลงแล้ว", + "chatMuteText": "ปิดเสียงแชท", + "chatMutedText": "ปิดเสียงการแชท", + "chatUnMuteText": "ยกเลิกการปิดเสียงแขท", + "choosingPlayerText": "<กำลังเลือกผู้เล่น>", + "completeThisLevelToProceedText": "คุณต้องผ่านด่านนี้\nก่อนจึงจะไปต่อได้!", + "completionBonusText": "รางวัลการผ่านด่าน", + "configControllersWindow": { + "configureControllersText": "ตั้งค่าคอนโทรลเลอร์", + "configureKeyboard2Text": "ตั้งค่าคีย์บอร์ดผู้เล่นคนที่ 2", + "configureKeyboardText": "ตั้งค่าคีย์บอร์ด", + "configureMobileText": "ใช้โทรศัพท์มือถือเป็นคอนโทรลเลอร์", + "configureTouchText": "ตั้งค่าหน้าจอสัมผัส", + "ps3Text": "คอนโทรลเลอร์ PS3", + "titleText": "คอนโทรลเลอร์", + "wiimotesText": "Wiimotes", + "xbox360Text": "คอนโทรลเลอร์ Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "โน๊ต: คอนโทรลเลอร์ที่สนับสนุนจะแตกต่างกันไปตามอุปกรณ์และเวอร์ชั่นแอนดรอยด์", + "pressAnyButtonText": "กดปุ่มใดก็ได้บนคอนโทรลเลอร์\nที่คุณต้องการจะตั้งค่า...", + "titleText": "ตั้งค่าคอนโทรลเลอร์" + }, + "configGamepadWindow": { + "advancedText": "ขั้นสูง", + "advancedTitleText": "การตั้งค่าคอนโทรลเลอร์ขั้นสูง", + "analogStickDeadZoneDescriptionText": "(เปิดสิ่งนี้ถ้าตัวละครของคุณ 'ซัดเซ' เวลาที่คุณปล่อยการควบคุม)", + "analogStickDeadZoneText": "Dead Zone จอยอนาล็อก", + "appliesToAllText": "(ใช้ได้กับทุกคอนโทรลเลอร์ที่เป็นประเภทนี้)", + "autoRecalibrateDescriptionText": "(เปิดสิ่งนี้ถ้าตัวละครของคุณขยับได้ไม่เร็วเท่าความเร็วสูงสุด)", + "autoRecalibrateText": "ปรับจอยอนาล็อกอัติโนมัติ", + "axisText": "แกน", + "clearText": "เคลียร์", + "dpadText": "dpad", + "extraStartButtonText": "ปุ่มสตาร์ทพิเศษ", + "ifNothingHappensTryAnalogText": "ถ้าไม่เกิดอะไรขึ้น, ลองกำหนดเป็นจอยอนาล็อกแทน", + "ifNothingHappensTryDpadText": "ถ้าไม่เกิดอะไรขึ้น, ลองกำหนดเป็น dpad แทน", + "ignoreCompletelyDescriptionText": "(ป้องกันคอนโทรลเลอร์ตัวนี้ไม่ให้มีผลกระทบต่อเกมหรือเมนู)", + "ignoreCompletelyText": "ละเว้นเสร็จสมบูรณ์", + "ignoredButton1Text": "ปุ่มที่ละเว้น 1", + "ignoredButton2Text": "ปุ่มที่ละเว้น 2", + "ignoredButton3Text": "ปุ่มที่ละเว้น 3", + "ignoredButton4Text": "ปุ่มที่ละเว้น 4", + "ignoredButtonDescriptionText": "(ใช้สิ่งนี้เพื่อป้องกันปุ่ม 'home' หรือ 'ซิงค์' ไม่ให้มีผลกระทบต่อ UI)", + "pressAnyAnalogTriggerText": "กดปุ่มใดก็ได้บนอนาล็อก...", + "pressAnyButtonOrDpadText": "กดปุ่มใดก็ได้หรือ dpad...", + "pressAnyButtonText": "กดปุ่มใดก็ได้...", + "pressLeftRightText": "กดปุ่มซ้ายหรือขวา...", + "pressUpDownText": "กดปุ่มขึ้นหรือลง...", + "runButton1Text": "ปุ่มวิ่ง 1", + "runButton2Text": "ปุ่มวิ่ง 2", + "runTrigger1Text": "ปุ่มวิ่ง 1", + "runTrigger2Text": "ปุ่มวิ่ง 2", + "runTriggerDescriptionText": "(ปุ่มอนาล็อกที่ทำให้คุณวิ่งในความเร็วที่เปลี่ยนได้))", + "secondHalfText": "ใช้สิ่งนี้เพื่อตั้งค่าให้ใช้คอนโทรลเลอร์\n2 อัน ใน 1 อุปกรณ์ ที่จะแสดงให้เห็น\nว่าใช้คอนโทรลเลอร์เพียงตัวเดียว", + "secondaryEnableText": "ยอมรับ", + "secondaryText": "คอนโทรลเลอร์ตัวที่ 2", + "startButtonActivatesDefaultDescriptionText": "(ปิดสิ่งนี้ถ้าปุ่มสตาร์ทของคุณเป็นมากกว่าปุ่ม 'เมนู')", + "startButtonActivatesDefaultText": "ปุ่มสตาร์ทเปิดวิดเจ็ตเพื้นฐาน", + "titleText": "การตั้งค่าคอนโทรลเลอร์", + "twoInOneSetupText": "การตั้งค่าคอนโทรลเลอร์แบบ 2 ใน 1", + "uiOnlyDescriptionText": "(ป้องกันคอนโทรลเลอร์ตัวนี้ไม่ให้ใช้เข้าร่วมเกม)", + "uiOnlyText": "จำกัดในการใช้เมนู", + "unassignedButtonsRunText": "วิ่งปุ่มที่ไม่ได้ตั้งทั้งหมด", + "unsetText": "<ไม่ได้ตั้ง>", + "vrReorientButtonText": "ปรับทิศทางปุ่ม VR" + }, + "configKeyboardWindow": { + "configuringText": "กำลังตั้งค่า ${DEVICE}", + "keyboard2NoteText": "โน็ต: คีย์บอร์ดส่วนใหญ่สามารถตั้งปุ่มได้ไม่กี่ปุ่มในครั้งเดียว\nดังนั้นการมีคีย์บอร์ดสำหรับผู้เล่นที่ 2 อาจจะทำให้เล่นได้ดีขึ้น\nถ้ามีการแยกคีย์บอร์ดมาสำหรับพวกเขาที่จะใช้\nหรือคุณจะต้องกำหนดปุ่มที่เป็นเอกลักษณ์สำหรับผู้เล่น\nทั้ง 2 คน ในกรณีนั้น" + }, + "configTouchscreenWindow": { + "actionControlScaleText": "มาตราส่วนปุ่มควบคุมการกระทำ", + "actionsText": "การกระทำ", + "buttonsText": "ปุ่ม", + "dragControlsText": "< ลากปุ่มควบคุมเพื่อเปลี่ยนตำแหน่ง >", + "joystickText": "จอยสติ๊ก", + "movementControlScaleText": "มาตราส่วนปุ่มควบคุมการเคลื่อนไหว", + "movementText": "การเคลื่อนไหว", + "resetText": "รีเซ็ต", + "swipeControlsHiddenText": "ซ่อนปุ่มแบบปัด", + "swipeInfoText": "การควบคุมแบบ 'ปัด' จะใช้เวลาเล็กน้อยในการใช้แต่\nมันจะทำให้ควบคุมแบบไม่มองปุ่มควบคุมได้ง่ายขึ้น", + "swipeText": "การปัด", + "titleText": "การตั้งค่าหน้าจอสัมผัส" + }, + "configureItNowText": "จะตั้งค่ามันตอนนี้หรือไม่?", + "configureText": "ตั้งค่า", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "เพื่อผลลัพท์ที่ดีที่สุดคุณจะต้องการไวไฟที่ไม่มีความล่าช้า\nคุณสามารถลดความล่าช้าได้โดยการปิดอุปกรณ์ไร้สาย,\nเล่นให้อยู่ใกล้ๆ กับเครื่องไวไฟ, และการเชื่อมต่อโดยตรง\nกับเจ้าของห้องผ่านอีเธอร์เน็ต", + "explanationText": "เพื่อที่จะใช้สมาร์ทโฟนหรือแท็บเล็ตเป็นคอนโทรลเลอร์ไร้สาย\nติ้งตั้งแอพ \"${REMOTE_APP_NAME}\" บนเครื่องนั้น กี่เครื่องก็ได้ที่\nสามารถเชื่อมต่อกับเกม ${APP_NAME} ผ่านไวไฟ และแอพก็ฟรีอีกด้วย!", + "forAndroidText": "สำหรับแอนดรอยด์:", + "forIOSText": "สำหรับ IOS:", + "getItForText": "รับ ${REMOTE_APP_NAME} สำหรับ IOS ใน Apple App Store\nหรือสำหรับแอนดรอยด์ที่ Google Play Store หรือ Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "การใช้โทรศัพท์มือถือเป็นคอนโทรลเลอร์" + }, + "continuePurchaseText": "จะเล่นต่อหรือไม่?(จ่าย ${PRICE})", + "continueText": "ดำเนินการต่อ", + "controlsText": "การควบคุม", + "coopSelectWindow": { + "activenessAllTimeInfoText": "สิ่งนี้จะไม่ได้ใช้ในการจัดอันดับแบบทุกเวลา", + "activenessInfoText": "การคูณคะแนนนี้จะเพิ่มขึ้นเวลาที่\nคุณเล่นและจะลดลงเวลาที่คุณไม่ได้เล่น", + "activityText": "กิจกรรม", + "campaignText": "โหมดภารกิจ", + "challengesInfoText": "รับรางวัลจากการผ่านมินิเกมส์\n\nเงินรางวัลและความยากจะเพิ่มขึ้นทุกครั้ง\nที่คุณผ่านการท้าทายและจะลดลงเมื่อ\nครบระยะเวลาหนึ่งหรือได้ละทิ้งการท้าทาย", + "challengesText": "การท้าทาย", + "currentBestText": "ผู้เล่นที่ดีที่สุดในขณะนี้", + "customText": "กำหนดเอง", + "entryFeeText": "ค่าใช้จ่าย", + "forfeitConfirmText": "จะละทิ้งการท้าทายนี้หรือไม่?", + "forfeitNotAllowedYetText": "การท้าทายนี้ไม่สามารถละทิ้งได้", + "forfeitText": "ละทิ้ง", + "multipliersText": "การคูณคะแนนเพิ่ม", + "nextChallengeText": "การท้าทายต่อไป", + "nextPlayText": "เล่นครั้งต่อไปได้ใน", + "ofTotalTimeText": "จาก ${TOTAL}", + "playNowText": "เล่นทันที", + "pointsText": "คะแนน", + "powerRankingFinishedSeasonUnrankedText": "(ฤดูกาลที่จบไปแล้วที่คุณไม่ได้อยู่ในอันดับ)", + "powerRankingNotInTopText": "(คุณไม่ได้อยู่ในอันดับสูงสุด ${NUMBER} อันดับ)", + "powerRankingPointsEqualsText": "= ${NUMBER} คะแนน", + "powerRankingPointsMultText": "(x ${NUMBER} คะแนน)", + "powerRankingPointsText": "${NUMBER} คะแนน", + "powerRankingPointsToRankedText": "(${CURRENT} จาก ${REMAINING} คะแนน)", + "powerRankingText": "การจัดอันดับ", + "prizesText": "รางวัล", + "proMultInfoText": "ผู้เล่นที่มีการอัพเกรดเป็น ${PRO} แล้ว\nจะได้รับคะแนนเพิ่ม ${PERCENT}% ในนี้", + "seeMoreText": "มากกว่านี้...", + "skipWaitText": "ข้ามการรอ", + "timeRemainingText": "เวลาที่เหลือ", + "toRankedText": "เพื่อให้อยู่ในอันดับ", + "totalText": "ทั้งหมด", + "tournamentInfoText": "แข่งขันเพื่อให้ได้คะแนนสูงสุด\nกับผู้เล่นคนอื่นๆ ในลีกของคุณ\n\nผู้เล่นที่อยู่ในอันดับสูงสุดจะได้รับ\nรางวัลเมื่อทัวร์นาเมนท์ได้จบลง", + "welcome1Text": "ยินดีต้อนรับสู่ ${LEAGUE} คุณสามารถเพิ่มระดับ\nลีกของคุณการรับเรตติ้งดาว การปลดล็อคความสำเร็จ \nและการชนะทัวร์นาเมนท์ให้ได้รับถ้วยรางวัล", + "welcome2Text": "คุณสามารถได้ตั๋วจากการทำกิจกรรมเดิมๆ ได้\nตัวสามารถใช้ในการปลดล็อคตัวละครใหม่ แผนที่ใหม่\nและมินิเกมใหม่ การใช้เข้าทัวร์นาเมนท์ และอีกหลายอย่าง", + "yourPowerRankingText": "อันดับของคุณ:" + }, + "copyConfirmText": "คัดลอกไปที่คลิปบอร์ดแล้ว", + "copyOfText": "${NAME} ที่ถูกคัดลอก", + "copyText": "คัดลอก", + "createEditPlayerText": "<สร้าง/แก้ไข ผู้เล่น>", + "createText": "สร้าง", + "creditsWindow": { + "additionalAudioArtIdeasText": "เสียงเพิ่มเติม งานออกแบบ และไอเดียโดย ${NAME}", + "additionalMusicFromText": "เพลงประกอบเพิ่มเติมโดย ${NAME}", + "allMyFamilyText": "เพื่อนๆ และครอบครัวของผมที่ช่วยในการทดสอบเกม", + "codingGraphicsAudioText": "การเขียนโปรแกรม กราฟฟิก และเสียงโดย ${NAME}", + "languageTranslationsText": "ผู้ที่แปลภาษา:", + "legalText": "ลิขสิทธ์:", + "publicDomainMusicViaText": "เพลงโดเมนสาธารณะผ่าน ${NAME}", + "softwareBasedOnText": "ซอฟต์แวร์นี้เป็นส่วนหนึ่งในงานของ ${NAME}", + "songCreditText": "${TITLE} ดำเนินการโดย ${PERFORMER} เรียบเรียงโดย \n${COMPOSER}, เตรียมการโดย ${ARRANGER}, จัดทำโดย \n${PUBLISHER}, ขอบคุณนำ้ใจจาก${SOURCE}", + "soundAndMusicText": "เสียงและเพลงประกอบ:", + "soundsText": "เสียงประกอบ(${SOURCE}):", + "specialThanksText": "ขอขอบคุณเป็นพิเศษ:", + "thanksEspeciallyToText": "ขอขอบคุณ ${NAME} โดยเฉพาะอย่างยิ่ง", + "titleText": "${APP_NAME} เครดิต", + "whoeverInventedCoffeeText": "ใครก็ตามที่คิดค้นกาแฟ" + }, + "currentStandingText": "อันดับของคุณในขณะนี้คือ #${RANK}", + "customizeText": "ปรับแต่ง...", + "deathsTallyText": "ตาย ${COUNT} ครั้ง", + "deathsText": "ตาย", + "debugText": "ดีบั๊ก", + "debugWindow": { + "reloadBenchmarkBestResultsText": "โน๊ต: แนะนำให้คุณตั้งค่าใน ตั้งค่า->กราฟฟิก->ระดับภาพ เป็น 'สูง' ระหว่างที่กำลังทดสอบสิ่งนี้", + "runCPUBenchmarkText": "รันมาตรฐาน CPU", + "runGPUBenchmarkText": "รันมาตรฐาน GPU", + "runMediaReloadBenchmarkText": "รันมาตรฐานการรีโหลดสื่อ", + "runStressTestText": "รันตัวทดสอบความตึงเครียด", + "stressTestPlayerCountText": "จำนวนผู้เล่น", + "stressTestPlaylistDescriptionText": "เพลย์ลิสที่จะทดสอบความตึงเครียด", + "stressTestPlaylistNameText": "ชื่อเพลย์ลิส", + "stressTestPlaylistTypeText": "ประเภทเพลย์ลิส", + "stressTestRoundDurationText": "ระยะเวลารอบ", + "stressTestTitleText": "ทดสอบความตึงเครียด", + "titleText": "มาตรฐานและการทดสอบความตึงเครียด", + "totalReloadTimeText": "เวลารีโหลดทั้งหมด: ${TIME} (ดูใน log สำหรับข้อมูลเพิ่มเติม)" + }, + "defaultGameListNameText": "เพลย์ลิส ${PLAYMODE} พื้นฐาน", + "defaultNewGameListNameText": "เพลย์ลิส ${PLAYMODE} ของฉัน", + "deleteText": "ลบ", + "demoText": "ทดลอง", + "denyText": "ยกเลิก", + "deprecatedText": "คัดค้าน", + "desktopResText": "เดสก์ท็อป Res", + "deviceAccountUpgradeText": "คำเตือน:\nคุณลงชื่อเข้าใช้ด้วยบัญชีอุปกรณ์ (${NAME})\nบัญชีอุปกรณ์จะถูกลบออกในการอัปเดตในอนาคต\nอัปเกรดเป็นบัญชี V2 หากคุณต้องการติดตามความคืบหน้า", + "difficultyEasyText": "ง่าย", + "difficultyHardOnlyText": "โหมดยากเท่านั้น", + "difficultyHardText": "ยาก", + "difficultyHardUnlockOnlyText": "ด่านนี้สามารถปลดล็อคได้เฉพาะในโหมดยากเท่านั้น\nคุณคิดว่ามันจะใช้เวลาเท่าไหร่กันล่ะ!?!?!", + "directBrowserToURLText": "กรุณาเปิดเว็บโดยตรงตาม URL นี้:", + "disableRemoteAppConnectionsText": "ปิดการใช้การเชื่อมต่อแอพรีโมต", + "disableXInputDescriptionText": "อนุญาตให้ใช้คอนโทรลเลอร์มากกว่า 4 ตัวแต่จะทำงานได้ไม่ค่อยดีเท่าไหร่", + "disableXInputText": "ปิด XInput", + "doneText": "เสร็จสิ้น", + "drawText": "เสมอ", + "duplicateText": "ทำซ้ำ", + "editGameListWindow": { + "addGameText": "เพิ่ม\nเกม", + "cantOverwriteDefaultText": "ไม่สามารถเขียนทับเพลย์ลิสปกติได้!", + "cantSaveAlreadyExistsText": "เพลย์ลิสที่ใช้ชื่อนี้มีอยู่แล้ว!", + "cantSaveEmptyListText": "ไม่สามารถบันทึกเพลย์ลิสเปล่าได้!", + "editGameText": "แก้ไข\nเกม", + "listNameText": "ชื่อเพลย์ลิส", + "nameText": "ชื่อ", + "removeGameText": "ลบ\nเกม", + "saveText": "บันทึกลิสต์", + "titleText": "แก้ไขเพลย์ลิส" + }, + "editProfileWindow": { + "accountProfileInfoText": "โปรไฟล์พิเศษนี้มีชื่อและไอคอน\nตามบัญชีของคุณ\n\n${ICONS}\n\nสร้างโปรไฟล์แบบกำหนดเองเพื่อ\nใช้ชื่ออื่นหรือไอคอนแบบกำหนดเอง", + "accountProfileText": "(โปรไฟล์บัญชี)", + "availableText": "ชื่อ \"${NAME}\" สามารถใช้ได้", + "characterText": "ตัวละคร", + "checkingAvailabilityText": "กำลังเช็คว่าชื่อ \"${NAME}\" สามรถใช้ได้หรือไม่...", + "colorText": "สี", + "getMoreCharactersText": "รับตัวละครเพิ่มเติม...", + "getMoreIconsText": "รับไอคอนเพิ่มเติม...", + "globalProfileInfoText": "โปรไฟล์สาธารณะรับประกันว่าจะใช้ชื่อที่เป็นเอกลักษณ์\nในทั่วโลก และยังสามารถใช้ไอคอนแบบกำหนดเองได้อีกด้วย", + "globalProfileText": "(โปรไฟล์สาธารณะ)", + "highlightText": "ไฮไลท์", + "iconText": "ไอคอน", + "localProfileInfoText": "โปรไฟล์ส่วนตัวจะไม่มีไอคอนและชื่อที่ใช้จะไม่รับประกันว่าเป็น\nชื่อที่เป็นเอกลักษณ์หรือไม่ อัพเกรดเป็นโปรไฟล์สาธารณะเพื่อ\nจองชื่อที่เป็นเอกลักษณ์และใช้ไอคอนกำหนดเอง", + "localProfileText": "(โปรไฟล์ส่วนตัว)", + "nameDescriptionText": "ชื่อผู้เล่น", + "nameText": "ชื่อ", + "randomText": "สุ่มชื่อ", + "titleEditText": "แก้ไขโปรไฟล์", + "titleNewText": "สร้างโปรไฟล์ใหม่", + "unavailableText": "\"${NAME}\" ไม่สามารถใช้ได้ กรุณาลองใช้ชื่ออื่น", + "upgradeProfileInfoText": "การทำสิ่งนี้จะเป็นการจองชื่อตัวละครของคุณในทั่วโลก\nและจะทำให้คุณสามารถตั้งไอคอนกำหนดเองได้", + "upgradeToGlobalProfileText": "อัพเกรดเป็นโปรไฟล์สาธารณะ" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "คุณไม่สามารถลบเสียงประกอบเริ่มต้นได้", + "cantEditDefaultText": "ไม่สามารถแก้ไขเสียงประกอบเริ่มต้นได้ กรุณาคัดลอกหรือสร้างอันใหม่แทน", + "cantOverwriteDefaultText": "ไม่สามารถเขียนทับเสียงประกอบพื้นฐานได้", + "cantSaveAlreadyExistsText": "เสียงประกอบที่ใช้ชื่อนั้นมีอยู่แล้ว!", + "defaultGameMusicText": "<เพลงประกอบเกมเริ่มต้น>", + "defaultSoundtrackNameText": "เสียงประกอบเริ่มต้น", + "deleteConfirmText": "ลบเสียงประกอบ:\n\n'${NAME}'?", + "deleteText": "ลบ\nเสียงประกอบ", + "duplicateText": "ทำซ้ำ\nเสียงประกอบ", + "editSoundtrackText": "แก้ไขเสียงประกอบ", + "editText": "แก้ไข\nเสียงประกอบ", + "fetchingITunesText": "กำลังเรียกรายการเพลงในแอพ Music...", + "musicVolumeZeroWarning": "คำเตือน: เสียงเพลงตั้งค่าเป็น 0", + "nameText": "ชื่อ", + "newSoundtrackNameText": "เสียงประกอบของฉัน ${COUNT}", + "newSoundtrackText": "เสียงประกอบใหม่:", + "newText": "สร้าง\nเสียงประกอบใหม่", + "selectAPlaylistText": "เลือกเพลย์ลิส:", + "selectASourceText": "แหล่งเพลง", + "testText": "ทดสอบ", + "titleText": "เสียงประกอบ", + "useDefaultGameMusicText": "เพลงประกอบเกมเริ่มต้น", + "useITunesPlaylistText": "เพลย์ลิสต์แอพเพลง", + "useMusicFileText": "ไฟล์เพลง (mp3,ฯลฯ)", + "useMusicFolderText": "โฟลเดอร์ของไฟล์เพลง" + }, + "editText": "แก้ไข", + "endText": "จบ", + "enjoyText": "ขอให้สนุก!", + "epicDescriptionFilterText": "${DESCRIPTION} ในการเคลื่อนไหวที่ช้ามากๆ", + "epicNameFilterText": "${NAME} แบบช้ามหากาฬ", + "errorAccessDeniedText": "การเข้าถึงถูกปฏิเสธ", + "errorDeviceTimeIncorrectText": "เวลาของอุปกรณ์ไม่ถูกต้อง ${HOURS} ชั่วโมง\nมีแนวโน้มที่จะทำให้เกิดปัญหา\nโปรดตรวจสอบการตั้งค่าเวลาและเขตเวลาของคุณ", + "errorOutOfDiskSpaceText": "พื้นที่ว่างในเครื่องหมด", + "errorSecureConnectionFailText": "ไม่สามารถสร้างการเชื่อมต่อระบบคลาวด์ที่ปลอดภัยได้ การทำงานของเครือข่ายอาจล้มเหลว", + "errorText": "ข้อผิดพลาด", + "errorUnknownText": "ข้อผิดพลาดที่ไม่รู้จัก", + "exitGameText": "จะออกจาก ${APP_NAME} หรือไม่?", + "exportSuccessText": "'${NAME}' ถูกส่งออกแล้ว", + "externalStorageText": "พื้นที่ว่าง", + "failText": "ล้มเหลว", + "fatalErrorText": "โอ๊ะ! บางสิ่งบางอย่างหายหรือเสียหายไป\nกรุณาลองติดตั้งแอพใหม่อีกครั้งหรือ\nติดต่อ ${EMAIL} สำหรับความชาวยเหลือ", + "fileSelectorWindow": { + "titleFileFolderText": "เลือกไฟล์หรือโฟลเดอร์", + "titleFileText": "เลือกไฟล์", + "titleFolderText": "เลือกโฟลเดอร์", + "useThisFolderButtonText": "ใช้โฟลเดอร์นี้" + }, + "filterText": "กรอง", + "finalScoreText": "คะแนนสิ้นสุด", + "finalScoresText": "คะแนนสิ้นสุด", + "finalTimeText": "เวลาสิ้นสุด", + "finishingInstallText": "กำลังติดตั้ง กรุณารอสักครู่...", + "fireTVRemoteWarningText": "* เพื่อประสบการณ์ที่ดีขึ้น ใช้เกม\nคอนโทรลเลอร์หรือติดตั้งแอพ\n '${REMOTE_APP_NAME}' ใน\nโทรศัพท์หรือแท็บเล็ตของคุณ", + "firstToFinalText": "คนแรกที่ได้ ${COUNT} คะแนน", + "firstToSeriesText": "คนแรกที่ได้ ${COUNT} คะแนน ฤดูกาล", + "fiveKillText": "ฆ่าห้า!!!", + "flawlessWaveText": "ชนะอย่างไร้ที่ติ!", + "fourKillText": "ฆ่าสี่!!!", + "friendScoresUnavailableText": "คะแนนเพื่อนไม่สามารถใช้ได้", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "${COUNT} อันดับแรกของเกม", + "gameListWindow": { + "cantDeleteDefaultText": "คุณไม่สามารถลบเพลย์ลิสเริ่มต้นได้", + "cantEditDefaultText": "ไม่สามารถแก้ไขเพลย์ลิสเริ่มต้นได้! คัดลอกหรือสร้างอีกอันใหม่", + "cantShareDefaultText": "คุณไม่สามารถแบ่งปันเพลย์ลิสเริ่มต้นได้", + "deleteConfirmText": "จะลบเกม \"${LIST}\" หรือไม่?", + "deleteText": "ลบ\nเพลย์ลิส", + "duplicateText": "ทำซ้ำ\nเพลย์ลิส", + "editText": "แก้ไข\nเพลย์ลิส", + "newText": "สร้าง\nเพลย์ลิสใหม่", + "showTutorialText": "โชว์การสอนก่อนเริ่ม", + "shuffleGameOrderText": "เรียงเกมตามลำดับ", + "titleText": "ปรับแต่งเพลย์ลิส ${TYPE}" + }, + "gameSettingsWindow": { + "addGameText": "เพิ่มเกม" + }, + "gamesToText": "ชนะ ${WINCOUNT} ต่อ ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "โปรดจำ: ไม่ว่าอุปกรณ์ใหนก็ตามในปาร์ตี้ก็สามารถมี\nมากกว่า 1 ผู้เล่นได้ถ้าหากคุณมีคอนโทรลเลอร์พอ", + "aboutDescriptionText": "ใช้แท็บนี้ในการจัดปาร์ตี้\n\nปาร์ตี้จะทำให้คุณเล่นเกมและทัวร์นาเมนท์\nกับเพื่อนของคุณผ่านอุปกรณ์ที่แตกต่างกันได้\n\nใช้ปุ่ม ${PARTY} ด้านบนขวาเพื่อสนทนาและ\nทำความรู้จักกับคนในปาร์ตี้ของคุณ\n(ในคอนโทรลเลอร์ ใช้ปุ่ม ${BUTTON} ในหน้าเมนู)", + "aboutText": "เกี่ยวกับ", + "addressFetchErrorText": "<พบข้อผิดพลาดในการหาแอดเดรส>", + "appInviteMessageText": "${NAME} ให้ตั๋วคุณ ${COUNT} อันใน ${APP_NAME}", + "appInviteSendACodeText": "ส่งรหัสให้กับพวกเขา", + "appInviteTitleText": "ชวนเพื่อน ${APP_NAME}", + "bluetoothAndroidSupportText": "(ทำงานร่วมกับเครื่องแอนดรอยด์ที่สนับสนุน Bluetooth)", + "bluetoothDescriptionText": "สร้าง/เข้าร่วมปาร์ตี้ผ่านทาง Bluetooth:", + "bluetoothHostText": "สร้างปาร์ตี้ผ่านทาง Bluetooth", + "bluetoothJoinText": "เข้าร่วมปาร์ตี้ผ่านทาง Bluetooth", + "bluetoothText": "บลูทูธ", + "checkingText": "กำลังตรวจ..", + "copyCodeConfirmText": "คัดลอกรหัสไปยังคลิปบอร์ดแล้ว", + "copyCodeText": "คัดลอกรหัส", + "dedicatedServerInfoText": "เพื่อผลลัพธ์ที่ดีที่สุดตั้งค่าเซิร์ฟเวอร์เฉพาะ ดู bombsquadgame.com/server เพื่อเรียนรู้วิธีการ", + "disconnectClientsText": "สิ่งนี้จะตัดการเชื่อมต่อผู้เล่น ${COUNT} คน\nในงานปาร์ตี้ของคุณ คุณแน่ใจไหม?", + "earnTicketsForRecommendingAmountText": "เพื่อน ๆ จะได้รับตั๋ว ${COUNT} ถ้าพวกเขาลองเล่นเกม\n(และคุณจะได้รับ ${YOU_COUNT} สำหรับแต่ละคนที่ทำ)", + "earnTicketsForRecommendingText": "แชร์เกมนี้\nสำหรับตั๋วฟรี", + "emailItText": "อีเมล์นี้", + "favoritesSaveText": "บันทึกเป็นรายการโปรด", + "favoritesText": "รายการโปรด", + "freeCloudServerAvailableMinutesText": "เซิร์ฟเวอร์คลาวด์ฟรีถัดไปพร้อมใช้งานใน ${MINUTES} นาที", + "freeCloudServerAvailableNowText": "เซิร์ฟเวอร์คลาวด์ฟรีพร้อมใช้งาน!", + "freeCloudServerNotAvailableText": "ไม่มีเซิร์ฟเวอร์คลาวด์ฟรี", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} ตั๋วจาก ${NAME}", + "friendPromoCodeAwardText": "คุณจะได้รับตั๋ว ${COUNT} ทุกครั้งที่ใช้", + "friendPromoCodeExpireText": "รหัสจะหมดอายุใน ${EXPIRE_HOURS} ชั่วโมงและใช้ได้กับผู้เล่นใหม่เท่านั้น", + "friendPromoCodeInstructionsText": "หากต้องการใช้งานให้เปิด ${APP_NAME} แล้วไปที่ \"การตั้งค่า -> ขั้นสูง -> ใส่รหัส\"\nดู bombsquadgame.com สำหรับลิงก์ดาวน์โหลดสำหรับแพลตฟอร์มที่รองรับทั้งหมด", + "friendPromoCodeRedeemLongText": "สามารถแลกเป็นตั๋วฟรี ${COUNT} คนสูงถึง ${MAX_USES} คน", + "friendPromoCodeRedeemShortText": "สามารถแลกเป็นตั๋ว ${COUNT} ใบในเกม", + "friendPromoCodeWhereToEnterText": "(ใน \"การตั้งค่า->ขั้นสูง->ป้อนรหัส\")", + "getFriendInviteCodeText": "รับรหัสเชิญเพื่อน", + "googlePlayDescriptionText": "เชิญผู้เล่น Google Play เข้าร่วมปาร์ตี้ของคุณ:", + "googlePlayInviteText": "เชิญ", + "googlePlayReInviteText": "มีผู้เล่น Google Play ${COUNT} คนในปาร์ตี้ของคุณ\nใครจะถูกตัดการเชื่อมต่อหากคุณเริ่มคำเชิญใหม่\nรวมไว้ในคำเชิญใหม่เพื่อรับพวกเขากลับมา", + "googlePlaySeeInvitesText": "ดูคำเชิญ", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(เวอร์ชัน Android / Google Play)", + "hostPublicPartyDescriptionText": "โฮสต์ปาร์ตี้สาธารณะ", + "hostingUnavailableText": "โฮสต์ไม่พร้อมใช้งาน", + "inDevelopmentWarningText": "บันทึก:\n\nการเล่นผ่านเครือข่ายเป็นคุณลักษณะใหม่ที่ยังคงพัฒนาอยู่\nสำหรับตอนนี้ขอแนะนำเป็นอย่างยิ่งว่า\nผู้เล่นอยู่ในเครือข่าย Wi-Fi เดียวกัน", + "internetText": "อินเทอร์เน็ต", + "inviteAFriendText": "เพื่อนไม่มีเกม? ชวนเพื่อน\nมาลองแล้วจะได้รับตั๋วฟรี ${COUNT} ใบ", + "inviteFriendsText": "เชิญเพื่อน ๆ", + "joinPublicPartyDescriptionText": "เข้าร่วมปาร์ตี้สาธารณะ", + "localNetworkDescriptionText": "เข้าร่วมปาร์ตี้ใกล้เคียง (LAN, Bluetooth ฯลฯ)", + "localNetworkText": "เครือข่ายท้องถิ่น", + "makePartyPrivateText": "ทำให้ปาร์ตี้ของฉันเป็นส่วนตัว", + "makePartyPublicText": "ทำให้ปาร์ตี้ของฉันเป็นสาธารณะ", + "manualAddressText": "ที่อยู่", + "manualConnectText": "เชื่อมต่อ", + "manualDescriptionText": "เข้าร่วมปาร์ตี้ด้วยที่อยู่:", + "manualJoinSectionText": "เข้าร่วมด้วยที่อยู่", + "manualJoinableFromInternetText": "คุณสามารถเข้าร่วมจากอินเทอร์เน็ตได้หรือไม่:", + "manualJoinableNoWithAsteriskText": "ไม่*", + "manualJoinableYesText": "ใช่", + "manualRouterForwardingText": "*เพื่อแก้ไขปัญหานี้ ลองกำหนดค่าเราเตอร์ของคุณเพื่อส่งต่อพอร์ต UDP ${PORT} ไปยังที่อยู่ในเครื่องของคุณ", + "manualText": "ด้วยตนเอง", + "manualYourAddressFromInternetText": "ที่อยู่ของคุณจากอินเทอร์เน็ต:", + "manualYourLocalAddressText": "ที่อยู่ในท้องถิ่นของคุณ:", + "nearbyText": "ใกล้เคียง", + "noConnectionText": "<ไม่มีการเชื่อมต่อ>", + "otherVersionsText": "(เวอร์ชั่นอื่นๆ)", + "partyCodeText": "รหัสปาร์ตี้", + "partyInviteAcceptText": "ยอมรับ", + "partyInviteDeclineText": "ปฏิเสธ", + "partyInviteGooglePlayExtraText": "(ดูแท็บ 'Google Play' ในหน้าต่าง 'รวบรวม')", + "partyInviteIgnoreText": "ไม่สนใจ", + "partyInviteText": "${NAME} เชิญ\nคุณเข้าร่วมปาร์ตี้ของเขา!", + "partyNameText": "ชื่อปาร์ตี้", + "partyServerRunningText": "เซิร์ฟเวอร์ปาร์ตี้ของคุณกำลังทำงาน", + "partySizeText": "ขนาดปาร์ตี้", + "partyStatusCheckingText": "กำลังตรวจสอบสถานะ...", + "partyStatusJoinableText": "ปาร์ตี้ของคุณสามารถเข้าร่วมได้จากอินเทอร์เน็ต", + "partyStatusNoConnectionText": "ไม่สามารถเชื่อมต่อกับระบบได้", + "partyStatusNotJoinableText": "ปาร์ตี้ของคุณไม่สามารถเข้าร่วมจากอินเทอร์เน็ตได้", + "partyStatusNotPublicText": "ปาร์ตี้ของคุณไม่เป็นสาธารณะ", + "pingText": "ปิง", + "portText": "พอร์ต", + "privatePartyCloudDescriptionText": "ปาร์ตี้ส่วนตัวทำงานบนเซิร์ฟเวอร์คลาวด์เฉพาะ ไม่จำเป็นต้องกำหนดค่าเราเตอร์", + "privatePartyHostText": "โฮสต์ปาร์ตี้ส่วนตัว", + "privatePartyJoinText": "เข้าร่วมปาร์ตี้ส่วนตัว", + "privateText": "ส่วนตัว", + "publicHostRouterConfigText": "ซึ่งอาจต้องมีการกำหนดค่าการส่งต่อพอร์ตบนเราเตอร์ของคุณ ให้จัดปาร์ตี้ส่วนตัวเพื่อตัวเลือกที่ง่ายกว่า", + "publicText": "สาธารณะ", + "requestingAPromoCodeText": "ขอรหัส...", + "sendDirectInvitesText": "ส่งคำเชิญโดยตรง", + "shareThisCodeWithFriendsText": "แบ่งปันรหัสนี้กับเพื่อน:", + "showMyAddressText": "แสดงที่อยู่ของฉัน", + "startHostingPaidText": "โฮสต์ตอนนี้ราคา ${COST}", + "startHostingText": "โฮสต์", + "startStopHostingMinutesText": "คุณสามารถเริ่มและหยุดการโฮสต์ได้ฟรีเป็นเวลาอีก ${MINUTES} นาที", + "stopHostingText": "หยุดโฮสต์", + "titleText": "รวมตัว", + "wifiDirectDescriptionBottomText": "หากอุปกรณ์ทั้งหมดมีแผง 'Wi-Fi Direct' ก็ควรจะสามารถใช้แผงนี้เพื่อค้นหา\nและเชื่อมต่อถึงกัน เมื่อเชื่อมต่ออุปกรณ์ทั้งหมดแล้ว คุณสามารถสร้างปาร์ตี้ได้\nที่นี่โดยใช้แท็บ 'เครือข่ายท้องถิ่น' เช่นเดียวกับเครือข่าย Wi-Fi ปกติ\n\nเพื่อผลลัพธ์ที่ดีที่สุด โฮสต์ Wi-Fi Direct ควรเป็นโฮสต์ปาร์ตี้ ${APP_NAME} ด้วย", + "wifiDirectDescriptionTopText": "สามารถใช้ Wi-Fi Direct เพื่อเชื่อมต่ออุปกรณ์ Android ได้โดยตรงโดยไม่ต้องใช้\nต้องการเครือข่าย Wi-Fi วิธีนี้ใช้ได้ผลดีที่สุดบน Android 4.2 หรือใหม่กว่า\n\nในการใช้งาน ให้เปิดการตั้งค่า Wi-Fi และมองหา 'Wi-Fi Direct' ในเมนู", + "wifiDirectOpenWiFiSettingsText": "เปิดการตั้งค่า Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(ทำงานระหว่างแพลตฟอร์มทั้งหมด)", + "worksWithGooglePlayDevicesText": "(ใช้งานได้กับอุปกรณ์ที่ใช้เกมเวอร์ชัน Google Play (android))", + "youHaveBeenSentAPromoCodeText": "คุณได้รับรหัสโปรโหมด ${APP_NAME} แล้ว:" + }, + "getTicketsWindow": { + "freeText": "ฟรี!", + "freeTicketsText": "ตั๋วฟรี", + "inProgressText": "กำลังดำเนินการธุรกรรม โปรดลองอีกครั้งในอีกสักครู่", + "purchasesRestoredText": "คืนค่าการซื้อแล้ว", + "receivedTicketsText": "ได้รับตั๋ว ${COUNT} ใบแล้ว!", + "restorePurchasesText": "เรียกคืนการซื้อสินค้า", + "ticketPack1Text": "แพ็คตั๋วขนาดเล็ก", + "ticketPack2Text": "แพ็คตั๋วขนาดกลาง", + "ticketPack3Text": "แพ็กตั๋วขนาดใหญ่", + "ticketPack4Text": "แพ็กตั๋วจัมโบ้", + "ticketPack5Text": "แพ็กตั๋วแมมมอธ", + "ticketPack6Text": "แพ็กตั๋วสูงสุด", + "ticketsFromASponsorText": "ดูโฆษณา\nเพื่อรับตั๋ว ${COUNT} ใบ", + "ticketsText": "ตั๋ว ${COUNT} ใบ", + "titleText": "รับตั๋ว", + "unavailableLinkAccountText": "ขออภัย ไม่สามารถซื้อได้บนแพลตฟอร์มนี้\nวิธีแก้ปัญหา คุณสามารถเชื่อมโยงบัญชีนี้กับบัญชีบน\nแพลตฟอร์มอื่นและทำการซื้อที่นั่น", + "unavailableTemporarilyText": "ไม่สามารถใช้งานได้ในขณะนี้ โปรดลองอีกครั้งในภายหลัง.", + "unavailableText": "ขออภัย ไม่สามารถใช้ได้", + "versionTooOldText": "ขออภัย เกมเวอร์ชันนี้เก่าเกินไป โปรดอัปเดตเป็นเวอร์ชันที่ใหม่กว่า", + "youHaveShortText": "คุณมี ${COUNT} ใบ", + "youHaveText": "คุณมีตั๋ว ${COUNT} ใบ" + }, + "googleMultiplayerDiscontinuedText": "ขออภัย บริการผู้เล่นหลายคนของ Google ไม่มีให้บริการอีกต่อไป\nฉันกำลังดำเนินการเปลี่ยนให้เร็วที่สุด\nในระหว่างนี้ โปรดลองวิธีการเชื่อมต่ออื่น\n-เอริค", + "googlePlayPurchasesNotAvailableText": "ไม่สามารถซื้อด้วย Google Play ได้\nคุณอาจต้องอัปเดตแอปร้านค้าของคุณ", + "googlePlayServicesNotAvailableText": "บริการ Google Play ไม่พร้อมใช้งาน\nฟังก์ชันบางอย่างของแอปอาจถูกปิดใช้งาน", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "ตลอด", + "fullScreenCmdText": "เต็มหน้าจอ (Cmd-F)", + "fullScreenCtrlText": "เต็มหน้าจอ (Ctrl-F)", + "gammaText": "ส่องสว่าง", + "highText": "สูง", + "higherText": "สูงกว่า", + "lowText": "ต่ำ", + "mediumText": "ปานกลาง", + "neverText": "ไม่เคย", + "resolutionText": "ความละเอียด", + "showFPSText": "แสดง FPS", + "texturesText": "พื้นผิว", + "titleText": "กราฟิก", + "tvBorderText": "ขอบทีวี", + "verticalSyncText": "ซิงค์แนวตั้ง", + "visualsText": "ภาพ" + }, + "helpWindow": { + "bombInfoText": "- ระเบิด -\nแข็งแกร่งกว่าหมัด แต่\nอาจทำให้ตนเองบาดเจ็บสาหัสได้\nเพื่อผลลัพธ์ที่ดีที่สุด ให้โยนไปทาง\nศัตรูก่อนฟิวส์หมด", + "canHelpText": "${APP_NAME} ช่วยได้", + "controllersInfoText": "คุณสามารถเล่น ${APP_NAME} กับเพื่อนผ่านเครือข่ายหรือคุณ\nทุกคนสามารถเล่นบนอุปกรณ์เดียวกันได้ถ้าคุณมีตัวควบคุมเพียงพอ\n${APP_NAME} รองรับได้หลากหลาย; คุณยังสามารถใช้โทรศัพท์ได้\nในฐานะผู้ควบคุมผ่านแอป '${REMOTE_APP_NAME}' ฟรี\nดูการตั้งค่า -> ตัวควบคุมสำหรับข้อมูลเพิ่มเติม", + "controllersInfoTextRemoteOnly": "คุณสามารถเล่น ${APP_NAME} กับเพื่อนผ่านเครือข่ายหรือคุณ\nทุกคนสามารถเล่นบนอุปกรณ์เดียวกันได้โดยใช้โทรศัพท์เป็น\nคอนโทรลเลอร์ผ่านแอป '${REMOTE_APP_NAME}' ฟรี", + "controllersText": "คอนโทรลเลอร์", + "controlsSubtitleText": "ตัวละครที่เป็นมิตร ${APP_NAME} ของคุณมีการดำเนินการพื้นฐานบางประการ:", + "controlsText": "การควบคุม", + "devicesInfoText": "เวอร์ชัน VR ของ ${APP_NAME} สามารถเล่นผ่านเครือข่ายได้ด้วย\nเวอร์ชันปกติ ลองใช้โทรศัพท์ แท็บเล็ตเพิ่มเติม\nและคอมพิวเตอร์และเล่นเกมของคุณ มันยังมีประโยชน์กับ\nเชื่อมต่อเกมเวอร์ชันปกติกับเวอร์ชัน VR เพียงเพื่อ\nให้คนภายนอกได้ชมการกระทำ", + "devicesText": "อุปกรณ์", + "friendsGoodText": "สิ่งเหล่านี้เป็นสิ่งที่ดีที่จะมี ${APP_NAME} สนุกที่สุดด้วยหลายรายการ\nผู้เล่นและสามารถรองรับได้ถึง 8 ต่อครั้ง ซึ่งทำให้เรา:", + "friendsText": "เพื่อน", + "jumpInfoText": "- กระโดด -\nกระโดดข้ามช่องว่างเล็ก ๆ\nโยนสิ่งที่สูงขึ้นและ\nเพื่อแสดงความรู้สึกของความสุข", + "orPunchingSomethingText": "หรือต่อยอะไรบางอย่าง ขว้างมันออกจากหน้าผา แล้วเป่าขึ้นระหว่างทางด้วยระเบิดเหนียว", + "pickUpInfoText": "- ยกขึ้น -\nคว้าธง ศัตรู หรืออะไรก็ได้\nอย่างอื่นไม่ได้ยึดติดกับพื้น\nกดอีกครั้งเพื่อโยน", + "powerupBombDescriptionText": "ให้คุณโยนระเบิดสามลูก\nแทนที่จะเป็นลูกเดียว", + "powerupBombNameText": "ระเบิดสามลูก", + "powerupCurseDescriptionText": "คุณอาจต้องการหลีกเลี่ยงสิ่งเหล่านี้\n ...หรือคุณ?", + "powerupCurseNameText": "คำสาป", + "powerupHealthDescriptionText": "ให้คุณมีสุขภาพแข็งแรงสมบูรณ์\nคุณคงไม่เคยคิด", + "powerupHealthNameText": "แพ็คยา", + "powerupIceBombsDescriptionText": "อ่อนแอกว่าระเบิดธรรมดา\nแต่ปล่อยให้ศัตรูเย็นชา\nและเปราะเป็นพิเศษ", + "powerupIceBombsNameText": "ระเบิดน้ำแข็ง", + "powerupImpactBombsDescriptionText": "อ่อนกว่าปกติเล็กน้อย\nระเบิด แต่ระเบิดเมื่อกระทบ", + "powerupImpactBombsNameText": "ระเบิดไก", + "powerupLandMinesDescriptionText": "เจ้านี่มาในแพ็ค 3 อัน;\nมีประโยชน์สำหรับการป้องกันฐานหรือ\nหยุดศัตรูที่รวดเร็ว", + "powerupLandMinesNameText": "ทุ่นระเบิด", + "powerupPunchDescriptionText": "ทำให้หมัดของคุณหนักขึ้น\nเร็วขึ้นดีขึ้นแข็งแรงขึ้น", + "powerupPunchNameText": "นวมชกมวย", + "powerupShieldDescriptionText": "ดูดซับความเสียหายเล็กน้อย\nดังนั้นคุณไม่จำเป็นต้อง", + "powerupShieldNameText": "โล่พลังงาน", + "powerupStickyBombsDescriptionText": "ยึดติดกับสิ่งที่พวกเขาตี\nความฮาจึงบังเกิด", + "powerupStickyBombsNameText": "ระเบิดเหนียวหนืด", + "powerupsSubtitleText": "แน่นอนว่าไม่มีเกมใดที่จะสมบูรณ์ได้หากไม่มีการเพิ่มพลัง:", + "powerupsText": "เพิ่มพลัง", + "punchInfoText": "- ต่อย -\nหมัดสร้างความเสียหายมากขึ้น\nหมัดของคุณขยับเร็วขึ้นดังนั้น\nวิ่งและหมุนเหมือนคนบ้า", + "runInfoText": "- วิ่ง -\nกดค้างปุ่มใดก็ได้เพื่อวิ่ง ปุ่มทริกเกอร์หรือปุ่มไหล่ทำงานได้ดีถ้าคุณมี\nการวิ่งทำให้คุณได้ตำแหน่งเร็วขึ้นแต่ทำให้เลี้ยวยาก ดังนั้นให้ระวังหน้าผา", + "someDaysText": "บางวันคุณรู้สึกอยากต่อยอะไรบางอย่าง หรือเป่าอะไรขึ้น", + "titleText": "${APP_NAME} ความช่วยเหลือ", + "toGetTheMostText": "เพื่อให้ได้ประโยชน์สูงสุดจากเกมนี้ คุณจะต้อง:", + "welcomeText": "ยินดีต้อนรับสู่ ${APP_NAME}!" + }, + "holdAnyButtonText": "<กดปุ่มใดก็ได้>", + "holdAnyKeyText": "<กดปุ่มใดก็ได้>", + "hostIsNavigatingMenusText": "- ${HOST} กำลังนำทางเมนูเหมือนหัวหน้า -", + "importPlaylistCodeInstructionsText": "ใช้รหัสต่อไปนี้เพื่อนำเข้าเพลย์ลิสต์นี้ที่อื่น:", + "importPlaylistSuccessText": "นำเข้าเพลย์ลิสต์ ${TYPE} '${NAME}'", + "importText": "นำเข้า", + "importingText": "กำลังนำเข้า...", + "inGameClippedNameText": "ในเกมจะเป็น\n\"${NAME}\"", + "installDiskSpaceErrorText": "ข้อผิดพลาด: ไม่สามารถทำการติดตั้งให้เสร็จสิ้นได้\nคุณอาจไม่มีที่ว่างบนอุปกรณ์ของคุณ\nล้างพื้นที่บางส่วนแล้วลองอีกครั้ง", + "internal": { + "arrowsToExitListText": "กด ${LEFT} หรือ ${RIGHT} เพื่อออกจากรายการ", + "buttonText": "ปุ่ม", + "cantKickHostError": "คุณเตะโฮสต์ไม่ได้", + "chatBlockedText": "${NAME} ถูกบล็อกการแชทเป็นเวลา ${TIME} วินาที", + "connectedToGameText": "เข้าร่วม '${NAME}'", + "connectedToPartyText": "เข้าร่วมปาร์ตี้ของ ${NAME}!", + "connectingToPartyText": "กำลังเชื่อมต่อ...", + "connectionFailedHostAlreadyInPartyText": "การเชื่อมต่อล้มเหลว; โฮสต์อยู่ในปาร์ตี้อื่น", + "connectionFailedPartyFullText": "การเชื่อมต่อล้มเหลว; ปาร์ตี้เต็ม", + "connectionFailedText": "การเชื่อมต่อล้มเหลว.", + "connectionFailedVersionMismatchText": "การเชื่อมต่อล้มเหลว; โฮสต์กำลังใช้เกมเวอร์ชันอื่น\nตรวจสอบให้แน่ใจว่าคุณเป็นเวอร์ชั่นล่าสุดแล้วลองอีกครั้ง", + "connectionRejectedText": "การเชื่อมต่อถูกปฏิเสธ", + "controllerConnectedText": "เชื่อมต่อ ${CONTROLLER} แล้ว", + "controllerDetectedText": "ตรวจพบคอนโทรลเลอร์ 1 รายการ", + "controllerDisconnectedText": "${CONTROLLER} ถูกตัดการเชื่อมต่อ", + "controllerDisconnectedTryAgainText": "${CONTROLLER} ถูกตัดการเชื่อมต่อ โปรดลองเชื่อมต่ออีกครั้ง", + "controllerForMenusOnlyText": "คอนโทรลเลอร์นี้ไม่สามารถใช้เล่นได้ ใช้เพื่อนำทางไปยังเมนูเท่านั้น", + "controllerReconnectedText": "${CONTROLLER} เชื่อมต่อใหม่แล้ว", + "controllersConnectedText": "เชื่อมต่อตัวควบคุม ${COUNT} รายการแล้ว", + "controllersDetectedText": "ตรวจพบคอนโทรลเลอร์ ${COUNT} รายการ", + "controllersDisconnectedText": "ยกเลิกการเชื่อมต่อคอนโทรลเลอร์ ${COUNT} รายการแล้ว", + "corruptFileText": "ตรวจพบไฟล์ที่เสียหาย โปรดลองติดตั้งใหม่ หรือส่งอีเมลไปที่ ${EMAIL}", + "errorPlayingMusicText": "เกิดข้อผิดพลาดในการเล่นเพลง: ${MUSIC}", + "errorResettingAchievementsText": "ไม่สามารถรีเซ็ตความสำเร็จออนไลน์ได้ โปรดลองอีกครั้งในภายหลัง.", + "hasMenuControlText": "${NAME} มีการควบคุมเมนู", + "incompatibleNewerVersionHostText": "โฮสต์กำลังเรียกใช้เกมเวอร์ชันใหม่กว่า\nอัปเดตเป็นเวอร์ชันล่าสุดแล้วลองอีกครั้ง", + "incompatibleVersionHostText": "โฮสต์กำลังเรียกใช้เกมเวอร์ชันอื่น\nตรวจสอบให้แน่ใจว่าคุณเป็นข้อมูลล่าสุดแล้วลองอีกครั้ง", + "incompatibleVersionPlayerText": "${NAME} กำลังเรียกใช้เกมเวอร์ชันอื่น\nตรวจสอบให้แน่ใจว่าคุณเป็นข้อมูลล่าสุดแล้วลองอีกครั้ง", + "invalidAddressErrorText": "ข้อผิดพลาด: ที่อยู่ไม่ถูกต้อง", + "invalidNameErrorText": "ข้อผิดพลาด: ชื่อไม่ถูกต้อง", + "invalidPortErrorText": "ข้อผิดพลาด: พอร์ตไม่ถูกต้อง", + "invitationSentText": "ส่งคำเชิญแล้ว", + "invitationsSentText": "ส่งคำเชิญแล้ว ${COUNT} รายการ", + "joinedPartyInstructionsText": "มีคนเข้าร่วมปาร์ตี้ของคุณ\nไปที่ 'เล่น' เพื่อเริ่มเกม", + "keyboardText": "แป้นพิมพ์", + "kickIdlePlayersKickedText": "เตะ ${NAME} เพราะไม่ได้ใช้งาน", + "kickIdlePlayersWarning1Text": "${NAME} จะถูกเตะใน ${COUNT} วินาทีหากไม่ได้ใช้งาน", + "kickIdlePlayersWarning2Text": "(คุณสามารถปิดได้ในการตั้งค่า -> ขั้นสูง)", + "leftGameText": "ออก '${NAME}'", + "leftPartyText": "ออกจากปาร์ตี้ของ ${NAME}", + "noMusicFilesInFolderText": "โฟลเดอร์ไม่มีไฟล์เพลง", + "playerJoinedPartyText": "${NAME} เข้าร่วมปาร์ตี้!", + "playerLeftPartyText": "${NAME} ออกจากปาร์ตี้", + "rejectingInviteAlreadyInPartyText": "ปฏิเสธคำเชิญ (อยู่ในปาร์ตี้แล้ว)", + "serverRestartingText": "เซิร์ฟเวอร์กำลังเริ่มต้นใหม่ โปรดเข้าร่วมใหม่ในอีกสักครู่...", + "serverShuttingDownText": "กำลังปิดเซิฟเวอร์...", + "signInErrorText": "เกิดข้อผิดพลาดในการลงชื่อเข้าใช้", + "signInNoConnectionText": "ไม่สามารถลงชื่อเข้าใช้ (ไม่มีการเชื่อมต่ออินเทอร์เน็ตหรอ?)", + "telnetAccessDeniedText": "ข้อผิดพลาด: ผู้ใช้ไม่ได้ให้สิทธิ์การเข้าถึง telnet", + "timeOutText": "(หมดเวลาใน ${TIME} วินาที)", + "touchScreenJoinWarningText": "คุณได้เข้าร่วมกับหน้าจอสัมผัส\nหากนี่เป็นข้อผิดพลาด ให้แตะ 'เมนู -> ออกจากเกม' ด้วย", + "touchScreenText": "หน้าจอสัมผัส", + "unableToResolveHostText": "ข้อผิดพลาด: ไม่สามารถแก้ไขโฮสต์", + "unavailableNoConnectionText": "ไม่สามารถใช้งานได้ในขณะนี้ (ไม่มีการเชื่อมต่ออินเทอร์เน็ตหรอ?)", + "vrOrientationResetCardboardText": "ใช้เพื่อรีเซ็ตการวางแนว VR\nในการเล่นเกม คุณจะต้องมีคอนโทรลเลอร์ภายนอก", + "vrOrientationResetText": "รีเซ็ตการวางแนว VR", + "willTimeOutText": "(จะหมดเวลาถ้าว่าง)" + }, + "jumpBoldText": "กระโดด", + "jumpText": "กระโดด", + "keepText": "เก็บไว้", + "keepTheseSettingsText": "เก็บการตั้งค่าเหล่านี้ไว้ไหม", + "keyboardChangeInstructionsText": "กด Space สองครั้งเพื่อเปลี่ยนคีย์บอร์ด", + "keyboardNoOthersAvailableText": "ไม่มีแป้นพิมพ์อื่นๆ", + "keyboardSwitchText": "กำลังสลับแป้นพิมพ์เป็น \"${NAME}\"", + "kickOccurredText": "${NAME} ถูกเตะ", + "kickQuestionText": "เตะ ${NAME} ไหม?", + "kickText": "เตะ", + "kickVoteCantKickAdminsText": "แอดมินไม่สามารถเตะได้", + "kickVoteCantKickSelfText": "คุณไม่สามารถเตะตัวเองได้", + "kickVoteFailedNotEnoughVotersText": "ผู้เล่นไม่เพียงพอสำหรับการโหวท", + "kickVoteFailedText": "โหวตเตะล้มเหลว", + "kickVoteStartedText": "เริ่มต้นการโหวตสำหรับ ${NAME} แล้ว", + "kickVoteText": "โหวตเตะ", + "kickVotingDisabledText": "โหวทเตะ ถูกปิดใช้งาน", + "kickWithChatText": "พิมพ์ ${YES} ในแชทถ้าโหวตใช่และพิมพ์ ${NO} ถ้าโหวตไม่", + "killsTallyText": "ฆ่าไป ${COUNT}", + "killsText": "ฆ่า", + "kioskWindow": { + "easyText": "ง่าย", + "epicModeText": "โหมดมหากาพย์", + "fullMenuText": "เมนูเต็ม", + "hardText": "ยาก", + "mediumText": "ปานกลาง", + "singlePlayerExamplesText": "ตัวอย่างผู้เล่นคนเดียว / Co-op", + "versusExamplesText": "ตัวอย่างต่อสู้" + }, + "languageSetText": "ขณะนี้ภาษาคือ \"${LANGUAGE}\"", + "lapNumberText": "รอบ ${CURRENT}/${TOTAL}", + "lastGamesText": "(${COUNT} เกมสุดท้าย )", + "leaderboardsText": "กระดานผู้นำ", + "league": { + "allTimeText": "ตลอดเวลา", + "currentSeasonText": "ซีซั่นปัจจุบัน (${NUMBER})", + "leagueFullText": "ลีก ${NAME}", + "leagueRankText": "อันดับลีก", + "leagueText": "ลีก", + "rankInLeagueText": "#${RANK} ลีก ${NAME} ${SUFFIX}", + "seasonEndedDaysAgoText": "สิ้นสุดซีซั่นเมื่อ ${NUMBER} วันที่ผ่านมา", + "seasonEndsDaysText": "จะสิ้นสุดซีซั่นในอีก ${NUMBER} วัน", + "seasonEndsHoursText": "จะสิ้นสุดซีซั่นในอีก ${NUMBER} ชั่วโมง", + "seasonEndsMinutesText": "จะสิ้นสุดซีซั่นในอีก ${NUMBER} นาที", + "seasonText": "ซีซั่น ${NUMBER}", + "tournamentLeagueText": "คุณต้องไปถึงลีก ${NAME} เพื่อเข้าร่วมการแข่งขันนี้", + "trophyCountsResetText": "จำนวนถ้วยรางวัลจะรีเซ็ตในซีซั่นหน้า" + }, + "levelBestScoresText": "คะแนนที่ดีที่สุดใน ${LEVEL}", + "levelBestTimesText": "เวลาที่ดีที่สุดใน ${LEVEL}", + "levelIsLockedText": "${LEVEL} ถูกล็อก", + "levelMustBeCompletedFirstText": "${LEVEL} ต้องเสร็จสิ้นก่อน", + "levelText": "ระดับ ${NUMBER}", + "levelUnlockedText": "ปลดล็อคระดับ!", + "livesBonusText": "โบนัสชีวิต", + "loadingText": "กำลังโหลด", + "loadingTryAgainText": "กำลังโหลด; โปรดลองอีกครั้งในอีกสักครู่...", + "macControllerSubsystemBothText": "ทั้งสอง (ไม่แนะนำ)", + "macControllerSubsystemClassicText": "คลาสสิค", + "macControllerSubsystemDescriptionText": "(ลองเปลี่ยนสิ่งนี้หากคอนโทรลเลอร์ของคุณไม่ทำงาน)", + "macControllerSubsystemMFiNoteText": "ตรวจพบคอลโทรลเลอร์ที่สร้างขึ้นสำหรับ iOS/Mac\nคุณอาจต้องการเปิดใช้งานสิ่งเหล่านี้ในการตั้งค่า -> โทรลเลอร์", + "macControllerSubsystemMFiText": "สร้างขึ้นสำหรับ iOS/Mac", + "macControllerSubsystemTitleText": "รองรับคอนโทรลเลอร์", + "mainMenu": { + "creditsText": "เครดิต", + "demoMenuText": "เมนูสาธิต", + "endGameText": "จบเกม", + "endTestText": "สิ้นสุดการทดสอบ", + "exitGameText": "ออกจากเกม", + "exitToMenuText": "จะออกไปหน้าเมนูหรือไม่?", + "howToPlayText": "วิธีการเล่น", + "justPlayerText": "(แค่ ${NAME})", + "leaveGameText": "ออกจากเกม", + "leavePartyConfirmText": "คุณแน่ใจที่จะออกจากปาร์ตี้หรือไม่?", + "leavePartyText": "ออกจากปาร์ตี้", + "quitText": "ออก", + "resumeText": "เล่นต่อ", + "settingsText": "ตั้งค่า" + }, + "makeItSoText": "ใช้", + "mapSelectGetMoreMapsText": "รับแผนที่เพิ่มเติม", + "mapSelectText": "เลือก...", + "mapSelectTitleText": "แผนที่สำหรับเกม ${GAME}", + "mapText": "แผนที่", + "maxConnectionsText": "จำนวนผู้ที่เชื่อมต่อได้สูงสุด", + "maxPartySizeText": "จำนวนคนในปาร์ตี้สูงสุด", + "maxPlayersText": "ผู้เล่นที่เล่นได้สูงสุด", + "modeArcadeText": "โหมดอาเขต", + "modeClassicText": "โหมดคลาสสิก", + "modeDemoText": "โหมดสาธิต", + "mostValuablePlayerText": "ผู้เล่นที่ทำคะแนนมากที่สุด", + "mostViolatedPlayerText": "ผู้เล่นที่ฆ่าน้อยที่สุด", + "mostViolentPlayerText": "ผู้เล่นที่ฆ่ามากที่สุด", + "moveText": "เคลื่อนไหว", + "multiKillText": "ฆ่า ${COUNT}!!!", + "multiPlayerCountText": "ผู้เล่น ${COUNT} คน", + "mustInviteFriendsText": "หมายเหตุ: คุณต้องเชิญเพื่อนใน\nแผง \"${GATHER}\" หรือไฟล์แนบ\nตัวควบคุมเพื่อเล่นหลายคน", + "nameBetrayedText": "${NAME} หักหลัง ${VICTIM}", + "nameDiedText": "${NAME} ตาย", + "nameKilledText": "${NAME} ได้ฆ่า ${VICTIM}", + "nameNotEmptyText": "ชื่อไม่สามารถปล่อยให้ว่างได้!", + "nameScoresText": "${NAME} ทำคะแนน!", + "nameSuicideKidFriendlyText": "${NAME} ตายจากอุบัติเหตุ", + "nameSuicideText": "${NAME} ฆ่าตัวตาย", + "nameText": "ชื่อ", + "nativeText": "พื้นเมือง", + "newPersonalBestText": "ใหม่ส่วนตัวดีที่สุด!", + "newTestBuildAvailableText": "มีการสร้างการทดสอบที่ใหม่กว่า! (${VERSION} บิลด์ ${BUILD})\nรับได้ที่ ${ADDRESS}", + "newText": "ใหม่", + "newVersionAvailableText": "มี ${APP_NAME} เวอร์ชันใหม่แล้ว! (${VERSION})", + "nextAchievementsText": "ความสำเร็จต่อไป:", + "nextLevelText": "ด่านต่อไป", + "noAchievementsRemainingText": "- ไม่มี", + "noContinuesText": "(ไม่มีต่อ)", + "noExternalStorageErrorText": "ไม่พบที่จัดเก็บข้อมูลภายนอกในอุปกรณ์นี้", + "noGameCircleText": "ข้อผิดพลาด: ไม่ได้ลงชื่อเข้าใช้ GameCircle", + "noScoresYetText": "ไม่มีคะแนน", + "noThanksText": "ไม่เป็นไรขอบคุณ", + "noTournamentsInTestBuildText": "คำเตือน: คะแนนการแข่งขันจากรุ่นทดสอบนี้จะถูกละเว้น", + "noValidMapsErrorText": "ไม่พบแผนที่ที่ถูกต้องสำหรับเกมนี้", + "notEnoughPlayersRemainingText": "ไม่มีผู้เล่นเหลือพอ กรุณาออกแล้วเริ่มเกมใหม่", + "notEnoughPlayersText": "คุณต้องการผู้เล่นอย่างน้อย ${COUNT} คนจึงจะเริ่มเกมได้!", + "notNowText": "ไม่ใช่ตอนนี้", + "notSignedInErrorText": "คุณต้องลงชื่อเข้าใช้เพื่อทำสิ่งนี้", + "notSignedInGooglePlayErrorText": "คุณต้องลงชื่อเข้าใช้ Google Play เพื่อดำเนินการนี้", + "notSignedInText": "ไม่ได้ลงชื่อเข้าใช้", + "notUsingAccountText": "หมายเหตุ: ละเว้นบัญชี ${SERVICE}\nไปที่ 'บัญชี -> ลงชื่อเข้าใช้ด้วย ${SERVICE}' หากคุณต้องการ", + "nothingIsSelectedErrorText": "ไม่มีอะไรถูกเลือก!", + "numberText": "#${NUMBER}", + "offText": "ปิด", + "okText": "โอเค", + "onText": "เปิด", + "oneMomentText": "แป๊บนึง...", + "onslaughtRespawnText": "${PLAYER} จะเกิดใหม่ในรอบที่ ${WAVE}", + "orText": "${A} หรือ ${B}", + "otherText": "อื่น...", + "outOfText": "(#${RANK} จาก ${ALL})", + "ownFlagAtYourBaseWarning": "ธงของคุณจะต้องอยู่ที่\nฐานจึงจะทำคะแนนได้!", + "packageModsEnabledErrorText": "การเล่นแบบใช้เน็ตไม่มสามรถใช้งานได้ในเมื่อ \"แพ็คเกจม็อดท้องถิ่น\" กำลังเปิดอยู่ (ดูได้ใน การตั้งค่า-> ขั้นสูง)", + "partyWindow": { + "chatMessageText": "ข้อความแชท", + "emptyText": "ปาร์ตี้ของคุณว่าง", + "hostText": "(หัวหน้าห้อง)", + "sendText": "ส่ง", + "titleText": "ปาร์ตี้ของคุณ" + }, + "pausedByHostText": "(หยุดโดยเจ้าของห้อง)", + "perfectWaveText": "สมบูรณ์แบบ!", + "pickUpText": "หยิบขึ้นมา", + "playModes": { + "coopText": "ร่วมมือกัน", + "freeForAllText": "เล่นแบบอิสระ", + "multiTeamText": "เล่นแบบทีม", + "singlePlayerCoopText": "เล่นคนเดียวหรือแบบร่วมมือกัน", + "teamsText": "เล่นแบบทีม" + }, + "playText": "เล่น", + "playWindow": { + "oneToFourPlayersText": "1-4 คน", + "titleText": "เล่น", + "twoToEightPlayersText": "2-8 คน" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} จะเข้าร่วมเกมในรอบต่อไป", + "playerInfoText": "ข้อมูลผู้เล่น", + "playerLeftText": "${PLAYER} ออกจากเกม", + "playerLimitReachedText": "ผู้เล่นเต็ม ${COUNT} คนแล้ว ไม่สามารถเข้าร่วมได้", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "คุณไม่สามารถลบโปรไฟล์ของบัญชีได้", + "deleteButtonText": "ลบ\nโปรไฟล์", + "deleteConfirmText": "คุณแน่ใจที่จะลบ '${PROFILE}' หรือไม่?", + "editButtonText": "แก้ไข\nโปรไฟล์", + "explanationText": "(กำหนดชื่อและตัวละครเองสำหรับผู้เล่นในบัญชีนี้)", + "newButtonText": "สร้าง\nโปรไฟล์ใหม่", + "titleText": "โปรไฟล์ผู้เล่น" + }, + "playerText": "ผู้เล่น", + "playlistNoValidGamesErrorText": "เพลย์ลิสนี้ไม่ได้ใส่เกมที่ปลดล็อคแล้วเลย", + "playlistNotFoundText": "ไม่พบเพลย์ลิส", + "playlistText": "เพลย์ลิสต์", + "playlistsText": "เพลย์ลิส", + "pleaseRateText": "หากคุณชอบ ${APP_NAME} โปรดพิจารณาใช้ a\nและให้คะแนนหรือเขียนรีวิว นี้ให้\nข้อเสนอแนะที่เป็นประโยชน์และช่วยสนับสนุนการพัฒนาในอนาคต\n\nขอบใจ!\n-eric", + "pleaseWaitText": "โปรดรอ...", + "pluginClassLoadErrorText": "เกิดข้อผิดพลาดในการโหลดคลาสปลั๊กอิน '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "เกิดข้อผิดพลาดในการเริ่มต้นปลั๊กอิน '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "ตรวจพบปลั๊กอินใหม่ รีสตาร์ทเกมเพื่อเปิดใช้งาน หรือกำหนดค่าได้ในการตั้งค่า", + "pluginsRemovedText": "ไม่พบปลั๊กอิน ${NUM} รายการอีกต่อไป", + "pluginsText": "ปลั๊กอิน", + "practiceText": "ฝึกฝน", + "pressAnyButtonPlayAgainText": "กดปุ่มใดก็ได้เพื่อเล่นอีกครั้ง...", + "pressAnyButtonText": "กดปุ่มใดก็ได้เพื่อไปต่อ...", + "pressAnyButtonToJoinText": "กดปุ่มใดก็ได้เพื่อเข้าร่วม...", + "pressAnyKeyButtonPlayAgainText": "กดปุ่มใดก็ได้เพื่อเล่นอีกครั้ง...", + "pressAnyKeyButtonText": "กดปุ่มใดๆก็ได้ เพื่อดำเนินการต่อ...", + "pressAnyKeyText": "กดปุ่มใดก็ได้...", + "pressJumpToFlyText": "**กดกระโดดซ้ำๆเพื่อโบยบิน**", + "pressPunchToJoinText": "กด ต่อย เพื่อเข้าร่วม...", + "pressToOverrideCharacterText": "กด ${BUTTONS} เพื่อแทนที่ตัวละครของคุณ", + "pressToSelectProfileText": "กด ${BUTTONS} เพื่อเลือกผู้เล่น", + "pressToSelectTeamText": "กด ${BUTTONS} เพื่อเลือกทีม", + "promoCodeWindow": { + "codeText": "รหัส", + "enterText": "ถัดไป" + }, + "promoSubmitErrorText": "เกิดข้อผิดพลาดในการส่งรหัส ตรวจสอบการเชื่อมต่ออินเทอร์เน็ตของคุณ", + "ps3ControllersWindow": { + "macInstructionsText": "ปิดสวิตช์ที่ด้านหลัง PS3 ของคุณ ตรวจสอบให้แน่ใจ\nMac ของคุณเปิดใช้งาน Bluetooth แล้ว จากนั้นเชื่อมต่อคอนโทรลเลอร์ของคุณ\nกับ Mac ของคุณผ่านสาย USB เพื่อจับคู่ทั้งสองเครื่อง ตั้งแต่นั้นมา คุณ\nสามารถใช้ปุ่มโฮมของคอนโทรลเลอร์เพื่อเชื่อมต่อกับ Mac ของคุณ\nในโหมดมีสาย (USB) หรือไร้สาย (Bluetooth)\n\nใน Mac บางเครื่อง คุณอาจได้รับแจ้งให้ป้อนรหัสผ่านเมื่อจับคู่\nหากเกิดเหตุการณ์นี้ โปรดดูบทช่วยสอนต่อไปนี้หรือ google เพื่อขอความช่วยเหลือ\n\n\n\n\nคอนโทรลเลอร์ PS3 ที่เชื่อมต่อแบบไร้สายควรปรากฏขึ้นในอุปกรณ์\nรายการใน System Preferences->Bluetooth คุณอาจต้องลบออก\nจากรายการนั้นเมื่อคุณต้องการใช้กับ PS3 ของคุณอีกครั้ง\n\nตรวจสอบให้แน่ใจว่าได้ยกเลิกการเชื่อมต่อจาก Bluetooth เมื่อไม่อยู่ใน\nใช้งานไม่เช่นนั้นแบตเตอรี่จะสิ้นเปลืองต่อไป\n\nBluetooth ควรรองรับอุปกรณ์ที่เชื่อมต่อถึง 7 เครื่อง\nแม้ว่าระยะทางของคุณอาจแตกต่างกันไป", + "ouyaInstructionsText": "ในการใช้คอนโทรลเลอร์ PS3 กับ OUYA ของคุณ เพียงแค่เชื่อมต่อด้วยสาย USB\nครั้งเดียวเพื่อจับคู่ การทำเช่นนี้อาจตัดการเชื่อมต่อคอนโทรลเลอร์อื่นของคุณ ดังนั้น\nจากนั้นคุณควรรีสตาร์ท OUYA และถอดสาย USB\n\nจากนั้นคุณควรจะสามารถใช้ปุ่ม HOME ของคอนโทรลเลอร์เพื่อ\nเชื่อมต่อแบบไร้สาย เมื่อคุณเล่นเสร็จแล้ว ให้กดปุ่ม HOME ค้างไว้\nเป็นเวลา 10 วินาทีเพื่อปิดคอนโทรลเลอร์ มิฉะนั้นอาจยังคงอยู่ใน\nและเปลืองแบตเตอรี่", + "pairingTutorialText": "วิดีโอแนะนำการจับคู่", + "titleText": "การใช้คอนโทรลเลอร์ PS3 กับ ${APP_NAME}:" + }, + "punchBoldText": "ต่อย", + "punchText": "ต่อย", + "purchaseForText": "ซื้อในราคา ${PRICE}", + "purchaseGameText": "ซื้อเกม", + "purchasingText": "กำลังจัดซื้อ...", + "quitGameText": "ออกจาก ${APP_NAME} ไหม?", + "quittingIn5SecondsText": "ออกจากระบบใน 5 วินาที...", + "randomPlayerNamesText": "ชื่อเริ่มต้น", + "randomText": "สุ่ม", + "rankText": "อันดับ", + "ratingText": "เรตติ้ง", + "reachWave2Text": "ไปถึงเวฟ 2 เพื่อจัดอันดับ", + "readyText": "พร้อม", + "recentText": "ล่าสุด", + "remoteAppInfoShortText": "${APP_NAME} จะสนุกที่สุดเมื่อเล่นกับครอบครัวและเพื่อนๆ\nเชื่อมต่อคอนโทรลเลอร์ฮาร์ดแวร์อย่างน้อยหนึ่งตัวหรือติดตั้ง\nแอป ${REMOTE_APP_NAME} บนโทรศัพท์หรือแท็บเล็ตเพื่อใช้งาน\nเป็นคอนโทรลเลอร์", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "ตำแหน่งปุ่ม", + "button_size": "ขนาดปุ่ม", + "cant_resolve_host": "ไม่สามารถแก้ไขโฮสต์", + "capturing": "กำลังจับภาพ...", + "connected": "เชื่อมต่อแล้ว", + "description": "ใช้โทรศัพท์หรือแท็บเล็ตของคุณเป็นตัวควบคุมด้วย BombSquad\nสามารถเชื่อมต่ออุปกรณ์สูงสุด 8 เครื่องพร้อมกันเพื่อความคลั่งไคล้ผู้เล่นหลายคนในท้องถิ่นบนทีวีหรือแท็บเล็ตเครื่องเดียว", + "disconnected": "ตัดการเชื่อมต่อโดยเซิร์ฟเวอร์", + "dpad_fixed": "แก้ไขแล้ว", + "dpad_floating": "ลอยตัว", + "dpad_position": "ตำแหน่ง D-Pad", + "dpad_size": "ขนาด D-Pad", + "dpad_type": "ประเภท D-Pad", + "enter_an_address": "ใส่ที่อยู่", + "game_full": "เกมเต็มหรือไม่ยอมรับการเชื่อมต่อ", + "game_shut_down": "เกมปิดตัวลงแล้ว", + "hardware_buttons": "ปุ่มฮาร์ดแวร์", + "join_by_address": "เข้าร่วมตามที่อยู่…", + "lag": "ล่าช้า: ${SECONDS} วินาที", + "reset": "รีเซ็ตเป็นค่าเริ่มต้น", + "run1": "วิ่ง 1", + "run2": "วิ่ง 2", + "searching": "กำลังค้นหาเกม BombSquad...", + "searching_caption": "แตะที่ชื่อเกมเพื่อเข้าร่วม\nตรวจสอบให้แน่ใจว่าคุณอยู่ในเครือข่าย wifi เดียวกันกับเกม", + "start": "เริ่ม", + "version_mismatch": "เวอร์ชั่นตรงกัน.\nตรวจสอบให้แน่ใจว่า BombSquad และ BombSquad Remote\nเป็นเวอร์ชันล่าสุดแล้วลองอีกครั้ง" + }, + "removeInGameAdsText": "ปลดล็อก \"${PRO}\" ในร้านค้าเพื่อลบโฆษณาในเกม", + "renameText": "เปลี่ยนชื่อ", + "replayEndText": "สิ้นสุดการเล่นซ้ำ", + "replayNameDefaultText": "รีเพลย์เกมล่าสุด", + "replayReadErrorText": "เกิดข้อผิดพลาดในการอ่านไฟล์เล่นซ้ำ", + "replayRenameWarningText": "เปลี่ยนชื่อ \"${REPLAY}\" หลังเกมหากคุณต้องการเก็บไว้ มิฉะนั้นจะถูกเขียนทับ", + "replayVersionErrorText": "ขออภัย เล่นซ้ำนี้ทำในรูปแบบอื่น\nเวอร์ชั่นเกมแล้วใช้ไม่ได้", + "replayWatchText": "ดูรีเพลย์", + "replayWriteErrorText": "เกิดข้อผิดพลาดในการเขียนไฟล์เล่นซ้ำ", + "replaysText": "เล่นซ้ำ", + "reportPlayerExplanationText": "ใช้อีเมลนี้เพื่อรายงานการโกง ภาษาที่ไม่เหมาะสม หรือพฤติกรรมที่ไม่ดีอื่นๆ\nโปรดอธิบายด้านล่าง:", + "reportThisPlayerCheatingText": "โกง", + "reportThisPlayerLanguageText": "ภาษาที่ไม่เหมาะสม", + "reportThisPlayerReasonText": "คุณต้องการรายงานอะไร", + "reportThisPlayerText": "รายงานผู้เล่นคนนี้", + "requestingText": "กำลังขอ...", + "restartText": "เริ่มต้นใหม่", + "retryText": "ลองอีกครั้ง", + "revertText": "ย้อนกลับ", + "runText": "วิ่ง", + "saveText": "บันทึก", + "scanScriptsErrorText": "ข้อผิดพลาดในการสแกนสคริปต์; ดูบันทึกสำหรับรายละเอียด", + "scoreChallengesText": "คะแนนความท้าทาย", + "scoreListUnavailableText": "ไม่มีรายการคะแนน", + "scoreText": "คะแนน", + "scoreUnits": { + "millisecondsText": "มิลลิวินาที", + "pointsText": "คะแนน", + "secondsText": "วินาที" + }, + "scoreWasText": "(เดิมคือ ${COUNT})", + "selectText": "เลือก", + "seriesWinLine1PlayerText": "ชนะ", + "seriesWinLine1TeamText": "ชนะ", + "seriesWinLine1Text": "ชนะ", + "seriesWinLine2Text": "ซีรีส์", + "settingsWindow": { + "accountText": "บัญชี", + "advancedText": "ขั้นสูง", + "audioText": "เสียง", + "controllersText": "คอนโทรลเลอร์", + "graphicsText": "กราฟิก", + "playerProfilesMovedText": "หมายเหตุ: โปรไฟล์ผู้เล่นได้ย้ายไปที่หน้าต่างบัญชีในเมนูหลัก", + "titleText": "ตั้งค่า" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(แป้นพิมพ์บนหน้าจอที่เรียบง่ายและเป็นมิตรกับตัวควบคุมสำหรับการแก้ไขข้อความ)", + "alwaysUseInternalKeyboardText": "ใช้แป้นพิมพ์ภายในเสมอ", + "benchmarksText": "เกณฑ์มาตรฐานและการทดสอบความเครียด", + "disableCameraGyroscopeMotionText": "ปิดใช้งานการเคลื่อนไหวของกล้อง Gyroscope", + "disableCameraShakeText": "ปิดใช้งานการสั่นของกล้อง", + "disableThisNotice": "(คุณสามารถปิดการใช้งานประกาศนี้ในการตั้งค่าขั้นสูง)", + "enablePackageModsDescriptionText": "(การเปิดใช้งานที่ทำให้ใช้ม็อดได้หลากหลายมากขึ้นแต่จะปิดระบบการเล่นแบบใช้เน็ต)", + "enablePackageModsText": "เปิดแพ็คเกจม็อดท้องถิ่น", + "enterPromoCodeText": "ใส่รหัส", + "forTestingText": "หมายเหตุ: ค่าเหล่านี้ใช้สำหรับการทดสอบเท่านั้นและจะสูญหายไปเมื่อออกจากแอป", + "helpTranslateText": "การแปลที่ไม่ใช่ภาษาอังกฤษของ ${APP_NAME} เป็นชุมชน\nสนับสนุนความพยายาม หากคุณต้องการมีส่วนร่วมหรือแก้ไข\nแปลตามลิงค์ด้านล่างครับ ขอบคุณล่วงหน้า!", + "kickIdlePlayersText": "เตะผู้เล่นที่ไม่ได้ใช้งาน", + "kidFriendlyModeText": "โหมดเป็นมิตรกับเด็ก (ลดความรุนแรง ฯลฯ)", + "languageText": "ภาษา", + "moddingGuideText": "คู่มือการม็อด", + "mustRestartText": "คุณต้องเริ่มเกมใหม่เพื่อให้สิ่งนี้มีผล", + "netTestingText": "การทดสอบเครือข่าย", + "resetText": "รีเซ็ต", + "showBombTrajectoriesText": "แสดงวิถีลูกระเบิด", + "showPlayerNamesText": "แสดงชื่อผู้เล่น", + "showUserModsText": "แสดงโฟลเดอร์ Mods", + "titleText": "ขั้นสูง", + "translationEditorButtonText": "${APP_NAME} ผู้แก้ไขการแปล", + "translationFetchErrorText": "สถานะการแปลไม่พร้อมใช้งาน", + "translationFetchingStatusText": "กำลังตรวจสอบสถานะการแปล...", + "translationInformMe": "แจ้งฉันเมื่อภาษาของฉันต้องการการอัปเดต", + "translationNoUpdateNeededText": "ภาษาปัจจุบันเป็นปัจจุบัน วู้ฮู!", + "translationUpdateNeededText": "** ภาษาปัจจุบันต้องการการอัปเดต !! **", + "vrTestingText": "การทดสอบ VR" + }, + "shareText": "แบ่งปัน", + "sharingText": "การแบ่งปัน...", + "showText": "แสดง", + "signInForPromoCodeText": "คุณต้องลงชื่อเข้าใช้บัญชีเพื่อให้รหัสมีผล", + "signInWithGameCenterText": "ในการใช้บัญชี Game Center\nลงชื่อเข้าใช้ด้วยแอพ Game Center", + "singleGamePlaylistNameText": "แค่ ${GAME}", + "singlePlayerCountText": "ผู้เล่น 1 คน", + "soloNameFilterText": "เดี่ยว ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "การเลือกตัวละคร", + "Chosen One": "ผู้ถูกเลือก", + "Epic": "เกมโหมดมหากาพย์", + "Epic Race": "มหากาพย์การแข่งขัน", + "FlagCatcher": "ยึดธง", + "Flying": "ความคิดที่เป็นสุข", + "Football": "ฟุตบอล", + "ForwardMarch": "จู่โจม", + "GrandRomp": "พิชิต", + "Hockey": "ฮอกกี้", + "Keep Away": "ระวังอย่าเข้าไปใกล้", + "Marching": "วิ่งไปรอบ ๆ", + "Menu": "เมนูหลัก", + "Onslaught": "การโจมตี", + "Race": "แข่ง", + "Scary": "ราชาแห่งขุนเขา", + "Scores": "หน้าจอคะแนน", + "Survival": "กำจัด", + "ToTheDeath": "นัดสุดท้าย", + "Victory": "หน้าจอคะแนนสุดท้าย" + }, + "spaceKeyText": "เว้นวรรค", + "statsText": "ข้อมูล", + "storagePermissionAccessText": "สิ่งนี้ต้องการการเข้าถึงที่เก็บข้อมูล", + "store": { + "alreadyOwnText": "คุณเป็นเจ้าของ ${NAME} แล้ว!", + "bombSquadProNameText": "${APP_NAME} โปร", + "bombSquadProNewDescriptionText": "• ลบโฆษณาในเกมและหน้าจอจู้จี้\n• ปลดล็อกการตั้งค่าเกมเพิ่มเติม\n• รวมถึง:", + "buyText": "ซื้อ", + "charactersText": "ตัวละคร", + "comingSoonText": "เร็ว ๆ นี้...", + "extrasText": "พิเศษ", + "freeBombSquadProText": "BombSquad เปิดให้เล่นฟรีแล้ว แต่เนื่องจากคุณซื้อมันมาในตอนแรก คุณจึงกลายเป็น\nรับการอัปเกรด BombSquad Pro และตั๋ว ${COUNT} เป็นการขอบคุณ\nเพลิดเพลินกับคุณสมบัติใหม่ และขอขอบคุณสำหรับการสนับสนุนของคุณ!\n-เอริค", + "holidaySpecialText": "วันหยุดพิเศษ", + "howToSwitchCharactersText": "(ไปที่ \"${SETTINGS} -> ${PLAYER_PROFILES}\" เพื่อกำหนดและปรับแต่งตัวละคร)", + "howToUseIconsText": "(สร้างโปรไฟล์ผู้เล่นทั่วโลก (ในหน้าต่างบัญชี) เพื่อใช้สิ่งเหล่านี้)", + "howToUseMapsText": "(ใช้แผนที่เหล่านี้ในทีมของคุณเอง/เพลย์ลิสต์ฟรีสำหรับทุกคน)", + "iconsText": "ไอคอน", + "loadErrorText": "ไม่สามารถโหลดหน้า\nตรวจสอบการเชื่อมต่ออินเทอร์เน็ตของคุณ", + "loadingText": "กำลังโหลด", + "mapsText": "แผนที่", + "miniGamesText": "มินิเกม", + "oneTimeOnlyText": "(ครั้งเดียวเท่านั้น)", + "purchaseAlreadyInProgressText": "การสั่งซื้อรายการนี้อยู่ระหว่างดำเนินการ", + "purchaseConfirmText": "คุณแน่ใจที่จะสั่งซื้อ ${ITEM} หรือไม่?", + "purchaseNotValidError": "สั่งซื้อไม่สำเร็จ\nติดต่อ ${EMAIL} ถ้าสิ่งนี้เป็นข้อผิดพลาด", + "purchaseText": "สั่งซื้อ", + "saleBundleText": "ขายยกชุด!", + "saleExclaimText": "ขาย!", + "salePercentText": "(ลด ${PERCENT}%)", + "saleText": "ลดราคา", + "searchText": "ค้นหา", + "teamsFreeForAllGamesText": "ทีม / เดี่ยว", + "totalWorthText": "*** มูลค่า ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "อัพเกรด?", + "winterSpecialText": "พิเศษฤดูหนาว", + "youOwnThisText": "- คุณเป็นเจ้าของสิ่งนี้ -" + }, + "storeDescriptionText": "8 ผู้เล่นปาร์ตี้เกมบ้า!\n\nระเบิดเพื่อนของคุณ (หรือคอมพิวเตอร์) ในทัวร์นาเมนต์มินิเกมระเบิดเช่น Capture-the-Flag, Bomber-Hockey และ Epic-Slow-Motion-Death-Match!\n\nการควบคุมที่เรียบง่ายและการรองรับคอนโทรลเลอร์ที่ครอบคลุมทำให้ผู้คนมากถึง 8 คนสามารถลงมือได้ คุณยังสามารถใช้อุปกรณ์มือถือของคุณเป็นตัวควบคุมผ่านแอพ 'BombSquad Remote' ฟรี!\n\nระเบิดออกไป!\n\nตรวจสอบ www.froemling.net/bombsquad สำหรับข้อมูลเพิ่มเติม", + "storeDescriptions": { + "blowUpYourFriendsText": "ระเบิดเพื่อนของคุณ", + "competeInMiniGamesText": "แข่งขันในมินิเกมตั้งแต่การแข่งรถไปจนถึงการบิน", + "customize2Text": "ปรับแต่งตัวละคร มินิเกม และแม้แต่เพลงประกอบ", + "customizeText": "ปรับแต่งตัวละครและสร้างรายการเล่นมินิเกมของคุณเอง", + "sportsMoreFunText": "กีฬาสนุกยิ่งขึ้นด้วยระเบิด", + "teamUpAgainstComputerText": "ร่วมทีมกับคอมพิวเตอร์" + }, + "storeText": "ร้านค้า", + "submitText": "ส่ง", + "submittingPromoCodeText": "กำลังส่งรหัส...", + "teamNamesColorText": "Team Names/Colors...", + "telnetAccessGrantedText": "เปิดใช้งานการเข้าถึง Telnet", + "telnetAccessText": "ตรวจพบการเข้าถึง Telnet; อนุญาต?", + "testBuildErrorText": "รุ่นทดสอบนี้ไม่ทำงานอีกต่อไป โปรดตรวจสอบเวอร์ชันใหม่", + "testBuildText": "ทดสอบบิลด์", + "testBuildValidateErrorText": "ไม่สามารถตรวจสอบการสร้างการทดสอบ (ไม่มีการเชื่อมต่อเน็ต?)", + "testBuildValidatedText": "ทดสอบบิลด์ที่ตรวจสอบแล้ว; สนุก!", + "thankYouText": "ขอบคุณสำหรับการสนับสนุนของคุณ! สนุกกับเกม!!", + "threeKillText": "ฆ่าสามครั้ง!!", + "timeBonusText": "โบนัสเวลา", + "timeElapsedText": "เวลาที่ผ่านไป", + "timeExpiredText": "เวลาหมด", + "timeSuffixDaysText": "${COUNT}ว", + "timeSuffixHoursText": "${COUNT}ชม", + "timeSuffixMinutesText": "${COUNT}น", + "timeSuffixSecondsText": "${COUNT}วิ", + "tipText": "เคล็ดลับ", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "เพื่อนที่ดีที่สุด", + "tournamentCheckingStateText": "การตรวจสอบสถานะการแข่งขัน โปรดรอ...", + "tournamentEndedText": "การแข่งขันนี้สิ้นสุดลงแล้ว ใหม่จะเริ่มเร็ว ๆ นี้", + "tournamentEntryText": "รายการแข่งขัน", + "tournamentResultsRecentText": "ผลการแข่งขันล่าสุด", + "tournamentStandingsText": "อันดับการแข่งขัน", + "tournamentText": "การแข่งขัน", + "tournamentTimeExpiredText": "เวลาการแข่งขันหมดอายุ", + "tournamentsDisabledWorkspaceText": "การแข่งขันจะถูกปิดการใช้งานเมื่อมีการใช้งานพื้นที่ทำงาน \nหากต้องการเปิดใช้งานการแข่งขันอีกครั้ง ให้ปิดใช้งานพื้นที่ทำงานของคุณแล้วเริ่มใหม่", + "tournamentsText": "การแข่งขัน", + "translations": { + "characterNames": { + "Agent Johnson": "Agent Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Bones", + "Butch": "Butch", + "Easter Bunny": "Easter Bunny", + "Flopsy": "Flopsy", + "Frosty": "Frosty", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Middle-Man", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Santa Claus", + "Snake Shadow": "Snake Shadow", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao Mascot", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} การฝึกซ้อม", + "Infinite ${GAME}": "ไม่มีที่สิ้นสุด ${GAME}", + "Infinite Onslaught": "การโจมตีที่ไม่มีที่สิ้นสุด", + "Infinite Runaround": "วิ่งรอบ ๆ ไม่มีที่สิ้นสุด", + "Onslaught Training": "การฝึกจู่โจม", + "Pro ${GAME}": "โปร ${GAME}", + "Pro Football": "โปรฟุตบอล", + "Pro Onslaught": "โปรจู่โจม", + "Pro Runaround": "โปรวิ่งรอบ ๆ", + "Rookie ${GAME}": "มือใหม่ ${GAME}", + "Rookie Football": "ฟุตบอลมือใหม่", + "Rookie Onslaught": "มือใหม่จู่โจม", + "The Last Stand": "ยืนสุดท้าย", + "Uber ${GAME}": "Uber ${GAME}", + "Uber Football": "Uber Football", + "Uber Onslaught": "Uber Onslaught", + "Uber Runaround": "Uber Runaround" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "เป็นผู้ที่ได้รับเลือกเป็นระยะเวลาหนึ่งเพื่อชนะ\nฆ่าคนที่ถูกเลือกให้เป็น", + "Bomb as many targets as you can.": "วางระเบิดเป้าหมายให้ได้มากที่สุด", + "Carry the flag for ${ARG1} seconds.": "ถือธงเป็นเวลา ${ARG1} วินาที", + "Carry the flag for a set length of time.": "ถือธงตามระยะเวลาที่กำหนด", + "Crush ${ARG1} of your enemies.": "บดขยี้ศัตรูของคุณ ${ARG1} คน", + "Defeat all enemies.": "เอาชนะศัตรูทั้งหมด", + "Dodge the falling bombs.": "หลบระเบิดที่ตกลงมา", + "Final glorious epic slow motion battle to the death.": "มหากาพย์การต่อสู้แบบสโลว์โมชั่นสุดท้ายอันรุ่งโรจน์สู่ความตาย", + "Gather eggs!": "เก็บไข่!", + "Get the flag to the enemy end zone.": "ถือธงไปยังฐานของศัตรู", + "How fast can you defeat the ninjas?": "คุณสามารถเอาชนะนินจาได้เร็วแค่ไหน?", + "Kill a set number of enemies to win.": "ฆ่าศัตรูตามจำนวนที่กำหนดเพื่อชนะ", + "Last one standing wins.": "รอดคนสุดท้ายชนะ", + "Last remaining alive wins.": "ชัยชนะที่เหลืออยู่", + "Last team standing wins.": "รอดทีมสุดท้ายชนะ", + "Prevent enemies from reaching the exit.": "ป้องกันไม่ให้ศัตรูไปถึงทางออก", + "Reach the enemy flag to score.": "ถือธงศัตรูเพื่อทำคะแนน", + "Return the enemy flag to score.": "ส่งธงศัตรูคืนเพื่อทำคะแนน", + "Run ${ARG1} laps.": "วิ่ง ${ARG1} รอบ", + "Run ${ARG1} laps. Your entire team has to finish.": "วิ่ง ${ARG1} รอบ ทีมของคุณทั้งหมดต้องเข้าเส้นชัย", + "Run 1 lap.": "วิ่ง 1 รอบ", + "Run 1 lap. Your entire team has to finish.": "วิ่ง 1 รอบ ทีมของคุณทั้งหมดต้องเข้าเส้นชัย", + "Run real fast!": "วิ่งเร็วจริง!", + "Score ${ARG1} goals.": "ทำประตูได้ ${ARG1} ประตู", + "Score ${ARG1} touchdowns.": "ทำคะแนน ${ARG1} ทัชดาวน์", + "Score a goal.": "ทำประตู", + "Score a touchdown.": "ทำแต้มทัชดาวน์", + "Score some goals.": "ทำประตูได้บ้าง", + "Secure all ${ARG1} flags.": "ยึด ${ARG1} ธง", + "Secure all flags on the map to win.": "ยึดธงทั้งหมดบนแผนที่เพื่อชนะ", + "Secure the flag for ${ARG1} seconds.": "ยึดธงไว้เป็นเวลา ${ARG1} วินาที", + "Secure the flag for a set length of time.": "ยึดธงไว้ตามระยะเวลาที่กำหนด", + "Steal the enemy flag ${ARG1} times.": "ขโมยธงของศัตรู ${ARG1} ครั้ง", + "Steal the enemy flag.": "ขโมยธงศัตรู", + "There can be only one.": "สามารถมีได้เพียงคนเดียว", + "Touch the enemy flag ${ARG1} times.": "แตะธงศัตรู ${ARG1} ครั้ง", + "Touch the enemy flag.": "แตะธงศัตรู", + "carry the flag for ${ARG1} seconds": "ถือธงเป็นเวลา ${ARG1} วินาที", + "kill ${ARG1} enemies": "ฆ่าศัตรู ${ARG1} คน", + "last one standing wins": "รอดคนสุดท้ายชนะ", + "last team standing wins": "รอดทีมสุดท้ายชนะ", + "return ${ARG1} flags": "ส่งคืน ${ARG1} ธง", + "return 1 flag": "ส่งคืน 1 ธง", + "run ${ARG1} laps": "วิ่ง ${ARG1} รอบ", + "run 1 lap": "วิ่ง 1 รอบ", + "score ${ARG1} goals": "ทำประตูได้ ${ARG1} ประตู", + "score ${ARG1} touchdowns": "ทำคะแนน ${ARG1} ทัชดาวน์", + "score a goal": "ทำประตู", + "score a touchdown": "ทำแต้มทัชดาวน์", + "secure all ${ARG1} flags": "ยึด ${ARG1} ธง", + "secure the flag for ${ARG1} seconds": "ยึดธงไว้เป็นเวลา ${ARG1} วินาที", + "touch ${ARG1} flags": "แตะ ${ARG1} ธง", + "touch 1 flag": "แตะ ${ARG1} ธง" + }, + "gameNames": { + "Assault": "จู่โจม", + "Capture the Flag": "ยึดธง", + "Chosen One": "ผู้ถูกเลือก", + "Conquest": "พิชิต", + "Death Match": "นัดสุดท้าย", + "Easter Egg Hunt": "การล่าไข่อิสเตอร์", + "Elimination": "การกำจัด", + "Football": "ฟุตบอล", + "Hockey": "ฮอกกี้", + "Keep Away": "ระวังอย่าเข้าไปใกล้", + "King of the Hill": "ราชาแห่งขุนเขา", + "Meteor Shower": "ฝนดาวตก", + "Ninja Fight": "นินจาต่อสู้", + "Onslaught": "การโจมตี", + "Race": "แข่งขัน", + "Runaround": "วิ่งไปรอบ ๆ", + "Target Practice": "ฝึกเล็งเป้าหมาย", + "The Last Stand": "รอดคนสุดท้าย" + }, + "inputDeviceNames": { + "Keyboard": "แป้นพิมพ์", + "Keyboard P2": "แป้นพิมพ์ คนที่ 2" + }, + "languages": { + "Arabic": "ภาษาอารบิก", + "Belarussian": "ภาษาเบลารุส", + "Chinese": "ภาษาจีนตัวย่อ", + "ChineseTraditional": "ภาษาจีนดั้งเดิม", + "Croatian": "ภาษาโครเอเชีย", + "Czech": "ภาษาเช็ก", + "Danish": "ภาษาเดนมาร์ก", + "Dutch": "ภาษาดัตช์", + "English": "ภาษาอังกฤษ", + "Esperanto": "ภาษาเอสเปรันโต", + "Filipino": "ภาษาฟิลิปปินส์", + "Finnish": "ภาษาฟินแลนด์", + "French": "ภาษาฝรั่งเศส", + "German": "ภาษาเยอรมัน", + "Gibberish": "พูดไรสาระ", + "Greek": "ภาษากรีก", + "Hindi": "ภาษาฮินดู", + "Hungarian": "ภาษาฮังการี", + "Indonesian": "ภาษาอินโดนีเซีย", + "Italian": "ภาษาอิตาลี", + "Japanese": "ภาษาญี่ปุ่น", + "Korean": "ภาษาเกาหลี", + "Persian": "ภาษาเปอร์เซีย", + "Polish": "ภาษาโปแลนด์", + "Portuguese": "ภาษาโปรตุเกส", + "Romanian": "ภาษาโรมาเนีย", + "Russian": "ภาษารัสเซีย", + "Serbian": "ภาษาเซอร์เบีย", + "Slovak": "ภาษาสโลวัก", + "Spanish": "ภาษาสเปน", + "Swedish": "ภาษาสวีเดน", + "Tamil": "ภาษาทมิฬ", + "Thai": "ภาษาไทย", + "Turkish": "ภาษาตุรกี", + "Ukrainian": "ยูเครน", + "Venetian": "ภาษาเวนิส", + "Vietnamese": "ภาษาเวียดนาม" + }, + "leagueNames": { + "Bronze": "บรอนซ์", + "Diamond": "ไดมอนด์", + "Gold": "โกลด์", + "Silver": "ซิลเวอร์" + }, + "mapsNames": { + "Big G": "บิ๊ก จี", + "Bridgit": "บริดจิต", + "Courtyard": "ลาน", + "Crag Castle": "ปราสาท แคร็ก", + "Doom Shroom": "ดูมชรูม", + "Football Stadium": "สนามฟุตบอล", + "Happy Thoughts": "ความคิดที่เป็นสุข", + "Hockey Stadium": "สนามฮอกกี้", + "Lake Frigid": "ทะเลสาบฟริจิด", + "Monkey Face": "หน้าลิง", + "Rampage": "อาละวาด", + "Roundabout": "วงเวียน", + "Step Right Up": "ก้าวขวาขึ้น", + "The Pad": "แพด", + "Tip Top": "ทิปท็อป", + "Tower D": "ทาวเวอร์ ดี", + "Zigzag": "ซิกแซก" + }, + "playlistNames": { + "Just Epic": "แค่มหากาพย์", + "Just Sports": "แค่กีฬา" + }, + "scoreNames": { + "Flags": "ธง", + "Goals": "ประตู", + "Score": "คะแนน", + "Survived": "รอด", + "Time": "เวลา", + "Time Held": "เวลาที่ถือไว้" + }, + "serverResponses": { + "A code has already been used on this account.": "มีการใช้รหัสในบัญชีนี้แล้ว", + "A reward has already been given for that address.": "ได้รับรางวัลสำหรับที่อยู่นั้นแล้ว", + "Account linking successful!": "เชื่อมโยงบัญชีสำเร็จ!", + "Account unlinking successful!": "ยกเลิกการเชื่อมโยงบัญชีสำเร็จ!", + "Accounts are already linked.": "บัญชีถูกเชื่อมโยงแล้ว", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "ไม่สามารถตรวจสอบการดูโฆษณาได้\nโปรดตรวจสอบให้แน่ใจว่าคุณกำลังใช้งานเกมเวอร์ชันที่เป็นทางการและเป็นปัจจุบัน", + "An error has occurred; (${ERROR})": "เกิดข้อผิดพลาด; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "เกิดข้อผิดพลาด; โปรดติดต่อฝ่ายสนับสนุน (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "เกิดข้อผิดพลาด; โปรดติดต่อ support@froemling.net", + "An error has occurred; please try again later.": "เกิดข้อผิดพลาด; โปรดลองอีกครั้งในภายหลัง.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "คุณแน่ใจหรือไม่ว่าต้องการเชื่อมโยงบัญชีเหล่านี้\n\n${ACCOUNT1}\n${ACCOUNT2} \n\nสิ่งนี้ไม่สามารถยกเลิกได้!", + "BombSquad Pro unlocked!": "BombSquad Pro ปลดล็อคแล้ว!", + "Can't link 2 accounts of this type.": "ไม่สามารถเชื่อมโยง 2 บัญชีประเภทนี้", + "Can't link 2 diamond league accounts.": "ไม่สามารถเชื่อมโยงบัญชีลีกไดมอนด์ 2 บัญชีได้", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "ไม่สามารถเชื่อมโยง; จะเกินบัญชีที่เชื่อมโยงสูงสุด ${COUNT} บัญชี", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "ตรวจพบการโกง; คะแนนและรางวัลถูกระงับเป็นเวลา ${COUNT} วัน", + "Could not establish a secure connection.": "ไม่สามารถสร้างการเชื่อมต่อที่ปลอดภัย", + "Daily maximum reached.": "ถึงสูงสุดรายวันแล้ว", + "Entering tournament...": "เข้าสู่การแข่งขัน...", + "Invalid code.": "รหัสไม่ถูกต้อง", + "Invalid payment; purchase canceled.": "การชำระเงินไม่ถูกต้อง การซื้อถูกยกเลิก", + "Invalid promo code.": "รหัสโปรโหมทไม่ถูกต้อง", + "Invalid purchase.": "การซื้อที่ไม่ถูกต้อง", + "Invalid tournament entry; score will be ignored.": "รายการทัวร์นาเมนต์ไม่ถูกต้อง คะแนนจะถูกละเว้น", + "Item unlocked!": "ปลดล็อคไอเทมแล้ว!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "การเชื่อมโยงถูกปฏิเสธ ${ACCOUNT} ประกอบด้วย\nข้อมูลสำคัญที่จะสูญหายทั้งหมด\nคุณสามารถเชื่อมโยงในลำดับตรงกันข้ามหากคุณต้องการ\n(และสูญเสียข้อมูลของบัญชีนี้แทน)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "เชื่อมโยงบัญชี ${ACCOUNT} กับบัญชีนี้หรือไม่\nข้อมูลที่มีอยู่ทั้งหมดใน ${ACCOUNT} จะหายไป\nไม่สามารถยกเลิกได้ คุณแน่ใจไหม?", + "Max number of playlists reached.": "ถึงจำนวนเพลย์ลิสต์สูงสุดแล้ว", + "Max number of profiles reached.": "ถึงจำนวนโปรไฟล์สูงสุดแล้ว", + "Maximum friend code rewards reached.": "รางวัลรหัสเพื่อนถึงขีดจำกัดแล้ว", + "Message is too long.": "ข้อความยาวเกินไป", + "No servers are available. Please try again soon.": "ไม่มีเซิร์ฟเวอร์ที่พร้อมใช้งาน โปรดลองอีกครั้งในเร็วๆ นี้", + "Profile \"${NAME}\" upgraded successfully.": "อัปเกรดโปรไฟล์ \"${NAME}\" สำเร็จแล้ว", + "Profile could not be upgraded.": "ไม่สามารถอัพเกรดโปรไฟล์ได้", + "Purchase successful!": "ซื้อสำเร็จ!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "ได้รับตั๋ว ${COUNT} ใบสำหรับการลงชื่อเข้าใช้\nกลับมาพรุ่งนี้เพื่อรับ ${TOMORROW_COUNT}", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "ไม่รองรับการทำงานของเซิร์ฟเวอร์ในเกมเวอร์ชั่นนี้อีกต่อไป\nโปรดอัปเดตเป็นเวอร์ชันที่ใหม่กว่า", + "Sorry, there are no uses remaining on this code.": "ขออภัย ไม่มีการใช้งานที่เหลืออยู่ในรหัสนี้", + "Sorry, this code has already been used.": "ขออภัย รหัสนี้ถูกใช้ไปแล้ว", + "Sorry, this code has expired.": "ขออภัย รหัสนี้หมดอายุแล้ว", + "Sorry, this code only works for new accounts.": "ขออภัย รหัสนี้ใช้ได้กับบัญชีใหม่เท่านั้น", + "Still searching for nearby servers; please try again soon.": "ยังคงค้นหาเซิร์ฟเวอร์ใกล้เคียง โปรดลองอีกครั้งในเร็วๆ นี้", + "Temporarily unavailable; please try again later.": "ปิดให้บริการชั่วคราว; โปรดลองอีกครั้งในภายหลัง.", + "The tournament ended before you finished.": "การแข่งขันสิ้นสุดลงก่อนที่คุณจะเสร็จสิ้น", + "This account cannot be unlinked for ${NUM} days.": "บัญชีนี้ไม่สามารถยกเลิกการเชื่อมโยงได้เป็นเวลา ${NUM} วัน", + "This code cannot be used on the account that created it.": "ไม่สามารถใช้รหัสนี้กับบัญชีที่สร้างรหัสได้", + "This is currently unavailable; please try again later.": "ไม่สามารถใช้งานได้ในขณะนี้ โปรดลองอีกครั้งในภายหลัง.", + "This requires version ${VERSION} or newer.": "ต้องใช้เวอร์ชัน ${VERSION} หรือใหม่กว่า", + "Tournaments disabled due to rooted device.": "การแข่งขันถูกปิดใช้งานเนื่องจากอุปกรณ์ที่รูท", + "Tournaments require ${VERSION} or newer": "ทัวร์นาเมนต์ต้องใช้ ${VERSION} หรือใหม่กว่า", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "ยกเลิกการเชื่อมโยง ${ACCOUNT} จากบัญชีนี้หรือไม่\nข้อมูลทั้งหมดใน ${ACCOUNT} จะถูกรีเซ็ต\n(ยกเว้นความสำเร็จในบางกรณี)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "คำเตือน: มีการร้องเรียนเกี่ยวกับการแฮ็กบัญชีของคุณ\nบัญชีที่พบว่ามีการแฮ็คจะถูกแบน กรุณาเล่นอย่างยุติธรรม", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "คุณต้องการเชื่อมโยงบัญชีอุปกรณ์ของคุณกับบัญชีนี้หรือไม่?\n\nบัญชีอุปกรณ์ของคุณคือ ${ACCOUNT1}\nบัญชีนี้คือ ${ACCOUNT2}\n\nนี้จะช่วยให้คุณรักษาความคืบหน้าที่มีอยู่ของคุณ\nคำเตือน: สิ่งนี้ไม่สามารถยกเลิกได้!", + "You already own this!": "คุณเป็นเจ้าของสิ่งนี้แล้ว!", + "You can join in ${COUNT} seconds.": "คุณสามารถเข้าร่วมได้ภายในอีก ${COUNT} วินาที", + "You don't have enough tickets for this!": "คุณมีตั๋วไม่เพียงพอสำหรับสิ่งนี้!", + "You don't own that.": "คุณไม่ได้เป็นเจ้าของสิ่งนั้น", + "You got ${COUNT} tickets!": "คุณได้รับตั๋ว ${COUNT} ใบ!", + "You got a ${ITEM}!": "คุณได้รับ ${ITEM}!", + "You have been promoted to a new league; congratulations!": "คุณได้รับการเลื่อนตำแหน่งเป็นลีกใหม่ ยินดีด้วย!", + "You must update to a newer version of the app to do this.": "คุณต้องอัปเดตแอปเป็นเวอร์ชันใหม่กว่าจึงจะทำได้", + "You must update to the newest version of the game to do this.": "คุณต้องอัปเดตเป็นเวอร์ชันใหม่ล่าสุดของเกมจึงจะสามารถทำได้", + "You must wait a few seconds before entering a new code.": "คุณต้องรอสักครู่ก่อนที่จะป้อนรหัสใหม่", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "คุณติดอันดับ #${RANK} ในทัวร์นาเมนต์ที่แล้ว ขอบคุณสำหรับการเล่น!", + "Your account was rejected. Are you signed in?": "บัญชีของคุณถูกปฏิเสธ คุณลงชื่อเข้าใช้หรือไม่", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "สำเนาเกมของคุณได้รับการแก้ไขแล้ว\nโปรดยกเลิกการเปลี่ยนแปลงและลองอีกครั้ง", + "Your friend code was used by ${ACCOUNT}": "รหัสเพื่อนของคุณถูกใช้โดย ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 นาที", + "1 Second": "1 วินาที", + "10 Minutes": "10 นาที", + "2 Minutes": "2 นาที", + "2 Seconds": "2 วินาที", + "20 Minutes": "20 นาที", + "4 Seconds": "4 วินาที", + "5 Minutes": "5 นาที", + "8 Seconds": "8 วินาที", + "Allow Negative Scores": "อนุญาตให้คะแนนติดลบ", + "Balance Total Lives": "ยอดรวมชีวิต", + "Bomb Spawning": "ระเบิดเกิด", + "Chosen One Gets Gloves": "ผู้ถูกเลือกรับถุงมือ", + "Chosen One Gets Shield": "ผู้ถูกเลือกรับโล่", + "Chosen One Time": "เวลาผู้ถูกเลือก", + "Enable Impact Bombs": "เปิดใช้งาน Impact Bombs", + "Enable Triple Bombs": "เปิดใช้งาน Triple Bombs", + "Entire Team Must Finish": "ทั้งทีมต้องเข้าเส้นชัย", + "Epic Mode": "โหมดมหากาพย์", + "Flag Idle Return Time": "Flag Idle Return Time", + "Flag Touch Return Time": "Flag Touch Return Time", + "Hold Time": "Hold Time", + "Kills to Win Per Player": "ฆ่าเพื่อชนะต่อผู้เล่น", + "Laps": "รอบ", + "Lives Per Player": "ชีวิตต่อผู้เล่น", + "Long": "ยาว", + "Longer": "ยาวกว่า", + "Mine Spawning": "Mine Spawning", + "No Mines": "No Mines", + "None": "ไม่มี", + "Normal": "ปกติ", + "Pro Mode": "โหมดโปร", + "Respawn Times": "เวลาเกิดใหม่", + "Score to Win": "คะแนนที่จะชนะ", + "Short": "สั้น", + "Shorter": "สั้นกว่า", + "Solo Mode": "โหมดโซโล", + "Target Count": "จำนวนเป้าหมาย", + "Time Limit": "เวลาที่ จำกัด" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} ถูกตัดสิทธิ์เนื่องจาก ${PLAYER} ออก", + "Killing ${NAME} for skipping part of the track!": "สังหาร ${NAME} จากการกระโดดข้ามแทร็ก!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "คำเตือนถึง ${NAME}: สแปม / สแปมของปุ่มทำให้คุณล้มลง" + }, + "teamNames": { + "Bad Guys": "คนเลว", + "Blue": "สีฟ้า", + "Good Guys": "คนดี", + "Red": "สีแดง" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "วิ่ง-กระโดด-ปั่น-ต่อยอย่างหมดเวลาสามารถฆ่าได้ในการโจมตีครั้งเดียว\nและได้รับความเคารพตลอดชีวิตจากเพื่อนของคุณ", + "Always remember to floss.": "อย่าลืมใช้ไหมขัดฟัน", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "สร้างโปรไฟล์ผู้เล่นสำหรับตัวคุณเองและเพื่อนของคุณด้วย\nชื่อและรูปลักษณ์ที่คุณต้องการแทนที่จะใช้ชื่อแบบสุ่ม", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "กล่องคำสาปจะทำให้คุณกลายเป็นระเบิดเวลา\nทางเดียวที่รักษาได้คือรีบคว้าชุดสุขภาพ", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "แม้จะมีรูปลักษณ์ แต่ความสามารถของตัวละครทั้งหมดก็เหมือนกัน\nดังนั้นเพียงแค่เลือกอันที่คุณใกล้เคียงที่สุด", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "อย่าอวดดีเกินไปกับโล่พลังงานนั้น คุณยังสามารถทำให้ตัวเองตกจากหน้าผาได้", + "Don't run all the time. Really. You will fall off cliffs.": "อย่าวิ่งตลอดเวลา จริงหรือ. คุณจะตกหน้าผา", + "Don't spin for too long; you'll become dizzy and fall.": "อย่าหมุนนานเกินไป คุณจะเวียนหัวและล้มลง", + "Hold any button to run. (Trigger buttons work well if you have them)": "กดค้างปุ่มใดก็ได้เพื่อวิ่ง (ปุ่มทริกเกอร์ทำงานได้ดีถ้าคุณมี)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "กดค้างปุ่มใดก็ได้เพื่อวิ่ง คุณจะได้สถานที่เร็วขึ้น\nแต่เลี้ยวไม่ค่อยดี ระวังหน้าผานะ", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "ระเบิดน้ำแข็งไม่แรงมาก แต่มันแข็ง\nใครก็ตามที่พวกเขาตี ปล่อยให้พวกเขาเสี่ยงที่จะแตกเป็นเสี่ยงๆ", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "ถ้ามีคนมารับคุณ ต่อยเขาแล้วเขาจะปล่อย\nสิ่งนี้ใช้ได้ผลในชีวิตจริงด้วย", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "หากคุณขาดคอนโทรลเลอร์ ให้ติดตั้งแอป \"${REMOTE_APP_NAME}\"\nบนอุปกรณ์มือถือของคุณเพื่อใช้เป็นคอนโทรลเลอร์", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "หากคุณมีระเบิดเหนียวติดอยู่ ให้กระโดดไปรอบๆ และหมุนเป็นวงกลม คุณอาจ\nสลัดทิ้งระเบิด หรือถ้าไม่มีอะไรอย่างอื่นช่วงเวลาสุดท้ายของคุณจะสนุกสนาน", + "If you kill an enemy in one hit you get double points for it.": "หากคุณฆ่าศัตรูในการโจมตีครั้งเดียว คุณจะได้รับคะแนนสองเท่าสำหรับมัน", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "หากคุณรับคำสาป ความหวังเดียวในการเอาตัวรอดคือ\nค้นหาแพ็คยาในอีกไม่กี่วินาทีข้างหน้า", + "If you stay in one place, you're toast. Run and dodge to survive..": "หากคุณอยู่ในที่เดียว วิ่งหนีเอาตัวรอด..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "หากคุณมีผู้เล่นจำนวนมากเข้าและออก ให้เปิด 'เตะผู้เล่นอัตโนมัติ'\nภายใต้การตั้งค่าในกรณีที่ใครลืมออกจากเกม", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "หากอุปกรณ์ของคุณร้อนเกินไปหรือคุณต้องการประหยัดพลังงานแบตเตอรี่\nลด \"ภาพ\" หรือ \"ความละเอียด\" ในการตั้งค่า -> กราฟิก", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "หากอัตราเฟรมของคุณขาดๆ หายๆ ให้ลองลดความละเอียดลง\nหรือภาพในการตั้งค่ากราฟิกของเกม", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "ในการยึดธง ธงของคุณเองจะต้องอยู่ที่ฐานของคุณเพื่อทำคะแนน ถ้าอีกอันหนึ่ง\nทีมกำลังจะทำคะแนน การขโมยธงอาจเป็นวิธีที่ดีในการหยุดพวกเขา", + "In hockey, you'll maintain more speed if you turn gradually.": "ในฮ็อกกี้ คุณจะรักษาความเร็วได้มากขึ้นหากคุณค่อยๆ เลี้ยว", + "It's easier to win with a friend or two helping.": "มันง่ายกว่าที่จะชนะกับเพื่อนหรือสองคนช่วย", + "Jump just as you're throwing to get bombs up to the highest levels.": "กระโดดในขณะที่คุณกำลังขว้างระเบิดขึ้นไปสูงขึ้น", + "Land-mines are a good way to stop speedy enemies.": "ทุ่นระเบิดเป็นวิธีที่ดีในการหยุดศัตรูที่รวดเร็ว", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "หยิบของได้หลายอย่าง รวมทั้งผู้เล่นคนอื่นด้วย โยน\nศัตรูของคุณนอกหน้าผาอาจเป็นกลยุทธ์ที่มีประสิทธิภาพและตอบสนองทางอารมณ์", + "No, you can't get up on the ledge. You have to throw bombs.": "ไม่ คุณไม่สามารถขึ้นไปบนหิ้งได้ คุณต้องขว้างระเบิด", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "ผู้เล่นสามารถเข้าร่วมและออกจากเกมส่วนใหญ่ได้\nและคุณยังสามารถเสียบและถอดปลั๊กคอนโทรลเลอร์ได้ทันที", + "Practice using your momentum to throw bombs more accurately.": "ฝึกใช้โมเมนตัมในการขว้างระเบิดให้แม่นยำยิ่งขึ้น", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "การชกสร้างความเสียหายมากขึ้นเมื่อหมัดของคุณเคลื่อนไหวเร็วขึ้น\nดังนั้นลองวิ่ง กระโดด และหมุนอย่างบ้าคลั่ง", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "วิ่งกลับไปกลับมาก่อนจะปาระเบิด\nเพื่อ 'แส้' และโยนมันออกไปไกลขึ้น", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "นำกลุ่มศัตรูออกไปโดย\nวางระเบิดใกล้กล่องทีเอ็นที", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "ส่วนหัวเป็นบริเวณที่เปราะบางที่สุด ดังนั้น ระเบิดเหนียว\nto the noggin มักจะหมายถึงการจบเกม", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "ระดับนี้ไม่สิ้นสุด แต่คะแนนสูงที่นี่\nจะได้รับความเคารพชั่วนิรันดร์จากทั่วโลก", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "กำลังขว้างจะขึ้นอยู่กับทิศทางที่คุณถืออยู่\nโยนบางสิ่งต่อหน้าคุณอย่างแผ่วเบาอย่าถือทิศทางใด ๆ", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "เบื่อเพลงประกอบละคร? แทนที่ด้วยของคุณเอง!\nดูการตั้งค่า -> เสียง -> เพลงประกอบ", + "Try 'Cooking off' bombs for a second or two before throwing them.": "ลอง 'ทำอาหาร' ระเบิดสักสองสามวินาทีก่อนจะโยนทิ้ง", + "Try tricking enemies into killing eachother or running off cliffs.": "ลองหลอกให้ศัตรูฆ่ากันเองหรือวิ่งหนีจากหน้าผา", + "Use the pick-up button to grab the flag < ${PICKUP} >": "ใช้ปุ่มรับธงเพื่อคว้าธง < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "ตีกลับไปกลับมาเพื่อให้โยนได้ไกลขึ้น..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "คุณสามารถ 'เล็ง' หมัดของคุณโดยหมุนไปทางซ้ายหรือขวา\nสิ่งนี้มีประโยชน์สำหรับการกำจัดคนเลวออกจากขอบหรือให้คะแนนในฮ็อกกี้", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "คุณสามารถตัดสินได้ว่าเมื่อใดที่ระเบิดจะระเบิดขึ้นอยู่กับ\nสีของประกายไฟจากฟิวส์: เหลือง..ส้ม..แดง..บูม.", + "You can throw bombs higher if you jump just before throwing.": "คุณสามารถขว้างระเบิดให้สูงขึ้นได้หากคุณกระโดดก่อนขว้าง", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "คุณได้รับความเสียหายเมื่อคุณตีหัวกับสิ่งของ\nดังนั้นอย่าพยายามตีหัวของคุณกับสิ่งต่างๆ", + "Your punches do much more damage if you are running or spinning.": "หมัดของคุณสร้างความเสียหายได้มากกว่าถ้าคุณวิ่งหรือหมุน" + } + }, + "trophiesRequiredText": "ต้องมีอย่างน้อย ${NUMBER} ถ้วยรางวัล", + "trophiesText": "ถ้วยรางวัล", + "trophiesThisSeasonText": "ถ้วยรางวัลในฤดูกาลนี้", + "tutorial": { + "cpuBenchmarkText": "กวดวิชาทำงานด้วยความเร็วที่น่าหัวเราะ (ทดสอบความเร็วของ CPU เป็นหลัก)", + "phrase01Text": "สวัสดี!", + "phrase02Text": "ยินดีต้อนรับสู่ ${APP_NAME}!", + "phrase03Text": "เคล็ดลับบางประการในการควบคุมตัวละครของคุณมีดังนี้", + "phrase04Text": "หลายสิ่งใน ${APP_NAME} เป็นพื้นฐานทางฟิสิกส์", + "phrase05Text": "เช่น เมื่อคุณต่อย..", + "phrase06Text": "..ความเสียหายขึ้นอยู่กับความเร็วของหมัดของคุณ", + "phrase07Text": "เห็นมั้ย? เราไม่ได้เคลื่อนไหว ดังนั้นมันแทบไม่เจ็บ ${NAME}", + "phrase08Text": "ตอนนี้มากระโดดและหมุนเพื่อรับความเร็วมากขึ้น", + "phrase09Text": "อ่า ดีขึ้นแล้ว", + "phrase10Text": "การวิ่งก็ช่วยได้เช่นกัน", + "phrase11Text": "กดปุ่มใด ๆ ค้างไว้เพื่อวิ่ง", + "phrase12Text": "สำหรับการชกที่ยอดเยี่ยมเป็นพิเศษ ให้ลองวิ่งและหมุน", + "phrase13Text": "อ๊ะ; ขอโทษด้วย ${NAME}", + "phrase14Text": "คุณสามารถหยิบและโยนสิ่งของต่างๆ เช่น ธง.. หรือ ${NAME}", + "phrase15Text": "สุดท้ายมีระเบิด", + "phrase16Text": "การขว้างระเบิดต้องฝึกฝน", + "phrase17Text": "อุ๊ย! โยนไม่ค่อยดี", + "phrase18Text": "การเคลื่อนไหวช่วยให้คุณขว้างได้ไกลขึ้น", + "phrase19Text": "การกระโดดช่วยให้คุณขว้างได้สูงขึ้น", + "phrase20Text": "\"แส้\" ระเบิดของคุณสำหรับการขว้างอีกต่อไป", + "phrase21Text": "การกำหนดเวลาระเบิดของคุณอาจเป็นเรื่องยาก", + "phrase22Text": "แย่ล่ะ", + "phrase23Text": "ลอง \"หุง\" ฟิวส์สักสองสามวินาที", + "phrase24Text": "ไชโย! ปรุงอย่างดี", + "phrase25Text": "นั่นเป็นเพียงเรื่องเกี่ยวกับมัน", + "phrase26Text": "ไปหามันเดี๋ยวนี้ เสือ!", + "phrase27Text": "จำการฝึกของคุณไว้ แล้วคุณจะกลับมามีชีวิตอีกครั้ง!", + "phrase28Text": "...ก็อาจจะ...", + "phrase29Text": "ขอให้โชคดี!", + "randomName1Text": "เฟรด", + "randomName2Text": "แฮร์รี่", + "randomName3Text": "บิล", + "randomName4Text": "ชัค", + "randomName5Text": "ฟิล", + "skipConfirmText": "ข้ามบทช่วยสอนจริงๆหรอ? แตะหรือกดเพื่อยืนยัน", + "skipVoteCountText": "ข้ามโหวท ${COUNT}/${TOTAL} คน", + "skippingText": "ข้ามบทช่วยสอน...", + "toSkipPressAnythingText": "(แตะหรือกดอะไรก็ได้เพื่อข้ามบทแนะนำ)" + }, + "twoKillText": "ดับเบิ้ลคิล!", + "unavailableText": "ไม่พร้อมใช้งาน", + "unconfiguredControllerDetectedText": "ตรวจพบคอนโทรลเลอร์ที่ไม่ได้กำหนดค่า:", + "unlockThisInTheStoreText": "สิ่งนี้จะต้องปลดล็อคในร้านค้า", + "unlockThisProfilesText": "ในการสร้างมากกว่า ${NUM} โปรไฟล์ คุณต้อง:", + "unlockThisText": "เพื่อปลดล็อกสิ่งนี้ คุณต้อง:", + "unsupportedHardwareText": "ขออภัย ฮาร์ดแวร์นี้ไม่ได้รับการสนับสนุนโดยบิวด์ของเกมนี้", + "upFirstText": "ขึ้นก่อน:", + "upNextText": "ต่อไปในเกม ${COUNT}:", + "updatingAccountText": "กำลังอัปเดตบัญชีของคุณ...", + "upgradeText": "อัพเกรด", + "upgradeToPlayText": "ปลดล็อก \"${PRO}\" ในร้านค้าในเกมเพื่อเล่นเกมนี้", + "useDefaultText": "ใช้ค่าเริ่มต้น", + "usesExternalControllerText": "เกมนี้ใช้คอนโทรลเลอร์ภายนอกสำหรับการป้อนข้อมูล", + "usingItunesText": "การใช้แอพ Music สำหรับซาวด์แทร็ก...", + "v2AccountLinkingInfoText": "หากต้องการเชื่อมโยงบัญชี V2 ให้ใช้ปุ่ม 'จัดการบัญชี'", + "validatingTestBuildText": "กำลังตรวจสอบการสร้างการทดสอบ...", + "victoryText": "ชัยชนะ!", + "voteDelayText": "คุณไม่สามารถเริ่มโหวตได้อีกเป็นเวลา ${NUMBER} วินาที", + "voteInProgressText": "กำลังดำเนินการโหวทอยู่แล้ว", + "votedAlreadyText": "คุณโหวตแล้ว", + "votesNeededText": "ต้องการ ${NUMBER} คะแนน", + "vsText": "vs.", + "waitingForHostText": "(กำลังรอ ${HOST} ดำเนินการต่อ)", + "waitingForPlayersText": "รอผู้เล่นเข้าร่วม...", + "waitingInLineText": "เข้าแถวรอ(ปาร์ตี้เต็ม)...", + "watchAVideoText": "ดูวิดีโอ", + "watchAnAdText": "ดูโฆษณา", + "watchWindow": { + "deleteConfirmText": "ลบ \"${REPLAY}\" ไหม", + "deleteReplayButtonText": "ลบ\nรีเพลย์", + "myReplaysText": "รีเพลย์ของฉัน", + "noReplaySelectedErrorText": "ไม่ได้เลือกรีเพลย์", + "playbackSpeedText": "ความเร็วในการเล่น: ${SPEED}", + "renameReplayButtonText": "เปลี่ยนชื่อ\nรีเพลย์", + "renameReplayText": "เปลี่ยนชื่อ \"${REPLAY}\" เป็น:", + "renameText": "เปลี่ยนชื่อ", + "replayDeleteErrorText": "เกิดข้อผิดพลาดในการลบรีเพลย์", + "replayNameText": "ชื่อรีเพลย์", + "replayRenameErrorAlreadyExistsText": "มีรีเพลย์ที่มีชื่อนั้นอยู่แล้ว", + "replayRenameErrorInvalidName": "ไม่สามารถเปลี่ยนชื่อรีเพลย์ได้ ชื่อไม่ถูกต้อง.", + "replayRenameErrorText": "เกิดข้อผิดพลาดในการเปลี่ยนชื่อรีเพลย์", + "sharedReplaysText": "แชร์รีเพลย์", + "titleText": "ดู", + "watchReplayButtonText": "ดู\nรีเพลย์" + }, + "waveText": "เวฟ", + "wellSureText": "แน่นอน!", + "whatIsThisText": "นี่คืออะไร?", + "wiimoteLicenseWindow": { + "titleText": "ลิขสิทธิ์ DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "กำลังฟังสำหรับ Wiimotes...", + "pressText": "กดปุ่ม Wiimote 1 และ 2 พร้อมกัน", + "pressText2": "สำหรับ Wiimotes รุ่นใหม่ที่มี Motion Plus ในตัว ให้กดปุ่ม 'ซิงค์' สีแดงที่ด้านหลังแทน" + }, + "wiimoteSetupWindow": { + "copyrightText": "ลิขสิทธิ์ DarwiinRemote", + "listenText": "ฟัง", + "macInstructionsText": "ตรวจสอบให้แน่ใจว่า Wii ของคุณปิดอยู่และเปิดใช้งาน Bluetooth แล้ว\nบน Mac ของคุณ จากนั้นกด 'ฟัง' รองรับ Wiimote ได้\nเป็นขุยๆ หน่อย ต้องลองสักครั้ง\nก่อนที่คุณจะได้รับการเชื่อมต่อ\n\nBluetooth ควรรองรับอุปกรณ์ที่เชื่อมต่อถึง 7 เครื่อง\nแม้ว่าระยะทางของคุณอาจแตกต่างกันไป\n\nBombSquad รองรับ Wiimotes, Nunchuks,\nและตัวควบคุมแบบคลาสสิก\nตอนนี้ Wii Remote Plus ที่ใหม่กว่าก็ใช้งานได้เช่นกัน\nแต่ไม่มีไฟล์แนบ", + "thanksText": "ขอขอบคุณทีมงาน DarwiinRemote\nเพื่อทำให้สิ่งนี้เป็นไปได้", + "titleText": "การตั้งค่า Wiimote" + }, + "winsPlayerText": "${NAME} ชนะ!", + "winsTeamText": "${NAME} ชนะ!", + "winsText": "${NAME} ชนะ!", + "workspaceSyncErrorText": "เกิดข้อผิดพลาดในการซิงค์ ${WORKSPACE} เปิดlogเพื่อดูรายละเอียด", + "workspaceSyncReuseText": "ไม่สามารถซิงค์ ${WORKSPACE} ได้ จึงนำเวอร์ชันที่ซิงค์ก่อนหน้านี้มาใช้", + "worldScoresUnavailableText": "ไม่มีคะแนนโลก", + "worldsBestScoresText": "คะแนนที่ดีที่สุดในโลก", + "worldsBestTimesText": "เวลาที่ดีที่สุดในโลก", + "xbox360ControllersWindow": { + "getDriverText": "รับไดรเวอร์", + "macInstructions2Text": "หากต้องการใช้คอนโทรลเลอร์แบบไร้สาย คุณจะต้องมีเครื่องรับที่\nมาพร้อมกับ 'Xbox 360 Wireless Controller สำหรับ Windows'\nตัวรับสัญญาณหนึ่งตัวช่วยให้คุณเชื่อมต่อคอนโทรลเลอร์ได้สูงสุด 4 ตัว\n\nสำคัญ: เครื่องรับบุคคลที่สามจะไม่ทำงานกับไดรเวอร์นี้\nตรวจสอบให้แน่ใจว่าผู้รับของคุณระบุว่า 'Microsoft' ไม่ใช่ 'XBOX 360'\nMicrosoft ไม่จำหน่ายแยกต่างหากอีกต่อไป ดังนั้นคุณจะต้องซื้อ\nอันที่มาพร้อมกับคอนโทรลเลอร์หรือค้นหา ebay\n\nหากคุณพบว่าสิ่งนี้มีประโยชน์ โปรดพิจารณาบริจาคให้กับ\nผู้พัฒนาไดรเวอร์ที่ไซต์ของเขา", + "macInstructionsText": "ในการใช้คอนโทรลเลอร์ Xbox 360 คุณจะต้องติดตั้ง\nไดรเวอร์ Mac มีอยู่ที่ลิงค์ด้านล่าง\nใช้งานได้กับทั้งคอนโทรลเลอร์แบบมีสายและไร้สาย", + "ouyaInstructionsText": "หากต้องการใช้สายควบคุม Xbox 360 ด้วย BombSquad เพียง\nเสียบเข้ากับพอร์ต USB ของอุปกรณ์ของคุณ คุณสามารถใช้ฮับ USB\nเพื่อเชื่อมต่อคอนโทรลเลอร์หลายตัว\nในการใช้ตัวควบคุมไร้สายคุณจะต้องมีตัวรับสัญญาณไร้สาย\nเป็นส่วนหนึ่งของ \"Xbox 360 คอนโทรลเลอร์ไร้สายสำหรับ Windows\"\nแพคเกจหรือขายแยกต่างหาก ตัวรับสัญญาณแต่ละตัวจะเสียบเข้ากับพอร์ต USB และ\nช่วยให้คุณเชื่อมต่อคอนโทรลเลอร์ไร้สายได้สูงสุด 4 ตัว", + "titleText": "การใช้ตัวควบคุม Xbox 360 กับ ${APP_NAME}:" + }, + "yesAllowText": "ใช่อนุญาต!", + "yourBestScoresText": "คะแนนที่ดีที่สุดของคุณ", + "yourBestTimesText": "เวลาที่ดีที่สุดของคุณ" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/turkish.json b/dist/ba_data/data/languages/turkish.json new file mode 100644 index 0000000..3b8de28 --- /dev/null +++ b/dist/ba_data/data/languages/turkish.json @@ -0,0 +1,1889 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Hesap isimleri emoji veya başka özel karakterler içeremez", + "accountProfileText": "(hesap profili) ", + "accountsText": "Hesaplar", + "achievementProgressText": "Başarılar: ${COUNT} / ${TOTAL}", + "campaignProgressText": "Mücadele İlerlemesi [Zor]: ${PROGRESS}", + "changeOncePerSeason": "Bunu sezon başına sadece bir kere değiştirebilirsin", + "changeOncePerSeasonError": "Bunu tekrar değiştirmek için bir sonraki sezona kadar beklemelisin (${NUM}gün)", + "customName": "Özel isim", + "googlePlayGamesAccountSwitchText": "Eğer farklı bir google hesabı kullanmak istiyorsanız,\nGoogle Play Oyunlar uygulamasını kullabilirsiniz.", + "linkAccountsEnterCodeText": "Kod Gir", + "linkAccountsGenerateCodeText": "Kod Oluştur", + "linkAccountsInfoText": "(ilerlemeyi farklı platformlar ile paylaş)", + "linkAccountsInstructionsNewText": "İki hesabı bağlamak için, ilk hesapta kod oluştur\nve bu kodu ikinci hesaba gir. İkinci hesaptaki\nveriler iki hesap arasında paylaşılacaktır. \n(İlk hesaptaki veriler kaybolacaktır) \n\n${COUNT} tane hesap bağlayabilirsin. \n\nÖnemli:Sadece kendi hesaplarını bağla;\nEğer arkadaşlarının hesabını bağlarsan \naynı anda çevrimiçi oynayamayacaksınız.", + "linkAccountsInstructionsText": "İki hesabı birbirine bağlamak için, birinde kod oluşturun\nve o kodu diğerinde girin.\nİlerlemeler ve envanterler birleşecektir.\n${COUNT} taneye kadar hesap bağlayabilirsiniz.\n\nÖNEMLİ: Yalnızca kendi hesaplarını bağla!\nEğer arkadaşınla hesapları bağlarsan\naynı anda oynayamayacaksınız!\n\nAyrıca: bu işlem şu anda geri alınamaz, yani dikkatli ol!", + "linkAccountsText": "Hesapları Bağla", + "linkedAccountsText": "Bağlı Hesaplar:", + "manageAccountText": "Hesabı Yönet", + "nameChangeConfirm": "Hesap adın ${NAME} olarak değiştirilsinmi ?", + "resetProgressConfirmNoAchievementsText": "Bu co-op ilerlemeyi ve \nlokaldeki yüksek puanlarnı sıfırlar(ama biletlerini değil).\nBu geri alınamaz. Emin misiniz?", + "resetProgressConfirmText": "Bu co-op ilerlemeyi, başarıları ve \nEn yüksek skorları sıfırlayacak \n(ama biletlerini değil). Bu işlem\ngeri alınamaz. Emin misin?", + "resetProgressText": "İlerlemeyi Sıfırla", + "setAccountName": "Hesap adı düzenle", + "setAccountNameDesc": "Hesabın için gösterilecek bir isim seç. \nBağladığın hesaplardan birinin adını kullanabilir\nya da yeni bir tane oluşturabilirsin.", + "signInInfoText": "Bilet toplamak Çevrimiçi olmak ve ilerlemeyi \ndiğer cihazlarla paylaşmak için Giriş yap.", + "signInText": "Giriş Yap", + "signInWithDeviceInfoText": "Otomatik bir hesap sadece bu cihaz için kullanılabilir", + "signInWithDeviceText": "Cihaz hesabı ile Giriş yap", + "signInWithGameCircleText": "Game Circle ile Giriş yap", + "signInWithGooglePlayText": "Google Play ile Giriş yap", + "signInWithTestAccountInfoText": "(miras hesabı;bu cihaz hesaplarını ileride de kullan)", + "signInWithTestAccountText": "Test hesabı ile Giriş yap", + "signInWithV2InfoText": "(bütün platformlarda çalışan bir hesap)", + "signInWithV2Text": "BombSquad hesabıyla giriş yap", + "signOutText": "Çıkış Yap", + "signingInText": "Giriş yapılıyor...", + "signingOutText": "Çıkış yapılıyor...", + "ticketsText": "Biletler: ${COUNT}", + "titleText": "Hesap", + "unlinkAccountsInstructionsText": "Ayırmak için bir hesap seç", + "unlinkAccountsText": "Hesapları ayır", + "unlinkLegacyV1AccountsText": "Eski V1 Hesaplarını Kaldırın", + "v2LinkInstructionsText": "Bu bağlantıyı kullanarak bir hesap oluşturun yada giriş yapın.", + "viaAccount": "(${NAME}hesabı ile)", + "youAreSignedInAsText": "Aşağıdaki ile giriş yapıldı" + }, + "achievementChallengesText": "Başarı Mücadelesi", + "achievementText": "Başarı", + "achievements": { + "Boom Goes the Dynamite": { + "description": "TNT ile 3 haylaz öldür", + "descriptionComplete": "TNT ile 3 haylaz öldürüldü", + "descriptionFull": "${LEVEL} da TNT ile 3 haylaz öldür", + "descriptionFullComplete": "${LEVEL} da TNT ile 3 haylaz öldürüldü", + "name": "Dinamit Gümledi" + }, + "Boxer": { + "description": "Hiç bomba kullanmadan kazan", + "descriptionComplete": "Hiç bomba kullanmadan kazanıldı", + "descriptionFull": "Hiç bomba kullanmadan ${LEVEL} tamamla", + "descriptionFullComplete": "Hiç bomba kullanmadan ${LEVEL} tamamlandı", + "name": "Boksör" + }, + "Dual Wielding": { + "descriptionFull": "2 kontrolcü bağla (donanım veya uygulama)", + "descriptionFullComplete": "2 kontrolcü bağlandı (donanım veya uygulama)", + "name": "Çifte Kullanım" + }, + "Flawless Victory": { + "description": "Hiç darbe almadan kazan", + "descriptionComplete": "Hiç darbe almadan kazanıldı", + "descriptionFull": "Hiç darbe almadan ${LEVEL} kazan", + "descriptionFullComplete": "Hiç darbe almadan ${LEVEL} kazanıldı", + "name": "Çiziksiz Galibiyet" + }, + "Free Loader": { + "descriptionFull": "2+ oyuncu ile Herkes-Tek oyunu başlat", + "descriptionFullComplete": "2+ oyuncu ile Herkes-Tek oyunu başlatıldı", + "name": "Otlakçı" + }, + "Gold Miner": { + "description": "Kara mayını ile 6 haylaz öldür", + "descriptionComplete": "Kara mayını ile 6 haylaz öldürüldü", + "descriptionFull": "Kara mayını ile ${LEVEL} da 6 haylaz öldür", + "descriptionFullComplete": "Kara mayını ile ${LEVEL} da 6 haylaz öldürüldü", + "name": "Altın Mayıncı" + }, + "Got the Moves": { + "description": "Yumruk veya bomba kullanmadan kazan", + "descriptionComplete": "Yumruk veya bomba kullanmadan kazanıldı", + "descriptionFull": "Yumruk ve bomba kullanmadan ${LEVEL} da kazan", + "descriptionFullComplete": "Yumruk ve bomba kullanmadan ${LEVEL} da kazanıldı", + "name": "Hamleni Yap" + }, + "In Control": { + "descriptionFull": "Bir kontrolcü bağla (donanım veya uygulama)", + "descriptionFullComplete": "Bir kontrolcü bağlandı. (donanım veya uygulama)", + "name": "Kontrol Altında" + }, + "Last Stand God": { + "description": "1000 puan kazan", + "descriptionComplete": "1000 puan kazanıldı", + "descriptionFull": "${LEVEL} da 1000 puan kazan", + "descriptionFullComplete": "${LEVEL} da 1000 puan kazanıldı", + "name": "${LEVEL} Tanrısı" + }, + "Last Stand Master": { + "description": "250 puan kazan", + "descriptionComplete": "250 puan kazanıldı", + "descriptionFull": "${LEVEL} da 250 puan kazan", + "descriptionFullComplete": "${LEVEL} da 250 puan kazanıldı", + "name": "${LEVEL} Ustası" + }, + "Last Stand Wizard": { + "description": "500 puan kazan", + "descriptionComplete": "500 puan kazanıldı", + "descriptionFull": "${LEVEL} da 500 puan kazan", + "descriptionFullComplete": "${LEVEL} da 500 puan kazanıldı", + "name": "${LEVEL} Büyücüsü" + }, + "Mine Games": { + "description": "Kara mayını ile 3 haylaz öldür", + "descriptionComplete": "kara mayını ile 3 haylaz öldürüldü", + "descriptionFull": "kara mayını ile ${LEVEL} da 3 haylaz öldür", + "descriptionFullComplete": "kara mayını ile ${LEVEL} da 3 haylaz öldürüldü", + "name": "Mayın Oyunları" + }, + "Off You Go Then": { + "description": "Haritadan dışarıya 3 haylaz fırlat", + "descriptionComplete": "Haritadan dışarıya 3 haylaz fırlatıldı", + "descriptionFull": "${LEVEL} da haritadan dışarıya 3 haylaz fırlat", + "descriptionFullComplete": "${LEVEL} da haritadan dışarıya 3 haylaz fırlatıldı", + "name": "O Halde Bas Git!" + }, + "Onslaught God": { + "description": "5000 puan kazan", + "descriptionComplete": "5000 puan kazanıldı", + "descriptionFull": "${LEVEL} da 5000 puan kazan", + "descriptionFullComplete": "${LEVEL} da 5000 puan kazanıldı", + "name": "${LEVEL} Tanrısı" + }, + "Onslaught Master": { + "description": "500 puan kazan", + "descriptionComplete": "500 puan kazanıldı", + "descriptionFull": "${LEVEL} da 500 puan kazan", + "descriptionFullComplete": "${LEVEL} da 500 puan kazanıldı", + "name": "${LEVEL} Ustası" + }, + "Onslaught Training Victory": { + "description": "Tüm dalgaları kazan", + "descriptionComplete": "Tüm dalgalar kazanıldı", + "descriptionFull": "${LEVEL} da tüm dalgaları kazan", + "descriptionFullComplete": "${LEVEL} da tüm dalgalar kazanıldı", + "name": "${LEVEL} Galibiyeti" + }, + "Onslaught Wizard": { + "description": "1000 puan kazan", + "descriptionComplete": "1000 puan kazanıldı", + "descriptionFull": "${LEVEL} da 1000 puan kazan", + "descriptionFullComplete": "${LEVEL} da 1000 puan kazan", + "name": "${LEVEL} Büyücüsü" + }, + "Precision Bombing": { + "description": "Hiç güçlendirici kullanmadan kazan", + "descriptionComplete": "Hiç güçlendirici kullanmadan kazanıldı", + "descriptionFull": "Hiç güçlendirici kullanmadan ${LEVEL} da kazan", + "descriptionFullComplete": "Hiç güçlendirici kullanmadan ${LEVEL} da kazanıldı", + "name": "Hassas Bombalama" + }, + "Pro Boxer": { + "description": "Hiç bomba kullanmadan kazan", + "descriptionComplete": "Hiç bomba kullanmadan kazanıldı", + "descriptionFull": "Hiç bomba kullanmadan ${LEVEL} tamamla", + "descriptionFullComplete": "Hiç bomba kullanmadan ${LEVEL} tamamlandı", + "name": "Uzman Boksör" + }, + "Pro Football Shutout": { + "description": "Haylazlara puan yaptırmadan kazan", + "descriptionComplete": "Haylazlara puan yaptırmadan kazanıldı", + "descriptionFull": "Haylazlara puan yaptırmadan ${LEVEL} da kazan", + "descriptionFullComplete": "Haylazlara puan yaptırmadan ${LEVEL} da kazanıldı", + "name": "${LEVEL} Lokavt" + }, + "Pro Football Victory": { + "description": "Oyunu kazan", + "descriptionComplete": "Oyun kazanıldı", + "descriptionFull": "${LEVEL} da oyunu kazan", + "descriptionFullComplete": "${LEVEL} da oyun kazanıldı", + "name": "${LEVEL} Galibiyeti" + }, + "Pro Onslaught Victory": { + "description": "Tüm dalgaları kazan", + "descriptionComplete": "Tüm dalgalar kazanıldı", + "descriptionFull": "${LEVEL} da tüm dalgaları kazan", + "descriptionFullComplete": "${LEVEL} da tüm dalgalar kazanıldı", + "name": "${LEVEL} Galibiyeti" + }, + "Pro Runaround Victory": { + "description": "Tüm dalgaları tamamla", + "descriptionComplete": "Tüm dalgalar tamamlandı", + "descriptionFull": "${LEVEL} da tüm dalgaları tamamla", + "descriptionFullComplete": "${LEVEL} da tüm dalgalar tamamlandı", + "name": "${LEVEL} Galibiyeti" + }, + "Rookie Football Shutout": { + "description": "Haylazlara puan yaptırmadan kazan", + "descriptionComplete": "Haylazlara puan yaptırmadan kazanıldı", + "descriptionFull": "${LEVEL} da haylazlara puan yaptırmadan kazan", + "descriptionFullComplete": "${LEVEL} da haylazlara puan yaptırmadan kazanıldı", + "name": "${LEVEL} Lokavt" + }, + "Rookie Football Victory": { + "description": "Oyunu kazan", + "descriptionComplete": "Oyun kazanıldı", + "descriptionFull": "${LEVEL} da oyunu kazan", + "descriptionFullComplete": "${LEVEL} da oyun kazanıldı", + "name": "${LEVEL} Galibiyeti" + }, + "Rookie Onslaught Victory": { + "description": "Tüm dalgaları kazan", + "descriptionComplete": "Tüm dalgaları kazan", + "descriptionFull": "${LEVEL} da tüm dalgaları kazan", + "descriptionFullComplete": "${LEVEL} da tüm dalgalar kazanıldı", + "name": "${LEVEL} Galibiyeti" + }, + "Runaround God": { + "description": "2000 puan kazan", + "descriptionComplete": "2000 puan kazanıldı", + "descriptionFull": "${LEVEL} da 2000 puan kazan", + "descriptionFullComplete": "${LEVEL} da 2000 puan kazanıldı", + "name": "${LEVEL} Tanrı" + }, + "Runaround Master": { + "description": "500 puan kazan", + "descriptionComplete": "500 puan kazanıldı", + "descriptionFull": "${LEVEL} da 500 puan kazan", + "descriptionFullComplete": "${LEVEL} da 500 puan kazanıldı", + "name": "${LEVEL} Ustası" + }, + "Runaround Wizard": { + "description": "1000 puan kazan", + "descriptionComplete": "1000 puan kazan", + "descriptionFull": "${LEVEL} da 1000 puan kazan", + "descriptionFullComplete": "${LEVEL} da 1000 puan kazanıldı", + "name": "${LEVEL} Büyücüsü" + }, + "Sharing is Caring": { + "descriptionFull": "Başarılı bir şekilde oyunu bir arkadaş ile paylaş", + "descriptionFullComplete": "Başarılı bir şekilde, oyun bir arkadaş ile paylaşıldı", + "name": "Paylaşmak Önemsemektir" + }, + "Stayin' Alive": { + "description": "Hiç ölmeden Kazan", + "descriptionComplete": "Hiç ölmeden kazan", + "descriptionFull": "Hiç ölmeden ${LEVEL} da kazan", + "descriptionFullComplete": "Hiç ölmeden ${LEVEL} da kazanıldı", + "name": "Hayatta Kal" + }, + "Super Mega Punch": { + "description": "Tek yumruk ile %100 hasar ver", + "descriptionComplete": "Tek yumruk ile %100 hasar verildi", + "descriptionFull": "${LEVEL} da tek yumruk ile %100 hasar ver", + "descriptionFullComplete": "${LEVEL} da tek yumruk ile %100 hasar verildi", + "name": "Süper Mega Yumruk" + }, + "Super Punch": { + "description": "Tek yumruk ile %50 hasar ver", + "descriptionComplete": "Tek yumruk ile $50 hasar verildi", + "descriptionFull": "${LEVEL} da tek yumruk ile %50 hasar ver", + "descriptionFullComplete": "${LEVEL} da tek yumruk ile %50 hasar verildi", + "name": "Süper Yumruk" + }, + "TNT Terror": { + "description": "TNT ile 6 haylaz öldür", + "descriptionComplete": "TNT ile 6 haylaz öldürüldü", + "descriptionFull": "${LEVEL} da TNT ile 6 haylaz öldür", + "descriptionFullComplete": "${LEVEL} da TNT ile 6 haylaz öldürüldü", + "name": "TNT Dehşeti" + }, + "Team Player": { + "descriptionFull": "4+ oyuncu ile bir Takımlar oyunu başlat", + "descriptionFullComplete": "4+ oyuncu ile bir Takım oyunu başlat", + "name": "Takım Oyuncusu" + }, + "The Great Wall": { + "description": "Bütün haylazları durdur", + "descriptionComplete": "Bütün haylazları durdur", + "descriptionFull": "${LEVEL} da bütün haylazları durdur", + "descriptionFullComplete": "${LEVEL} da bütün haylazlar durduruldu", + "name": "Muhteşem Bariyer" + }, + "The Wall": { + "description": "Bütün haylazları durdur", + "descriptionComplete": "Bütün haylazları durdur", + "descriptionFull": "${LEVEL} da bütün haylazları durdur", + "descriptionFullComplete": "${LEVEL} da bütün haylazlar durduruldu", + "name": "Bariyer" + }, + "Uber Football Shutout": { + "description": "Haylazlara puan yaptırmadan kazan", + "descriptionComplete": "Haylazlara puan yaptırmadan kazanıldı", + "descriptionFull": "${LEVEL} da haylazlara puan yaptırmadan kazan", + "descriptionFullComplete": "${LEVEL} da haylazlara puan yaptırmadan kazanıldı", + "name": "${LEVEL} Lokavt" + }, + "Uber Football Victory": { + "description": "Oyunu kazan", + "descriptionComplete": "Oyun kazanıldı", + "descriptionFull": "${LEVEL} da oyunu kazan", + "descriptionFullComplete": "${LEVEL} da oyun kazanıldı", + "name": "${LEVEL} Galibiyeti" + }, + "Uber Onslaught Victory": { + "description": "Tüm dalgaları kazan", + "descriptionComplete": "Tüm dalgalar kazanıldı", + "descriptionFull": "${LEVEL} da tüm dalgaları kazan", + "descriptionFullComplete": "${LEVEL} da tüm dalgalar kazanıldı", + "name": "${LEVEL} Galibiyeti" + }, + "Uber Runaround Victory": { + "description": "Tüm dalgaları tamamla", + "descriptionComplete": "Tüm dalgalar tamamlandı", + "descriptionFull": "${LEVEL} da tüm dalgaları tamamla", + "descriptionFullComplete": "${LEVEL} da tüm dalgalar tamamlandı", + "name": "${LEVEL} Galibiyet" + } + }, + "achievementsRemainingText": "Kalan Başarılar;", + "achievementsText": "Başarı", + "achievementsUnavailableForOldSeasonsText": "Üzgünüz, başarı detayları eski sezonlar için kullanılamaz.", + "activatedText": "${THING} aktifleştirildi.", + "addGameWindow": { + "getMoreGamesText": "Daha Çok Oyun...", + "titleText": "Oyun Ekle" + }, + "allowText": "Kabul Et", + "alreadySignedInText": "Başka bir cihazda hesabına giriş yapılmış;\nlütfen hesapları değiştir ya da diğer cihazlardaki\noyunu kapat ve tekrar dene.", + "apiVersionErrorText": "Modul yüklenemiyor ${NAME}; hedef api-versiyon ${VERSION_USED}; ihtiyacımız olan ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(\"Oto\" yalnızca kulaklıklar takılı iken etkinleşir)", + "headRelativeVRAudioText": "Head-Relative VR Ses", + "musicVolumeText": "Müzik Seviyesi", + "soundVolumeText": "Ses Seviyesi", + "soundtrackButtonText": "Müzikler", + "soundtrackDescriptionText": "(oyun sırasında çalmak için kendi müziğinizi atayın)", + "titleText": "Ses" + }, + "autoText": "Oto", + "backText": "Geri", + "banThisPlayerText": "Bu oyuncuyu banla", + "bestOfFinalText": "En-İyi-${COUNT} Final", + "bestOfSeriesText": "En-İyi-${COUNT} Seri:", + "bestOfUseFirstToInstead": 0, + "bestRankText": "En İyi #${RANK} oldun", + "bestRatingText": "En iyi derecen ${RATING}", + "bombBoldText": "BOMBA", + "bombText": "Bomba", + "boostText": "Öne Geç", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} Uygulamayı kendisine yapılandır", + "buttonText": "buton", + "canWeDebugText": "Oyun otomatik olarak hataları, çökmeleri ve basit \nkullanım istatistiklerini geliştiriciye gondersin mi?\n\nBu veri içeriği kişisel bilgilerinizi kullanmaz\noyunun daha iyi çalışmasına yardımcı olur.", + "cancelText": "İptal", + "cantConfigureDeviceText": "Üzgünüz, ${DEVICE} ayarlanabilir değil.", + "challengeEndedText": "Bu mücadele sona erdi.", + "chatMuteText": "Konuşmayı sustur", + "chatMutedText": "Sohbet Susturuldu", + "chatUnMuteText": "Konuşmayı aç", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "İlerlemek için bu \nseviyeyi tamamlamalısınız!", + "completionBonusText": "Tamamlama Bonusu", + "configControllersWindow": { + "configureControllersText": "Kontrolcüleri Ayarla", + "configureKeyboard2Text": "P2 Klavye Ayarla", + "configureKeyboardText": "Klavye Ayarla", + "configureMobileText": "Kontrolcü olarak Mobil Cihaz", + "configureTouchText": "Dokunmatikleri Ayarla", + "ps3Text": "PS3 Kontrolcüsü", + "titleText": "Kontrolcüler", + "wiimotesText": "Wiimote'ler", + "xbox360Text": "Xbox 360 Kontrolcüleri" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Not: kontrolcü desteği cihaz ve android sürümüne göre değişebilir.", + "pressAnyButtonText": "Kontrolcüyü ayarlamak istiyorsan\nherhangi bir tuşuna bas...", + "titleText": "Kontrolcüleri Ayarla" + }, + "configGamepadWindow": { + "advancedText": "Gelişmiş", + "advancedTitleText": "Gelişmiş Kontrolcü Kurulumu", + "analogStickDeadZoneDescriptionText": "(eğer çubuğu bıraktığında karakterin \"sapıtıyorsa,tıkanıyorsa\" bunu aç)", + "analogStickDeadZoneText": "Analog Çubuk Ölü Bölgesi", + "appliesToAllText": "(bu tipi tüm kontrolcülere uygula)", + "autoRecalibrateDescriptionText": "(eğer karakterin tam hızda hareket etmiyorsa bunu etkinleştir)", + "autoRecalibrateText": "Analog Çubuğu Oto-Yeniden Ayarlama", + "axisText": "Eksenler", + "clearText": "Temizle", + "dpadText": "dpad", + "extraStartButtonText": "İlave Başlat Butonu", + "ifNothingHappensTryAnalogText": "Eğer hiçbir şey olmuyorsa, bunun yerine analog çubuk atamayı deneyin.", + "ifNothingHappensTryDpadText": "Eğer hiçbir şey olmuyorasa, bunun yerine d-pad atamayı deneyin.", + "ignoreCompletelyDescriptionText": "(bu kontolcüyü menüden ve oyundan engelleyin)", + "ignoreCompletelyText": "Tamamen Yoksay", + "ignoredButton1Text": "Yoksayılmış Buton 1", + "ignoredButton2Text": "Yoksayılmış Buton 2", + "ignoredButton3Text": "Yoksayılmış Buton 3", + "ignoredButton4Text": "Yoksayılmış Buton 4", + "ignoredButtonDescriptionText": "(UI yi etkilememesi için 'ev' veya 'senktron' butonların kullanımını engelle)", + "pressAnyAnalogTriggerText": "Herhangi bir analoğu hareket ettir...", + "pressAnyButtonOrDpadText": "Herhangi bir dpad veya butona basın...", + "pressAnyButtonText": "Herhangi bir butona basın...", + "pressLeftRightText": "Sağa veya Sola basın...", + "pressUpDownText": "Yukarı veya Aşağıya basın...", + "runButton1Text": "Çalıştır Buton 1", + "runButton2Text": "Çalıştır Buton 2", + "runTrigger1Text": "Çalıştır Tetik 1", + "runTrigger2Text": "Çalıştır Tetik 2", + "runTriggerDescriptionText": "(analog tetikler sana değişken hızlar sunar)", + "secondHalfText": "2'si 1 arada cihaz kontrolcüsünün birini\nyapılandırmak için bunu kullan.\nTek bir kontrolcü gibi görünecek.", + "secondaryEnableText": "Etkinleştir", + "secondaryText": "İkincil Kontrolcü", + "startButtonActivatesDefaultDescriptionText": "(eğer başlat butonun daha çok \"menü\" butonu ise bunu kapat)", + "startButtonActivatesDefaultText": "Başlat Butonu Varsayılan Aktifleştirme Zımpırtısıdır", + "titleText": "Kontrolcü Kurulumu", + "twoInOneSetupText": "2'si 1 arada Kontrolcü Kurulumu", + "uiOnlyDescriptionText": "(bu kontrolcüyü bir oyuna katılmaması için engelle)", + "uiOnlyText": "Menü Kullanımını Kısıtla", + "unassignedButtonsRunText": "Atanmamış Tüm Butonları Çalıştır", + "unsetText": "", + "vrReorientButtonText": "VR Buton Yönünü Değiştir" + }, + "configKeyboardWindow": { + "configuringText": "${DEVICE} Yapılandırılıyor", + "keyboard2NoteText": "Not: Çoğu klavyenin tek seferde yalnızca\nbirkaç tuşu çalışır, bu yüzden ikinci oyuncunun\nikinci klavye ile oynaması daha iyi olacaktır.\nNot:Bunu yapmak için oyunculara farklı \ntuşları atamalısınız." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Eylem Kontrolü Ölçeği", + "actionsText": "Eylemler", + "buttonsText": "Butonlar", + "dragControlsText": "< Kontrol yerini değiştirmek için sürükleyin >", + "joystickText": "joystick", + "movementControlScaleText": "Hareket Kontrolü Ölçeği", + "movementText": "Hareket", + "resetText": "Sıfırla", + "swipeControlsHiddenText": "Joystick'i gizle", + "swipeInfoText": "\"Sürme\" kontrol stilleri kullanışlıdır fakat\nkontrollere bakmadan oynamak daha kolaydır.", + "swipeText": "sürme", + "titleText": "Dokunmatikleri Yapılandır" + }, + "configureItNowText": "Şimdi yapılandır?", + "configureText": "Yapılandır", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "En iyi sonuçları gecikmesiz Wifi ağına bağlıyken\nalırsınız. Diğer wifi cihazlarını kapatarak, wifi \nvericisine yakın olarak ve oyunu direkt ethernet \nile kurarak gecikmeyi azaltabilirsiniz.", + "explanationText": "Akıllı Telefon veya Tableti kablosuz kontrolcü olarak kullanmak için\n\"${REMOTE_APP_NAME}\" uygulamasını yükleyin. Çok sayıda cihazı Wi-Fi\nile ${APP_NAME} a bağlayabilirsiniz. Ve bu bedava!", + "forAndroidText": "Android için:", + "forIOSText": "iOS için:", + "getItForText": "${REMOTE_APP_NAME} iOS için Apple App Store ve Android\niçin Google Play Store veya Amazon Appstore da", + "googlePlayText": "Google Play", + "titleText": "Mobil Cihazı Kontrolcü Olarak Kullan:" + }, + "continuePurchaseText": "${PRICE} için devam et?", + "continueText": "Devam Et", + "controlsText": "Kontroller", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Bu Tüm-Zamanlar sıralamalarında uygulanamaz.", + "activenessInfoText": "Bu çarpan oynadığın günlerde yükselir\noynamadığın günlerde düşer.", + "activityText": "Aktiflik", + "campaignText": "Mücadele", + "challengesInfoText": "Mini-oyunları tamamlayarak ödül kazan.\n\nÖdüller ve zorluk seviyesi mücalede\ntamamlandığı her zaman artar süre bittiğinde\nve caydığında azalır.", + "challengesText": "Meydan Okumalar", + "currentBestText": "Şimdiki En İyi", + "customText": "Özel", + "entryFeeText": "Katılım", + "forfeitConfirmText": "Bu meydan okumadan cay?", + "forfeitNotAllowedYetText": "Bu meydan okuma henüz cayılamaz.", + "forfeitText": "Cayma", + "multipliersText": "Çarpanlar", + "nextChallengeText": "Sonraki Meydan Okuma", + "nextPlayText": "Sonraki Oyun", + "ofTotalTimeText": "${TOTAL} üzerinden", + "playNowText": "Şimdi Oyna", + "pointsText": "Puanlar", + "powerRankingFinishedSeasonUnrankedText": "(bitmiş sezon sıralanmaz)", + "powerRankingNotInTopText": "İlk (${NUMBER} içinde değil", + "powerRankingPointsEqualsText": "= ${NUMBER} puan", + "powerRankingPointsMultText": "(x ${NUMBER} puan)", + "powerRankingPointsText": "${NUMBER} puan", + "powerRankingPointsToRankedText": "(${REMAINING} puandan ${CURRENT} puan)", + "powerRankingText": "Oyuncu Sıralaman", + "prizesText": "Ödüller", + "proMultInfoText": "${PRO} yükseltmesi olan oyuncular\n${PERCENT}% daha fazla puan kazanır.", + "seeMoreText": "Daha Fazla...", + "skipWaitText": "Beklemeden Geç", + "timeRemainingText": "Kalan Süre", + "toRankedText": "Sıralamasında", + "totalText": "toplam", + "tournamentInfoText": "Ligindeki diğer oyuncular arasında\nen yüksek skoru yap.\n\nÖdüller En fazla skor yapan oyuncular\narasında turnuva süresi bittiğinde verilir.", + "welcome1Text": "${LEAGUE} hoş geldiniz. Lig sıralamanı turnuvalarda\nyıldız derecesi kazanarak, başarıları tamamlayarak\nve kupalar kazanarak geliştirebilirsin.", + "welcome2Text": "Ayrıca benzer aktivitelerden biletler kazanabilirsin.\nBiletler yeni karakterler, haritalar, mini-oyunlar\nve turnuvalara katılmak için kulanılabilir.", + "yourPowerRankingText": "Oyuncu Sıralaman:" + }, + "copyConfirmText": "Panoya kopyalandı.", + "copyOfText": "Kopya ${NAME}", + "copyText": "Kopyala", + "createEditPlayerText": "", + "createText": "Oluştur", + "creditsWindow": { + "additionalAudioArtIdeasText": "Ek Ses, Early Artwork ve ${NAME} dan fikirler", + "additionalMusicFromText": "${NAME} tarafından ilave müzik", + "allMyFamilyText": "Tüm aile ve arkadaşlarım, kimler yardımcı olduysa", + "codingGraphicsAudioText": "${NAME} tarafından Kodlama, Grafikler ve Ses", + "languageTranslationsText": "Dil Çevirileri:", + "legalText": "Yasal:", + "publicDomainMusicViaText": "${NAME} ile Kullanımı serbest müzik", + "softwareBasedOnText": "Bu yazılım ${NAME} altyapısının bir parçasıdır", + "songCreditText": "${TITLE}, ${PERFORMER} tarafından yapıldı\n${COMPOSER} tarafından bestelendi, ${ARRANGER} tarafından düzenlendi\n${PUBLISHER} tarafından yayımlandı, ${SOURCE} ya iltifaten.", + "soundAndMusicText": "Ses & Müzik:", + "soundsText": "Sesler (${SOURCE}):", + "specialThanksText": "Özel Teşekkürler:", + "thanksEspeciallyToText": "Özellikle ${NAME} a Teşkkürler", + "titleText": "${APP_NAME} Jenerik", + "whoeverInventedCoffeeText": "Kahveyi kim icat ettiyse" + }, + "currentStandingText": "Şu anki mevkin #${RANK}", + "customizeText": "Özelleştir...", + "deathsTallyText": "${COUNT} Ölüm", + "deathsText": "Ölümler", + "debugText": "Hata Ayıklama", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Not: Bunu test ederken Ayarlar->Grafikler->Dokular'ı 'Yüksek' yapmanız önerilir.", + "runCPUBenchmarkText": "CPU Benchmark Çalıştır", + "runGPUBenchmarkText": "GPU Benchmark Çalıştır", + "runMediaReloadBenchmarkText": "Medya-Yükleme Benchmark Çalıştır", + "runStressTestText": "Stres Testi Çalıştır", + "stressTestPlayerCountText": "Oyuncu Sayısı", + "stressTestPlaylistDescriptionText": "Stres Testi ÇalmaListesi", + "stressTestPlaylistNameText": "ÇalmaListesi Adı", + "stressTestPlaylistTypeText": "ÇaşmaListesi Tipi", + "stressTestRoundDurationText": "Tur Süresi", + "stressTestTitleText": "Stres Testi", + "titleText": "Benchmark & Stres Testleri", + "totalReloadTimeText": "Tomplam yükleme zamanı: ${TIME} (detaylar için kayda bak)" + }, + "defaultGameListNameText": "Varsayılan ${PLAYMODE} ÇalmaListesi", + "defaultNewGameListNameText": "Benim ${PLAYMODE} ÇalmaListem", + "deleteText": "Sil", + "demoText": "Tanıtım", + "denyText": "Reddet", + "deprecatedText": "Kullanımdan kaldırıldı", + "desktopResText": "PC Çözünürlüğü", + "deviceAccountUpgradeText": "Uyarı:\n(${NAME}) isimli bir cihaz hesabıyla giriş yaptın.\nCihaz hesapları gelecek güncellemelerde kaldırılacak.\nİlerlemeni tutmak istiyorsan V2 hesabına geçiş yap.", + "difficultyEasyText": "Kolay", + "difficultyHardOnlyText": "Sadece Zor Mod", + "difficultyHardText": "Zor", + "difficultyHardUnlockOnlyText": "Bu seviye sadece Zor modda açılır.\nNeler olabileceğini düşünebiliyor musun!?!?", + "directBrowserToURLText": "Lütfen gelen URL yi doğrudan bir web tarayıcıyda kullanın:", + "disableRemoteAppConnectionsText": "Remote-App Bağlantılarını Engelle", + "disableXInputDescriptionText": "4 kontrolcüden fazla kullanılabilir fakat iyi çalışmayabilir.", + "disableXInputText": "XInput etkisizleştir", + "doneText": "Tamam", + "drawText": "Beraberlik", + "duplicateText": "Kopyala", + "editGameListWindow": { + "addGameText": "Oyun\nEkle", + "cantOverwriteDefaultText": "Varsayılan çalmaListesinin üzerine yazılamaz!", + "cantSaveAlreadyExistsText": "Bu isimde bir çalmaListesi zaten var!", + "cantSaveEmptyListText": "Boş çalmaListesi kaydedilemez!", + "editGameText": "Oyun\nDüzenle", + "listNameText": "ÇalmaListesi Adı", + "nameText": "İsim", + "removeGameText": "Oyun\nKaldır", + "saveText": "Listeyi Kaydet", + "titleText": "ÇalmaListesi Editörü" + }, + "editProfileWindow": { + "accountProfileInfoText": "Bu özel profil, ismin ve simgen\nüzerine oluşturulur.\n\n${ICONS}\n\n\nKullanmak için özel profil yarat", + "accountProfileText": "(hesap profili)", + "availableText": "\"${NAME}\" adı kullanılabilir.", + "characterText": "karakter", + "checkingAvailabilityText": "\"${NAME}\" kullanılabilirliği kontrol ediliyor...", + "colorText": "renk", + "getMoreCharactersText": "Daha Fazla Karakter...", + "getMoreIconsText": "Daha Fazla Simge...", + "globalProfileInfoText": "Global oyuncu profilleri dünya çapında benzersiz\nisimleri garanti eder.Ayrıca özel simgeleri kapsar.", + "globalProfileText": "(global profil)", + "highlightText": "vurgu", + "iconText": "simge", + "localProfileInfoText": "Yerel oyuncu profilleri, simgenin ve adının benzersiz\nolmasını garanti etmez.Global profile yükseltirsen\nbenzersiz ad ve simge rezerv edebilirsin.", + "localProfileText": "(yerel profil)", + "nameDescriptionText": "Oyuncu Adı", + "nameText": "Ad", + "randomText": "rastgele", + "titleEditText": "Profil Düzenle", + "titleNewText": "Yeni Profil", + "unavailableText": "\"${NAME}\" kullanılamaz; başka bir tane dene.", + "upgradeProfileInfoText": "Bu senin dünya çapında benzersiz oyuncu adı\nalmanı ve özel simge atamanı sağlar.", + "upgradeToGlobalProfileText": "Global Profile Yükselt" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Varsayılan müzikListesini silemezsin.", + "cantEditDefaultText": "Varsayılan müzikListesini düzenleyemezsin. Birleştirebilir ya da yenisini yapabilirsin.", + "cantOverwriteDefaultText": "Varsayılan müzikListesinin üzerine yazılamaz", + "cantSaveAlreadyExistsText": "Bu isimde bir müzikListesi zaten mevcut!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Varsayılan MüzikListesi", + "deleteConfirmText": "MüzikListesini Sil:\n\n'${NAME}' ?", + "deleteText": "MüzikListesi\nSil", + "duplicateText": "MüzikListesi\nKopyala", + "editSoundtrackText": "MüzikListesi Editörü", + "editText": "MüzikListesi\nDüzenle", + "fetchingITunesText": "iTunes Müzikleri Alınıyor", + "musicVolumeZeroWarning": "Uyarı: müzik seviyesi 0 ayarlanmış", + "nameText": "İsim", + "newSoundtrackNameText": "MüzikListem ${COUNT}", + "newSoundtrackText": "Yeni MüzikListesi:", + "newText": "MüzikListesi\nYarat", + "selectAPlaylistText": "ÇalmaListesi Seç", + "selectASourceText": "Müzik Kaynağı", + "testText": "test", + "titleText": "MüzikListeleri", + "useDefaultGameMusicText": "Varsayılan Oyun Müziği", + "useITunesPlaylistText": "iTunesçalma listesi", + "useMusicFileText": "Müzik Dosyası (mp3, vb)", + "useMusicFolderText": "Müzik Dosyaları Klasörü" + }, + "editText": "Düzenle", + "endText": "Bitir", + "enjoyText": "Keyfini Çıkar!", + "epicDescriptionFilterText": "${DESCRIPTION} epik ağırçekim.", + "epicNameFilterText": "Epik ${NAME}", + "errorAccessDeniedText": "erişim reddedildi", + "errorDeviceTimeIncorrectText": "Cihazın ile sunucu arasındaki zaman farkı ${HOURS} saat.\nBu bazı sorunlara yol açabilir.\nLütfen saat ve saat dilimi ayarlarını kontrol et.", + "errorOutOfDiskSpaceText": "disk alanı doldu", + "errorSecureConnectionFailText": "Güvenli bulut bağlantısı kurulamadı; ağ işlevi başarısız olabilir.", + "errorText": "Hata", + "errorUnknownText": "bilinmeyen hata", + "exitGameText": "Çık ${APP_NAME}?", + "exportSuccessText": "'${NAME}' Dışa Aktarıldı.", + "externalStorageText": "Harici Depolama", + "failText": "Başarısızlık", + "fatalErrorText": "Uh oh; bir şeyler eksik veya hatalı\nLütfen uygulamayı yeniden yükleyin\nveya ${EMAIL} ile yardım alın.", + "fileSelectorWindow": { + "titleFileFolderText": "Bir Dosya veya Klasör Seç", + "titleFileText": "Bir Dosya Seç", + "titleFolderText": "Bir Klasör Seç", + "useThisFolderButtonText": "Bu Klasörü Kullan" + }, + "filterText": "Filtre", + "finalScoreText": "Final Skoru", + "finalScoresText": "Final Skorları", + "finalTimeText": "Final Süresi", + "finishingInstallText": "Yükleme tamamlanıyor; bir dakika...", + "fireTVRemoteWarningText": "* En iyi deneyim için, Oyun\nkontrolcüsü kullanın veya\n'${REMOTE_APP_NAME}' uygulamasını\ntablet ya da telefonunuza yükleyin.", + "firstToFinalText": "İlk-${COUNT} Final", + "firstToSeriesText": "İlk-${COUNT} Seri", + "fiveKillText": "5 Öldürme!!!", + "flawlessWaveText": "Çiziksiz Dalga!", + "fourKillText": "Dörtlü Öldürme!!!", + "friendScoresUnavailableText": "Arkadaş skorları mevcut değil.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Oyun ${COUNT} Liderler", + "gameListWindow": { + "cantDeleteDefaultText": "Varsayılan çalmaListesini silemezsin.", + "cantEditDefaultText": "Varsayılan çalmaListesi düzenlenemez! Kopyalanabilir ya da yenisi yapılabilir.", + "cantShareDefaultText": "Varsayılan ÇalmaListesi paylaşılamaz.", + "deleteConfirmText": "Sil \"${LIST}\"?", + "deleteText": "ÇalmaListesi\nSil", + "duplicateText": "ÇalmaListesi\nKopyala", + "editText": "ÇalmaListesi\nDüzenle", + "newText": "ÇalmaListesi\nYarat", + "showTutorialText": "Öğreticiyi Göster", + "shuffleGameOrderText": "Oyun Sırasını Karıştır", + "titleText": "Özel ${TYPE} ÇalmaListeleri" + }, + "gameSettingsWindow": { + "addGameText": "Oyun Ekle" + }, + "gamesToText": "${WINCOUNT}-${LOSECOUNT} kazandı", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Hatırlatma: Eğer yeterince kontrolcüye sahipsen,\nher cihazda birden fazla oyuncu partiye katılabilir.", + "aboutDescriptionText": "Bu sekmeleri partide toplanmak için kullan\n\nPartiler, oyunları ve turnuvaları başka cihazlar\nile birlikte oynamanı sağlar.\n\nSohbet ve parti ile etkileşim için sağ üstteki\n${PARTY} butonunu kullan.\n(menüdeyken kontrolcüden ${BUTTON} simgesine bas)", + "aboutText": "Hakkında", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} sana ${APP_NAME} ile ${COUNT} bilet gönderdi.", + "appInviteSendACodeText": "Bir Kod Gönder", + "appInviteTitleText": "${APP_NAME} Uygulama Daveti", + "bluetoothAndroidSupportText": "(bluetooth destekli tüm adroid cihazla ile çalışır)", + "bluetoothDescriptionText": "Bluetooth ile bir parti Kur/katıl:", + "bluetoothHostText": "Bluetooth ile Kur", + "bluetoothJoinText": "Bluetooth ile Katıl", + "bluetoothText": "Bluetooth", + "checkingText": "denetleniyor...", + "copyCodeConfirmText": "Kod panoya kopyalandı", + "copyCodeText": "Kodu kopyala", + "dedicatedServerInfoText": "En iyi sonuçlar için ozel sunucu ayarlayın. Bakınız; bombsquadgame.com/server", + "disconnectClientsText": "Bu, partindeki ${COUNT} oyuncunun bağlantısını\nkesecek. Emin misin ?", + "earnTicketsForRecommendingAmountText": "Eğer arkadaşların oyunu denerler ise ${COUNT} bilet alacak\n(Sen ise bunu her yapan için ${YOU_COUNT} tane.)", + "earnTicketsForRecommendingText": "Bedave bilet için\nOyunu paylaş...", + "emailItText": "E-Posta Gönder", + "favoritesSaveText": "Favori Olarak Kaydet", + "favoritesText": "Favoriler", + "freeCloudServerAvailableMinutesText": "Sonraki ücretsiz bulut sunucusu ${MINUTES} dakika içinde kullanılabilir olacak", + "freeCloudServerAvailableNowText": "Ücretsiz bulut sunucusu şuan kullanılabilir", + "freeCloudServerNotAvailableText": "Ücretsiz bulut sunucusu şuan mevcut değil.", + "friendHasSentPromoCodeText": "${NAME} tarafından ${COUNT} ${APP_NAME} bileti", + "friendPromoCodeAwardText": "Kullanıldığı her zaman ${COUNT} bilet alacaksın.", + "friendPromoCodeExpireText": "Bu kodun ${EXPIRE_HOURS} saat içinde süresi dolacak ve sadece yeni oyuncularda çalışır.", + "friendPromoCodeInstructionsText": "Kullanmak için ${APP_NAME} uygulamasını açın ve \"Ayarlar->Gelişmiş->Promo Kodu\"\nna gidin. Tüm platformlar arası İndirme bağlantıları için bombsquadgame.com'a gidin.", + "friendPromoCodeRedeemLongText": "Maksimum ${MAX_USES} kişi olmak üzere ${COUNT} bedava bilet alabilirsin.", + "friendPromoCodeRedeemShortText": "Oyun içi ${COUNT} bilet alabilirsin", + "friendPromoCodeWhereToEnterText": "(Ayarlar>Gelişmiş>Promo kodu gir içinde)", + "getFriendInviteCodeText": "Arkadaş Davet Kodu Al", + "googlePlayDescriptionText": "Partine Google Play oyuncularını davet et:", + "googlePlayInviteText": "Davet", + "googlePlayReInviteText": "Partinde şuan ${COUNT} Google Play oyuncusu var.\nEğer yeni Davet başlatırsan bağlantıları kesilecek.\nTerar yeni davet göndermen gerekecek.", + "googlePlaySeeInvitesText": "Davetleri Gör", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Android / Google Play versiyonu)", + "hostPublicPartyDescriptionText": "Herkese açık bir parti kur.", + "hostingUnavailableText": "Sunucu ev sahipliği mevcut değil", + "inDevelopmentWarningText": "Not:\n\nAğ oyunu yeni ve geliştirilebilir bir özellik.\nŞimdilik tüm oyuncuların aynı Wi-Fi ağına bağlı\nolması önerilir.", + "internetText": "İnternet", + "inviteAFriendText": "Bu oyun arkadaşlarında yok mu? Onları davet et.\nDenerler ise ${COUNT} bedava bilet alacaklar.", + "inviteFriendsText": "Arkadaş Davetleri", + "joinPublicPartyDescriptionText": "Herkese açık bir partiye katıl", + "localNetworkDescriptionText": "Ağındaki bir partiye katıl (LAN, Bluetooth, vb.)", + "localNetworkText": "Yerel Ağ", + "makePartyPrivateText": "Partimi Gizle", + "makePartyPublicText": "Partimi Herkese Açık Yap", + "manualAddressText": "Adres", + "manualConnectText": "Bağlan", + "manualDescriptionText": "Adres ile partiye katıl:", + "manualJoinSectionText": "Adresle Katıl", + "manualJoinableFromInternetText": "İnternet üzerinden katılınabilirliğin?:", + "manualJoinableNoWithAsteriskText": "HAYIR*", + "manualJoinableYesText": "EVET", + "manualRouterForwardingText": "*Bunu düzeltmek için, modeminizden yerel adresinizin UDP portunu ${PORT} yapın", + "manualText": "Manuel", + "manualYourAddressFromInternetText": "İnternetteki adresiniz:", + "manualYourLocalAddressText": "Yerel adresiniz:", + "nearbyText": "Yakında", + "noConnectionText": "", + "otherVersionsText": "(diğer sürümler)", + "partyCodeText": "Parti kodu", + "partyInviteAcceptText": "Kabul Et", + "partyInviteDeclineText": "Reddet", + "partyInviteGooglePlayExtraText": "('Lobi' penceresinden 'Google Play' sekmesine bakın)", + "partyInviteIgnoreText": "Gözardı Et", + "partyInviteText": "${NAME} seni partisine\nkatılman için davet etti!", + "partyNameText": "Parti Adı", + "partyServerRunningText": "Parti sunucun çalışıyor.", + "partySizeText": "parti kapasitesi", + "partyStatusCheckingText": "durum denetleniyor...", + "partyStatusJoinableText": "şuan partine internetten katılınabilir", + "partyStatusNoConnectionText": "sunucuya bağlanılamıyor", + "partyStatusNotJoinableText": "partin internetten katılınabilir değil", + "partyStatusNotPublicText": "partin herkese açık değil", + "pingText": "ping", + "portText": "Port", + "privatePartyCloudDescriptionText": "Özel partiler özel bulut sunucularında çalışır; yönlendirici yapılandırması gerekmez", + "privatePartyHostText": "Özel bir partiye ev sahipliği yapın", + "privatePartyJoinText": "Özel Bir Partiye Katılın", + "privateText": "Özel", + "publicHostRouterConfigText": "Bu, yönlendiricinizde bağlantı noktası iletme yapılandırması gerektirebilir. Daha kolay bir seçenek için, özel bir partiye ev sahipliği yapın.", + "publicText": "Herkese Açık", + "requestingAPromoCodeText": "Kod talep ediliyor...", + "sendDirectInvitesText": "Doğrudan Davet Gönder", + "shareThisCodeWithFriendsText": "Bu kodu arkadaşların ile paylaş:", + "showMyAddressText": "Adresimi Göster", + "startHostingPaidText": "${COST} karşılığında ev sahibi olun", + "startHostingText": "Ev sahibi ol", + "startStopHostingMinutesText": "Önümüzdeki ${MINUTES} dakika boyunca ücretsiz ev sahibi özelliğini başlatıp durdurabilirsiniz.", + "stopHostingText": "Ev sahipliğini durdur", + "titleText": "Lobi", + "wifiDirectDescriptionBottomText": "Eğer tüm cihazların 'Wi-Fi Direct' paneli varsa, diğerlerini bulmak ve bağlanmak için\nkullanılabilir. Tüm cihazlar bağlandığında, Aynı Wi-Fi ağına bağlıymış gibi 'Yerel Ağ'\nsekmesini kullanarak partiler oluşturabilirsin. \n\nEn iyi sonuç için, Wi-Fi Direct kurucusu ayrıca ${APP_NAME} parti kurucusu olmalı.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct Android cihazların Wi-Fi ağı ihtiyacı olmadan doğrudan\nbağlanmasını sağlar.Bu en iyi Android 4.2 ve üstünde çalışır.\n\nKullanmak için, Wi-Fi ayarlarını açın ve Menüden 'Wi-Fi Direct' e bakın.", + "wifiDirectOpenWiFiSettingsText": "Wi-Fi Ayarlarını Aç", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(tüm platformlar arasında çalışır)", + "worksWithGooglePlayDevicesText": "(Google Play (android) sürümü kullanan cihazlar arasında çalışır)", + "youHaveBeenSentAPromoCodeText": "${APP_NAME} promo kodu gönderdin:" + }, + "getTicketsWindow": { + "freeText": "ÜCRETSİZ!", + "freeTicketsText": "Ücretsiz Bilet", + "inProgressText": "Ödeme işlemde... lütfen birazdan tekrar deneyin.", + "purchasesRestoredText": "Satın Almalar Geri Yüklendi.", + "receivedTicketsText": "${COUNT} Bilet Alındı!", + "restorePurchasesText": "Satın Almaları Geri Yükle", + "ticketPack1Text": "Ufak Bilet Paketi", + "ticketPack2Text": "Standart Bilet Paketi", + "ticketPack3Text": "Büyük Bilet Paketi", + "ticketPack4Text": "Dev Bilet Paketi", + "ticketPack5Text": "Muazzam Bilet Paketi", + "ticketPack6Text": "En Üst Düzey Bilet Paketi", + "ticketsFromASponsorText": "${COUNT} Bilet için\nbir reklam izle", + "ticketsText": "${COUNT} Bilet", + "titleText": "Bilet Al", + "unavailableLinkAccountText": "Üzgünüz, Satın almalar bu patformda kullanılamaz.\nBu geçici oldugu gibi, bu hesabını diğer platformlardaki\nhesablara bağlayabilir oradan satın alma işlemi yapbilirsin.", + "unavailableTemporarilyText": "Bu şu anda müsait değil; lütfen daha sonra tekrar deneyin.", + "unavailableText": "Üzgünüz, Bu mümkün değil.", + "versionTooOldText": "Üzgünüz, Oyunun bu sürümü çok eski; lütfen yeni bir sürüme güncelleyin.", + "youHaveShortText": "${COUNT} Biletin var", + "youHaveText": "${COUNT} biletin var" + }, + "googleMultiplayerDiscontinuedText": "Üzgünüz, Google'ın çok oyunculu servisi şu anda çalışmıyor.\nBir yer değişimi için olabildiğince hızlı çalışıyorum.\nO zamana kadar, lütfen başka bir bağlantı yöntemi deneyin.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Google Play satın alma işlemleri mevcut değildir.\nMağaza uygulamanızı güncellemeniz gerekebilir.", + "googlePlayServicesNotAvailableText": "Google Play Hizmetleri kullanılamıyor.\nBazı uygulama işlevleri devre dışı bırakılabilir.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Her Zaman", + "fullScreenCmdText": "Tam Ekran (Cmd-F)", + "fullScreenCtrlText": "Tam Ekran (Ctrl-F)", + "gammaText": "Gama", + "highText": "Yüksek", + "higherText": "Çok Yüksek", + "lowText": "Düşük", + "mediumText": "Orta", + "neverText": "Asla", + "resolutionText": "Çözünürlük", + "showFPSText": "FPS göster", + "texturesText": "Dokular", + "titleText": "Grafikler", + "tvBorderText": "TV Ekranı", + "verticalSyncText": "Dikey Senkron", + "visualsText": "Görseller" + }, + "helpWindow": { + "bombInfoText": "- Bomba -\nYumruktan daha güçlüdür, fakat\nkendi bomban ile zarar görebilirsin.\nEn iyi sonuç için fitil bitmeden önce\ndüşmanlarına doğru fırlat.", + "canHelpText": "${APP_NAME} sana yardımcı olabilir.", + "controllersInfoText": "Arkadaşlarınla birlikte ağ üzerinden veya yeterince kontrolcünüz\nvar ise tek bir cihazdan ${APP_NAME} oynayabilirsiniz.\nHatta telefonunuzu bile bedava '${REMOTE_APP_NAME}' uygulaması ile\nkontrolcü olarak kullanabilirsiniz. ${APP_NAME} bunu destekler.\nDaha fazla bilgi için Ayarlar->Kontroller'e bakın.", + "controllersInfoTextRemoteOnly": "${APP_NAME} 'ı internet üzerinden arkadaşlarınla, ya da telefonları kullanarak aynı cihaz\nüzerinden\n'${REMOTE_APP_NAME}' uygulamasını kullanarak oynayabilirsin.", + "controllersText": "Kontrolcüler", + "controlsSubtitleText": "Dost Canlısı ${APP_NAME} karakterinin birkaç basit özelliği var:", + "controlsText": "Kontroller", + "devicesInfoText": "${APP_NAME}'ın VR sürümü ile normal sürümü ağ\nüzerinde oynanabilir. Yani ekstra telefon, tablet veya\nbilgisayar al ve oyunu aç, Oyunun normal sürümünü\nVR sürümüne bağlamak kullanışlıdır, başkalarının\noyunu izlemesini sağlar.", + "devicesText": "Cihazlar", + "friendsGoodText": "Bunların olması güzel. ${APP_NAME} birkaç oyuncu ile daha\neğlencelidir. Tek seferde 8 oyuncuya kadar destekler.", + "friendsText": "Arkadaşlar", + "jumpInfoText": "- Zıpla -\nZıplamak, ufak çıkıntılardan geçmeni\nve bir şeyleri daha yukarı atmanı\nsağlar. Aşırı eğlencelidir.", + "orPunchingSomethingText": "Bir şeyleri patlatmak, uçurumdan fırlatmak veya yoluna çıkanlara yapışkan bomba atmak.", + "pickUpInfoText": "- Kaldır -\nBayrakları, düşmanları veya etraftaki\nherhangi bir şeyi tutmanı sağlar.\nFırlatmak için tekrar bas.", + "powerupBombDescriptionText": "Tek seferde bir bomba yerine \nPeş peşe üç bomba atmanı sağlar.", + "powerupBombNameText": "Üçlü-Bomba", + "powerupCurseDescriptionText": "Muhtemelen bundan kaçınmak isteyeceksin.\n...Ya da istemez misin?", + "powerupCurseNameText": "Lanet", + "powerupHealthDescriptionText": "Sağlığının tamamını doldurur.\nTahmin etmiş olamazsın...", + "powerupHealthNameText": "Sağlık-Paketi", + "powerupIceBombsDescriptionText": "Normal bombalardan güçsüzdür\nfakat düşmanlarını dondurur\nve özellikle kırılgan yapar.", + "powerupIceBombsNameText": "Buz-Bombaları", + "powerupImpactBombsDescriptionText": "Nispeten normal bombalardan\ngüçsüzdür fakat temas halinde patlarlar.", + "powerupImpactBombsNameText": "Tahrik-Bombaları", + "powerupLandMinesDescriptionText": "Bu 3 paket olarak gelir. Bölgeni\nsavunmak ve hızlı düşmanları\ndurdurmak için kullanışlıdır.", + "powerupLandMinesNameText": "Kara-Mayınları", + "powerupPunchDescriptionText": "Yumruklarını daha sert\nhızlı ve güçlü yapar.", + "powerupPunchNameText": "Boks-Eldivenleri", + "powerupShieldDescriptionText": "Senin için bir parça\nhasarı absorbe eder.", + "powerupShieldNameText": "Enerji-Kalkanı", + "powerupStickyBombsDescriptionText": "Değdiği herhangi bir şeye\nyapışır. Eğlence konusu olur.", + "powerupStickyBombsNameText": "Yapışkan-Bombalar", + "powerupsSubtitleText": "Elbette güçlendiriciler olmadan oyun tamamlanmış değildir:", + "powerupsText": "Güçlendiriciler", + "punchInfoText": "- Yumruk -\nYumruklar, hızlı hareket edersen\ndaha fazla hasar verir.\nYani deli gibi koş ve dön.", + "runInfoText": "- Koş -\nKoşmak için herhangi bir tuşa basılı tut. Koşmak hızlıca yerdeğiştirmeni sağlar\nfakat dönmeni zorlaştırır, yani uçurumlara dikkat et.", + "someDaysText": "Bazı günler canın bir şeyleri yumruklamak ister. Ya da fırlatmak.", + "titleText": "${APP_NAME} Yardımı", + "toGetTheMostText": "Bu oyunu en iyi şekilde oynamak için ihtiyacın olan;", + "welcomeText": "${APP_NAME}'a Hoş Geldiniz!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} Menüde krallar gibi geziniyor -", + "importPlaylistCodeInstructionsText": "ÇalmaListesini bir yerlerde kullanmak için bu kodu kullan:", + "importPlaylistSuccessText": "${TYPE} ÇalmaListesi içe aktarıldı'${NAME}'", + "importText": "İçe Aktar", + "importingText": "İçe Aktarılıyor...", + "inGameClippedNameText": "Şöyle görünecek\n\"${NAME}\"", + "installDiskSpaceErrorText": "HATA: Kurulum tamamlanamıyor.\nCihazınızda boş alan kalmamış olabilir.\nBiraz alan açın ve yeniden deneyin.", + "internal": { + "arrowsToExitListText": "Listeden çıkmak için ${LEFT} ya da ${RIGHT} basın.", + "buttonText": "buton", + "cantKickHostError": "Kurucu'yu atamazsın.", + "chatBlockedText": "${NAME}, ${TIME} saniye sohbette bloklandı.", + "connectedToGameText": "'${NAME}' Sunucusuna girildi", + "connectedToPartyText": "${NAME} Partisine katılındı!", + "connectingToPartyText": "Bağlanılıyor...", + "connectionFailedHostAlreadyInPartyText": "Bağlantı başarısız; Kurucu başka bir partide.", + "connectionFailedPartyFullText": "Bağlantı başarısız; parti dolu", + "connectionFailedText": "Bağlantı başarısız.", + "connectionFailedVersionMismatchText": "Bağlantı başarısız; Kurucu oyunun başka bir sürümünü kullanıyor.\nHer iki cihazın da güncel olduğundan emin olun ve tekrar deneyin.", + "connectionRejectedText": "Bağlantı reddedildi.", + "controllerConnectedText": "${CONTROLLER} bağlandı.", + "controllerDetectedText": "1 kontrolcü algılandı.", + "controllerDisconnectedText": "${CONTROLLER} bağlantısı koptu.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} bağlantısı koptu. Lürfen tekrar bağlamayı deneyin.", + "controllerForMenusOnlyText": "Bu kontrolcü oynamak için kullanılamaz; sadece menüde gezmek için.", + "controllerReconnectedText": "${CONTROLLER} tekrar bağlandı.", + "controllersConnectedText": "${COUNT} kontrolcü bağlandı.", + "controllersDetectedText": "${COUNT} kontrolcü algılandı.", + "controllersDisconnectedText": "${COUNT} kontrolcünün bağlantısı koptu.", + "corruptFileText": "Bozuk dosya algılandı. Lütfen tekrar yükleme yapın, veya E-Posta ${EMAIL}", + "errorPlayingMusicText": "Müzik Çalınırken Hata: ${MUSIC}", + "errorResettingAchievementsText": "Çevrimiçi başarılar sıfırlanamıyor; lütfen daha sonra tekrar deneyin.", + "hasMenuControlText": "${NAME} menü kontrolü yapıyor.", + "incompatibleNewerVersionHostText": "Kurucu oyunun daha yeni bir sürümünü kullanıyor.\nSon sürüme güncelleyin ve tekrar deneyin.", + "incompatibleVersionHostText": "Kurucu oyunun başka bir sürümünü kullanıyor.\nİki cihazın da güncel olduğundan emin olun.", + "incompatibleVersionPlayerText": "${NAME} oyunun başka bir sürümünü kullanıyor.\niki cihazın da güncel olduğundan emin olun.", + "invalidAddressErrorText": "Hata: Geçersiz adres.", + "invalidNameErrorText": "Hata: geçersiz isim.", + "invalidPortErrorText": "Hata: Geçersiz port", + "invitationSentText": "Davet Göderildi.", + "invitationsSentText": "${COUNT} davet gönderildi.", + "joinedPartyInstructionsText": "Biri senin partine katıldı.\nOyunu başlatmak için 'Oyna' ya git", + "keyboardText": "Klavye", + "kickIdlePlayersKickedText": "${NAME} boşta olduğu için atıldı.", + "kickIdlePlayersWarning1Text": "${NAME} boşta durmaya devam ederse ${COUNT} saniye içinde atılacak.", + "kickIdlePlayersWarning2Text": "(Ayarlar-> Gelişmiş den bunu kapatabilirsin)", + "leftGameText": "'${NAME}' Terkedildi", + "leftPartyText": "${NAME}'in partisini terk ettin.", + "noMusicFilesInFolderText": "Klasör müzik dosyası içermiyor.", + "playerJoinedPartyText": "${NAME} partiye katıldı!", + "playerLeftPartyText": "${NAME} partiyi terk etti.", + "rejectingInviteAlreadyInPartyText": "Davet reddedildi (zaten partide).", + "serverRestartingText": "Sunucu yeniden başlatılıyor. Lütfen birazdan tekrar girin...", + "serverShuttingDownText": "Sunucu kapatılıyor...", + "signInErrorText": "Giriş yapılırken Hata.", + "signInNoConnectionText": "Giriş yapılamıyor. (internet bağlantısı yok?)", + "telnetAccessDeniedText": "HATA: kullanıcı telnet erişim izni vermedi.", + "timeOutText": "(${TIME} saniye içinde süre dolacak)", + "touchScreenJoinWarningText": "DokunmatikEkran ile katıldın.\nEğer yanlışlıkla olduysa 'Menü->Oyundan Ayrıl' ile düzelt.", + "touchScreenText": "DokunmatikEkran", + "unableToResolveHostText": "Hata: kurucu çözümlenemiyor.", + "unavailableNoConnectionText": "Bu şu an kullanılamaz (internet bağlantısı yok?)", + "vrOrientationResetCardboardText": "Bunu kullanmak için VR oryantasyonunu sıfırla.\nOyunu oynamak için harici kontrolcüye ihtiyacın olacak.", + "vrOrientationResetText": "VR oryantasyonunu sıfırla.", + "willTimeOutText": "(boşta durursa süre dolacak)" + }, + "jumpBoldText": "ZIPLA", + "jumpText": "Zıpla", + "keepText": "Koru", + "keepTheseSettingsText": "Bu ayarları koru?", + "keyboardChangeInstructionsText": "Klavyeleri değiştirmek için iki defa boşluk tuşuna basın.", + "keyboardNoOthersAvailableText": "Başka klavye yok.", + "keyboardSwitchText": "Klavye \"${NAME}\"'a değiştiriliyor.", + "kickOccurredText": "${NAME} atıldı.", + "kickQuestionText": "${NAME} At ?", + "kickText": "At", + "kickVoteCantKickAdminsText": "Yöneticiler atılamaz.", + "kickVoteCantKickSelfText": "Kendini atamazsın.", + "kickVoteFailedNotEnoughVotersText": "Oylama için yeterli oyuncu yok.", + "kickVoteFailedText": "Atma-oylaması başarısız.", + "kickVoteStartedText": "${NAME} için oyundan atma oylaması başlatıldı.", + "kickVoteText": "Atmak için oyla", + "kickVotingDisabledText": "Atma-oylaması devre dışı.", + "kickWithChatText": "Evet için sohbete ${YES} Hayır için ${NO} yazın.", + "killsTallyText": "${COUNT} öldürme", + "killsText": "Öldürme", + "kioskWindow": { + "easyText": "Kolay", + "epicModeText": "Epik Mod", + "fullMenuText": "Tam Menü", + "hardText": "Zor", + "mediumText": "Orta", + "singlePlayerExamplesText": "Tek Oyuncu / Ekip Örnekleri", + "versusExamplesText": "Karşılaşma Örnekleri" + }, + "languageSetText": "Şuan dil \"${LANGUAGE}\".", + "lapNumberText": "Tur ${CURRENT}/${TOTAL}", + "lastGamesText": "(son ${COUNT} oyun)", + "leaderboardsText": "Lider Tahtası", + "league": { + "allTimeText": "Tüm Zamanlarda", + "currentSeasonText": "Şimdiki sezon (${NUMBER})", + "leagueFullText": "${NAME} Ligi", + "leagueRankText": "Lig Sıralaması", + "leagueText": "Lig", + "rankInLeagueText": "${NAME} Ligi${SUFFIX}, #${RANK}", + "seasonEndedDaysAgoText": "Sezon ${NUMBER} gün önce sonlandı.", + "seasonEndsDaysText": "Sezon ${NUMBER} gün içinde sonlanacak.", + "seasonEndsHoursText": "Sezon ${NUMBER} saat içinde sonlanacak.", + "seasonEndsMinutesText": "Sezon ${NUMBER} dakika içinde sonlanacak", + "seasonText": "Sezon ${NUMBER}", + "tournamentLeagueText": "Bu tunuvaya katılmak için ${NAME} olmalısın.", + "trophyCountsResetText": "Kupalar bir sonraki sezon sıfırlanacak." + }, + "levelBestScoresText": "${LEVEL} En-İyi Skorlar", + "levelBestTimesText": "${LEVEL} En-İyi Süreler", + "levelIsLockedText": "${LEVEL} kilitli.", + "levelMustBeCompletedFirstText": "Önce ${LEVEL} tamamlanmalı.", + "levelText": "Seviye ${NUMBER} oldu", + "levelUnlockedText": "Seviye Açıldı!", + "livesBonusText": "Bonus Canlar", + "loadingText": "yükleniyor", + "loadingTryAgainText": "Yükleniyor; Birazdan tekrar deneyin...", + "macControllerSubsystemBothText": "Her ikisi de (önerilmez)", + "macControllerSubsystemClassicText": "Klasik", + "macControllerSubsystemDescriptionText": "(eğer kontrolcülerin çalışmıyorsa bunu değiştirmeyi dene)", + "macControllerSubsystemMFiNoteText": "Made-for-iOS/Mac kontrolcü algılandı;\nAktifleştirmek istiyorsan Ayarlar -> Kontroller'e git.", + "macControllerSubsystemMFiText": "Made-for-iOS/Mac", + "macControllerSubsystemTitleText": "Kontrolcü Desteği", + "mainMenu": { + "creditsText": "Jenerik", + "demoMenuText": "Demo Menü", + "endGameText": "Oyunu Bitir", + "endTestText": "Testi Bitir", + "exitGameText": "Oyundan Çık", + "exitToMenuText": "Menüye Git?", + "howToPlayText": "Nasıl Oynanır", + "justPlayerText": "(Sadece ${NAME})", + "leaveGameText": "Oyundan Ayrıl", + "leavePartyConfirmText": "Gerçekten partiden ayrılmak istiyor musunuz?", + "leavePartyText": "Partiden Ayrıl", + "quitText": "Çık", + "resumeText": "Sürdür", + "settingsText": "Ayarlar" + }, + "makeItSoText": "Yap", + "mapSelectGetMoreMapsText": "Daha Fazla Harita Al...", + "mapSelectText": "Seç...", + "mapSelectTitleText": "${GAME} Haritaları", + "mapText": "Harita", + "maxConnectionsText": "Maksimum Bağlantı", + "maxPartySizeText": "Maksimum Parti Kapasitesi", + "maxPlayersText": "Maksimum Oyuncu", + "merchText": "Merch!", + "modeArcadeText": "Arcade Modu", + "modeClassicText": "Klasik Mod", + "modeDemoText": "Demo Modu", + "mostValuablePlayerText": "En Değerli Oyuncu", + "mostViolatedPlayerText": "En Çok Saldırılan Oyuncu", + "mostViolentPlayerText": "En Saldırgan Oyuncu", + "moveText": "Hareket", + "multiKillText": "${COUNT}-ÖLDÜRME!!!", + "multiPlayerCountText": "${COUNT} oyuncu", + "mustInviteFriendsText": "Not: Çok oyunculu oynamak için \"${GATHER}\"\npanelinden arkadaş davet etmelisin veya\nkontrolcü bağlamalısın.", + "nameBetrayedText": "${VICTIM}, ${NAME} tarafından ihanete uğradı.", + "nameDiedText": "${NAME} Öldü.", + "nameKilledText": "${VICTIM}, ${NAME} tarafından öldürüldü.", + "nameNotEmptyText": "Ad boş olamaz.", + "nameScoresText": "${NAME} Sayı Yaptı!", + "nameSuicideKidFriendlyText": "${NAME} kazara öldü.", + "nameSuicideText": "${NAME} intihar etti.", + "nameText": "İsim", + "nativeText": "Gerçek", + "newPersonalBestText": "Yeni kişisel rekor!", + "newTestBuildAvailableText": "Yeni bir test yapısı mevcut! (${VERSION} yapı ${BUILD}).\n${ADDRESS} buradan edinebilirsin", + "newText": "Yeni", + "newVersionAvailableText": "${APP_NAME} uygulamasının yeni bir sürümü mevcut! (${VERSION})", + "nextAchievementsText": "Sıradaki Başarılar:", + "nextLevelText": "Sıradaki Seviye", + "noAchievementsRemainingText": "- hiçbiri", + "noContinuesText": "(sürdürülemiyor)", + "noExternalStorageErrorText": "Bu cihazda harici depolama bulunamadı", + "noGameCircleText": "Hata: GameCircle girişi yapılamadı", + "noScoresYetText": "Henüz skor yok.", + "noThanksText": "Hayır Teşekkürler", + "noTournamentsInTestBuildText": "DİKKAT: Bu test sürümündeki turnuva skorları dikkate alınmayacaktır.", + "noValidMapsErrorText": "Bu oyun tipi için geçerli harita bulunamadı.", + "notEnoughPlayersRemainingText": "Yeterince oyuncu kalmadı; çık ve yeni bir oyun başlat.", + "notEnoughPlayersText": "Bu oyunu başlatmak için en az ${COUNT} oyuncuya ihtiyacın var!", + "notNowText": "Şimdi Değil", + "notSignedInErrorText": "Bunu yapmak için giriş yapmalısın.", + "notSignedInGooglePlayErrorText": "Bunu yapmak için Google Play ile giriş yapmalısın.", + "notSignedInText": "giriş yapılmadı", + "notUsingAccountText": "Not: ${SERVICE} hesabı kullanılmıyor\nEğer kullanmak istiyorsanız 'Hesabım -> ${SERVICE} ile Kayıt ol' a gidin.", + "nothingIsSelectedErrorText": "Hiçbir şey seçilmedi!", + "numberText": "#${NUMBER}", + "offText": "Kapalı", + "okText": "Tamam", + "onText": "Açık", + "oneMomentText": "Bir dakika...", + "onslaughtRespawnText": "${PLAYER} oyuncusu ${WAVE}. dalgada yeniden doğacak", + "orText": "${A} veya ${B}", + "otherText": "Diğer...", + "outOfText": "(${ALL} için #${RANK})", + "ownFlagAtYourBaseWarning": "Skor için kendi bayrağın\nkendi bölgende olmalı!", + "packageModsEnabledErrorText": "Ağ-oyunu'na yerel-paket-modları etkinken izin verilmiyor (bak Ayarlar->Gelişmiş)", + "partyWindow": { + "chatMessageText": "Sohbet Mesajı", + "emptyText": "Partin Boş", + "hostText": "(kurucu)", + "sendText": "Gönder", + "titleText": "Partin" + }, + "pausedByHostText": "(kurucu tarafından durduruldu)", + "perfectWaveText": "Mükemmel Dalga!", + "pickUpText": "Kaldır", + "playModes": { + "coopText": "Ekip", + "freeForAllText": "Herkes-Tek", + "multiTeamText": "Çoklu-Takım", + "singlePlayerCoopText": "Tek Oyuncu / Ekip", + "teamsText": "Takımlar" + }, + "playText": "Oyna", + "playWindow": { + "oneToFourPlayersText": "1-4 oyuncu", + "titleText": "Oyna", + "twoToEightPlayersText": "2-8 oyuncu" + }, + "playerCountAbbreviatedText": "${COUNT}p", + "playerDelayedJoinText": "${PLAYER} bir sonraki round başladığında girecek.", + "playerInfoText": "Oyuncu Bilgisi", + "playerLeftText": "${PLAYER} oyunu terk etti.", + "playerLimitReachedText": "${COUNT} oyuncu limitine ulaşıldı; katılımcılar kabul edilmeyecek.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Kendi hesap profilini silemezsin.", + "deleteButtonText": "Profil\nSil", + "deleteConfirmText": "Sil '${PROFILE}' ?", + "editButtonText": "Profil\nDüzenle", + "explanationText": "(bu hesap için özel oyuncu adları ve görünümleri)", + "newButtonText": "Profil\nYarat", + "titleText": "Oyuncu Profilleri" + }, + "playerText": "Oyuncu", + "playlistNoValidGamesErrorText": "Bu ÇalmaListesi içeriği kilitli olmayan oyunlarda geçersiz.", + "playlistNotFoundText": "çalmaListesi bulunamadı", + "playlistText": "Çalma listesi", + "playlistsText": "ÇalmaListesi", + "pleaseRateText": "Eğer ${APP_NAME}'dan zevk aldıysan, lütfen oyunu değerlerdir\nve yorumunu yaz. Bu oyunun daha fazla geliştirilmesine\nyardımcı olur.\n\nteşekkürler!\n-eric", + "pleaseWaitText": "Lütfen bekle...", + "pluginClassLoadErrorText": "'${PLUGIN}' eklenti sınıfı yüklenirken hata oluştu: ${ERROR}", + "pluginInitErrorText": "'${PLUGIN}' eklentisi başlatılırken hata oluştu: ${ERROR}", + "pluginSettingsText": "Eklenti Ayarları", + "pluginsAutoEnableNewText": "Yeni Eklentileri Otomatik Etkinleştir", + "pluginsDetectedText": "Yeni eklentiler tespit edildi. Onları etkinleştirmek veya ayarlarda yapılandırmak için oyunu yeniden başlatın.", + "pluginsDisableAllText": "Tüm Eklentileri Devre Dışı Bırak", + "pluginsEnableAllText": "Tüm Eklentileri Etkinleştir", + "pluginsRemovedText": "${NUM} eklenti(ler) artık bulunmuyor.", + "pluginsText": "Eklentiler", + "practiceText": "Alıştırma", + "pressAnyButtonPlayAgainText": "Tekrar oynamak için bir tuşa basın...", + "pressAnyButtonText": "Devam etmek için bir tuşa basın...", + "pressAnyButtonToJoinText": "Katılmak için bir tuşa basın...", + "pressAnyKeyButtonPlayAgainText": "Tekrar oynamak için herhangi bir tuş/butona basın...", + "pressAnyKeyButtonText": "Devam etmek için bir tuş/buton'a basın...", + "pressAnyKeyText": "Bir tuşa basın...", + "pressJumpToFlyText": "** Uçmak için defalarca zıplaya basın **", + "pressPunchToJoinText": "Katılmak için YUMRUK'a basın...", + "pressToOverrideCharacterText": "karakterini değiştirmek için ${BUTTONS}'ya bas", + "pressToSelectProfileText": "karakter seçmek için ${BUTTONS} bas.", + "pressToSelectTeamText": "takım seçmek için ${BUTTONS} bas.", + "promoCodeWindow": { + "codeText": "Kod", + "enterText": "Gir" + }, + "promoSubmitErrorText": "Kod gönderilirken hata oluştu; internet bağlantını kontrol et", + "ps3ControllersWindow": { + "macInstructionsText": "PS3'ünüzü kapatıp açın. Bluetooth'un Mac'inizde etkin\nolduğundan emin olun. Her ikisini eşlemek için kontrolcünüzü\nUSB kablosu ile Mac'inize bağlayın.Yaptığınızda kontrolcülerin\nhome butonuna basarak Kablolu(USB) ya da Kablosuz(Bluetooth)\nolarak bağlanabilirsiniz.\n\nBazı Macler eşlemek için şifre isterler. Eğer bu olursa;\nTakip eden öğreticiye bakın ya da google dan yardım alın.\n\n\n\n\nBağlı olan PS3 Kontrollerini aygıt listesinden görebilirsiniz;\nTercihler->Bluetooth. PS3'ünü tekrar kullanmak istiyorsan listeden\nkaldırmalısın.\n\nAyrıca kullanmadığın zaman pilinin bitmemesi için bağlantısının\nkesildiğinden emin ol.\n\nBluetooth çeşitli uzaklıklardan 7 tane bağlı cihaza\nkadar destekler", + "ouyaInstructionsText": "OUYA ile PS3 kotnroller kullanmak; basitçe eşlemek için USB kablosunu\nbağlayın. Bunu yapmak diğer kontrolcülerin bağlantısını kesebilir.\nOUYA yeniden başlatıp USB kablosunu çıkarabilirsin \n\nKontrolcüleri kablosuz bağlayıp kullanabilmek için HOME\nbutotnuna basmalısın. Oynadıktan sonra kontrolcüyü kapatmak\niçin HOME butonuna 10 saniye basılı tutmalısın. Bunu yapmamak\nbataryanı harcamana neden olur.", + "pairingTutorialText": "eşleme öğretici video", + "titleText": "PS3 kolu ile ${APP_NAME} kullan:" + }, + "punchBoldText": "YUMRUK", + "punchText": "yumruk", + "purchaseForText": "${PRICE} için Satın Al", + "purchaseGameText": "Oyun Satın Al", + "purchasingText": "Satın Alınıyor...", + "quitGameText": "Çık ${APP_NAME}?", + "quittingIn5SecondsText": "5 saniye içinde çıkılacak...", + "randomPlayerNamesText": "DEFAULT_NAMES", + "randomText": "Rastgele", + "rankText": "Sıralama", + "ratingText": "Derecelendirme", + "reachWave2Text": "Sıralama için dalga 2'ye ulaş.", + "readyText": "hazır", + "recentText": "En Son", + "remoteAppInfoShortText": "${APP_NAME} aile ve arkadaşların ile oynadığında daha eğlencelidir.\nBir veya daha fazla donanım kontrolcüsü bağla veya ${REMOTE_APP_NAME}\nuygulamasını telefon veya tablette kontrolcü olarak kullanmak\niçin indir.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Buton Pozisyonu", + "button_size": "Buton Boyutu", + "cant_resolve_host": "Sunucu Çözülemiyor.", + "capturing": "Yakalanıyor...", + "connected": "Bağlanıldı.", + "description": "Telefonunu veya tabletini BombSquad'da kontrolcü olarak kullan.\nTek seferde 8 oyuncuya kadar Destansı yerel çoklu oyuncu çılgınlığına TV veya tablet ile bağlanılabilir.", + "disconnected": "Sunucu bağlantısı kesildi.", + "dpad_fixed": "Sabit", + "dpad_floating": "Kaydırma", + "dpad_position": "D-Pad Posizyonu", + "dpad_size": "D-Pad Boyutu", + "dpad_type": "D-Pad Tipi", + "enter_an_address": "Bir Adres Gir", + "game_full": "Bu oyun dolu veya bağlantıları kabul etmiyor.", + "game_shut_down": "Oyun Kapalı", + "hardware_buttons": "Fiziksel Butonlar", + "join_by_address": "Adres ile Katıl...", + "lag": "Gecikme: ${SECONDS} saniye", + "reset": "Varsayılana Sıfırla", + "run1": "Koş 1", + "run2": "Koş 2", + "searching": "BombSquad oyunları araştırılıyor...", + "searching_caption": "Katılacağın oyunun adına tıkla.\nOyun ile aynı ağa bağlı olduğundan emin ol.", + "start": "Başlat", + "version_mismatch": "Versiyon uyuşmuyor.\nBombSquad ve BombSquad Remote'nin son \nsürüm olduğundan emin ol ve tekrar dene." + }, + "removeInGameAdsText": "Oyun-içi reklamları kaldırmak için \"${PRO}\" kilidini mağazadan aç.", + "renameText": "Yeniden Adlandır", + "replayEndText": "Tekrarı Kapat", + "replayNameDefaultText": "Son Oyun Tekrarı", + "replayReadErrorText": "Tekrar dosyası okunurken hata.", + "replayRenameWarningText": "Saklamak istiyorsan \"${REPLAY}\"nı yeniden adlandır; aksi halde üzerine yazılacak.", + "replayVersionErrorText": "Üzgünüz, Bu tekrar oyunun eski bir sürümünde\nyapılmış ve kullanılamaz.", + "replayWatchText": "Tekrar İzle", + "replayWriteErrorText": "Tekrar dosyası yazılırken hata.", + "replaysText": "Tekrarlar", + "reportPlayerExplanationText": "Hile, uygunsuz dil ya da diğer kötü şeyleri rapor etmek için bu E-Postayı kullanın.\nLütfen aşağıya belirtin:", + "reportThisPlayerCheatingText": "Hile", + "reportThisPlayerLanguageText": "Uygunsuz Dil", + "reportThisPlayerReasonText": "Ne raporu göndermek istersiniz?", + "reportThisPlayerText": "Bu Oyuncuyu Rapor Et", + "requestingText": "Talep Ediliyor...", + "restartText": "Yeniden Başlat", + "retryText": "Tekrar Dene", + "revertText": "Eski Haline Döndür", + "runText": "Koş", + "saveText": "Kaydet", + "scanScriptsErrorText": "Betikleri tararken hata oluştu; detaylar için logları kontrol edin.", + "scoreChallengesText": "Mücadele Skoru", + "scoreListUnavailableText": "Skor listesi mevcut değil.", + "scoreText": "Skor", + "scoreUnits": { + "millisecondsText": "Milisaniye", + "pointsText": "Puanlar", + "secondsText": "Saniye" + }, + "scoreWasText": "(${COUNT} idi)", + "selectText": "Seç", + "seriesWinLine1PlayerText": "SERİLERİ", + "seriesWinLine1TeamText": "SERİLERİ", + "seriesWinLine1Text": "SERİLERİ", + "seriesWinLine2Text": "KAZANDI!", + "settingsWindow": { + "accountText": "Hesap", + "advancedText": "Gelişmiş", + "audioText": "Ses", + "controllersText": "Kontroller", + "graphicsText": "Grafikler", + "playerProfilesMovedText": "Not: Oyuncu profilleri, ana menüdeki Hesaplar penceresine taşındı.", + "titleText": "Ayarlar" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(Basitçe; yazı yazmak için daha kullanışlı ekran klavyesi)", + "alwaysUseInternalKeyboardText": "Her zaman Dahili Klavye Kullan", + "benchmarksText": "Benchmark & Stres-Testleri", + "disableCameraGyroscopeMotionText": "Kamera Jiroskop Hareketini Devre Dışı Bırak", + "disableCameraShakeText": "Kamera Titremesini Devre Dışı Bırak", + "disableThisNotice": "(bu bildiriyi gelişmiş ayarlardan devre dışı bırakabilirsiniz)", + "enablePackageModsDescriptionText": "(ekstra modlama özelliği ekler fakat ağ-oyununu etkisiz kılar)", + "enablePackageModsText": "Yerel Paket Modlarını Etkinleştir", + "enterPromoCodeText": "Kodu gir", + "forTestingText": "Not: Bu değerler sadece test için ve uygulamadan çıkıldığında sıfırlanacak.", + "helpTranslateText": "${APP_NAME}'ın İngilizce olmayan çevirileri topluluk yardımı ile\nyapılabilir. Katkı veya düzgün çeviri yapmak istiyorsan aşağıdaki\nbağlantıya tıkla. Şimdiden teşekkürler!", + "kickIdlePlayersText": "Boştaki Oyuncuları Çıkar", + "kidFriendlyModeText": "Çoçuk Modu (Azaltılmış şiddet, vb)", + "languageText": "Dil", + "moddingGuideText": "Modlama Rehberi", + "mustRestartText": "Etkisini göstermesi için oyunu yeniden başlatmalısınız.", + "netTestingText": "Ağ Testi", + "resetText": "Sıfırla", + "showBombTrajectoriesText": "Bomba Gidişatını Göster", + "showInGamePingText": "Oyun İçinde Gecikmeyi Göster", + "showPlayerNamesText": "Oyuncu Adlarını Göster", + "showUserModsText": "Mod Klasörünü Göster", + "titleText": "Gelişmiş", + "translationEditorButtonText": "${APP_NAME} Çeviri Editörü", + "translationFetchErrorText": "çeviri durumu mevcut değil", + "translationFetchingStatusText": "Çeviri durumu kontrol ediliyor...", + "translationInformMe": "Benim dilimin güncellenmesi gerektiğinde bana haber ver", + "translationNoUpdateNeededText": "Şu anki dil güncel; wohooo!", + "translationUpdateNeededText": "** Şu anki dilin güncellenmeye ihtiyacı var!! **", + "vrTestingText": "VR Testi" + }, + "shareText": "Paylaş", + "sharingText": "Paylaşılıyor...", + "showText": "Göster", + "signInForPromoCodeText": "Kodlar etkisini göstermesi için bir hesap ile giriş yapmalısın.", + "signInWithGameCenterText": "Game Center hesabı kullanmak için\nGame Center uygulaması ile giriş yap.", + "singleGamePlaylistNameText": "Sadece ${GAME}", + "singlePlayerCountText": "1 oyuncu", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Karakter Seçimi", + "Chosen One": "Seçilmiş Kişi", + "Epic": "Epik Mod Oyunları", + "Epic Race": "Epik Yarış", + "FlagCatcher": "Bayrak Kapmaca", + "Flying": "Düşler Vadisi", + "Football": "Futbol", + "ForwardMarch": "Hücum", + "GrandRomp": "İşgal", + "Hockey": "Hokey", + "Keep Away": "Uzak Dur", + "Marching": "Dolambaç", + "Menu": "Ana Menü", + "Onslaught": "Saldırı", + "Race": "Yarış", + "Scary": "Tepelerin Hakimi", + "Scores": "Skor Ekranı", + "Survival": "Eleme", + "ToTheDeath": "Ölüm Müsabakası", + "Victory": "Final Skoru Ekranı" + }, + "spaceKeyText": "boşluk", + "statsText": "İstatistikler", + "storagePermissionAccessText": "Bu depolama erişimine ihtiyaç duyuyor", + "store": { + "alreadyOwnText": "${NAME} zaten sende var!", + "bombSquadProDescriptionText": "• 2 kat başarı ödülü bileti\n• Oyun-içi reklamlar kalkar\n• ${COUNT} bonus bilet içerir\n• +%${PERCENT} lig skoru bonusu\n• '${INF_ONSLAUGHT}' kilidi ve \n '${INF_RUNAROUND}' kilidi açılır\n ", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "•Oyun-içi reklam ve rahatsız edici ekranlar kalkar\n•Daha fazla oyun ayarları açılır\n•Ayrıca şunları içerir:", + "buyText": "Satın Al", + "charactersText": "Karakterler", + "comingSoonText": "Çok Yakında...", + "extrasText": "Ekstralar", + "freeBombSquadProText": "BombSquad şuan bedava fakat orijinal olarak oyunu satın aldığın zaman\nBombSquad Pro yükseltmesi ve bir teşekkür olarak ${COUNT} bilet alırsın.\nYeni özelliklerin keyfini çıkar, ve desteğin için teşekkürler!\n-Eric", + "holidaySpecialText": "Bayram Özel", + "howToSwitchCharactersText": "(karakter atamak ve özelleştirmek için, git: \"${SETTINGS} -> ${PLAYER_PROFILES}\")", + "howToUseIconsText": "(bunu kullanmak için global profil yarat(hesaplar penceresinde))", + "howToUseMapsText": "(bu haritayı takımlar/herkes-tek çalmalistelerinde kullan)", + "iconsText": "Simgeler", + "loadErrorText": "Sayfa yüklenemiyor.\nİnternet bağlantınızı kontrol edin.", + "loadingText": "yükleniyor", + "mapsText": "Haritalar", + "miniGamesText": "MiniOyunlar", + "oneTimeOnlyText": "(tek seferlik)", + "purchaseAlreadyInProgressText": "Bu ögeyi satın alım zaten işlemde.", + "purchaseConfirmText": "${ITEM} Satın Al?", + "purchaseNotValidError": "Satın Alma geçersiz.\nBu bir hata ise ${EMAIL} ile iletişime geç.", + "purchaseText": "Satın Al", + "saleBundleText": "Yığınla İndirim!", + "saleExclaimText": "İndirim!", + "salePercentText": "(%${PERCENT} ucuz)", + "saleText": "İNDİRİM", + "searchText": "Arama", + "teamsFreeForAllGamesText": "Takımlar / Herkes-Tek Oyunları", + "totalWorthText": "*** ${TOTAL_WORTH} değerinde! ***", + "upgradeQuestionText": "Yükselt?", + "winterSpecialText": "Kışa Özel", + "youOwnThisText": "- buna sahipsin -" + }, + "storeDescriptionText": "8 Kişilik Parti Oyunu Çılgınlığı!\n\nArkadaşlarını (ya da bilgisayarı) turnuva içindeki mini-oyunlar olan (Bayrak-Kapmaca, Bombacı-Hokeyi ve Epik-AğırÇekim-Ölüm-Müsabakası) ile çılgına döndür!\n\n8 kişiye kadar basit ve yaygın olan kontrolcüler dekteklenir. Ayrıca bedava 'BombSquad Remote' uygulaması ile de mobil cihazlarını kontrolcü olarak kullanabilirsin!\n\nBombayı Patlat!\n\nDaha fazla bilgi için; www.froemling.net/bombsquad", + "storeDescriptions": { + "blowUpYourFriendsText": "Arkadaşlarını tahrip et.", + "competeInMiniGamesText": "mini-oyunlar'ı yarış'tan uçma'ya kadar tamamla.", + "customize2Text": "Özel karakterler, mini-oyunlar ve tabiki müzik.", + "customizeText": "Karakterini özelleştir ve kendi mini-oyun çalmaListeni yarat.", + "sportsMoreFunText": "Sporlar patlayıcılar ile daha eğlencelidir.", + "teamUpAgainstComputerText": "Bilgisayara karşı takım ol." + }, + "storeText": "Mağaza", + "submitText": "Gönder", + "submittingPromoCodeText": "Kod Gönderiliyor...", + "teamNamesColorText": "Takım isimleri/Renkler...", + "telnetAccessGrantedText": "Telnet Erişimi aktif.", + "telnetAccessText": "Telnet erişimi algılandı; izin ver?", + "testBuildErrorText": "Bu test yapısı uzun süredir aktif değil;yeni sürümü kontrol edin.", + "testBuildText": "Test Yapısı", + "testBuildValidateErrorText": "Test yapısı onaylanamıyor. (ağ bağlantısı yok?)", + "testBuildValidatedText": "Test Yapısı Onaylandı; Keyfinı Çıkar!", + "thankYouText": "Desteğin için teşekkürler! Oyunun tadını çıkar!!", + "threeKillText": "ÜÇLÜ ÖLÜM!!", + "timeBonusText": "Süre Bonusu", + "timeElapsedText": "Geçen Süre", + "timeExpiredText": "Süre Doldu", + "timeSuffixDaysText": "${COUNT}g", + "timeSuffixHoursText": "${COUNT}s", + "timeSuffixMinutesText": "${COUNT}d", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "İpucu", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "En İyi Arkadaşlar", + "tournamentCheckingStateText": "Turnuva durumu denetleniyor; lütfen bekleyin...", + "tournamentEndedText": "Bu turnuva sonlandı. Yeni bir tanesi yakında başlayacak.", + "tournamentEntryText": "Turnuva Katılımı", + "tournamentResultsRecentText": "Son Turnıva Sonuçları", + "tournamentStandingsText": "Turnuva Kazananları", + "tournamentText": "Turnuva", + "tournamentTimeExpiredText": "Turnuva Sona Erdi", + "tournamentsDisabledWorkspaceText": "Çalışma alanları aktif olduğunda turnuvalar devre dışı bırakılır.\nTurnuvaları yeniden etkinleştirmek için çalışma alanınızı devre dışı bırakın ve yeniden başlatın.", + "tournamentsText": "Turnuvalar", + "translations": { + "characterNames": { + "Agent Johnson": "Ajan Johnson", + "B-9000": "B-9000", + "Bernard": "Bay Pofuduk", + "Bones": "Kemik Torbası", + "Butch": "Butch", + "Easter Bunny": "Paskalya Tavşanı", + "Flopsy": "Tavşik", + "Frosty": "Donak", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Şaşkın-Adam", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Noel Baba", + "Snake Shadow": "Sinsi Gölge", + "Spaz": "Spaz", + "Taobao Mascot": "Toabao Mascot", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} Alıştırması", + "Infinite ${GAME}": "Sonsuz ${GAME}", + "Infinite Onslaught": "Sonsuz Saldırı", + "Infinite Runaround": "Sonsuz Dolambaç", + "Onslaught Training": "Saldırı Alıştırması", + "Pro ${GAME}": "Pro ${GAME}", + "Pro Football": "Pro Futbol", + "Pro Onslaught": "Pro Saldırı", + "Pro Runaround": "Pro Dolambaç", + "Rookie ${GAME}": "Acemi ${GAME}", + "Rookie Football": "Acemi Futbol", + "Rookie Onslaught": "Acemi Saldırı", + "The Last Stand": "Son Çırpınış", + "Uber ${GAME}": "Üst Düzey ${GAME}", + "Uber Football": "Üst Düzey Futbol", + "Uber Onslaught": "Üst Düzey Saldırı", + "Uber Runaround": "Üst Düzey Dolambaç" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Kazanmak için uzun süre seçilmiş kişi ol.\nseçilmiş kişi olmak için seçilmiş kişiyi öldür.", + "Bomb as many targets as you can.": "Yapabildiğin kadar hedefi bombala.", + "Carry the flag for ${ARG1} seconds.": "Bayrağı ${ARG1} saniye taşı.", + "Carry the flag for a set length of time.": "Bayrağı en uzun süre taşı.", + "Crush ${ARG1} of your enemies.": "${ARG1} düşmanı ezip geç.", + "Defeat all enemies.": "Tüm düşmanları Mağlup Et.", + "Dodge the falling bombs.": "Düşen bombalardan kaç.", + "Final glorious epic slow motion battle to the death.": "Ölümüne son büyük epik ağır çekim savaşı.", + "Gather eggs!": "Yumurtaları Topla!", + "Get the flag to the enemy end zone.": "Bölgeden ve düşmandan bayrağı al.", + "How fast can you defeat the ninjas?": "Ninjaları ne kadar hızlı mağlup edebilirsin?", + "Kill a set number of enemies to win.": "Kazanmak için öldürülecek düşman sayısını ayarla.", + "Last one standing wins.": "Son kalan kazanır.", + "Last remaining alive wins.": "En son hayatta kalan kazanır.", + "Last team standing wins.": "Sona kalan takım kazanır.", + "Prevent enemies from reaching the exit.": "Düşmanların çıkışa ulaşmalarına engel ol.", + "Reach the enemy flag to score.": "Skor için düşman bayrağına ulaş.", + "Return the enemy flag to score.": "Skor için düşman bayrağını getir.", + "Run ${ARG1} laps.": "${ARG1} tur koş.", + "Run ${ARG1} laps. Your entire team has to finish.": "${ARG1} tur koş. Tüm takım için geçerli.", + "Run 1 lap.": "1 Tur koş.", + "Run 1 lap. Your entire team has to finish.": "1 Tur koş. Tüm takım için geçerli.", + "Run real fast!": "Cidden hızlı koş!", + "Score ${ARG1} goals.": "${ARG1} Gol At.", + "Score ${ARG1} touchdowns.": "${ARG1} Sayı Yap.", + "Score a goal.": "Gol at.", + "Score a touchdown.": "Bir sayı yap.", + "Score some goals.": "Birkaç gol at.", + "Secure all ${ARG1} flags.": "${ARG1} bayrağın tümünü ele geçir.", + "Secure all flags on the map to win.": "Kazanmak için haritadaki tüm bayrakları ele geçir.", + "Secure the flag for ${ARG1} seconds.": "Bayrağı ${ARG1} saniye ele geçir.", + "Secure the flag for a set length of time.": "Bayrağı ayarlanmış süre boyunca ele geçir.", + "Steal the enemy flag ${ARG1} times.": "Düşman bayrağını ${ARG1} kere çal.", + "Steal the enemy flag.": "Düşman bayrağını çal.", + "There can be only one.": "Sadece biri kalabilir.", + "Touch the enemy flag ${ARG1} times.": "Düşman bayrağına ${ARG1} kere dokun.", + "Touch the enemy flag.": "Düşman bayrağına dokun.", + "carry the flag for ${ARG1} seconds": "bayrağı ${ARG1} saniye taşı", + "kill ${ARG1} enemies": "${ARG1} düşman öldür", + "last one standing wins": "sona kalan kazanır", + "last team standing wins": "sona kalan takım kazanır", + "return ${ARG1} flags": "${ARG1} bayrak getir", + "return 1 flag": "1 bayrak getir", + "run ${ARG1} laps": "${ARG1} tur koş", + "run 1 lap": "1 tur koş", + "score ${ARG1} goals": "${ARG1} gol at", + "score ${ARG1} touchdowns": "${ARG1} sayı yap", + "score a goal": "gol at", + "score a touchdown": "bir sayı yap", + "secure all ${ARG1} flags": "${ARG1} bayrağın tümünü ele geçir", + "secure the flag for ${ARG1} seconds": "Bayrağı ${ARG1} saniye ele geçir", + "touch ${ARG1} flags": "${ARG1} bayrağa dokun", + "touch 1 flag": "1 bayrağa dokun" + }, + "gameNames": { + "Assault": "Hücum", + "Capture the Flag": "Bayrak Kapmaca", + "Chosen One": "Seçilmiş Kişi", + "Conquest": "İşgal", + "Death Match": "Ölüm Müsabakası", + "Easter Egg Hunt": "Paskalya Yumurtası Avı", + "Elimination": "Eleme", + "Football": "Futbol", + "Hockey": "Hokey", + "Keep Away": "Uzak Dur", + "King of the Hill": "Tepelerin Hakimi", + "Meteor Shower": "Meteor Yağmuru", + "Ninja Fight": "Ninja Kavgası", + "Onslaught": "Saldırı", + "Race": "Yarış", + "Runaround": "Dolambaç", + "Target Practice": "Hedef Alıştırması", + "The Last Stand": "Son Çırpınış" + }, + "inputDeviceNames": { + "Keyboard": "Klavye", + "Keyboard P2": "P2 Klavye" + }, + "languages": { + "Arabic": "Arapça", + "Belarussian": "Beyazrusça", + "Chinese": "Basitleştirilmiş Çince", + "ChineseTraditional": "Geleneksel Çince", + "Croatian": "Hırvatça", + "Czech": "Çekçe", + "Danish": "Danimarkaca", + "Dutch": "Flemenkçe", + "English": "İngilizce", + "Esperanto": "Esperanto", + "Filipino": "Filipince", + "Finnish": "Fince", + "French": "Fransızca", + "German": "Almanca", + "Gibberish": "Abuk Sabukça", + "Greek": "Yunanca", + "Hindi": "Hintçe", + "Hungarian": "Macarca", + "Indonesian": "Endonezyaca", + "Italian": "İtalyanca", + "Japanese": "Japonca", + "Korean": "Korece", + "Malay": "Malayca", + "Persian": "Farsça", + "Polish": "Polonya Dili", + "Portuguese": "Portekizce", + "Romanian": "Romence", + "Russian": "Rusça", + "Serbian": "Sırpça", + "Slovak": "Slovakça", + "Spanish": "İspanyolca", + "Swedish": "İsveççe", + "Tamil": "Tamilce", + "Thai": "Tayland dili", + "Turkish": "Türkçe", + "Ukrainian": "Ukrayna", + "Venetian": "Venedik", + "Vietnamese": "Vietnamca" + }, + "leagueNames": { + "Bronze": "Bronz", + "Diamond": "Elmas", + "Gold": "Altın", + "Silver": "Gümüş" + }, + "mapsNames": { + "Big G": "Büyük G", + "Bridgit": "Köprü", + "Courtyard": "Avlu", + "Crag Castle": "Uçurum Kalesi", + "Doom Shroom": "Lanetli Mantar", + "Football Stadium": "Futbol Stadyumu", + "Happy Thoughts": "Düşler Vadisi", + "Hockey Stadium": "Hokey Stadyumu", + "Lake Frigid": "Donmuş Göl", + "Monkey Face": "Maymun Surat", + "Rampage": "Katliam", + "Roundabout": "Dönemeç", + "Step Right Up": "Uzaktan Bakma Yakına Gel", + "The Pad": "Kutu", + "Tip Top": "Zıp Zıp", + "Tower D": "Kule D", + "Zigzag": "Zikzak" + }, + "playlistNames": { + "Just Epic": "Sadece Epik", + "Just Sports": "Sadece Sporlar" + }, + "scoreNames": { + "Flags": "Bayraklar", + "Goals": "Goller", + "Score": "Skor", + "Survived": "Hayatta Kalındı", + "Time": "Süre", + "Time Held": "Tutulmuş Süre" + }, + "serverResponses": { + "A code has already been used on this account.": "Kod bu hesapta zaten kullanılmış.", + "A reward has already been given for that address.": "Ödül bu adres için zaten verilmiş.", + "Account linking successful!": "Hesap bağlama başarılı!", + "Account unlinking successful!": "Hesap bağlantısı başarıyla kesildi!", + "Accounts are already linked.": "Hesaplar zaten bağlı.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Reklam görünümü doğrulanamadı.\nLütfen oyunun resmi ve güncel bir sürümünü çalıştırdığınızdan emin olun.", + "An error has occurred; (${ERROR})": "Bir hata oluştu; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Bir hata oluştu; Lütfen destek ile iletişime geçin. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Bir hata meydana geldi; lütfen support@froemling.net ile iletişime geçin.", + "An error has occurred; please try again later.": "Bir hata meydana geldi; Lütfen sonra tekrar deneyin.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Bu hesapları bağlamak istediğine emin misin?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nBu işlem geri alınamaz!", + "BombSquad Pro unlocked!": "BombSquad Pro Kilidi Açıldı!", + "Can't link 2 accounts of this type.": "Bu tipte 2 hesap bağlanamaz.", + "Can't link 2 diamond league accounts.": "2 elmas ligi hesabı birleştirilemez.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Bağlanamıyor; maksimum ${COUNT} bağlı hesap sınırına ulaşıldı.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Hile algılandı; skorlar ve ödüller ${COUNT} gün için askıya alındı.", + "Could not establish a secure connection.": "Güvenli bir bağlantı sağlanamadı.", + "Daily maximum reached.": "Günlük sınıra ulaşıldı.", + "Entering tournament...": "Turnuvaya giriliyor...", + "Invalid code.": "Geçersiz kod.", + "Invalid payment; purchase canceled.": "Geçersiz ödeme; satın alma iptal edildi.", + "Invalid promo code.": "Geçersiz promo kodu.", + "Invalid purchase.": "Geçersiz satın alma.", + "Invalid tournament entry; score will be ignored.": "Geçersiz turnuva girişi; skor yok sayılacak.", + "Item unlocked!": "Öğe kilidi açıldı!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "EŞLEŞTİRME ENGELLENDİ ${ACCOUNT}\nhesabının önemli verilerinin tümü kayıp olacak!\nKarşı taraftan eşleştirme yapabilirsiniz\n(Ve verileriniz kayıp olmaz)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "${ACCOUNT} hesabı bu hesaba bağlansın mı?\n${ACCOUNT} hesabı üzerindeki tüm mevcut veriler kaybolacak.\nBu işlem geri alınamaz. Emin misiniz?", + "Max number of playlists reached.": "Maksimum çalmaListesine ulaşıldı.", + "Max number of profiles reached.": "Profiller için maksimum sayıya ulaşıldı.", + "Maximum friend code rewards reached.": "Arkadaş kodu maksimuma ulaştı.", + "Message is too long.": "Mesaj çok uzun.", + "No servers are available. Please try again soon.": "Kullanılabilir sunucu yok. Lütfen kısa süre sonra tekrar deneyin.", + "Profile \"${NAME}\" upgraded successfully.": "\"${NAME}\" Profili başarı ile yükseltildi.", + "Profile could not be upgraded.": "Profil yükseltilemedi.", + "Purchase successful!": "Satın Alma Başarılı!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "${COUNT} Bilet giriş yapıldığı için alındı.\nYarın geri gel ve ${TOMORROW_COUNT} bilet al.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Oyunun bu sürümünde sunucu işlevleri artık desteklenmiyor;\nLütfen daha yeni bir sürüme güncelleyin.", + "Sorry, there are no uses remaining on this code.": "Üzgünüz, bu kodun kullanım bakiyesi doldu.", + "Sorry, this code has already been used.": "Üzgünüz, bu kod zaten kullanılmış.", + "Sorry, this code has expired.": "Üzgünüz, Bu kodun süresi doldu.", + "Sorry, this code only works for new accounts.": "Üzgünüz, bu kod yalnızca yeni hesaplar için çalışır.", + "Still searching for nearby servers; please try again soon.": "Hala yakındaki sunucuları arıyor; lütfen kısa süre sonra tekrar deneyin.", + "Temporarily unavailable; please try again later.": "Geçici olarak kullanım dışı; lütfen daha sonra tekrar deneyiniz.", + "The tournament ended before you finished.": "Sen bitiremeden turnuva sona erdi.", + "This account cannot be unlinked for ${NUM} days.": "Bu hesap, ${NUM} gün boyunca kaldırılamaz.", + "This code cannot be used on the account that created it.": "Bu kod onun yaptığı hesapta kullanılamaz.", + "This is currently unavailable; please try again later.": "Bu şu anda kullanılamıyor; lütfen daha sonra tekrar deneyin.", + "This requires version ${VERSION} or newer.": "Bu ${VERSION} veya daha üst sürümüne ihtiyaç duyuyor.", + "Tournaments disabled due to rooted device.": "Rootlu cihaz nedeniyle turnuvalar devre dışı", + "Tournaments require ${VERSION} or newer": "Turnuvalar ${VERSION} veya daha yeni bir sürümü gerektirir", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "${ACCOUNT} hesabının bağlantısını kaldırmak mı istiyorsunuz?\n${ACCOUNT} hesabı üzerindeki tüm veriler sıfırlanacak.\n(bazı durumlarda başarılar hariç)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "UYARI: Hesabınız hile kullanımı nedeniyle şikayet edilmiştir.\nHile kullanıldığı tespit edilen hesaplar yasaklanacaktır. Lütfen adil oyna.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Cihaz hesabınızı bununla bağlamak istermisiniz?\n\nCihaz hesabınız: ${ACCOUNT1}\nBu hesap: ${ACCOUNT2}\n\nUlaştığın ilerlemeler saklanacak.\nUyarı: Bu işlem geri alınamaz!", + "You already own this!": "Buna zaten sahipsin!", + "You can join in ${COUNT} seconds.": "\"${COUNT}\" saniye içinde katılabilirsin.", + "You don't have enough tickets for this!": "Bunun için yeterince biletiniz yok!", + "You don't own that.": "Buna sahip değilsin.", + "You got ${COUNT} tickets!": "${COUNT} Bilet kazandınız!", + "You got a ${ITEM}!": "Bir ${ITEM} kazandınız!", + "You have been promoted to a new league; congratulations!": "Yeni bir lige terfi ettin; tebrikler!", + "You must update to a newer version of the app to do this.": "Bunu yapmak için uygulamayı yeni bir sürüme güncellemelisin.", + "You must update to the newest version of the game to do this.": "Bunu yapmak için oyunun en yeni sürümüne güncellemelisiniz.", + "You must wait a few seconds before entering a new code.": "Yeni bir kod girmeden önce biraz beklemelisin.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Son turnuvada #${RANK}. oldun. Oynadığın için teşekkürler!", + "Your account was rejected. Are you signed in?": "Hesabın reddedildi. Oturum açtın mı?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Oyununun kopyası modifiye edilmiş.\nLütfen eski haline döndürüp tekrar deneyin.", + "Your friend code was used by ${ACCOUNT}": "Arkadaş kodun ${ACCOUNT} tarafından kullanılmış" + }, + "settingNames": { + "1 Minute": "1 Dakika", + "1 Second": "1 Saniye", + "10 Minutes": "10 Dakika", + "2 Minutes": "2 Dakika", + "2 Seconds": "2 Saniye", + "20 Minutes": "20 Dakika", + "4 Seconds": "4 Saniye", + "5 Minutes": "5 Dakika", + "8 Seconds": "8 Saniye", + "Allow Negative Scores": "Negatif Skorlara İzin Ver", + "Balance Total Lives": "Toplam Canları Dengele", + "Bomb Spawning": "Bomba Oluşumu", + "Chosen One Gets Gloves": "Seçilmiş Kişi Eldivenler Alsın", + "Chosen One Gets Shield": "Seçilmiş Kişi Kalkan Alsın", + "Chosen One Time": "Seçilmiş Kişi Süresi", + "Enable Impact Bombs": "Bombalara Çarpmayı Etkinleştir", + "Enable Triple Bombs": "Üçlü Bombaları Etkinleştir", + "Entire Team Must Finish": "Tüm Takım Bitirmeli", + "Epic Mode": "Epik Mod", + "Flag Idle Return Time": "Boştaki Bayrağın Geri Dönme Süresi", + "Flag Touch Return Time": "Dokunulan Bayrağın Geri Dönme Süresi", + "Hold Time": "Tutma Süresi", + "Kills to Win Per Player": "Kazanmak için Öldürülecek Oyuncu", + "Laps": "Turlar", + "Lives Per Player": "Her Oyuncunun Canı", + "Long": "Uzun", + "Longer": "Daha Uzun", + "Mine Spawning": "Mayın Oluşumu", + "No Mines": "Mayın Yok", + "None": "Hiçbiri", + "Normal": "Normal", + "Pro Mode": "Pro Mod", + "Respawn Times": "Yeniden Doğma Süresi", + "Score to Win": "Kazanmak için gereken Skor", + "Short": "Kısa", + "Shorter": "Daha Kısa", + "Solo Mode": "Tek Kişilik Mod", + "Target Count": "Hedef Miktarı", + "Time Limit": "Süre Sınırı" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "\"${PLAYER}\" ayrıldığından \"${TEAM}\" diskalifiye oldu.", + "Killing ${NAME} for skipping part of the track!": "${NAME} oyuncusu yoldan saptığı için öldürüldü!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "${NAME}: için uyarı: Hızlı/gereksiz buton tıklaması seni mahveder." + }, + "teamNames": { + "Bad Guys": "Haylazlar", + "Blue": "Mavi", + "Good Guys": "Kankalar", + "Red": "Kırmızı" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "koşmak-zıplamak-dönmek-vurmak Mükemmel zamanlama ile tek vuruşta öldürür\nve arkadaşlarının hayat boyu sana saygı duymasını sağlar.", + "Always remember to floss.": "Diş iplerini yanına almayı hiçbir zaman unutma.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Rastgele bir tane yerine, tercih ettiğiniz ve\ngörülmesini istediğiniz ad için oyuncu profili yaratın.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Lanet kutuları seni saatli bombaya dönüştürür.\nTek kurtuluş yolu Sağlık-Paketi almaktır.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Görünüşlerinin yanı sıra, tüm karakterlerin yetenekleri aynıdır.\nYani sana en çok benzeyen bir tanesini seç.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Enerji-Kalkanı ileyken kendinden çok emin olma; kendini uçurumdan düşürebilirsin.", + "Don't run all the time. Really. You will fall off cliffs.": "Her zaman koşma. Cidden. Uçurumlardan düşebilirsin.", + "Don't spin for too long; you'll become dizzy and fall.": "Çok uzun süre boyunca dönme; sersemleyip düşersin.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Koşmak için bir tuşa basılı tut. (Eğer varsa tetik butonları da çalışır)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Koşmak için herhangi bir tuşa basılı tut. Hızlıca yerdeğiştirmeni\nsağlar fakat dönmeni zorlaştırır, yani uçurumlara dikkat et.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Buz-Bombaları çok güçlü değildir fakat değdiği şeyi\ndondurur ve kırılmalarını kolaylaştırır.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Birisi seni kaldırırsa, yumrukla ki seni salıversin.\nBu gerçek hayatta da işe yarar.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Eğer kontrolcü için aceleciysen; '${REMOTE_APP_NAME}'\nuygulamasını yükle ve mobil cihazını kontrolcü olarak kullan.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Eğer yapışkan-bomba sana yapıştıysa, etrafta zıpla ve daireler çizerek dön\nbombayı üzerinden atabilirsin. Ya da hiçbir şey yapma, son anların eğlenceli geçsin.", + "If you kill an enemy in one hit you get double points for it.": "Eğer düşmanını tek vuruşta öldürürsen, bunun için çifte puan alırsın.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Eğer Lanetlenirsen, Uğruna savaşılacak tek umudun;\nilerleyen saniyelerde bir sağlık-paketi bulmak olur.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Bir yerde durursan, kızarmış ekmek olursun. Hayatta kalmak için koş ve kaç..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Eğer girip çıkan birçok oyuncun varsa; oyundan çıkmayı unutma ihtimallerine karşı\nayarlardaki 'Boştaki-oyuncuları-çıkar'ı aktifleştir.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Eğer cihazın çok ısındıysa veya güç tasarrufu yapmak istiyorsan\nAyarlar->Grafikler den \"Görseller\" veya \"Çözünürlük\" ayarlarını düşür.", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Eğer FPS dengesiz ise; Oyunun grafik ayarlarından görseller\nveya çözünürlüğü düşürmeyi dene.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Bayrak-Yakalamaca'da skor yapmak için kendi bayrağın kendi bölgende olmalı. Eğer diğer\ntakım skor yapmak üzereyse; bayraklarını çalmak, onları durdurmak için güzel bir yoldur.", + "In hockey, you'll maintain more speed if you turn gradually.": "Hokey de, yavaşça dönersen topu daha hızlı sürebilirsin.", + "It's easier to win with a friend or two helping.": "Bir arkadaşla yardımlaşarak oynamak, kolayca kazanmanı sağlar.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Zıplamak, bombaları daha yüksek seviyelere atmanı sağlar.", + "Land-mines are a good way to stop speedy enemies.": "Kara-mayınları hızlı düşmanları durdurmak için iyidir.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Çoğu şey kaldırılıp atılabilir, diğer oyuncular da dahil. Düşmanlarını\nuçurumdan fırlatmak, etkili ve seni tatmin edecek bir yöntemdir.", + "No, you can't get up on the ledge. You have to throw bombs.": "Hayır, tümseğe çıkamazsın. Atabileceğin bombaların var.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Oyuncular çoğu oyunun ortasında girip çıkabilir. Ayrıca\nhızlıca kontrolcü bağlayıp da çıkarabilirsin.", + "Practice using your momentum to throw bombs more accurately.": "İvmeni kullanma alıştırması yapman, bombaları daha isabetli atmanı sağlar", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Hızlı hareket edersen yumrukların daha fazla hasar verir\nyani deli gibi koşmayı, zıplamayı ve dönmeyi dene.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Daha uzağa atmak için bomba atmadan önce kırbaç gibi\ngeri-ileri hareket et.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Grupça düşman imha etmek için\nbombayı TNT kutusunun yanına at.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Kafa en zayıf bölgedir, bu yüzden yapışkan-bombayı\nkafaya atman oyun-bitirici bir hamledir.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Bu bölüm hiç bitmez. Fakat yaptığın yüksek-skorlar\ndünyanın sonuna kadar mevcut kalır.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Fırlatma kuvveti senin yöneliminle alakalıdır.\nBir şeyleri nazikçe önüne bırakmak için herhangi bir yöne gitmeden bırak.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Müziklerden sıkıldın mı? Kendininkiyle değiştir!\nAyarlar->Müzikler'e bak", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Bombaları, patlamasına bir ya da iki saniye kala fırlat.", + "Try tricking enemies into killing eachother or running off cliffs.": "Düşmanlarının kandırarak birbirlerini öldürmesini ve uçurumdan fırlatmasını sağla.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Bayrak tutmak için Kaldır butonunu kullan <${PICKUP}>", + "Whip back and forth to get more distance on your throws..": "Geri-ileri gitmek daha uzağa fırlatmanı sağlar.", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Yumruklarınla sağa veya sola dönerken hedef alabilirsin.\nBu haylazları köşelere fırlatmak ve hokeyde skor yapmak için birebirdir.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Bombanın patlama zamanını Fitil kıvılcımlarının rengine bakarak\ntahmin edebilirsin: sarı..turuncu..kırmızı..BOOM.", + "You can throw bombs higher if you jump just before throwing.": "Bombaları atmadan önce zıplarsan, daha yükseğe fırlatabilirsin.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Kafanı bir şeylere çarparsan hasar alırsın\nkafanı bir şeylere çarpmamaya özen göster.", + "Your punches do much more damage if you are running or spinning.": "Dönüyor ve koşuyorsan, yumrukların daha fazla hasar verir." + } + }, + "trophiesRequiredText": "Bunun için en az ${NUMBER} kupa gerekiyor.", + "trophiesText": "Kupa", + "trophiesThisSeasonText": "Bu Sezonki Kupalar", + "tutorial": { + "cpuBenchmarkText": "Öğretici aptalca çalışıyor (öncellikle CPU hızını test et)", + "phrase01Text": "Merhaba !", + "phrase02Text": "${APP_NAME}'a Hoş Geldiniz!", + "phrase03Text": "Karakterini kontrol etmek için birkaç ipucu:", + "phrase04Text": "${APP_NAME}'da çoğu şey FİZİK temellidir.", + "phrase05Text": "Örnek; yumruk attığında...", + "phrase06Text": "...hasar yumruklarının hızına bağlıdır.", + "phrase07Text": "Gördün mü? Hareket etmediğinden ${NAME} zar zor incildi.", + "phrase08Text": "Şimdi daha fazla hızlanmak için zıpla ve Dön.", + "phrase09Text": "Ah, bu daha iyi.", + "phrase10Text": "Koşmak da yardımcı olur.", + "phrase11Text": "Koşmak için herhangi bir butona basılı tut.", + "phrase12Text": "Ekstra-Müthiş yumruklar için koşmayı ve dönmeyi dene.", + "phrase13Text": "Ayy! bunun için üzgünüm ${NAME}.", + "phrase14Text": "Bir şeyleri kaldırıp fırlatabilirsin. Bayraklar gibi.. ya da ${NAME}.", + "phrase15Text": "Son olarak, bombalar var.", + "phrase16Text": "Bombaları fırlatmak, tecrübe işidir.", + "phrase17Text": "Ayy! İyi bir fırlatış değil.", + "phrase18Text": "Koşmak, ileriye fırlatmak için sana yardımcı olur.", + "phrase19Text": "Zıplamak, yükseğe fırlatmak için sana yardımcı olur.", + "phrase20Text": "Bombaları daha uzağa fırlatmak için kamçı vurur gibi at.", + "phrase21Text": "Bombalarını akıllıca zamanlayabilirsin.", + "phrase22Text": "Lanet olsun.", + "phrase23Text": "Fitil bitimine bir ya da iki saniye kala atmayı dene.", + "phrase24Text": "Oley! Güzelce pişmiş.", + "phrase25Text": "Evet, işte tam da böyle.", + "phrase26Text": "Şimdi kaplan gibi olma zamanı!", + "phrase27Text": "Eğitimini hatırla ve buraya canlı DÖN!", + "phrase28Text": "...evet, olabilir...", + "phrase29Text": "İyi şanslar!", + "randomName1Text": "Fred", + "randomName2Text": "Chuck", + "randomName3Text": "Bill", + "randomName4Text": "Myth B.", + "randomName5Text": "Carl", + "skipConfirmText": "Öğreticiyi gerçekten atlamak istiyor musun? Onaylamak için dokun.", + "skipVoteCountText": "geçme oylaması ${COUNT}/${TOTAL}", + "skippingText": "Öğretici Atlanıyor...", + "toSkipPressAnythingText": "(öğreticiyi atlamak için herhangi bir tuşa bas)" + }, + "twoKillText": "ÇİFTE ÖLÜM!", + "unavailableText": "mevcut değil", + "unconfiguredControllerDetectedText": "Yapılandırılmamış kontrolcü tespit edildi:", + "unlockThisInTheStoreText": "Bunun mağazada kilidi açık olmalı.", + "unlockThisProfilesText": "${NUM} taneden daha fazla profil yaratmak için ihtiyacın olan:", + "unlockThisText": "Bu kilidi açmak için ihtiyacın olan:", + "unsupportedHardwareText": "Üzgünüz, bu donanım oyunun bu sürümü tarafından desteklenmiyor.", + "upFirstText": "İlki:", + "upNextText": "Sıradaki oyun ${COUNT}:", + "updatingAccountText": "Hesabınız güncelleniyor...", + "upgradeText": "Yükselt", + "upgradeToPlayText": "Bunu oynamak için \"${PRO}\" kilidini oyun-içi mağazadan aç.", + "useDefaultText": "Varsayılanı Kullan", + "usesExternalControllerText": "Bu oyun girdi olarak harici kontrolcü kullanıyor.", + "usingItunesText": "Müzikler için iTunes kullanılıyor...", + "usingItunesTurnRepeatAndShuffleOnText": "Lütfen iTunes da karıştırmanın KAPALI oldugundan ve Yinelemenin TÜM oldugundan emin olun. ", + "v2AccountLinkingInfoText": "V2 hesapları bağlamak için, 'Hesabı yönet' butonuna tıklayın.", + "validatingTestBuildText": "Test Yapısı Onaylanıyor...", + "victoryText": "Galibiyet!", + "voteDelayText": "${NUMBER} saniye boyunca başka oylama başlatamazsın.", + "voteInProgressText": "Oylama zaten işlemde.", + "votedAlreadyText": "Zaten oyladın", + "votesNeededText": "${NUMBER} oy gerekli", + "vsText": "vs.", + "waitingForHostText": "(devam etmesi için ${HOST} bekleniyor)", + "waitingForPlayersText": "Oyuncuların katılması bekleniyor...", + "waitingInLineText": "Sırada bekleniyor (parti dolu)...", + "watchAVideoText": "Bir Video İzle", + "watchAnAdText": "Reklam İzle", + "watchWindow": { + "deleteConfirmText": "Sil \"${REPLAY}\"?", + "deleteReplayButtonText": "Tekrar\nSil", + "myReplaysText": "Tekrarlarım", + "noReplaySelectedErrorText": "Tekrar Seçilmedi", + "playbackSpeedText": "Oynatma hızı: ${SPEED}", + "renameReplayButtonText": "Tekrar\nYeniden Adlandır", + "renameReplayText": "\"${REPLAY}\" Yeniden Adlandır:", + "renameText": "Yeniden Adlandır", + "replayDeleteErrorText": "Tekrar Silinirken Hata", + "replayNameText": "Tekrar Adı", + "replayRenameErrorAlreadyExistsText": "Bu isimde bir tekrar zaten mevcut.", + "replayRenameErrorInvalidName": "Tekrar yeniden adlandırılamıyor; geçersiz ad.", + "replayRenameErrorText": "Tekrar Yeniden Adlandırılırken Hata", + "sharedReplaysText": "Paylaşılmış Tekrarlar", + "titleText": "İzle", + "watchReplayButtonText": "Tekrar\nİzle" + }, + "waveText": "Dalga", + "wellSureText": "Elbette!", + "whatIsThisText": "Bu da ne?", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Telif Hakkı" + }, + "wiimoteListenWindow": { + "listeningText": "Wiimote dinleniyor...", + "pressText": "Lütfen Wiimote 1 ve 2 butonlarına aynı anda basın.", + "pressText2": "Motion Plus içerisinde hiç Wiimote yok, geri yerine kırmızı 'senkron' butonuna basın." + }, + "wiimoteSetupWindow": { + "copyrightText": "DarwiinRemote TelifHakkı", + "listenText": "Dinle", + "macInstructionsText": "Wii nin kapalı olduğundan ve 'Dinle'ye bastığında\nMac'inde Bluetooth'un açık olduğundan emin ol.Wii\ndesteği biraz tuhaftır bu yüzden bağlanmadan önce\nbirkaç kere denemelisin.\n\nBluetooth çeşitli uzaklıklardan 7 cihaza\nkadar destek verir.\n\nBombSquad Orijinal Wiimoteleri Nunchukslari ve\nKlasik Kontrolcüleri destekler.\nYeni Wii Remote Plus'da şuanda çalışıyor\nfakat eklenmiş değil.", + "thanksText": "DarwiinRemote takımına bunu mümkün\nkıldığı için teşekkürler.", + "titleText": "Wiimote Kurulumu" + }, + "winsPlayerText": "${NAME} Kazandı!", + "winsTeamText": "${NAME} Kazandı!", + "winsText": "${NAME} Kazandı!", + "workspaceSyncErrorText": "${WORKSPACE} eşitlemesinde hata oluştu. Detaylar için günlüğü inceleyin.", + "workspaceSyncReuseText": "${WORKSPACE} eşitlenemiyor. Önceden eşitlenmiş sürüm kullanılıyor.", + "worldScoresUnavailableText": "Global Skorlar Mevcut Değil.", + "worldsBestScoresText": "Global En İyi Skorlar", + "worldsBestTimesText": "Global En İyi Süreler", + "xbox360ControllersWindow": { + "getDriverText": "Sürücüyü İndir", + "macInstructions2Text": "Kablosuz olarak kullanmak için; ayrıca 'Xbox 360 Kontroller for Windows'\nile gelen bir alıcı kullanman lazım. \nBir alıcı sana 4 taneye kadar bağlantı sağlar.\n\nÖnemli: 3.şahıs alıcılar bu sürücü ile çalışmaz;\nAlıcının 'Microsoft' için olduğuna dikkat et 'XBOX 360' değil.\nMicrosoft bunu uzun süredir ayrı olarak satmıyor. Kontrolcüleri ile \nbirlikte alabilirsin ya da ebay de araştırabilirsin.\n\nEğer bunu kullanışlı bulduysan, lütfen değerlendirerek sürücü\ngeliştirilmesine bu siteden bağış yap.", + "macInstructionsText": "Xbox 360 kolunu kullanmak için aşağıdaki bağlantıdaki\nMac sürücüsü yüklemen gerekiyor.\nKablolu ve Kablosuz kontroller de çalışır.", + "macInstructionsTextScale": 0.8, + "ouyaInstructionsText": "BombSquad ile kablolu Xbox 360 kontrolcüsü kullanmak için basitçe\ncihazının USB girişine takın. Çoklu kontrolcü kullanmak için USB\nçoklayıcı kullanabilirsiniz.\n\nKablosuz kontrolcü için \"Xbox 360 Wireless Controller for Windows\"\nkablosuz alıcısına ihtiyacınız var. Her alıcıya\nUSB girişi ile bağlanır ve 4 kablosuz kontrolcüye\nkadar desteklenir.", + "titleText": "Xbox 360 Kontrolcüsü ${APP_NAME} ile kullanılıyor:" + }, + "yesAllowText": "Evet, Kabul!", + "yourBestScoresText": "En İyi Skorların", + "yourBestTimesText": "En İyi Sürelerin" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/ukrainian.json b/dist/ba_data/data/languages/ukrainian.json new file mode 100644 index 0000000..371b3df --- /dev/null +++ b/dist/ba_data/data/languages/ukrainian.json @@ -0,0 +1,1889 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Імена акаунтів не можуть містити емоджі або інші особливі символи", + "accountProfileText": "(профіль аккаунта)", + "accountsText": "Акаунти", + "achievementProgressText": "Досягнення: ${COUNT} з ${TOTAL}", + "campaignProgressText": "Прогрес кампанії [Тяжко]: ${PROGRESS}", + "changeOncePerSeason": "Ви можете змінити це лише раз в сезон.", + "changeOncePerSeasonError": "Ви повинні дочекатися наступного сезону, щоб змінити це знову (${NUM} днів)", + "customName": "Ім'я акаунта", + "googlePlayGamesAccountSwitchText": "Якщо ви хочете використовувати інший акаунт Google,\nперейдіть у додаток Google Play Games, щоб змінити його.", + "linkAccountsEnterCodeText": "Ввести Код", + "linkAccountsGenerateCodeText": "Створити Код", + "linkAccountsInfoText": "(поділитися прогресом на різних платформах)", + "linkAccountsInstructionsNewText": "Щоб зв'язати два облікові записи, згенеруйте код на\nпершому і введіть цей код на другому. Дані з другого\nоблікового запису будуть розподілені між ними.\n(Дані з першого облікового запису буде втрачено)\n\nВи можете зв'язати акаунтів: ${COUNT}.\n\nВАЖЛИВО: зв'язуйте тільки власні облікові записи;\nЯкщо ви зв'яжетесь з акаунтами друзів, ви не зможете\nодночасно грати онлайн.", + "linkAccountsInstructionsText": "Щоб зв'язати дви обликови записи, створювати код на одному з них и ввести цей код на инший. Прогрес та инвентаризации будуць об'эднанни. Ви можете зв'язати ${COUNT} рахунки.", + "linkAccountsText": "Зв'язати акаунти", + "linkedAccountsText": "Зв'язані акаунти:", + "manageAccountText": "Керувати аккаунтом", + "nameChangeConfirm": "Ви впевнені що хочете змінити ім'я на ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Це скине весь ваш прогрес кооперативу\nі локальні рекорди (але не ваші квитки).\nЦей процес є незворотнім. Ви впевнені?", + "resetProgressConfirmText": "Це скине весь ваш прогрес кооперативу,\nдосягнення та локальні рекорди (але не\nваші квитки). Цей процес незворотній.\nВи впевнені?", + "resetProgressText": "Скинути прогрес", + "setAccountName": "Задати ім'я акаунта", + "setAccountNameDesc": "Виберіть ім'я для відображення свого акаунту.\nВи можете використовувати ім'я одного з ваших прив'язаних\nакаунтів або створити своє унікальне ім'я.", + "signInInfoText": "Увійдіть, щоб збирати квитки, змагатися онлайн,\nі синхронізувати прогрес між пристроями.", + "signInText": "Увійти", + "signInWithDeviceInfoText": "(для цього пристрою доступний тільки стандартний акаунт)", + "signInWithDeviceText": "Увійти використовуючи акаунт пристрою", + "signInWithGameCircleText": "Увійти через Game Circle", + "signInWithGooglePlayText": "Увійти через Google Play", + "signInWithTestAccountInfoText": "(тест-аккаунт; надалі використовуйте акаунт пристрою)", + "signInWithTestAccountText": "Увійти через тестовий акаунт", + "signInWithV2InfoText": "(обліковий запис, який працює на всіх платформах)", + "signInWithV2Text": "Увійдіть за допомогою облікового запису BombSquad", + "signOutText": "Вийти", + "signingInText": "Вхід…", + "signingOutText": "Вихід…", + "testAccountWarningOculusText": "Увага: ви входите під \"тестовим\" аккаунтом.\nВін буде замінений \"справжнім\" акаунтом пізніше в цьому\nроці, що дозволить здійснювати покупки квитків і багато іншого.\nНа даний момент Вам доведеться заробляти квитки в грі.", + "testAccountWarningText": "Увага: ви увійшли під \"тестовим\" аккаунтом.\nЦей аккаунт зв'язанний з певним девайсом та може\nчас від часу скидатися. (так що не марнуйте час для\nзбирання/розблокування добра для нього)\n\nДля використання \"реального\" аккаунту (Game-Center,\nGoogle Plus та інші) запустіть платну версію гри. Це\nнадасть вам можливість зберігати прогрес у хмарі та\nробити його доступним для різних девайсів.", + "ticketsText": "Квитки: ${COUNT}", + "titleText": "Акаунт пупсель", + "unlinkAccountsInstructionsText": "Виберіть акаунт, який хочете відв'язати", + "unlinkAccountsText": "Відв'язати акаунт", + "unlinkLegacyV1AccountsText": "від’єднати застарілі облікові записи (v1)", + "v2LinkInstructionsText": "Скористайтеся цим посиланням, щоб створити обліковий запис або увійти.", + "viaAccount": "(через акаунт ${NAME})", + "youAreSignedInAsText": "Ви увійшли як:" + }, + "achievementChallengesText": "Досягнення", + "achievementText": "Досягнення", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Вбийте 3 поганих хлопців за допомогою TNT", + "descriptionComplete": "Вбито 3 поганих хлопців за допомогою TNT", + "descriptionFull": "Вбийте 3 поганих хлопців за допомогою TNT на рівні ${LEVEL}", + "descriptionFullComplete": "Вбито 3 поганих хлопців за допомогою TNT на рівні ${LEVEL}", + "name": "Зараз бабахне" + }, + "Boxer": { + "description": "Виграйте без використання бомб", + "descriptionComplete": "Перемога без використання бомб", + "descriptionFull": "Завершіть рівень ${LEVEL} без використання бомб", + "descriptionFullComplete": "Рівень ${LEVEL} завершений без використання бомб", + "name": "Боксер" + }, + "Dual Wielding": { + "descriptionFull": "Підключіть 2 контролери (реальний або додаток)", + "descriptionFullComplete": "Підключено 2 контролери (реальний або додаток)", + "name": "Подвійна зброя" + }, + "Flawless Victory": { + "description": "Виграйте не отримавши ушкоджень", + "descriptionComplete": "Перемога без пошкоджень", + "descriptionFull": "Пройдіть рівень ${LEVEL} не отримавши ушкоджень", + "descriptionFullComplete": "Рівень ${LEVEL} пройдений без ушкоджень", + "name": "Бездоганна перемога" + }, + "Free Loader": { + "descriptionFull": "Почати вільну для всіх гру з 2 і більш гравцями", + "descriptionFullComplete": "Почав вільну для всіх гру з 2 і більш гравцями", + "name": "Вільний завантажувач" + }, + "Gold Miner": { + "description": "Вбийте 6 поганих хлопців за допомогою мін", + "descriptionComplete": "Вбито 6 поганих хлопців за допомогою мін", + "descriptionFull": "Вбийте 6 поганих хлопців за допомогою мін на рівні ${LEVEL}", + "descriptionFullComplete": "Вбито 6 поганих хлопців за допомогою мін на рівні ${LEVEL}", + "name": "Золотий мінер" + }, + "Got the Moves": { + "description": "Виграйте без ударів і бомб", + "descriptionComplete": "Перемога без ударів і бомб", + "descriptionFull": "Виграйте рівень ${LEVEL} без ударів і бомб", + "descriptionFullComplete": "Перемога на рівні ${LEVEL} без ударів і бомб", + "name": "Точні рухи" + }, + "In Control": { + "descriptionFull": "Підключіть контролер (реальний або додаток)", + "descriptionFullComplete": "Підключений контролер. (реальний або додаток)", + "name": "Під контролем" + }, + "Last Stand God": { + "description": "Наберіть 1000 очок", + "descriptionComplete": "Набрано 1000 очок", + "descriptionFull": "Наберіть 1000 очок на рівні ${LEVEL}", + "descriptionFullComplete": "Набрано 1000 очок на рівні ${LEVEL}", + "name": "Бог рівня ${LEVEL}" + }, + "Last Stand Master": { + "description": "Наберіть 250 очок", + "descriptionComplete": "Набрано 250 очок", + "descriptionFull": "Наберіть 250 очок на рівні ${LEVEL}", + "descriptionFullComplete": "Набрано 250 очок на рівні ${LEVEL}", + "name": "Майстер рівня ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Наберіть 500 очок", + "descriptionComplete": "Набрано 500 очок", + "descriptionFull": "Наберіть 500 очок на рівні ${LEVEL}", + "descriptionFullComplete": "Набрано 500 очок на рівні ${LEVEL}", + "name": "Чарівник рівня ${LEVEL}" + }, + "Mine Games": { + "description": "Вбийте 3 поганих хлопців за допомогою мін", + "descriptionComplete": "Вбито 3 поганих хлопців за допомогою мін", + "descriptionFull": "Вбийте 3 поганих хлопців за допомогою мін на рівні ${LEVEL}", + "descriptionFullComplete": "Вбито 3 поганих хлопців за допомогою мін на рівні ${LEVEL}", + "name": "Ігри з мінами" + }, + "Off You Go Then": { + "description": "Скиньте 3 поганих хлопців з карти", + "descriptionComplete": "Скинуто 3 поганих хлопців з карти", + "descriptionFull": "Скиньте 3 поганих хлопців з карти на рівні ${LEVEL}", + "descriptionFullComplete": "Скинуто 3 поганих хлопців з карти на рівні ${LEVEL}", + "name": "Давай звідси" + }, + "Onslaught God": { + "description": "Наберіть 5000 очок", + "descriptionComplete": "Набрано 5000 очок", + "descriptionFull": "Наберіть 5000 очок на рівні ${LEVEL}", + "descriptionFullComplete": "Набрано 5000 очок на рівні ${LEVEL}", + "name": "Бог рівня ${LEVEL}" + }, + "Onslaught Master": { + "description": "Наберіть 500 очок", + "descriptionComplete": "Набрано 500 очок", + "descriptionFull": "Наберіть 500 очок на рівні ${LEVEL}", + "descriptionFullComplete": "Набрано 500 очок на рівні ${LEVEL}", + "name": "Майстер рівня ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Переможіть всі хвилі", + "descriptionComplete": "Переможені всі хвилі", + "descriptionFull": "Переможіть всі хвилі на рівні ${LEVEL}", + "descriptionFullComplete": "Переможені всі хвилі на рівні ${LEVEL}", + "name": "Перемога на рівні ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Наберіть 1000 очок", + "descriptionComplete": "Набрано 1000 очок", + "descriptionFull": "Наберіть 1000 очок на рівні ${LEVEL}", + "descriptionFullComplete": "Набрано 1000 очок на рівні ${LEVEL}", + "name": "Чарівник рівня ${LEVEL}" + }, + "Precision Bombing": { + "description": "Виграйте без підсилювачів", + "descriptionComplete": "Перемога без підсилювачів", + "descriptionFull": "Виграйте без підсилювачів на рівні ${LEVEL}", + "descriptionFullComplete": "Перемога без підсилювачів на рівні ${LEVEL}", + "name": "Прицільне бомбометання" + }, + "Pro Boxer": { + "description": "Виграйте без використання бомб", + "descriptionComplete": "Перемога без використання бомб", + "descriptionFull": "Виграйте без використання бомб на рівні ${LEVEL}", + "descriptionFullComplete": "Перемога без використання бомб на рівні ${LEVEL}", + "name": "Боксер профі" + }, + "Pro Football Shutout": { + "description": "Виграйте в суху", + "descriptionComplete": "Переміг в суху", + "descriptionFull": "Виграйте в суху на рівні ${LEVEL}", + "descriptionFullComplete": "Переміг в суху на рівні ${LEVEL}", + "name": "${LEVEL} в суху" + }, + "Pro Football Victory": { + "description": "Виграйте матч", + "descriptionComplete": "Матч виграно", + "descriptionFull": "Виграйте матч ${LEVEL}", + "descriptionFullComplete": "Матч виграно ${LEVEL}", + "name": "Перемога на рівні ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Переможіть всі хвилі", + "descriptionComplete": "Переможені всі хвилі", + "descriptionFull": "Переможіть всі хвилі на рівні ${LEVEL}", + "descriptionFullComplete": "Переможені всі хвилі на рівні ${LEVEL}", + "name": "Перемога на рівні ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Пройдіть всі хвилі", + "descriptionComplete": "Пройдені всі хвилі", + "descriptionFull": "Пройдіть всі хвилі на рівні ${LEVEL}", + "descriptionFullComplete": "Пройдені всі хвилі на рівні ${LEVEL}", + "name": "Перемога на рівні ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Виграйте, не давши поганим хлопцям забити", + "descriptionComplete": "Перемога, не давши поганим хлопцям забити", + "descriptionFull": "Виграйте матч ${LEVEL}, не давши поганим хлопцям забити", + "descriptionFullComplete": "Перемога в матчі ${LEVEL}, не давши поганим хлопцям забити", + "name": "${LEVEL} в суху" + }, + "Rookie Football Victory": { + "description": "Виграйте матч", + "descriptionComplete": "Матч виграний", + "descriptionFull": "Виграйте матч ${LEVEL}", + "descriptionFullComplete": "Виграний матч ${LEVEL}", + "name": "Перемога на рівні ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Переможіть всі хвилі", + "descriptionComplete": "Переможені всі хвилі", + "descriptionFull": "Переможіть всі хвилі на рівні ${LEVEL}", + "descriptionFullComplete": "Переможені всі хвилі на рівні ${LEVEL}", + "name": "Перемога на рівні ${LEVEL}" + }, + "Runaround God": { + "description": "Наберіть 2000 очок", + "descriptionComplete": "Набрано 2000 очок", + "descriptionFull": "Наберіть 2000 очок на рівні ${LEVEL}", + "descriptionFullComplete": "Набрано 2000 очок на рівні ${LEVEL}", + "name": "Бог рівня ${LEVEL}" + }, + "Runaround Master": { + "description": "Наберіть 500 очок", + "descriptionComplete": "Набрано 500 очок", + "descriptionFull": "Наберіть 500 очок на рівні ${LEVEL}", + "descriptionFullComplete": "Набрано 500 очок на рівні ${LEVEL}", + "name": "Майстер рівня ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Наберіть 1000 очок", + "descriptionComplete": "Набрано 1000 очок", + "descriptionFull": "Наберіть 1000 очок на рівні ${LEVEL}", + "descriptionFullComplete": "Набрано 1000 очок на рівні ${LEVEL}", + "name": "Чарівник рівня ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Успішно поділитися грою з другом", + "descriptionFullComplete": "Успішно поділився грою з другом", + "name": "Ділитися - значить піклуватися" + }, + "Stayin' Alive": { + "description": "Виграйте без смертей", + "descriptionComplete": "Перемога без смертей", + "descriptionFull": "Виграйте рівень ${LEVEL} не вмираючи", + "descriptionFullComplete": "Переміг на рівні ${LEVEL} не вмерши", + "name": "Залишитися в живих" + }, + "Super Mega Punch": { + "description": "Нанесіть 100% шкоди одним ударом", + "descriptionComplete": "Нанесено 100% шкоди одним ударом", + "descriptionFull": "Нанесіть 100% шкоди одним ударом на рівні ${LEVEL}", + "descriptionFullComplete": "Нанесено 100% шкоди одним ударом на рівні ${LEVEL}", + "name": "Супер-мега-удар" + }, + "Super Punch": { + "description": "Нанесіть 50% пошкодження одним ударом", + "descriptionComplete": "Нанесено 50% шкоди одним ударом", + "descriptionFull": "Нанесіть 50% шкоди одним ударом на рівні ${LEVEL}", + "descriptionFullComplete": "Нанесено 50% шкоди одним ударом на рівні ${LEVEL}", + "name": "Супер-удар" + }, + "TNT Terror": { + "description": "Вбийте 6 поганих хлопців з допомогою TNT", + "descriptionComplete": "Вбито 6 поганих хлопців з допомогою TNT", + "descriptionFull": "Вбийте 6 поганих хлопців з допомогою TNT на рівні ${LEVEL}", + "descriptionFullComplete": "Вбито 6 поганих хлопців з допомогою TNT на рівні ${LEVEL}", + "name": "Тротиловий жах" + }, + "Team Player": { + "descriptionFull": "Почати гру в командах з 4 і більш гравцями", + "descriptionFullComplete": "Почата гра в командах з 4 і більш гравцями", + "name": "Командний гравець" + }, + "The Great Wall": { + "description": "Зупиніть кожного поганого хлопця", + "descriptionComplete": "Зупинений кожен поганий хлопець", + "descriptionFull": "Зупиніть кожного поганого хлопця на рівні ${LEVEL}", + "descriptionFullComplete": "Зупинений кожен поганий хлопець на рівні ${LEVEL}", + "name": "Велика стіна" + }, + "The Wall": { + "description": "Зупиніть кожного поганого хлопця", + "descriptionComplete": "Зупинений кожен поганий хлопець", + "descriptionFull": "Зупиніть кожного поганого хлопця на рівні ${LEVEL}", + "descriptionFullComplete": "Зупинений кожен поганий хлопець на рівні ${LEVEL}", + "name": "Стіна" + }, + "Uber Football Shutout": { + "description": "Виграйте в суху", + "descriptionComplete": "Переміг в суху", + "descriptionFull": "Виграйте в суху на рівні ${LEVEL}", + "descriptionFullComplete": "Переміг в суху на рівні ${LEVEL}", + "name": "${LEVEL} в суху" + }, + "Uber Football Victory": { + "description": "Виграйте матч", + "descriptionComplete": "Матч виграно", + "descriptionFull": "Виграйте матч ${LEVEL}", + "descriptionFullComplete": "Матч виграно ${LEVEL}", + "name": "Перемога на рівні ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Переможіть всі хвилі", + "descriptionComplete": "Переможені всі хвилі", + "descriptionFull": "Переможіть всі хвилі на рівні ${LEVEL}", + "descriptionFullComplete": "Переможені всі хвилі на рівні ${LEVEL}", + "name": "Перемога на рівні ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Пройдіть всі хвилі", + "descriptionComplete": "Пройдені всі хвилі", + "descriptionFull": "Пройдіть всі хвилі на рівні ${LEVEL}", + "descriptionFullComplete": "Пройдені всі хвилі на рівні ${LEVEL}", + "name": "Перемога на рівні ${LEVEL}" + } + }, + "achievementsRemainingText": "Досягнень залишилось:", + "achievementsText": "Досягнення", + "achievementsUnavailableForOldSeasonsText": "На жаль, специфіка досягнення недоступна для старих сезонів.", + "activatedText": "${THING} активовано", + "addGameWindow": { + "getMoreGamesText": "Ще ігри...", + "titleText": "Додати гру" + }, + "allowText": "Дозволити", + "alreadySignedInText": "На вашому акаунті грають на іншому пристрої;\nбудь ласка зайдіть з іншого акаунта або закрийте гру на\nіншому пристрої та спробуйте знову.", + "apiVersionErrorText": "Неможливо завантажити модуль ${NAME}; він призначений для API версії ${VERSION_USED}; потрібна версія ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(Режим \"Auto\" включайте його тільки коли підключені навушники)", + "headRelativeVRAudioText": "Позиційно-залежне VR-аудіо", + "musicVolumeText": "Гучність музики", + "soundVolumeText": "Гучність звуку", + "soundtrackButtonText": "Саундтреки", + "soundtrackDescriptionText": "(виберіть свою власну музику, яка буде звучати під час гри)", + "titleText": "Аудіо" + }, + "autoText": "Авто", + "backText": "Назад", + "banThisPlayerText": "Забанити гравця", + "bestOfFinalText": "Фінал: кращий з ${COUNT}", + "bestOfSeriesText": "Кращий в ${COUNT} партіях:", + "bestRankText": "Ваш найкращий ранг: ${RANK}", + "bestRatingText": "Ваш найкращий рейтинг: ${RATING}", + "bombBoldText": "БОМБА", + "bombText": "Бомба", + "boostText": "Підсилення", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} налаштовується в самому додатку.", + "buttonText": "кнопка", + "canWeDebugText": "Хочете, щоб BombSquad автоматично повідомляв розробнику\nпро помилки, збої і основну інформацію про використання?\n\nЦі дані не містять ніякої особистої інформації і допомагають\nпідтримувати гру в робочому стані без збоїв і помилок.", + "cancelText": "Скасувати", + "cantConfigureDeviceText": "Вибачте, ${DEVICE} неможливо налаштувати.", + "challengeEndedText": "Це змагання завершено.", + "chatMuteText": "Приглушити чат", + "chatMutedText": "Чат приглушений", + "chatUnMuteText": "Включити чат", + "choosingPlayerText": "<вибір гравця>", + "completeThisLevelToProceedText": "Щоб продовжити, потрібно\nпройти цей рівень!", + "completionBonusText": "Бонус за проходження", + "configControllersWindow": { + "configureControllersText": "Налаштування контролерів", + "configureKeyboard2Text": "Налаштування клавіатури P2", + "configureKeyboardText": "Налаштування клавіатури", + "configureMobileText": "Мобільні пристрої як контролери", + "configureTouchText": "Налаштування сенсорного екрану", + "ps3Text": "Контролери PS3", + "titleText": "Контролери", + "wiimotesText": "Wiimotes", + "xbox360Text": "Контролери Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Увага: підтримка контролерів різниться в залежності від пристрою і версії Android.", + "pressAnyButtonText": "Натисніть будь-яку кнопку на контролері,\n  який хочете налаштувати...", + "titleText": "Налаштування контролерів" + }, + "configGamepadWindow": { + "advancedText": "Додатково", + "advancedTitleText": "Додаткові настройки контролера", + "analogStickDeadZoneDescriptionText": "(включіть, якщо персонаж продовжує рухатися після того, як стік відпущений)", + "analogStickDeadZoneText": "Мертва Зона Аналоговогу Стіку", + "appliesToAllText": "(застосовується до всіх контроллерів такого типу)", + "autoRecalibrateDescriptionText": "(увімкніть цю опцію якщо ваш персонаж не рухається на повній швидкості)", + "autoRecalibrateText": "Авто-калібрування аналогових стіків", + "axisText": "вісь", + "clearText": "очистити", + "dpadText": "хрестовина", + "extraStartButtonText": "Додаткова кнопка Start", + "ifNothingHappensTryAnalogText": "Якщо нічого не відбувається, спробуйте назначити це аналоговому стіку.", + "ifNothingHappensTryDpadText": "Якщо нічого не відбувається, спробуйте назначити це на хрестовину", + "ignoreCompletelyDescriptionText": "(не дайте цьому контролеру впливати на гру, або меню)", + "ignoreCompletelyText": "Ігнорувати повністю", + "ignoredButton1Text": "Ігнорована кнопка 1", + "ignoredButton2Text": "Ігнорована кнопка 2", + "ignoredButton3Text": "Ігнорована кнопка 3", + "ignoredButton4Text": "Ігнорована кнопка 4", + "ignoredButtonDescriptionText": "(використовуйте це, щоб кнопки 'home' або 'sync' не вплинули на користувацький інтерфейс)", + "pressAnyAnalogTriggerText": "Натисніть будь-який аналоговий тригер...", + "pressAnyButtonOrDpadText": "Натисніть будь-яку кнопку або хрестовину...", + "pressAnyButtonText": "Натисніть будь-яку кнопку", + "pressLeftRightText": "Натисніть вліво або вправо...", + "pressUpDownText": "Натисніть вгору або вниз...", + "runButton1Text": "Кнопка для бігу 1", + "runButton2Text": "Кнопка для бігу 2", + "runTrigger1Text": "Тригер для бігу 1", + "runTrigger2Text": "Тригер для бігу 2", + "runTriggerDescriptionText": "(аналогові тригери дозволяють бігати з різною швидкістю)", + "secondHalfText": "Використовуйте це для настройки другої половини\nпристрою 'два контролера в одному',\nяке показується як один контролер.", + "secondaryEnableText": "Увімкнути", + "secondaryText": "Вторинний контролер", + "startButtonActivatesDefaultDescriptionText": "(вимкніть, якщо ваша кнопка \"старт\" працює як кнопки \"меню\")", + "startButtonActivatesDefaultText": "Кнопка Старт активує стандартний віджет", + "titleText": "Налаштування контролера", + "twoInOneSetupText": "Налаштування контролера 2-в-1", + "uiOnlyDescriptionText": "(відключити цей контролер приєднуючись до гри)", + "uiOnlyText": "Обмежуватись навігацією в меню", + "unassignedButtonsRunText": "Всі не присвоєні кнопки для бігу", + "unsetText": "<не задано>", + "vrReorientButtonText": "Кнопка переорієнтації VR" + }, + "configKeyboardWindow": { + "configuringText": "Налаштування ${DEVICE}", + "keyboard2NoteText": "Примітка: більшість клавіатур можуть зареєструвати тільки кілька \nнатискань клавіш за раз, так що другому гравцеві з клавіатури \nкраще грати з окремою підключеної для них клавіатури. \nЗауважте, що навіть в цьому випадку все одно потрібно \nбуде присвоїти унікальні клавіші для двох гравців." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Розміри кнопок дії", + "actionsText": "Дії", + "buttonsText": "кнопки", + "dragControlsText": "< щоб пересунути елементи управління, перетягніть їх >", + "joystickText": "джойстик", + "movementControlScaleText": "Розміри кнопок руху", + "movementText": "Рух", + "resetText": "Скидання", + "swipeControlsHiddenText": "Сховати іконки змахування", + "swipeInfoText": "До контролерів, які працюють зі змахування, потрібно звикнути,\nзате з ними можна грати, не дивлячись на контролер.", + "swipeText": "змахнути", + "titleText": "Налаштування сенсорного екрану" + }, + "configureItNowText": "Налаштувати зараз?", + "configureText": "Налаштувати", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Appstore", + "appStoreText": "App Store", + "bestResultsText": "Для найкращого результату вам знадобиться мережу Wi-Fi без затримок.\nВи можете зменшити затримки Wi-Fi, вимкнувши інші бездротові\nпристрою, граючи близько до маршрутизатора Wi-Fi, і підключивши\nхост гри безпосередньо до мережі через Ethernet.", + "explanationText": "Для налаштування смартфона або планшета в якості контролера\nвстановіть на ньому додаток \"${REMOTE_APP_NAME}\". До гри ${APP_NAME}\nможна підключити будь-яку кількість пристроїв через Wi-Fi, безкоштовно!", + "forAndroidText": "для Android:", + "forIOSText": "для iOS:", + "getItForText": "Завантажте додаток ${REMOTE_APP_NAME} для iOS в Apple App Store\nабо для Android в Google Play Store або Amazon Appstore", + "googlePlayText": "Google Play", + "titleText": "Використання мобільних пристроїв в якості контролерів:" + }, + "continuePurchaseText": "Продовжити за ${PRICE}?", + "continueText": "Продовжити", + "controlsText": "Управління", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Це не відноситься до абсолютних рекордів.", + "activenessInfoText": "Цей множник підвищується коли ви граєте,\nі знижується коли ви не граєте.", + "activityText": "Активність", + "campaignText": "Компанія", + "challengesInfoText": "Вигравай призи за міні-ігри.\n\nПризи та складність збільшуються\nкожен раз після перемоги і\nзменшуються в разі провалу.", + "challengesText": "Випробування", + "currentBestText": "Останній рекорд", + "customText": "Інше", + "entryFeeText": "Участь", + "forfeitConfirmText": "Так просто здаєтеся?", + "forfeitNotAllowedYetText": "Ви не можете покинути це змагання.", + "forfeitText": "Здатися", + "multipliersText": "Множники", + "nextChallengeText": "Наступне випробування", + "nextPlayText": "Наступна гра", + "ofTotalTimeText": "З ${TOTAL}", + "playNowText": "Грати", + "pointsText": "Бали", + "powerRankingFinishedSeasonUnrankedText": "Сезон завершений не в лізі", + "powerRankingNotInTopText": "(не в ${NUMBER} кращих)", + "powerRankingPointsEqualsText": "= ${NUMBER} очко", + "powerRankingPointsMultText": "(x ${NUMBER} балів)", + "powerRankingPointsText": "${NUMBER} балів", + "powerRankingPointsToRankedText": "(${CURRENT} з ${REMAINING} балів)", + "powerRankingText": "Ранг гравця", + "prizesText": "Призи", + "proMultInfoText": "Гравці з ${PRO} покращенням\nОтримують ${PERCENT}% множника тут.", + "seeMoreText": "Детальніше...", + "skipWaitText": "Прискорити очікування", + "timeRemainingText": "Часу залишився", + "toRankedText": "Отримано", + "totalText": "всього", + "tournamentInfoText": "Добийтеся високого результату з\nіншими гравцями твоєї ліги.\n\nНагороди вручаються найкрутішим\nпісля закінчення турніру.", + "welcome1Text": "Ласкаво просимо в ${LEAGUE}. Ви можете\nпідвищити свою лігу отримуючи зірки, отримуючи\nдосягнення і виграючи трофеї в турнірах.", + "welcome2Text": "Ви також можете заробити квитки від багатьох однакових видів діяльності.\nКвитки можуть бути використані, щоб розблокувати нових персонажів, карти та\nміні-ігри, щоб увійти турніри, і багато іншого.", + "yourPowerRankingText": "Ваш ранг:" + }, + "copyConfirmText": "Скопійовано до буферу обміну", + "copyOfText": "Копія ${NAME}", + "copyText": "Копія", + "createEditPlayerText": "<Створення / редагування гравця>", + "createText": "Створити", + "creditsWindow": { + "additionalAudioArtIdeasText": "Додаткове аудіо, попередні ілюстрації та ідеї: ${NAME}", + "additionalMusicFromText": "Додаткова музика: ${NAME}", + "allMyFamilyText": "Всім моїм друзям і родині, котрі допомогли грати тестову версію", + "codingGraphicsAudioText": "Програмування, графіка і аудіо: ${NAME}", + "languageTranslationsText": "Мовні переклади:", + "legalText": "Юридична інформація:", + "publicDomainMusicViaText": "Загальнодоступна музика через ${NAME}", + "softwareBasedOnText": "Це програмне забезпечення частково базується на роботі ${NAME}", + "songCreditText": "${TITLE} виконує ${PERFORMER}\nКомпозитор ${COMPOSER}, Аранжування ${ARRANGER}, Видано ${PUBLISHER},\nНадано ${SOURCE}", + "soundAndMusicText": "Звук і музика:", + "soundsText": "Звуки (${SOURCE}):", + "specialThanksText": "Особлива подяка:", + "thanksEspeciallyToText": "Окреме спасибі ${NAME}", + "titleText": "Брали участь в створенні ${APP_NAME}", + "whoeverInventedCoffeeText": "Тому, хто винайшов каву" + }, + "currentStandingText": "Ваша поточна позиція: ${RANK}", + "customizeText": "Змінити...", + "deathsTallyText": "${COUNT} смертей", + "deathsText": "Смерті", + "debugText": "налагодження", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Увага: для цього тесту рекомендується встановити Настройки->графіка->Текстури на 'Високий.'", + "runCPUBenchmarkText": "Запустити тест продуктивності CPU", + "runGPUBenchmarkText": "Запустити тест продуктивності GPU", + "runMediaReloadBenchmarkText": "Запустити тест продуктивності завантаження медіа", + "runStressTestText": "Виконати тест-навантаження", + "stressTestPlayerCountText": "Кількість гравців", + "stressTestPlaylistDescriptionText": "Плейлист навантажувального випробування", + "stressTestPlaylistNameText": "Назва плейлиста", + "stressTestPlaylistTypeText": "Тип плейлиста", + "stressTestRoundDurationText": "Тривалість раунду", + "stressTestTitleText": "Тест-навантаження", + "titleText": "Тести продуктивності і тести-навантаження", + "totalReloadTimeText": "Загальний час перезавантаження: ${TIME} (подробиці див. в лозі)" + }, + "defaultGameListNameText": "Стандартний плейлист режиму ${PLAYMODE}", + "defaultNewGameListNameText": "Мій плейлист ${PLAYMODE}", + "deleteText": "Видалити", + "demoText": "Демо", + "denyText": "Відхилити", + "deprecatedText": "Застаріла", + "desktopResText": "Розширення екрану", + "deviceAccountUpgradeText": "Увага!\nТи ввійшов за допомогою акаунта пристрою (${NAME}).\nАкаунти пристроїв будуть видалені у майбутньому оновленні.\nОновись до V2-акаунта, якщо ти хочеш зберегти свій прогрес.", + "difficultyEasyText": "Легкий", + "difficultyHardOnlyText": "Тільки в складному режимі", + "difficultyHardText": "Складний", + "difficultyHardUnlockOnlyText": "Цей рівень може бути відкритий тільки у складному режимі.\nВи цього не зробили !!!!!", + "directBrowserToURLText": "Будь ласка, перейдіть у веб-браузері за наступною адресою:", + "disableRemoteAppConnectionsText": "Відключення з'єднання RemoteApp", + "disableXInputDescriptionText": "Підключення більше 4 контролерів, але може не працювати.", + "disableXInputText": "Відключити XInput", + "doneText": "Готово", + "drawText": "Нічия", + "duplicateText": "Дублювати", + "editGameListWindow": { + "addGameText": "Додати\nГру", + "cantOverwriteDefaultText": "Неможливо перезаписати стандартний плейлист!", + "cantSaveAlreadyExistsText": "Плейлист з таким ім'ям вже існує!", + "cantSaveEmptyListText": "Неможливо зберегти порожній плейлист!", + "editGameText": "Змінити\nГру", + "listNameText": "Назва плейлиста", + "nameText": "Назва плейлиста", + "removeGameText": "Видалити\nгру", + "saveText": "Зберегти список", + "titleText": "Редактор плейлиста" + }, + "editProfileWindow": { + "accountProfileInfoText": "Цей спеціальний профіль має\nім'я та іконку, основані на вашому акаунті.\n\n${ICONS}\n\nСтворіть додаткові профілі, щоб\nВикористовувати різні імена і іконки.", + "accountProfileText": "(профіль акаунта)", + "availableText": "Ім'я \"${NAME}\" доступне.", + "characterText": "персонаж", + "checkingAvailabilityText": "Перевірка доступності для \"${NAME}\"...", + "colorText": "колір", + "getMoreCharactersText": "Ще персонажів...", + "getMoreIconsText": "Отримати додаткові іконки...", + "globalProfileInfoText": "Глобальні профілі гравців гарантовано мають унікальні\nІмена. Вони також включають додаткові іконки.", + "globalProfileText": "(глобальний профіль)", + "highlightText": "акцент", + "iconText": "іконка", + "localProfileInfoText": "Локальні ігрові профілі не мають іконки і їхні імена\nне гарантовано унікальні. Підніміть до глобального профілю\nщоб зарезервувати унікальне ім'я і додати додаткову іконку.", + "localProfileText": "(локальний профіль)", + "nameDescriptionText": "Ім'я гравця", + "nameText": "Ім'я", + "randomText": "випадкове", + "titleEditText": "Змінити профіль", + "titleNewText": "Новий профіль", + "unavailableText": "\"${NAME}\" недоступно; спробуйте інше ім'я.", + "upgradeProfileInfoText": "Це зарезервує ваше ім'я гравця\nІ дозволить вам змінити іконкую.", + "upgradeToGlobalProfileText": "Оновити до глобального профілю" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Неможливо видалити стандартний саундтрек.", + "cantEditDefaultText": "Неможливо змінити стандартний саундтрек. Створіть копію або новий саундтрек.", + "cantOverwriteDefaultText": "Неможливо перезаписати стандартний саундтрек", + "cantSaveAlreadyExistsText": "Саундтрек з таким ім'ям вже існує!", + "defaultGameMusicText": "<стандартна музика гри>", + "defaultSoundtrackNameText": "Стандартний саундтрек", + "deleteConfirmText": "Видалити саундтрек:\n\n'${NAME}?", + "deleteText": "Видалити\nсаундтрек", + "duplicateText": "Копіювати\nсаундтрек", + "editSoundtrackText": "Редактор саундтрека", + "editText": "Змінити\nсаундтрек", + "fetchingITunesText": "завантаження музикальних плейлистів...", + "musicVolumeZeroWarning": "Увага: гучність музики встановлена на 0", + "nameText": "Назва", + "newSoundtrackNameText": "Мій саундтрек ${COUNT}", + "newSoundtrackText": "Новий саундтрек:", + "newText": "Новий", + "selectAPlaylistText": "Виберіть плейлист", + "selectASourceText": "Джерело музики", + "testText": "тест", + "titleText": "Саундтреки", + "useDefaultGameMusicText": "Стандартна музика", + "useITunesPlaylistText": "Музикальний плейлист", + "useMusicFileText": "Музичні файли (mp3 і т.д.)", + "useMusicFolderText": "Тека з музикою" + }, + "editText": "Редагувати", + "endText": "Кінець", + "enjoyText": "Успіхів!", + "epicDescriptionFilterText": "${DESCRIPTION} в епічному сповільненій дії.", + "epicNameFilterText": "${NAME} в епічному режимі", + "errorAccessDeniedText": "доступ заборонено", + "errorDeviceTimeIncorrectText": "Час вашого пристрою зміщено на${HOURS} год.\nЦе може спричинити проблеми.\nБудь ласка, перевірте свій час і налаштування часового поясу.", + "errorOutOfDiskSpaceText": "немає місця на диску", + "errorSecureConnectionFailText": "Неможливо встановити безпечне хмарне з’єднання; мережеві функції можуть не працювати.", + "errorText": "Помилка", + "errorUnknownText": "невідома помилка", + "exitGameText": "Вийти з ${APP_NAME}?", + "exportSuccessText": "'${NAME}' експортовано.", + "externalStorageText": "Зовнішня пам'ять", + "failText": "Провал", + "fatalErrorText": "Ой, щось загубилося або зламалося.\nСпробуйте перевстановити додаток або\nзверніться до ${EMAIL} за допомогою.", + "fileSelectorWindow": { + "titleFileFolderText": "Виберіть файл або папку", + "titleFileText": "Виберіть файл", + "titleFolderText": "Виберіть папку", + "useThisFolderButtonText": "Використовувати цю папку" + }, + "filterText": "Фiльтр", + "finalScoreText": "Фінальні очки", + "finalScoresText": "Фінальні очки", + "finalTimeText": "Фінальний час", + "finishingInstallText": "Завершується установка, хвилинку ...", + "fireTVRemoteWarningText": "* Для кращого результату використовуйте\nігрові контролери або встановіть\nдодаток '${REMOTE_APP_NAME}'\nна ваших телефонах і планшетах.", + "firstToFinalText": "Фінал до ${COUNT} очок", + "firstToSeriesText": "Серія до ${COUNT} очок", + "fiveKillText": "П'ЯТЬОХ ЗА РАЗ!!!", + "flawlessWaveText": "Бездоганна хвиля!", + "fourKillText": "ЧОТИРЬОХ ЗА РАЗ!!!", + "friendScoresUnavailableText": "Очки друзів недоступні.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Лідери гри ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "Неможливо видалити стандартний плейлист!", + "cantEditDefaultText": "Неможливо змінити стандартний плейлист! Створіть копію або новий список.", + "cantShareDefaultText": "Ви не можете ділитися стандартним плейлистом.", + "deleteConfirmText": "Видалити \"${LIST}\"?", + "deleteText": "Видалити\nплейлист", + "duplicateText": "Дублювати\nплейлист", + "editText": "Змінити\nплейлист", + "newText": "Новий\nплейлист", + "showTutorialText": "Показати туторіал", + "shuffleGameOrderText": "Змішати порядок ігор", + "titleText": "Налаштувати плейлисти '${TYPE}'" + }, + "gameSettingsWindow": { + "addGameText": "Додати гру" + }, + "gamesToText": "${WINCOUNT}: ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Пам'ятайте: будь-який пристрій у спільній грі підтримує\nкілька гравців, якщо у вас вистачає контролерів.", + "aboutDescriptionText": "Використовуйте ці закладки, щоб створити лобі.\n\nЛобі дозволяє грати в ігри і турніри\nз друзями на різних пристроях.\n\nНатисніть кнопку ${PARTY} в правому верхньому куті,\nщоб спілкуватися з друзями в вашому лобі.\n(На контролері, натисніть ${BUTTON} перебуваючи в меню)", + "aboutText": "Інфо", + "addressFetchErrorText": "<помилка запиту адрес>", + "appInviteMessageText": "${NAME} відправив вам ${COUNT} квитків в ${APP_NAME}", + "appInviteSendACodeText": "Надішліть їм код", + "appInviteTitleText": "Запрошення в ${APP_NAME}", + "bluetoothAndroidSupportText": "(працює з будь-яким пристроєм, що підтримує Bluetooth)", + "bluetoothDescriptionText": "Створити/увійти в лобі через Bluetooth:", + "bluetoothHostText": "Створити лобі через Bluetooth", + "bluetoothJoinText": "Приєднатися через Bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "Перевірка ...", + "copyCodeConfirmText": "Код скопійовано до буферу обміну", + "copyCodeText": "Скопіювати код", + "dedicatedServerInfoText": "Для кращого результату створіть окремий сервер. Дивись bombsquadgame.com/server", + "disconnectClientsText": "Це відключить ${COUNT} гравців\nУ вашому лобі. Ви впевнені?", + "earnTicketsForRecommendingAmountText": "Друзі отримають ${COUNT} квитки, якщо вони спробують гру \n(і ви будете отримувати ${YOU_COUNT} для кожного, це зробить)", + "earnTicketsForRecommendingText": "Поділися грою\nОтримай квитки ...", + "emailItText": "Надіслати Email", + "favoritesSaveText": "Встановити як улюблене", + "favoritesText": "Улюблене", + "freeCloudServerAvailableMinutesText": "Наступний безкоштовний сервер у хмарі буде доступним через ${MINUTES} хвилин.", + "freeCloudServerAvailableNowText": "Безкоштовний сервер у хмарі тепер достуний!", + "freeCloudServerNotAvailableText": "Не знайдено доступних серверів у хмарі.", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} квитків від ${NAME}", + "friendPromoCodeAwardText": "Ви отримаєте ${COUNT} квитків за кожну активацію.", + "friendPromoCodeExpireText": "Код дійсний протягом ${EXPIRE_HOURS} годин і тільки для нових гравців.", + "friendPromoCodeInstructionsText": "Для активації в ${APP_NAME} зайдіть в \"Налаштування->Додатково->Ввести код\".\nЗнайди на bombsquadgame.com версію гри для своєї платформи.", + "friendPromoCodeRedeemLongText": "Кожна активація приносить ${COUNT} квитків до ${MAX_USES} гравцям.", + "friendPromoCodeRedeemShortText": "Він принесе ${COUNT} квитків в грі.", + "friendPromoCodeWhereToEnterText": "(В \"Налаштування->Додатково->Ввести код\")", + "getFriendInviteCodeText": "Отримати промо-код", + "googlePlayDescriptionText": "Запросити гравців Google Play в ваше лобі:", + "googlePlayInviteText": "Запросити", + "googlePlayReInviteText": "У вашому лобі ${COUNT} гравців Google Play.\nЯкщо ви почнете нове запрошення, вони будуть відключені.\nДодайте їх в нове запрошення, щоб їх повернути.", + "googlePlaySeeInvitesText": "Подивитися запрошення", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Тільки для Android / Google Play)", + "hostPublicPartyDescriptionText": "Створити публічну групу", + "hostingUnavailableText": "Хостинг не доступний", + "inDevelopmentWarningText": "Примітка:\n\nМережева гра є новою і ще розвивається.\nВ даний час, дуже рекомендується, щоб усі\nгравці були в тій же мережі Wi-Fi.", + "internetText": "Інтернет", + "inviteAFriendText": "Друзі ще не грають? Запроси їх\nспробувати і вони отримають ${COUNT} квитків.", + "inviteFriendsText": "Запросити друзів", + "joinPublicPartyDescriptionText": "Приєднатися до публічної групи", + "localNetworkDescriptionText": "Увійти в лобі у вашій мережі (через LAN, Bluetooth, т. д. )", + "localNetworkText": "Локальна мережа", + "makePartyPrivateText": "Зробити моє лобі приватним", + "makePartyPublicText": "Зробити моє лобі публічним", + "manualAddressText": "Адреса", + "manualConnectText": "Підключитися", + "manualDescriptionText": "Увійти в лобі за адресою:", + "manualJoinSectionText": "Приєднатися за адресою", + "manualJoinableFromInternetText": "До вас можна підключатися через інтернет?:", + "manualJoinableNoWithAsteriskText": "НІ*", + "manualJoinableYesText": "ТАК", + "manualRouterForwardingText": "*щоб виправити, спробуйте налаштувати маршрутизатор для перенаправлення UDP-порта ${PORT} на ваш локальний адресу", + "manualText": "Вручну", + "manualYourAddressFromInternetText": "Ваш інтернет адрес:", + "manualYourLocalAddressText": "Ваш локальний адрес:", + "nearbyText": "Поблизу", + "noConnectionText": "<немає з'єднання>", + "otherVersionsText": "(інші версії)", + "partyCodeText": "Код групи", + "partyInviteAcceptText": "Прийняти", + "partyInviteDeclineText": "Відхилити", + "partyInviteGooglePlayExtraText": "(дивіться вкладку 'Google Play' в розділі 'Зібрати')", + "partyInviteIgnoreText": "Ігнорувати", + "partyInviteText": "${NAME} запросив\nвас в його лобі!", + "partyNameText": "Ім'я команди", + "partyServerRunningText": "Ваш груповий сервер запущений.", + "partySizeText": "розмір групи", + "partyStatusCheckingText": "перевірка...", + "partyStatusJoinableText": "ваша команда доступна через інтернет", + "partyStatusNoConnectionText": "сервер не доступний", + "partyStatusNotJoinableText": "ваша команда недоступна через інтернет", + "partyStatusNotPublicText": "ваша команда не для всіх", + "pingText": "пінг", + "portText": "порт", + "privatePartyCloudDescriptionText": "Приватні групи працюють на серверах хмари; конфігурація роутера не потрібна.", + "privatePartyHostText": "Створити приватну групу", + "privatePartyJoinText": "Приєднатися до публічної групи", + "privateText": "Приватний", + "publicHostRouterConfigText": "Це може потребувати конфігурацію спрямування порту на вашому роутері. Легшим вибором є хостинг приватної групи.", + "publicText": "Публічний", + "requestingAPromoCodeText": "Запитуємо код...", + "sendDirectInvitesText": "Послати запрошення", + "shareThisCodeWithFriendsText": "Поділися кодом з друзями:", + "showMyAddressText": "Показати мою адресу", + "startHostingPaidText": "Запустити зараз за ${COST}", + "startHostingText": "Запустити", + "startStopHostingMinutesText": "Ви можете розпочати хостинг безкоштовно через наступних ${MINUTES} хвилин.", + "stopHostingText": "Зупинити хостинг", + "titleText": "Зібрати", + "wifiDirectDescriptionBottomText": "Якщо у всіх пристроїв є панель 'Wi-Fi Direct', вони можуть використовувати її, щоб знайти\nі з'єднатися один з одним. Коли всі пристрої підключені, ви можете створити тут лобі,\nвикористовуючи вкладку 'Локальна мережа', так само, як і зі звичайною Wi-Fi мережею.\n\nДля кращих результатів, хост Wi-Fi Direct також повинен бути хостом групи ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct може бути використаний для з'єднання пристроїв Android безпосередньо без\nWi-Fi мережі. Це найкраще працює на Android 4.2 або новіше.\n\nЩоб використовувати, відкрийте налаштування Wi-Fi і пошукайте Wi-Fi Direct в меню.", + "wifiDirectOpenWiFiSettingsText": "Відкрити налаштування Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(працює між всіма платформами)", + "worksWithGooglePlayDevicesText": "(працює з пристроями, що використовують версію гри Google Play (Android)", + "youHaveBeenSentAPromoCodeText": "Вам був висланий ${APP_NAME} промо-код:" + }, + "getTicketsWindow": { + "freeText": "БЕЗКОШТОВНО!", + "freeTicketsText": "Безкоштовні квитки", + "inProgressText": "Виконується транзакція; спробуйте ще раз через кілька секунд.", + "purchasesRestoredText": "Покупки перевірені", + "receivedTicketsText": "Отримано ${COUNT} квитків!", + "restorePurchasesText": "Відновити покупки", + "ticketPack1Text": "Маленька пачка квитків", + "ticketPack2Text": "Середня пачка квитків", + "ticketPack3Text": "Велика пачка квитків", + "ticketPack4Text": "Величезна пачка квитків", + "ticketPack5Text": "Слонова пачка квитків", + "ticketPack6Text": "Максимальна пачка квитків", + "ticketsFromASponsorText": "Перегляньте рекламу\nза ${COUNT} квитків", + "ticketsText": "Квитків: ${COUNT}", + "titleText": "Отримати квитки", + "unavailableLinkAccountText": "Вибачте, але на цій платформі покупки недоступні.\nВ якості вирішення, ви можете прив'язати цей акаунт\nдо акаунту на іншій платформі, і здійснювати покупки там.", + "unavailableTemporarilyText": "Зараз недоступно; Спробуйте ще раз пізніше.", + "unavailableText": "На жаль це не доступно.", + "versionTooOldText": "Вибачте, ваша версія гри застаріла; будь ласка, завантажте оновлення.", + "youHaveShortText": "у вас ${COUNT}", + "youHaveText": "У вас ${COUNT} квитків" + }, + "googleMultiplayerDiscontinuedText": "Пробачте, але сервіс мультіплеєра від Google тепер не доступний.\nЯ працюю над зміною сервіса як можно скоріше.\nДо цього, будь ласка, подивіться інакші способи гри в мультіплеєр. \n-Ерік", + "googlePlayPurchasesNotAvailableText": "Покупки в Google Play недоступні.\nМожливо, вам знадобиться оновити програму магазину.", + "googlePlayServicesNotAvailableText": "Google Play сервіси недоступні.\nДеякі функції програми не роблять.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Завжди", + "fullScreenCmdText": "Повноекранний (Cmd-F)", + "fullScreenCtrlText": "Повноекранний (Ctrl-F)", + "gammaText": "Гамма", + "highText": "Високий", + "higherText": "Вище", + "lowText": "Низький", + "mediumText": "Середній", + "neverText": "Ніколи", + "resolutionText": "Розширення", + "showFPSText": "Показувати FPS", + "texturesText": "Текстури", + "titleText": "Графіка", + "tvBorderText": "Границя телевізора", + "verticalSyncText": "Вертикальна синхронізація", + "visualsText": "Відеоряд" + }, + "helpWindow": { + "bombInfoText": "- Бомба -\nСильніше ударів, але може привести\nдо смертельних ушкоджень. для\nнайкращих результатів кидати в\nпротивника поки не догорів гніт.", + "canHelpText": "${APP_NAME} може допомогти.", + "controllersInfoText": "Ви можете грати в ${APP_NAME} з друзями по мережі, або ви всі можете\nграти на одному пристрої, якщо у вас досить контролерів.\n${APP_NAME} підтримує будь-які контролери; можна навіть використовувати телефони\nв якості контролерів через безкоштовний додаток '${REMOTE_APP_NAME}.\nДивіться Налаштування->Контролери для отримання додаткової інформації.", + "controllersInfoTextRemoteOnly": "Ви можете грати в ${APP_NAME} з друзями по інтернету, або ви\nможете усі грати на одному девайсі якщо використовуєте смартфони як\nконтролери вони безкоштовні '${REMOTE_APP_NAME}' app.", + "controllersText": "Контролери", + "controlsSubtitleText": "У вашого дружнього персонажа з ${APP_NAME} є кілька простих дій:", + "controlsText": "Управління", + "devicesInfoText": "У VR-версію ${APP_NAME} можна грати по мережі зі звичайною \nверсією, так що витягуйте свої додаткові телефони, планшети\nі комп'ютери, і грайте на них. Можна навіть підключити\nзвичайну версію гри до VR-версії, щоб дозволити\nіншим спостерігати за діями.", + "devicesText": "Пристрої", + "friendsGoodText": "Бувають корисні. В ${APP_NAME} веселіше грати з кількома гравцями;\nпідтримується до 8 гравців одночасно, що призводить нас до:", + "friendsText": "Друзі", + "jumpInfoText": "- Стрибок -\nСтрибайте для перескакування,\nкидання предметів подалі\nабо для вираження радості.", + "orPunchingSomethingText": "Або вдарити, скинути з обриву і підірвати бомбою-липучкою по дорозі вниз.", + "pickUpInfoText": "- Захоплення -\nХапайте прапори, ворогів\nі все, що не прикручено до підлоги.\nЩоб кинути, натисніть ще раз.", + "powerupBombDescriptionText": "Дозволяє жбурнути три бомби\nпоспіль, замість однієї.", + "powerupBombNameText": "Потрійні бомби", + "powerupCurseDescriptionText": "Цих, напевно, краще уникати.\n  ...чи ні?", + "powerupCurseNameText": "Прокляття", + "powerupHealthDescriptionText": "Нізащо не здогадаєтеся.\nПовертає повне здоров'я.", + "powerupHealthNameText": "Аптечка", + "powerupIceBombsDescriptionText": "Слабші, ніж звичайні бомби\nале робить ворогів замороженими\nі особливо крихкими.", + "powerupIceBombsNameText": "Крижані бомби", + "powerupImpactBombsDescriptionText": "Трохи слабші звичайних бомб,\nале вибухають при ударі.", + "powerupImpactBombsNameText": "Ударні бомби", + "powerupLandMinesDescriptionText": "Видаються по 3 штуки.\nКорисні для захисту бази або\nупокорення прудконогих ворогів.", + "powerupLandMinesNameText": "Міни", + "powerupPunchDescriptionText": "Роблять ваші удари швидше,\nкраще, сильніше.", + "powerupPunchNameText": "Боксерські рукавички", + "powerupShieldDescriptionText": "Трохи поглинає пошкодження,\nщоб вам не довелося.", + "powerupShieldNameText": "Енергетичний щит", + "powerupStickyBombsDescriptionText": "Липнуть до всього, чого торкаються.\nІ починаються веселощі.", + "powerupStickyBombsNameText": "Бомби-липучки", + "powerupsSubtitleText": "Звичайно, жодна гра не обходиться без підсилювачів:", + "powerupsText": "Підсилювачі", + "punchInfoText": "- Удар -\nЧим швидше рухаються кулаки -\nтим сильніше удар. Так що бігайте\nі крутіться як ненормальні.", + "runInfoText": "- Біг -\nДля бігу утримуйте БУДЬ-ЯКУ кнопку. Для цього добрі верхні тригери\nабо плечові кнопки, якщо вони у вас є. Бігом пересуватися швидше,\nале важче повертати, так що обережно з обривами.", + "someDaysText": "Іноді просто хочеться що-небудь вдарити. Або підірвати.", + "titleText": "Довідка ${APP_NAME}", + "toGetTheMostText": "Щоб вичавити максимум з цієї гри, вам необхідно:", + "welcomeText": "Ласкаво просимо в ${APP_NAME}!" + }, + "holdAnyButtonText": "<тримати будь-яку кнопку>", + "holdAnyKeyText": "<тримати будь-яку клавішу>", + "hostIsNavigatingMenusText": "- ${HOST} в меню навігації як бос -", + "importPlaylistCodeInstructionsText": "Використовуйте вказаний код щоб імпортувати цей плейлист ще десь:", + "importPlaylistSuccessText": "Імпортовано плейлист ${TYPE} '${NAME}'", + "importText": "Імпорт", + "importingText": "Імпортую...", + "inGameClippedNameText": "У грі буде\n\"${NAME}\"", + "installDiskSpaceErrorText": "ПОМИЛКА: не вдалося завершити встановлення. \nМоже не вистачає вільного місця на вашому \nпристрої. Звільніть місце та спробуйте ще раз.", + "internal": { + "arrowsToExitListText": "Щоб вийти зі списку натисніть ${LEFT} або ${RIGHT}", + "buttonText": "кнопка", + "cantKickHostError": "Неможливо вигнати творця.", + "chatBlockedText": "${NAME} заблокований на ${TIME} секунд.", + "connectedToGameText": "Увійшов в гру '${NAME}'", + "connectedToPartyText": "Увійшов в лобі ${NAME}!", + "connectingToPartyText": "Йде з'єднання...", + "connectionFailedHostAlreadyInPartyText": "З'єднання невдале; хост знаходиться в іншому лобі.", + "connectionFailedPartyFullText": "З'єднання невдале; група повна.", + "connectionFailedText": "З'єднання невдале.", + "connectionFailedVersionMismatchText": "З'єднання невдале; хост використовує іншу версію гри.\nПереконайтеся, що версії обох сторін оновлені, і спробуйте знову.", + "connectionRejectedText": "З'єднання відхилено.", + "controllerConnectedText": "${CONTROLLER} підключено.", + "controllerDetectedText": "Знайдено 1 контролер.", + "controllerDisconnectedText": "${CONTROLLER} від'єднано.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} від'єднано. Спробуйте підключитися ще раз.", + "controllerForMenusOnlyText": "Цей контролер не використовується в грі; тільки в навігаційному меню", + "controllerReconnectedText": "${CONTROLLER} знову підключений.", + "controllersConnectedText": "Підключено ${COUNT} контролерів.", + "controllersDetectedText": "Виявлено ${COUNT} контролерів.", + "controllersDisconnectedText": "Від'єднано ${COUNT} контролерів.", + "corruptFileText": "Виявлено пошкоджені файли. Спробуйте перевстановити або зверніться до ${EMAIL}", + "errorPlayingMusicText": "Помилка відтворення музики: ${MUSIC}", + "errorResettingAchievementsText": "Неможливо скинути онлайн-досягнення, будь ласка, спробуйте пізніше.", + "hasMenuControlText": "${NAME} контролює меню", + "incompatibleNewerVersionHostText": "Хост використовує новішу версію гри.\nОновіться до останньої версії і спробуйте знову.", + "incompatibleVersionHostText": "Хост використовує іншу версію гри.\nПереконайтеся, що обидві ваші версії оновлені, і спробуйте знову.", + "incompatibleVersionPlayerText": "${NAME} використовує іншу версію гри і не може з'єднається.\nПереконайтеся, що обидві ваші версії оновлені, і спробуйте знову.", + "invalidAddressErrorText": "Помилка: неправильний адрес.", + "invalidNameErrorText": "Помилка: некоректне ім'я.", + "invalidPortErrorText": "Помилка: невірний порт.", + "invitationSentText": "Запрошення відправлено.", + "invitationsSentText": "Відправлено ${COUNT} запрошень.", + "joinedPartyInstructionsText": "Хтось увійшов у ваше лобі.\nНатисніть 'Грати' щоб почати гру.", + "keyboardText": "Клавіатура", + "kickIdlePlayersKickedText": "${NAME} викинутий за бездіяльність.", + "kickIdlePlayersWarning1Text": "${NAME} буде викинутий через ${COUNT} секунд при бездіяльності.", + "kickIdlePlayersWarning2Text": "(це можна вимкнути в Налаштування->Додатково)", + "leftGameText": "Покинув '${NAME}'", + "leftPartyText": "Вийшов з лобі ${NAME}.", + "noMusicFilesInFolderText": "У теці немає музичних файлів.", + "playerJoinedPartyText": "${NAME} увійшов в лобі!", + "playerLeftPartyText": "${NAME} покинув лобі.", + "rejectingInviteAlreadyInPartyText": "Запрошення відхилено (вже в лобі).", + "serverRestartingText": "Сервер перезавантажуєтся. Спробуй пізніше...", + "serverShuttingDownText": "Сервер вимикаєтся...", + "signInErrorText": "Помилка входу", + "signInNoConnectionText": "Неможливо увійти. (немає інтернет з'єднання?)", + "telnetAccessDeniedText": "ПОМИЛКА: користувач не надав доступ Telnet.", + "timeOutText": "(залишилося ${TIME} секунд)", + "touchScreenJoinWarningText": "Ви приєдналися з сенсорним екраном.\nЯкщо це була помилка, натисніть 'Меню->Покинути гру'.", + "touchScreenText": "Сенсорний екран", + "unableToResolveHostText": "Помилка: неможливо досягти хоста.", + "unavailableNoConnectionText": "Зараз це недоступно (немає інтернет з'єднання?)", + "vrOrientationResetCardboardText": "Використовуйте це, щоб скинути орієнтацію VR.\nЩоб грати в гру вам буде потрібен зовнішній контролер.", + "vrOrientationResetText": "Скидання орієнтації VR.", + "willTimeOutText": "(час вийде при бездіяльності)" + }, + "jumpBoldText": "СТРИБОК", + "jumpText": "Стрибнути", + "keepText": "Залишити", + "keepTheseSettingsText": "Залишити ці налаштування?", + "keyboardChangeInstructionsText": "Натисни двічи для зміни клавіатури.", + "keyboardNoOthersAvailableText": "Немає інших контроллерів.", + "keyboardSwitchText": "Перемикання контролю на \"${NAME}\".", + "kickOccurredText": "${NAME} вигнали.", + "kickQuestionText": "Вигнати ${NAME}?", + "kickText": "Вигнати", + "kickVoteCantKickAdminsText": "Адміни не можуть бути вигнані.", + "kickVoteCantKickSelfText": "Ви не можете вигнати себе.", + "kickVoteFailedNotEnoughVotersText": "Недостатньо гравців для голосування", + "kickVoteFailedText": "Вигнання не вдалося.", + "kickVoteStartedText": "Голосування за вигнання ${NAME}", + "kickVoteText": "Вигнати", + "kickVotingDisabledText": "Вигнання вимкненно.", + "kickWithChatText": "Наберіть ${YES} для згоди або ${NO} для відмови.", + "killsTallyText": "Убито ${COUNT}", + "killsText": "Убито", + "kioskWindow": { + "easyText": "Легкий", + "epicModeText": "Епічний режим", + "fullMenuText": "Повне меню", + "hardText": "Важкий", + "mediumText": "Середній", + "singlePlayerExamplesText": "Приклади одиночної гри / кооперативу", + "versusExamplesText": "Приклади гри один проти одного" + }, + "languageSetText": "Мова тепер \"${LANGUAGE}\".", + "lapNumberText": "Коло ${CURRENT} / ${TOTAL}", + "lastGamesText": "(останні ${COUNT} ігор)", + "leaderboardsText": "Таблиці лідерів", + "league": { + "allTimeText": "Абсолютні", + "currentSeasonText": "Поточний сезон (${NUMBER})", + "leagueFullText": "Ліга ${NAME}", + "leagueRankText": "Ранг ліги", + "leagueText": "Ліга", + "rankInLeagueText": "#${RANK}, ${NAME} League ${SUFFIX}", + "seasonEndedDaysAgoText": "Сезон завершився ${NUMBER} днів тому.", + "seasonEndsDaysText": "Сезон завершиться через ${NUMBER} днів.", + "seasonEndsHoursText": "Сезон завершиться через ${NUMBER} годин.", + "seasonEndsMinutesText": "Сезон завершиться через ${NUMBER} хвилин.", + "seasonText": "Сезон ${NUMBER}", + "tournamentLeagueText": "Щоб брати участь в цьому турнірі, ви повинні досягти ліги ${NAME}.", + "trophyCountsResetText": "Трофеї будуть скинуті в наступному сезоні." + }, + "levelBestScoresText": "Кращий рекорд на ${LEVEL}", + "levelBestTimesText": "Кращий час на ${LEVEL}", + "levelIsLockedText": "${LEVEL} заблокований.", + "levelMustBeCompletedFirstText": "Спочатку повинен бути пройдений ${LEVEL}.", + "levelText": "Рівень ${NUMBER}", + "levelUnlockedText": "Рівень розблоковано!", + "livesBonusText": "Бонус життів", + "loadingText": "завантаження", + "loadingTryAgainText": "Завантаження; спробуйте знову через кілька секунд ...", + "macControllerSubsystemBothText": "Обидва (не рекомендується)", + "macControllerSubsystemClassicText": "Класичний", + "macControllerSubsystemDescriptionText": "(спробуйте змінити це, якщо ваші контролери неробочі)", + "macControllerSubsystemMFiNoteText": "Made-for-iOS/Mac контролер виявлено;\nМожливо, ви захочете включити це в Налаштування -> Контролери", + "macControllerSubsystemMFiText": "Made-for-iOS/Mac", + "macControllerSubsystemTitleText": "Підтримка контролера", + "mainMenu": { + "creditsText": "Подяки", + "demoMenuText": "Меню прикладів", + "endGameText": "Завершити гру", + "endTestText": "Закінчити тест", + "exitGameText": "Вийти з гри", + "exitToMenuText": "Вийти в меню?", + "howToPlayText": "Як грати", + "justPlayerText": "(Тільки ${NAME})", + "leaveGameText": "Покинути гру", + "leavePartyConfirmText": "Дійсно покинути лобі?", + "leavePartyText": "Покинути лобі", + "quitText": "Вийти", + "resumeText": "Продовжити", + "settingsText": "Налаштування" + }, + "makeItSoText": "Поїхали!", + "mapSelectGetMoreMapsText": "Ще карт...", + "mapSelectText": "Вибрати...", + "mapSelectTitleText": "Карти гри ${GAME}", + "mapText": "Карта", + "maxConnectionsText": "Максимум з'єднань", + "maxPartySizeText": "Розмір групи", + "maxPlayersText": "Максимум гравців", + "merchText": "Мерч!", + "modeArcadeText": "Аркадний режим", + "modeClassicText": "Класичний режим", + "modeDemoText": "Демо режим", + "mostValuablePlayerText": "Найцінніший гравець", + "mostViolatedPlayerText": "Самий побитий гравець", + "mostViolentPlayerText": "Самий буйний гравець", + "moveText": "Рух", + "multiKillText": "${COUNT} ЗА РАЗ!!!", + "multiPlayerCountText": "${COUNT} гравця", + "mustInviteFriendsText": "Примітка: ви повинні запросити друзів\nна панелі \"${GATHER}\" або приєднати\nконтролери для спільної гри.", + "nameBetrayedText": "${NAME} зрадив ${VICTIM}.", + "nameDiedText": "${NAME} помер.", + "nameKilledText": "${NAME} вбив ${VICTIM}.", + "nameNotEmptyText": "Ім'я не може бути порожнім!", + "nameScoresText": "${NAME} веде!", + "nameSuicideKidFriendlyText": "${NAME} вбився.", + "nameSuicideText": "${NAME} скоїв суїцид.", + "nameText": "Ім'я", + "nativeText": "Власний", + "newPersonalBestText": "Новий особистий рекорд!", + "newTestBuildAvailableText": "Доступна нова тестова версія! (${VERSION} збірка ${BUILD}).\nОновити: ${ADDRESS}", + "newText": "Новий", + "newVersionAvailableText": "Доступна нова версія ${APP_NAME}! (${VERSION})", + "nextAchievementsText": "Наступні досягнення:", + "nextLevelText": "Наступний рівень", + "noAchievementsRemainingText": "- немає", + "noContinuesText": "(без продовжень)", + "noExternalStorageErrorText": "На цьому пристрої не знайдено зовнішньої пам'яті", + "noGameCircleText": "Помилка: не ввійшли в GameCircle", + "noScoresYetText": "Рахунка поки немає.", + "noThanksText": "Ні дякую", + "noTournamentsInTestBuildText": "ВАЖЛИВО: Турнірні Очки на цій тестовій версії будуть ігноровані.", + "noValidMapsErrorText": "Для даного типу гри не знайдено коректних карт.", + "notEnoughPlayersRemainingText": "Залишилося недостатньо гравців; вийдіть і почніть нову гру.", + "notEnoughPlayersText": "Для початку цієї гри потрібно як мінімум ${COUNT} гравця!", + "notNowText": "Не зараз", + "notSignedInErrorText": "Увійдіть щоб зробити це.", + "notSignedInGooglePlayErrorText": "Увійдіть спочатку в Google Play, а там подивимося.", + "notSignedInText": "(ви не ввійшли)", + "notUsingAccountText": "Примітка: ти не підключив акаунт ${SERVICE}.\nПерейди у 'Акаунт -> Увійти за допомогою ${SERVICE}', якщо ти хочеш його використовувати.", + "nothingIsSelectedErrorText": "Нічого не вибрано!", + "numberText": "#${NUMBER}", + "offText": "Викл", + "okText": "Ок", + "onText": "Вкл", + "oneMomentText": "Хвилинку...", + "onslaughtRespawnText": "${PLAYER} відродиться в ${WAVE} хвилі", + "orText": "${A} або ${B}", + "otherText": "Інші...", + "outOfText": "(${RANK} з ${ALL})", + "ownFlagAtYourBaseWarning": "Щоб набрати очки, ваш власний\nпрапор повинен бути на вашій базі!", + "packageModsEnabledErrorText": "Мережева гра заборонена коли включені моди локального пакета (див. Налаштування->Додатково)", + "partyWindow": { + "chatMessageText": "Повідомлення чату", + "emptyText": "Ваше лобі порожнє", + "hostText": "(хост)", + "sendText": "Відправити", + "titleText": "Ваше лобі" + }, + "pausedByHostText": "(зупинено хостом)", + "perfectWaveText": "Ідеальна хвиля!", + "pickUpText": "Підняти", + "playModes": { + "coopText": "Кооператив", + "freeForAllText": "Кожен сам за себе", + "multiTeamText": "Мультикомандний", + "singlePlayerCoopText": "Самітня гра / Кооператив", + "teamsText": "Команди" + }, + "playText": "Грати", + "playWindow": { + "oneToFourPlayersText": "1-4 гравця", + "titleText": "Грати", + "twoToEightPlayersText": "2-8 гравців" + }, + "playerCountAbbreviatedText": "${COUNT}г", + "playerDelayedJoinText": "${PLAYER} приєднається в наступному раунді.", + "playerInfoText": "Про Гравця", + "playerLeftText": "${PLAYER} покинув гру.", + "playerLimitReachedText": "Досягнуто ліміт ${COUNT} гравців. Більше додати не можна.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Ви не можете видалити профіль акаунта.", + "deleteButtonText": "Видалити\nпрофіль", + "deleteConfirmText": "Видалити '${PROFILE}'?", + "editButtonText": "Змінити\nпрофіль", + "explanationText": "(налаштовуйте імена і зовнішній вигляд гравця)", + "newButtonText": "Новий\nпрофіль", + "titleText": "Профілі гравців" + }, + "playerText": "Гравець", + "playlistNoValidGamesErrorText": "Цей плейлист містить невідкриті ігри.", + "playlistNotFoundText": "Плейлист не знайдено", + "playlistText": "Плейлист", + "playlistsText": "Плейлисти", + "pleaseRateText": "Якщо вам подобається гра ${APP_NAME}, будь ласка, подумайте про те,\nщоб оцінити її або написати рецензію. Це забезпечує корисну\nзворотний зв'язок і допомагає підтримати подальшу розробку.\n\nДякуємо!\n-Ерік", + "pleaseWaitText": "Будь ласка зачекайте...", + "pluginClassLoadErrorText": "Помилка завантаження класу плагіна \"${PLUGIN}\": ${ERROR}", + "pluginInitErrorText": "Помилка запуску плагіна \"${PLUGIN}\": ${ERROR}", + "pluginSettingsText": "Налаштування плагінів", + "pluginsAutoEnableNewText": "Автоматично вмикати нові плагіни", + "pluginsDetectedText": "Виявлено нові плагіни. Перезапустіть, щоб активувати їх, або налаштуйте їх у налаштуваннях", + "pluginsDisableAllText": "Вимкнути усі плагіни", + "pluginsEnableAllText": "Увімкнути усі плагіни", + "pluginsRemovedText": "${NUM} плагін(ів) більше не знайдено.", + "pluginsText": "Плагіни", + "practiceText": "Тренування", + "pressAnyButtonPlayAgainText": "Натисніть будь-яку кнопку щоб грати знову...", + "pressAnyButtonText": "Натисніть будь-яку кнопку щоб продовжити...", + "pressAnyButtonToJoinText": "натисніть будь-яку кнопку щоб приєднатися...", + "pressAnyKeyButtonPlayAgainText": "Натисніть будь-яку клавішу/кнопку щоб грати знову...", + "pressAnyKeyButtonText": "Натисніть будь-яку клавішу/кнопку щоб продовжити...", + "pressAnyKeyText": "Натисніть будь-яку клавішу...", + "pressJumpToFlyText": "** Щоб летіти, продовжуйте натискати стрибок **", + "pressPunchToJoinText": "натисніть УДАР щоб приєднатися...", + "pressToOverrideCharacterText": "натисніть ${BUTTONS} щоб перевизначити свого персонажа", + "pressToSelectProfileText": "натисніть ${BUTTONS} щоб вибрати гравця", + "pressToSelectTeamText": "натисніть ${BUTTONS} щоб вибрати команду", + "promoCodeWindow": { + "codeText": "Код", + "enterText": "Відправити" + }, + "promoSubmitErrorText": "Помилка відправки коду, перевірте своє інтернет-з'єднання", + "ps3ControllersWindow": { + "macInstructionsText": "Вимкніть живлення на задній панелі PS3, переконайтеся, що Bluetooth\nвключений на вашому комп'ютері, а потім підключіть контролер до Mac\nза допомогою кабелю USB для синхронізації. Тепер можна використовувати\nкнопку контролера 'PS' щоб підключити його до Mac\nв дротовому (USB) або бездротовому (Bluetooth) режимі.\n\nНа деяких Mac при синхронізації може знадобитися введення пароля.\nВ цьому випадку зверніться до наступної інструкції або до Google.\n\n\n\n\nКонтролери PS3, пов'язані по бездротовій мережі, повинні з'явитися\nв списку пристроїв в Налаштуваннях системи->Bluetooth. Можливо, \nвам доведеться видалити їх з цього списку, якщо ви хочете знову \nвикористовувати їх з PS3.\n\nТакож завжди відключайте їх від Bluetooth, коли він не використовується,\nінакше будуть розряджатися батарейки.\n\nBluetooth повинен обробляти до 7 підключених пристроїв,\nхоча у вас може вийти по-іншому.", + "ouyaInstructionsText": "Щоб використовувати контролер PS3 з OUYA, просто підключіть його один раз\nза допомогою кабелю USB для синхронізації. Це може відключити інші\nконтролери, тоді потрібно перезавантажити OUYA і від'єднати кабель USB.\n\nПісля цього можна використовувати кнопку 'PS' контролера для бездротового\nпідключення. Після гри натисніть і утримуйте кнопку 'PS' протягом\n10 секунд щоб вимкнути контролер, в іншому випадку він може\nзалишитися включеним і розрядить батарейки.", + "pairingTutorialText": "відео-інструкції по синхронізації", + "titleText": "Використання контролерів PS3 з ${APP_NAME}:" + }, + "punchBoldText": "УДАР", + "punchText": "Вдарити", + "purchaseForText": "Купити за ${PRICE}", + "purchaseGameText": "Купити гру", + "purchasingText": "Покупка...", + "quitGameText": "Вийти з ${APP_NAME}?", + "quittingIn5SecondsText": "Вихід через 5 секунд...", + "randomPlayerNamesText": "Петро, Василь, Микола, Дацюк, Андрюха, Козак, Сашка, Володька, Вітальон, Сака, Пупчик, Олька", + "randomText": "Випадковий", + "rankText": "Ранг", + "ratingText": "Рейтинг", + "reachWave2Text": "Досягніть другої хвилі, щоб отримати ранг.", + "readyText": "готовий", + "recentText": "останній", + "remoteAppInfoShortText": "Грати в ${APP_NAME} з сім'єю або друзями набагато веселіше.\nПідключіть один або кілька контролерів або встановіть\n${REMOTE_APP_NAME} на свої пристрої, щоб використовувати\nїх в якості контролерів.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Положення кнопки", + "button_size": "Розмір кнопки", + "cant_resolve_host": "Сервер не знайдений.", + "capturing": "Слухаю...", + "connected": "Пов'язано.", + "description": "Використовуйте Ваш телефон або планшет як контролер BombSquad.\nДо 8 пристроїв можуть бути одночасно підключені для епічних битв в мультиплеєрі на одному TV або планшеті.", + "disconnected": "Викинутий сервером.", + "dpad_fixed": "нерухомий", + "dpad_floating": "плаваючий", + "dpad_position": "Розташування D-Pad", + "dpad_size": "Розмір D-Pad", + "dpad_type": "Тип D-Pad", + "enter_an_address": "Введіть адресу", + "game_full": "Кімната заповнена або з'єднання не приймаються.", + "game_shut_down": "Сервер відключився.", + "hardware_buttons": "Апаратні кнопки.", + "join_by_address": "Приєднатися за адресою...", + "lag": "Лаг: ${SECONDS} секунд", + "reset": "Скидання", + "run1": "Біг 1", + "run2": "Біг 2", + "searching": "Шукаємо ігри BombSquad...", + "searching_caption": "Натисніть на назву гри для входу.\nПереконайтеся, що ви перебуваєте в тій же мережі, що і гра.", + "start": "Старт", + "version_mismatch": "Розбіжність версій.\nПереконайтеся, що BombSquad і контролер BombSquad Remote\nоновлені до останньої версії і спробуйте ще раз." + }, + "removeInGameAdsText": "Розблокуйте \"${PRO}\" в магазині, щоб прибрати рекламу в грі.", + "renameText": "Перейменувати", + "replayEndText": "Завершити перегляд повтору", + "replayNameDefaultText": "Повтор останньої гри", + "replayReadErrorText": "Помилка читання файлу повтору.", + "replayRenameWarningText": "Перейменуйте повтор \"${REPLAY}\" щоб його зберегти; інакше він буде переписаний.", + "replayVersionErrorText": "На жаль, цей повтор було зроблено в інший\nверсії гри і не може бути використана.", + "replayWatchText": "Дивитися повтор", + "replayWriteErrorText": "Помилка запису файлу повтору.", + "replaysText": "Повтори", + "reportPlayerExplanationText": "Поскаржіться за цією адресою на чітера, грубіяна або того хто погано поводиться.\nОпишіть чим ви незадоволені:", + "reportThisPlayerCheatingText": "Нечесний гравець", + "reportThisPlayerLanguageText": "Грубіян", + "reportThisPlayerReasonText": "На що хочете поскаржитися?", + "reportThisPlayerText": "Скарга на Гравця", + "requestingText": "Запит даних...", + "restartText": "Почати заново", + "retryText": "Повтор", + "revertText": "Відновити", + "runText": "Бігти", + "saveText": "Зберегти", + "scanScriptsErrorText": "Помилка(и) сканування скриптів; дивіться лог для деталей.", + "scoreChallengesText": "Медалі за очки", + "scoreListUnavailableText": "Список очок недоступний.", + "scoreText": "Очки", + "scoreUnits": { + "millisecondsText": "Мілісекунди", + "pointsText": "Бали", + "secondsText": "Секунди" + }, + "scoreWasText": "(було ${COUNT})", + "selectText": "Вибрати", + "seriesWinLine1PlayerText": "ПЕРЕМІГ У", + "seriesWinLine1TeamText": "ПЕРЕМОГЛИ У", + "seriesWinLine1Text": "ПЕРЕМІГ У", + "seriesWinLine2Text": "СЕРІЇ!", + "settingsWindow": { + "accountText": "Акаунт", + "advancedText": "Додатково", + "audioText": "Аудіо", + "controllersText": "Контролери", + "graphicsText": "Графіка", + "playerProfilesMovedText": "Примітка: Користувачі гравців були переміщені у вікно Акаунти в головному меню.", + "titleText": "Налаштування" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(проста, зручна для контролера віртуальна клавіатура для введення тексту)", + "alwaysUseInternalKeyboardText": "Завжди використовувати вбудовану клавіатуру", + "benchmarksText": "Тест продуктивності і навантаження", + "disableCameraGyroscopeMotionText": "Вимкнути Рух Гіроскопу Камери", + "disableCameraShakeText": "Вимкнути Тремтіння Камери", + "disableThisNotice": "(ви можете відключити це повідомлення в налаштуваннях)", + "enablePackageModsDescriptionText": "(включає додаткові можливості для модінгу, але відключає мережеву гру)", + "enablePackageModsText": "Включити моди локального пакета", + "enterPromoCodeText": "Ввести код", + "forTestingText": "Примітка: ці значення використовуються тільки для тестування і будуть втрачені, коли додаток завершить роботу.", + "helpTranslateText": "Переклади гри ${APP_NAME} з англійської зроблені спільнотою. \nЯкщо ви хочете запропонувати або виправити переклад, \nПерейдіть за посиланню нижче. Заздалегідь дякую!", + "kickIdlePlayersText": "Викидати неактивних гравців", + "kidFriendlyModeText": "Сімейний режим (менше насильства, і т.д.)", + "languageText": "Мова", + "moddingGuideText": "Інструкція по модінгу", + "mustRestartText": "Необхідно перезапустити гру, щоб зміни вступили в силу.", + "netTestingText": "Тестування мережі", + "resetText": "Скинути", + "showBombTrajectoriesText": "Показувати траєкторію бомби", + "showInGamePingText": "Показувати пінг у грі", + "showPlayerNamesText": "Показувати імена гравців", + "showUserModsText": "Показати теку модів", + "titleText": "Додатково", + "translationEditorButtonText": "Редактор перекладу ${APP_NAME}", + "translationFetchErrorText": "статус перекладу недоступний", + "translationFetchingStatusText": "перевірка статусу перекладу...", + "translationInformMe": "Повідомляйте мене, коли моя мова потребує оновлення", + "translationNoUpdateNeededText": "дана мова повністю оновлена, ура!", + "translationUpdateNeededText": "** дана мова потребує оновлення!! **", + "vrTestingText": "Тестування VR" + }, + "shareText": "Поділитися", + "sharingText": "Ділимося...", + "showText": "Показати", + "signInForPromoCodeText": "Ви повинні увійти, для активації коду.", + "signInWithGameCenterText": "Щоб використовувати аккаунт GameCenter,\nувійдіть через GameCenter.", + "singleGamePlaylistNameText": "Просто ${GAME}", + "singlePlayerCountText": "1 гравець", + "soloNameFilterText": "${NAME} соло", + "soundtrackTypeNames": { + "CharSelect": "Вибір персонажа", + "Chosen One": "Обраний", + "Epic": "Ігри в епічному режимі", + "Epic Race": "Епічна гонка", + "FlagCatcher": "Захоплення прапору", + "Flying": "Щасливі думки", + "Football": "Регбі", + "ForwardMarch": "Напад", + "GrandRomp": "Завоювання", + "Hockey": "Хокей", + "Keep Away": "Не підходити!", + "Marching": "Маневр", + "Menu": "Головне меню", + "Onslaught": "Атака", + "Race": "Гонка", + "Scary": "Король гори", + "Scores": "Результати", + "Survival": "Ліквідація", + "ToTheDeath": "Смертельний бій", + "Victory": "Табло фінального рахунку" + }, + "spaceKeyText": "пробіл", + "statsText": "Статистика", + "storagePermissionAccessText": "Це вимагає доступу до сховища", + "store": { + "alreadyOwnText": "У вас вже є ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• Прибирає рекламу\n• Відкриє міні-ігри\n• Також включає:", + "buyText": "Купити", + "charactersText": "Персонажі", + "comingSoonText": "Скоро в ефірі...", + "extrasText": "Додатково", + "freeBombSquadProText": "BombSquad тепер безкоштовна гра, але якщо ви придбали її раніше, то ви\nотримуєте оновлення BombSquad Pro і ${COUNT} квитків в якості подяки.\nНасолоджуйтесь новими можливостями, і спасибі за вашу підтримку!\n-Ерік", + "holidaySpecialText": "Святкова акція", + "howToSwitchCharactersText": "(зайдіть в \"${SETTINGS} -> ${PLAYER_PROFILES}\", щоб вибрати і змінити персонажів)", + "howToUseIconsText": "(створіть глобальні профілі гравців (у вікні акаунт) щоб використовувати це)", + "howToUseMapsText": "(використовуйте ці карти в ваших власних командних/всі-проти-всіх плейлистах)", + "iconsText": "Іконки", + "loadErrorText": "Неможливо завантажити сторінку.\nПеревірте з'єднання з Інтернетом.", + "loadingText": "завантаження", + "mapsText": "Карти", + "miniGamesText": "Міні-ігри", + "oneTimeOnlyText": "(тільки один раз)", + "purchaseAlreadyInProgressText": "Ця покупка вже виконується.", + "purchaseConfirmText": "Купити ${ITEM}?", + "purchaseNotValidError": "Купівля недійсна.\nЯкщо це помилка, зверніться до ${EMAIL}.", + "purchaseText": "Купити", + "saleBundleText": "Розпродаж в комплекті!", + "saleExclaimText": "Розпродаж!", + "salePercentText": "(Знижка ${PERCENT}%)", + "saleText": "ЗНИЖКА", + "searchText": "Пошук", + "teamsFreeForAllGamesText": "Командні ігри / Кожен сам за себе", + "totalWorthText": "*** ${TOTAL_WORTH} значення! ***", + "upgradeQuestionText": "Оновити?", + "winterSpecialText": "Зимова акція", + "youOwnThisText": "- у вас це вже є -" + }, + "storeDescriptionText": "Ігрове безумство з 8 гравцями!\n\nПідривайте своїх друзів (або ботів) в турнірі вибухових міні-ігор, таких як Захоплення прапора і Епічний смертельний бій уповільненої дії!\n\nЗ простим управлінням і розширеною підтримкою контролерів 8 осіб можуть приєднатися до гри, можна навіть використовувати мобільні пристрої як контролери через безкоштовний додаток 'BombSquad Remote'!\n\nДо бою!\n\nДив. www.froemling.net/BombSquad для додаткової інформації.", + "storeDescriptions": { + "blowUpYourFriendsText": "Підірви друзів.", + "competeInMiniGamesText": "Змагайтесь в міні-іграх від гонок до левітації.", + "customize2Text": "Налаштування персонажів, міні-ігор і навіть саундтрека.", + "customizeText": "Налаштування персонажів і створення своїх власних плейлистів міні-ігор.", + "sportsMoreFunText": "Спорт веселіший з вибухівкою.", + "teamUpAgainstComputerText": "Команда проти комп'ютера." + }, + "storeText": "Магазин", + "submitText": "Відправити", + "submittingPromoCodeText": "Активація коду...", + "teamNamesColorText": "імена/кольори команд", + "telnetAccessGrantedText": "Доступ Telnet включений.", + "telnetAccessText": "Виявлено доступ Telnet. Дозволити?", + "testBuildErrorText": "Ця версія застаріла, будь ласка, перевірте оновлення.", + "testBuildText": "Тестова версія", + "testBuildValidateErrorText": "Не вдається перевірити тестову збірку. (немає з'єднання з мережею?)", + "testBuildValidatedText": "Тестова збірка перевірена. Насолоджуйтесь!", + "thankYouText": "Дякую за вашу підтримку! Веселої гри!!", + "threeKillText": "ТРЬОХ ЗА РАЗ!!", + "timeBonusText": "Бонус часу", + "timeElapsedText": "Пройшло часу", + "timeExpiredText": "Час вийшов", + "timeSuffixDaysText": "${COUNT}д", + "timeSuffixHoursText": "${COUNT}г", + "timeSuffixMinutesText": "${COUNT}х", + "timeSuffixSecondsText": "${COUNT}с", + "tipText": "Підказка", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Топ друзів", + "tournamentCheckingStateText": "Перевірка статусу турніру, будь ласка, зачекайте...", + "tournamentEndedText": "Турнір закінчився. Скоро почнеться новий.", + "tournamentEntryText": "Вхід в турнір", + "tournamentResultsRecentText": "Останні Результати турніру", + "tournamentStandingsText": "Позиції в турнірі", + "tournamentText": "Турнір", + "tournamentTimeExpiredText": "Час турніру минув", + "tournamentsDisabledWorkspaceText": "Турніри вимкнені, коли робочі області активні.\n Щоб знову ввімкнути турніри, вимкніть робочу область і перезапустіть.", + "tournamentsText": "Турніри", + "translations": { + "characterNames": { + "Agent Johnson": "Агент Джонсон", + "B-9000": "B-9000", + "Bernard": "Бернард", + "Bones": "Кістячок", + "Butch": "Силач", + "Easter Bunny": "Великодній Кролик", + "Flopsy": "Флопс", + "Frosty": "Морозний", + "Gretel": "Гретель", + "Grumbledorf": "Грамблдорф", + "Jack Morgan": "Джек Морган", + "Kronk": "Кронк", + "Lee": "Лі", + "Lucky": "Щасливчик", + "Mel": "Мел", + "Middle-Man": "Середняк", + "Minimus": "Мінімус", + "Pascal": "Паскаль", + "Pixel": "Піксель", + "Sammy Slam": "Семі Слем", + "Santa Claus": "Санта Клаус", + "Snake Shadow": "Тінь Змії", + "Spaz": "Спаз", + "Taobao Mascot": "Талісман Таобао", + "Todd McBurton": "Тод МакБартон", + "Zoe": "Зої", + "Zola": "Зола" + }, + "coopLevelNames": { + "${GAME} Training": "Тренування ${GAME}", + "Infinite ${GAME}": "Нескінченний рівень ${GAME}", + "Infinite Onslaught": "Нескінченна атака", + "Infinite Runaround": "Нескінченний маневр", + "Onslaught Training": "Атака: тренування", + "Pro ${GAME}": "${GAME} Про", + "Pro Football": "Регбі профі", + "Pro Onslaught": "Атака профі", + "Pro Runaround": "Маневр профі", + "Rookie ${GAME}": "${GAME} для новачків", + "Rookie Football": "Регбі для новачків", + "Rookie Onslaught": "Атака для новачків", + "The Last Stand": "Останній рубіж", + "Uber ${GAME}": "Убер ${GAME}", + "Uber Football": "Убер регбі", + "Uber Onslaught": "Убер атака", + "Uber Runaround": "Убер маневр" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Щоб перемогти, стань обраним на деякий час.\nЩоб стати обраним, вбий обраного.", + "Bomb as many targets as you can.": "Підірвіть стільки мішеней, скільки зможете.", + "Carry the flag for ${ARG1} seconds.": "Проносіть прапор протягом ${ARG1} секунд.", + "Carry the flag for a set length of time.": "Проносіть прапор протягом заданого часу.", + "Crush ${ARG1} of your enemies.": "Розбийте ${ARG1} ворогів.", + "Defeat all enemies.": "Переможіть всіх ворогів.", + "Dodge the falling bombs.": "Ухиліться від падаючих бомб.", + "Final glorious epic slow motion battle to the death.": "Фінальна епічна смертельна битва уповільненої дії.", + "Gather eggs!": "Зберіть яйця!", + "Get the flag to the enemy end zone.": "Віднесіть прапор в зону захисту супротивника.", + "How fast can you defeat the ninjas?": "Як швидко ви зможете перемогти ніндзя?", + "Kill a set number of enemies to win.": "Вбийте заданий число ворогів, щоб виграти.", + "Last one standing wins.": "Перемагає останній стоячий на ногах.", + "Last remaining alive wins.": "Перемагає останній живий.", + "Last team standing wins.": "Перемагає остання стояща на ногах команда.", + "Prevent enemies from reaching the exit.": "Не дайте ворогам дійти до виходу.", + "Reach the enemy flag to score.": "Доберіться до ворожого прапора щоб набрати очки.", + "Return the enemy flag to score.": "Принесіть ворожий прапор на базу, щоб набрати очки.", + "Run ${ARG1} laps.": "Пробіжіть кіл: ${ARG1}.", + "Run ${ARG1} laps. Your entire team has to finish.": "Пробіжіть кіл: ${ARG1}. Фінішувати повинна вся команда.", + "Run 1 lap.": "Пробіжіть 1 коло.", + "Run 1 lap. Your entire team has to finish.": "Пробіжіть 1 коло. Фінішувати повинна вся команда.", + "Run real fast!": "Біжіть дуже швидко!", + "Score ${ARG1} goals.": "Забийте голів: ${ARG1}.", + "Score ${ARG1} touchdowns.": "Зробіть тачдаунів: ${ARG1}.", + "Score a goal.": "Забийте гол.", + "Score a touchdown.": "Зробіть тачдаун.", + "Score some goals.": "Забийте кілька голів.", + "Secure all ${ARG1} flags.": "Захопіть всі прапори: ${ARG1}.", + "Secure all flags on the map to win.": "Захопіть всі прапори на карті, щоб виграти.", + "Secure the flag for ${ARG1} seconds.": "захопіть прапор на ${ARG1} секунд.", + "Secure the flag for a set length of time.": "Захопіть прапор на певний час.", + "Steal the enemy flag ${ARG1} times.": "Вкрадіть ворожий прапор ${ARG1} раз.", + "Steal the enemy flag.": "Вкрадіть ворожий прапор.", + "There can be only one.": "Може бути тільки один.", + "Touch the enemy flag ${ARG1} times.": "Торкніться ворожого прапора ${ARG1} раз.", + "Touch the enemy flag.": "Торкніться ворожого прапора.", + "carry the flag for ${ARG1} seconds": "проносіть прапор протягом ${ARG1} секунд", + "kill ${ARG1} enemies": "Вбийте ${ARG1} ворогів", + "last one standing wins": "перемагає останній стоячий на ногах", + "last team standing wins": "перемагає остання стояща на ногах команда", + "return ${ARG1} flags": "принесіть ${ARG1} прапорів на базу", + "return 1 flag": "принесіть 1 прапор на базу", + "run ${ARG1} laps": "пробіжіть кіл: ${ARG1}", + "run 1 lap": "пробіжіть 1 коло", + "score ${ARG1} goals": "забийте голів: ${ARG1}", + "score ${ARG1} touchdowns": "зробіть тачдаунів: ${ARG1}", + "score a goal": "забийте гол", + "score a touchdown": "зробіть тачдаун", + "secure all ${ARG1} flags": "захопіть всі прапори: ${ARG1}", + "secure the flag for ${ARG1} seconds": "захопіть прапор на ${ARG1} секунд", + "touch ${ARG1} flags": "торкніться прапорів: ${ARG1}", + "touch 1 flag": "торкніться 1 прапора" + }, + "gameNames": { + "Assault": "Напад", + "Capture the Flag": "Захоплення прапору", + "Chosen One": "Обраний", + "Conquest": "Завоювання", + "Death Match": "Смертельний бій", + "Easter Egg Hunt": "Полювання на крашанки", + "Elimination": "Ліквідація", + "Football": "Регбі", + "Hockey": "Хокей", + "Keep Away": "Не підходити!", + "King of the Hill": "Король гори", + "Meteor Shower": "Метеоритний дощ", + "Ninja Fight": "Бій з ніндзя", + "Onslaught": "Атака", + "Race": "Гонка", + "Runaround": "Обхід", + "Target Practice": "Стрілянина по мішенях", + "The Last Stand": "Останній рубіж" + }, + "inputDeviceNames": { + "Keyboard": "Клавіатура", + "Keyboard P2": "Клавіатура P2" + }, + "languages": { + "Arabic": "Арабська", + "Belarussian": "Білоруська", + "Chinese": "Китайська", + "ChineseTraditional": "Китайська традиційна", + "Croatian": "Хорватська", + "Czech": "Чеська", + "Danish": "Данська", + "Dutch": "Голландська", + "English": "Англійська", + "Esperanto": "Есперанто", + "Filipino": "Філіппінський", + "Finnish": "Фінська", + "French": "Французька", + "German": "Німецька", + "Gibberish": "Гіберіш", + "Greek": "Грецький", + "Hindi": "Хінді", + "Hungarian": "Угорська", + "Indonesian": "Індонезійська", + "Italian": "Італійська", + "Japanese": "Японська", + "Korean": "Корейська", + "Malay": "Малайська", + "Persian": "Перська", + "Polish": "Польська", + "Portuguese": "Португальська", + "Romanian": "Румунська", + "Russian": "Російська", + "Serbian": "Сербська", + "Slovak": "Словацька", + "Spanish": "Іспанська", + "Swedish": "Шведська", + "Tamil": "тамільська", + "Thai": "Тайська", + "Turkish": "Турецька", + "Ukrainian": "Українська", + "Venetian": "Венеціанський", + "Vietnamese": "В'єьнамська" + }, + "leagueNames": { + "Bronze": "Бронзова", + "Diamond": "Діамантова", + "Gold": "Золота", + "Silver": "Срібна" + }, + "mapsNames": { + "Big G": "Велика G", + "Bridgit": "Містки", + "Courtyard": "Внутрішній двір", + "Crag Castle": "Замок на скелі", + "Doom Shroom": "Фатальний гриб", + "Football Stadium": "Стадіон регбі", + "Happy Thoughts": "Щасливі думки", + "Hockey Stadium": "Хокейний стадіон", + "Lake Frigid": "Крижане озеро", + "Monkey Face": "Мавпа", + "Rampage": "Беззаконня", + "Roundabout": "Кільцева", + "Step Right Up": "Проходьте", + "The Pad": "Подушка", + "Tip Top": "Тіп-Топ", + "Tower D": "Вежа D", + "Zigzag": "Зигзаг" + }, + "playlistNames": { + "Just Epic": "Тільки епічний", + "Just Sports": "Тільки спорт" + }, + "scoreNames": { + "Flags": "Прапори", + "Goals": "Голи", + "Score": "Очки", + "Survived": "Вижив", + "Time": "Час", + "Time Held": "Час утримання" + }, + "serverResponses": { + "A code has already been used on this account.": "Код вже був активований на цьому акаунті.", + "A reward has already been given for that address.": "Ця нагорода вже була видана на цей ip адреса", + "Account linking successful!": "Акаунт успішно прив'язаний!", + "Account unlinking successful!": "Акаунт роз'єднаному успішно!", + "Accounts are already linked.": "Акаунти вже прив'язані.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Не вдалося перевірити перегляд оголошення. \nБудь ласка, переконайтеся, що у вас запущена офіційна та остання версія гри.", + "An error has occurred; (${ERROR})": "Сталася помилка; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Сталася помилка; будь ласка, зв'яжіться зі службою підтримки (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Сталася помилка; будь ласка, зв'яжіться з support@froemling.net.", + "An error has occurred; please try again later.": "Сталася помилка, будь ласка, спробуйте ще раз пізніше.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Точно хочете зв'язати акаунти?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nЦе не може бути скасоване!", + "BombSquad Pro unlocked!": "BombSquad Pro розблоковано!", + "Can't link 2 accounts of this type.": "Неможливо зв'язати 2 акаунти цього типу.", + "Can't link 2 diamond league accounts.": "Неможливо зв'язати 2 акаунти діамантовою ліги.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Неможливо зв'язати; буде перевищено максимум ${COUNT} зв'язаних акаунтів.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Ах ти, чітер; Очки і нагороди заморожені на ${COUNT} днів.", + "Could not establish a secure connection.": "Не вдалося встановити безпечне з'єднання.", + "Daily maximum reached.": "Досить на сьогодні.", + "Entering tournament...": "Вхід в турнір...", + "Invalid code.": "Невірний код.", + "Invalid payment; purchase canceled.": "Щось пішло не так. Купівля скасована.", + "Invalid promo code.": "Невірний промокод.", + "Invalid purchase.": "Помилка транзакції.", + "Invalid tournament entry; score will be ignored.": "Невірна заявка на турнір; рахунок буде проігнорований.", + "Item unlocked!": "Предмет разблоковано!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "Об'єднання не дозволено. ${ACCOUNT} містить \nважливі дані і вони ВСІ ЗНИКНУТЬ.\nТи можеш об'єднанати у зворотньому порядку, якщо ти цього захочеш\n(І втратити дані ЦЬОГО акаунта)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Зв'язати ${ACCOUNT} акаунт з цим?\nВсі існуючі дані на ${ACCOUNT} будуть втрачені.\nЦя дія не може бути скасовано. Ви впевнені?", + "Max number of playlists reached.": "Досягнуто максимальну кількість плейлистів.", + "Max number of profiles reached.": "Максимальна кількість профілів досягнута.", + "Maximum friend code rewards reached.": "Досягнуто ліміт кодів", + "Message is too long.": "Повідомлення занадто довге.", + "No servers are available. Please try again soon.": "Немає доступних серверів. Будь ласка, поспробуйте пізніше.", + "Profile \"${NAME}\" upgraded successfully.": "Профіль \"${NAME}\" оновлений успішно.", + "Profile could not be upgraded.": "Профіль не може бути оновлений.", + "Purchase successful!": "Успішна транзакція!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Отримано ${COUNT} квитків за вхід.\nПриходьте завтра, щоб отримати ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Функціональність сервера більше не підтримується в цій версії гри;\nБудь ласка оновіть гру.", + "Sorry, there are no uses remaining on this code.": "Ой, код більше не може бути активований.", + "Sorry, this code has already been used.": "Ой, цей код вже використаний.", + "Sorry, this code has expired.": "Ой, час дії коду минув.", + "Sorry, this code only works for new accounts.": "Ой, цей код працює тільки для нових акаунтів.", + "Still searching for nearby servers; please try again soon.": "Все ще йде пошук сусідніх серверів; будь-ласка, спробуйте ще раз найближчим часом.", + "Temporarily unavailable; please try again later.": "Тимчасово недоступний; будь ласка, спробуйте ще раз пізніше.", + "The tournament ended before you finished.": "Турнір закінчився раніше, ніж ви закінчили.", + "This account cannot be unlinked for ${NUM} days.": "Цей обліковий запис неможливо відв'язати протягом ${NUM} днів.", + "This code cannot be used on the account that created it.": "Цей код не може бути використаний його творцем.", + "This is currently unavailable; please try again later.": "Це зараз не доступно; будь ласка, спробуйте ще раз пізніше.", + "This requires version ${VERSION} or newer.": "Для цього необхідна версія ${VERSION} або новіша.", + "Tournaments disabled due to rooted device.": "Турніри вимкнені через рутований пристрій.", + "Tournaments require ${VERSION} or newer": "Для турнірів потрібна версія ${VERSION} або вище.", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Відв'язати ${ACCOUNT} від цього акаунта?\nВсі дані на ${ACCOUNT} будуть скинуті.\n(За винятком досягнень в деяких випадках)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "ПОПЕРЕДЖЕННЯ: скарги на хакерство були видані на ваш обліковий запис.\nОблікові записи, які вважаються зламаними, будуть заблоковані. Будь ласка, грайте чесно.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Бажаєте пов'язати обліковий запис пристрою з цим?\n\nАкаунт пристрою ${ACCOUNT1}\nПоточний акаунт ${ACCOUNT2}\n\nЦе дозволить зберегти ваші нинішні досягнення.\nУвага: скасування неможлива!", + "You already own this!": "Ви це вже придбали!", + "You can join in ${COUNT} seconds.": "Ти зможеш увійти через ${COUNT} секунд", + "You don't have enough tickets for this!": "У вас недостатньо квитків для цієї покупки!", + "You don't own that.": "Вам це не належить", + "You got ${COUNT} tickets!": "Ви отримали ${COUNT} квитків!", + "You got a ${ITEM}!": "Ви отримали ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Вас підвищили і перевели в нову лігу; вітаємо!", + "You must update to a newer version of the app to do this.": "Щоб це зробити, ви повинні оновити додаток.", + "You must update to the newest version of the game to do this.": "Ви повинні оновитися до нової версії гри, щоб зробити це.", + "You must wait a few seconds before entering a new code.": "Зачекайте кілька секунд, перш ніж вводити новий код.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Ваш ранг в останньому турнірі: ${RANK}! Дякуємо за гру!", + "Your account was rejected. Are you signed in?": "Вашу обліковку відхилено. Ви ввійшли?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ваша версія гри була модифікована.\nПриберіть всі зміни і спробуйте знову", + "Your friend code was used by ${ACCOUNT}": "Ваш код був використаний ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 хвилина", + "1 Second": "1 секунда", + "10 Minutes": "10 хвилин", + "2 Minutes": "2 хвилини", + "2 Seconds": "2 секунди", + "20 Minutes": "20 хвилин", + "4 Seconds": "4 секунди", + "5 Minutes": "5 хвилин", + "8 Seconds": "8 секунд", + "Allow Negative Scores": "Дозволити негативний рахунок", + "Balance Total Lives": "Розподіляти всі життя", + "Bomb Spawning": "Поява бомб", + "Chosen One Gets Gloves": "Обраний отримує рукавички", + "Chosen One Gets Shield": "Обраний отримує щит", + "Chosen One Time": "Час обраного", + "Enable Impact Bombs": "Включити розривні бомби", + "Enable Triple Bombs": "Включити потрійні бомби", + "Entire Team Must Finish": "Вся команда повинна фінішувати", + "Epic Mode": "Епічний режим", + "Flag Idle Return Time": "Час повернення кинутого прапора", + "Flag Touch Return Time": "Час захоплення прапора", + "Hold Time": "Час утримання", + "Kills to Win Per Player": "Вбивств що перемогти", + "Laps": "Кола", + "Lives Per Player": "Життів на гравця", + "Long": "Довго", + "Longer": "Довше", + "Mine Spawning": "Мінування", + "No Mines": "Без мін", + "None": "Немає", + "Normal": "Нормальний", + "Pro Mode": "Професійний режим", + "Respawn Times": "Час до воскресіння", + "Score to Win": "Очок для перемоги", + "Short": "Коротко", + "Shorter": "Коротше", + "Solo Mode": "Режим соло", + "Target Count": "Кількість цілей", + "Time Limit": "Ліміт часу" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} дискваліфікована бо ${PLAYER} вийшов", + "Killing ${NAME} for skipping part of the track!": "Ліквідація ${NAME} за зрізання траси!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Попередження для ${NAME}: турбо / спам-кнопок викидує вас." + }, + "teamNames": { + "Bad Guys": "Погані хлопці", + "Blue": "Сині", + "Good Guys": "Хороші хлопці", + "Red": "Червоні" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Своєчасна послідовність біг-стрибок-поворот-удар може вбити\nодним ударом і заробити вам довічну повагу друзів.", + "Always remember to floss.": "Не забувайте користуватися зубною ниткою.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Створіть профілі гравців для себе і своїх друзів з власними\nіменами і зовнішністю замість випадкових.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Ящики з прокляттям перетворюють вас в цокаючу бомбу.\nЄдині ліки - швидко схопити аптечку.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Незалежно від зовнішності, здатності всіх персонажів ідентичні,\nтак що просто вибирайте того, на кого ви більше схожі.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Не зазнавайстеся з цим енергетичним щитом, вас все ще можуть скинути з обриву.", + "Don't run all the time. Really. You will fall off cliffs.": "Не бігай весь час. Серйозно. Впадеш з обриву.", + "Don't spin for too long; you'll become dizzy and fall.": "Не крутись довго; у тебе закрутиться голова і ти впадеш.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Для бігу натисніть і тримайте будь-яку кнопку. (Для цього зручні тригери, якщо вони є)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Для бігу утримуйте будь-яку кнопку. Бігати, звичайно, швидше,\nзате важче повертати, так що не забувайте про обриви.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Крижані бомби не дуже потужні, але вони заморожують\nвсіх навколо, роблячи їх крихкими.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Якщо хтось вас схопив, бийте, і вас відпустять.\nУ реальному житті це теж працює.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Якщо вам не вистачає контролерів, встановіть програму '${REMOTE_APP_NAME}'\nна ваші мобільні пристрої, щоб використовувати їх в якості контролерів.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Якщо до вас прилипла липка бомба, стрибайте і крутитесь. може пощастить\nструсити бомбу або, на худий кінець, повеселити оточуючих.", + "If you kill an enemy in one hit you get double points for it.": "Якщо вбиваєш ворога з одного удару, то отримуєш подвійні очки.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Якщо підхопили прокляття, то єдина надія на виживання\n- це знайти аптечку в найближчі кілька секунд.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Не стій на місці — підсмажижся. Біжи і ухилятися щоб вижити..", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Якщо у вас багато гравців, які приходять і йдуть, включіть \"автоматично викидати \nне активних гравців \"в налаштуваннях на випадок, якщо хтось забуде вийти з гри.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Якщо ваш пристрій нагрівається або ви хочете зберегти заряд батареї,\nзменшіть \"Візуальні ефекти\" або \"Розширення\" в Налаштуваннях->Графіка", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Якщо картинка переривчаста, спробуйте зменшити розширення\nабо візуальні ефекти в налаштуваннях графіки гри.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "У Захопленні прапору, щоб набрати очки, свій власний прапор повинен бути на базі.\nЯкщо інша команда ось-ось заб'є, можна вкрасти їх прапор, щоб їх зупинити.", + "In hockey, you'll maintain more speed if you turn gradually.": "У хокеї можна підтримувати більш високу швидкість, якщо повертати поступово.", + "It's easier to win with a friend or two helping.": "Виграти легше з допомогою одного або двох друзів.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Стрибни прямо перед кидком щоб закинути бомбу якомога вище.", + "Land-mines are a good way to stop speedy enemies.": "Міни - непоганий спосіб зупинити прудконогих ворогів.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Можна багато чого підняти і кинути, включаючи інших гравців. Жбурляння ворогів\nз обриву буває ефективною і підбадьорливою стратегією.", + "No, you can't get up on the ledge. You have to throw bombs.": "Ні, ви не зможете залізти на виступ. Кидайте бомби.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Гравці можуть приєднуватися і йти посеред гри,\nтакож можна підключати і відключати контролери прямо на льоту.", + "Practice using your momentum to throw bombs more accurately.": "Тренуйтеся використовувати інерцію для більш точних кидків.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Удари наносять більше шкоди, чим швидше рухаються кулаки,\nтак що намагайтеся бігати, стрибати і крутитися, як ненормальні.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Пробіжіться туди-назад перед кидком, щоб\n'підкрутити' бомбу і кинути її далі.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Зметіть групу ворогів, підірвавши\nбомбу біля коробки TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Голова - найвразливіше місце, так що липка бомба\nпо чайнику, як правило, означає капут.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Цей рівень безкінечний, але високі очки тут\nзароблять вам вічну пошану у всьому світі.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Сила кидка залежить від напрямку. Щоб акуратно кинути \nщось прямо перед собою, не натискайте ні в якому напрямку.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Набрид саундтрек? Замініть його власним!\nДивіться Налаштування->Аудіо->Саундтрек", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Спробуйте 'підігрівати' бомби секунду або дві, перш ніж їх кинути.", + "Try tricking enemies into killing eachother or running off cliffs.": "Спробуйте обдурити ворогів, щоб вони вбили один одного або стрибнули з обрива.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Використовуйте кнопку вибору (трикутник), щоб схопити прапор <${PICKUP}>", + "Whip back and forth to get more distance on your throws..": "Змахни туди-сюди, щоб закинути подалі..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Ви можете 'націлювати' удари, крутись вліво або вправо.\nЦе корисно для зіштовхування поганих хлопців з краю або для голів в хокеї.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Коли вибухне бомба можна визначити за кольором іскор гніту:\nжовтий..оранжевий..червоний..БАБАХ.", + "You can throw bombs higher if you jump just before throwing.": "Бомбу можна кинути вище, якщо підстрибнути прямо перед кидком.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Ви отримуєте пошкодження, коли вдаряється головою,\nтак що бережіть голову.", + "Your punches do much more damage if you are running or spinning.": "Від ударів набагато більше шкоди, коли біжиш або крутишся." + } + }, + "trophiesRequiredText": "Для цього треба мінімум ${NUMBER} трофеїв.", + "trophiesText": "Трофеїв", + "trophiesThisSeasonText": "Трофеї за цей Сезон", + "tutorial": { + "cpuBenchmarkText": "Прогін туторіала на шаленій швидкості (перевіряє швидкість процесора)", + "phrase01Text": "Привіт!", + "phrase02Text": "Ласкаво просимо до ${APP_NAME}!", + "phrase03Text": "Кілька порад з управління персонажем:", + "phrase04Text": "Багато чого в ${APP_NAME} базується на законах фізики.", + "phrase05Text": "Наприклад, при ударі кулаком..", + "phrase06Text": "..пошкодження залежать від швидкості кулака.", + "phrase07Text": "Бачите? Ми не рухалися, тому ${NAME} майже в повному порядку.", + "phrase08Text": "Тепер підстрибніть і крутаніться для швидкості.", + "phrase09Text": "Ага, так-то краще.", + "phrase10Text": "Також допомагає біг.", + "phrase11Text": "Для бігу утримуйте будь-яку кнопку.", + "phrase12Text": "Для супер-крутих ударів спробуйте бігти і крутитися.", + "phrase13Text": "Ой .. Вибач, ${NAME}.", + "phrase14Text": "Ви можете піднімати і кидати речі, наприклад прапори .. або ${NAME}.", + "phrase15Text": "І, зрештою, бомби.", + "phrase16Text": "Кидання бомб потребує тренування.", + "phrase17Text": "Ай! Не дуже хороший кидок.", + "phrase18Text": "У русі кинути виходить далі.", + "phrase19Text": "У стрибку кинути виходить вище.", + "phrase20Text": "\"Підкручені\" бомби летять ще далі.", + "phrase21Text": "\"Вичікування\" бомби робиться досить складно.", + "phrase22Text": "Чорт.", + "phrase23Text": "Спробуйте \"підігріти\" гніт секунду або дві.", + "phrase24Text": "Ура! Добре \"підігріто\".", + "phrase25Text": "Ну на цьому, мабуть, все.", + "phrase26Text": "Вперед, на міни!", + "phrase27Text": "Не забувай ці поради, і ТОЧНО повернешся живим!", + "phrase28Text": "...може бути...", + "phrase29Text": "Успіхів!", + "randomName1Text": "Петро", + "randomName2Text": "Вася", + "randomName3Text": "Микола", + "randomName4Text": "Ігор", + "randomName5Text": "Сашко", + "skipConfirmText": "Пропустити туторіал? Торкніться або натисніть кнопку для підтвердження.", + "skipVoteCountText": "${COUNT}/${TOTAL} голосів за пропуск", + "skippingText": "пропуск навчання ...", + "toSkipPressAnythingText": "(торкніться або натисніть що-небудь щоб пропустити туторіал)" + }, + "twoKillText": "ДВОХ ЗА РАЗ!", + "unavailableText": "недоступно", + "unconfiguredControllerDetectedText": "Виявлено налаштований контролер:", + "unlockThisInTheStoreText": "Це повинно бути розблоковано в магазині.", + "unlockThisProfilesText": "Щоб створити більш ${NUM} профіль, Вам необхідно:", + "unlockThisText": "Щоб розблокувати це, вам потрібно:", + "unsupportedHardwareText": "На жаль, це устаткування не підтримується в цій збірці гри.", + "upFirstText": "Для початку:", + "upNextText": "Далі в грі ${COUNT}:", + "updatingAccountText": "Оновлення вашого акаунту...", + "upgradeText": "Оновлення", + "upgradeToPlayText": "Розблокуйте \"${PRO}\" в магазині щоб грати в це.", + "useDefaultText": "Використовувати стандартні", + "usesExternalControllerText": "Ця гра може використовувати зовнішній контролер для управління.", + "usingItunesText": "Використання музикального додатку для саундтрека...", + "usingItunesTurnRepeatAndShuffleOnText": "Будь ласка, переконайтеся, що випадковий порядок і повтор усіх пісень включений в Itunes.", + "v2AccountLinkingInfoText": "Щоб підключити V2-акаунти, використовуйте кнопку 'Керування акаунтом'.", + "validatingTestBuildText": "Перевірка тестової збірки...", + "victoryText": "Перемога!", + "voteDelayText": "Ви зможете почати голосування через ${NUMBER} секунд", + "voteInProgressText": "Голосування ще триває.", + "votedAlreadyText": "Ви вже голосували", + "votesNeededText": "Потрібно ${NUMBER} голосів", + "vsText": "vs.", + "waitingForHostText": "(очікування ${HOST} щоб продовжити)", + "waitingForPlayersText": "очікування гравців для початку...", + "waitingInLineText": "Почекай трохи (кімната заповнена)...", + "watchAVideoText": "Дивитися відео", + "watchAnAdText": "Дивитись рекламу", + "watchWindow": { + "deleteConfirmText": "Видалити \"${REPLAY}\"?", + "deleteReplayButtonText": "Видалити\nповтор", + "myReplaysText": "Мої повтори", + "noReplaySelectedErrorText": "Повтор не обрано", + "playbackSpeedText": "Швидкість відтворення: ${SPEED}", + "renameReplayButtonText": "Перейменувати\nповтор", + "renameReplayText": "Перейменувати \"${REPLAY}\" на:", + "renameText": "Перейменувати", + "replayDeleteErrorText": "Помилка видалення повтору.", + "replayNameText": "Ім'я повтору", + "replayRenameErrorAlreadyExistsText": "Повтор з таким ім'ям вже існує.", + "replayRenameErrorInvalidName": "Неможливо перейменувати повтор; невірне ім'я.", + "replayRenameErrorText": "Помилка перейменування повтору.", + "sharedReplaysText": "Загальні повтори", + "titleText": "Дивитися", + "watchReplayButtonText": "Дивитися\nповтор" + }, + "waveText": "Хвиля", + "wellSureText": "Зійде!", + "whatIsThisText": "Шо це?", + "wiimoteLicenseWindow": { + "titleText": "Авторські права DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "Очікування контролерів Wii...", + "pressText": "Натисніть кнопки 1 та 2 на Wiimote одночасно.", + "pressText2": "На нових Wiimote з вбудованим Motion Plus натисніть червону кнопку 'sync' на задній частині." + }, + "wiimoteSetupWindow": { + "copyrightText": "Авторські права DarwiinRemote", + "listenText": "Слухати", + "macInstructionsText": "Переконайтеся, що ваш Wii вимкнений, а на вашому Mac включений\nBluetooth, потім натисніть 'Слухати'. Підтримка контролерів Wii\nбуває трохи примхлива, так що, можливо, доведеться\nспробувати кілька разів, поки вийде під'єднатися.\n\nBluetooth повинен обробляти до 7 підключених пристроїв,\nхоча всяке буває.\n\nBombSquad підтримує оригінальні контролери Wiimote,\nнунчаки і класичні контролери.\nТакож тепер працює і новий Wii Remote Plus,\nПравда, без аксесуарів.", + "macInstructionsTextScale": 0.7, + "thanksText": "Це стало можливим завдяки\nкоманді DarwiinRemote.", + "titleText": "Налаштування контролера Wii" + }, + "winsPlayerText": "Перемагає ${NAME}!", + "winsTeamText": "Перемогли ${NAME}!", + "winsText": "${NAME} виграє!", + "workspaceSyncErrorText": "Помилка синхронізації ${WORKSPACE}. Подробиці дивіться в журналі.", + "workspaceSyncReuseText": "Не вдається синхронізувати ${WORKSPACE}. Повторне використання попередньої синхронізованої версії.", + "worldScoresUnavailableText": "Світові результати недоступні.", + "worldsBestScoresText": "Кращі в світі результати", + "worldsBestTimesText": "Кращий світовий час", + "xbox360ControllersWindow": { + "getDriverText": "Завантажити драйвер", + "macInstructions2Text": "Для використання контролерів по бездротовому зв'язку, вам також\nбуде потрібно ресивер, який поставляється з \"бездротовим контролером\nXbox 360 для Windows\". Один ресивер дозволяє підключити до 4 контролерів.\n\nУвага: ресивери сторонніх виробників не будуть працювати з цим драйвером,\nпереконайтеся, що на вашому ресівері написано \"Microsoft\", а не \"XBOX 360\".\nMicrosoft більше не продає їх окремо, так що вам потрібно буде знайти\nресивер в комплекті з контролером, або шукати на ebay.\n\nЯкщо ви вважаєте це за необхідне, можете відправити грошей розробнику\nдрайвера на його сайті.", + "macInstructionsText": "Для використання контролерів Xbox 360 необхідно\nвстановити драйвер Mac, доступний за посиланням нижче.\nВін працює і з провідними і бездротовими контролерами.", + "ouyaInstructionsText": "Для використання провідних контролерів Xbox 360 в BombSquad,\nпросто підключіть їх до USB-порту вашого пристрою. для кількох\nконтролерів можна використовувати концентратор USB.\n\nДля використання бездротових контролерів вам знадобиться бездротовий\nресивер який поставляється в наборі \"бездротового контролера Xbox 360\nдля Windows \"або продається окремо. Кожен ресивер підключається\nдо порту USB і дозволяє підключати до 4 бездротових контролерів.", + "titleText": "Використання контролерів Xbox 360 в ${APP_NAME}:" + }, + "yesAllowText": "Так, дозволити!", + "yourBestScoresText": "Ваші кращі результати", + "yourBestTimesText": "Ваш кращий час" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/venetian.json b/dist/ba_data/data/languages/venetian.json new file mode 100644 index 0000000..d87d9a8 --- /dev/null +++ b/dist/ba_data/data/languages/venetian.json @@ -0,0 +1,1875 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "I nomi de i account no i połe miga ver rento emoji o altri caràtari spesiałi", + "accountsText": "Account", + "achievementProgressText": "Obietivi: ${COUNT} de ${TOTAL}", + "campaignProgressText": "Progreso canpagna [Defìsiłe]: ${PROGRESS}", + "changeOncePerSeason": "Te połi canbiar ’sto dato soło na volta par stajon.", + "changeOncePerSeasonError": "Par canbiarlo te ghè da spetar ła pròsema stajon (${NUM} days).", + "customName": "Nome parsonałizà", + "googlePlayGamesAccountSwitchText": "Se te vołi doparar un account Google defarente,\ndòpara l'apl Google Play Giochi par canbiarlo.", + "linkAccountsEnterCodeText": "Insarisi còdaze", + "linkAccountsGenerateCodeText": "Jènara còdaze", + "linkAccountsInfoText": "(sparpagna progresi infrà dispozidivi defarenti)", + "linkAccountsInstructionsNewText": "Par cołegar do account, jènara un còdaze inte'l primo\ndispozidivo e insarìseło inte’l segondo. I dati de’l\nsegondo account i vegnarà sparpagnài so tuti do i account\n(i dati de’l primo account i ndarà perdesti).\n\nTe połi cołegar fin a ${COUNT} account.\n\nINPORTANTE: cołega soło i account de to propiedà.\nSe te cołeghi account de calche to amigo, no sarè\npì boni de zugar online inte’l mèdemo momento.", + "linkAccountsText": "Cołega account", + "linkedAccountsText": "Account cołegài:", + "manageAccountText": "Jestisi account", + "nameChangeConfirm": "Vutu canbiar el nome de’l to account co ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Te si drio ełimenar i to progresi so ła modałidà\ncooparadiva e i to punteji łogałi (ma miga i to biłieti).\n’Sta asion no ła połe pì èsar anułada. Vutu ndar vanti?", + "resetProgressConfirmText": "Te si drio ełimenar i to progresi so ła\nmodałidà cooparadiva, i to obietivi e i to punteji\nłogałi (ma miga i to biłieti). ’Sta asion\nno ła połe pì èsar anułada. Vutu ndar vanti?", + "resetProgressText": "Ełìmena progresi", + "setAccountName": "Inposta un nome utente", + "setAccountNameDesc": "Sełesiona el nome da vizuałizar so’l to account.\nTe połi doparar el nome da uno de i to account\ncołegài o crear un nome parsonałizà ma ùnivogo.", + "signInInfoText": "Conétate par tirar sù biłieti, batajar online e\nsparpagnar i to progresi infrà dispozidivi defarenti.", + "signInText": "Conétate", + "signInWithDeviceInfoText": "(par 'sto dispozidivo ze disponìbiłe un soło account automàtego)", + "signInWithDeviceText": "Conétate co un account łogałe", + "signInWithGameCircleText": "Conétate co Game Circle", + "signInWithGooglePlayText": "Conétate co Google Play", + "signInWithTestAccountInfoText": "(account de proa vecio: in fuduro dòpara un account łogałe)", + "signInWithTestAccountText": "Conétate co un account de proa", + "signInWithV2InfoText": "(un account che fusiona so tute łe piataforme)", + "signInWithV2Text": "Acedi co un account BombSquad", + "signOutText": "Sortisi da l'account", + "signingInText": "Conesion in corso...", + "signingOutText": "Sortìa in corso...", + "ticketsText": "Biłieti: ${COUNT}", + "titleText": "Account", + "unlinkAccountsInstructionsText": "Sełesiona un account da descołegar", + "unlinkAccountsText": "Descołega account", + "v2LinkInstructionsText": "Acedi o dòpara 'sto link par crear un account.", + "viaAccount": "(doparando ${NAME})", + "youAreSignedInAsText": "Te zugarè cofà:" + }, + "achievementChallengesText": "Obietivi sfide", + "achievementText": "Obietivo", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Copa 3 cataràdeghi co ła TNT", + "descriptionComplete": "Copài co ła TNT 3 cataràdeghi", + "descriptionFull": "Copa 3 cataràdeghi co ła TNT so ${LEVEL}", + "descriptionFullComplete": "Copài co ła TNT 3 cataràdeghi so ${LEVEL}", + "name": "Parla ła dimanite: Boom!" + }, + "Boxer": { + "description": "Vinsi sensa doparar bonbe", + "descriptionComplete": "Vinsesto sensa doparar bonbe", + "descriptionFull": "Vinsi so ${LEVEL} sensa doparar bonbe", + "descriptionFullComplete": "Vinsesto so ${LEVEL} sensa doparar bonbe", + "name": "Boxador" + }, + "Dual Wielding": { + "descriptionFull": "Coneti 2 controładori (fìzeghi o apl)", + "descriptionFullComplete": "Conetesti 2 controładori (fìzeghi o apl)", + "name": "Tegnùa dupia" + }, + "Flawless Victory": { + "description": "Vinsi sensa èsar becà", + "descriptionComplete": "Vinsesto sensa èsar becà", + "descriptionFull": "Fenisi ${LEVEL} sensa mai èsar becà", + "descriptionFullComplete": "${LEVEL} fenìo sensa mai èsar becà", + "name": "Capoto!" + }, + "Free Loader": { + "descriptionFull": "Taca na partìa \"Tuti contro tuti\" co pì de 2 zugadori", + "descriptionFullComplete": "Partìa \"Tuti contro tuti\" co pì de 2 zugadori fata!", + "name": "Bote da orbi" + }, + "Gold Miner": { + "description": "Copa 6 cataràdeghi co łe mine", + "descriptionComplete": "6 cataràdeghi copài co łe mine", + "descriptionFull": "Copa 6 cataràdeghi co łe mine so ${LEVEL}", + "descriptionFullComplete": "6 cataràdeghi copài co łe mine so ${LEVEL}", + "name": "Mina-d’or" + }, + "Got the Moves": { + "description": "Vinsi sensa tirar crogni o bonbe", + "descriptionComplete": "Vinsesto sensa tirar crogni o bonbe", + "descriptionFull": "Vinsi so ${LEVEL} sensa tirar crogni o bonbe", + "descriptionFullComplete": "Vinsesto so ${LEVEL} sensa tirar crogni o bonbe", + "name": "Forest Gunp" + }, + "In Control": { + "descriptionFull": "Coneti un controłador (fìzego o apl)", + "descriptionFullComplete": "Controłador conetesto (fìzego o apl)", + "name": "Soto controło" + }, + "Last Stand God": { + "description": "Ingruma sù 1000 punti", + "descriptionComplete": "1000 punti ingrumài sù", + "descriptionFull": "Ingruma sù 1000 punti so ${LEVEL}", + "descriptionFullComplete": "1000 punti ingrumài sù so ${LEVEL}", + "name": "Łejenda de ${LEVEL}" + }, + "Last Stand Master": { + "description": "Ingruma sù 250 punti", + "descriptionComplete": "250 punti ingrumài sù", + "descriptionFull": "Ingruma sù 250 punti so ${LEVEL}", + "descriptionFullComplete": "250 punti ingrumài sù so ${LEVEL}", + "name": "Aso de ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Ingruma sù 500 punti", + "descriptionComplete": "500 punti ingrumài sù", + "descriptionFull": "Ingruma sù 500 punti so ${LEVEL}", + "descriptionFullComplete": "500 punti ingrumài sù so ${LEVEL}", + "name": "Mago de ${LEVEL}" + }, + "Mine Games": { + "description": "Copa co łe mine 3 cataràdeghi", + "descriptionComplete": "3 cataràdeghi copài co łe mine", + "descriptionFull": "Copa co łe mine 3 tacaràdeghi so ${LEVEL}", + "descriptionFullComplete": "3 cataràdeghi copài co łe mine so ${LEVEL}", + "name": "Canpo minà" + }, + "Off You Go Then": { + "description": "Trà zó da ła mapa 3 cataràdeghi", + "descriptionComplete": "Trato zó da ła mapa 3 cataràdeghi", + "descriptionFull": "Trà zó da ła mapa 3 cataràdeghi so ${LEVEL}", + "descriptionFullComplete": "Trato zó da ła mapa 3 cataràdeghi so ${LEVEL}", + "name": "Aerosaltador" + }, + "Onslaught God": { + "description": "Ingruma sù 5000 punti", + "descriptionComplete": "5000 punti ingrumài sù", + "descriptionFull": "Ingruma sù 5000 punti so ${LEVEL}", + "descriptionFullComplete": "5000 punti ingrumài sù so ${LEVEL}", + "name": "Łejenda de ${LEVEL}" + }, + "Onslaught Master": { + "description": "Ingruma sù 500 punti", + "descriptionComplete": "500 punti ingrumài sù", + "descriptionFull": "Ingruma sù 500 punti so ${LEVEL}", + "descriptionFullComplete": "500 punti ingrumài sù so ${LEVEL}", + "name": "Aso de ${LEVEL}" + }, + "Onslaught Training Victory": { + "description": "Fà fora tute łe ondàe", + "descriptionComplete": "Fazeste fora tute łe ondàe", + "descriptionFull": "Fà fora tute łe ondàe so ${LEVEL}", + "descriptionFullComplete": "Fazeste fora tute łe ondàe so ${LEVEL}", + "name": "Vitoria so ${LEVEL}" + }, + "Onslaught Wizard": { + "description": "Ingruma sù 1000 punti", + "descriptionComplete": "1000 punti ingrumài sù", + "descriptionFull": "Ingruma sù 1000 punti so ${LEVEL}", + "descriptionFullComplete": "1000 punti ingrumài sù so ${LEVEL}", + "name": "Mago de ${LEVEL}" + }, + "Precision Bombing": { + "description": "Vinsi sensa doparar potensiadori", + "descriptionComplete": "Vinsesto sensa doparar potensiadori", + "descriptionFull": "Vinsi so ${LEVEL} sensa doparar potensiadori", + "descriptionFullComplete": "Vinsesto so ${LEVEL} sensa doparar potensiadori", + "name": "Tirador de presizion" + }, + "Pro Boxer": { + "description": "Vinsi sensa doparar bonbe", + "descriptionComplete": "Vinsesto sensa doparar bonbe", + "descriptionFull": "Vinsi so ${LEVEL} sensa doparar bonbe", + "descriptionFullComplete": "Vinsesto so ${LEVEL} sensa doparar bonbe", + "name": "Boxador profesionałe" + }, + "Pro Football Shutout": { + "description": "Vinsi sensa łasar che i cataràdeghi i fasa punti", + "descriptionComplete": "Vinsesto sensa łasar che i cataràdeghi i fasa punti", + "descriptionFull": "Vinsi so ${LEVEL} sensa łasar che i cataràdeghi i fasa punti", + "descriptionFullComplete": "Vinsesto so ${LEVEL} sensa łasar che i cataràdeghi i fasa punti", + "name": "Vanpadora so ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Vinsi ła partìa", + "descriptionComplete": "Partìa vinsesta", + "descriptionFull": "Vinsi ła partìa so ${LEVEL}", + "descriptionFullComplete": "Partìa vinsesta so ${LEVEL}", + "name": "Vitoria so ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Fà fora tute łe ondàe", + "descriptionComplete": "Fazeste fora tute łe ondàe", + "descriptionFull": "Fà fora tute łe ondàe de ${LEVEL}", + "descriptionFullComplete": "Fazeste fora tute łe ondàe de ${LEVEL}", + "name": "Vitoria so ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Bloca tute łe ondàe", + "descriptionComplete": "Blocàe tute łe ondàe", + "descriptionFull": "Bloca tute łe ondàe so ${LEVEL}", + "descriptionFullComplete": "Blocàe tute łe ondàe so ${LEVEL}", + "name": "Vitoria so ${LEVEL}" + }, + "Rookie Football Shutout": { + "description": "Vinsi sensa łasar che i cataràdeghi i fasa punti", + "descriptionComplete": "Vinsesto sensa łasar che i cataràdeghi i fasa punti", + "descriptionFull": "Vinsi so ${LEVEL} sensa łasar che i cataràdeghi i fasa punti", + "descriptionFullComplete": "Vinsesto so ${LEVEL} sensa łasar che i cataràdeghi i fasa punti", + "name": "Vanpadora so ${LEVEL}" + }, + "Rookie Football Victory": { + "description": "Vinsi ła partìa", + "descriptionComplete": "Partìa vinsesta", + "descriptionFull": "Vinsi ła partìa so ${LEVEL}", + "descriptionFullComplete": "Partìa vinsesta so ${LEVEL}", + "name": "Vitoria so ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Fà fora tute łe ondàe", + "descriptionComplete": "Fazeste fora tute łe ondàe", + "descriptionFull": "Fà fora tute łe ondàe so ${LEVEL}", + "descriptionFullComplete": "Fazeste fora tute łe ondàe so ${LEVEL}", + "name": "Vitoria so ${LEVEL}" + }, + "Runaround God": { + "description": "Ingruma sù 2000 punti", + "descriptionComplete": "2000 punti ingrumài sù", + "descriptionFull": "Ingruma sù 2000 punti so ${LEVEL}", + "descriptionFullComplete": "2000 punti ingrumài sù so ${LEVEL}", + "name": "Łejenda de ${LEVEL}" + }, + "Runaround Master": { + "description": "Ingruma sù 500 punti", + "descriptionComplete": "500 punti ingrumài sù", + "descriptionFull": "Ingruma sù 500 punti so ${LEVEL}", + "descriptionFullComplete": "500 punti ingrumài sù so ${LEVEL}", + "name": "Aso de ${LEVEL}" + }, + "Runaround Wizard": { + "description": "Ingruma sù 1000 punti", + "descriptionComplete": "1000 punti ingrumài sù", + "descriptionFull": "Ingruma sù 1000 punti so ${LEVEL}", + "descriptionFullComplete": "1000 punti ingrumài sù so ${LEVEL}", + "name": "Mago de ${LEVEL}" + }, + "Sharing is Caring": { + "descriptionFull": "Sparpagna el zugo co un amigo co suceso", + "descriptionFullComplete": "Zugo sparpagnà co suceso co un amigo", + "name": "Sparpagnar A vołe dir tegnerghe" + }, + "Stayin' Alive": { + "description": "Vinsi sensa mai crepar", + "descriptionComplete": "Vinsesto sensa mai crepar", + "descriptionFull": "Vinsi so ${LEVEL} sensa mai crepar", + "descriptionFullComplete": "Vinsesto so ${LEVEL} sensa mai crepar", + "name": "Ła scanpada!" + }, + "Super Mega Punch": { + "description": "Cava el 100% de vita co un crogno soło", + "descriptionComplete": "100% de vita cavada vìa co un crogno soło", + "descriptionFull": "Cava vìa el 100% de vita co un crogno soło so ${LEVEL}", + "descriptionFullComplete": "100% de vita cavada vìa co un crogno soło so ${LEVEL}", + "name": "Super mega crogno" + }, + "Super Punch": { + "description": "Cava vìa el 50% de vita co un crogno soło", + "descriptionComplete": "50% de vita cavada vìa co un crogno soło", + "descriptionFull": "Cava vìa el 50% de vita co un crogno soło so ${LEVEL}", + "descriptionFullComplete": "50% de vita cavada vìa co un crogno soło so ${LEVEL}", + "name": "Super crogno" + }, + "TNT Terror": { + "description": "Copa 6 cataràdeghi co ła TNT", + "descriptionComplete": "Copài co ła TNT 6 cataràdeghi", + "descriptionFull": "Copa 6 cataràdeghi co ła TNT so ${LEVEL}", + "descriptionFullComplete": "Copài co ła TNT 6 cataràdeghi so ${LEVEL}", + "name": "Dinamitaro" + }, + "Team Player": { + "descriptionFull": "Taca na partìa a \"Scuadre\" co pì de 4 zugadori", + "descriptionFullComplete": "Partìa a \"Scuadre\" co pì de 4 zugadori fata!", + "name": "Spirido cołaboradivo" + }, + "The Great Wall": { + "description": "Bloca tuti i cataràdeghi", + "descriptionComplete": "Blocài tuti i cataràdeghi", + "descriptionFull": "Bloca tuti i cataràdeghi so ${LEVEL}", + "descriptionFullComplete": "Blocài tuti i cataràdeghi so ${LEVEL}", + "name": "Muraja Cineze" + }, + "The Wall": { + "description": "Bloca tuti i cataràdeghi", + "descriptionComplete": "Blocài tuti i cataràdeghi", + "descriptionFull": "Bloca tuti i cataràdeghi so ${LEVEL}", + "descriptionFullComplete": "Blocài tuti i cataràdeghi so ${LEVEL}", + "name": "El muro" + }, + "Uber Football Shutout": { + "description": "Vinsi sensa łasar che i cataràdeghi i fasa punti", + "descriptionComplete": "Vinsesto sensa łasar che i cataràdeghi i gapia fazesto punti", + "descriptionFull": "Vinsi so ${LEVEL} sensa łasar che i cataràdeghi i fasa punti", + "descriptionFullComplete": "Vinsesto so ${LEVEL} sensa łasar che i cataràdeghi i gapia fazesto punti", + "name": "Vanpadora so ${LEVEL}" + }, + "Uber Football Victory": { + "description": "Vinsi ła partìa", + "descriptionComplete": "Partìa vinsesta", + "descriptionFull": "Vinsi ła partìa so ${LEVEL}", + "descriptionFullComplete": "Partìa vinsesta so ${LEVEL}", + "name": "Vitoria so ${LEVEL}" + }, + "Uber Onslaught Victory": { + "description": "Fà fora tute łe ondàe", + "descriptionComplete": "Fazeste fora tute łe ondàe", + "descriptionFull": "Fà fora tute łe ondàe so ${LEVEL}", + "descriptionFullComplete": "Fazeste fora tute łe ondàe so ${LEVEL}", + "name": "Vitoria so ${LEVEL}" + }, + "Uber Runaround Victory": { + "description": "Bloca tute łe ondàe", + "descriptionComplete": "Blocàe tute łe ondàe", + "descriptionFull": "Bloca tute łe ondàe so ${LEVEL}", + "descriptionFullComplete": "Blocàe tute łe ondàe so ${LEVEL}", + "name": "Vitoria so ${LEVEL}" + } + }, + "achievementsRemainingText": "Obietivi restanti:", + "achievementsText": "Obietivi", + "achievementsUnavailableForOldSeasonsText": "Ne despiaze, i obietivi de łe stajon pasàe no i ze pì disponìbiłi.", + "activatedText": "${THING} ativà.", + "addGameWindow": { + "getMoreGamesText": "Otien pì łevełi...", + "titleText": "Zonta zugo" + }, + "allowText": "Parmeti", + "alreadySignedInText": "El to account el ze in dòparo inte n’antro\ndispozidivo: canbia account o sara sù el zugo\ninte cheł’altro to dispozidivo e proa danovo.", + "apiVersionErrorText": "Inposìbiłe cargar el mòduło ${NAME}, el se refarise a ła varsion ${VERSION_USED}. Serve invese ła ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(Ativa \"Auto\" soło co te tachi sù łe fonarołe par ła realtà virtuałe)", + "headRelativeVRAudioText": "Àudio par fonarołe VR", + "musicVolumeText": "Vołume mùzega", + "soundVolumeText": "Vołume son", + "soundtrackButtonText": "Son de fondo", + "soundtrackDescriptionText": "(scolta ła to mùzega fin che te zughi)", + "titleText": "Àudio" + }, + "autoText": "Automàtega", + "backText": "Indrìo", + "banThisPlayerText": "Bloca 'sto zugador", + "bestOfFinalText": "Fenałe de \"El mejo de i ${COUNT}\"", + "bestOfSeriesText": "El mejo de i ${COUNT}", + "bestRankText": "Ła to pozision pì alta: #${RANK}", + "bestRatingText": "Ła to vałutasion pì alta: ${RATING}", + "bombBoldText": "BONBA", + "bombText": "Bonba", + "boostText": "Potensiador", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} el se configura rento l'apl mèdema.", + "buttonText": "boton", + "canWeDebugText": "Ghetu caro che BombSquad el reporte in automàtego bai,\nblochi e informasion baze só'l so dòparo a'l dezviłupador?\n\n'Sti dati no i contien miga informasion parsonałi ma i ło\njuta a far ndar ben el zugo sensa blochi o bai.", + "cancelText": "Anuła", + "cantConfigureDeviceText": "Ne despiaze, ${DEVICE} no'l ze miga configuràbiłe.", + "challengeEndedText": "'Sta sfida ła ze fenìa.", + "chatMuteText": "Siłensia ciacołada", + "chatMutedText": "Ciacołada siłensiada", + "chatUnMuteText": "Reativa son", + "choosingPlayerText": "", + "completeThisLevelToProceedText": "Par ndar vanti te ghè\nda conpletar 'sto łeveło!", + "completionBonusText": "Premio de concruzion", + "configControllersWindow": { + "configureControllersText": "Configura controładori", + "configureKeyboard2Text": "Configura botonera P2", + "configureKeyboardText": "Configura botonera", + "configureMobileText": "Dòpara dispozidivi cofà controładori", + "configureTouchText": "Configura schermo tàtiłe", + "ps3Text": "Controładori PS3", + "titleText": "Controładori", + "wiimotesText": "Controładori Wii", + "xbox360Text": "Controładori Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Nota: ła conpatibiłidà par i controładori ła muda drio dispozidivo e varsion de Android.", + "pressAnyButtonText": "Struca un boton calsìase de'l controłador\nche te vołi configurar...", + "titleText": "Configura controładori" + }, + "configGamepadWindow": { + "advancedText": "Avansàe", + "advancedTitleText": "Configurasion avansàe controładori", + "analogStickDeadZoneDescriptionText": "(da alsar se el to parsonajo el \"zbanda\" anca co no te tochi gnente)", + "analogStickDeadZoneText": "Pozision baze łeviera nałòzega", + "appliesToAllText": "(aplegàe a tuti i controładori de 'sto tipo)", + "autoRecalibrateDescriptionText": "(da ativar se'l to parsonajo no'l se move a ła vełosidà màsema)", + "autoRecalibrateText": "Autocàłebra ła łeviera nałòzega", + "axisText": "ase", + "clearText": "reinposta", + "dpadText": "Croze deresionałe", + "extraStartButtonText": "Boton Start in pì", + "ifNothingHappensTryAnalogText": "Se no càpita gnente, proa inpostarghe a'l só posto ła łeviera nałòzega.", + "ifNothingHappensTryDpadText": "Se no càpita gnente, proa inpostarghe a'l só posto ła croze deresionałe.", + "ignoreCompletelyDescriptionText": "(par evitar che 'sto controłador el posa influir so'l zugo o so i menù)", + "ignoreCompletelyText": "Ignora de'l tuto", + "ignoredButton1Text": "Boton ignorà 1", + "ignoredButton2Text": "Boton ignorà 2", + "ignoredButton3Text": "Boton ignorà 3", + "ignoredButton4Text": "Boton ignorà 4", + "ignoredButtonDescriptionText": "(par evitar anca che i botoni \"cao\" e \"sincro\" i interfarisa co l'interfasa utente)", + "pressAnyAnalogTriggerText": "Struca un griłeto nałòzego calsìase...", + "pressAnyButtonOrDpadText": "Struca un boton o croze deresionałe calsìase...", + "pressAnyButtonText": "Struca un boton calsìase...", + "pressLeftRightText": "Struca el boton sanco o drito...", + "pressUpDownText": "Struca el boton sù o zó...", + "runButton1Text": "Boton par córar 1", + "runButton2Text": "Boton par córar 2", + "runTrigger1Text": "Griłeto par córar 1", + "runTrigger2Text": "Griłeto par córar 2", + "runTriggerDescriptionText": "(i griłeti nałòzeghi i te parmete de variar ła vełosidà de corsa)", + "secondHalfText": "Configura ła segonda serie de inpostasion\nde'l controłador 2 in 1 che'l vegnarà\nmostrà cofà un controłador ùgnoło.", + "secondaryEnableText": "Ativa", + "secondaryText": "Controłador segondaro", + "startButtonActivatesDefaultDescriptionText": "(da dezativar se'l to boton Start el ze considarà pì cofà un boton menù)", + "startButtonActivatesDefaultText": "El boton Start l'ativa el menù predefenìo", + "titleText": "Configurasion controłador", + "twoInOneSetupText": "Configurasion controłador 2 so 1", + "uiOnlyDescriptionText": "(par evitar che 'sto controłador el posa zontarse inte na partìa)", + "uiOnlyText": "Łìmida el dòparo de'l menù", + "unassignedButtonsRunText": "Tuti i botoni miga defenìi i fà córar", + "unsetText": "", + "vrReorientButtonText": "Boton de repozision VR" + }, + "configKeyboardWindow": { + "configuringText": "Configurasion ${DEVICE}", + "keyboard2NoteText": "Nota: ła parte pì granda de łe botonere łe połe rejistrar\nsoło un fià de comandi a'l colpo. Donca, par zugar in du,\nse ndarìa mejo doparar do botonere defarenti. Tien daconto\nche te gavarè da defenir in tuti i cazi botoni unìvoghi\npar i tuti do i zugadori." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Grandesa controło", + "actionsText": "Asion a", + "buttonsText": "botoni", + "dragControlsText": "< strasina i controłi par repozisionarli >", + "joystickText": "łeviera", + "movementControlScaleText": "Grandesa controło", + "movementText": "Movimento a", + "resetText": "Reinposta", + "swipeControlsHiddenText": "Scondi i comandi a zlizo", + "swipeInfoText": "Par bituarse co i controłi a \"zlizo\" A serve un fià de pì tenpo.\nMa sensa dover vardar i controłi, el zugo el deventarà pì senpio.", + "swipeText": "zlizo", + "titleText": "Configura schermo tàtiłe" + }, + "configureItNowText": "Vutu configurarlo deso?", + "configureText": "Configura", + "connectMobileDevicesWindow": { + "amazonText": "Amazon Store", + "appStoreText": "App Store", + "bestResultsText": "Par zugar co rezultài pì boni te serve na rede wifi ràpida.\nTe połi redùzar el retardo (lag) de ła rede zugando visin a’l\ntrazmetidor de’l segnałe, desconetendo altri dispozidivi sensa\nfiło o conetendo l’ospitador de’l zugo co un cavo ethernet.", + "explanationText": "Par doparar un tełèfono o un tołeto cofà un controłador sensa fiło,\ninstàłaghe rento l’apl \"${REMOTE_APP_NAME}\". Par zugar a ${APP_NAME}\nte połi conétar co’l wifi tuti i dispozidivi che te vołi! Ze agratis!", + "forAndroidText": "par Android:", + "forIOSText": "par iOS:", + "getItForText": "Descarga ${REMOTE_APP_NAME} par iOS so l'AppStore de\nApple o par Android so'l Store de Google Play o l'Amazon Store", + "googlePlayText": "Google Play", + "titleText": "Doparar dispozidivi mòbiłi cofà controładori:" + }, + "continuePurchaseText": "Vutu ndar vanti par ${PRICE}?", + "continueText": "Sì!", + "controlsText": "Comandi", + "coopSelectWindow": { + "activenessAllTimeInfoText": "'Sto chive no'l vien aplegà inte ła clasìfega globałe.", + "activenessInfoText": "'Sto moltiplegador el và sù inte i dì co\nte zughi e el và zó inte cheł'altri.", + "activityText": "Costansa", + "campaignText": "Canpagna", + "challengesInfoText": "Vadagna i premi conpletando i minizughi.\n\nI premi e ła defegoltà de i łevełi i ndarà\nsù par cauna sfida conpletada e i ndarà zó\nco łe vien perdeste o miga zugàe.", + "challengesText": "Sfide", + "currentBestText": "El mejo par deso", + "customText": "E in pì...", + "entryFeeText": "Costo", + "forfeitConfirmText": "Vutu dabon dàrgheła vinta?", + "forfeitNotAllowedYetText": "Deso A no te połi miga dàrgheła vinta suito.", + "forfeitText": "Dàgheła vinta", + "multipliersText": "Moltiplegadori", + "nextChallengeText": "Sfida pròsema", + "nextPlayText": "Partìa pròsema", + "ofTotalTimeText": "de ${TOTAL}", + "playNowText": "Zuga suito", + "pointsText": "Punti", + "powerRankingFinishedSeasonUnrankedText": "(stajon fenìa sensa ver partesipà)", + "powerRankingNotInTopText": "(miga inte i primi ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} punti", + "powerRankingPointsMultText": "(x ${NUMBER} punti)", + "powerRankingPointsText": "${NUMBER} punti", + "powerRankingPointsToRankedText": "${CURRENT} punti so ${REMAINING}", + "powerRankingText": "Clasìfega globałe", + "prizesText": "Premi", + "proMultInfoText": "I zugadori co'l mejoramento ${PRO}\ni beca el ${PERCENT}% de punti in pì.", + "seeMoreText": "Clasìfega conpleta", + "skipWaitText": "Vanti suito", + "timeRemainingText": "Tenpo che resta", + "toRankedText": "par ndar sù de pozision", + "totalText": "totałe", + "tournamentInfoText": "Conpeti co cheł'altri zugadori par\nndar sù de puntejo inte ła to łega.\n\nCo'l tornèo el fenirà, i zugadori pì\nbrai i vegnarà reconpensài co i premi.", + "welcome1Text": "Benrivài inte ła ${LEAGUE}. A te połi mejorar ła to\npozision vadagnando stełe inte i łevełi, conpletando\ni obietivi o vinsendo i trofèi inte i tornèi.", + "welcome2Text": "Fazendo racuante atividà de 'sto tipo te połi anca vadagnar biłieti.\nI biłieti i połe èsar doparài par dezblocar parsonaji novi, łevełi e\nminizughi ma anca par ndar rento a tornèi o ver funsion in pì.", + "yourPowerRankingText": "Ła to pozision:" + }, + "copyConfirmText": "Copià inte łe note.", + "copyOfText": "Copia de ${NAME}", + "copyText": "Copia", + "createEditPlayerText": "", + "createText": "Crea", + "creditsWindow": { + "additionalAudioArtIdeasText": "Soni adisionałi, gràfega inisiałe e idee de ${NAME}", + "additionalMusicFromText": "Mùzega adisionałe de ${NAME}", + "allMyFamilyText": "ła me fameja e tuti i me amighi che i gà jutà a testar el zugo", + "codingGraphicsAudioText": "Tradusion in łengua veneta: VeC - Łengua Veneta\n Mail: venetianlanguage@gmail.com - Telegram: @LenguaVeneta\n\nProgramasion, gràfega e àudio de ${NAME}", + "languageTranslationsText": "Tradusion inte cheł'altre łengue:", + "legalText": "Informasion łegałi:", + "publicDomainMusicViaText": "Mùzega a dòparo pùblego de ${NAME}", + "softwareBasedOnText": "'Sta aplegasion ła ze in parte bazada so'l łaoro de ${NAME}", + "songCreditText": "${TITLE} sonada da ${PERFORMER}\nFata sù da ${COMPOSER}, intarpretada da ${ARRANGER}, piovegada da ${PUBLISHER},\nPar grasia de ${SOURCE}", + "soundAndMusicText": "Son e mùzega:", + "soundsText": "Soni (${SOURCE}):", + "specialThanksText": "Rengrasiamenti spesiałi a:", + "thanksEspeciallyToText": "Un grasie partegołar a ${NAME}", + "titleText": "Reconosimenti", + "whoeverInventedCoffeeText": "chichesipia che'l ghese inventà el cafè" + }, + "currentStandingText": "Ła to pozision par deso: #${RANK}", + "customizeText": "Parsonałiza...", + "deathsTallyText": "crepà ${COUNT} 'olte", + "deathsText": "Crepà", + "debugText": "dezbao", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Nota: par 'sta proa A sarìa mejo inpostar ła Defenision so 'Alta' so Inpostasion > Gràfega > Defenision.", + "runCPUBenchmarkText": "Saja prestasion CPU", + "runGPUBenchmarkText": "Saja prestasion GPU", + "runMediaReloadBenchmarkText": "Saja prestasion recargamento gràfega", + "runStressTestText": "Saja zugo soto sforso", + "stressTestPlayerCountText": "Nùmaro zugadori", + "stressTestPlaylistDescriptionText": "Łista de zugo par proa soto sforso", + "stressTestPlaylistNameText": "Nome łista de zugo", + "stressTestPlaylistTypeText": "Tipo łista de zugo", + "stressTestRoundDurationText": "Durada turno", + "stressTestTitleText": "Proa soto sforso", + "titleText": "Prestasion e Proe soto sforso", + "totalReloadTimeText": "Tenpo totałe recargamento: ${TIME} (par i detaji varda el rejistro eventi)" + }, + "defaultGameListNameText": "Łista de zugo \"${PLAYMODE}\" predefenìa", + "defaultNewGameListNameText": "Ła me łista de zugo ${PLAYMODE}", + "deleteText": "Ełìmena", + "demoText": "Demo", + "denyText": "Refuda", + "deprecatedText": "Roba vecia", + "desktopResText": "Resołusion PC", + "deviceAccountUpgradeText": "Ocio:\nte ghè fazesto l'aceso co l'account łogałe ${NAME}.\nCo un pròsemo ajornamento i account łogałi i vegnarà cavài via.\nSe te vołi tegnerte i to progresi ajorna el to account a ła varsion V2.", + "difficultyEasyText": "Fàsiłe", + "difficultyHardOnlyText": "Soło modałità defìsiłe", + "difficultyHardText": "Defìsiłe", + "difficultyHardUnlockOnlyText": "'Sto łeveło el połe èsar dezblocà soło in modałità defìsiłe.\nPénsitu de fàrgheła!?", + "directBrowserToURLText": "Verzi 'sto cołegamento so un browser:", + "disableRemoteAppConnectionsText": "Dezativa conesion co BombSquad Remote", + "disableXInputDescriptionText": "Dòpara pì de 4 controładori (ma co'l riscio che no i funsione ben).", + "disableXInputText": "Dezativa XInput", + "doneText": "Fato", + "drawText": "Pata", + "duplicateText": "Zdopia", + "editGameListWindow": { + "addGameText": "Zonta\nłeveło", + "cantOverwriteDefaultText": "A no te połi miga sorascrìvar ła łista de zugo predefenìa!", + "cantSaveAlreadyExistsText": "Eziste dezà na łista de zugo co 'sto nome!", + "cantSaveEmptyListText": "A no te połi miga salvar na łista de zugo voda!", + "editGameText": "Muda\nłeveło", + "listNameText": "Nome łista de zugo", + "nameText": "Nome", + "removeGameText": "Ełìmena\nłeveło", + "saveText": "Salva łista de zugo", + "titleText": "Mudador łiste de zugo" + }, + "editProfileWindow": { + "accountProfileInfoText": "'Sto profiło zugador spesiałe el gà nome e icona\nautomàteghi, inpostài drio el to account conetesto.\n\n${ICONS}\n\nCrea un profiło parsonałizà par\ndoparar nomi o icone defarenti.", + "accountProfileText": "(profiło account)", + "availableText": "El nome \"${NAME}\" el ze disponìbiłe.", + "characterText": "parsonajo", + "checkingAvailabilityText": "Controło disponibiłidà par \"${NAME}\"...", + "colorText": "cołor", + "getMoreCharactersText": "Otien pì parsonaji...", + "getMoreIconsText": "Otien pì icone...", + "globalProfileInfoText": "I profiłi zugador globałi i gà nomi ùgnołi garantìi.\nIn pì A se połe zontarghe anca icone parsonałizàe.", + "globalProfileText": "(profiło globałe)", + "highlightText": "detaji", + "iconText": "icona", + "localProfileInfoText": "I profiłi zugador łocałi no i połe ver icone e i nomi no i\nze garantìi cofà ùgnołi. Mejòrełi a profiłi globałi par\nreservarte un nome ùnego e zontarghe na icona parsonałizada.", + "localProfileText": "(profiło łogałe)", + "nameDescriptionText": "Nome zugador", + "nameText": "Nome", + "randomText": "", + "titleEditText": "Muda profiło", + "titleNewText": "Profiło novo", + "unavailableText": "\"${NAME}\" no'l ze miga disponìbiłe: proa n'antro nome.", + "upgradeProfileInfoText": "Ndando vanti te reservarè el to nome zugador in tuto\nel mondo e te podarè zontarghe na icona parsonałizada.", + "upgradeToGlobalProfileText": "Mejora a profiło globałe" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "A no te połi miga ełimenar el son de fondo predefenìo.", + "cantEditDefaultText": "A no te połi miga mudar el son de fondo predefenìo. Zdópieło o crèaghine uno novo.", + "cantOverwriteDefaultText": "A no te połi miga sorascrìvar el son de fondo predefenìo.", + "cantSaveAlreadyExistsText": "Eziste dezà un son de fondo co 'sto nome!", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Son de fondo predefenìo", + "deleteConfirmText": "Vutu ełimenar el son de fondo:\n\n'${NAME}'?", + "deleteText": "Ełìmena\nson de fondo", + "duplicateText": "Zdopia\nson de fondo", + "editSoundtrackText": "Mudador son de fondo", + "editText": "Muda\nson de fondo", + "fetchingITunesText": "rancurasion łiste de scolto de l'apl...", + "musicVolumeZeroWarning": "Avertensa: el vołume de ła mùzega el ze inpostà a 0", + "nameText": "Nome", + "newSoundtrackNameText": "El me son de fondo ${COUNT}", + "newSoundtrackText": "Son de fondo novo:", + "newText": "Novo\nson de fondo", + "selectAPlaylistText": "Sełesiona na łista de scolto", + "selectASourceText": "Fóntego mùzega", + "testText": "proa", + "titleText": "Soni de fondo", + "useDefaultGameMusicText": "Mùzega zugo predefenìa", + "useITunesPlaylistText": "Łista de scolto de l'apl", + "useMusicFileText": "File mùzegałe (mp3, evc)", + "useMusicFolderText": "Carteła de file muzegałi" + }, + "editText": "Muda", + "endText": "Moła", + "enjoyText": "Profìtaghine e gòdateła!", + "epicDescriptionFilterText": "${DESCRIPTION} in movensa camoma.", + "epicNameFilterText": "${NAME} in movensa camoma", + "errorAccessDeniedText": "aceso refudà", + "errorDeviceTimeIncorrectText": "L'ora de'l to dispozidivo ła ze zbałada de ${HOURS} ore.\nPodarìa verifegarse problemi.\nControła l'ora e łe inpostasion de'l to fuzorario.", + "errorOutOfDiskSpaceText": "spasio so'l disco fenìo", + "errorSecureConnectionFailText": "Inposìbiłe stabiłir na conesion segura co ła nùvoła: podarìa èsarghe erori co łe funsionałidà de rede.", + "errorText": "Eror", + "errorUnknownText": "eror miga conosesto", + "exitGameText": "Vutu ndar fora da ${APP_NAME}?", + "exportSuccessText": "'${NAME}' esportà.", + "externalStorageText": "Memoria esterna", + "failText": "Desfata", + "fatalErrorText": "Orpo! Calcosa el manca o el ze danejà.\nProa a reinstałar l'apl o contata\n${EMAIL} par ver juto.", + "fileSelectorWindow": { + "titleFileFolderText": "Sełesiona un file o na carteła", + "titleFileText": "Sełesiona un file", + "titleFolderText": "Sełesiona na carteła", + "useThisFolderButtonText": "Dòpara 'sta carteła" + }, + "filterText": "Tamizo", + "finalScoreText": "Puntejo fenałe", + "finalScoresText": "Punteji fenałi", + "finalTimeText": "Tenpo fenałe", + "finishingInstallText": "Conpletamento instałasion: n'àtemo soło...", + "fireTVRemoteWarningText": "* Par mejorar l'espariensa, dòpara\ni controładori o instała l'app\n'${REMOTE_APP_NAME}' so i to\ntełèfoni o tołeti.", + "firstToFinalText": "Fenałe de Brinca ${COUNT} punti", + "firstToSeriesText": "Brinca ${COUNT} punti", + "fiveKillText": "BEN 5 SASINÀI!!!!", + "flawlessWaveText": "Ondada parfeta!", + "fourKillText": "EŁIMENÀI: 4!!!", + "friendScoresUnavailableText": "Punteji de i amighi miga disponìbiłi.", + "gameCenterText": "GameCenter", + "gameCircleText": "GameCircle", + "gameLeadersText": "Clasìfega de'l łeveło ${COUNT}", + "gameListWindow": { + "cantDeleteDefaultText": "A no te połi miga ełimenar ła łista de zugo predefenìa.", + "cantEditDefaultText": "A no te połi miga modifegar ła łista de zugo predefenìa. Zdòpieła o crèaghine una nova.", + "cantShareDefaultText": "A no te połi miga sparpagnar ła łista de zugo predefenìa.", + "deleteConfirmText": "Vutu ełimenar \"${LIST}\"?", + "deleteText": "Ełìmena\nłista de zugo", + "duplicateText": "Zdopia\nłista de zugo", + "editText": "Muda\nłista de zugo", + "newText": "Nova\nłista de zugo", + "showTutorialText": "Demostrasion", + "shuffleGameOrderText": "Zmisia òrdene łevełi", + "titleText": "Parsonałiza łiste de zugo \"${TYPE}\"" + }, + "gameSettingsWindow": { + "addGameText": "Zonta partìa" + }, + "gamesToText": "${WINCOUNT} a ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Recòrdate: se te ghè bastansa controładori, tuti i\ndispozidivi de un grupo i połe ospitar pì zugadori.", + "aboutDescriptionText": "Dòpara 'ste sesion par far sù un grupo.\n\nI grupi i te parmete de zugar partìe e tornèi\nco i to amighi infrà i vari dispozidivi.\n\nDòpara el boton ${PARTY} insima a drita par\nciacołar e interajir co’l to grupo.\n(so un controłador, struca ${BUTTON} co te si inte un menù)", + "aboutText": "Info", + "addressFetchErrorText": "", + "appInviteMessageText": "L'utente ${NAME} el te ga mandà ${COUNT} biłieti so ${APP_NAME}", + "appInviteSendACodeText": "Màndaghe un còdaze", + "appInviteTitleText": "Invido a proar ${APP_NAME}", + "bluetoothAndroidSupportText": "(el funsiona so tuti i dispozidivi Android co el bluetooth)", + "bluetoothDescriptionText": "Òspita/zóntate so un grupo co'l bluetooth:", + "bluetoothHostText": "Òspita", + "bluetoothJoinText": "Zóntate", + "bluetoothText": "Bluetooth", + "checkingText": "controło...", + "copyCodeConfirmText": "Còdaze copià inte łe note.", + "copyCodeText": "Copia còdaze", + "dedicatedServerInfoText": "Inposta un server dedegà par rezultài pì boni. Daghe un ocio so bombsquadgame.com/server par capir come far.", + "disconnectClientsText": "'Sta oparasion ła desconetarà ${COUNT} zugador/i\nda'l to grupo. Vutu ndar vanti?", + "earnTicketsForRecommendingAmountText": "Se i provarà el zugo, i to amighi i resevarà ${COUNT} biłieti\n(e ti te ghin resevarè ${YOU_COUNT} par caun de łori che'l ło dopararà)", + "earnTicketsForRecommendingText": "Sparpagna el zugo par\nver biłieti gratùidi...", + "emailItText": "Màndeło par mail", + "favoritesSaveText": "Salva inte i prefarìì", + "favoritesText": "Prefarìi", + "freeCloudServerAvailableMinutesText": "Server agratis tenpo ${MINUTES} menuti.", + "freeCloudServerAvailableNowText": "Disponìbiłe server agratis!", + "freeCloudServerNotAvailableText": "Gnaun server agratis disponìbiłe.", + "friendHasSentPromoCodeText": "Par ti ${COUNT} biłieti de ${APP_NAME} da ${NAME}!", + "friendPromoCodeAwardText": "Tute łe 'olte che'l vegnarà doparà te resevarè ${COUNT} biłieti.", + "friendPromoCodeExpireText": "El còdaze el ze soło par i zugaduri novi e el terminarà tenpo ${EXPIRE_HOURS} ore.", + "friendPromoCodeInstructionsText": "Par dopararlo, verzi ${APP_NAME} e và so \"Inpostasion > Avansàe > Insarisi còdaze\".\nDaghe un ocio so bombsquadgame.com par i link de descargamento de'l zugo par tute łe piataforme conpatìbiłi.", + "friendPromoCodeRedeemLongText": "El połe èsar scanbià par ${COUNT} biłieti gratùidi da ${MAX_USES} parsone.", + "friendPromoCodeRedeemShortText": "El połe èsar scanbià inte'l zugo par ${COUNT} biłieti gratùidi.", + "friendPromoCodeWhereToEnterText": "(so \"Inpostasion > Avansàe > Insarisi còdaze\")", + "getFriendInviteCodeText": "Jènara còdaze de invido", + "googlePlayDescriptionText": "Invida zugadori de Google Play inte'l to grupo:", + "googlePlayInviteText": "Invida", + "googlePlayReInviteText": "Se A te mandi un invido novo el/i ${COUNT} zugador(i) de\nGoogle Play inte'l to grupo el/i vegnarà desconetesto/i.\nPar tegnerlo/i in grupo màndaghe anca a łù/łori l'invido novo.", + "googlePlaySeeInvitesText": "Mostra invidi", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(soło inte ła varsion Android / Google Play)", + "hostPublicPartyDescriptionText": "Òspita un grupo pùblego", + "hostingUnavailableText": "Ospitamento miga disponìbiłe", + "inDevelopmentWarningText": "Nota:\n\nEl zugo in rede ła ze na funsion nova e in dezviłupo.\nPar deso, ze dabon racomandà che tuti i\nzugadori i sipie tuti so ła mèdema rede wifi.", + "internetText": "Internet", + "inviteAFriendText": "I to amighi zełi sensa zugo? Invìdełi a\nproarlo e i resevarà ${COUNT} biłieti gratùidi.", + "inviteFriendsText": "Invida amighi", + "joinPublicPartyDescriptionText": "Zóntate so un grupo pùblego", + "localNetworkDescriptionText": "Zóntate so un grupo łogałe (LAN, Bluetooth, evc.)", + "localNetworkText": "Rede łogałe", + "makePartyPrivateText": "Canbia el me grupo in privà", + "makePartyPublicText": "Canbia el me grupo in pùblego", + "manualAddressText": "Ndariso", + "manualConnectText": "Coneti", + "manualDescriptionText": "Zóntate inte un grupo par ndariso:", + "manualJoinSectionText": "Zóntate par ndariso", + "manualJoinableFromInternetText": "Pòsitu èsar catà da internet?:", + "manualJoinableNoWithAsteriskText": "NÒ*", + "manualJoinableYesText": "SÌ", + "manualRouterForwardingText": "*par sistemar, proa configurar el to router in magnera che'l rederesione ła porta UDP ${PORT} a'l to ndariso łogałe", + "manualText": "A man", + "manualYourAddressFromInternetText": "El to ndariso da internet:", + "manualYourLocalAddressText": "El to ndariso łogałe:", + "nearbyText": "Łogałe", + "noConnectionText": "", + "otherVersionsText": "(par altre varsion)", + "partyCodeText": "Còdaze de'l grupo", + "partyInviteAcceptText": "Và ben", + "partyInviteDeclineText": "Miga deso", + "partyInviteGooglePlayExtraText": "(varda el paneło 'Google Play' inte ła fenestra 'Crea grupo')", + "partyInviteIgnoreText": "Ignora", + "partyInviteText": "A te ze rivà un invido de ${NAME}\npar zontarte inte'l só grupo!", + "partyNameText": "Nome grupo", + "partyServerRunningText": "Server pa'l grupo ativo.", + "partySizeText": "grandesa", + "partyStatusCheckingText": "Varìfega condision...", + "partyStatusJoinableText": "deso el to grupo el połe èsar catà da internet", + "partyStatusNoConnectionText": "A no ze miga posìbiłe conétarse a'l server", + "partyStatusNotJoinableText": "el to grupo no'l połe miga èsar catà da internet", + "partyStatusNotPublicText": "el to grupo no'l ze miga pùblego", + "pingText": "łatensa", + "portText": "Porta", + "privatePartyCloudDescriptionText": "I grupi privài i funsiona so server dedegài: no serve miga configurar un router.", + "privatePartyHostText": "Òspida un grupo privà", + "privatePartyJoinText": "Zóntate so un grupo privà", + "privateText": "Privà", + "publicHostRouterConfigText": "Podarìa servir configurar na porta spesìfega so'l to router. Ospidar un grupo privà ze pì fàsiłe.", + "publicText": "Pùblego", + "requestingAPromoCodeText": "Dimanda par un còdaze…", + "sendDirectInvitesText": "Manda invidi direti", + "shareThisCodeWithFriendsText": "Sparpagna 'sto còdaze co i amighi:", + "showMyAddressText": "Mostra el me ndariso", + "startHostingPaidText": "Òspita suito par ${COST}", + "startHostingText": "Òspita", + "startStopHostingMinutesText": "Te połi tacar o fermar de ospitar grupi łìbaramente par n'antri ${MINUTES} menuti.", + "stopHostingText": "Ferma ospitamento", + "titleText": "Crea grupo", + "wifiDirectDescriptionBottomText": "Se tuti i dispozidivi i gà ła sesion 'Wifi direto', i sarà boni de dopararlo par\ncatarse e conétarse infrà de łori. Na volta che tuti i dispozidivi i sarà conetesti,\nte podarè crear grupi inte ła sesion 'Rede łogałe', cofà ła fuse na rede wifi normałe.\n\nPar rezultài pì boni, mejo che l’ospitador de’l wifi direto el sipie l’òspite anca de’l grupo so ${APP_NAME}.", + "wifiDirectDescriptionTopText": "El Wifi direto el połe èsar doparà par conétar diretamente dispozidivi Android\nsensa pasar par ła rede wifi. El funsiona mejo so varsion Android 4.2 o pì resenti.\n\nPar dopararlo, verzi łe inpostasion wifi e controła ła funsion 'Wifi direto'.", + "wifiDirectOpenWiFiSettingsText": "Verzi inpostasion wifi", + "wifiDirectText": "Wifi direto", + "worksBetweenAllPlatformsText": "(el funsiona intrà tute łe piataforme)", + "worksWithGooglePlayDevicesText": "(el funsiona co tuti i dispozidivi co ła varsion de’l zugo de Google Play par Android)", + "youHaveBeenSentAPromoCodeText": "A te ze stà mandà un còdaze promosionałe de ${APP_NAME}:" + }, + "getTicketsWindow": { + "freeText": "GRATIS!", + "freeTicketsText": "Biłieti gratùidi", + "inProgressText": "Na tranzasion ła ze dezà in ełaborasion: proa danovo infrà na scianta.", + "purchasesRestoredText": "Cronpe recuparàe.", + "receivedTicketsText": "${COUNT} biłieti resevesti!", + "restorePurchasesText": "Recùpara cronpe.", + "ticketPack1Text": "Pacheto de biłieti ceło", + "ticketPack2Text": "Pacheto de biłieti mezan", + "ticketPack3Text": "Pacheto de biłieti grando", + "ticketPack4Text": "Pacheto de biłieti ultra", + "ticketPack5Text": "Pacheto de biłieti despropozità", + "ticketPack6Text": "Pacheto de biłieti defenidivo", + "ticketsFromASponsorText": "Varda na reclan e\notien ${COUNT} biłieti", + "ticketsText": "${COUNT} biłieti", + "titleText": "Otien biłieti", + "unavailableLinkAccountText": "No se połe miga cronpar so 'sta piataforma.\nVołendo, te połi cołegar 'sto account co uno inte\nn'antra piataforma e cronpar calcosa da łà.", + "unavailableTemporarilyText": "'Sta funsion no ła ze miga disponìbiłe par deso: proa danovo pì tardi.", + "unavailableText": "Ne despiaze, 'sta funsion no ła ze miga disponìbiłe.", + "versionTooOldText": "Ne despiaze, 'sta varsion ła ze masa vecia: ajorna el zugo co cheła nova.", + "youHaveShortText": "A te ghè ${COUNT}", + "youHaveText": "A te ghè ${COUNT} biłieti" + }, + "googleMultiplayerDiscontinuedText": "Me despiaze, el sarviso multizugador de Google no'l ze miga pì disponìbiłe.\nA sò drio łaorar a un renpiaso pì in presa che se połe.\nIntanto proa n'antro mètodo de conesion.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Łe cronpe vecie no łe ze miga disponìbiłi.\nPodarìa èsarghe bezogno de ajornar l'apl Google Play.", + "googlePlayServicesNotAvailableText": "Google Play Services no'l ze miga disponìbiłe.\nSerte funsion de l'apl łe podarìa èsar dezativàe.", + "googlePlayText": "Google Play", + "graphicsSettingsWindow": { + "alwaysText": "Senpre", + "fullScreenCmdText": "Schermo pien (Cmd-F)", + "fullScreenCtrlText": "Schermo pien (Ctrl-F)", + "gammaText": "Gama", + "highText": "Alta", + "higherText": "Màsema", + "lowText": "Basa", + "mediumText": "Mezana", + "neverText": "Mai", + "resolutionText": "Resołusion", + "showFPSText": "Mostra FPS", + "texturesText": "Defenision", + "titleText": "Gràfega", + "tvBorderText": "Bordaura TV", + "verticalSyncText": "Sincronizasion vertegałe", + "visualsText": "Prospetiva" + }, + "helpWindow": { + "bombInfoText": "- Bonbe -\nPì forti de i crogni, ma łe połe\nfarte małe anca a ti. Dopàrełe\nben tràndoghełe doso a i nemighi\nprima che łe salte par aria.", + "canHelpText": "${APP_NAME} el połe jutarte!", + "controllersInfoText": "Te połi zugar a ${APP_NAME} co i amighi co na rede o, se gavì\ncontroładori che basta, połì zugar tuti insenbre so el mèdemo\ndispozidivo: ${APP_NAME} el ghin suporta racuanti. Połì senpre doparar\ni tełèfoni cofà controładori co l’apl gratùida '${REMOTE_APP_NAME}'.\nPar info in pì varda so Inpostasion > Controładori.", + "controllersInfoTextRemoteOnly": "Te połi zugar a ${APP_NAME} co i to amighi doparando na rede,\no zugar tuti so'l mèdemo dispozidivo doparando i tełèfoni cofà\ncontroładori co l'apl gratùida '${REMOTE_APP_NAME}'.", + "controllersText": "Controładori", + "controlsSubtitleText": "El to amighévołe parsonajo de ${APP_NAME} el gà un fià de funsion de baze:", + "controlsText": "Controłi", + "devicesInfoText": "Ła varsion VR de ${APP_NAME} ła połe èsar zugada so na rede anca\nco ła varsion normałe de l'app, donca tira fora tełèfoni, tołeti\ne computers e taca a zugar! Podarìa èsar ùtiłe conétar na varsion\nnormałe de'l zugo a cheła VR anca soło par parmétarghe a łe parsone\nde poder ndarghe drio a'l zugo da fora.", + "devicesText": "Dispozidivi", + "friendsGoodText": "A ze senpre bona roba vèrghene. Se se ła gode de pì co pì zugadori\ne ${APP_NAME} el ghin suporta fin a 8, e 'sta roba ła ne mena a:", + "friendsText": "Amighi", + "jumpInfoText": "- Salto -\nSalta par traversar buzi cełi,\npar trar robe pì alte, o par\nfar védar tuta ła to ałegresa.", + "orPunchingSomethingText": "O de ciaparla a crogni, trarla zó par na croda, e fin che ła casca zó, farla saltar par aria co na bonba petaisa.", + "pickUpInfoText": "- Łeva sù -\nBrinca sù bandiere, nemighi o calsìase\naltra roba miga inciodada par tera.\nStruca danovo par trarla in jiro.", + "powerupBombDescriptionText": "El te parmete de trar in jiro fin\na 3 bonbe drioman invese che 1.", + "powerupBombNameText": "Bonbe triple", + "powerupCurseDescriptionText": "Probabilmente A te vorè schivarla\n'sta chive. ...o dìzitu de nò?", + "powerupCurseNameText": "Małedision", + "powerupHealthDescriptionText": "El te recarga de'l tuto ła vida.\nA no te ło gavarisi mai pensà, ahn?", + "powerupHealthNameText": "Parecio mèdego", + "powerupIceBombsDescriptionText": "Pì débołi de łe bonbe normałi\nma łe injasa i to nemighi e\nłi fà deventar pì fràjiłi.", + "powerupIceBombsNameText": "Bonbe jaso", + "powerupImpactBombsDescriptionText": "Un peło pì débołi de łe bonbe normałi,\nma łe sciopa suito co łe brinca calcosa.", + "powerupImpactBombsNameText": "Bonbe a inpato", + "powerupLandMinesDescriptionText": "In pacheti còmodi da 3!\nÙtiłi par na defeza de baze o\npar fermar nemighi ràpidi.", + "powerupLandMinesNameText": "Mine", + "powerupPunchDescriptionText": "I to crogni i deventarà uncora\nmejo: pì fisi, gajardi, ràpidi.", + "powerupPunchNameText": "Guantoni da boxe", + "powerupShieldDescriptionText": "El se sorbise un fià de dano in \nmagnera che no'l te rive a ti.", + "powerupShieldNameText": "Scudo nerjètego", + "powerupStickyBombsDescriptionText": "Łe se peta so cauna roba che\nłe toca. Zganasàe seguràe!", + "powerupStickyBombsNameText": "Bonbe petaise", + "powerupsSubtitleText": "Par forsa, gnaun zugo el sarìe conpleto sensa potensiadori:", + "powerupsText": "Potensiadori", + "punchInfoText": "- Crogno -\nPì che te te movi ràpidamente,\npì i to crogni i farà małe, donca\ncori, salta e và torno cofà un mato.", + "runInfoText": "- Corsa -\nTien strucà CALSÌASE boton par córar. I botoni de testa o i griłeti nałòzeghi i ze i pì adati se\nA te łi ghè. Corendo A te rivarè prima inte i posti ma sarà pì dura voltar, donca ocio a łe crode.", + "someDaysText": "In serti dì A se gà soło voja de tirarghe crogni a calcosa. O de farla saltar par aria.", + "titleText": "Istrusion de ${APP_NAME}", + "toGetTheMostText": "Par tirar fora el mejo da 'sto zugo A te serve:", + "welcomeText": "Benrivài so ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} ze drio navegar intrà i menù a zbregabałon! -", + "importPlaylistCodeInstructionsText": "Dòpara 'sto còdaze par inportar 'sta łista de zugo ndove che te vołi:", + "importPlaylistSuccessText": "Łista de zugo '${NAME}' a ${TYPE} inportada", + "importText": "Inporta", + "importingText": "Inportasion...", + "inGameClippedNameText": "rento el zugo:\n\"${NAME}\"", + "installDiskSpaceErrorText": "EROR: inposìbiłe fenir l’instałasion.\nEl to dispozidivo el podarìa èsar sensa spasio.\nŁìbara un fià de memoria e proa danovo.", + "internal": { + "arrowsToExitListText": "struca ${LEFT} o ${RIGHT} par ndar fora da ła serie", + "buttonText": "boton", + "cantKickHostError": "A no te połi miga parar vìa l'ospitador.", + "chatBlockedText": "${NAME} ze stà tajà fora da ła chat par ${TIME} segondi.", + "connectedToGameText": "A te te si zontà so '${NAME}'", + "connectedToPartyText": "A te te si zontà so'l grupo de ${NAME}!", + "connectingToPartyText": "Conesion...", + "connectionFailedHostAlreadyInPartyText": "Conesion fałìa: l'ospitador el ze inte n'antro grupo.", + "connectionFailedPartyFullText": "Conesion fałìa: el grupo el ze pien.", + "connectionFailedText": "Conesion fałìa.", + "connectionFailedVersionMismatchText": "Conesion fałìa: l'ospitador el gà na varsion de'l zugo defarente.\nSegureve de ver tuti do l'apl ajornada e provè danovo.", + "connectionRejectedText": "Conesion refudada.", + "controllerConnectedText": "${CONTROLLER} conetesto.", + "controllerDetectedText": "Rełevà 1 controłador.", + "controllerDisconnectedText": "${CONTROLLER} desconetesto.", + "controllerDisconnectedTryAgainText": "${CONTROLLER} desconetesto. Proa conétarlo danovo.", + "controllerForMenusOnlyText": "'Sto controłador no'l połe miga èsar doparà par zugar, ma soło par navegar intrà i menù.", + "controllerReconnectedText": "${CONTROLLER} reconetesto.", + "controllersConnectedText": "${COUNT} controładori conetesti.", + "controllersDetectedText": "${COUNT} controładori rełevài.", + "controllersDisconnectedText": "${COUNT} controładori desconetesti.", + "corruptFileText": "A ze stà catài fora file coronpesti. Proa reinstałar el zugo o manda na mail a: ${EMAIL}", + "errorPlayingMusicText": "Eror de reprodusion muzegałe: ${MUSIC}", + "errorResettingAchievementsText": "A no ze miga posìbiłe reinpostar i obietivi in łinea. Proa danovo pì tardi.", + "hasMenuControlText": "${NAME} gà el controło de'l menù", + "incompatibleNewerVersionHostText": "L'ospitador el gà na varsion de'l zugo pì resente.\nAjórneło anca ti a ła varsion ùltema e proa danovo.", + "incompatibleVersionHostText": "L'ospitador el gà na varsion de'l zugo defarente.\nSegùreve de ver tuti do l'apl ajornada e provè danovo.", + "incompatibleVersionPlayerText": "${NAME} gà na varsion de'l zugo defarente.\nSegùreve de ver tuti do l'apl ajornada e provè danovo.", + "invalidAddressErrorText": "Eror: ndariso miga vàłido.", + "invalidNameErrorText": "Eror: nome miga vàłido.", + "invalidPortErrorText": "Eror: porta miga vàłida.", + "invitationSentText": "Invido mandà.", + "invitationsSentText": "Mandài ${COUNT} invidi.", + "joinedPartyInstructionsText": "Calchedun el se gà zontà inte'l to grupo.\nVà so \"Zuga\" par tacar na partìa.", + "keyboardText": "Botonera", + "kickIdlePlayersKickedText": "Ze stà parà fora ${NAME} par masa sonera.", + "kickIdlePlayersWarning1Text": "Se ła só sonera ła sèvita, ${NAME} vegnarà parà fora tenpo ${COUNT} segondi.", + "kickIdlePlayersWarning2Text": "(A te połi dezativarlo so Inpostasion > Avansàe)", + "leftGameText": "A te si ndà fora da '${NAME}'.", + "leftPartyText": "A te si ndà fora da'l grupo de ${NAME}.", + "noMusicFilesInFolderText": "Ła carteła no ła gà rento gnaun file muzegałe.", + "playerJoinedPartyText": "${NAME} l'se gà zontà inte'l grupo!", + "playerLeftPartyText": "${NAME} gà mołà el grupo!", + "rejectingInviteAlreadyInPartyText": "Invido refudà (dezà inte un grupo).", + "serverRestartingText": "El server el ze drio retacarse. Reconétate infrà na scianta...", + "serverShuttingDownText": "El server el ze drio stuarse...", + "signInErrorText": "Eror in entrada.", + "signInNoConnectionText": "Inposìbiłe acédar. (sensa conesion internet?)", + "telnetAccessDeniedText": "EROR: l'utente no'l gà miga parmeso l'aceso co telnet.", + "timeOutText": "(tocarà a ti tenpo ${TIME} segondi)", + "touchScreenJoinWarningText": "A te te si zontà co'l touchscreen.\nSe ła ze stà na capeła, struca 'Menù > Moła łeveło'.", + "touchScreenText": "TouchScreen", + "unableToResolveHostText": "Eror: A no ze mìa posìbiłe conétarse co l'ospitador.", + "unavailableNoConnectionText": "Par deso mìa disponìbiłe (gnauna conesion a internet?)", + "vrOrientationResetCardboardText": "Dopàreło par reinpostar l'orientasion de'l VR.\nA te servirà un controłador esterno par zugar.", + "vrOrientationResetText": "Reinposta orientasion VR.", + "willTimeOutText": "(ma se in sonera el ghe vegnarà cavà)." + }, + "jumpBoldText": "SALTO", + "jumpText": "Salto", + "keepText": "Tien", + "keepTheseSettingsText": "Vutu tegner 'ste inpostasion?", + "keyboardChangeInstructionsText": "Struca spasio do 'olte par mudar botonera.", + "keyboardNoOthersAvailableText": "A no ghe ze miga altre botonere disponìbiłi.", + "keyboardSwitchText": "Pasajo a ła botonera \"${NAME}\".", + "kickOccurredText": "${NAME} ze stà parà fora.", + "kickQuestionText": "Vutu parar vìa ${NAME}?", + "kickText": "Para fora", + "kickVoteCantKickAdminsText": "I aministradori no i połe mìa èsar parài vìa.", + "kickVoteCantKickSelfText": "A no te połi mìa pararte vìa da soło.", + "kickVoteFailedNotEnoughVotersText": "A ghe ze masa pochi zugadori par na votasion.", + "kickVoteFailedText": "Votasion de zlontanamento fałìa.", + "kickVoteStartedText": "A se gà tacà na votasion par parar vìa ${NAME}.", + "kickVoteText": "Vota par parar vìa", + "kickVotingDisabledText": "El voto de zlontanamento el ze dezativà.", + "kickWithChatText": "Scrivi inte ła chat ${YES} par sì e ${NO} par nò.", + "killsTallyText": "${COUNT} fati fora", + "killsText": "Fati fora", + "kioskWindow": { + "easyText": "Fàsiłe", + "epicModeText": "Movensa camoma", + "fullMenuText": "Menù intiero", + "hardText": "Defìsiłe", + "mediumText": "Medhan", + "singlePlayerExamplesText": "Ezenpi de Zugador ùgnoło / Cooperadiva", + "versusExamplesText": "Ezenpi de Scontro" + }, + "languageSetText": "Łengua inpostada: \"${LANGUAGE}\".", + "lapNumberText": "Jiro ${CURRENT}/${TOTAL}", + "lastGamesText": "(${COUNT} partìe ùlteme)", + "leaderboardsText": "Clasìfeghe", + "league": { + "allTimeText": "Clasìfega globałe", + "currentSeasonText": "Stajon in corso (${NUMBER})", + "leagueFullText": "Łega ${NAME}", + "leagueRankText": "Pozision łega", + "leagueText": "Łega", + "rankInLeagueText": "#${RANK}, ${NAME} Łega${SUFFIX}", + "seasonEndedDaysAgoText": "Stajon fenìa da ${NUMBER} dì.", + "seasonEndsDaysText": "Ła stajon ła fenirà tenpo ${NUMBER} dì.", + "seasonEndsHoursText": "Ła stajon ła fenirà tenpo ${NUMBER} ore.", + "seasonEndsMinutesText": "Ła stajon ła fenirà tenpo ${NUMBER} menuti.", + "seasonText": "Stajon ${NUMBER}", + "tournamentLeagueText": "A te ghè da rivar inte ła łega ${NAME} par zugar inte 'sto tornèo.", + "trophyCountsResetText": "Par ła stajon che ła vien el puntejo\nde i trofèi el se zerarà." + }, + "levelBestScoresText": "I punteji mejo so ${LEVEL}", + "levelBestTimesText": "I tenpi mejo so ${LEVEL}", + "levelIsLockedText": "${LEVEL} el ze blocà.", + "levelMustBeCompletedFirstText": "Prima A te ghè da conpletar ${LEVEL}.", + "levelText": "Łeveło ${NUMBER}", + "levelUnlockedText": "Łeveło dezblocà!", + "livesBonusText": "Vite bonus", + "loadingText": "cargamento", + "loadingTryAgainText": "Cargamento: proa danovo infrà na scianta...", + "macControllerSubsystemBothText": "Tuti do (ma miga racomandà)", + "macControllerSubsystemClassicText": "Clàsego", + "macControllerSubsystemDescriptionText": "(se i to controładori no i funsiona, proa mudar 'sta inpostasion)", + "macControllerSubsystemMFiNoteText": "Rełevà controłador 'Fato par iOS/Mac';\nSe te ghè caro ativarlo, và so Inpostasion > Controładori", + "macControllerSubsystemMFiText": "Fato par iOS/Mac", + "macControllerSubsystemTitleText": "Suporto controłador", + "mainMenu": { + "creditsText": "Mension", + "demoMenuText": "Menù demo", + "endGameText": "Sara sù partìa", + "endTestText": "Fenisi prova", + "exitGameText": "Sortisi da'l zugo", + "exitToMenuText": "Vutu tornar inte'l menù?", + "howToPlayText": "Come zugar", + "justPlayerText": "(Soło par ${NAME})", + "leaveGameText": "Moła łeveło", + "leavePartyConfirmText": "Vutu dabon ndar fora da'l grupo?", + "leavePartyText": "Moła grupo", + "quitText": "Sortisi", + "resumeText": "Continua", + "settingsText": "Inpostasion" + }, + "makeItSoText": "Àplega", + "mapSelectGetMoreMapsText": "Otien pì łevełi...", + "mapSelectText": "Sełesiona...", + "mapSelectTitleText": "Łevełi ${GAME}", + "mapText": "Łeveło", + "maxConnectionsText": "Łìmite conesion", + "maxPartySizeText": "Łìmite grandesa grupo", + "maxPlayersText": "Łìmite zugadori", + "modeArcadeText": "Modałidà arcade", + "modeClassicText": "Modałidà clàsega", + "modeDemoText": "Modałidà demo", + "mostValuablePlayerText": "Zugador pì zgajo", + "mostViolatedPlayerText": "Zugador pì sacagnà", + "mostViolentPlayerText": "Zugador pì viołento", + "moveText": "Movi", + "multiKillText": "CAENA DE ${COUNT} FATI FORA!!!!!", + "multiPlayerCountText": "${COUNT} zugadori", + "mustInviteFriendsText": "Nota: A te ghè da invidar i amighi\nso'l paneło \"${GATHER}\" o picar pì\ncontroładori par zugar in multizugador.", + "nameBetrayedText": "${NAME} gà tradìo ${VICTIM}.", + "nameDiedText": "${NAME} ze crepà.", + "nameKilledText": "${NAME} gà copà ${VICTIM}.", + "nameNotEmptyText": "El nome no'l połe miga star vodo!", + "nameScoresText": "Un ponto par ${NAME}!", + "nameSuicideKidFriendlyText": "${NAME} par zbałio L ze crepà.", + "nameSuicideText": "${NAME} l'se gà eutanà.", + "nameText": "Nome", + "nativeText": "Nadiva", + "newPersonalBestText": "Novo record parsonałe!", + "newTestBuildAvailableText": "A ze disponìbiłe na varsion de proa nova. (${VERSION} beta ${BUILD}).\nDescàrgheła da ${ADDRESS}", + "newText": "Novo", + "newVersionAvailableText": "A ze disponìbiłe na varsion nova de ${APP_NAME}! (${VERSION})", + "nextAchievementsText": "Obietivi pròsemi:", + "nextLevelText": "Łeveło seguente", + "noAchievementsRemainingText": "- gnaun", + "noContinuesText": "(sensa continui)", + "noExternalStorageErrorText": "So ’sto dispozidivo no ze stà catada gnauna memoria esterna", + "noGameCircleText": "Eror: no te si miga conetesto co GameCircle", + "noScoresYetText": "Gnancora gnaun puntejo.", + "noThanksText": "Nò, grasie", + "noTournamentsInTestBuildText": "AVERTENSA: i punteji de'l tornèo de 'sta varsion de proa i vegnarà ignorài.", + "noValidMapsErrorText": "A no ze stà catà gnaun łeveło vàłido par 'sto tipo de zugo.", + "notEnoughPlayersRemainingText": "A no ghe ze pì zugadori che basta: sortisi e taca na partìa nova.", + "notEnoughPlayersText": "A serve almanco ${COUNT} zugadori par tacar 'sta partìa!", + "notNowText": "Miga deso", + "notSignedInErrorText": "Par partesipar A te ghè da conétarte.", + "notSignedInGooglePlayErrorText": "Far farlo A te ghè da conétarte co Google Play.", + "notSignedInText": "gnancora cołegà", + "notUsingAccountText": "Ocio: ze stà łasà in parte l'account ${SERVICE}.\nSe te vołi dopararlo và so 'Account > Acedi co ${SERVICE}'.", + "nothingIsSelectedErrorText": "A no ze sełesionà gnente!", + "numberText": "#${NUMBER}", + "offText": "Dezativa", + "okText": "Và ben", + "onText": "Ativa", + "oneMomentText": "Un segondo...", + "onslaughtRespawnText": "Rejenerasion de ${PLAYER} inte l'ondada ${WAVE}", + "orText": "${A} o ${B}", + "otherText": "Altro...", + "outOfText": "(#${RANK} de ${ALL})", + "ownFlagAtYourBaseWarning": "Par far punti ła to bandiera\nła gà da èsar so ła to baze!", + "packageModsEnabledErrorText": "El zugo in rede no'l ze miga parmeso co A ze ativi i pacheti mod łogałi (varda so Inpostasion > Avansàe)", + "partyWindow": { + "chatMessageText": "Mesaji", + "emptyText": "El to grupo el ze vodo", + "hostText": "(ospitador)", + "sendText": "Manda", + "titleText": "El to grupo" + }, + "pausedByHostText": "(sospezo da l'ospitador)", + "perfectWaveText": "Ondada parfeta!", + "pickUpText": "Łeva sù", + "playModes": { + "coopText": "Cooperadiva", + "freeForAllText": "Tuti contro tuti", + "multiTeamText": "Multi-scuadra", + "singlePlayerCoopText": "Un zugador / Cooperadiva", + "teamsText": "Scuadre" + }, + "playText": "Zuga", + "playWindow": { + "oneToFourPlayersText": "1-4 zugadori", + "titleText": "Zuga", + "twoToEightPlayersText": "2-8 zugadori" + }, + "playerCountAbbreviatedText": "${COUNT}z", + "playerDelayedJoinText": "Co tacarà el turno che'l vien A se zontarà anca ${PLAYER}.", + "playerInfoText": "Informasion zugador", + "playerLeftText": "${PLAYER} gà mołà el łeveło.", + "playerLimitReachedText": "Nùmaro màsemo de ${COUNT} zugadori: A no połe zontarse pì nesun.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "A no te połi miga ełimenar el profiło prinsipałe de'l to account.", + "deleteButtonText": "Ełìmena\nprofiło", + "deleteConfirmText": "Vutu ełimenar '${PROFILE}'?", + "editButtonText": "Muda\nprofiło", + "explanationText": "(nomi e parense parsonałizàe par 'sto account)", + "newButtonText": "Novo\nprofiło", + "titleText": "Profiłi zugador" + }, + "playerText": "Zugador", + "playlistNoValidGamesErrorText": "'Sta łista de zugo ła gà rento łevełi dezblocài mìa vàłidi.", + "playlistNotFoundText": "łista de zugo mìa catada", + "playlistText": "Łista de zugo", + "playlistsText": "Łiste de zugo", + "pleaseRateText": "Se ${APP_NAME} el ze drio piazerte, tote un àtemo par\nłasarghe zó na vałudasion o scrìvarghe zó un comento. 'Ste\nopinion łe tornarà còmode par dezviłupi fuduri de'l zugo.\n\ngrasie!\n-eric", + "pleaseWaitText": "Speta n'àtemo...", + "pluginClassLoadErrorText": "Eror de cargamento de ła clase de estension '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Eror de inisiałizasion de l'estension '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Estension nove rełevàe. Retaca el zugo par ativarle, o configùrełe so łe inpostasion.", + "pluginsRemovedText": "Estension miga catàe: ${NUM}", + "pluginsText": "Estension", + "practiceText": "Pràtega", + "pressAnyButtonPlayAgainText": "Struca un boton calsìase par zugar danovo...", + "pressAnyButtonText": "Struca un boton calsìase par ndar vanti...", + "pressAnyButtonToJoinText": "struca un boton calsìase par zontarte...", + "pressAnyKeyButtonPlayAgainText": "Struca un boton calsìase par zugar danovo...", + "pressAnyKeyButtonText": "Struca un boton calsìase par ndar vanti...", + "pressAnyKeyText": "Struca un boton calsìase...", + "pressJumpToFlyText": "** Sèvita strucar SALTO par zvołar **", + "pressPunchToJoinText": "struca CROGNO par zontarte...", + "pressToOverrideCharacterText": "struca ${BUTTONS} par renpiasar el to parsonajo", + "pressToSelectProfileText": "struca ${BUTTONS} par sernir un profiło zugador", + "pressToSelectTeamText": "struca ${BUTTONS} par sernir na scuadra", + "promoCodeWindow": { + "codeText": "Còdaze", + "enterText": "Dòpara" + }, + "promoSubmitErrorText": "Eror de trazmision de'l còdaze: controła ła to conesion internet", + "ps3ControllersWindow": { + "macInstructionsText": "Stua ła corente so'l dadrìo de ła to PS3, segùrate che'l\nbluetooth de'l to Mac el sipie ativà, daspò coneti el to controłador\na'l to Mac co un cavo USB par cubiarli. Da deso in vanti te\npołi doparar el boton \"cao\" de'l controłador par conétarlo co'l to\nMac in modałidà USB (co'l fiło) o bluetooth (sensa fiło).\n\nPar el cubiamento calche Mac el podarìa dimandarte un còdaze.\nSe càpida, varda ła demostrasion seguente o serca juto so Google.\n\n\n\n\nI controładori PS3 conetesti sensa fiło i gavarìa da védarse inte ła łista\nde'l dispozidivo so Prefarense de sistema > Bluetooth. Co te vorè\ndopararli danovo so ła to PS3, te podarisi ver da cavarli vìa da 'sta łista.\n\nSegùrate anca de desconétarli da'l bluetooth co no te łi\ndòpari o łe só batarìe łe sevitarà a sconsumarse.\n\nEl bluetooth el gavarìa da suportar fin a 7 dispozidivi conetesti,\nanca se ła capasidà ła podarìa variar.", + "ouyaInstructionsText": "Par doparar un controłador PS3 co ła to OUYA, conéteło co un cavo USB par\ncubiarlo. 'Sta asion ła podarìa desconétar cheł'altri to controładori, donca\nA podarìa servirte retacar ła to OUYA e destacar el cavo USB.\n\nDa deso in vanti A te dovarisi èsar bon de doparar el boton \"cao\" de'l\ncontrołador par conétarlo sensa fiło. Co A te ghè fenìo de zugar, tien\nstrucà el boton \"cao\" par 10 segondi par stuar el controłador, el\npodarìa restar inpisà e stracar ła batarìa.", + "pairingTutorialText": "demostrasion video pa'l cubiamento", + "titleText": "Doparar un controłador PS3 co ${APP_NAME}:" + }, + "punchBoldText": "CROGNO", + "punchText": "Crogno", + "purchaseForText": "Cronpa par ${PRICE}", + "purchaseGameText": "Cronpa el zugo", + "purchasingText": "Cronpa in corso...", + "quitGameText": "Vutu sortir da ${APP_NAME}?", + "quittingIn5SecondsText": "Sortìa tenpo 5 segondi...", + "randomPlayerNamesText": "Toni, Bepi, Ciano, Ico, Tisio, Senpronio, Cajo, Ciorci, Ucio, Tòio, Stełio, Duiłio, Mariza, Sunta, Tano, Tilde, Piero, Neno, Nena, Momi, Ménego, Łełe, Jani, Jaco, Cicio, Giza, Checo, Bice, Beta, Gneze, Àndoło, Jijo, Aneta, Bórtoło, Metrio, Gidio, Gnegno, Baldi, Icio, Nane, Tano, Jema, Maria, Zezi, Giobata, Marco, Nicołò, Orsoła, Fosca, Zeno, Almorò, Zuan, Poło, Bazejo, Tòdaro, Micel, Zanze, Elvira, Zita, Dora, Noemi, Irma, Elda, Stae, Mirałio, Zerlin, Dardi, Ełide", + "randomText": "A stin", + "rankText": "Pozision", + "ratingText": "Vałudasion", + "reachWave2Text": "Riva so ła segonda ondada par clasifegarte.", + "readyText": "aposto", + "recentText": "Resenti", + "remoteAppInfoShortText": "Co A se zuga a ${APP_NAME} co fameja e amighi A se se ła\ngode de pì. Coneti uno o pì controładori fìzeghi o instała l'apl\n${REMOTE_APP_NAME} so tełèfoni o tołeti par dopararli cofà\ncontroładori.", + "remote_app": { + "app_name": "BombSquad Remote", + "app_name_short": "BSRemote", + "button_position": "Pozision botoni", + "button_size": "Grandesa botoni", + "cant_resolve_host": "A no ze mìa posìbiłe catar fora l'ospitador.", + "capturing": "Drio spetar i zugadori…", + "connected": "Conetesto.", + "description": "Dòpara el to tełèfono o tołeto cofà controłador par BombSquad.\nPołe conétarse so un schermo ùgnoło fin a 8 dispozidivi insenbre, par un feston bueło multizugador!", + "disconnected": "Desconetesto da'l server.", + "dpad_fixed": "fiso", + "dpad_floating": "mòbiłe", + "dpad_position": "Pozision croze deresionałe", + "dpad_size": "Grandesa croze deresionałe", + "dpad_type": "Tipo de croze deresionałe", + "enter_an_address": "Insarisi ndariso", + "game_full": "El zugo el ze pien o no l'aceta conesion.", + "game_shut_down": "El zugo el se gà stuà.", + "hardware_buttons": "Botoni fìzeghi", + "join_by_address": "Zóntate par ndariso...", + "lag": "Lag: ${SECONDS} segondi", + "reset": "Reinposta", + "run1": "Corsa 1", + "run2": "Corsa 2", + "searching": "Reserca partìe de BombSquad…", + "searching_caption": "Toca el nome de ła partìa par zontarte.\nSegùrate de èsar so ła mèdema rede wifi de ła partìa.", + "start": "Taca", + "version_mismatch": "Varsion zbałiada.\nSegùrate che BombSquad e BombSquad Remote i\nsipie ajornài a ła varsion ùltema e proa danovo." + }, + "removeInGameAdsText": "Par cavar vìa łe reclan, dezbloca \"${PRO}\" inte ła botega.", + "renameText": "Renòmena", + "replayEndText": "Sara sù Revardo", + "replayNameDefaultText": "Revardo partìa ùltema", + "replayReadErrorText": "Eror de łedura de'l file de revardo.", + "replayRenameWarningText": "Par salvar na partìa fenìa, renòmena \"${REPLAY}\". Senò te sevitarè sorascrìvarle.", + "replayVersionErrorText": "Ne despiaze, 'sto revardo el ze stà fato co na varsion\nde'l zugo defarente e no'l połe mìa èsar doparà.", + "replayWatchText": "Varda revardo", + "replayWriteErrorText": "Eror de salvatajo de'l revardo.", + "replaysText": "Revardi", + "reportPlayerExplanationText": "Dòpara 'sta mail par segnałar inbroji, łenguaji ofansivi o altri conportamenti bruti.\nZonta na descrision soto chive:", + "reportThisPlayerCheatingText": "Inbrojo", + "reportThisPlayerLanguageText": "Łenguajo ofansivo", + "reportThisPlayerReasonText": "'Sa ghetu caro segnałar?", + "reportThisPlayerText": "Segnała 'sto zugador", + "requestingText": "Drio far domanda...", + "restartText": "Retaca", + "retryText": "Reproa", + "revertText": "Anuła", + "runText": "Cori", + "saveText": "Salva", + "scanScriptsErrorText": "Tirando sù i script A se gà catà erori: varda el rejistro eventi par i detaji.", + "scoreChallengesText": "Puntejo sfide", + "scoreListUnavailableText": "Łista de puntejo mìa disponìbiłe.", + "scoreText": "Puntejo", + "scoreUnits": { + "millisecondsText": "Miłesegondi", + "pointsText": "Punti", + "secondsText": "Segondi" + }, + "scoreWasText": "(prima ${COUNT})", + "selectText": "Sełesiona", + "seriesWinLine1PlayerText": "GÀ VINTO ŁA", + "seriesWinLine1TeamText": "GÀ VINTO ŁA", + "seriesWinLine1Text": "GÀ VINTO ŁA", + "seriesWinLine2Text": "DESFIDA!", + "settingsWindow": { + "accountText": "Account", + "advancedText": "Avansàe", + "audioText": "Àudio", + "controllersText": "Controładori", + "graphicsText": "Gràfega", + "playerProfilesMovedText": "Nota: \"Profiłi zugador\" el ze stà spostà rento ła sesion \"Account\" inte'l menù prinsipałe.", + "titleText": "Inpostasion" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(na botonera so schermo, senpia e còmoda, par scrìvar testi)", + "alwaysUseInternalKeyboardText": "Dòpara botonera integrada", + "benchmarksText": "Prestasion & Proe soto sforso", + "disableCameraGyroscopeMotionText": "Dezativa movimento de ła prospetiva łigada a'l jiroscopio", + "disableCameraShakeText": "Dezativa i zgorlamenti de ła videocàmara", + "disableThisNotice": "(A te połi dezativar 'sta notìfega inte łe inpostasion avansàe)", + "enablePackageModsDescriptionText": "(l'ativasion de ła capasidà de modifegasion ła dezativa el zugo in rede)", + "enablePackageModsText": "Ativa pacheti mod łogałi", + "enterPromoCodeText": "Insarisi còdaze", + "forTestingText": "Nota: vałori vàłidi soło par proe. Sortendo da l'apl łi vegnarà perdesti.", + "helpTranslateText": "Łe tradusion de ${APP_NAME} łe ze curàe da vołontari.\nSe te vołi darghe na ociada a cheła veneta, struca so'l boton\ncuà soto. Curada da VeC: venetianlanguage@gmail.com", + "kickIdlePlayersText": "Para fora zugadori in sonera", + "kidFriendlyModeText": "Modałidà bocia (viołensa reduzesta, evc)", + "languageText": "Łengua", + "moddingGuideText": "Guida par modifegasion", + "mustRestartText": "Par rèndar efetive łe modìfeghe, A te ghè da retacar el zugo.", + "netTestingText": "Proa de rede", + "resetText": "Reinposta", + "showBombTrajectoriesText": "Mostra trajetore bonbe", + "showPlayerNamesText": "Mostra nomi zugadori", + "showUserModsText": "Mostra carteła modifegasion", + "titleText": "Avansàe", + "translationEditorButtonText": "Piataforma de tradusion de ${APP_NAME}", + "translationFetchErrorText": "stado de ła tradusion mìa disponìbiłe", + "translationFetchingStatusText": "controło stado de ła tradusion...", + "translationInformMe": "Infòrmame co A ghe ze tochi novi da tradùzar", + "translationNoUpdateNeededText": "ła tradusion in veneto ła ze aposto: un aereo!", + "translationUpdateNeededText": "** A ghe ze testi novi da tradùzar!! **", + "vrTestingText": "Proa VR" + }, + "shareText": "Sparpagna", + "sharingText": "Sparpagnasion...", + "showText": "Mostra", + "signInForPromoCodeText": "Conétate co un account par poder far funsionar el còdaze.", + "signInWithGameCenterText": "Par doparar un account Game Center,\nconétate da rento l'apl Game Center.", + "singleGamePlaylistNameText": "Tuti \"${GAME}\"", + "singlePlayerCountText": "1 zugador", + "soloNameFilterText": "\"${NAME}\" 1 VS 1", + "soundtrackTypeNames": { + "CharSelect": "Sełesion parsonajo", + "Chosen One": "L'ełeto", + "Epic": "Zughi in movensa camoma", + "Epic Race": "Corsa camoma", + "FlagCatcher": "Brinca ła bandiera", + "Flying": "Pensieri contenti", + "Football": "Football", + "ForwardMarch": "Asalto", + "GrandRomp": "Conchista", + "Hockey": "Hockey", + "Keep Away": "Tien distante", + "Marching": "Mena torno", + "Menu": "Menù prinsipałe", + "Onslaught": "Dezìo", + "Race": "Corsa", + "Scary": "Re de'l col", + "Scores": "Schermada puntejo", + "Survival": "Ełimenasion", + "ToTheDeath": "Scontro mortałe", + "Victory": "Schermada puntejo fenałe" + }, + "spaceKeyText": "spasio", + "statsText": "Statìsteghe", + "storagePermissionAccessText": "A serve el parmeso de aceso a ła memoria", + "store": { + "alreadyOwnText": "${NAME} dezà cronpà!", + "bombSquadProNameText": "${APP_NAME} Pro", + "bombSquadProNewDescriptionText": "• El cava vìa i anunsi e łe reclan\n• El dezbloca tute łe funsion de'l zugo\n• El te dà anca:", + "buyText": "Cronpa", + "charactersText": "Parsonaji", + "comingSoonText": "E presto...", + "extrasText": "Extra", + "freeBombSquadProText": "Daromài BombSquad el ze gratis, ma visto che te ło ghivi dezà cronpà prima,\nte vegnarà dezblocà el mejoramento BombSquad Pro e te vegnarà zontài ${COUNT}\nbiłieti cofà rengrasiamento. Gòdate łe funsion nove, e grasie de'l to suporto!\n-Eric", + "holidaySpecialText": "Spesiałe feste", + "howToSwitchCharactersText": "(và so \"${SETTINGS} > ${PLAYER_PROFILES}\" par sernir i to parsonaji e parsonałizarli)", + "howToUseIconsText": "(par dopararle, crea un profiło zugador globałe inte ła sesion account)", + "howToUseMapsText": "(dòpara 'sti łevełi inte łe to łiste de zugo: scuadre/tuti contro tuti)", + "iconsText": "Icone", + "loadErrorText": "A no ze mìa posìbiłe cargar ła pàjina.\nDaghe na ociada a ła to conesion internet.", + "loadingText": "cargamento", + "mapsText": "Łevełi", + "miniGamesText": "Minizughi", + "oneTimeOnlyText": "(ocazion ùgnoła)", + "purchaseAlreadyInProgressText": "Cronpa de 'sto ojeto dezà drio conpirse.", + "purchaseConfirmText": "Vutu cronpar ${ITEM}?", + "purchaseNotValidError": "Cronpa mìa vàłida.\nSe'l ze un eror, contata ${EMAIL}.", + "purchaseText": "Cronpa", + "saleBundleText": "Pacheto in oferta!", + "saleExclaimText": "Oferta!", + "salePercentText": "(${PERCENT}% de manco)", + "saleText": "SCONTI", + "searchText": "Serca", + "teamsFreeForAllGamesText": "Par zughi a Scuadre / Tuti contro tuti", + "totalWorthText": "*** Un vałor de ${TOTAL_WORTH} a soło ***", + "upgradeQuestionText": "Mejorar BombSquad?", + "winterSpecialText": "Spesiałe inverno", + "youOwnThisText": "- dezà tuo -" + }, + "storeDescriptionText": "Feston bueło a 8 zugadori!\n\nFà saltar par aria i to amighi (o el computer) inte un tornèo de minizughi cofà 'Brinca ła bandiera', 'Scravaso de stełe' o 'Scontri mortałi' in movensa camoma!\n\nFin a 8 parsone łe sarà bone de batajar insenbre, grasie a comandi senpi e a ła conpatibiłidà co tanti controładori. Co l'apl gratùida 'BombSquad Remote' te połi parfin doparar i to dispozidivi mòbiłi cofà controładori!\n\nE deso... tira fora łe bonbe!\n\nPar informasion in pì daghe na ociada so www.froemling.net/bombsquad.", + "storeDescriptions": { + "blowUpYourFriendsText": "Fà sciopar par aria i to amighi.", + "competeInMiniGamesText": "Zuga co tanti minizughi: da corse a zvołi.", + "customize2Text": "Parsonałiza parsonaji, minizughi, o anca i son de fondo.", + "customizeText": "Parsonałiza i parsonaji e crea łe to łiste de minizughi.", + "sportsMoreFunText": "Inte i sport A se se ła gode de pì co i esprozivi.", + "teamUpAgainstComputerText": "Cołàbora contro el computer." + }, + "storeText": "Botega", + "submitText": "Manda", + "submittingPromoCodeText": "Trazmision còdaze...", + "teamNamesColorText": "Nome/Cołor scuadra...", + "telnetAccessGrantedText": "Aceso a telnet ativà.", + "telnetAccessText": "Rełevà aceso a telnet: vutu autorizarlo?", + "testBuildErrorText": "'Sta varsion de proa no ła ze miga pì ativa. Controła se A ghin ze una pì resente.", + "testBuildText": "Varsion de proa", + "testBuildValidateErrorText": "A no ze mìa posìbiłe varifegar ła varsion de proa. (gnauna conesion a internet?)", + "testBuildValidatedText": "Varsion de proa aposto. Gòdateła!", + "thankYouText": "Grasie par el to suporto! Gùstate el zugo!", + "threeKillText": "NO GHE N'È 2 SENSA 3!!", + "timeBonusText": "Tenpo bonus", + "timeElapsedText": "Tenpo pasà", + "timeExpiredText": "Tenpo fenìo", + "timeSuffixDaysText": "${COUNT}d", + "timeSuffixHoursText": "${COUNT}o", + "timeSuffixMinutesText": "${COUNT}m", + "timeSuffixSecondsText": "${COUNT}s", + "tipText": "Drita", + "titleText": "BombSquad", + "titleVRText": "BombSquad VR", + "topFriendsText": "Mejori amighi", + "tournamentCheckingStateText": "Verìfega stado de'l tornèo: speta n'àtemo...", + "tournamentEndedText": "'Sto tornèo el ze fenìo. A ghin tacarà presto uno novo.", + "tournamentEntryText": "Entrada tornèo", + "tournamentResultsRecentText": "Rezultài tornèi resenti", + "tournamentStandingsText": "Clasìfega tornèo", + "tournamentText": "Tornèo", + "tournamentTimeExpiredText": "Tenpo de'l tornèo fenìo!", + "tournamentsDisabledWorkspaceText": "Co te ghè modifegasion ative i tornèi i vien dezativài.\nPar ativarli danovo, dezativa łe modifegasion e retaca l'apl.", + "tournamentsText": "Tornèi", + "translations": { + "characterNames": { + "Agent Johnson": "Ajente Johnson", + "B-9000": "B-9000", + "Bernard": "Pùpoło", + "Bones": "Oseto", + "Butch": "Vacher", + "Easter Bunny": "Cunicio de Pascua", + "Flopsy": "Jévare", + "Frosty": "Zgrìzoło", + "Gretel": "Reitia", + "Grumbledorf": "Silendalf", + "Jack Morgan": "Cap. Canaja", + "Kronk": "Sciavon", + "Lee": "Tàng", + "Lucky": "Masaroło", + "Mel": "Cogo", + "Middle-Man": "Gnagno", + "Minimus": "Antènore", + "Pascal": "Pinghin", + "Pixel": "Fada", + "Sammy Slam": "Tentori", + "Santa Claus": "Pupà Nadal", + "Snake Shadow": "Bison", + "Spaz": "Fagin", + "Taobao Mascot": "Mascot Taobao", + "Todd McBurton": "Mc Tresà", + "Zoe": "Sone", + "Zola": "Màsone" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} - łenamento", + "Infinite ${GAME}": "${GAME} - sensa fine", + "Infinite Onslaught": "Dezìo - sensa fine", + "Infinite Runaround": "Mena torno - sensa fine", + "Onslaught Training": "Dezìo - łenamento", + "Pro ${GAME}": "${GAME} - pro", + "Pro Football": "Football - pro", + "Pro Onslaught": "Dezìo - pro", + "Pro Runaround": "Mena torno - pro", + "Rookie ${GAME}": "${GAME} - novisià", + "Rookie Football": "Football - novisià", + "Rookie Onslaught": "Dezìo - novisià", + "The Last Stand": "Resta in pie", + "Uber ${GAME}": "${GAME} - ultra", + "Uber Football": "Football - ultra", + "Uber Onslaught": "Dezìo - ultra", + "Uber Runaround": "Mena torno - ultra" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Copa l'ełeto par ciapar el só posto!\nPar vìnsar resta l'ełeto par un serto tenpo.", + "Bomb as many targets as you can.": "Bonbarda tuti i sentri che A te pol!", + "Carry the flag for ${ARG1} seconds.": "Tiente ła bandiera par ${ARG1} segondi.", + "Carry the flag for a set length of time.": "Tiente ła bandiera par un serto tenpo.", + "Crush ${ARG1} of your enemies.": "Copa ${ARG1} nemighi.", + "Defeat all enemies.": "Copa tuti i nemighi.", + "Dodge the falling bombs.": "A piove bonbe: schìvełe tute.", + "Final glorious epic slow motion battle to the death.": "Bataja fenałe, èpega e mortałe, in movensa camoma.", + "Gather eggs!": "Rancura sù i ovi!", + "Get the flag to the enemy end zone.": "Roba ła bandiera da ła baze nemiga.", + "How fast can you defeat the ninjas?": "A che vełosidà coparetu tuti i ninja?", + "Kill a set number of enemies to win.": "Copa un serto nùmaro de nemighi par vìnsar.", + "Last one standing wins.": "L'ùltemo a restar in pie el vinse.", + "Last remaining alive wins.": "L'ùltemo a restar vivo el vinse.", + "Last team standing wins.": "L'ùltema scuadra in pie ła vinse.", + "Prevent enemies from reaching the exit.": "Inpedisi che i nemighi i rive so ła sortìa.", + "Reach the enemy flag to score.": "Riva a ła bandiera de i nemighi par far ponto.", + "Return the enemy flag to score.": "Torna co ła bandiera nemiga par far ponto.", + "Run ${ARG1} laps.": "Cori par ${ARG1} jiri.", + "Run ${ARG1} laps. Your entire team has to finish.": "Cori par ${ARG1} jiri. Tuta ła to scuadra ła gà da fenirli.", + "Run 1 lap.": "Cori par 1 jiro.", + "Run 1 lap. Your entire team has to finish.": "Cori par 1 jiro. Tuta ła to scuadra ła gà da fenirlo.", + "Run real fast!": "Cori fà na foina!", + "Score ${ARG1} goals.": "Piasa ${ARG1} gol.", + "Score ${ARG1} touchdowns.": "Piasa ${ARG1} touchdown.", + "Score a goal.": "Piasa un gol.", + "Score a touchdown.": "Piasa un touchdown.", + "Score some goals.": "Piasa racuanti gol.", + "Secure all ${ARG1} flags.": "Proteji tute ${ARG1} łe bandiere.", + "Secure all flags on the map to win.": "Proteji tute łe bandiere de'l łeveło par vìnsar.", + "Secure the flag for ${ARG1} seconds.": "Proteji ła bandiera par ${ARG1} segondi.", + "Secure the flag for a set length of time.": "Proteji ła bandiera par un serto tenpo.", + "Steal the enemy flag ${ARG1} times.": "Roba ${ARG1} 'olte ła bandiera nemiga.", + "Steal the enemy flag.": "Roba ła bandiera nemiga.", + "There can be only one.": "A połe èsarghine soło un.", + "Touch the enemy flag ${ARG1} times.": "Toca ${ARG1} 'olte ła bandiera nemiga.", + "Touch the enemy flag.": "Toca ła bandiera nemiga.", + "carry the flag for ${ARG1} seconds": "tiente ła bandiera par ${ARG1} segondi", + "kill ${ARG1} enemies": "Copa ${ARG1} nemighi", + "last one standing wins": "l'ùltemo a restar in pie el vinse", + "last team standing wins": "l'ùltema scuadra a restar in pie ła vinse", + "return ${ARG1} flags": "torna co ${ARG1} bandiere", + "return 1 flag": "torna co 1 bandiera", + "run ${ARG1} laps": "cori par ${ARG1} jiri", + "run 1 lap": "cori par 1 jiro", + "score ${ARG1} goals": "piasa ${ARG1} gol", + "score ${ARG1} touchdowns": "piasa ${ARG1} touchdown", + "score a goal": "piasa un gol", + "score a touchdown": "piasa un touchdown", + "secure all ${ARG1} flags": "proteji tute ${ARG1} łe bandiere", + "secure the flag for ${ARG1} seconds": "proteji ła bandiera par ${ARG1} segondi", + "touch ${ARG1} flags": "toca ${ARG1} bandiere", + "touch 1 flag": "toca 1 bandiera" + }, + "gameNames": { + "Assault": "Asalto", + "Capture the Flag": "Brinca ła bandiera", + "Chosen One": "L'ełeto", + "Conquest": "Conchista", + "Death Match": "Scontro mortałe", + "Easter Egg Hunt": "Casador de ovi", + "Elimination": "Ełimenasion", + "Football": "Football", + "Hockey": "Hockey", + "Keep Away": "Tien distante", + "King of the Hill": "Re de'l col", + "Meteor Shower": "Scravaso de stełe", + "Ninja Fight": "Petuche ninja", + "Onslaught": "Dezìo", + "Race": "Corsa", + "Runaround": "Mena torno", + "Target Practice": "Pràtega de tiro", + "The Last Stand": "Resta in pie" + }, + "inputDeviceNames": { + "Keyboard": "Botonera", + "Keyboard P2": "Botonera Z2" + }, + "languages": { + "Arabic": "Àrabo", + "Belarussian": "Bełoruso", + "Chinese": "Sineze senplifegà", + "ChineseTraditional": "Sineze tradisionałe", + "Croatian": "Croà", + "Czech": "Ceco", + "Danish": "Daneze", + "Dutch": "Ołandeze", + "English": "Ingleze", + "Esperanto": "Esperanto", + "Filipino": "Fiłipin", + "Finnish": "Fiłandeze", + "French": "Franseze", + "German": "Todesco", + "Gibberish": "Tabascà", + "Greek": "Grego", + "Hindi": "Hindi", + "Hungarian": "Ongareze", + "Indonesian": "Indonezian", + "Italian": "Itałian", + "Japanese": "Japoneze", + "Korean": "Corean", + "Persian": "Persian", + "Polish": "Połaco", + "Portuguese": "Portogheze", + "Romanian": "Romen", + "Russian": "Ruso", + "Serbian": "Serbo", + "Slovak": "Zlovaco", + "Spanish": "Spagnoło", + "Swedish": "Zvedeze", + "Tamil": "Tamil", + "Thai": "Thailandeze", + "Turkish": "Turco", + "Ukrainian": "Ucrain", + "Venetian": "Veneto", + "Vietnamese": "Vietnamita" + }, + "leagueNames": { + "Bronze": "Bronzo", + "Diamond": "Damante", + "Gold": "Oro", + "Silver": "Arzento" + }, + "mapsNames": { + "Big G": "G granda", + "Bridgit": "Pontezeło", + "Courtyard": "Corte", + "Crag Castle": "Tori zemełe", + "Doom Shroom": "Fongo de ła danasion", + "Football Stadium": "Stadio de football", + "Happy Thoughts": "Antigravidà", + "Hockey Stadium": "Stadio de hockey", + "Lake Frigid": "Łago injasà", + "Monkey Face": "Testa de simia", + "Rampage": "Ła ranpa", + "Roundabout": "Tranpołini", + "Step Right Up": "Sù e Zó", + "The Pad": "L'altopian", + "Tip Top": "Fortesa", + "Tower D": "Muraja", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Ndemo camomi", + "Just Sports": "Ndemo de sport" + }, + "scoreNames": { + "Flags": "Bandiere", + "Goals": "Gol", + "Score": "Puntejo", + "Survived": "Soravivesto", + "Time": "Tenpo", + "Time Held": "Tenpo tegnùa" + }, + "serverResponses": { + "A code has already been used on this account.": "So 'sto profiło A ze dezà stà doparà un còdaze.", + "A reward has already been given for that address.": "Par 'sto ndariso A ze dezà stà dà na reconpensa.", + "Account linking successful!": "Profiło cołegà co suceso!", + "Account unlinking successful!": "Profiło descołegà co suceso!", + "Accounts are already linked.": "I profiłi i ze dezà cołegài.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "No ze stà posìbiłe verifegar che te ghè vardà ła reclan.\nSegùrate de èsar drio doparar na varsion de'l zugo ofisiałe e ajornada.", + "An error has occurred; (${ERROR})": "A se gà verifegà un eror: (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "A se gà verifegà un eror: contata l'asistensa. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "A se gà verifegà un eror: contata support@froemling.net.", + "An error has occurred; please try again later.": "A se gà verifegà un eror: proa danovo pì tardi.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Vutu dabon cołegar 'sti profiłi?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\n'Sta asion no ła połe pì èsar anułada!", + "BombSquad Pro unlocked!": "BombSquad Pro dezblocà!", + "Can't link 2 accounts of this type.": "A no se połe mìa cołegar 2 profiłi de 'sto tipo.", + "Can't link 2 diamond league accounts.": "A no se połe mìa cołegar 2 profiłi de ła łega de damante.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "A no se połe mìa cołegarlo: A ze dezà stà cołegài un màsemo de ${COUNT} profiłi.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Rełevà un inbrojo: punteji e premi sospendesti par ${COUNT} dì.", + "Could not establish a secure connection.": "A no ze mìa posìbiłe stabiłir na conesion segura.", + "Daily maximum reached.": "Màsemo jornałiero pasà.", + "Entering tournament...": "Entrada inte'l tornèo...", + "Invalid code.": "Còdaze mìa vàłido.", + "Invalid payment; purchase canceled.": "Pagamento miga vàłido: cronpa anułada.", + "Invalid promo code.": "Còdaze promosionałe mìa vàłido.", + "Invalid purchase.": "Cronpa mìa vàłida.", + "Invalid tournament entry; score will be ignored.": "Entrada inte'l tornèo mìa vàłida: el puntejo el vegnarà ignorà.", + "Item unlocked!": "Ojeto dezblocà!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "COŁEGAMENTO REFUDÀ. ${ACCOUNT} el contien dati\ninportanti che i ndarà PERDESTI.\nSe te vołi A te połi cołegarli in òrdane raverso\n(e pèrdar a'l só posto i dati de 'STO account cuà).", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Vutu dabon cołegar l'account ${ACCOUNT} a 'sto account?\nTuti i dati so ${ACCOUNT} i ndarà perdesti.\n'Sta asion no ła połe pì èsar anułada: vutu ndar vanti?", + "Max number of playlists reached.": "Nùmaro màsemo de łiste de scolto pasà.", + "Max number of profiles reached.": "Nùmaro màsemo de profiłi pasà.", + "Maximum friend code rewards reached.": "Brincà el nùmaro màsemo de premi da'l còdaze amigo.", + "Message is too long.": "Mesajo masa łongo.", + "No servers are available. Please try again soon.": "Gnaun server disponìbiłe. Proa pì tardi.", + "Profile \"${NAME}\" upgraded successfully.": "Profiło \"${NAME}\" mejorà co suceso.", + "Profile could not be upgraded.": "El profiło no'l połe mìa èsar mejorà.", + "Purchase successful!": "Cronpà co suceso!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "A te ghè resevesto ${COUNT} biłieti par ver verto el zugo.\nTorna anca doman par brincàrghine ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Ła funsionałidà de'l server no ła ze mìa pì suportada inte 'sta varsion de'l zugo.\nAjòrneło a ła varsion nova.", + "Sorry, there are no uses remaining on this code.": "Ne despiaze, 'sto còdaze el ze dezà stà doparà a'l màsemo.", + "Sorry, this code has already been used.": "Ne despiaze, 'sto còdaze el ze dezà stà doparà.", + "Sorry, this code has expired.": "Ne despiaze, ła vałidità de 'sto còdaze ła ze terminada.", + "Sorry, this code only works for new accounts.": "Ne despiaze, 'sto còdaze el funsiona soło so i account novi.", + "Still searching for nearby servers; please try again soon.": "Reserca de server visini in corso: proa danovo pì tardi.", + "Temporarily unavailable; please try again later.": "Par deso miga disponìbiłe: proa danovo pì tardi.", + "The tournament ended before you finished.": "El tornèo el ze terminà prima che te ghesi fenìo.", + "This account cannot be unlinked for ${NUM} days.": "'Sto account no'l połe mìa èsar descołegà prima de ${NUM} dì.", + "This code cannot be used on the account that created it.": "'Sto còdaze no'l połe mìa èsar doparà inte l'account che'l ło gà creà.", + "This is currently unavailable; please try again later.": "Par deso, funsion miga disponìbiłe. Proa danovo pì tardi.", + "This requires version ${VERSION} or newer.": "A ghe serve ła varsion ${VERSION} o una pì nova.", + "Tournaments disabled due to rooted device.": "Tornèi dezativài parvìa de'l dispozidivo co'l root.", + "Tournaments require ${VERSION} or newer": "Par i tornèi A serve ła varsion ${VERSION} o una pì resente", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Vutu descołegar l'account ${ACCOUNT} da 'sto account?\nTuti i dati de ${ACCOUNT} i vegnarà ełimenài.\n(obietivi a parte in calche cazo)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "AVERTENSA: el to account el ze stà segnałà par el dòparo de truchi.\nI zugaduri catài a doparar truchi i vegnarà blocài. Zuga da gałantomo.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Ghetu caro cołegar el to account łogałe co 'sto cuà?\n\nEl to account łogałe el ze ${ACCOUNT1}\n'Sto account el ze ${ACCOUNT2}\n\n'Sta oparasion ła te parmetarà de mantegner i to progresi ezistenti.\nOcio: 'sta asion no ła połe pì èsar anułada!", + "You already own this!": "Dezà cronpà!", + "You can join in ${COUNT} seconds.": "A te połi zontarte tenpo ${COUNT} segondi.", + "You don't have enough tickets for this!": "A no te ghè miga biłieti che basta par cronparlo!", + "You don't own that.": "Gnancora cronpà!", + "You got ${COUNT} tickets!": "A te ghè otegnesto ${COUNT} biłieti!", + "You got a ${ITEM}!": "A te ghè otegnesto un ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Promosion a ła łega suparior: congratułasion!", + "You must update to a newer version of the app to do this.": "Par ndar vanti A te ghè da ajornar l'apl a ła varsion pì resente.", + "You must update to the newest version of the game to do this.": "Par ndar vanti A te ghè da ajornar el zugo a ła varsion pì resente.", + "You must wait a few seconds before entering a new code.": "A te ghè da spetar calche segondo prima de insarir un còdaze novo.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Inte'l tornèo ùltemo A te si rivà #${RANK}. Grasie par ver zugà!", + "Your account was rejected. Are you signed in?": "El to account el ze stà refudà. Ghetu fato l'aceso?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Ła to copia de'l zugo ła ze stada modifegada.\nPar piaser, anuła łe modìfeghe e proa danovo.", + "Your friend code was used by ${ACCOUNT}": "El to còdaze amigo el ze stà doparà da ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 menuto", + "1 Second": "1 segondo", + "10 Minutes": "10 menuti", + "2 Minutes": "2 menuti", + "2 Seconds": "2 segondi", + "20 Minutes": "20 menuti", + "4 Seconds": "4 segondi", + "5 Minutes": "5 menuti", + "8 Seconds": "8 segondi", + "Allow Negative Scores": "Parmeti anca i punteji negadivi", + "Balance Total Lives": "Bałansa el nùmaro totałe de vide", + "Bomb Spawning": "Jenerasion bonbe", + "Chosen One Gets Gloves": "L'ełeto l'otien i guantoni", + "Chosen One Gets Shield": "L'ełeto l'otien el scudo", + "Chosen One Time": "Tenpo de l'ełeto", + "Enable Impact Bombs": "Ativa bonbe a inpato", + "Enable Triple Bombs": "Ativa bonbe triple", + "Entire Team Must Finish": "Tuta ła scuadra ła gà da fenir", + "Epic Mode": "Movensa camoma", + "Flag Idle Return Time": "Tenpo de retorno a bandiera ferma", + "Flag Touch Return Time": "Tenpo de retorno a bandiera tocada", + "Hold Time": "Tenpo de tegnùa", + "Kills to Win Per Player": "Copài par vìnsar par zugador", + "Laps": "Jiri", + "Lives Per Player": "Vide par zugador", + "Long": "Łonga", + "Longer": "Pì łonga", + "Mine Spawning": "Jenerasion mine", + "No Mines": "Sensa mine", + "None": "Gnaun", + "Normal": "Normałe", + "Pro Mode": "Modałidà pro", + "Respawn Times": "Tenpo de rejenerasion", + "Score to Win": "Puntejo par vìnsar", + "Short": "Curta", + "Shorter": "Pì curta", + "Solo Mode": "Modałidà zugador ùgnoło", + "Target Count": "Nùmaro de obietivi", + "Time Limit": "Łìmide de tenpo" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "Ła scuadra ${TEAM} ła ze scuałifegada parché ${PLAYER} gà mołà.", + "Killing ${NAME} for skipping part of the track!": "Copà ${NAME} par ver saltà un toco de'l parcorso!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Avertensa par ${NAME}: el turbo / spam co i botoni el te gà fato trar fora." + }, + "teamNames": { + "Bad Guys": "Cataràdeghi", + "Blue": "Blè", + "Good Guys": "Ałeài", + "Red": "Rosi" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Co'l justo tenpo de corsa, salto e rodasion, un crogno el połe copar inte un\ncolpo soło e farte vadagnar el respeto de i to amighi par tuta ła vida.", + "Always remember to floss.": "Recòrdate senpre de doparar el fiło intardentałe.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Invese de doparàrghine de fati a cazo, par ti e i to\namighi crea profiłi zugador co nomi e parense parsonałizàe.", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Łe case małedision łe te transforma inte na bonba a tenpo.\nA te połi curarte soło tołendo in presa un pacheto sałude.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Anca se drio ła siera A no par, łe abiłidà de tuti i parsonaji\nłe ze conpagne, donca tote sù cheło che'l te połe somejar de pì.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Mai far masa i gałeti co'l scudo nerjètego: A te połi uncora farte trar baso da na croda.", + "Don't run all the time. Really. You will fall off cliffs.": "No stà córar tuto el tenpo. Dabon. Te fenirè zó par na croda.", + "Don't spin for too long; you'll become dizzy and fall.": "No stà ndar torno par masa tenpo: te vegnarà na storniroła e te cascarè.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Tien strucà un boton calsìase par córar. (I griłeti nałòzeghi i ze i pì adati, se A te łi ghè)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Tien strucà un boton calsìase par córar. A te te movarè pì in\npresa ma no te voltarè miga masa ben, donca ocio a łe crode.", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Łe bonbe jaso no łe ze miga tanto potenti, ma łe injasa tuto cheło\nche łe brinca, e cheło che'l ze injasà el ze anca fàsiłe da fracasar.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Se calchedun el te łeva sù, daghe un crogno che'l te\nmołe zó. 'Sta roba ła funsiona anca inte ła vida vera.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Se te si a curto de controładori, instała l'apl '${REMOTE_APP_NAME}'\nso i to dispozidivi mòbiłi e dopàrełi cofà controładori.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Se na bonba petaisa ła te se taca doso, salta in volta e và torno: ła gavarìa da cavarse.\nE se no funsionase, i to momenti ùltemi de vida i gavarà almanco dà spetàgoło!", + "If you kill an enemy in one hit you get double points for it.": "Se A te copi un nemigo co un colpo soło A te ciapi el dupio de i punti.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Se A te ciapi na małedision, A te ghè soło na sparansa de salvesa:\ncatar fora un pacheto sałude inte i puchi segondi che A te resta.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Se A se stà fermi inte un posto, A se ze friti. Cori e schiva par soravìvar...", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Se te te cati tanti zugadori che và e vien, e inte'l cazo che calchedun el se dezménteghe de\nmołar el zugo, ativa ła funsion automàtega 'Para fora zugadori in sonera' inte łe inpostasion.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Se'l to dispozidivo el taca scotar o se te ghè caro sparagnar batarìa,\ncała ła \"Prospetiva\" o ła \"Resołusion\" so Inpostasion > Gràfega", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Se el zugo el và a scati, proa całar ła resołusion\no ła prospetiva inte l'inpostasion gràfega.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Par far ponto so 'Brinca ła bandiera', A te ghè da portar ła bandiera fin so ła to\nbaze. Se cheł'altra scuadra ła ze drio far ponto, A te połi fermarla anca robàndogheła.", + "In hockey, you'll maintain more speed if you turn gradually.": "Inte l'hockey, voltando gradualmente A te mantien alta ła vełosidà.", + "It's easier to win with a friend or two helping.": "A ze pì fàsiłe vìnsar se un amigo o do i te dà na man.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Co A te si drio tirar na bonba, salta par farla rivar pì alta posìbiłe.", + "Land-mines are a good way to stop speedy enemies.": "Łe mine łe ze fantàsteghe par fermar i nemighi pì ràpidi.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "A te połi łevar sù e tirar racuante robe, anca cheł'altri zugadori. Trar zó da na croda\ni to nemighi ła połe èsar na stratejìa efisente che ła połe cavarte anca calche spisa.", + "No, you can't get up on the ledge. You have to throw bombs.": "Nò, A no te połi mìa montar so'l bordo. A te ghè da tirar bonbe.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "I zugadori i połe zontarse e ndar vìa inte'l medo de ła majornasa de łe\npartìe. Ti A te połi anca tacar e destacar un controłador a'l voło.", + "Practice using your momentum to throw bombs more accurately.": "Fà pràtega tirardo bonbe corendo par far crèsar ła to presizion.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Pì vełosi che se move łe to man, pì dano i farà i to\ncrogni! Donca proa córar, saltar e ndar torno cofà un mato.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Prima de tirar na bonba cori prima indrìo e daspò in\nvanti par darghe na \"scuriatada\" e trarla pì distante.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Fà fora un grupo intiero de nemighi\npiasando na bonba visin a na TNT.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Ła testa ła ze el posto pì vulneràbiłe, donca na bonba\npetaisa inte ła suca de sòłito ła vołe dir fine de i zughi.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "'Sto łeveło no'l fenise mai, ma un puntejo alto cuà\nel vołe dir el respeto eterno de tuto el mondo.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Ła potensa de tiro ła ze bazada so ła diresion che A te si drio strucar. Par\nmołar zó calcosa davanti de ti dolsemente, no stà tegner strucà gnauna diresion.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Stufo de ła mùzega de'l zugo? Meti sù ła tua!\nVarda so Inpostasion > Àudio > Son de fondo", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Prima de tirarle, proa 'łasar so'l fogo' łe bonbe par un segondo o do.", + "Try tricking enemies into killing eachother or running off cliffs.": "Frega i to nemighi parché i se cope infrà de łori o i cora zó par na croda.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Dòpara el boton 'łeva sù' par brincar ła bandiera < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Cori prima indrìo e daspò in vanti par rivar pì distante co i to tiri...", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "A te połi 'mirar' i to crogni ndando torno par drita o sanca. A torna\ncòmodo par trar baso i cataràdeghi da łe crode o par far ponto so l'hockey.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "A te połi capir el tenpo de esplozion de na bonba drio el cołor\nde łe fałive de ła micia: zało.. naranson.. roso.. e BUM!!", + "You can throw bombs higher if you jump just before throwing.": "A te połi tirar łe bonbe pì alte, se te salti pena prima de tirarle.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Se A te bati ła testa da calche parte A te te fè małe,\ndonca proa a no zbàtar da gnauna parte.", + "Your punches do much more damage if you are running or spinning.": "I to crogni i fà pì małe se A te si drio córar o ndar torno." + } + }, + "trophiesRequiredText": "Par zugarghe A serve almanco ${NUMBER} trofèi.", + "trophiesText": "Trofèi", + "trophiesThisSeasonText": "Trofèi de 'sta stajon", + "tutorial": { + "cpuBenchmarkText": "El fà ndar ła demostrasion a vełosidà redìgoła (par proar prinsipalmente ła rapidità de'l procesor)", + "phrase01Text": "Ciao!", + "phrase02Text": "Benrivài so ${APP_NAME}!", + "phrase03Text": "Eco calche sujarimento so come far móvar el to parsonajo:", + "phrase04Text": "Rento ${APP_NAME} tante robe łe ze bazàe so ła FÌZEGA.", + "phrase05Text": "Par dir, co te tiri un crogno...", + "phrase06Text": "...el dano el ze bazà so ła vełosidà de i to pugni.", + "phrase07Text": "Visto? A te si fermo, donca ${NAME} el ło gà sentìo a cico.", + "phrase08Text": "Deso salta e và torno par ciapar pì vełosidà.", + "phrase09Text": "Eco, cusì A ze mejo.", + "phrase10Text": "Anca córar juta.", + "phrase11Text": "Tien strucà un boton CALSÌASE par córar.", + "phrase12Text": "Par crogni uncora pì fisi, proa córar e ndar torno INSENBRE.", + "phrase13Text": "Orpo! Colpa mia ${NAME}.", + "phrase14Text": "A te połi łevar sù e tirar robe cofà łe bandiere o anca cofà... ${NAME}.", + "phrase15Text": "In ùltema, A ghe ze łe bonbe.", + "phrase16Text": "A serve pràtega par tirar ben łe bonbe.", + "phrase17Text": "Òstrega! Un tiro miga masa beło...", + "phrase18Text": "Móvarte el te juta a tirarle pì distante.", + "phrase19Text": "Móvarte el te juta a tirarle pì alte.", + "phrase20Text": "\"Scuriata\" łe bonbe par tiri uncora pì łonghi.", + "phrase21Text": "Calcołar el tenpo de esplozion de łe bonbe A połe èsar defìsiłe.", + "phrase22Text": "Canaja!", + "phrase23Text": "Proa 'łasar so'l fogo' ła micia par un segondo o do.", + "phrase24Text": "Grande! Cotura spesiałe!", + "phrase25Text": "Benon, A ghemo fenìo.", + "phrase26Text": "Deso và e dàghine na rata a tuti!", + "phrase27Text": "Recòrdate el to łenamento... e A te tornarè caza tut'un toco!", + "phrase28Text": "...beh, forse...", + "phrase29Text": "Bona fortuna!", + "randomName1Text": "Fede", + "randomName2Text": "Enry", + "randomName3Text": "Teo", + "randomName4Text": "Cesco", + "randomName5Text": "Stè", + "skipConfirmText": "Vutu dabon saltar ła demostrasion? Toca o struca par confermar.", + "skipVoteCountText": "Voti par saltar ła demostrasion: ${COUNT}/${TOTAL}", + "skippingText": "demostrasion saltada...", + "toSkipPressAnythingText": "(toca o struca un boton par saltar ła demostrasion)" + }, + "twoKillText": "E 2 DE COPÀI!", + "unavailableText": "miga disponìbiłe", + "unconfiguredControllerDetectedText": "Rełevà controłador miga configurà:", + "unlockThisInTheStoreText": "Da dezblocar inte ła botega.", + "unlockThisProfilesText": "Par crear pì de ${NUM} profiłi, A te serve:", + "unlockThisText": "Par dezblocar 'sta funsion A te serve:", + "unsupportedHardwareText": "Ne despiaze, 'sto hardware no'l ze mìa conpatìbiłe co 'sta varsion de'l zugo.", + "upFirstText": "Par tacar:", + "upNextText": "Inte'l łeveło n°${COUNT}:", + "updatingAccountText": "Ajornamento de'l to account...", + "upgradeText": "Mejora", + "upgradeToPlayText": "Par zugarghe, dezbloca \"${PRO}\" inte ła botega.", + "useDefaultText": "Reinposta", + "usesExternalControllerText": "'Sto zugo el dòpara un controłador esterno cofà dispozidivo de entrada.", + "usingItunesText": "Doparar l'apl de mùzega par el son de fondo...", + "v2AccountLinkingInfoText": "Par łigar un account V2 dòpara el boton 'Jestisi account'.", + "validatingTestBuildText": "Confermasion varsion de proa...", + "victoryText": "Vitoria!", + "voteDelayText": "A no te połi tacar n'antra votasion par ${NUMBER} segondi", + "voteInProgressText": "A ze dezà in corso na votasion.", + "votedAlreadyText": "A te ghè zà votà", + "votesNeededText": "A serve ${NUMBER} voti", + "vsText": "vs.", + "waitingForHostText": "(drio spetar ${HOST} par ndar vanti)", + "waitingForPlayersText": "drio spetar che A se zonte altri zugadori...", + "waitingInLineText": "Drio spetar in coa (el grupo el ze pien)...", + "watchAVideoText": "Varda un video", + "watchAnAdText": "Varda na reclan", + "watchWindow": { + "deleteConfirmText": "Vutu ełimenar \"${REPLAY}\"?", + "deleteReplayButtonText": "Ełìmena\nrevardo", + "myReplaysText": "I me revardi", + "noReplaySelectedErrorText": "Gnaun revardo sełesionà", + "playbackSpeedText": "Vełosidà de reprodusion: ${SPEED}", + "renameReplayButtonText": "Renòmena\nrevardo", + "renameReplayText": "Renòmena \"${REPLAY}\" co:", + "renameText": "Renòmena", + "replayDeleteErrorText": "A se gà verifegà un eror ełimenando el revardo.", + "replayNameText": "Nome de'l revardo", + "replayRenameErrorAlreadyExistsText": "A eziste dezà un revardo co 'sto nome.", + "replayRenameErrorInvalidName": "A no ze mìa posìbiłe renomenar el revardo: nome mìa vàłido.", + "replayRenameErrorText": "A se gà verifegà un eror renomenando el revardo.", + "sharedReplaysText": "Revardi sparpagnài", + "titleText": "Varda", + "watchReplayButtonText": "Varda\nrevardo" + }, + "waveText": "Ondada", + "wellSureText": "Ciaro!", + "whatIsThisText": "Cosa zeła 'sta roba?", + "wiimoteLicenseWindow": { + "titleText": "Deriti d'autor DarwiinRemote" + }, + "wiimoteListenWindow": { + "listeningText": "Reserca de controładori Wiimotes...", + "pressText": "Struca simultaneamente i botoni 1 e 2 de'l Wiimote.", + "pressText2": "Invese, so i Wiimotes novi co'l Motion Plus integrà, struca el boton roso 'sync' che A ghe ze dadrìo." + }, + "wiimoteSetupWindow": { + "copyrightText": "Deriti d'autor DarwiinRemote", + "listenText": "Scolta", + "macInstructionsText": "Segùrate che ła to Wii ła sipie stuada e el bluetooth de'l\nto Mac ativà, donca stuca so 'Scolta'. Ła conpatibiłidà co'l\nWiimote ła podarìa èsar un fià inserta, donca te podarisi\ncatarte a proar pì 'olte prima de otegner na conesion.\n\nEl bluetooth el gavarìa da suportar fin a 7 dispozidivi conetesti,\nanca se ła capasidà ła podarìa variar.\n\nBombSquad el suporta el controłador Clàsego e i controładori\norijinałi Wiimotes, Nunchuks.\nAnca el novo Wii Remote Plus el funsiona\nma soło sensa acesori.", + "thanksText": "Grasie a ła scuadra DarwiinRemote\npar verlo rendesto posìbiłe.", + "titleText": "Configurasion Wiimote" + }, + "winsPlayerText": "Vitoria de ${NAME}!", + "winsTeamText": "Vitoria de i ${NAME}!", + "winsText": "Vitoria de ${NAME}!", + "workspaceSyncErrorText": "Eror de sincronizasion de ${WORKSPACE}. Varda el rejistro eventi par i detaji.", + "workspaceSyncReuseText": "Inposìbiłe sinconizar ${WORKSPACE}. Dòparo de ła varsion sincronizada presedente.", + "worldScoresUnavailableText": "Punteji mondiałi miga disponìbiłi.", + "worldsBestScoresText": "I punteji mejo de'l mondo", + "worldsBestTimesText": "I tenpi mejo de'l mondo", + "xbox360ControllersWindow": { + "getDriverText": "Descarga el driver", + "macInstructions2Text": "Par doparar sensa fiło i controładori, A te serve anca el resevidor\nche'l riva co l''Xbox 360 Wireless Controller par Windows'.\nUn resevidor el te parmete de conétar fin a 4 controładori.\n\nInportante: i resevidori de terse parti no i funsionarà miga co 'sto driver;\nsegùrate che'l to resevidor el sipia 'Microsoft' e miga 'XBOX 360'.\nŁa Microsoft no łi vende pì destacài, donca te servirà par forsa cheło\nvendesto insebre co'l controłador, o senò, proa sercar so Ebay.\n\nSe te cati ùtiłe el driver, ciapa in considerasion de farghe na\ndonasion a'l só dezviłupador so 'sto sito.", + "macInstructionsText": "Per doparar i controładori co'l fiło de ła Xbox 360, te ghè\nda instałar el driver Mac disponìbiłe so'l link cuà soto.\nEl funsiona co anbo i controładori, co'l fiło o sensa.", + "ouyaInstructionsText": "Par doparar so Bombsquad un controłador de l'Xbox 360 co'l fiło,\ntàcheło sù inte ła porta USB de’l to dispozidivo. Te połi anca\ntacar sù pì controładori insenbre doparando un hub USB.\n\nPar doparar i controładori sensa fiło invese, te serve un resevidor\nde segnałe. Te połi catarlo, o rento ła scàtoła \"Controładori sensa fiło\nXbox 360 par Windows\", o vendesto a parte. Caun resevidor el và tacà so\nna porta USB e el te parmete de conétar fin a 4 controładori.", + "titleText": "Doparar un controłador Xbox 360 co ${APP_NAME}:" + }, + "yesAllowText": "Sì, parmeti!", + "yourBestScoresText": "I to punteji mejo", + "yourBestTimesText": "I to tenpi mejo" +} \ No newline at end of file diff --git a/dist/ba_data/data/languages/vietnamese.json b/dist/ba_data/data/languages/vietnamese.json new file mode 100644 index 0000000..6165104 --- /dev/null +++ b/dist/ba_data/data/languages/vietnamese.json @@ -0,0 +1,1872 @@ +{ + "accountSettingsWindow": { + "accountNameRules": "Tên tài khoản không được chứa biểu tượng cảm xúc và kí tự đặc biệt", + "accountProfileText": "Tài Khoản", + "accountsText": "Tài khoản", + "achievementProgressText": "Huy Hiệu:${COUNT} trong ${TOTAL}", + "campaignProgressText": "Tiến trình(khó) :${PROGRESS}", + "changeOncePerSeason": "Bạn chỉ có thể thay đổi một lần mỗi mùa.", + "changeOncePerSeasonError": "Bạn có thể đổi nó vào mùa sau (${NUM} days)", + "customName": "Tên tùy chỉnh", + "linkAccountsEnterCodeText": "Nhập Mã", + "linkAccountsGenerateCodeText": "Tạo mã", + "linkAccountsInfoText": "(Chia sẽ dữ liệu giữa các máy)", + "linkAccountsInstructionsNewText": "Để kết nối hai tài khoản, tạo mã trên tài khoản thứ\nnhất rồi nhập vào tài khoản thứ hai. Dữ liệu trên tài\nkhoản thứ hai sẽ được đồng bộ.\n(Dữ liệu trên tài khoản thứ nhất sẽ bị xóa vĩnh viễn)\n\nBạn có thể kết nối lên đến ${COUNT} tài khoản.\n\nLƯU Ý: chỉ kết nối tài khoản của bạn;\nNếu bạn kết nối tài khoản của người khác thì\ncả hai người sẽ không thể trực tuyến cùng một lúc.", + "linkAccountsInstructionsText": "Để kết nối 2 tài khoản khác nhau, tạo mã ở\nmột máy và nhập mã ở máy còn lại.\nDữ liệu sẽ được liên kết giữa các máy\nBạn có thể kết nối đến ${COUNT} thiết bị.\n\nQUAN TRỌNG: Chỉ kết nối tài khoản của bạn!\nNếu bạn kết nối tài khoản với bạn bè\nbạn không thể chơi cùng một lúc!\n\nNgoài ra: nó không thể hoàn tác, nên hãy cẩn thận!", + "linkAccountsText": "kết nối máy khác", + "linkedAccountsText": "Tài khoản kết nối:", + "nameChangeConfirm": "Đổi tên tài khoản thành ${NAME}?", + "resetProgressConfirmNoAchievementsText": "Việc này sẽ đặt lại toàn bộ dữ liệu của bạn\nngoại trừ số tiền của ban\nđiều này không thể hoàn tác. Chắc chắn?", + "resetProgressConfirmText": "Việc này sẽ đặt lại toàn bộ dữ liệu của bạn\nvà cả huy hiệu\nngoại trừ số tiền của ban\nđiều này không thể hoàn tác. Chắc chắn?", + "resetProgressText": "Xóa dữ liệu", + "setAccountName": "Đặt lại tên tài khoản", + "setAccountNameDesc": "Chọn tên cho tài khoản của bạn.\nBạn có thể dùng tên từ tài khoản đã kết nối\nhoặc tạo tên khác.", + "signInInfoText": "Đăng nhập để lưu dữ liệu giữa các máy \nchơi online và tham gia giải đấu", + "signInText": "Đăng Nhập", + "signInWithDeviceInfoText": "(một tài khoản ở máy khác sẽ tự động đăng nhập)", + "signInWithDeviceText": "đăng nhập bằng tài khoản của máy tính", + "signInWithGameCircleText": "Đăng nhập với Game Circle", + "signInWithGooglePlayText": "đăng nhập bằng google chơi trò chơi", + "signInWithTestAccountInfoText": "(loại tài khoản đặc biệt; chỉ đăng nhập trên máy này)", + "signInWithTestAccountText": "Đăng nhập bằng tài khoản máy tính", + "signInWithV2InfoText": "(một tài khoản hoạt động trên tất cả các nền tảng)", + "signInWithV2Text": "Đăng nhập bằng tài khoản BombSquad", + "signOutText": "Đăng Xuất", + "signingInText": "Đang đăng nhập...", + "signingOutText": "Đang Đăng xuất...", + "testAccountWarningCardboardText": "Cảnh Báo: bạn đang Đang Chơi tài Khoản 'Thử'\ndữ liệu sẽ bị thay thế bởi tài khoản\nvà nó sẽ đè lên TK thử\n\nBây giờ bạn sẽ có tất cả tiền trong Game\n(Bạn hãy chơi Boomsquad Pro miẽn phí", + "testAccountWarningOculusText": "Cảnh báo:bạn đang đăng nhập với kí tự chữ.Chúng sẽ được thay thế bằng kí tự ô.\nTài khoản này sẽ được dùng để mua vé và các tính năng khác.\n\n\nVà bây giờ bạn sẽ được học cách thu thập các vé trong game.\n(Mách nhỏ bạn có thể cập nhật BombSquad Pro miễn phí bằng vé)", + "testAccountWarningText": "Cảnh báo:bạn đang đăng nhập bằng tài khoản thử nghiệm.\nTài khoản này sẽ xác thưc thiết bị của bạn và sẽ xóa mất dữ liệu.\n(vì vậy chúng tôi khuyên bạn đừng bỏ nhiều thời gian thu thập \nhoặc mở các vật phẩm trong game.\n\nHãy dùng phiên bản bày bán để có tài khoản thực(vd:Game-Center,Google Plus,...)\nViệc này sẽ giúp bạn lưu trữ các quá trình \nkhi chơi bằng dữ liệu đám mây \nvà bạn có thể chơi trên các thiết bị khác.", + "ticketsText": "Số Tiền: ${COUNT}", + "titleText": "Tài Khoản", + "unlinkAccountsInstructionsText": "Chọn tài khoản để hủy kết nối", + "unlinkAccountsText": "Hủy kết nối", + "v2LinkInstructionsText": "Sử dụng liên kết này để tạo tài khoản hoặc đăng nhập.", + "viaAccount": "(qua tài khoản ${NAME})", + "youAreSignedInAsText": "Bạn đang đăng nhập tài khoản:" + }, + "achievementChallengesText": "Các thành tựu đạt được.", + "achievementText": "Thành tựu", + "achievements": { + "Boom Goes the Dynamite": { + "description": "Tiêu diệt 3 kẻ xấu bằng TNT", + "descriptionComplete": "Giết 3 kẻ xấu với TNT", + "descriptionFull": "Tiêu diệt 3 kẻ xấu bằng TNT với ${LEVEL}", + "descriptionFullComplete": "Tiêu diệt 3 kẻ xấu bằng TNT với ${LEVEL}", + "name": "Bom tạo ra sức mạnh" + }, + "Boxer": { + "description": "Chiến thắng mà không sử dụng bom", + "descriptionComplete": "Đã chiến thắng mà không sử dụng bom", + "descriptionFull": "Hoàn thành ${LEVEL} mà không sử dụng bom", + "descriptionFullComplete": "Hoàn thành ${LEVEL} mà không sử dụng bom", + "name": "Tay đấm xuất sắc" + }, + "Dual Wielding": { + "descriptionFull": "Kết nối 2 điều khiển (thiết bị hoặc ứng dụng)", + "descriptionFullComplete": "Kết nối 2 điều khiển (thiết bị hoặc ứng dụng)", + "name": "Gấp đôi điều khiển" + }, + "Flawless Victory": { + "description": "Chiến thắng mà không đánh đối thủ", + "descriptionComplete": "Đã chiến thắng mà không đánh đối thủ", + "descriptionFull": "Nhận được ${LEVEL} mà không đánh đối thủ", + "descriptionFullComplete": "Đã thắng ${LEVEL} mà không đánh đối thủ", + "name": "Chiến thắng vinh quang" + }, + "Free Loader": { + "descriptionFull": "Chơi Đánh đơn với 2+ người chơi", + "descriptionFullComplete": "Chơi Đánh đơn với 2+ người chơi", + "name": "Chơi Vô Hạn" + }, + "Gold Miner": { + "description": "Tiêu diệt 6 kẻ xấu bằng mìn", + "descriptionComplete": "Đã tiêu diệt 6 kẻ xấu bằng mìn", + "descriptionFull": "Tiêu diệt 6 kẻ xấu bằng mìn trên ${LEVEL}", + "descriptionFullComplete": "Đã tiêu diệt 6 kẻ xấu bằng mìn trên ${LEVEL}", + "name": "Người đào vàng" + }, + "Got the Moves": { + "description": "Chiến thắng mà không đấm đối thủ hoặc sử dụng bom", + "descriptionComplete": "Đã thắng mà không đấm đối thủ hoặc sử dụng bom", + "descriptionFull": "Nhận được ${LEVEL} mà không đấm đối thủ hoặc sử dụng bom", + "descriptionFullComplete": "Đã thắng ${LEVEL} mà không đắm đối thủ hoặc không sử đụng bom", + "name": "Hãy di chuyển" + }, + "In Control": { + "descriptionFull": "Kết nối với điều khiển (thiết bị hoặc ứng dụng)", + "descriptionFullComplete": "Kết nối với điều khiển (thiết bị hoặc ứng dụng)", + "name": "Trong điều khiển" + }, + "Last Stand God": { + "description": "Ghi 1000 điểm", + "descriptionComplete": "Đã ghi được 1000 điểm", + "descriptionFull": "Ghi 1000 điểm trên ${LEVEL}", + "descriptionFullComplete": "Đã ghi 1000 điểm trên ${LEVEL}", + "name": "${LEVEL} Thánh" + }, + "Last Stand Master": { + "description": "Ghi 250 điểm", + "descriptionComplete": "Đạt 250 điểm", + "descriptionFull": "Điểm 250 trong vòng ${LEVEL}", + "descriptionFullComplete": "Đạt 250 điểm trong vòng ${LEVEL}", + "name": "Sư phụ của vòng ${LEVEL}" + }, + "Last Stand Wizard": { + "description": "Điểm đạt 500", + "descriptionComplete": "Đạt 500 điểm", + "descriptionFull": "Đạt 500 điểm tại ${LEVEL}", + "descriptionFullComplete": "Đạt 500 điểm tại ${LEVEL}", + "name": "${LEVEL} Wizard" + }, + "Mine Games": { + "description": "Giết 3 kẻ xấu vứi land-mines", + "descriptionComplete": "Giết 3 kẻ xấu với land-mines", + "descriptionFull": "Giết 3 kẻ xấu với land-mines tại ${LEVEL}", + "descriptionFullComplete": "Giết 3 kẻ xấu với land-mines tại ${LEVEL}", + "name": "Trò chơi Mine" + }, + "Off You Go Then": { + "description": "Ném 3 đối thủ khỏi bản đồ", + "descriptionComplete": "Ném 3 kẻ xấu ra khỏi bản đồ", + "descriptionFull": "Ném 3 kẻ xấu ra khỏi bản đồ tại ${LEVEL}", + "descriptionFullComplete": "Ném 3 kẻ xấu ra khỏi bản đồ tại ${LEVEL}", + "name": "Đến Ai Tiếp Theo" + }, + "Onslaught God": { + "description": "Đạt 5000 điểm", + "descriptionComplete": "Đạt 5000 điểm", + "descriptionFull": "Đạt 5000 điểm tại ${LEVEL}", + "descriptionFullComplete": "Đạt 5000 điểm tại ${LEVEL}", + "name": "${LEVEL} thánh" + }, + "Onslaught Master": { + "description": "Đạt 500 điểm", + "descriptionComplete": "Đạt 500 điểm", + "descriptionFull": "Đạt 500 điểm tại ${LEVEL}", + "descriptionFullComplete": "Đạt 500 điểm tại ${LEVEL}", + "name": "${LEVEL} Sư phụ" + }, + "Onslaught Training Victory": { + "description": "Thắng tất cả các ải", + "descriptionComplete": "Thắng tất cả các ải", + "descriptionFull": "Thắng tất cả các ải tại ${LEVEL}", + "descriptionFullComplete": "Thắng tất cả các ải tại ${LEVEL}", + "name": "${LEVEL} Chiến thắng" + }, + "Onslaught Wizard": { + "description": "Đạt 1000 điểm", + "descriptionComplete": "Đạt 1000 điểm", + "descriptionFull": "Đạt 1000 điểm tại ${LEVEL}", + "descriptionFullComplete": "Đạt 1000 điểm tại ${LEVEL}", + "name": "${LEVEL} phù thủy" + }, + "Precision Bombing": { + "description": "Thắng mà không cần powerups", + "descriptionComplete": "Thắng mà không cần powerups", + "descriptionFull": "Thắng tại ${LEVEL} mà không cần powerups", + "descriptionFullComplete": "Hoàn thành ${LEVEL} mà không sử dụng Power-ups", + "name": "Tự Tin Ném Bom" + }, + "Pro Boxer": { + "description": "Thắng mà không sử dụng bom", + "descriptionComplete": "Thắng mà không sử dụng bom", + "descriptionFull": "Hoàn thành ${LEVEL} không sử dụng bom", + "descriptionFullComplete": "Hoàn thành ${LEVEL} không sử dụng bom", + "name": "Đấm Bốc Chuyên Nhiệp" + }, + "Pro Football Shutout": { + "description": "Thắng mà không để đội bên ghi điểm", + "descriptionComplete": "Thắng mà không để đội bên ghi điểm", + "descriptionFull": "Hoàn thành ${LEVEL} mà không để đội bên ghi điểm", + "descriptionFullComplete": "Hoàn thành ${LEVEL} mà không để đội bên ghi điểm", + "name": "Xuất Sắc ${LEVEL}" + }, + "Pro Football Victory": { + "description": "Hoàn thành vòng", + "descriptionComplete": "Hoàn thành vòng", + "descriptionFull": "Hoàn thành vòng ${LEVEL}", + "descriptionFullComplete": "Hoàn thành vòng ${LEVEL}", + "name": "Chiến thắng ${LEVEL}" + }, + "Pro Onslaught Victory": { + "description": "Đánh bại tất cả", + "descriptionComplete": "Đánh bại tất cả", + "descriptionFull": "Đánh bại tất cả ở ${LEVEL}", + "descriptionFullComplete": "Đánh bại tất cả ở ${LEVEL}", + "name": "Chiến thang ${LEVEL}" + }, + "Pro Runaround Victory": { + "description": "Hoàn thành tất cả các vòng", + "descriptionComplete": "Đã hoàn thành tất cả các vòng", + "descriptionFull": "Hoàn thành tất cả các vòng tại ${LEVEL}", + "descriptionFullComplete": "Đã hoàn thành tất cả các vòng tại ${LEVEL}", + "name": "${LEVEL} Chiến thắng" + }, + "Rookie Football Shutout": { + "description": "Thắng mà không để đối phương ghi bàn nào", + "descriptionComplete": "Chiến thắng mà không để kẻ xấu ghi điểm", + "descriptionFull": "Chiến thắng ${LEVEL} mà không để kẻ xấu ghi điểm", + "descriptionFullComplete": "Chiến thắng ${LEVEL} mà không để kẻ xấu ghi điểm", + "name": "${LEVEL} Bắn ra" + }, + "Rookie Football Victory": { + "description": "Hoàn Thành Trò Chơi", + "descriptionComplete": "Hoàn Thành Trò Chơi", + "descriptionFull": "Hoàn Thành Trò Chơi ở ${LEVEL}", + "descriptionFullComplete": "Hoàn Thành Trò Chơi ở ${LEVEL}", + "name": "Chiến Thắng ${LEVEL}" + }, + "Rookie Onslaught Victory": { + "description": "Vượt qua tất cả vòng", + "descriptionComplete": "Vượt qua tất cả vòng", + "descriptionFull": "Vượt qua tất cả vòng ở ${LEVEL}", + "descriptionFullComplete": "Vượt qua tất cả vòng ở ${LEVEL}", + "name": "${LEVEL} Chiến thắng" + }, + "Runaround God": { + "description": "Đạt 2000 điểm", + "descriptionComplete": "Đạt 2000 điểm", + "descriptionFull": "Đạt 2000 điểm tại ${LEVEL}", + "descriptionFullComplete": "Đạt 2000 điểm tại ${LEVEL}", + "name": "${LEVEL} Thánh" + }, + "Runaround Master": { + "description": "Đạt 500 điểm", + "descriptionComplete": "Đạt 500 điểm", + "descriptionFull": "Đạt 500 điểm tại ${LEVEL}", + "descriptionFullComplete": "Đạt 500 điểm tại ${LEVEL}", + "name": "${LEVEL} Sư phụ" + }, + "Runaround Wizard": { + "description": "Đạt 1000 điểm", + "descriptionComplete": "Đạt 1000 điểm", + "descriptionFull": "Đạt 1000 điểm tại ${LEVEL}", + "descriptionFullComplete": "Đạt 1000 điểm tại ${LEVEL}", + "name": "${LEVEL} Phù thủy" + }, + "Sharing is Caring": { + "descriptionFull": "Chia sẻ thành công trò chơi này với bạn bè", + "descriptionFullComplete": "Đã chia sẻ trò chơi này với bạn bè", + "name": "Chia sẻ là Quan tâm" + }, + "Stayin' Alive": { + "description": "Thắng mà không chết", + "descriptionComplete": "Thắng mà không chết", + "descriptionFull": "Thắng ${LEVEL} mà không chết", + "descriptionFullComplete": "Đã thắng ${LEVEL} mà không chết", + "name": "Sống sót" + }, + "Super Mega Punch": { + "description": "Gây sát thương 100% với một cú đấm", + "descriptionComplete": "Gây sát thương 100% với một cú đấm", + "descriptionFull": "Gây sát thương 100% với một cú đấm trong ${LEVEL}", + "descriptionFullComplete": "Gây sát thương 100% với một cú đấm trong ${LEVEL}", + "name": "Cú đấm siêu hạng" + }, + "Super Punch": { + "description": "Gây sát thương 50% với một cú đấm", + "descriptionComplete": "Gây sát thương 50% với một cú đấm", + "descriptionFull": "Gây sát thương 50% với một cú đấm trong ${LEVEL}", + "descriptionFullComplete": "Gây sát thương 50% với một cú đấm trong ${LEVEL}", + "name": "Siêu đấm" + }, + "TNT Terror": { + "description": "Giết 6 kẻ địch với TNT", + "descriptionComplete": "Giết 6 kẻ địch với TNT", + "descriptionFull": "Giết 6 kẻ địch với TNT trong ${LEVEL}", + "descriptionFullComplete": "Giết 6 kẻ địch với TNT trong ${LEVEL}", + "name": "Nỗi khiếp sợ TNT" + }, + "Team Player": { + "descriptionFull": "Chơi cùng với 4+ người khác", + "descriptionFullComplete": "Chơi cùng với 4+ người khác", + "name": "Đồng đội" + }, + "The Great Wall": { + "description": "Chặn toàn bộ kẻ địch", + "descriptionComplete": "Chặn toàn bộ kẻ địch", + "descriptionFull": "Chặn toàn bộ kẻ địch trong ${LEVEL}", + "descriptionFullComplete": "Chặn toàn bộ kẻ địch trong ${LEVEL}", + "name": "Bức tường vĩ đại" + }, + "The Wall": { + "description": "Chặn tất cả kẻ địch", + "descriptionComplete": "Chặn tất cả kẻ địch", + "descriptionFull": "Chặn tất cả kẻ địch trong ${LEVEL}", + "descriptionFullComplete": "Chặn tất cả kẻ địch trong ${LEVEL}", + "name": "Bức tường" + }, + "Uber Football Shutout": { + "description": "Chiến thấng mà không cho kẻ địch ghi điểm", + "descriptionComplete": "Chiến thấng mà không cho kẻ địch ghi điểm", + "descriptionFull": "Chiến thấng ${LEVEL} mà không cho kẻ địch ghi điểm", + "descriptionFullComplete": "Chiến thấng ${LEVEL} mà không cho kẻ địch ghi điểm", + "name": "${LEVEL} Áp đảo" + }, + "Uber Football Victory": { + "description": "Chiến thắng", + "descriptionComplete": "Chiến thắng", + "descriptionFull": "Chiến thắng trong ${LEVEL}", + "descriptionFullComplete": "Chiến thấng trong ${LEVEL}", + "name": "${LEVEL} Chiến thắng" + }, + "Uber Onslaught Victory": { + "description": "Thắng tất cả các vòng", + "descriptionComplete": "Thấng tất cả các ải", + "descriptionFull": "Thấng tất cả các ải trong ${LEVEL}", + "descriptionFullComplete": "Thấng tất cả các ải trong ${LEVEL}", + "name": "${LEVEL} Chiến thấng" + }, + "Uber Runaround Victory": { + "description": "Thấng tất cả các ải", + "descriptionComplete": "Thấng tất cả các ải", + "descriptionFull": "Thấng tất cả các ải trong ${LEVEL}", + "descriptionFullComplete": "Thấng tất cả các ải trong ${LEVEL}", + "name": "${LEVEL} Chiến thắng" + } + }, + "achievementsRemainingText": "Các thành tựu tiếp theo:", + "achievementsText": "Các thành tựu", + "achievementsUnavailableForOldSeasonsText": "Xin lỗi , huy hiệu này không có ở mùa trước", + "activatedText": "${THING} đã được kích hoạt.", + "addGameWindow": { + "getMoreGamesText": "Thêm các thể loại chơi", + "titleText": "Thêm trận đấu" + }, + "allowText": "Cho phép", + "alreadySignedInText": "Tài khoản của bạn đã được đăng nhập trên thiết bị khác;\nhãy đổi tài khoản hoặc đăng xuất khỏi thiết bị khác\nvà thử lại.", + "apiVersionErrorText": "Không thể tải ${NAME}; phiên bản ${VERSION_USED}; yêu cầu ${VERSION_REQUIRED}.", + "audioSettingsWindow": { + "headRelativeVRAudioInfoText": "(tự động bật chức năng này khi cắm tai phone vào)", + "headRelativeVRAudioText": "Tai nghe VR Audio", + "musicVolumeText": "Mức âm lượng", + "soundVolumeText": "Mức độ âm thanh nền", + "soundtrackButtonText": "Các bản nhạc khác", + "soundtrackDescriptionText": "(sử dụng bài nhạc của bạn khi đang chơi game)", + "titleText": "Âm thanh" + }, + "autoText": "Tự động", + "backText": "Quay lại", + "banThisPlayerText": "Khóa người chơi này", + "bestOfFinalText": "Đứng đầu ${COUNT} ván", + "bestOfSeriesText": "Đứng đầu ${COUNT} ván", + "bestRankText": "Thành tích cao nhất của bạn #${RANK}", + "bestRatingText": "Đánh giá cao nhất của bạn ${RATING}", + "bombBoldText": "BOM", + "bombText": "Bom", + "boostText": "Tăng Lực", + "bsRemoteConfigureInAppText": "${REMOTE_APP_NAME} sẽ từ được điều chỉnh.", + "buttonText": "Nút", + "canWeDebugText": "Bạn có muốn BombSquad tự động gửi bug,lỗi \ngame và thồn tin cơ bản cho nhà phát triển?\n\nNhững dữ liệu này không chứa thông tin \ncá nhân và chúng giúp game chạy mượt và không gặp bug.", + "cancelText": "Hủy", + "cantConfigureDeviceText": "Rất tiếc,${DEVICE} không định cấu hình được", + "challengeEndedText": "Thử thách này đã kết thúc.", + "chatMuteText": "Ẩn trò chuyện", + "chatMutedText": "Đã ẩn trò chuyện", + "chatUnMuteText": "Khôi phục trò chuyện", + "choosingPlayerText": "<đang chọn nhân vật>", + "completeThisLevelToProceedText": "Bạn phải hoàn thành \ncấp độ này để tiếp tục!", + "completionBonusText": "Hoàn thành phần thưởng", + "configControllersWindow": { + "configureControllersText": "Điều chỉnh bộ điều khiển", + "configureKeyboard2Text": "Điều chỉnh bàn phím P2", + "configureKeyboardText": "Điều chỉnh bàn phím", + "configureMobileText": "Thiết bị di động đang là bộ điều khiển", + "configureTouchText": "Điều chỉnh màn hình cảm ứng", + "ps3Text": "Bộ điều khiển PS3", + "titleText": "Các bộ điều khiển", + "wiimotesText": "Bộ điều khiển Wii", + "xbox360Text": "Bộ điều khiển Xbox 360" + }, + "configGamepadSelectWindow": { + "androidNoteText": "Lưu ý:bộ điều khiển sẽ hỗ trợ khác nhau tùy theo thiết bị và hệ thống Android", + "pressAnyButtonText": "Nhấn phím bất kỳ trên bộ điều khiển \nmà bạn muốn điều chỉnh....", + "titleText": "Điều chỉnh bộ điều khiển" + }, + "configGamepadWindow": { + "advancedText": "Phát triển", + "advancedTitleText": "Cài đặt bộ điều khiển", + "analogStickDeadZoneDescriptionText": "(Bật cái này nếu nhân vật của bạn trượt khi bạn nhấn cần điều hướng)", + "analogStickDeadZoneText": "Điểm chết trên Điều khiển Analog", + "appliesToAllText": "(áp dụng cho tất cả các bộ điều khiển với kiểu này)", + "autoRecalibrateDescriptionText": "(bật cái này nếu nhân vật không chạy được)", + "autoRecalibrateText": "Tự Đông Hiệu Chỉnh Điều Khiển Analog", + "axisText": "Trục", + "clearText": "xóa", + "dpadText": "Màn Hình", + "extraStartButtonText": "Thêm nút Start", + "ifNothingHappensTryAnalogText": "Nếu không sử dụng được,thử thay thế nút điều hướng khác", + "ifNothingHappensTryDpadText": "Nếu không sử dụng được,thử thay thế D-pad", + "ignoreCompletelyDescriptionText": "(ngăn chặn bộ điều khiển ảnh hưởng tới trò chơi hay menus)", + "ignoreCompletelyText": "Bỏ qua toàn bộ", + "ignoredButton1Text": "Bỏ qua Nút 1", + "ignoredButton2Text": "Bỏ qua Nút 2", + "ignoredButton3Text": "Bỏ qua Nút 3", + "ignoredButton4Text": "Bỏ qua Nút 4", + "ignoredButtonDescriptionText": "(dùng để ngăn nút 'home' hoặc 'sync' ảnh hưởng đến giao diện)", + "pressAnyAnalogTriggerText": "Nhấn bất kì nút trigger", + "pressAnyButtonOrDpadText": "Nhấn bất kì nút hay dpad nào...", + "pressAnyButtonText": "Nhấn nút bất kỳ...", + "pressLeftRightText": "Nhấn nút trái hay phải...", + "pressUpDownText": "Nhấn nut lên hoặc xuống...", + "runButton1Text": "Bật nút 1", + "runButton2Text": "Bật nút 2", + "runTrigger1Text": "Bật nút Trigger 1", + "runTrigger2Text": "Bật nút Trigger 2", + "runTriggerDescriptionText": "(nút Triggers có thể chạy với tốc độ khác nhau)", + "secondHalfText": "Sử dụng cái này để cấu hình nửa thứ hai\ncủa thiết bị 2 bộ điều khiển trong 1\nhiển thị như một bộ điều khiển duy nhất.", + "secondaryEnableText": "Kích hoạt", + "secondaryText": "Bộ điều khiển thứ hai", + "startButtonActivatesDefaultDescriptionText": "(tắt cái này đi nếu nút bắt đầu của bạn có nhiều nút 'menu' hơn)", + "startButtonActivatesDefaultText": "Nút bắt đầu kích hoạt widget mặc định", + "titleText": "Thiết lập điều khiển", + "twoInOneSetupText": "Thiết lập cần điều khiển 2-trong-1", + "uiOnlyDescriptionText": "(ngăn bộ điều khiển này thực sự tham gia một trò chơi)", + "uiOnlyText": "Giới hạn sử dụng Menu", + "unassignedButtonsRunText": "Tất cả các nút chưa được gắn Chạy", + "unsetText": "", + "vrReorientButtonText": "Nút định hướng VR" + }, + "configKeyboardWindow": { + "configuringText": "Cấu hình ${DEVICE}", + "keyboard2NoteText": "Lưu ý: hầu hết các bàn phím chỉ có thể đăng ký một vài phím bấm tại\nmột lần, vì vậy có một trình phát bàn phím thứ hai có thể hoạt động tốt hơn\nnếu có một bàn phím riêng kèm theo để họ sử dụng.\nLưu ý rằng bạn vẫn sẽ cần gán các khóa duy nhất cho\nHai người chơi ngay cả trong trường hợp đó." + }, + "configTouchscreenWindow": { + "actionControlScaleText": "Độ lớn phím hành động", + "actionsText": "Các hành động", + "buttonsText": "các nút", + "dragControlsText": "< di chuyển phím điều khiển để thay đổi vi trí chúng>", + "joystickText": "Phím xoay", + "movementControlScaleText": "Độ lớn phím di chuyển", + "movementText": "Di chuyển", + "resetText": "Chơi lại từ đầu", + "swipeControlsHiddenText": "Ân nút di chuyển", + "swipeInfoText": "Kiểu điều khiển 'Swipe'làm cho việc điều khiển dễ dàng hơn \nmà không cần nhìn phím", + "swipeText": "Trượt", + "titleText": "Điều chinh màn hình cảm ứng" + }, + "configureItNowText": "Điều chỉnh nó ngay ?", + "configureText": "Điều chỉnh", + "connectMobileDevicesWindow": { + "amazonText": "Cửa hàng Amazon", + "appStoreText": "Cửa hàng", + "bestResultsText": "Để chơi game tốt hơn bạn nên sử dụng wifi mạnh.\nBạn cũng có thể tắt các thiết bị đang sử dụng \nwifi khác để giảm lag,chơi game gần người chơi \nkhác trong vong phát sóng wifi và có thể kết nối wifi direct.", + "explanationText": "Để sử dụng điên thoại thông minh hoặc máy tính bảng để làm thiết bị điều khiển,\ncài đặt ứng dụng \"${REMOTE_APP_NAME}\" lên cấc thiết bị đó.\nTất cả các thiêt bị đều có thể kết nối với ${APP_NAME} game thông qua wifi và hoàn toàn miễn phí", + "forAndroidText": "Cho Adndroid:", + "forIOSText": "cho iOS:", + "getItForText": "Tải ${REMOTE_APP_NAME} cho IOS và Android tại App Store \nhoặc cho Android tại cửa hàng Google Play hoặc Amazone Appstore", + "googlePlayText": "Google play", + "titleText": "Sử dụng thiết bị di động như bộ điều khiển." + }, + "continuePurchaseText": "Tiếp tục cho ${PRICE}?", + "continueText": "Tiếp tục", + "controlsText": "Các bộ điều khiển", + "coopSelectWindow": { + "activenessAllTimeInfoText": "Nó không được áp dụng cho tất cả các xếp hạng", + "activenessInfoText": "Những người chơi cùng sẽ tăng khi \nbạn chơi hoặc giảm khi bạn nghỉ.", + "activityText": "Hoạt động", + "campaignText": "Đi cảnh", + "challengesInfoText": "Nhận giải thưởng khi hoàn thành xong các minigames.\n\nPhần thưởng và độ khó tăng \nmỗi khi hoàn thành thử thách và \ngiảm xuống khi thử thách đó bị hết hạn hoặc hủy bỏ", + "challengesText": "Thử thách", + "currentBestText": "Cao nhất hiện tại", + "customText": "Tùy chỉnh", + "entryFeeText": "Mục", + "forfeitConfirmText": "Thím muốn Hủy bỏ thử thách này ?", + "forfeitNotAllowedYetText": "Thím chưa hủy bỏ đc cái thử thách này đâu.", + "forfeitText": "Hủy bỏ", + "multipliersText": "Người chơi khác", + "nextChallengeText": "Thử thách tiếp", + "nextPlayText": "Lần chơi tiếp theo", + "ofTotalTimeText": "của ${TOTAL}", + "playNowText": "Chơi bây giờ", + "pointsText": "Điểm", + "powerRankingFinishedSeasonUnrankedText": "(Hoàn thành mùa không đánh giá)", + "powerRankingNotInTopText": "(không ở top ${NUMBER})", + "powerRankingPointsEqualsText": "= ${NUMBER} Điểm", + "powerRankingPointsMultText": "(x ${NUMBER} Điểm)", + "powerRankingPointsText": "${NUMBER} Điểm", + "powerRankingPointsToRankedText": "(${CURRENT} của ${REMAINING} Điểm)", + "powerRankingText": "Xếp hạng sức mạnh", + "prizesText": "Thưởng", + "proMultInfoText": "Người chơi với ${PRO} nâng cấp\nnhận thêm ${PERCENT}% điểm", + "seeMoreText": "Thêm...", + "skipWaitText": "Bỏ qua việc chờ đợi", + "timeRemainingText": "Thời gian kết thúc", + "toRankedText": "Xêp hạng", + "totalText": "tổng cộng", + "tournamentInfoText": "Hoàn thành điểm cao để cùng thi\nđấu với người chơi khác cùng giải.\n\nGiải thưởng được trao cho những người\ncó điểm cao nhất khi giải đấu kết thúc.", + "welcome1Text": "Chào mừng đến ${LEAGUE}.Bạn có thể nâng cao hạng giải đấu của bạn \nbằng cách đánh giá,hoàn thành các thành tựu và giành các cúp ở \nphần chơi hướng dẫn.", + "welcome2Text": "Bạn có thể kiếm vé từ các hoạt động giống nhau.\nVé có thể sử dụng để mở khóa nhân vật,màn chơi mới \nvà mini games các hướng dẫn mới và nhiều cái khác", + "yourPowerRankingText": "Xếp hạng sức mạnh của bạn" + }, + "copyConfirmText": "sao chép vào clipboard", + "copyOfText": "${NAME} copy", + "copyText": "Sao chép", + "createEditPlayerText": "", + "createText": "Tạo", + "creditsWindow": { + "additionalAudioArtIdeasText": "Thêm vào âm thanh,hình ảnh mới và ý kiến bởi ${NAME}", + "additionalMusicFromText": "Thêm âm nhạc từ ${NAME}", + "allMyFamilyText": "Người thân và bạn bè tôi đã thử nghiệm", + "codingGraphicsAudioText": "Mã hóa,đồ họa và âm thanh bởi ${NAME}", + "languageTranslationsText": "Phiên dịch:", + "legalText": "Pháp lý:", + "publicDomainMusicViaText": "Nhạc của nhóm cộng đồng qua ${NAME}", + "softwareBasedOnText": "Phần mềm này được phát triển trong một dự án của ${NAME}", + "songCreditText": "${TITLE} Phát triển bởi ${PERFORMER}\nTác giả ${COMPOSER}, Sắp xếp bởi ${ARRANGER},Phát hành bởi ${PUBLISHER},\nNguồn ${SOURCE}", + "soundAndMusicText": "Âm thanh và nhạc:", + "soundsText": "Âm thanh (${SOURCE}):", + "specialThanksText": "Dành lời cảm ơn đặc biệt cho :", + "thanksEspeciallyToText": "Vô cùng cảm ơn đến ${NAME}", + "titleText": "Nhóm Sáng Tạo ${APP_NAME}", + "whoeverInventedCoffeeText": "Ai đó tạo ra cà phê" + }, + "currentStandingText": "Vị trí hiện tại của bạn là #${RANK}", + "customizeText": "Tùy chinh...", + "deathsTallyText": "${COUNT} lần chết", + "deathsText": "Chết", + "debugText": "Sửa lỗi", + "debugWindow": { + "reloadBenchmarkBestResultsText": "Lưu ý:khuyến nghị bật Cài Đặt->Đồ Họa->Khung Cảnh thành cao khi thử nghiệm", + "runCPUBenchmarkText": "Chấm điểm CPU benchmark", + "runGPUBenchmarkText": "Chấm điểm đồ họa", + "runMediaReloadBenchmarkText": "Chạy lại nội dung chuẩn", + "runStressTestText": "Chạy thử nghiệm", + "stressTestPlayerCountText": "Đếm người chơi", + "stressTestPlaylistDescriptionText": "Danh sách thử độ trễ", + "stressTestPlaylistNameText": "Danh sách tên", + "stressTestPlaylistTypeText": "Kiểu danh sách", + "stressTestRoundDurationText": "Thời hạn Vòng", + "stressTestTitleText": "Thử độ trễ", + "titleText": "Chấm điểm và đo độ trễ", + "totalReloadTimeText": "Tổng cộng thời gian lặp lại :${TIME} (xem danh sách để biết chi tiết)" + }, + "defaultGameListNameText": "Danh Sách Mặc Định ${PLAYMODE}", + "defaultNewGameListNameText": "Danh Sách ${PLAYMODE} Của Tôi", + "deleteText": "Xóa", + "demoText": "Giới thiệu", + "denyText": "Từ chối", + "desktopResText": "Độ phân giải", + "difficultyEasyText": "Dễ", + "difficultyHardOnlyText": "Chỉ chế độ khó", + "difficultyHardText": "Khó", + "difficultyHardUnlockOnlyText": "Vòng này chỉ mở ở chế độ khó\nBạn nghĩ mình có thể dễ dàng vào được vòng này sao ?!?", + "directBrowserToURLText": "Hãy cho phép trình duyệt theo đường dẫn:", + "disableRemoteAppConnectionsText": "Tắt Trình Điều Khiên", + "disableXInputDescriptionText": "Cho phép trên 4 thiết bị điều khiển nhưng nó có thể hoạt động không tốt", + "disableXInputText": "Ngắt Kết NỐi XInput", + "doneText": "Xong", + "drawText": "Hòa", + "duplicateText": "Nhân Đôi", + "editGameListWindow": { + "addGameText": "Thêm\ngame", + "cantOverwriteDefaultText": "Không thể ghi đè danh sách mặc định", + "cantSaveAlreadyExistsText": "Tên danh sach đã tồn tại", + "cantSaveEmptyListText": "Không thể lưu danh sách trống", + "editGameText": "Chỉnh\nsửa game", + "listNameText": "Tên danh sách", + "nameText": "Tên", + "removeGameText": "Bỏ \ngame", + "saveText": "Lưu danh sách", + "titleText": "Chỉnh sửa danh sách" + }, + "editProfileWindow": { + "accountProfileInfoText": "Tài khoản đặc biệt này có tên \nvà biểu tượng dựa vào máy.\n\n${ICONS}", + "accountProfileText": "(thông tin tài khoản)", + "availableText": "Tên \"${NAME}\" khả dụng", + "changesNotAffectText": "Lưu ý:những thay đổi sẽ không có tác dụng với các nhân vật có sẵn trong game", + "characterText": "Nhân vật", + "checkingAvailabilityText": "Đang kiểm tra tên \"${NAME}\"...", + "colorText": "Màu sắc", + "getMoreCharactersText": "Thêm nhân vật mới", + "getMoreIconsText": "Nhận được nhiều icons hơn...", + "globalProfileInfoText": "Tài khoản toàn cầu được khuyến nghị để có \ntên riêng biệt. Nó củng có kí hiệu đặc biệt", + "globalProfileText": "(tài khoản toàn cầu)", + "highlightText": "Màu tóc", + "iconText": "Kí hiệu", + "localProfileInfoText": "Tài khoản nội bộ không có kí hiệu và tên của nó\ncủng không được bảo lưu để được độc nhất. Nâng\ncấp lên tài khoản toàn cầu để được nhận ưu đãi.", + "localProfileText": "(tài khoản cố định)", + "nameDescriptionText": "Tên nhân vật", + "nameText": "Tên", + "randomText": "Ngẫu nhiên", + "titleEditText": "Chỉnh sửa thông tin", + "titleNewText": "Tạo mới", + "unavailableText": "${NAME} không khả dụng; hãy thử tên khác", + "upgradeProfileInfoText": "Nó sẽ bảo lưu tên của bạn toàn cầu\nvà bạn có thể gắn được kí hiệu.", + "upgradeToGlobalProfileText": "Nâng lên Tài Khoản Toàn Cầu" + }, + "editSoundtrackWindow": { + "cantDeleteDefaultText": "Bạ không thể xóa file nhạc mặc định", + "cantEditDefaultText": "Không thể chỉnh sửa file nhạc gốc.Nhân đôi lên hoặc tạo mới", + "cantOverwriteDefaultText": "Không thể ghi đè file nhạc mặc định", + "cantSaveAlreadyExistsText": "Tên file nhạc đó đã tồn tại", + "defaultGameMusicText": "", + "defaultSoundtrackNameText": "Nhạc nền mặc định", + "deleteConfirmText": "Xóa nhạc nền: \n\n'${NAME}'?", + "deleteText": "Xóa bỏ\nNhạc nền", + "duplicateText": "Nhân đôi \nNhạc nền", + "editSoundtrackText": "Chỉnh sửa nhạc", + "editText": "Sửa\nÂm thanh", + "fetchingITunesText": "tìm nạp danh sách phát Ứng dụng Âm nhạc ...", + "musicVolumeZeroWarning": "Cảnh báo: Âm lượng nhạc được chỉnh về 0", + "nameText": "Tên", + "newSoundtrackNameText": "Nhạc nền của tôi ${COUNT}", + "newSoundtrackText": "Nhạc nền mới:", + "newText": "Nhạc nền\nMới", + "selectAPlaylistText": "Chọn một Playlist", + "selectASourceText": "Nguồn nhạc", + "testText": "Kiểm tra", + "titleText": "Nhạc nền", + "useDefaultGameMusicText": "Nhạc nền mặc định trò chơi", + "useITunesPlaylistText": "Danh sách phát ứng dụng âm nhạc", + "useMusicFileText": "Tập tin nhạc (mp3, khác)", + "useMusicFolderText": "Thư mục của files nhạc" + }, + "editText": "Sửa", + "endText": "kết thúc", + "enjoyText": "Chúc vui vẻ!", + "epicDescriptionFilterText": "${DESCRIPTION} trong chế độ quay chậm.", + "epicNameFilterText": "${NAME} Quay Chậm", + "errorAccessDeniedText": "từ chối kết nối", + "errorDeviceTimeIncorrectText": "thời gian của thiết bị của bạn không chính xác ${HOURS} giờ.\nđiều này có thể gây ra vấn đề.\nVui lòng kiểm tra cài đặt múi giờ và múi giờ của bạn.", + "errorOutOfDiskSpaceText": "hết bộ nhớ", + "errorSecureConnectionFailText": "Không thể thiết lập kết nối đám mây an toàn; chức năng mạng có thể bị lỗi.", + "errorText": "Lỗi", + "errorUnknownText": "Không rõ lỗi", + "exitGameText": "Thoát ${APP_NAME}?", + "exportSuccessText": "'${NAME}' Đã xuất", + "externalStorageText": "Bộ nhớ ngoài", + "failText": "Thất bại", + "fatalErrorText": "Ôi không; dữ liệu bị thiếu hoặc hỏng.\nHãy thử cài lại ứng dụng hoặc liên hệ\nvới chúng tôi ${EMAIL}để được giúp đỡ", + "fileSelectorWindow": { + "titleFileFolderText": "Chọn file hoặc thư mục", + "titleFileText": "Chon một file", + "titleFolderText": "Chọn thư mục", + "useThisFolderButtonText": "Sử dụng thư mục này" + }, + "filterText": "Bộ lọc", + "finalScoreText": "Điểm hoàn thành", + "finalScoresText": "Điểm cuối cùng", + "finalTimeText": "Thời gian hoàn thành", + "finishingInstallText": "Hoàn thành cài đặt; vui lòng chờ...", + "fireTVRemoteWarningText": "*Đê có trải nghiệm tốt nhất,\nsử dụng điều khiển hoặc cài\nđặt '${REMOTE_APP_NAME}' trên\nđiện thoại hay máy tính bảng.", + "firstToFinalText": "Dẫn đầu đến ${COUNT}", + "firstToSeriesText": "Dẫn đầu đến ${COUNT}", + "fiveKillText": "NĂM MẠNG", + "flawlessWaveText": "Chiến Thắng Hoàn Hảo!!", + "fourKillText": "BỐN MẠNG", + "friendScoresUnavailableText": "Điểm số bạn bè không có sẵn.", + "gameCenterText": "Trung tâm trò chơi", + "gameCircleText": "Vòng tròn trò chơi", + "gameLeadersText": "Quán quân ${COUNT} Trò chơi", + "gameListWindow": { + "cantDeleteDefaultText": "Bạn không thể xóa danh sách mặc định", + "cantEditDefaultText": "Không thể sửa danh sách mặc định! Nhân đôi nó hoặc tạo một cái mới.", + "cantShareDefaultText": "Bạn không thể chia sẻ danh sách mặc định", + "deleteConfirmText": "Xóa bỏ \"${LIST}\"?", + "deleteText": "Xóa \nDanh sách", + "duplicateText": "Nhân đôi \nDanh sách", + "editText": "Đặt lại \nDanh sách", + "newText": "Danh sách\nMới", + "showTutorialText": "Hiện Hướng dẫn", + "shuffleGameOrderText": "Xáo trộn thứ tự trò chơi", + "titleText": "Tùy chỉnh ${TYPE} Danh sách phát" + }, + "gameSettingsWindow": { + "addGameText": "Thêm trò chơi" + }, + "gamesToText": "${WINCOUNT} Các trò chơi thành ${LOSECOUNT}", + "gatherWindow": { + "aboutDescriptionLocalMultiplayerExtraText": "Lưu ý: Bất kỳ thiết bị nào trong tổ đội có nhiều \nhơn một thành viên nếu bạn có đủ tay cầm.", + "aboutDescriptionText": "Sử dụng các tab này để tập hợp một tổ đội.\n\nCác tổ đội cho phép bạn chơi các trò chơi và giải đấu\nvới bạn bè của bạn trên các thiết bị khác nhau.\n\nSử dụng nút ${PARTY} ở trên cùng bên phải để\ntrò chuyện và tương tác với tổ đội của bạn.\n(trên bộ điều khiển, nhấn ${BUTTON} trong khi ở trong menu)", + "aboutText": "Hướng Dẫn", + "addressFetchErrorText": "", + "appInviteMessageText": "${NAME} đã gửi cho bạn vé ${COUNT} bằng ${APP_NAME}", + "appInviteSendACodeText": "Gửi cho họ mã này", + "appInviteTitleText": "${APP_NAME} Ứng dụng mời", + "bluetoothAndroidSupportText": "(hoạt động với mọi thiết bị Android hỗ trợ Bluetooth)", + "bluetoothDescriptionText": "Tổ chức/tham gia một tổ đội qua Bluetooth:", + "bluetoothHostText": "Tổ chức qua Bluetooth", + "bluetoothJoinText": "Vào qua bluetooth", + "bluetoothText": "Bluetooth", + "checkingText": "Đang kiểm tra...", + "copyCodeConfirmText": "Mã đã sao chép vào bộ nhớ", + "copyCodeText": "Sao chép mã", + "dedicatedServerInfoText": "Để có kết quả tốt nhất, hãy thiết lập một máy chủ chuyên dụng.Vào bombsquadgame.com/server để tìm hiểu cách.", + "disconnectClientsText": "Điều này sẽ ngắt kết nối (các) người chơi ${COUNT}\n trong tổ đội của bạn.Bạn có chắc không?", + "earnTicketsForRecommendingAmountText": "Bạn bè sẽ nhận được vé ${COUNT} nếu họ thử trò chơi\n (và bạn sẽ nhận được ${YOU_COUNT} cho mỗi người làm)", + "earnTicketsForRecommendingText": "Chia sẻ trò chơi này với bạn bè\nđể có thêm vé miễn phí...", + "emailItText": "Gửi nó", + "favoritesSaveText": "Lưu thành Yêu Thích", + "favoritesText": "Yêu Thích", + "freeCloudServerAvailableMinutesText": "Máy chủ trên mây miễn phí sẽ có trong ${MINUTES} phút. Dịch bởi ShockedGaming", + "freeCloudServerAvailableNowText": "Máy chủ miễn phí trên mây đã có sẵn!", + "freeCloudServerNotAvailableText": "Không có máy chủ trên mây có sẵn", + "friendHasSentPromoCodeText": "${COUNT} ${APP_NAME} vé từ ${NAME}", + "friendPromoCodeAwardText": "Bạn sẽ nhận được ${COUNT} vé mỗi lần nó được sử dụng", + "friendPromoCodeExpireText": "Mã code sẽ hết hạn trong ${EXPIRE_HOURS} và chỉ hoạt động với người chơi mới.", + "friendPromoCodeInstructionsText": "Để dùng nó,mở ${APP_NAME} và tới \"Cài đặt ->Nâng cao->Nhập mã\".\nXem bombsquadgame.com cho đường dẫn tải xuống cho tất cả hệ điều hành hỗ trợ.", + "friendPromoCodeRedeemLongText": "Nó có thể được đổi lấy ${COUNT} vé miễn phí cho tối đa ${MAX_USES} người", + "friendPromoCodeRedeemShortText": "Nó có thể được đổi lấy vé ${COUNT} trong trò chơi.", + "friendPromoCodeWhereToEnterText": "(trong \"Cài đặt-> Nâng cao-> Nhập mã\")", + "getFriendInviteCodeText": "Nhận mã mời bạn bè", + "googlePlayDescriptionText": "Mời bạn bè trên google play đến party của bạn:", + "googlePlayInviteText": "Mời", + "googlePlayReInviteText": "Có ${COUNT} người chơi Google Play trong nhóm của bạn\n ai sẽ bị ngắt kết nối nếu bạn bắt đầu một lời mời mới.\n Bao gồm họ trong lời mời mới để họ quay lại .", + "googlePlaySeeInvitesText": "Xem lời mời", + "googlePlayText": "Google Play", + "googlePlayVersionOnlyText": "(Phiên bản Android / Google Play)", + "hostPublicPartyDescriptionText": "Làm chủ phòng công khai", + "hostingUnavailableText": "Làm chủ phòng không còn khả dụng", + "inDevelopmentWarningText": "Ghi chú:\n\n Chơi mạng là một tính năng mới và vẫn đang phát triển.\n Hiện tại, rất khuyến khích tất cả\n Người chơi ở trên cùng một mạng Wi-Fi.", + "internetText": "Internet", + "inviteAFriendText": "Bạn bè không có game này? Mời họ để\nthử nó và họ sẽ nhận được ${COUNT} tickets miễn phí", + "inviteFriendsText": "Mời bạn bè", + "joinPublicPartyDescriptionText": "Tham gia một phòng công khai", + "localNetworkDescriptionText": "Tham gia một phòng lân cận (LAN, Bluetooth, v.v.)", + "localNetworkText": "Mạng nội bộ", + "makePartyPrivateText": "Làm cho bữa tiệc của tôi riêng tư", + "makePartyPublicText": "Công khai bữa tiệc của tôi", + "manualAddressText": "Địa chỉ", + "manualConnectText": "Kết nối", + "manualDescriptionText": "Vào một party bằng địa chỉ IP:", + "manualJoinSectionText": "Tham gia bằng địa chỉ", + "manualJoinableFromInternetText": "Bạn có thể dược tham gia từ internet?:", + "manualJoinableNoWithAsteriskText": "KHÔNG*", + "manualJoinableYesText": "CÓ", + "manualRouterForwardingText": "*Hãy thử vào router và tạo cổng UDP ${PORT} trên IP của bạn", + "manualText": "Tự chọn", + "manualYourAddressFromInternetText": "Địa chỉ IP của bạn ở trên internet:", + "manualYourLocalAddressText": "Địa chỉ nội bộ:", + "nearbyText": "Gần nhất", + "noConnectionText": "(không có kết nối)", + "otherVersionsText": "(phiên bản khác)", + "partyCodeText": "Mã phòng", + "partyInviteAcceptText": "Chấp nhận", + "partyInviteDeclineText": "Từ chối", + "partyInviteGooglePlayExtraText": "(Ở bảng 'Google Play' trong 'Nhiều Người')", + "partyInviteIgnoreText": "Bỏ qua", + "partyInviteText": "${NAME} đã mời bạn\nvào party của họ!", + "partyNameText": "Tên Phòng", + "partyServerRunningText": "Máy chủ phòng của bạn đang chạy", + "partySizeText": "kích cỡ tiệc", + "partyStatusCheckingText": "Kiểm tra trạng thái...", + "partyStatusJoinableText": "Phòng của bạn có thể tham gia", + "partyStatusNoConnectionText": "không thể kết nối đến máy chủ", + "partyStatusNotJoinableText": "Phòng của bạn không thể tham gia", + "partyStatusNotPublicText": "phòng của bạn không thể tham gia", + "pingText": "ping", + "portText": "Cổng", + "privatePartyCloudDescriptionText": "Các phòng riêng chạy trên các máy chủ trên mây chuyên dụng; không cần cấu hình bộ định tuyến", + "privatePartyHostText": "Làm chủ 1 phòng riêng", + "privatePartyJoinText": "Tham gia 1 phòng riêng", + "privateText": "Riêng tư", + "publicHostRouterConfigText": "Điều này có thể yêu cầu định cấu hình chuyển tiếp cổng trên bộ định tuyến của bạn. Để có một lựa chọn dễ dàng hơn, hãy tổ chức một phòng riêng.", + "publicText": "Công khai", + "requestingAPromoCodeText": "Yêu cầu mã...", + "sendDirectInvitesText": "Gửi trực tiếp lời mời", + "shareThisCodeWithFriendsText": "Chia sẻ mã này với bạn bè:", + "showMyAddressText": "Hiển thị địa chỉ", + "startHostingPaidText": "Làm chủ phòng ngay bây giờ chỉ ${COST}", + "startHostingText": "Làm chủ phòng", + "startStopHostingMinutesText": "Bạn có thể bắt đầu và dừng làm chủ phòng MIỄN PHÍ trong ${MINUTES} phút tiếp theo", + "stopHostingText": "Dừng làm chủ phòng", + "titleText": "Nhiều Người", + "wifiDirectDescriptionBottomText": "Nếu tất cả các thiết bị có bảng điều khiển 'Wi-Fi Direct', họ sẽ có thể sử dụng nó để tìm\n và kết nối với nhau. Khi tất cả các thiết bị được kết nối, bạn có thể tạo thành các bữa tiệc\n ở đây sử dụng tab 'Mạng cục bộ', giống như với mạng Wi-Fi thông thường.\n\n Để có kết quả tốt nhất, máy chủ Wi-Fi Direct cũng phải là máy chủ của bữa tiệc ${APP_NAME}.", + "wifiDirectDescriptionTopText": "Wi-Fi Direct có thể được sử dụng để kết nối trực tiếp các thiết bị Android mà không cần\n một mạng Wi-Fi. Điều này hoạt động tốt nhất trên Android 4.2 trở lên.\n\n Để sử dụng nó, hãy mở cài đặt Wi-Fi và tìm 'Wi-Fi Direct' trong menu.", + "wifiDirectOpenWiFiSettingsText": "Mở cài đặt Wi-Fi", + "wifiDirectText": "Wi-Fi Direct", + "worksBetweenAllPlatformsText": "(Hoạt động trên tất cả hệ điều hành)", + "worksWithGooglePlayDevicesText": "(hoạt động với thiết bị chạy Google Trò chơi (Android) phiên bản của trò chơi)", + "youHaveBeenSentAPromoCodeText": "Bạn đã nhận một ${APP_NAME} mã code thưởng:" + }, + "getTicketsWindow": { + "freeText": "Miễn phí!", + "freeTicketsText": "Vé miễn phí", + "inProgressText": "Đang giao dịch; vui lòng thử lại sau một lát.", + "purchasesRestoredText": "Khôi phục hoàn tất.", + "receivedTicketsText": "Nhận được ${COUNT} vé!", + "restorePurchasesText": "Khôi phục Mua hàng", + "ticketPack1Text": "Gói vé nhỏ", + "ticketPack2Text": "Gói vé vừa", + "ticketPack3Text": "Gói vé lớn", + "ticketPack4Text": "Gói vé siêu lớn", + "ticketPack5Text": "Gói vé khổng lồ", + "ticketPack6Text": "Gói vé siêu khổng lồ", + "ticketsFromASponsorText": "Xem một quảng cáo\ncho ${COUNT} vé", + "ticketsText": "${COUNT} Vé", + "titleText": "Lấy vé", + "unavailableLinkAccountText": "Xin lỗi, không thể mua hàng trên hệ điều hành này.\nBạn có thể, liên kết tài khoản này\ntới một tài khoản trên hệ điều hành khác và mua hàng ở đó.", + "unavailableTemporarilyText": "Hiện tại không có sẵn; vui lòng thử lại sau", + "unavailableText": "Xin lỗi,cái này không có sẵn", + "versionTooOldText": "Xin lỗi,phiên bản trò chơi quá cũ; vui lòng nâng cấp lên phiên bản mới hơn.", + "youHaveShortText": "Bạn có ${COUNT}", + "youHaveText": "Bạn có ${COUNT} vé" + }, + "googleMultiplayerDiscontinuedText": "Xin lỗi, dịch vụ Google nhiều người chơi không còn nữa.\nTôi đang cố gắng thay thế nhanh nhất có thể.\nTrong lúc đó, vui lòng thử cách kết nối khác.\n-Eric", + "googlePlayPurchasesNotAvailableText": "Các giao dịch mua trên Google Play không khả dụng.\nBạn có thể cần cập nhật ứng dụng cửa hàng của mình.", + "googlePlayText": "Google Trò chơi", + "graphicsSettingsWindow": { + "alwaysText": "Luôn Luôn", + "fullScreenCmdText": "Toàn màn hình (Cmd-F)", + "fullScreenCtrlText": "Toàn màn hình (Ctrl-F)", + "gammaText": "Gam-ma", + "highText": "Cao", + "higherText": "Cao hơn", + "lowText": "Thấp", + "mediumText": "Vừa", + "neverText": "Không bao giờ", + "resolutionText": "Độ phân giải", + "showFPSText": "Hiển thị tốc độ khung hình", + "texturesText": "Bề mặt", + "titleText": "Đồ họa", + "tvBorderText": "Màn hình TV", + "verticalSyncText": "Đồng bộ dọc", + "visualsText": "Hình ảnh" + }, + "helpWindow": { + "bombInfoText": "- Bom -\nMạnh hơn nắm đấm, nhưng\nbạn có thể tự làm hại mình.\nĐể có kết quả tốt nhất, ném\nvề phía đối phương trước khi nổ.", + "canHelpText": "${APP_NAME} Có thể giúp bạn.", + "controllersInfoText": "Bạn có thể chơi ${APP_NAME} với bạn bè hay qua mạng, hoặc tất\ncả các bạn có thể chơi trên một thiết bị nếu đủ bộ điều khiển.\n${APP_NAME} hổ trợ một lượng lớn các thiết bị; bạn có thể sử dụng\nđiện thoại như một bộ điều khiển qua ứng dụng '${REMOTE_APP_NAME}'.\nĐến Cài Đặt -> bộ điều khiển để xem thêm.", + "controllersInfoTextRemoteOnly": "Chơi ${APP_NAME} với bạn bè \nqua mạng, hoặc thiết bị như điện thoại qua ứng dụng \n'${REMOTE_APP_NAME}'.", + "controllersText": "Bộ điều khiển", + "controlsSubtitleText": "Nhân vật ${APP_NAME} của bạn có một vài động tác cơ bản:", + "controlsText": "Điều khiển", + "devicesInfoText": "Phiên bản ${APP_NAME} VR có thể chơi cùng với phiên bản gốc,\nnên hãy lấy hết tất cả các điện thoại, máy tính bảng vả máy tính\ncá nhân rồi bắt đầu trận chiến! Nó còn có ích khi kết nối với\nphiên bản gốc đến phiên bản VR để một người khác có thể\ntheo dõi trận chiến.", + "devicesText": "Thiết bị", + "friendsGoodText": "Rất tốt nếu bạn có. ${APP_NAME} vui hơn khi có nhiều người chơi\nhơn và có thể hỗ trợ lên đến 8 người chơi cùng một lúc, Vì vậy:", + "friendsText": "Bạn bè", + "jumpInfoText": "- Nhảy -\nNhảy qua các chướng ngại vật,\nđể ném cao hơn, và cảm nhận\nđược niềm vui của bay lượn.", + "orPunchingSomethingText": "Hoặc đấm một vật nào đó, ném nó xuống vực, và làm nổ tung nó khi nó bay xuống bằng bom dính.", + "pickUpInfoText": "- Nhặt -\nNhặt cờ, đối thủ, hoặc bất cứ\nthứ gì khác không dính vào sàn.\nNhấn lại để ném.", + "powerupBombDescriptionText": "Cho phép bạn ném ba bom cùng\nmột lúc thay vì chỉ một.", + "powerupBombNameText": "Ba Lần Bom", + "powerupCurseDescriptionText": "Có thể bạn nên tránh nó.\n ...hoặc không?", + "powerupCurseNameText": "Lời Nguyền", + "powerupHealthDescriptionText": "Hồi đầy máu cho bạn.\nKhông cần phải lo lắng.", + "powerupHealthNameText": "Hộp Cứu Thương", + "powerupIceBombsDescriptionText": "Yếu hơn bom cơ bản nhưng\nlàm kẻ thù đóng băng và\nhoàn toàn bất động.", + "powerupIceBombsNameText": "Bom Băng Giá", + "powerupImpactBombsDescriptionText": "Yếu hơn bom cơ bản một chút, nhưng\nnó có thể nổ ngay khi chạm vào.", + "powerupImpactBombsNameText": "Bom Hạt Nhân", + "powerupLandMinesDescriptionText": "Nó đi theo gói 3; bảo \nPhù hợp để bảo vệ hoặc\nchặn kẻ thù tốc độ", + "powerupLandMinesNameText": "Mìn", + "powerupPunchDescriptionText": "Làm bạn đấm tốt hơn,\nnhanh hơn và mạnh hơn.", + "powerupPunchNameText": "Găng Tay", + "powerupShieldDescriptionText": "Hấp thụ một lượng sát thương\nđể bạn không phải chịu.", + "powerupShieldNameText": "Khiên Chắn", + "powerupStickyBombsDescriptionText": "Dính vào mọi thứ nó chạm.\nHoàn toàn chắc chắn.", + "powerupStickyBombsNameText": "Bom dính", + "powerupsSubtitleText": "Dĩ nhiên, không trò chơi nào có thể thiếu :", + "powerupsText": "Năng Lực", + "punchInfoText": "- Đấm -\nCú đấm gây ra nhiều sát thương hơn\nkhi bạn đang di chuyển, nên hãy\ncứ chạy và xoay như kẻ điên.", + "runInfoText": "- Chạy -\nGiữ BẤT KÌ nút nào để chạy. Các nút khác đều hoạt động nếu bạn có nó.\nChạy giúp bạn di chuyển nhanh hơn nhưng cũng làm bạn khó điều khiển hơn.", + "someDaysText": "Một ngày bạn muốn đấm thứ gì đó. Hoặc làm nổ tung nó.", + "titleText": "Giúp Đỡ Từ ${APP_NAME}", + "toGetTheMostText": "Để tối ưu hóa trò chơi, bạn sẽ cần:", + "welcomeText": "Chào mừng đến ${APP_NAME}!" + }, + "holdAnyButtonText": "", + "holdAnyKeyText": "", + "hostIsNavigatingMenusText": "- ${HOST} đang điều hướng màn hình chính như một ông trùm", + "importPlaylistCodeInstructionsText": "Sử dụng mã đi kèm để nhập danh sách này ở chỗ khác:", + "importPlaylistSuccessText": "Đã nhập ${TYPE} danh sách '${NAME}'", + "importText": "Xuất", + "importingText": "Đang nhập...", + "inGameClippedNameText": "trong game sẽ là \n\"${NAME}\"", + "installDiskSpaceErrorText": "Lỗi: Không thể hoàn thành tải xuống.\nBạn có thể hết dung lượng trên thiết bị của bạn.\nDọn một số chỗ và thử lại.", + "internal": { + "arrowsToExitListText": "nhấn ${LEFT} hoặc ${RIGHT} để rời khỏi danh sách", + "buttonText": "Nút", + "cantKickHostError": "Bạn không thể đuổi chủ phòng.", + "chatBlockedText": "${NAME} bị chặn nhắn tin trong ${TIME} giây.", + "connectedToGameText": "'${NAME}' đã tham gia", + "connectedToPartyText": "Đã tham gia tổ đội của ${NAME}!", + "connectingToPartyText": "Đang kết nối...", + "connectionFailedHostAlreadyInPartyText": "Kết nối thất bại; chủ phòng đã ở tổ đội khác.", + "connectionFailedPartyFullText": "Kết nối thất bại; tổ đội đã đủ người.", + "connectionFailedText": "Kết nối thất bại.", + "connectionFailedVersionMismatchText": "Kết nối thất bại; người tổ chức đang chạy một phiên bản khác của trò chơi.\nChắc chắn rằng cả hai đều là phiên bản mới nhất và thử lại.", + "connectionRejectedText": "Kết nối bị từ chối.", + "controllerConnectedText": "Đã kết nối ${CONTROLLER}.", + "controllerDetectedText": "Phát hiện 1 cần điều khiển.", + "controllerDisconnectedText": "${CONTROLLER} đã ngắt kết nối.", + "controllerDisconnectedTryAgainText": "Đã ngắt kết nối ${CONTROLLER}. Vui lòng thử kết nối lại.", + "controllerForMenusOnlyText": "Cần điều khiển này chỉ dùng để điều khiển.", + "controllerReconnectedText": "${CONTROLLER} đã kết nối lại.", + "controllersConnectedText": "${COUNT} cần điều khiển đã kết nối.", + "controllersDetectedText": "${COUNT} cần điều khiển đã phát hiện.", + "controllersDisconnectedText": "${COUNT} cần điều khiển đã ngắt kết nối.", + "corruptFileText": "Phát hiện tập tin bị hỏng. Vui lòng tải lại trò chơi, hoặc tương tác với email ${EMAIL}", + "errorPlayingMusicText": "Lỗi phát nhạc: ${MUSIC}", + "errorResettingAchievementsText": "Không thể làm mới thành tựu trực tuyến; vui lòng thử lại sau.", + "hasMenuControlText": "", + "incompatibleNewerVersionHostText": "Chủ phòng đang chạy một phiên bản mới hơn của trò chơi.\nCập nhật trò chơi lên phiên bản mới nhất và thử lại.", + "incompatibleVersionHostText": "Chủ phòng đang chạy một phiên bản khác của trò chơi.\nChắc chắn cả hai đều cập nhật phiên bản mới nhất và thử lại.", + "incompatibleVersionPlayerText": "${NAME} đang chạy một phiên bản khác của trò chơi.\nChắc chắn rằng cả hai đều cập nhật lên phiên bản mới nhất và thử lại.", + "invalidAddressErrorText": "Lỗi: địa chỉ không hợp lệ.", + "invalidNameErrorText": "Lỗi: tên không hợp lệ.", + "invalidPortErrorText": "Lỗi: cổng không hợp lệ.", + "invitationSentText": "Đã gửi lời mời", + "invitationsSentText": "Đã gửi ${COUNT} lời mời.", + "joinedPartyInstructionsText": "Một ai đó đã gia nhập tổ đội của bạn.\nNhấn nút 'Chơi' để bắt đầu trò chơi.", + "keyboardText": "Bàn phím", + "kickIdlePlayersKickedText": "Đuổi ${NAME} bởi vì người chơi không hoạt động.", + "kickIdlePlayersWarning1Text": "${NAME} sẽ bị đuổi trong ${COUNT} giây nếu tiếp tục không hoạt động.", + "kickIdlePlayersWarning2Text": "(bạn có thể tắt nó ở trong Cài đặt -> Nâng cao)", + "leftGameText": "Đã rời '${NAME}'.", + "leftPartyText": "Đã rời khỏi tổ đội của ${NAME}.", + "noMusicFilesInFolderText": "Thư mục không chứa tập tin nhạc.", + "playerJoinedPartyText": "${NAME} đã tham gia tổ đội!", + "playerLeftPartyText": "${NAME} đã rời khỏi tổ đội.", + "rejectingInviteAlreadyInPartyText": "Đang từ chối lời mời (đã ở trong một tổ đội).", + "serverRestartingText": "Máy chủ đang reset. Hãy vào trong giây lát", + "serverShuttingDownText": "Máy chủ đang đóng", + "signInErrorText": "Lỗi đăng nhập.", + "signInNoConnectionText": "Không thể đăng nhập. (không có kết nối mạng?)", + "telnetAccessDeniedText": "LỖI: người dùng không có quyền truy cập giao thức.", + "timeOutText": "(hết giờ trong ${TIME} giây)", + "touchScreenJoinWarningText": "Bạn đã gia nhập với màn hình cảm ứng.\nNếu đây là lỗi, nhấn 'Menu-> Rời trò chơi '.", + "touchScreenText": "Màn hình Cảm ứng", + "unableToResolveHostText": "Lỗi: không thể giải quyết máy chủ.", + "unavailableNoConnectionText": "Hiện tại không có sẵn (không có kết nối mạng?)", + "vrOrientationResetCardboardText": "Sử dụng cái này để cài lại VR định hướng.\nĐể chơi trò chơi bạn sẽ cần một cần điều khiển bên ngoài.", + "vrOrientationResetText": "Cài lại định hướng VR.", + "willTimeOutText": "(sẽ hết giờ nếu không hoạt động)" + }, + "jumpBoldText": "NHẢY", + "jumpText": "Nhảy", + "keepText": "Giữ", + "keepTheseSettingsText": "Giữ các cài đặt?", + "keyboardChangeInstructionsText": "Nhấn phím cách hai lần để đổi bàn phím.", + "keyboardNoOthersAvailableText": "Không có bàn phím khác sẵn có.", + "keyboardSwitchText": "Đổi sang bàn phím \"${NAME}\".", + "kickOccurredText": "${NAME} đã bị đuổi.", + "kickQuestionText": "Đuổi ${NAME}?", + "kickText": "Đuổi", + "kickVoteCantKickAdminsText": "Không thể kick Admin", + "kickVoteCantKickSelfText": "Bạn không thể đuổi chính bạn", + "kickVoteFailedNotEnoughVotersText": "Không đủ người chơi để bỏ phiếu.", + "kickVoteFailedText": "Bầu chọn đuổi người chơi thất bại.", + "kickVoteStartedText": "Một cuộc bầu chọn người chơi đã bắt đầu bởi ${NAME}.", + "kickVoteText": "Bầu chọn để Đuổi", + "kickVotingDisabledText": "Tính năng bầu chọn để đuổi đã tắt", + "kickWithChatText": "Nhấn ${YES} trong cuộc trò chuyện để đồng ý và ${NO} để phản đối.", + "killsTallyText": "Giết ${COUNT}", + "killsText": "Số mạng", + "kioskWindow": { + "easyText": "Dễ", + "epicModeText": "Chế độ chậm", + "fullMenuText": "Menu đầy đủ", + "hardText": "Khó", + "mediumText": "Bình thường", + "singlePlayerExamplesText": "Ví dụ người chơi đơn / Co-op", + "versusExamplesText": "Ví dụ Versus" + }, + "languageSetText": "Ngôn ngữ hiện là \"${LANGUAGE}\".", + "lapNumberText": "Vòng ${CURRENT}/${TOTAL}", + "lastGamesText": "(trò chơi ${COUNT} mới nhất)", + "leaderboardsText": "Bảng xếp hạng", + "league": { + "allTimeText": "Mọi lúc", + "currentSeasonText": "Mùa hiện tại (${NUMBER})", + "leagueFullText": "${NAME} Giải đấu", + "leagueRankText": "Hạng giải đấu", + "leagueText": "Giải đấu", + "rankInLeagueText": "#${RANK},${NAME} Giải đấu${SUFFIX}", + "seasonEndedDaysAgoText": "Mùa kết thúc ${NUMBER} ngày trước.", + "seasonEndsDaysText": "Mùa kết thúc ${NUMBER} ngày.", + "seasonEndsHoursText": "Mùa kết thúc ${NUMBER} giờ trước.", + "seasonEndsMinutesText": "Mùa kết thúc ${NUMBER} phúc trước.", + "seasonText": "Mùa ${NUMBER}", + "tournamentLeagueText": "Bạn phải đạt giải đấu ${NAME} để tham gia giải đấu này.", + "trophyCountsResetText": "Số lượng cúp sẽ thiết lập lại vào mùa giải tới." + }, + "levelBestScoresText": "Điểm số tốt nhất trên ${LEVEL}", + "levelBestTimesText": "Thời gian tốt nhất trên ${LEVEL}", + "levelIsLockedText": "${LEVEL} đã bị khóa.", + "levelMustBeCompletedFirstText": "${LEVEL} phải được hoàn thành trước.", + "levelText": "Màn chơi ${NUMBER}", + "levelUnlockedText": "Mở khóa cấp độ!", + "livesBonusText": "Tiền thưởng sống sót", + "loadingText": "Đang tải", + "loadingTryAgainText": "Đang tải; thử lại sau một lúc ...", + "macControllerSubsystemBothText": "Cả hai (không nên dùng)", + "macControllerSubsystemClassicText": "Cổ điển", + "macControllerSubsystemDescriptionText": "(thử thay đổi điều này nếu bộ điều khiển của bạn không hoạt động)", + "macControllerSubsystemMFiNoteText": "Đã phát hiện bộ điều khiển dành cho iOS / Mac;\nBạn có thể muốn bật những thứ này trong Cài đặt -> Bộ điều khiển", + "macControllerSubsystemMFiText": "Được tạo cho iOS / Mac", + "macControllerSubsystemTitleText": "Hỗ trợ điều khiển", + "mainMenu": { + "creditsText": "Giới thiệu", + "demoMenuText": "Cài đặt Demo", + "endGameText": "kết thúc game", + "exitGameText": "Thoat game", + "exitToMenuText": "Quay về Menu?", + "howToPlayText": "Hướng dẫn chơi", + "justPlayerText": "(Chỉ có ${NAME})", + "leaveGameText": "Rời trận", + "leavePartyConfirmText": "Có thật sự thoát game?", + "leavePartyText": "Rời nhóm", + "quitText": "Thoát", + "resumeText": "Trở lại", + "settingsText": "Tùy chỉnh" + }, + "makeItSoText": "Làm cho nó như vậy", + "mapSelectGetMoreMapsText": "Nhận thêm bản đồ ...", + "mapSelectText": "Chọn...", + "mapSelectTitleText": "Bản đồ ${GAME}", + "mapText": "Bản đồ", + "maxConnectionsText": "Kết nối tối đa", + "maxPartySizeText": "Số người trong bữa tiệc tối đa", + "maxPlayersText": "Người chơi tối đa", + "modeArcadeText": "Chế độ giải trí", + "modeClassicText": "Chế độ cổ điển", + "modeDemoText": "Chế độ thử nghiệm", + "mostValuablePlayerText": "Người chơi đáng giá nhất", + "mostViolatedPlayerText": "Người chơi bị chết nhiều nhất", + "mostViolentPlayerText": "Người chơi bạo lực nhất", + "moveText": "Di chuyển", + "multiKillText": "${COUNT}-KILL!!!", + "multiPlayerCountText": "${COUNT} người chơi", + "mustInviteFriendsText": "Lưu ý: bạn phải mời bạn bè vào\nbảng điều khiển \"${GATHER}\" hoặc đính kèm\nbộ điều khiển để chơi nhiều người chơi.", + "nameBetrayedText": "${NAME} đã phản bội ${VICTIM}.", + "nameDiedText": "${NAME} đã hy sinh.", + "nameKilledText": "${NAME} đã tiêu diệt ${VICTIM}.", + "nameNotEmptyText": "Tên không thể để trống!", + "nameScoresText": "${NAME} Ghi điểm!", + "nameSuicideKidFriendlyText": "${NAME} vô tình chết.", + "nameSuicideText": "${NAME} tự tử.", + "nameText": "Tên", + "nativeText": "Tự nhiên", + "newPersonalBestText": "Mới tốt nhất cá nhân!", + "newTestBuildAvailableText": "Một bản dựng thử nghiệm mới hơn có sẵn! (${VERSION} xây dựng ${BUILD}).\nNhận nó tại ${ADDRESS}", + "newText": "Mới", + "newVersionAvailableText": "Đã có phiên bản mới hơn của ${APP_NAME}! (${VERSION})", + "nextAchievementsText": "Thành tựu tiếp theo:", + "nextLevelText": "Cấp độ tiếp theo", + "noAchievementsRemainingText": "không có gì hết", + "noContinuesText": "(không tiếp tục)", + "noExternalStorageErrorText": "Không tìm thấy bộ nhớ ngoài trên thiết bị này", + "noGameCircleText": "Lỗi: không đăng nhập vào GameCircle", + "noScoresYetText": "Chưa có điểm nào.", + "noThanksText": "Không cảm ơn", + "noTournamentsInTestBuildText": "CẢNH BÁO: Điểm thi đấu từ bản dựng thử nghiệm này sẽ bị bỏ qua.", + "noValidMapsErrorText": "Không tìm thấy bản đồ hợp lệ cho loại trò chơi này.", + "notEnoughPlayersRemainingText": "Không đủ người chơi còn lại; thoát ra và bắt đầu một trò chơi mới", + "notEnoughPlayersText": "Bạn cần ít nhất ${COUNT} người chơi để bắt đầu trò chơi này!", + "notNowText": "Không phải bây giờ", + "notSignedInErrorText": "Bạn phải đăng nhập để làm điều này.", + "notSignedInGooglePlayErrorText": "Bạn phải đăng nhập bằng Google Play để làm điều này.", + "notSignedInText": "chưa đăng nhập", + "nothingIsSelectedErrorText": "Bạn chưa chọn cái nào!", + "numberText": "#${NUMBER}", + "offText": "Tắt", + "okText": "Ok", + "onText": "Bật", + "oneMomentText": "Một lúc...", + "onslaughtRespawnText": "${PLAYER} sẽ hồi sinh trong ải ${WAVE}", + "orText": "${A} hoặc ${B}", + "otherText": "Khác ...", + "outOfText": "(#${RANK} ra khỏi ${ALL})", + "ownFlagAtYourBaseWarning": "Cờ của riêng bạn phải là\ntại chỗ của bạn để ghi điểm!", + "packageModsEnabledErrorText": "Không cho phép chơi qua mạng khi gói mods nội bộ đang bật (mở Cài đặt->Nâng cao)", + "partyWindow": { + "chatMessageText": "Nhắn tin", + "emptyText": "Tổ đội của bạn không có ai hết", + "hostText": "(chủ phòng)", + "sendText": "Gửi", + "titleText": "Tổ đội của bạn" + }, + "pausedByHostText": "(Dừng lại bởi chủ phòng)", + "perfectWaveText": "Ải hoàn hảo!", + "pickUpText": "Nhặt", + "playModes": { + "coopText": "Chế độ co-op", + "freeForAllText": "Đấu đơn", + "multiTeamText": "Nhiều đội", + "singlePlayerCoopText": "Chơi đơn hoặc co-op", + "teamsText": "Đội" + }, + "playText": "Chơi", + "playWindow": { + "oneToFourPlayersText": "1-4 người chơi", + "titleText": "Chơi", + "twoToEightPlayersText": "2-8 người chơi" + }, + "playerCountAbbreviatedText": "${COUNT} người chơi", + "playerDelayedJoinText": "${PLAYER} sẽ tham gia vào đầu ván tiếp theo.", + "playerInfoText": "Thông tin Người chơi", + "playerLeftText": "${PLAYER} rời khỏi trò chơi.", + "playerLimitReachedText": "Đạt giới hạn ${COUNT} người chơi; không cho phép thêm người chơi.", + "playerProfilesWindow": { + "cantDeleteAccountProfileText": "Bạn không thể xóa hồ sơ tài khoản của bạn.", + "deleteButtonText": "Xóa\nHồ sơ", + "deleteConfirmText": "Xóa '${PROFILE}'?", + "editButtonText": "Sửa\nHồ sơ", + "explanationText": "(chỉnh sửa tên người chơi và hình đại diện cho tải khoản này)", + "newButtonText": "Hồ sơ \nMới", + "titleText": "Hồ sơ người chơi" + }, + "playerText": "Người chơi", + "playlistNoValidGamesErrorText": "Danh sách này không chứa trò chơi nào đã mở khóa.", + "playlistNotFoundText": "không tìm thấy danh sách", + "playlistText": "Danh sách chế độ chơi", + "playlistsText": "Danh sách", + "pleaseRateText": "Nếu bạn thấy ${APP_NAME} vui lòng \nđánh giá hoặc viết \ncảm nhận.\nĐiều này giúp hỗ trợ phát triển trong tương lai.\ncảm ơn!\n-eric", + "pleaseWaitText": "Vui lòng chờ...", + "pluginClassLoadErrorText": "Lỗi khi tải lớp plugin '${PLUGIN}': ${ERROR}", + "pluginInitErrorText": "Lỗi khi nhập plugin '${PLUGIN}': ${ERROR}", + "pluginsDetectedText": "Đã phát hiện (các) plugin mới. Khởi động lại để kích hoạt chúng hoặc định cấu hình chúng trong cài đặt.", + "pluginsRemovedText": "Không còn tìm thấy ${NUM} plugin nào nữa.", + "pluginsText": "Cắm", + "practiceText": "Luyện tập", + "pressAnyButtonPlayAgainText": "Nhấn nút bất kỳ để chơi lại...", + "pressAnyButtonText": "Nhấn nút bất kỳ để tiếp tục...", + "pressAnyButtonToJoinText": "nhấn nút bất kỳ để gia nhập...", + "pressAnyKeyButtonPlayAgainText": "Nhấn phím/nút bất kỳ để chơi lại...", + "pressAnyKeyButtonText": "Nhấn phím/nút bất kỳ để tiếp tục...", + "pressAnyKeyText": "Nhấn nút bất kỳ...", + "pressJumpToFlyText": "** nhấn nhảy liên tục để bay **", + "pressPunchToJoinText": "Nhấn ĐẤM để gia nhập...", + "pressToOverrideCharacterText": "nhấn ${BUTTONS} để đổi nhân vật", + "pressToSelectProfileText": "nhấn ${BUTTONS} để chọn người chơi", + "pressToSelectTeamText": "nhấn ${BUTTONS} để chọn đội", + "promoCodeWindow": { + "codeText": "Mã code", + "enterText": "Nhập" + }, + "promoSubmitErrorText": "Lỗi gửi code; kiểm tra kết nối mạng", + "ps3ControllersWindow": { + "macInstructionsText": "Tắt nguồn ở mặt sau của PS3, đảm bảo\nBluetooth được bật trên máy Mac của bạn, sau đó kết nối bộ điều khiển của bạn\nđến máy Mac của bạn thông qua cáp USB để ghép nối hai. Từ đó về sau\ncó thể sử dụng nút home của bộ điều khiển để kết nối nó với máy Mac của bạn\nở chế độ có dây (USB) hoặc không dây (Bluetooth).\n\nTrên một số máy Mac, bạn có thể được nhắc nhập mật mã khi ghép nối.\nNếu điều này xảy ra, hãy xem hướng dẫn hoặc google sau đây để được giúp đỡ.\n\n\n\n\nBộ điều khiển PS3 được kết nối không dây sẽ hiển thị trong thiết bị\ndanh sách trong Tùy chọn hệ thống-> Bluetooth. Bạn có thể cần phải loại bỏ chúng\ntừ danh sách đó khi bạn muốn sử dụng lại chúng với PS3.\n\nĐồng thời đảm bảo ngắt kết nối chúng khỏi Bluetooth khi không ở trong\nsử dụng hoặc pin của họ sẽ tiếp tục cạn kiệt.\n\nBluetooth nên xử lý tối đa 7 thiết bị được kết nối,\nmặc dù số dặm của bạn có thể thay đổi.", + "ouyaInstructionsText": "Để sử dụng cần điều khiển PS3 với OUYA, \nchỉ cần kết nối nó với một \ncổng USB để ghép đôi nó. \nLàm điều này có thể ngắt kết nối các cần điều khiển khác của bạn, vì vậy nên khởi động lại OUYA và ngắt cổng kết nối USB.", + "pairingTutorialText": "Đang ghép video hướng dẫn", + "titleText": "Sử dụng cần điều khiển PS3 với ${APP_NAME}:" + }, + "punchBoldText": "ĐẤM", + "punchText": "Đấm", + "purchaseForText": "Mua với ${PRICE}", + "purchaseGameText": "Mua trò chơi", + "purchasingText": "Đang mua...", + "quitGameText": "Rời ${APP_NAME}?", + "quittingIn5SecondsText": "Rời đi trong 5 giây...", + "randomPlayerNamesText": "Tên_Mặcđịnh", + "randomText": "Ngẫu nhiên", + "rankText": "Xếp hạng", + "ratingText": "Đánh giá", + "reachWave2Text": "Tới màn 2 để xếp hạng.", + "readyText": "sẵn sàng", + "recentText": "Gần đây", + "remoteAppInfoShortText": "${APP_NAME} sẽ vui hơn khi chơi cùng gia đình và bạn bè.\nKết nối một hoặc nhiều \ntay cầm phần cứng hoặc tải ứng dụng \n${REMOTE_APP_NAME} trên điện thoại hoặc máy tính bảng để sử dụng chúng như tay cầm.", + "remote_app": { + "app_name": "Điều khiển Bombsquad", + "app_name_short": "Điều khiển BS", + "button_position": "Vị trí Nút", + "button_size": "Kích cỡ Nút", + "cant_resolve_host": "Không thể tìm thấy máy chủ.", + "capturing": "Đang chờ chấp thuận...", + "connected": "Đã kết nối", + "description": "Sử dụng điện thoại của bạn hoặc máy tính bảng như cần điều khiển với Bombsquad.\nTới 8 thiết bị có thể kết nối một lần với trò chơi nội bộ nhiều người chơi điên cuồng trên một màn hình TV hoặc máy tính bảng.", + "disconnected": "Đã bị ngắt kết nối bởi máy chủ.", + "dpad_fixed": "Cố định", + "dpad_floating": "Di chuyển", + "dpad_position": "Vị trí D-pad", + "dpad_size": "Kích cỡ D-pad", + "dpad_type": "Loại D-pad", + "enter_an_address": "Nhập địa chỉ", + "game_full": "Trò chơi đã đủ người chơi hoặc không chấp nhận kết nối.", + "game_shut_down": "Trò chơi đã tắt.", + "hardware_buttons": "Nút Phần cứng", + "join_by_address": "Gia nhập qua địa chỉ...", + "lag": "Trễ: ${SECONDS} giây", + "reset": "Cài lại mặc định", + "run1": "Chạy 1", + "run2": "Chạy 2", + "searching": "Đang tìm trò chơi Bombsquad...", + "searching_caption": "Nhấn vào trò chơi để gia nhập.\nHãy chắc chắn rằng bạn có cùng mạng wifi.", + "start": "Bắt đầu", + "version_mismatch": "Không trùng phiên bản.\nChắc chắn rằng Bombsquad và\nBombsquad Remote là phiên bản mới nhất và thử lại." + }, + "removeInGameAdsText": "Mở khóa \"${PRO}\" trong cửa hàng để loại bỏ quảng cáo.", + "renameText": "Đặt lại tên", + "replayEndText": "Kết thúc phát lại", + "replayNameDefaultText": "Xem lại trò chơi vừa rồi", + "replayReadErrorText": "Lỗi trong lúc đọc tập tin phát lại.", + "replayRenameWarningText": "Đặt tên \"${REPLAY}\" sau trò chơi nếu bạn muốn giữ nó; nếu không nó sẽ bị viết đè.", + "replayVersionErrorText": "Xin lỗi, phát lại này đã được tạo ra\nbởi phiên bản khác của trò chơi và không thể sử dụng.", + "replayWatchText": "Xem phát lại", + "replayWriteErrorText": "Lỗi viết tập tin phát lại.", + "replaysText": "Phát lại", + "reportPlayerExplanationText": "Sử dụng email này để tố cáo gian lận, ngôn ngữ thô tục, hoặc các hành vi xấu khác.\nLàm ơn mô tả dưới đây:", + "reportThisPlayerCheatingText": "Gian lận", + "reportThisPlayerLanguageText": "Ngôn ngữ thô tục", + "reportThisPlayerReasonText": "Lý do tố cáo?", + "reportThisPlayerText": "Tố cáo người chơi này", + "requestingText": "Đang yêu cầu...", + "restartText": "Khởi động lại", + "retryText": "Thử lại", + "revertText": "Hủy bỏ", + "runText": "Chạy", + "saveText": "Lưu", + "scanScriptsErrorText": "Lỗi trong lúc quét mã bản thảo; xem bản thông báo cho chi tiết.", + "scoreChallengesText": "Thử thách Điểm số", + "scoreListUnavailableText": "Danh sách điểm số không có sẵn.", + "scoreText": "Điểm số", + "scoreUnits": { + "millisecondsText": "Mi-li-giây", + "pointsText": "Điểm", + "secondsText": "Giây" + }, + "scoreWasText": "(Cao nhất ${COUNT})", + "selectText": "Chọn", + "seriesWinLine1PlayerText": "ĐÃ THẮNG", + "seriesWinLine1TeamText": "ĐÃ THẮNG", + "seriesWinLine1Text": "ĐÃ THẮNG", + "seriesWinLine2Text": "LOẠT GAME!", + "settingsWindow": { + "accountText": "Tài khoản", + "advancedText": "Nâng cao", + "audioText": "Âm thanh", + "controllersText": "Điều khiển", + "graphicsText": "Đồ họa", + "playerProfilesMovedText": "Ghi chú: Hồ sơ nhân vật đã được chuyển tới cửa sổ Tài khoản ở màn hình chính.", + "titleText": "Cài đặt" + }, + "settingsWindowAdvanced": { + "alwaysUseInternalKeyboardDescriptionText": "(một bàn phím trên màn hình đơn giản, thân thiện với tay cầm cho nhập văn bản)", + "alwaysUseInternalKeyboardText": "Luôn sử dụng bàn phím nội bộ", + "benchmarksText": "Điểm chuẩn & Kiểm tra độ trễ", + "disableCameraGyroscopeMotionText": "Vô hiệu hóa Camera Gyroscope Motion", + "disableCameraShakeText": "Vô hiệu hóa Camera Shake", + "disableThisNotice": "(bạn có thể tắt thông báo này trong cài đặt nâng cao)", + "enablePackageModsDescriptionText": "(thêm tối đa chỗ mod nhưng tắt chơi qua mạng)", + "enablePackageModsText": "Bật Gói Mod Cục bộ", + "enterPromoCodeText": "Nhập mã", + "forTestingText": "Ghi chú: những giá trị này chỉ dành cho kiểm tra và sẽ bị mất khi rời khỏi ứng dụng.", + "helpTranslateText": "Cộng đồng dịch ${APP_NAME} là một cộng đồng được hỗ trợ.\nNếu bạn muốn góp phần hoặc sửa bản dịch,\nđi theo đường dẫn bên dưới.", + "kickIdlePlayersText": "Đuổi người chơi không hoạt động", + "kidFriendlyModeText": "Chế độ thân thiện với trẻ em (giảm bạo lực , vân vân)", + "languageText": "Ngôn ngữ", + "moddingGuideText": "Hướng dẫn mod", + "mustRestartText": "Bạn phải khởi động lại trò chơi để áp dụng cài đặt", + "netTestingText": "Kiểm tra mạng", + "resetText": "Cài lại", + "showBombTrajectoriesText": "Hiển thị quỹ đạo của bom", + "showPlayerNamesText": "Hiển thị tên người chơi", + "showUserModsText": "Hiển thị Thư mục Mod", + "titleText": "Nâng cao", + "translationEditorButtonText": "${APP_NAME} Thiết lập ngôn ngữ", + "translationFetchErrorText": "trạng thái bản dịch không có sẵn", + "translationFetchingStatusText": "kiểm tra trạng thái bản dịch...", + "translationInformMe": "Thông báo tôi khi ngôn ngữ cần được nâng cấp", + "translationNoUpdateNeededText": "Ngôn ngữ hiện tại đã được nâng cấp; quẩy đi!", + "translationUpdateNeededText": "** ngôn ngữ hiện tại cần được nâng cấp!! **", + "vrTestingText": "Thử nghiệm VR" + }, + "shareText": "Chia sẻ", + "sharingText": "Đang chia sẻ...", + "showText": "Xem", + "signInForPromoCodeText": "Bạn phải đăng nhập vào một tài khoản để nhập code", + "signInWithGameCenterText": "Để sử dụng một tài khoản Trung tâm trò chơi,\n đăng nhập với ứng dụng Trung Tâm Trò Chơi", + "singleGamePlaylistNameText": "Chỉ ${GAME}", + "singlePlayerCountText": "1 người chơi", + "soloNameFilterText": "Solo ${NAME}", + "soundtrackTypeNames": { + "CharSelect": "Chọn nhân vật", + "Chosen One": "Người được chọn", + "Epic": "Những trò chơi chế độ chậm", + "Epic Race": "Chạy đua chậm", + "FlagCatcher": "Cướp cờ", + "Flying": "Mảnh đất vui vẻ", + "Football": "Bóng bầu dục", + "ForwardMarch": "Công kích", + "GrandRomp": "Chinh phục", + "Hockey": "Khúc côn cầu", + "Keep Away": "Tránh xa", + "Marching": "Thủ thành", + "Menu": "Màn hình chính", + "Onslaught": "Tử chiến (Máy)", + "Race": "Chạy đua", + "Scary": "Chiếm đồi", + "Scores": "Màn hình điểm số", + "Survival": "Loại trừ", + "ToTheDeath": "Tử chiến", + "Victory": "Màn hình điểm số cuối cùng" + }, + "spaceKeyText": "dấu cách", + "statsText": "Thống kê", + "storagePermissionAccessText": "Yêu cầu truy cập lưu trữ", + "store": { + "alreadyOwnText": "Bạn đã có ${NAME}!", + "bombSquadProNameText": "${APP_NAME} Chuyên nghiệp", + "bombSquadProNewDescriptionText": "• Loại bỏ quảng cáo\n• Mở khóa thêm cài đặt trò chơi\n• Bao gồm cả:", + "buyText": "Mua", + "charactersText": "Nhân Vật", + "comingSoonText": "Sắp có mặt...", + "extrasText": "Nâng cao", + "freeBombSquadProText": "Hiện tại Bombsquad miễn phí, nhưng khi bạn mua nó trước đây thì không. Bây giờ bạn sẽ nhận được Bombsquad Chuyên nghiệp và ${COUNT} vé \nnhư một lời cảm ơn.\nTận hưởng những điều mới, và cảm ơn vì sự hỗ trợ của bạn!\n-Eric", + "holidaySpecialText": "Đặc biệt mùa lễ hội", + "howToSwitchCharactersText": "(đi tới \"${SETTINGS} -> ${PLAYER_PROFILES}\" để thay và chỉnh sửa nhân vật)", + "howToUseIconsText": "(tạo hồ sơ người chơi toàn cầu (trong cửa sổ tài khoản) để sử dụng)", + "howToUseMapsText": "Sử dụng ở danh sách đội/đơn của bạn)", + "iconsText": "Biểu tượng", + "loadErrorText": "Không thể tải trang.\nKiểm tra kết nối mạng của bạn.", + "loadingText": "đang tải", + "mapsText": "Bản đồ", + "miniGamesText": "Trò chơi", + "oneTimeOnlyText": "(một lần duy nhất)", + "purchaseAlreadyInProgressText": "Vật phẩm này đang được mua.", + "purchaseConfirmText": "Mua ${ITEM}?", + "purchaseNotValidError": "Không thể mua.\nLiên hệ ${EMAIL} nếu đây là lỗi.", + "purchaseText": "Mua", + "saleBundleText": "Combo giảm giá!", + "saleExclaimText": "Giảm giá!", + "salePercentText": "(giảm ${PERCENT}%)", + "saleText": "Giảm giá", + "searchText": "Tìm kiếm", + "teamsFreeForAllGamesText": "Trò chơi Đội/Đơn", + "totalWorthText": "*** Đáng giá ${TOTAL_WORTH}! ***", + "upgradeQuestionText": "Nâng cấp?", + "winterSpecialText": "Mùa đông đặc biệt", + "youOwnThisText": "- bạn đã có cái này -" + }, + "storeDescriptionText": "Trò chơi tổ đội 8 người chơi điên cuồng!\n\nThổi tung bạn bè (hoặc máy) trong một giải đấu mini-games toàn chất nổ như Cướp cờ, \n\nkhúc côn cầu và tử chiến tốc độ chậm!\nĐiều khiển đơn giản và hỗ trợ nhiều loại\ncần điều khiển làm cho dễ dàng chơi tới 8 người; bạn còn có thể sử dụng thiết bị di động của bạn như cần điều khiển thông qua ứng dụng miễn phí 'Điều khiển BombSquad'!\nNém bom đi!\nTới www.froemling.net/bombsquad để thêm thông tin.", + "storeDescriptions": { + "blowUpYourFriendsText": "Thổi bay bạn bè của bạn.", + "competeInMiniGamesText": "Cạnh tranh trong các trò chơi khác nhau từ chạy đua tới bay lượn.", + "customize2Text": "Điều chỉnh nhân vật, trò chơi, và thậm chí cả nhạc nền.", + "customizeText": "Tùy chỉnh nhân vật và tạo danh sách trò chơi của riêng bạn.", + "sportsMoreFunText": "Các môn thể thao sẽ vui hơn với chất nổ.", + "teamUpAgainstComputerText": "Lập đội chống lại máy." + }, + "storeText": "Cửa hàng", + "submitText": "Gửi", + "submittingPromoCodeText": "Đang xác nhận mã code...", + "teamNamesColorText": "Tên/Màu sắc đội...", + "telnetAccessGrantedText": "Đã kích hoạt truy cập giao thức.", + "telnetAccessText": "Phát hiện truy cập giao thức; cho phép?", + "testBuildErrorText": "Bản dựng thử nghiệm này không còn hoạt động; Vui lòng kiểm tra phiên bản mới.", + "testBuildText": "Thử nghiệm xây dựng", + "testBuildValidateErrorText": "Không thể xác nhận xây dựng thử nghiệm. (không có kết nối mạng?)", + "testBuildValidatedText": "Kiểm tra bản dựng được xác thực; Tận hưởng!", + "thankYouText": "Cảm ơn vì sự hỗ trợ của bạn! Hãy tận hưởng trò chơi!!", + "threeKillText": "Tam Sát!!", + "timeBonusText": "Thưởng thời gian", + "timeElapsedText": "Thời gian còn lại", + "timeExpiredText": "Hết giờ", + "timeSuffixDaysText": "${COUNT} ngày", + "timeSuffixHoursText": "${COUNT} giờ", + "timeSuffixMinutesText": "${COUNT} phút", + "timeSuffixSecondsText": "${COUNT} giây", + "tipText": "Gợi ý", + "titleText": "Bombsquad", + "titleVRText": "Bombsquad Thực tế ảo", + "topFriendsText": "Bạn bè đứng đầu", + "tournamentCheckingStateText": "Đang kiểm tra trạng thái giải đấu; vui lòng chờ...", + "tournamentEndedText": "Giải đấu này đã kết thúc. Giải đấu mới sẽ bắt đầu sớm.", + "tournamentEntryText": "Lệ phí", + "tournamentResultsRecentText": "Kết quả giải đấu gần đây", + "tournamentStandingsText": "Bảng xếp hạng giải đấu", + "tournamentText": "Giải đấu", + "tournamentTimeExpiredText": "Giải đấu đã hết thời gian.", + "tournamentsDisabledWorkspaceText": "Các giải đấu bị vô hiệu hóa khi không gian làm việc đang hoạt động.\nĐể bật lại các giải đấu, hãy tắt không gian làm việc của bạn và khởi động lại.", + "tournamentsText": "Giải đấu", + "translations": { + "characterNames": { + "Agent Johnson": "Điệp Viên Johnson", + "B-9000": "B-9000", + "Bernard": "Bernard", + "Bones": "Xương", + "Butch": "Butch", + "Easter Bunny": "Thỏ Phục Sinh", + "Flopsy": "Flopsy", + "Frosty": "Người Tuyết", + "Gretel": "Gretel", + "Grumbledorf": "Grumbledorf", + "Jack Morgan": "Jack Morgan", + "Kronk": "Kronk", + "Lee": "Lee", + "Lucky": "Lucky", + "Mel": "Mel", + "Middle-Man": "Middle-Man", + "Minimus": "Minimus", + "Pascal": "Pascal", + "Pixel": "Pixel", + "Sammy Slam": "Sammy Slam", + "Santa Claus": "Santa Claus", + "Snake Shadow": "Snake Shadow", + "Spaz": "Spaz", + "Taobao Mascot": "Taobao Mascot", + "Todd McBurton": "Todd McBurton", + "Zoe": "Zoe", + "Zola": "Zola" + }, + "coopLevelNames": { + "${GAME} Training": "${GAME} (Luyện tập)", + "Infinite ${GAME}": "${GAME} (Vô tận)", + "Infinite Onslaught": "Tử chiến (Vô tận)", + "Infinite Runaround": "Thủ thành (Vô tận)", + "Onslaught Training": "Tử chiến (Luyện tập)", + "Pro ${GAME}": "${GAME} Chuyên nghiệp", + "Pro Football": "Bóng bầu dục (Chuyên nghiệp)", + "Pro Onslaught": "Tử chiến (Chuyên nghiệp)", + "Pro Runaround": "Thủ thành (Chuyên nghiệp)", + "Rookie ${GAME}": "${GAME} (Tân binh)", + "Rookie Football": "Bóng bầu dục (Tân binh)", + "Rookie Onslaught": "Tử chiến (Tân Binh)", + "The Last Stand": "Người cuối cùng", + "Uber ${GAME}": "${GAME} (Bậc thầy)", + "Uber Football": "Bóng bầu dục (Bậc thầy)", + "Uber Onslaught": "Tử chiến (Bậc thầy)", + "Uber Runaround": "Thủ thành (Bậc thầy)" + }, + "gameDescriptions": { + "Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Làm người được chọn trong thời gian nhất định để chiến thắng.\nGiết người được chọn để trở thành họ.", + "Bomb as many targets as you can.": "Dội bom nhiều mục tiêu nhất có thể.", + "Carry the flag for ${ARG1} seconds.": "Cầm cờ trong ${ARG1} giây.", + "Carry the flag for a set length of time.": "Cầm cờ trong thời gian nhất định.", + "Crush ${ARG1} of your enemies.": "Đè bẹp ${ARG1} kẻ địch.", + "Defeat all enemies.": "Đánh bại tất cả kẻ địch.", + "Dodge the falling bombs.": "Tránh những quả Bomb đang rơi.", + "Final glorious epic slow motion battle to the death.": "Cuối cùng vinh quang chiến đấu chậm đến cái chết.", + "Gather eggs!": "Lấy trứng!", + "Get the flag to the enemy end zone.": "Lấy cờ tới khu vực kết thúc của kẻ địch.", + "How fast can you defeat the ninjas?": "Tốc độ tiêu diệt ninja của bạn nhanh bao nhiêu?", + "Kill a set number of enemies to win.": "Giết một số lượng địch nhất định sẽ thắng.", + "Last one standing wins.": "Người cuối cùng còn sống thắng.", + "Last remaining alive wins.": "Người còn sống cuối cùng thắng.", + "Last team standing wins.": "Đội sống sót cuối cùng chiến thắng.", + "Prevent enemies from reaching the exit.": "Chặn địch đi tới lối thoát.", + "Reach the enemy flag to score.": "Chạm cờ địch để ghi điểm.", + "Return the enemy flag to score.": "Lấy cờ địch về căn cứ của bạn để ghi điểm.", + "Run ${ARG1} laps.": "Chạy ${ARG1} vòng.", + "Run ${ARG1} laps. Your entire team has to finish.": "Chạy ${ARG1} vòng. Toàn bộ thành viên của đội phải hoàn thành.", + "Run 1 lap.": "Chạy 1 vòng.", + "Run 1 lap. Your entire team has to finish.": "Chạy 1 vòng. Toàn bộ thành viên của đội phải hoàn thành.", + "Run real fast!": "Chạy nhanh như hack đi! (Cấm hack)", + "Score ${ARG1} goals.": "Ghi ${ARG1} bàn.", + "Score ${ARG1} touchdowns.": "Ghi ${ARG1} bàn.", + "Score a goal.": "Ghi một bàn.", + "Score a touchdown.": "Ghi một bàn.", + "Score some goals.": "Ghi vài bàn thắng.", + "Secure all ${ARG1} flags.": "Chiếm giữ tất cả {ARG1} cờ.", + "Secure all flags on the map to win.": "Chiếm giữ tất cả cờ trên bản đồ để chiến thắng.", + "Secure the flag for ${ARG1} seconds.": "Chiếm giữ cờ trong ${ARG1} giây.", + "Secure the flag for a set length of time.": "Chiếm giữ cờ trong một khoảng thời gian cài sẵn.", + "Steal the enemy flag ${ARG1} times.": "Cướp cờ địch ${ARG1} lần.", + "Steal the enemy flag.": "Cướp cờ địch.", + "There can be only one.": "Chỉ có thể có một.", + "Touch the enemy flag ${ARG1} times.": "Chạm cờ địch ${ARG1} lần.", + "Touch the enemy flag.": "Chạm cờ địch", + "carry the flag for ${ARG1} seconds": "cầm cờ trong ${ARG1} giây.", + "kill ${ARG1} enemies": "giết ${ARG1} địch", + "last one standing wins": "người cuối cùng còn sống thắng", + "last team standing wins": "Đội sống sót cuối cùng chiến thắng.", + "return ${ARG1} flags": "Lấy ${ARG1} cờ", + "return 1 flag": "Lấy 1 lá cờ", + "run ${ARG1} laps": "chạy ${ARG1} vòng", + "run 1 lap": "chạy 1 vòng", + "score ${ARG1} goals": "ghi ${ARG1} bàn", + "score ${ARG1} touchdowns": "ghi ${ARG1} bàn.", + "score a goal": "ghi một bàn.", + "score a touchdown": "ghi một bàn.", + "secure all ${ARG1} flags": "Chiếm giữ tất cả ${ARG1} cờ.", + "secure the flag for ${ARG1} seconds": "bảo vệ cờ trong ${ARG1} giây.", + "touch ${ARG1} flags": "chạm ${ARG1} cờ", + "touch 1 flag": "chạm 1 lá cờ" + }, + "gameNames": { + "Assault": "Chiếm lĩnh", + "Capture the Flag": "Lấy cờ", + "Chosen One": "Người Được Chọn", + "Conquest": "Chiếm Đóng", + "Death Match": "Đối Đầu", + "Easter Egg Hunt": "Săn Trứng", + "Elimination": "Loại Bỏ", + "Football": "Bóng Bầu Dục", + "Hockey": "Hockey", + "Keep Away": "Tránh Xa", + "King of the Hill": "Vua Của Đỉnh Núi", + "Meteor Shower": "Mưa Bom", + "Ninja Fight": "Cuộc đấu của Ninja", + "Onslaught": "Onslaught", + "Race": "Đua", + "Runaround": "Chạy Một Vòng", + "Target Practice": "Luyện Ném", + "The Last Stand": "Người cuối cùng" + }, + "inputDeviceNames": { + "Keyboard": "Bàn Phím S1", + "Keyboard P2": "Bàn Phím S2" + }, + "languages": { + "Arabic": "Tiếng Ả Rập", + "Belarussian": "Tiếng Belarus", + "Chinese": "Tiếng Trung Giản thể", + "ChineseTraditional": "Tiếng Trung Quốc truyền thống", + "Croatian": "Tiếng Croatia", + "Czech": "Tiếng Séc", + "Danish": "Tiếng Đan Mạch", + "Dutch": "Tiếng Hà Lan", + "English": "Tiếng Anh", + "Esperanto": "Quốc tế ngữ", + "Filipino": "Người Phi Luật Tân", + "Finnish": "Tiếng Phần Lan", + "French": "Tiếng Pháp", + "German": "Tiếng Đức", + "Gibberish": "Tiếng vô nghia", + "Greek": "Tiếng Greeks", + "Hindi": "Tiếng Hin-ddi", + "Hungarian": "Tiếng Hungary", + "Indonesian": "Tiếng Indonesia", + "Italian": "Tiếng Ý", + "Japanese": "Tiếng Nhật", + "Korean": "Tiếng Hàn", + "Persian": "Tiếng Ba Tư", + "Polish": "Tiếng Polish", + "Portuguese": "Tiếng Bồ Đào Nha", + "Romanian": "Tiếng Rumani", + "Russian": "Tiếng Nga", + "Serbian": "Tiếng Serbia", + "Slovak": "Tiếng Slovakia", + "Spanish": "Tiếng Tây Ban Nha", + "Swedish": "Tiếng Thụy Điển", + "Tamil": "Tamil", + "Thai": "Tiếng thái", + "Turkish": "Tiếng Thổ Nhĩ Kỳ", + "Ukrainian": "Tiếng Ukraina", + "Venetian": "Tiếng Venice", + "Vietnamese": "Tiếng Việt" + }, + "leagueNames": { + "Bronze": "Đồng", + "Diamond": "Kim Cương", + "Gold": "Vàng", + "Silver": "Bạc" + }, + "mapsNames": { + "Big G": "Chữ G siêu to khổng lồ", + "Bridgit": "Vực gió hú", + "Courtyard": "Khu đất trống", + "Crag Castle": "Lâu đài cua", + "Doom Shroom": "Cây nấm chết chóc", + "Football Stadium": "Sân thi đấu bóng bầu dục", + "Happy Thoughts": "Mảnh đất vui vẻ", + "Hockey Stadium": "Sân thi đấu khúc khôn cầu", + "Lake Frigid": "Hồ thiên nga", + "Monkey Face": "Mặt khỉ", + "Rampage": "Điên cuồng", + "Roundabout": "Roundabout", + "Step Right Up": "Step Right Up", + "The Pad": "The Pad", + "Tip Top": "Tip Top", + "Tower D": "Tòa tháp D", + "Zigzag": "Zigzag" + }, + "playlistNames": { + "Just Epic": "Chỉ gồm trò chơi chuyển động chậm", + "Just Sports": "Chỉ gồm thể thao" + }, + "scoreNames": { + "Flags": "Số cờ", + "Goals": "Bàn thắng", + "Score": "Điểm số", + "Survived": "Đã sống sót", + "Time": "Thời gian", + "Time Held": "Thời gian tổ chức" + }, + "serverResponses": { + "A code has already been used on this account.": "Một mã code đã được sử dụng trên tài khoản này.", + "A reward has already been given for that address.": "Phần thưởng đã được gửi cho địa chỉ đó.", + "Account linking successful!": "Liên kết tài khoản hoàn tất!", + "Account unlinking successful!": "Hủy liên kết tài khoản hoàn tất!", + "Accounts are already linked.": "Tài khoản đã liên kết.", + "Ad view could not be verified.\nPlease be sure you are running an official and up-to-date version of the game.": "Không thể xác minh chế độ xem quảng cáo.\nHãy chắc chắn rằng bạn đang chạy phiên bản chính thức và cập nhật của trò chơi.", + "An error has occurred; (${ERROR})": "Lỗi xảy ra; (${ERROR})", + "An error has occurred; please contact support. (${ERROR})": "Một lỗi đã xảy ra; vui lòng liên hệ bộ phận hỗ trợ. (${ERROR})", + "An error has occurred; please contact support@froemling.net.": "Lỗi xảy ra; vui lòng báo cáo tại support@froemling.net.", + "An error has occurred; please try again later.": "Lỗi xảy ra,vui lòng thử lại sau.", + "Are you sure you want to link these accounts?\n\n${ACCOUNT1}\n${ACCOUNT2}\n\nThis cannot be undone!": "Bạn có muốn liên kết những tài khoản\nnày?\n\n${ACCOUNT1} \n\n${ACCOUNT2}", + "BombSquad Pro unlocked!": "Đã mở khóa Bombsquad Pro", + "Can't link 2 accounts of this type.": "Không thể liên kết 2 tài khoản loại này.", + "Can't link 2 diamond league accounts.": "Không thể liên kết 2 tài khoản ở giải đấu kim cương.", + "Can't link; would surpass maximum of ${COUNT} linked accounts.": "Không thể liên kết; đã vượt qua tối đa ${COUNT} liên kết tài khoản.", + "Cheating detected; scores and prizes suspended for ${COUNT} days.": "Phát hiện gian lận; không được ghi điểm số và nhận giải thưởng trong ${COUNT} ngày.", + "Could not establish a secure connection.": "Không thể thiết lập kết nối an toàn.", + "Daily maximum reached.": "Đã đạt tối đa số lượng hàng ngày.", + "Entering tournament...": "Gia nhập giải đấu...", + "Invalid code.": "Mã code không hợp lệ.", + "Invalid payment; purchase canceled.": "Thành toán không hợp lệ, mua thất bại.", + "Invalid promo code.": "Mã code thưởng không hợp lệ.", + "Invalid purchase.": "Mua sắm không hợp lệ.", + "Invalid tournament entry; score will be ignored.": "Lối vào giải đấu không hợp lệ; điểm số ghi được không công nhận.", + "Item unlocked!": "Vật phẩm đã mở khóa!", + "LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "LIÊN KẾT TỪ CHỐI. ${ACCOUNT} chứa\ndữ liệu quan trọng mà TẤT CẢ ĐƯỢC.\nBạn có thể liên kết theo thứ tự ngược lại nếu bạn muốn\n(và mất dữ liệu của tài khoản NÀY thay thế)", + "Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Liên kết tài khoản ${ACCOUNT} với tài khoản này?\nTất cả dữ liệu tồn tại trên ${ACCOUNT} sẽ bị mất.\nKhông thể hủy. Bạn chắc chứ?", + "Max number of playlists reached.": "Đã đạt tối đa danh sách.", + "Max number of profiles reached.": "Đã đạt tối đa số lượng hồ sơ.", + "Maximum friend code rewards reached.": "Đã đạt tối đa thưởng từ mã code bạn bè.", + "Message is too long.": "Tin nhắn quá dài.", + "No servers are available. Please try again soon.": "Không có server có sẵn. Hãy thử lại sau.", + "Profile \"${NAME}\" upgraded successfully.": "Hồ sơ \"${NAME}\" nâng cấp thành công.", + "Profile could not be upgraded.": "Hồ sơ không thể nâng cấp.", + "Purchase successful!": "Mua thành công!", + "Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "Nhận được ${COUNT} vé nhờ đăng nhập.\nQuay lại ngày mai để nhận ${TOMORROW_COUNT}.", + "Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "Chức năng máy chủ không còn hỗ trợ trong phiên bản này của trò chơi;\nVui lòng nâng cấp lên phiên bản mới hơn.", + "Sorry, there are no uses remaining on this code.": "Xin lỗi,không còn lần sử dụng nào trên mã code này.", + "Sorry, this code has already been used.": "Xin lỗi bạn, mã code này đã đc sử dụng", + "Sorry, this code has expired.": "Xin lỗi, mã code này đã hết hạn.", + "Sorry, this code only works for new accounts.": "Xin lỗi,mã code này chỉ dành cho người chơi mới.", + "Still searching for nearby servers; please try again soon.": "Vẫn đang tìm những server gần nhất; Hãy thử lại sau", + "Temporarily unavailable; please try again later.": "Tạm thời không có; vui lòng thử lại sau.", + "The tournament ended before you finished.": "Giải đấu đã kết thúc trước khi bạn hoàn thành.", + "This account cannot be unlinked for ${NUM} days.": "Tài khoản này không thể ngừng liên kết trong ${NUM} ngày.", + "This code cannot be used on the account that created it.": "Mã code này không thể sử dụng đc ở tài khoản đã tạo ra nó.", + "This is currently unavailable; please try again later.": "Hiền không có sẵn; hãy thử lại sau.", + "This requires version ${VERSION} or newer.": "Yêu cầu phiên bản ${VERSION} hoặc mới hơn.", + "Tournaments disabled due to rooted device.": "Giải đấu đã tắt bởi vì thiết bị đã root.", + "Tournaments require ${VERSION} or newer": "Giải đấu yêu cầu phiên bản ${VERSION} hoặc mới hơn.", + "Unlink ${ACCOUNT} from this account?\nAll data on ${ACCOUNT} will be reset.\n(except for achievements in some cases)": "Ngừng liên kết ${ACCOUNT} từ tài khoản này? \nTất cả dữ liệu trên ${ACCOUNT} sẽ bị cài lại.\n(ngoại trừ thành tựu trong một số trường hợp)", + "WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "Cảnh báo: Khiếu nại về hack đã được đưa ra về tài khoản của bạn.\nTài khoản phát hiện hack sẽ bị cấm chơi vĩnh viễn. Vui lòng chơi trung thực.", + "Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Bạn có muốn lên kết tài khoản thiết bị của bạn với cái này?\n\nTài khoản thiết bị là\n ${ACCOUNT1}\nTài khoản này là ${ACCOUNT2}", + "You already own this!": "Bạn đã có cái này!", + "You can join in ${COUNT} seconds.": "Bạn có thể tham gia trong ${COUNT} giây.", + "You don't have enough tickets for this!": "Bạn không đủ vé để mua!", + "You don't own that.": "Bạn không có cái đó.", + "You got ${COUNT} tickets!": "Bạn đã nhận được ${COUNT} vé!", + "You got a ${ITEM}!": "Bạn đã nhận được một ${ITEM}!", + "You have been promoted to a new league; congratulations!": "Bạn đã được thăng hạng lên một giải đấu mới; xin chúc mừng!", + "You must update to a newer version of the app to do this.": "Bạn phải nâng cấp lên phiên bản mới hơn của ứng dụng để làm điều này.", + "You must update to the newest version of the game to do this.": "Bạn phải nâng cấp trò chơi lên phiên bản mới nhất để làm điều này.", + "You must wait a few seconds before entering a new code.": "Bạn phải chờ một vài giây trước khi nhập một mã mới.", + "You ranked #${RANK} in the last tournament. Thanks for playing!": "Bạn đứng thứ #${RANK} trong giải đấu vừa rồi. Cảm ơn vì đã tham gia!", + "Your account was rejected. Are you signed in?": "Tài khoản của bạn đã bị từ chối. Bạn đã đăng nhập chưa?", + "Your copy of the game has been modified.\nPlease revert any changes and try again.": "Bản sao của trò chơi đã bị sửa đổi.\nVui lòng sửa lại bất kỳ thay đổi lại như cũ và thử lại.", + "Your friend code was used by ${ACCOUNT}": "Mã của bạn bè của bạn đã được dùng bởi ${ACCOUNT}" + }, + "settingNames": { + "1 Minute": "1 Phút", + "1 Second": "1 giây", + "10 Minutes": "10 phút", + "2 Minutes": "2 phút", + "2 Seconds": "2 giây", + "20 Minutes": "20 phút", + "4 Seconds": "4 giây", + "5 Minutes": "5 phút", + "8 Seconds": "8 giây", + "Allow Negative Scores": "Cho phép điểm số gián tiếp", + "Balance Total Lives": "Cân bằng tổng mạng", + "Bomb Spawning": "Xuất hiện bom", + "Chosen One Gets Gloves": "Người được chọn nhận găng tay", + "Chosen One Gets Shield": "Người được chọn nhận khiên", + "Chosen One Time": "Thời gian người được chọn", + "Enable Impact Bombs": "Kích hoạt bom tác động", + "Enable Triple Bombs": "Bật ba bom", + "Entire Team Must Finish": "Toàn đội phải hoàn thành", + "Epic Mode": "Chế độ sử thi", + "Flag Idle Return Time": "Thời gian chờ cờ quay trở lại", + "Flag Touch Return Time": "Thời gian cờ quay trở lại", + "Hold Time": "Thời gian giữ", + "Kills to Win Per Player": "Số mạng để thắng trên mỗi người chơi", + "Laps": "Vòng", + "Lives Per Player": "Mạng mỗi người chơi", + "Long": "Dài", + "Longer": "Dài hơn", + "Mine Spawning": "Xuất hiện mìn", + "No Mines": "Không mìn", + "None": "Không có", + "Normal": "Bình thường", + "Pro Mode": "Chế độ chuyên nghiệp", + "Respawn Times": "Thời gian hồi sinh", + "Score to Win": "Ghi điểm để Chiến thắng", + "Short": "Ngắn", + "Shorter": "Ngắn hơn", + "Solo Mode": "Chế độ đánh đơn", + "Target Count": "Số lượng mục tiêu", + "Time Limit": "Giới hạn thời gian" + }, + "statements": { + "${TEAM} is disqualified because ${PLAYER} left": "${TEAM} đã bị loại bởi vì ${PLAYER} rời đi", + "Killing ${NAME} for skipping part of the track!": "Giết ${NAME} để bỏ qua một phần đường đua!", + "Warning to ${NAME}: turbo / button-spamming knocks you out.": "Cảnh báo đến ${NAME}: spam / nút spam khiến bạn bị loại." + }, + "teamNames": { + "Bad Guys": "Kẻ xấu", + "Blue": "Xanh", + "Good Guys": "Người tốt", + "Red": "Đỏ" + }, + "tips": { + "A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Một cú đấm chạy-nhảy-xoay có thể một phát chết luôn\nvà cho bạn sự ngưỡng mộ từ bạn bè.", + "Always remember to floss.": "Luôn luôn nhớ Vinahouse.", + "Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Tạo hồ sơ người chơi cho bản thân và bạn bè \nvới tên và hình dáng yêu thích thay vì dùng ngẫu nhiên", + "Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Hộp nguyền rủa biến bạn trở thành quả bom hẹn giờ.\nThuốc duy nhất là bạn phải ăn hộp máu.", + "Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Ngoại hình khác nhau nhưng khả năng là như nhau,\nvì vậy hãy chọn nhân vật giống với tính cách của bạn nhất.", + "Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Đừng quá tự tin với chiếc lá chắn của mình; bạn vẫn có thể bị ném xuống vực đó.", + "Don't run all the time. Really. You will fall off cliffs.": "Đừng chạy nhiều quá. Thề . bạn sẽ bị ngã.", + "Don't spin for too long; you'll become dizzy and fall.": "Đừng xoay quá nhiều, bạn sẽ choáng váng và té.", + "Hold any button to run. (Trigger buttons work well if you have them)": "Giữ bất kì nút nào để chạy. (Cần xoay cũng hoạt động nếu bạn có)", + "Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "Giữ bất kì nút nào để chạy . bạn sẽ đến được chỗ bạn muốn rất nhanh , \nnhưng khó điều khiển , cẩn thận với vực nhé", + "Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "Bom băng yếu,nhưng nó đóng băng \nbất kỳ ai trong tầm nổ, làm chúng có khả năng bị vỡ thành mảnh vụn.", + "If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "Nếu ai đó nhặt bạn lên, đấm họ và họ sẽ thả ra.\nHoạt động trong cả đời thật.", + "If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "Nếu bạn không đủ cần điều khiển, tải '${REMOTE_APP_NAME}' \nứng dụng trên thiết bị di động của bạn để sử dụng như cần điều khiển.", + "If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "Nếu bạn dính bom dính, \nnhảy vòng quanh và xoay tròn. Bạn có thể hất bay bom, nếu không thì khoảng khắc cuối cùng của bạn sẽ rất thú vị.", + "If you kill an enemy in one hit you get double points for it.": "Nếu bạn giết một phát chết luôn một kẻ địch bạn nhận gấp đôi điểm.", + "If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "Nếu bạn nhặt một lời nguyền, hi vọng để sinh tồn là\ntìm một túi hồi máu trong một vài giây tiếp theo.", + "If you stay in one place, you're toast. Run and dodge to survive..": "Nếu bạn ở một chỗ,bạn gà.Chạy và né để sinh tồn.", + "If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Nếu bạn thấy rất nhiều người chơi ra vào\n liên tục, bật 'tự-động-đuổi-người-chơi-không-hoạt-động' trong cài đặt trong trường hợp có người quên rời khỏi trò chơi.", + "If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Nếu thiết bị của bạn quá nóng hoặc muốn tiết kiệm pin, giảm \"Trực quan\" hoặc \"Độ phân giải\" trong\nCài đặt->Đồ họa", + "If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Nếu tỷ lệ khung hình của bạn hay thay đổi, thử giảm độ phân giải \nhoặc trực quan trong cài đặt đồ họa trò chơi.", + "In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Trong cướp cờ, cờ của bạn phải ở căn cứ để ghi điểm, Nếu đội khác chuẩn bị ghi điểm,\ncướp cờ của họ là một cách tốt để chặn lại.", + "In hockey, you'll maintain more speed if you turn gradually.": "Trong khúc côn cầu,bạn sẽ duy trì tốc độ nếu bạn quay dần.", + "It's easier to win with a friend or two helping.": "Dễ thắng hơn khi có một người bạn hoặc hai người giúp.", + "Jump just as you're throwing to get bombs up to the highest levels.": "Nhảy giống như bạn đang ném để đưa bom lên đến cấp cao nhất.", + "Land-mines are a good way to stop speedy enemies.": "Mìn là một cách để dừng kẻ địch đang chạy.", + "Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Rất nhiều thứ có thể cầm lên và ném, \nbao gồm người chơi khác. Ném kẻ địch bay khỏi khu vực chơi là một cách hiệu lực và cảm xúc nhất.", + "No, you can't get up on the ledge. You have to throw bombs.": "Không, bạn không thể lên trên đó. Bạn cần phải ném bom.", + "Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "Người chơi có thể tham gia và rời đi giữa trận trong đa số trò chơi,\nvà bạn cũng có thể cắm và rút cần điều khiển một cách nhanh chóng.", + "Practice using your momentum to throw bombs more accurately.": "Luyện tập sử dụng quán tính của bạn để ném bom chuẩn xác hơn.", + "Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Đấm gây sát thương phụ thuộc vào tốc độ nấm đấm,\nvì vậy thử chạy, nhảy, và xoay như một thằng điên.", + "Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Chạy tới chạy lui trước khi ném bom\nđể 'whiplash' nó và ném nó xa hơn.", + "Take out a group of enemies by\nsetting off a bomb near a TNT box.": "Hất bay một nhóm kẻ địch bằng cách \ncài một quả bom gần thùng Thuốc-Nổ-Tung.", + "The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "Đầu là vùng dễ bị tổn thương nhất, vì vậy một quả bom dính \nvào đầu thường có nghĩa tèo.", + "This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "Màn này không bao giờ hết, \nnhưng điểm số cao ở đây sẽ giúp bạn nhận được sự tôn trọng khắp thế giới.", + "Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "Lực ném phụ thuộc vào hướng bạn đang giữ.\nĐể ném thứ gì ngay trước mặt bạn, đừng giữ bất kỳ hướng nào.", + "Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "Chán nhạc nền? Thay nó với cái của riêng bạn!\nXem Cài đặt->Âm thanh->Nhạc nền", + "Try 'Cooking off' bombs for a second or two before throwing them.": "Thử 'Ngâm' bom một hoặc hai giây trước khi ném chúng.", + "Try tricking enemies into killing eachother or running off cliffs.": "Thử lừa kẻ địch tiêu diệt lẫn nhau hoặc chạy khỏi khu vực chơi.", + "Use the pick-up button to grab the flag < ${PICKUP} >": "Sử dụng nút nhặt để lấy cờ < ${PICKUP} >", + "Whip back and forth to get more distance on your throws..": "Đi tới lui để có thêm khoảng cách trên những cú ném của bạn ..", + "You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Bạn có thể 'nhắm' cú đấm của bạn bằng cách xoay trái hoặc phải.\nĐiều này rất có ích cho hất kẻ xấu bay khỏi cạnh hoặc ghi bàn trong khúc côn cầu.", + "You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Bạn có thể quan sát khi nào quả bom sắp phát nổ nhờ màu sắc của tia lửa từ ngòi nổ của nó:\nVàng..cam..đỏ..Bùm.", + "You can throw bombs higher if you jump just before throwing.": "Bạn có thể ném bom bay cao hơn nếu bạn nhảy chỉ trước khi ném.", + "You take damage when you whack your head on things,\nso try to not whack your head on things.": "Bạn nhận sát thương khi bạn đập đầu vào vật thể,\nvì vậy cố gắng đừng đập đầu vào vật thể.", + "Your punches do much more damage if you are running or spinning.": "Đấm của bạn sẽ nhiều sát thương hơn nếu bạn chạy hoặc xoay" + } + }, + "trophiesRequiredText": "Yêu cầu ít nhất ${NUMBER} cúp.", + "trophiesText": "Cúp", + "trophiesThisSeasonText": "Cúp mùa hiện tại", + "tutorial": { + "cpuBenchmarkText": "Chạy hướng dẫn ở tốc độ lố bịch (chủ yếu kiểm tra tốc độ CPU)", + "phrase01Text": "Chào bạn!", + "phrase02Text": "Chào mừng đến ${APP_NAME}!", + "phrase03Text": "Đây là một vài cách về điều khiển nhân vật của bạn:", + "phrase04Text": "Nhiều thứ trên ${APP_NAME} dựa trên VẬT LÝ HỌC.", + "phrase05Text": "Ví dụ, khi bạn đấm,..", + "phrase06Text": "..sát thương dựa trên tốc độ của bạn.", + "phrase07Text": "Thấy chưa? Chúng ta không di chuyển, nên không làm bị thương ${NAME}.", + "phrase08Text": "Nào, hãy nhảy lên và chạy để có thêm tốc độ.", + "phrase09Text": "À, được hơn rồi đó.", + "phrase10Text": "Chạy cũng rất tốt.", + "phrase11Text": "Giữ bất cứ nút action nào và di chuyển để chạy.", + "phrase12Text": "Để có cú đấm Tuyệt vời và đặc biệt, thử vừa nhảy VÀ vừa chạy.", + "phrase13Text": "Ôi; xin lỗi về chuyện đó ${NAME}.", + "phrase14Text": "Bạn có thể nhặt lên và ném những thứ như cờ.. hoặc ${NAME}.", + "phrase15Text": "Cuối cùng, những trái Bom.", + "phrase16Text": "Luyện tập tạo nên thành công.", + "phrase17Text": "Ối!!! Đó không phải là một cú ném tốt.", + "phrase18Text": "Vừa di chuyển vừa ném giúp bạn ném xa hơn.", + "phrase19Text": "Vừa nhảy vừa ném giúp bạn ném cao hơn.", + "phrase20Text": "\"Whiplast\" còn giúp bạn ném xa hơn nữa.", + "phrase21Text": "Định thời gian ném có hơi khó khăn", + "phrase22Text": "Trượt.", + "phrase23Text": "Thử \"định giờ\" trái bom một hoặc hai giây", + "phrase24Text": "Tuyệt! Quá chính xác.", + "phrase25Text": "Và, chỉ có thế thôi.", + "phrase26Text": "Bây giờ thì tống cổ chúng nào !", + "phrase27Text": "Hãy nhớ buổi luyện tập, và bạn SẼ sống sót trở về!", + "phrase28Text": "...ummm, có thể...", + "phrase29Text": "Chúc may mắn", + "randomName1Text": "Fred", + "randomName2Text": "Harry", + "randomName3Text": "Bill", + "randomName4Text": "Chuck", + "randomName5Text": "Phil", + "skipConfirmText": "Bạn muốn skip cái tutorial? Bấm hoặc ấn để skip.", + "skipVoteCountText": "${COUNT}/${TOTAL} người muốn bỏ qua.", + "skippingText": "Đang bỏ qua...", + "toSkipPressAnythingText": "(chạm hoặc nhấn bất kì đâu để bỏ qua hướng dẩn)" + }, + "twoKillText": "Hai Mạng!", + "unavailableText": "Không Khả Dụng", + "unconfiguredControllerDetectedText": "Tay cầm không cấu hình được phát hiện:", + "unlockThisInTheStoreText": "Nó phải được mở khóa trong cửa hàng.", + "unlockThisProfilesText": "Để tạo nhiều hơn ${NUM} hồ sơ,bạn cần:", + "unlockThisText": "Để mở khóa bạn cần", + "unsupportedHardwareText": "Xin lỗi, phần cứng này không được hỗ trợ bởi bản dựng này của trò chơi.", + "upFirstText": "Game đầu:", + "upNextText": "Trò chơi tiếp theo ${COUNT}:", + "updatingAccountText": "Đang nâng cấp tài khoản của bạn...", + "upgradeText": "Nâng cấp", + "upgradeToPlayText": "Mở khóa \"${PRO}\" trong cửa hàng để chơi.", + "useDefaultText": "Sử dụng mặc định", + "usesExternalControllerText": "Trò chơi này sử dụng tay cầm bên ngoài cho đầu vào.", + "usingItunesText": "Sử dụng Ứng dụng âm nhạc cho nhạc nền", + "validatingTestBuildText": "Kiểm tra xác thực Xây dựng ...", + "victoryText": "Chiến thắng!", + "voteDelayText": "Bạn không thể bắt đầu cuộc bầu chọn khác trong ${NUMBER} giây", + "voteInProgressText": "Một cuộc bầu chọn đang tiến hành.", + "votedAlreadyText": "Bạn đã bầu chọn", + "votesNeededText": "${NUMBER} phiếu cần", + "vsText": "vs.", + "waitingForHostText": "(Đang chờ ${HOST} để tiếp tục)", + "waitingForPlayersText": "Đang chờ người chơi để tham gia...", + "waitingInLineText": "Chờ xếp hàng (tiệc đã đầy) ...", + "watchAVideoText": "Xem Video", + "watchAnAdText": "Xem Quảng cáo", + "watchWindow": { + "deleteConfirmText": "Xóa \"${REPLAY}\"?", + "deleteReplayButtonText": "Xóa\nPhát lại", + "myReplaysText": "Phát lại của tôi", + "noReplaySelectedErrorText": "Không phát lại được chọn", + "playbackSpeedText": "Tốc độ phát lại: ${SPEED}", + "renameReplayButtonText": "Đặt tên\nPhát lại", + "renameReplayText": "Đặt lại tên \"${REPLAY}\" thành:", + "renameText": "Đặt tên", + "replayDeleteErrorText": "Lỗi xóa phát lại.", + "replayNameText": "Đặt tên phát lại", + "replayRenameErrorAlreadyExistsText": "Một phát lại với cái tên đó đã tồn tại.", + "replayRenameErrorInvalidName": "Không thể đổi tên phát lại; tên không hợp lệ.", + "replayRenameErrorText": "Lỗi đổi tên phát lại.", + "sharedReplaysText": "Chia sẻ Phát lại", + "titleText": "Xem", + "watchReplayButtonText": "Xem \nLại" + }, + "waveText": "Vòng", + "wellSureText": "Chắc chắn rồi!", + "wiimoteLicenseWindow": { + "titleText": "DarwiinRemote Bản quyền" + }, + "wiimoteListenWindow": { + "listeningText": "Lắng nghe Wiimote ...", + "pressText": "Press Wiimote buttons 1 and 2 simultaneously.", + "pressText2": "Trên các Wiimote mới hơn có tích hợp Motion Plus, thay vào đó hãy nhấn nút 'đồng bộ hóa' màu đỏ ở mặt sau." + }, + "wiimoteSetupWindow": { + "copyrightText": "Bản quyền của DarwiinRemote", + "listenText": "Lắng nghe", + "macInstructionsText": "Hãy chắc chắn rằng Wii của bạn là tắt và Bluetooth được kích hoạt\ntrên máy Mac của bạn, sau đó nhấn 'Nghe'. Wiimote hỗ trợ có thể\nmột chút flaky, do đó, bạn có thể phải thử một vài lần\ntrước khi bạn nhận được một kết nối.\n\nBluetooth nên xử lý lên đến 7 thiết bị kết nối,\nmặc dù mileage của bạn có thể khác nhau.\n\nBombSquad hỗ trợ Wiimotes gốc, Nunchuk,\nvà bộ điều khiển cổ điển.\nCác mới Wii Remote Plus bây giờ hoạt động quá\nnhưng không phải với tập tin đính kèm", + "thanksText": "Cảm ơn nhóm DarwiinRemote\nĐã làm thứ này có thật.", + "titleText": "Thiết lập Wiimote" + }, + "winsPlayerText": "${NAME} Chiến thắng!", + "winsTeamText": "${NAME} Chiến thắng!", + "winsText": "${NAME} Chiến thắng!", + "workspaceSyncErrorText": "Lỗi đồng bộ hóa ${WORKSPACE}. Xem nhật ký để biết chi tiết.", + "workspaceSyncReuseText": "Không thể đồng bộ hóa ${WORKSPACE}. Sử dụng lại phiên bản đã đồng bộ hóa trước đó.", + "worldScoresUnavailableText": "Điểm trên thế giới không có sẵn.", + "worldsBestScoresText": "Điểm số thế giới cao nhất", + "worldsBestTimesText": "Thời gian tốt nhất thế giới", + "xbox360ControllersWindow": { + "getDriverText": "Lấy Driver", + "macInstructions2Text": "Để sử dụng bộ điều khiển không dây, bạn cũng sẽ cần người nhận đó\nđi kèm với các 'Xbox 360 Wireless Controller for Windows'.\nMột người nhận cho phép bạn kết nối bộ điều khiển lên đến 4.\n\nQuan trọng: bộ thu bên thứ 3 sẽ không làm việc với các trình điều khiển này;\nđảm bảo rằng bạn nhận nói 'Microsoft' vào nó, không phải 'Xbox360'.\nMicrosoft không còn bán chúng một cách riêng biệt, do đó bạn sẽ cần để có được\nmột trong những đi kèm với ebay điều khiển hoặc người nào khác tìm.\n\nNếu bạn thấy điều này hữu ích, hãy xem xét một tài trợ cho các\ntrình điều khiển các phát triển tại trang web của mình.", + "macInstructionsText": "Để sử dụng bộ điều khiển Xbox 360, bạn cần phải cài đặt\nTrình điều khiển Mac có sẵn tại liên kết bên dưới.\nNó hoạt động với cả bộ điều khiển có dây và không dây.", + "ouyaInstructionsText": "Sử dụng bộ điều khiển Xbox 360 có dây với BombSquad, chỉ đơn giản là\ncắm vào cổng USB của điện thoại. Bạn có thể sử dụng một USB hub\nđể kết nối nhiều bộ điều khiển.\n\nSử dụng bộ điều khiển không dây, bạn sẽ cần thu không dây\ncó sẵn như là một phần của \"Xbox 360 wireless Controller cho Windows\"\nđóng gói hoặc được bán rời. Mỗi người nhận cắm vào cổng USB và\ncho phép bạn kết nối bộ điều khiển không dây lên đến 4.", + "titleText": "Sử dụng Điều Khiển Xbox 360 với ${APP_NAME}:" + }, + "yesAllowText": "Có, chấp nhận !", + "yourBestScoresText": "Điểm kỉ lục của bạn", + "yourBestTimesText": "Thời gian kỉ lục của bạn" +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/big_g.json b/dist/ba_data/data/maps/big_g.json new file mode 100644 index 0000000..a7de281 --- /dev/null +++ b/dist/ba_data/data/maps/big_g.json @@ -0,0 +1,85 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [-0.4, 2.33, -0.54], "size": [19.12, 10.2, 23.5]} + ], + "ffa_spawn": [ + {"center": [3.14, 1.17, 6.17], "size": [4.74, 1.0, 1.03]}, + {"center": [5.42, 1.18, -0.17], "size": [2.95, 0.62, 0.5]}, + {"center": [-0.37, 2.89, -6.91], "size": [7.58, 0.62, 0.5]}, + {"center": [-2.39, 1.12, -3.42], "size": [2.93, 0.62, 0.98]}, + {"center": [-7.46, 2.86, 4.94], "size": [0.87, 0.62, 2.23]} + ], + "flag": [ + {"center": [7.56, 2.89, -7.21]}, + {"center": [7.7, 1.1, 6.1]}, + {"center": [-8.12, 2.84, 6.1]}, + {"center": [-8.02, 2.84, -6.2]} + ], + "flag_default": [ + {"center": [-7.56, 2.85, 0.09]} + ], + "map_bounds": [ + {"center": [-0.19, 8.76, 0.2], "size": [27.42, 18.47, 22.17]} + ], + "powerup_spawn": [ + {"center": [7.83, 2.12, -0.05]}, + {"center": [-5.19, 1.48, -3.8]}, + {"center": [-8.54, 3.76, -7.28]}, + {"center": [7.37, 3.76, -3.09]}, + {"center": [-8.69, 3.69, 6.63]} + ], + "race_mine": [ + {"center": [-0.06, 1.12, 4.97]}, + {"center": [-0.06, 1.12, 7.0]}, + {"center": [-0.73, 1.12, -2.83]}, + {"center": [-3.29, 1.12, 0.85]}, + {"center": [5.08, 2.85, -5.25]}, + {"center": [6.29, 2.85, -5.25]}, + {"center": [0.97, 2.85, -7.89]}, + {"center": [-2.98, 2.85, -6.24]}, + {"center": [-6.96, 2.85, -2.12]}, + {"center": [-6.87, 2.85, 2.72]} + ], + "race_point": [ + {"center": [2.28, 1.17, 6.02], "size": [0.71, 4.67, 1.32]}, + {"center": [4.85, 1.17, 6.04], "size": [0.39, 4.58, 1.35]}, + {"center": [6.91, 1.17, 1.14], "size": [1.61, 3.52, 0.11]}, + {"center": [2.68, 1.17, 0.77], "size": [0.65, 3.6, 0.11]}, + {"center": [-0.38, 1.23, 1.92], "size": [0.11, 4.25, 0.59]}, + {"center": [-4.37, 1.17, -0.36], "size": [1.63, 4.55, 0.11]}, + {"center": [0.41, 1.17, -3.39], "size": [0.11, 4.95, 1.31]}, + {"center": [4.27, 2.2, -3.34], "size": [0.11, 4.39, 1.2]}, + {"center": [2.55, 2.88, -7.12], "size": [0.11, 5.51, 1.0]}, + {"center": [-4.2, 2.88, -7.11], "size": [0.11, 5.5, 1.03]}, + {"center": [-7.63, 2.88, -3.62], "size": [1.44, 5.16, 0.06]}, + {"center": [-7.54, 2.88, 3.29], "size": [1.67, 5.52, 0.06]} + ], + "shadow_lower_bottom": [ + {"center": [-0.22, 0.29, 2.68]} + ], + "shadow_lower_top": [ + {"center": [-0.22, 0.88, 2.68]} + ], + "shadow_upper_bottom": [ + {"center": [-0.22, 6.31, 2.68]} + ], + "shadow_upper_top": [ + {"center": [-0.22, 9.47, 2.68]} + ], + "spawn": [ + {"center": [7.18, 2.86, -4.41], "size": [0.76, 1.0, 1.82]}, + {"center": [5.88, 1.14, 6.17], "size": [1.82, 1.0, 0.77]} + ], + "spawn_by_flag": [ + {"center": [7.18, 2.86, -4.41], "size": [0.76, 1.0, 1.82]}, + {"center": [5.88, 1.14, 6.17], "size": [1.82, 1.0, 0.77]}, + {"center": [-6.67, 3.55, 5.82], "size": [1.1, 1.0, 1.29]}, + {"center": [-6.84, 3.55, -6.17], "size": [0.82, 1.0, 1.29]} + ], + "tnt": [ + {"center": [-3.4, 2.07, -1.9]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/bridgit.json b/dist/ba_data/data/maps/bridgit.json new file mode 100644 index 0000000..9a30122 --- /dev/null +++ b/dist/ba_data/data/maps/bridgit.json @@ -0,0 +1,95 @@ +{ + "format": ["stdmap", 1], + "globals": { + "ambient_color": [1.1, 1.2, 1.3], + "tint": [1.1, 1.2, 1.3], + "vignette_inner": [0.9, 0.9, 0.93], + "vignette_outer": [0.65, 0.6, 0.55] + }, + "locations": { + "area_of_interest_bounds": [ + {"center": [-0.25, 3.83, -1.53], "size": [19.15, 7.31, 8.44]} + ], + "ffa_spawn": [ + {"center": [-5.87, 3.72, -1.62], "size": [0.94, 1.0, 1.82]}, + {"center": [5.16, 3.76, -1.44], "size": [0.77, 1.0, 1.82]}, + {"center": [-0.43, 3.76, -1.56], "size": [4.03, 1.0, 0.27]} + ], + "flag": [ + {"center": [-7.35, 3.77, -1.62]}, + {"center": [6.89, 3.77, -1.44]} + ], + "flag_default": [ + {"center": [-0.22, 3.8, -1.56]} + ], + "map_bounds": [ + {"center": [-0.19, 7.48, -1.31], "size": [27.42, 18.47, 19.52]} + ], + "powerup_spawn": [ + {"center": [6.83, 4.66, 0.19]}, + {"center": [-7.25, 4.73, 0.25]}, + {"center": [6.83, 4.66, -3.46]}, + {"center": [-7.25, 4.73, -3.4]} + ], + "shadow_lower_bottom": [ + {"center": [-0.22, 2.83, 2.68]} + ], + "shadow_lower_top": [ + {"center": [-0.22, 3.5, 2.68]} + ], + "shadow_upper_bottom": [ + {"center": [-0.22, 6.31, 2.68]} + ], + "shadow_upper_top": [ + {"center": [-0.22, 9.47, 2.68]} + ], + "spawn": [ + {"center": [-5.87, 3.72, -1.62], "size": [0.94, 1.0, 1.82]}, + {"center": [5.16, 3.76, -1.44], "size": [0.77, 1.0, 1.82]} + ] + }, + "name": "Bridgit", + "play_types": ["melee", "team_flag", "keep_away"], + "preview_texture": "bridgitPreview", + "terrain_nodes": [ + { + "collide_model": "bridgitLevelBottom", + "color_texture": "bridgitLevelColor", + "comment": "Top portion of bridge.", + "materials": ["footing"], + "model": "bridgitLevelTop" + }, + { + "color_texture": "bridgitLevelColor", + "comment": "Bottom portion of bridge with no lighting effects.", + "lighting": false, + "model": "bridgitLevelBottom" + }, + { + "background": true, + "color_texture": "natureBackgroundColor", + "comment": "Visible background.", + "lighting": false, + "model": "natureBackground" + }, + { + "background": true, + "color_texture": "model_bg_tex", + "comment": "360 degree bg for vr.", + "lighting": false, + "model": "bg_vr_fill_model", + "vr_only": true + }, + { + "bumper": true, + "collide_model": "railing_collide_model", + "comment": "Invisible railing to help prevent falls.", + "materials": ["railing"] + }, + { + "collide_model": "collide_bg", + "comment": "Collision shape for bg", + "materials": ["footing", "friction@10", "death"] + } + ] +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/courtyard.json b/dist/ba_data/data/maps/courtyard.json new file mode 100644 index 0000000..c485c95 --- /dev/null +++ b/dist/ba_data/data/maps/courtyard.json @@ -0,0 +1,130 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.35, 3.96, -2.18], "size": [16.38, 7.76, 13.39]} + ], + "bot_spawn_bottom": [ + {"center": [-0.06, 2.81, 1.95]} + ], + "bot_spawn_bottom_half_left": [ + {"center": [-2.05, 2.81, 1.95]} + ], + "bot_spawn_bottom_half_right": [ + {"center": [1.86, 2.81, 1.95]} + ], + "bot_spawn_bottom_left": [ + {"center": [-3.68, 2.81, 1.95]} + ], + "bot_spawn_bottom_right": [ + {"center": [3.59, 2.81, 1.95]} + ], + "bot_spawn_left": [ + {"center": [-6.45, 2.81, -2.32]} + ], + "bot_spawn_left_lower": [ + {"center": [-6.45, 2.81, -1.51]} + ], + "bot_spawn_left_lower_more": [ + {"center": [-6.45, 2.81, -0.48]} + ], + "bot_spawn_left_upper": [ + {"center": [-6.45, 2.81, -3.18]} + ], + "bot_spawn_left_upper_more": [ + {"center": [-6.45, 2.81, -4.01]} + ], + "bot_spawn_right": [ + {"center": [6.54, 2.81, -2.32]} + ], + "bot_spawn_right_lower": [ + {"center": [6.54, 2.81, -1.4]} + ], + "bot_spawn_right_lower_more": [ + {"center": [6.54, 2.81, -0.36]} + ], + "bot_spawn_right_upper": [ + {"center": [6.54, 2.81, -3.13]} + ], + "bot_spawn_right_upper_more": [ + {"center": [6.54, 2.81, -3.98]} + ], + "bot_spawn_top": [ + {"center": [-0.06, 2.81, -5.83]} + ], + "bot_spawn_top_half_left": [ + {"center": [-1.49, 2.81, -5.83]} + ], + "bot_spawn_top_half_right": [ + {"center": [1.6, 2.81, -5.83]} + ], + "bot_spawn_top_left": [ + {"center": [-3.12, 2.81, -5.95]} + ], + "bot_spawn_top_right": [ + {"center": [3.4, 2.81, -5.95]} + ], + "bot_spawn_turret_bottom_left": [ + {"center": [-6.13, 3.33, 1.91]} + ], + "bot_spawn_turret_bottom_right": [ + {"center": [6.37, 3.33, 1.8]} + ], + "bot_spawn_turret_top_left": [ + {"center": [-6.13, 3.33, -6.57]} + ], + "bot_spawn_turret_top_middle": [ + {"center": [0.08, 4.27, -8.52]} + ], + "bot_spawn_turret_top_middle_left": [ + {"center": [-1.27, 4.27, -8.52]} + ], + "bot_spawn_turret_top_middle_right": [ + {"center": [1.13, 4.27, -8.52]} + ], + "bot_spawn_turret_top_right": [ + {"center": [6.37, 3.33, -6.6]} + ], + "edge_box": [ + {"center": [0.0, 1.04, -2.14], "size": [12.02, 11.41, 7.81]} + ], + "ffa_spawn": [ + {"center": [-6.23, 3.77, -5.16], "size": [1.48, 1.0, 0.07]}, + {"center": [6.29, 3.77, -4.92], "size": [1.42, 1.0, 0.07]}, + {"center": [-0.02, 4.4, -6.96], "size": [1.51, 1.0, 0.25]}, + {"center": [-0.02, 3.79, 3.45], "size": [4.99, 1.0, 0.15]} + ], + "flag": [ + {"center": [-5.97, 2.82, -2.43]}, + {"center": [5.91, 2.8, -2.22]} + ], + "flag_default": [ + {"center": [0.25, 2.78, -2.64]} + ], + "map_bounds": [ + {"center": [0.26, 4.9, -3.54], "size": [29.24, 14.2, 29.93]} + ], + "powerup_spawn": [ + {"center": [-3.56, 3.17, 0.37]}, + {"center": [3.63, 3.17, 0.41]}, + {"center": [3.63, 3.17, -4.99]}, + {"center": [-3.56, 3.17, -5.02]} + ], + "shadow_lower_bottom": [ + {"center": [0.52, 0.02, 5.34]} + ], + "shadow_lower_top": [ + {"center": [0.52, 1.21, 5.34]} + ], + "shadow_upper_bottom": [ + {"center": [0.52, 6.36, 5.34]} + ], + "shadow_upper_top": [ + {"center": [0.52, 10.12, 5.34]} + ], + "spawn": [ + {"center": [-7.51, 3.8, -2.1], "size": [0.09, 1.0, 2.2]}, + {"center": [7.46, 3.77, -1.84], "size": [0.03, 1.0, 2.22]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/crag_castle.json b/dist/ba_data/data/maps/crag_castle.json new file mode 100644 index 0000000..28cd287 --- /dev/null +++ b/dist/ba_data/data/maps/crag_castle.json @@ -0,0 +1,48 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.7, 6.56, -3.15], "size": [16.74, 14.95, 11.6]} + ], + "ffa_spawn": [ + {"center": [-4.04, 7.55, -3.54], "size": [2.47, 1.16, 0.18]}, + {"center": [5.43, 7.58, -3.5], "size": [2.42, 1.13, 0.18]}, + {"center": [4.86, 9.31, -6.01], "size": [1.62, 1.13, 0.18]}, + {"center": [-3.63, 9.31, -6.01], "size": [1.62, 1.13, 0.18]}, + {"center": [-2.41, 5.93, 0.03], "size": [1.62, 1.13, 0.18]}, + {"center": [3.52, 5.93, 0.03], "size": [1.62, 1.13, 0.18]} + ], + "flag": [ + {"center": [-1.9, 9.36, -6.44]}, + {"center": [3.24, 9.32, -6.39]}, + {"center": [-6.88, 7.48, 0.21]}, + {"center": [8.19, 7.48, 0.15]} + ], + "flag_default": [ + {"center": [0.63, 6.22, -0.04]} + ], + "map_bounds": [ + {"center": [0.48, 9.09, -3.27], "size": [22.96, 9.91, 14.18]} + ], + "powerup_spawn": [ + {"center": [7.92, 7.84, -5.99]}, + {"center": [-0.7, 7.88, -6.07]}, + {"center": [1.86, 7.89, -6.08]}, + {"center": [-6.67, 7.99, -6.12]} + ], + "spawn": [ + {"center": [-5.17, 7.55, -3.54], "size": [1.06, 1.16, 0.18]}, + {"center": [6.2, 7.58, -3.5], "size": [1.01, 1.13, 0.18]} + ], + "spawn_by_flag": [ + {"center": [-2.87, 9.36, -6.04]}, + {"center": [4.31, 9.36, -6.04]}, + {"center": [-6.63, 7.51, -0.59]}, + {"center": [7.87, 7.51, -0.59]} + ], + "tnt": [ + {"center": [-5.04, 10.01, -6.16]}, + {"center": [6.2, 10.01, -6.16]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/doom_shroom.json b/dist/ba_data/data/maps/doom_shroom.json new file mode 100644 index 0000000..539de5e --- /dev/null +++ b/dist/ba_data/data/maps/doom_shroom.json @@ -0,0 +1,46 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.47, 2.32, -3.22], "size": [21.35, 10.26, 14.67]} + ], + "ffa_spawn": [ + {"center": [-5.83, 2.3, -3.45], "size": [1.0, 1.0, 2.68]}, + {"center": [6.5, 2.4, -3.57], "size": [1.0, 1.0, 2.68]}, + {"center": [0.88, 2.31, -0.36], "size": [4.46, 1.0, 0.27]}, + {"center": [0.88, 2.31, -7.12], "size": [4.46, 1.0, 0.27]} + ], + "flag": [ + {"center": [-7.15, 2.25, -3.43]}, + {"center": [8.1, 2.32, -3.55]} + ], + "flag_default": [ + {"center": [0.6, 2.37, -4.24]} + ], + "map_bounds": [ + {"center": [0.46, 1.33, -3.81], "size": [27.75, 14.45, 22.99]} + ], + "powerup_spawn": [ + {"center": [5.18, 4.28, -7.28]}, + {"center": [-3.24, 4.16, -0.32]}, + {"center": [5.08, 4.16, -0.32]}, + {"center": [-3.4, 4.28, -7.43]} + ], + "shadow_lower_bottom": [ + {"center": [0.6, -0.23, 3.37]} + ], + "shadow_lower_top": [ + {"center": [0.6, 0.7, 3.37]} + ], + "shadow_upper_bottom": [ + {"center": [0.6, 5.41, 3.37]} + ], + "shadow_upper_top": [ + {"center": [0.6, 7.89, 3.37]} + ], + "spawn": [ + {"center": [-5.83, 2.3, -3.45], "size": [1.0, 1.0, 2.68]}, + {"center": [6.5, 2.4, -3.57], "size": [1.0, 1.0, 2.68]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/football_stadium.json b/dist/ba_data/data/maps/football_stadium.json new file mode 100644 index 0000000..0441bd5 --- /dev/null +++ b/dist/ba_data/data/maps/football_stadium.json @@ -0,0 +1,42 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.0, 1.19, 0.43], "size": [29.82, 11.57, 18.89]} + ], + "edge_box": [ + {"center": [-0.1, 0.41, 0.43], "size": [22.48, 1.29, 8.99]} + ], + "ffa_spawn": [ + {"center": [-0.08, 0.02, -4.37], "size": [8.9, 1.0, 0.44]}, + {"center": [-0.08, 0.02, 4.08], "size": [8.9, 1.0, 0.44]} + ], + "flag": [ + {"center": [-10.99, 0.06, 0.11]}, + {"center": [11.01, 0.04, 0.11]} + ], + "flag_default": [ + {"center": [-0.1, 0.04, 0.11]} + ], + "goal": [ + {"center": [12.22, 1.0, 0.11], "size": [2.0, 2.0, 12.97]}, + {"center": [-12.16, 1.0, 0.11], "size": [2.0, 2.0, 13.12]} + ], + "map_bounds": [ + {"center": [0.0, 1.19, 0.43], "size": [42.1, 22.81, 29.77]} + ], + "powerup_spawn": [ + {"center": [5.41, 0.95, -5.04]}, + {"center": [-5.56, 0.95, -5.04]}, + {"center": [5.41, 0.95, 5.15]}, + {"center": [-5.74, 0.95, 5.15]} + ], + "spawn": [ + {"center": [-10.04, 0.02, 0.0], "size": [0.5, 1.0, 4.0]}, + {"center": [9.82, 0.01, 0.0], "size": [0.5, 1.0, 4.0]} + ], + "tnt": [ + {"center": [-0.08, 0.95, -0.78]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/happy_thoughts.json b/dist/ba_data/data/maps/happy_thoughts.json new file mode 100644 index 0000000..d6c82ba --- /dev/null +++ b/dist/ba_data/data/maps/happy_thoughts.json @@ -0,0 +1,44 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [-1.05, 12.68, -5.4], "size": [34.46, 20.94, 0.69]} + ], + "ffa_spawn": [ + {"center": [-9.3, 8.01, -5.44], "size": [1.56, 1.45, 0.12]}, + {"center": [7.48, 8.17, -5.61], "size": [1.55, 1.45, 0.04]}, + {"center": [9.56, 11.31, -5.61], "size": [1.34, 1.45, 0.04]}, + {"center": [-11.56, 10.99, -5.61], "size": [1.34, 1.45, 0.04]}, + {"center": [-1.88, 9.46, -5.61], "size": [1.34, 1.45, 0.04]}, + {"center": [-0.49, 5.08, -5.52], "size": [1.88, 1.45, 0.01]} + ], + "flag": [ + {"center": [-11.75, 8.06, -5.52]}, + {"center": [9.84, 8.19, -5.52]}, + {"center": [-0.22, 5.01, -5.52]}, + {"center": [-0.05, 12.73, -5.52]} + ], + "flag_default": [ + {"center": [-0.04, 12.72, -5.52]} + ], + "map_bounds": [ + {"center": [-0.87, 9.21, -5.73], "size": [36.1, 26.2, 7.9]} + ], + "powerup_spawn": [ + {"center": [1.16, 6.75, -5.47]}, + {"center": [-1.9, 10.56, -5.51]}, + {"center": [10.56, 12.25, -5.58]}, + {"center": [-12.34, 12.25, -5.58]} + ], + "spawn": [ + {"center": [-9.3, 8.01, -5.44], "size": [1.56, 1.45, 0.12]}, + {"center": [7.48, 8.17, -5.61], "size": [1.55, 1.45, 0.04]} + ], + "spawn_by_flag": [ + {"center": [-9.3, 8.01, -5.44], "size": [1.56, 1.45, 0.12]}, + {"center": [7.48, 8.17, -5.61], "size": [1.55, 1.45, 0.04]}, + {"center": [-1.46, 5.04, -5.54], "size": [0.95, 0.67, 0.09]}, + {"center": [0.49, 12.74, -5.6], "size": [0.52, 0.52, 0.02]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/hockey_stadium.json b/dist/ba_data/data/maps/hockey_stadium.json new file mode 100644 index 0000000..e5c6e51 --- /dev/null +++ b/dist/ba_data/data/maps/hockey_stadium.json @@ -0,0 +1,39 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.0, 0.8, 0.0], "size": [30.8, 0.6, 13.88]} + ], + "ffa_spawn": [ + {"center": [-0.0, 0.02, -3.82], "size": [7.83, 1.0, 0.16]}, + {"center": [-0.0, 0.02, 3.56], "size": [7.83, 1.0, 0.06]} + ], + "flag": [ + {"center": [-11.22, 0.1, -0.08]}, + {"center": [11.08, 0.04, -0.08]} + ], + "flag_default": [ + {"center": [-0.02, 0.06, -0.08]} + ], + "goal": [ + {"center": [8.45, 1.0, 0.0], "size": [0.43, 1.6, 3.0]}, + {"center": [-8.45, 1.0, 0.0], "size": [0.43, 1.6, 3.0]} + ], + "map_bounds": [ + {"center": [0.0, 0.8, -0.47], "size": [35.16, 12.19, 21.53]} + ], + "powerup_spawn": [ + {"center": [-3.65, 1.08, -4.77]}, + {"center": [-3.65, 1.08, 4.6]}, + {"center": [2.88, 1.08, -4.77]}, + {"center": [2.88, 1.08, 4.6]} + ], + "spawn": [ + {"center": [-6.84, 0.02, 0.0], "size": [1.0, 1.0, 3.0]}, + {"center": [6.86, 0.04, 0.0], "size": [1.0, 1.0, 3.0]} + ], + "tnt": [ + {"center": [-0.06, 1.08, -4.77]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/lake_frigid.json b/dist/ba_data/data/maps/lake_frigid.json new file mode 100644 index 0000000..a4cd90f --- /dev/null +++ b/dist/ba_data/data/maps/lake_frigid.json @@ -0,0 +1,84 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.62, 3.96, -2.49], "size": [20.62, 7.76, 12.33]} + ], + "ffa_spawn": [ + {"center": [-5.78, 2.6, -2.12], "size": [0.49, 1.0, 2.99]}, + {"center": [8.33, 2.56, -2.36], "size": [0.49, 1.0, 2.59]}, + {"center": [-0.02, 2.62, -6.52], "size": [4.45, 1.0, 0.25]}, + {"center": [-0.02, 2.62, 2.15], "size": [4.99, 1.0, 0.15]} + ], + "flag": [ + {"center": [-5.97, 2.61, -2.43]}, + {"center": [7.47, 2.6, -2.22]} + ], + "flag_default": [ + {"center": [0.58, 2.59, -6.08]} + ], + "map_bounds": [ + {"center": [0.67, 6.09, -2.48], "size": [26.78, 12.5, 19.09]} + ], + "powerup_spawn": [ + {"center": [-3.18, 3.17, 1.53]}, + {"center": [3.63, 3.17, 1.56]}, + {"center": [3.63, 3.17, -5.77]}, + {"center": [-3.18, 3.17, -5.81]} + ], + "race_mine": [ + {"center": [-5.3, 2.52, 1.96]}, + {"center": [-5.29, 2.52, -5.87]}, + {"center": [6.49, 2.52, 1.53]}, + {"center": [6.78, 2.52, -4.81]}, + {"center": [1.53, 2.52, -7.24]}, + {"center": [-1.55, 2.52, -6.39]}, + {"center": [-4.36, 2.52, -2.05]}, + {"center": [-0.71, 2.52, -0.13]}, + {"center": [-0.71, 2.52, 1.28]}, + {"center": [-0.71, 2.52, 3.11]}, + {"center": [9.39, 2.52, -1.65]}, + {"center": [5.75, 2.52, -2.3]}, + {"center": [6.21, 2.52, -0.81]}, + {"center": [5.38, 2.52, -4.17]}, + {"center": [1.5, 2.52, -5.82]}, + {"center": [-1.69, 2.52, -5.24]}, + {"center": [-3.87, 2.52, -4.15]}, + {"center": [-7.41, 2.52, -1.5]}, + {"center": [-2.19, 2.52, 1.86]}, + {"center": [8.03, 2.52, -0.01]}, + {"center": [7.38, 2.52, -5.78]}, + {"center": [-4.57, 2.52, -5.03]}, + {"center": [-5.87, 2.52, -0.28]}, + {"center": [2.79, 2.52, -7.9]}, + {"center": [5.82, 2.52, -6.59]}, + {"center": [-3.97, 2.52, -0.04]} + ], + "race_point": [ + {"center": [0.59, 2.54, 1.54], "size": [0.28, 3.95, 2.29]}, + {"center": [4.75, 2.49, 1.1], "size": [0.28, 3.95, 2.39]}, + {"center": [7.45, 2.6, -2.25], "size": [2.17, 3.95, 0.26]}, + {"center": [5.06, 2.49, -5.82], "size": [0.28, 3.95, 2.39]}, + {"center": [0.59, 2.68, -6.17], "size": [0.28, 3.95, 2.16]}, + {"center": [-3.06, 2.49, -6.11], "size": [0.28, 3.95, 2.32]}, + {"center": [-5.81, 2.58, -2.25], "size": [2.04, 3.95, 0.26]}, + {"center": [-2.96, 2.49, 1.36], "size": [0.28, 3.95, 2.53]} + ], + "shadow_lower_bottom": [ + {"center": [0.52, 1.52, 5.34]} + ], + "shadow_lower_top": [ + {"center": [0.52, 2.52, 5.34]} + ], + "shadow_upper_bottom": [ + {"center": [0.52, 4.54, 5.34]} + ], + "shadow_upper_top": [ + {"center": [0.52, 5.92, 5.34]} + ], + "spawn": [ + {"center": [-5.95, 2.52, -2.1], "size": [0.09, 1.0, 2.2]}, + {"center": [8.08, 2.51, -2.36], "size": [0.03, 1.0, 2.22]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/monkey_face.json b/dist/ba_data/data/maps/monkey_face.json new file mode 100644 index 0000000..b2daf11 --- /dev/null +++ b/dist/ba_data/data/maps/monkey_face.json @@ -0,0 +1,46 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [-1.66, 4.13, -1.58], "size": [17.36, 10.49, 12.31]} + ], + "ffa_spawn": [ + {"center": [-8.03, 3.35, -2.54], "size": [0.95, 0.95, 1.18]}, + {"center": [4.73, 3.31, -2.76], "size": [0.93, 1.0, 1.22]}, + {"center": [-1.91, 3.33, -6.57], "size": [4.08, 1.0, 0.29]}, + {"center": [-1.67, 3.33, 2.41], "size": [3.87, 1.0, 0.29]} + ], + "flag": [ + {"center": [-8.97, 3.36, -2.8]}, + {"center": [5.95, 3.35, -2.66]} + ], + "flag_default": [ + {"center": [-1.69, 3.39, -2.24]} + ], + "map_bounds": [ + {"center": [-1.62, 6.83, -2.2], "size": [22.52, 12.21, 15.91]} + ], + "powerup_spawn": [ + {"center": [-6.86, 4.43, -6.59]}, + {"center": [-5.42, 4.23, 2.8]}, + {"center": [3.15, 4.43, -6.59]}, + {"center": [1.83, 4.23, 2.8]} + ], + "shadow_lower_bottom": [ + {"center": [-1.88, 0.99, 5.5]} + ], + "shadow_lower_top": [ + {"center": [-1.88, 2.88, 5.5]} + ], + "shadow_upper_bottom": [ + {"center": [-1.88, 6.17, 5.5]} + ], + "shadow_upper_top": [ + {"center": [-1.88, 10.25, 5.5]} + ], + "spawn": [ + {"center": [-8.03, 3.35, -2.54], "size": [0.95, 0.95, 1.18]}, + {"center": [4.73, 3.31, -2.76], "size": [0.93, 1.0, 1.22]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/rampage.json b/dist/ba_data/data/maps/rampage.json new file mode 100644 index 0000000..5efa306 --- /dev/null +++ b/dist/ba_data/data/maps/rampage.json @@ -0,0 +1,45 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.35, 5.62, -4.07], "size": [19.9, 10.34, 8.16]} + ], + "edge_box": [ + {"center": [0.35, 5.44, -4.1], "size": [12.58, 4.65, 3.61]} + ], + "ffa_spawn": [ + {"center": [0.5, 5.05, -5.79], "size": [6.63, 1.0, 0.34]}, + {"center": [0.5, 5.05, -2.44], "size": [6.63, 1.0, 0.34]} + ], + "flag": [ + {"center": [-5.89, 5.11, -4.25]}, + {"center": [6.7, 5.1, -4.26]} + ], + "flag_default": [ + {"center": [0.32, 5.11, -4.29]} + ], + "map_bounds": [ + {"center": [0.45, 4.9, -3.54], "size": [23.55, 14.2, 12.08]} + ], + "powerup_spawn": [ + {"center": [-2.65, 6.43, -4.23]}, + {"center": [3.54, 6.55, -4.2]} + ], + "shadow_lower_bottom": [ + {"center": [5.58, 3.14, 5.34]} + ], + "shadow_lower_top": [ + {"center": [5.58, 4.32, 5.34]} + ], + "shadow_upper_bottom": [ + {"center": [5.27, 8.43, 5.34]} + ], + "shadow_upper_top": [ + {"center": [5.27, 11.93, 5.34]} + ], + "spawn": [ + {"center": [-4.75, 5.05, -4.25], "size": [0.92, 1.0, 0.52]}, + {"center": [5.84, 5.05, -4.26], "size": [0.92, 1.0, 0.52]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/roundabout.json b/dist/ba_data/data/maps/roundabout.json new file mode 100644 index 0000000..3205bf7 --- /dev/null +++ b/dist/ba_data/data/maps/roundabout.json @@ -0,0 +1,46 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [-1.55, 3.19, -2.41], "size": [11.96, 8.86, 9.53]} + ], + "ffa_spawn": [ + {"center": [-4.06, 3.86, -4.61], "size": [0.94, 1.0, 1.42]}, + {"center": [0.91, 3.85, -4.67], "size": [0.92, 1.0, 1.42]}, + {"center": [-1.5, 1.5, -0.73], "size": [5.73, 1.0, 0.19]} + ], + "flag": [ + {"center": [-3.02, 3.85, -6.7]}, + {"center": [-0.01, 3.83, -6.68]} + ], + "flag_default": [ + {"center": [-1.51, 1.45, -1.44]} + ], + "map_bounds": [ + {"center": [-1.62, 8.76, -2.66], "size": [20.49, 18.92, 13.8]} + ], + "powerup_spawn": [ + {"center": [-6.79, 2.66, 0.01]}, + {"center": [3.61, 2.66, 0.01]} + ], + "shadow_lower_bottom": [ + {"center": [-1.85, 0.63, 2.27]} + ], + "shadow_lower_top": [ + {"center": [-1.85, 1.08, 2.27]} + ], + "shadow_upper_bottom": [ + {"center": [-1.85, 6.05, 2.27]} + ], + "shadow_upper_top": [ + {"center": [-1.85, 9.19, 2.27]} + ], + "spawn": [ + {"center": [-4.06, 3.86, -4.61], "size": [0.94, 1.0, 1.42]}, + {"center": [0.91, 3.85, -4.67], "size": [0.92, 1.0, 1.42]} + ], + "tnt": [ + {"center": [-1.51, 2.46, 0.23]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/step_right_up.json b/dist/ba_data/data/maps/step_right_up.json new file mode 100644 index 0000000..5486d45 --- /dev/null +++ b/dist/ba_data/data/maps/step_right_up.json @@ -0,0 +1,59 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.35, 6.08, -2.27], "size": [22.55, 10.15, 14.66]} + ], + "ffa_spawn": [ + {"center": [-6.99, 5.82, -4.0], "size": [0.41, 1.0, 3.63]}, + {"center": [7.31, 5.87, -4.0], "size": [0.41, 1.0, 3.63]}, + {"center": [2.64, 4.79, -4.0], "size": [0.41, 1.0, 3.63]}, + {"center": [-2.36, 4.79, -4.0], "size": [0.41, 1.0, 3.63]} + ], + "flag": [ + {"center": [-6.01, 5.82, -8.18]}, + {"center": [6.67, 5.82, -0.32]}, + {"center": [-2.11, 4.79, -3.94]}, + {"center": [2.69, 4.79, -3.94]} + ], + "flag_default": [ + {"center": [0.25, 4.16, -3.69]} + ], + "map_bounds": [ + {"center": [0.26, 4.9, -3.54], "size": [29.24, 14.2, 29.93]} + ], + "powerup_spawn": [ + {"center": [-5.25, 4.73, 2.82]}, + {"center": [5.69, 4.73, 2.82]}, + {"center": [7.9, 6.31, -0.72]}, + {"center": [-7.22, 6.31, -7.94]}, + {"center": [-1.83, 5.25, -7.96]}, + {"center": [2.53, 5.25, -0.41]} + ], + "shadow_lower_bottom": [ + {"center": [0.52, 2.6, 5.34]} + ], + "shadow_lower_top": [ + {"center": [0.52, 3.78, 5.34]} + ], + "shadow_upper_bottom": [ + {"center": [0.52, 7.32, 5.34]} + ], + "shadow_upper_top": [ + {"center": [0.52, 11.09, 5.34]} + ], + "spawn": [ + {"center": [-4.27, 5.46, -4.0], "size": [0.41, 1.0, 2.2]}, + {"center": [5.07, 5.44, -4.06], "size": [0.35, 1.0, 2.22]} + ], + "spawn_by_flag": [ + {"center": [-6.66, 5.98, -6.17], "size": [0.75, 1.0, 0.85]}, + {"center": [7.39, 5.98, -1.71], "size": [0.75, 1.0, 0.85]}, + {"center": [-2.11, 4.8, -3.95], "size": [0.75, 1.0, 0.85]}, + {"center": [2.7, 4.8, -3.95], "size": [0.75, 1.0, 0.85]} + ], + "tnt": [ + {"center": [0.26, 4.83, -4.31]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/the_pad.json b/dist/ba_data/data/maps/the_pad.json new file mode 100644 index 0000000..359420d --- /dev/null +++ b/dist/ba_data/data/maps/the_pad.json @@ -0,0 +1,49 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.35, 4.49, -2.52], "size": [16.65, 8.06, 18.5]} + ], + "ffa_spawn": [ + {"center": [-3.81, 4.38, -8.96], "size": [2.37, 1.0, 0.87]}, + {"center": [4.47, 4.41, -9.01], "size": [2.71, 1.0, 0.87]}, + {"center": [6.97, 4.38, -7.42], "size": [0.49, 1.0, 1.6]}, + {"center": [-6.37, 4.38, -7.42], "size": [0.49, 1.0, 1.6]} + ], + "flag": [ + {"center": [-7.03, 4.31, -6.3]}, + {"center": [7.63, 4.37, -6.29]} + ], + "flag_default": [ + {"center": [0.46, 4.38, 3.68]} + ], + "map_bounds": [ + {"center": [0.26, 4.9, -3.54], "size": [29.24, 14.2, 29.93]} + ], + "powerup_spawn": [ + {"center": [-4.17, 5.28, -6.43]}, + {"center": [4.43, 5.34, -6.33]}, + {"center": [-4.2, 5.12, 0.44]}, + {"center": [4.76, 5.12, 0.35]} + ], + "shadow_lower_bottom": [ + {"center": [-0.29, 2.02, 5.34]} + ], + "shadow_lower_top": [ + {"center": [-0.29, 3.21, 5.34]} + ], + "shadow_upper_bottom": [ + {"center": [-0.29, 6.06, 5.34]} + ], + "shadow_upper_top": [ + {"center": [-0.29, 9.83, 5.34]} + ], + "spawn": [ + {"center": [-3.9, 4.38, -8.96], "size": [1.66, 1.0, 0.87]}, + {"center": [4.78, 4.41, -9.01], "size": [1.66, 1.0, 0.87]} + ], + "tnt": [ + {"center": [0.46, 4.04, -6.57]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/tip_top.json b/dist/ba_data/data/maps/tip_top.json new file mode 100644 index 0000000..d25695b --- /dev/null +++ b/dist/ba_data/data/maps/tip_top.json @@ -0,0 +1,49 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [0.0, 7.14, -0.02], "size": [21.13, 4.96, 16.69]} + ], + "ffa_spawn": [ + {"center": [-4.21, 6.97, -3.79], "size": [0.39, 1.16, 0.3]}, + {"center": [7.38, 5.21, -2.79], "size": [1.16, 1.16, 1.16]}, + {"center": [-7.26, 5.46, -3.1], "size": [1.16, 1.16, 1.16]}, + {"center": [0.02, 5.37, 4.08], "size": [1.88, 1.16, 0.2]}, + {"center": [-1.57, 7.04, -0.48], "size": [0.39, 1.16, 0.3]}, + {"center": [1.69, 7.04, -0.48], "size": [0.39, 1.16, 0.3]}, + {"center": [4.4, 6.97, -3.8], "size": [0.39, 1.16, 0.3]} + ], + "flag": [ + {"center": [-7.01, 5.42, -2.72]}, + {"center": [7.17, 5.17, -2.65]} + ], + "flag_default": [ + {"center": [0.07, 8.87, -4.99]} + ], + "map_bounds": [ + {"center": [-0.21, 7.75, -0.38], "size": [23.81, 13.86, 16.38]} + ], + "powerup_spawn": [ + {"center": [1.66, 8.05, -1.22]}, + {"center": [-1.49, 7.91, -1.23]}, + {"center": [2.63, 6.36, 1.4]}, + {"center": [-2.7, 6.36, 1.43]} + ], + "shadow_lower_bottom": [ + {"center": [0.07, 4.0, 6.32]} + ], + "shadow_lower_top": [ + {"center": [0.07, 4.75, 6.32]} + ], + "shadow_upper_bottom": [ + {"center": [0.07, 9.15, 6.32]} + ], + "shadow_upper_top": [ + {"center": [0.07, 13.82, 6.32]} + ], + "spawn": [ + {"center": [-7.26, 5.46, -3.1], "size": [1.16, 1.16, 1.16]}, + {"center": [7.38, 5.21, -2.79], "size": [1.16, 1.16, 1.16]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/tower_d.json b/dist/ba_data/data/maps/tower_d.json new file mode 100644 index 0000000..c1bc74f --- /dev/null +++ b/dist/ba_data/data/maps/tower_d.json @@ -0,0 +1,76 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [-0.47, 2.89, -1.51], "size": [17.9, 6.19, 15.96]} + ], + "b": [ + {"center": [-4.83, 2.58, -2.35], "size": [0.94, 2.75, 7.27]}, + {"center": [4.74, 2.58, -3.34], "size": [0.82, 2.75, 7.22]}, + {"center": [6.42, 2.58, -4.42], "size": [0.83, 4.53, 9.17]}, + {"center": [-6.65, 3.23, -3.06], "size": [0.94, 2.75, 8.93]}, + {"center": [3.54, 2.58, -2.37], "size": [0.63, 2.75, 5.33]}, + {"center": [5.76, 2.58, 1.15], "size": [2.3, 2.18, 0.5]}, + {"center": [-2.87, 2.58, -1.56], "size": [0.94, 2.75, 5.92]}, + {"center": [-0.69, 4.76, -5.32], "size": [24.86, 9.0, 13.43]}, + {"center": [-0.02, 2.86, -0.95], "size": [4.9, 3.04, 6.14]} + ], + "bot_spawn_bottom_left": [ + {"center": [-7.4, 1.62, 5.38], "size": [1.66, 1.0, 0.87]} + ], + "bot_spawn_bottom_right": [ + {"center": [6.49, 1.62, 5.38], "size": [1.66, 1.0, 0.87]} + ], + "bot_spawn_start": [ + {"center": [-9.0, 3.15, 0.31], "size": [1.66, 1.0, 0.87]} + ], + "edge_box": [ + {"center": [-0.65, 3.19, 4.1], "size": [14.24, 1.47, 2.9]}, + {"center": [-0.14, 2.3, 0.35], "size": [1.74, 1.06, 4.91]} + ], + "ffa_spawn": [ + {"center": [0.1, 2.71, -0.36], "size": [1.66, 1.0, 0.87]} + ], + "flag": [ + {"center": [-7.75, 3.14, 0.27]}, + {"center": [6.85, 2.25, 0.38]} + ], + "flag_default": [ + {"center": [0.02, 2.23, -6.31]} + ], + "map_bounds": [ + {"center": [0.26, 4.9, -3.54], "size": [29.24, 14.2, 29.93]} + ], + "powerup_region": [ + {"center": [0.35, 4.04, 3.41], "size": [12.49, 0.38, 1.62]} + ], + "powerup_spawn": [ + {"center": [-4.93, 2.4, 2.88]}, + {"center": [-1.96, 2.4, 3.75]}, + {"center": [1.65, 2.4, 3.75]}, + {"center": [4.4, 2.4, 2.88]} + ], + "score_region": [ + {"center": [8.38, 3.05, 0.51], "size": [1.28, 1.37, 0.69]} + ], + "shadow_lower_bottom": [ + {"center": [-0.29, 0.95, 5.34]} + ], + "shadow_lower_top": [ + {"center": [-0.29, 2.13, 5.34]} + ], + "shadow_upper_bottom": [ + {"center": [-0.45, 6.06, 5.34]} + ], + "shadow_upper_top": [ + {"center": [-0.29, 9.83, 5.34]} + ], + "spawn": [ + {"center": [0.1, 2.71, -0.36], "size": [1.66, 1.0, 0.87]}, + {"center": [0.14, 2.74, -0.34], "size": [1.66, 1.0, 0.87]} + ], + "tnt_loc": [ + {"center": [0.01, 2.78, 3.89]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/data/maps/zig_zag.json b/dist/ba_data/data/maps/zig_zag.json new file mode 100644 index 0000000..407591a --- /dev/null +++ b/dist/ba_data/data/maps/zig_zag.json @@ -0,0 +1,57 @@ +{ + "format": ["stdmap", 1], + "locations": { + "area_of_interest_bounds": [ + {"center": [-1.81, 3.94, -1.61], "size": [23.01, 13.28, 10.01]} + ], + "ffa_spawn": [ + {"center": [-9.52, 4.65, -3.19], "size": [0.85, 1.0, 1.3]}, + {"center": [6.22, 4.63, -3.19], "size": [0.88, 1.0, 1.3]}, + {"center": [-4.43, 3.01, -4.91], "size": [1.53, 1.0, 0.76]}, + {"center": [1.46, 3.01, -4.91], "size": [1.53, 1.0, 0.76]} + ], + "flag": [ + {"center": [-9.97, 4.65, -4.97]}, + {"center": [6.84, 4.65, -4.95]}, + {"center": [1.16, 2.97, -4.89]}, + {"center": [-4.22, 3.01, -4.89]} + ], + "flag_default": [ + {"center": [-1.43, 3.02, 0.88]} + ], + "map_bounds": [ + {"center": [-1.57, 8.76, -1.31], "size": [28.77, 17.65, 19.52]} + ], + "powerup_spawn": [ + {"center": [2.56, 4.37, -4.8]}, + {"center": [-6.02, 4.37, -4.8]}, + {"center": [5.56, 5.38, -4.8]}, + {"center": [-8.79, 5.38, -4.82]} + ], + "shadow_lower_bottom": [ + {"center": [-1.43, 1.68, 4.79]} + ], + "shadow_lower_top": [ + {"center": [-1.43, 2.55, 4.79]} + ], + "shadow_upper_bottom": [ + {"center": [-1.43, 6.8, 4.79]} + ], + "shadow_upper_top": [ + {"center": [-1.43, 8.78, 4.79]} + ], + "spawn": [ + {"center": [-9.52, 4.65, -3.19], "size": [0.85, 1.0, 1.3]}, + {"center": [6.22, 4.63, -3.19], "size": [0.88, 1.0, 1.3]} + ], + "spawn_by_flag": [ + {"center": [-9.52, 4.65, -3.19], "size": [0.85, 1.0, 1.3]}, + {"center": [6.22, 4.63, -3.19], "size": [0.88, 1.0, 1.3]}, + {"center": [1.46, 3.01, -4.91], "size": [1.53, 1.0, 0.76]}, + {"center": [-4.43, 3.01, -4.91], "size": [1.53, 1.0, 0.76]} + ], + "tnt": [ + {"center": [-1.43, 4.05, 0.04]} + ] + } +} \ No newline at end of file diff --git a/dist/ba_data/fonts/fontSmall0.fdata b/dist/ba_data/fonts/fontSmall0.fdata new file mode 100644 index 0000000..b9429c0 Binary files /dev/null and b/dist/ba_data/fonts/fontSmall0.fdata differ diff --git a/dist/ba_data/fonts/fontSmall1.fdata b/dist/ba_data/fonts/fontSmall1.fdata new file mode 100644 index 0000000..a0c2393 Binary files /dev/null and b/dist/ba_data/fonts/fontSmall1.fdata differ diff --git a/dist/ba_data/fonts/fontSmall2.fdata b/dist/ba_data/fonts/fontSmall2.fdata new file mode 100644 index 0000000..5d0330b Binary files /dev/null and b/dist/ba_data/fonts/fontSmall2.fdata differ diff --git a/dist/ba_data/fonts/fontSmall3.fdata b/dist/ba_data/fonts/fontSmall3.fdata new file mode 100644 index 0000000..70ba858 Binary files /dev/null and b/dist/ba_data/fonts/fontSmall3.fdata differ diff --git a/dist/ba_data/fonts/fontSmall4.fdata b/dist/ba_data/fonts/fontSmall4.fdata new file mode 100644 index 0000000..efc89bb Binary files /dev/null and b/dist/ba_data/fonts/fontSmall4.fdata differ diff --git a/dist/ba_data/fonts/fontSmall5.fdata b/dist/ba_data/fonts/fontSmall5.fdata new file mode 100644 index 0000000..884d3c4 Binary files /dev/null and b/dist/ba_data/fonts/fontSmall5.fdata differ diff --git a/dist/ba_data/fonts/fontSmall6.fdata b/dist/ba_data/fonts/fontSmall6.fdata new file mode 100644 index 0000000..1a26a92 Binary files /dev/null and b/dist/ba_data/fonts/fontSmall6.fdata differ diff --git a/dist/ba_data/fonts/fontSmall7.fdata b/dist/ba_data/fonts/fontSmall7.fdata new file mode 100644 index 0000000..a8ae082 Binary files /dev/null and b/dist/ba_data/fonts/fontSmall7.fdata differ diff --git a/dist/ba_data/models/alwaysLandLevelCollide.cob b/dist/ba_data/models/alwaysLandLevelCollide.cob new file mode 100644 index 0000000..12d0dae Binary files /dev/null and b/dist/ba_data/models/alwaysLandLevelCollide.cob differ diff --git a/dist/ba_data/models/bigGBumper.cob b/dist/ba_data/models/bigGBumper.cob new file mode 100644 index 0000000..295e22c Binary files /dev/null and b/dist/ba_data/models/bigGBumper.cob differ diff --git a/dist/ba_data/models/bigGCollide.cob b/dist/ba_data/models/bigGCollide.cob new file mode 100644 index 0000000..95fa187 Binary files /dev/null and b/dist/ba_data/models/bigGCollide.cob differ diff --git a/dist/ba_data/models/bridgitLevelCollide.cob b/dist/ba_data/models/bridgitLevelCollide.cob new file mode 100644 index 0000000..07e9304 Binary files /dev/null and b/dist/ba_data/models/bridgitLevelCollide.cob differ diff --git a/dist/ba_data/models/bridgitLevelRailingCollide.cob b/dist/ba_data/models/bridgitLevelRailingCollide.cob new file mode 100644 index 0000000..e376abf Binary files /dev/null and b/dist/ba_data/models/bridgitLevelRailingCollide.cob differ diff --git a/dist/ba_data/models/courtyardLevelCollide.cob b/dist/ba_data/models/courtyardLevelCollide.cob new file mode 100644 index 0000000..3c01a78 Binary files /dev/null and b/dist/ba_data/models/courtyardLevelCollide.cob differ diff --git a/dist/ba_data/models/courtyardPlayerWall.cob b/dist/ba_data/models/courtyardPlayerWall.cob new file mode 100644 index 0000000..b444f6d Binary files /dev/null and b/dist/ba_data/models/courtyardPlayerWall.cob differ diff --git a/dist/ba_data/models/cragCastleLevelBumper.cob b/dist/ba_data/models/cragCastleLevelBumper.cob new file mode 100644 index 0000000..c8d81aa Binary files /dev/null and b/dist/ba_data/models/cragCastleLevelBumper.cob differ diff --git a/dist/ba_data/models/cragCastleLevelCollide.cob b/dist/ba_data/models/cragCastleLevelCollide.cob new file mode 100644 index 0000000..31c4bf0 Binary files /dev/null and b/dist/ba_data/models/cragCastleLevelCollide.cob differ diff --git a/dist/ba_data/models/doomShroomLevelCollide.cob b/dist/ba_data/models/doomShroomLevelCollide.cob new file mode 100644 index 0000000..1fc6640 Binary files /dev/null and b/dist/ba_data/models/doomShroomLevelCollide.cob differ diff --git a/dist/ba_data/models/doomShroomStemCollide.cob b/dist/ba_data/models/doomShroomStemCollide.cob new file mode 100644 index 0000000..e6da3d1 Binary files /dev/null and b/dist/ba_data/models/doomShroomStemCollide.cob differ diff --git a/dist/ba_data/models/footballStadiumCollide.cob b/dist/ba_data/models/footballStadiumCollide.cob new file mode 100644 index 0000000..92f42c5 Binary files /dev/null and b/dist/ba_data/models/footballStadiumCollide.cob differ diff --git a/dist/ba_data/models/hockeyStadiumCollide.cob b/dist/ba_data/models/hockeyStadiumCollide.cob new file mode 100644 index 0000000..5f8b2f2 Binary files /dev/null and b/dist/ba_data/models/hockeyStadiumCollide.cob differ diff --git a/dist/ba_data/models/lakeFrigidCollide.cob b/dist/ba_data/models/lakeFrigidCollide.cob new file mode 100644 index 0000000..f8eba15 Binary files /dev/null and b/dist/ba_data/models/lakeFrigidCollide.cob differ diff --git a/dist/ba_data/models/monkeyFaceLevelBumper.cob b/dist/ba_data/models/monkeyFaceLevelBumper.cob new file mode 100644 index 0000000..ced1141 Binary files /dev/null and b/dist/ba_data/models/monkeyFaceLevelBumper.cob differ diff --git a/dist/ba_data/models/monkeyFaceLevelCollide.cob b/dist/ba_data/models/monkeyFaceLevelCollide.cob new file mode 100644 index 0000000..175433c Binary files /dev/null and b/dist/ba_data/models/monkeyFaceLevelCollide.cob differ diff --git a/dist/ba_data/models/natureBackgroundCollide.cob b/dist/ba_data/models/natureBackgroundCollide.cob new file mode 100644 index 0000000..570fdd8 Binary files /dev/null and b/dist/ba_data/models/natureBackgroundCollide.cob differ diff --git a/dist/ba_data/models/rampageBumper.cob b/dist/ba_data/models/rampageBumper.cob new file mode 100644 index 0000000..c39698f Binary files /dev/null and b/dist/ba_data/models/rampageBumper.cob differ diff --git a/dist/ba_data/models/rampageLevelCollide.cob b/dist/ba_data/models/rampageLevelCollide.cob new file mode 100644 index 0000000..7dc3431 Binary files /dev/null and b/dist/ba_data/models/rampageLevelCollide.cob differ diff --git a/dist/ba_data/models/roundaboutLevelBumper.cob b/dist/ba_data/models/roundaboutLevelBumper.cob new file mode 100644 index 0000000..a26cd03 Binary files /dev/null and b/dist/ba_data/models/roundaboutLevelBumper.cob differ diff --git a/dist/ba_data/models/roundaboutLevelCollide.cob b/dist/ba_data/models/roundaboutLevelCollide.cob new file mode 100644 index 0000000..e373044 Binary files /dev/null and b/dist/ba_data/models/roundaboutLevelCollide.cob differ diff --git a/dist/ba_data/models/stepRightUpLevelCollide.cob b/dist/ba_data/models/stepRightUpLevelCollide.cob new file mode 100644 index 0000000..4077edf Binary files /dev/null and b/dist/ba_data/models/stepRightUpLevelCollide.cob differ diff --git a/dist/ba_data/models/thePadLevelBumper.cob b/dist/ba_data/models/thePadLevelBumper.cob new file mode 100644 index 0000000..6d7774d Binary files /dev/null and b/dist/ba_data/models/thePadLevelBumper.cob differ diff --git a/dist/ba_data/models/thePadLevelCollide.cob b/dist/ba_data/models/thePadLevelCollide.cob new file mode 100644 index 0000000..a4a5cfd Binary files /dev/null and b/dist/ba_data/models/thePadLevelCollide.cob differ diff --git a/dist/ba_data/models/tipTopLevelBumper.cob b/dist/ba_data/models/tipTopLevelBumper.cob new file mode 100644 index 0000000..109ff12 Binary files /dev/null and b/dist/ba_data/models/tipTopLevelBumper.cob differ diff --git a/dist/ba_data/models/tipTopLevelCollide.cob b/dist/ba_data/models/tipTopLevelCollide.cob new file mode 100644 index 0000000..b0d94dc Binary files /dev/null and b/dist/ba_data/models/tipTopLevelCollide.cob differ diff --git a/dist/ba_data/models/towerDLevelCollide.cob b/dist/ba_data/models/towerDLevelCollide.cob new file mode 100644 index 0000000..0d49496 Binary files /dev/null and b/dist/ba_data/models/towerDLevelCollide.cob differ diff --git a/dist/ba_data/models/towerDPlayerWall.cob b/dist/ba_data/models/towerDPlayerWall.cob new file mode 100644 index 0000000..d563368 Binary files /dev/null and b/dist/ba_data/models/towerDPlayerWall.cob differ diff --git a/dist/ba_data/models/zigZagLevelBumper.cob b/dist/ba_data/models/zigZagLevelBumper.cob new file mode 100644 index 0000000..3dba9c5 Binary files /dev/null and b/dist/ba_data/models/zigZagLevelBumper.cob differ diff --git a/dist/ba_data/models/zigZagLevelCollide.cob b/dist/ba_data/models/zigZagLevelCollide.cob new file mode 100644 index 0000000..3d0ec27 Binary files /dev/null and b/dist/ba_data/models/zigZagLevelCollide.cob differ diff --git a/dist/ba_data/python-site-packages/__pycache__/filelock.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/__pycache__/filelock.cpython-310.opt-1.pyc new file mode 100644 index 0000000..6b82852 Binary files /dev/null and b/dist/ba_data/python-site-packages/__pycache__/filelock.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/__pycache__/typing_extensions.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/__pycache__/typing_extensions.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d5d362d Binary files /dev/null and b/dist/ba_data/python-site-packages/__pycache__/typing_extensions.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-aarch64-linux-gnu.so b/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-aarch64-linux-gnu.so new file mode 100644 index 0000000..f4b4204 Binary files /dev/null and b/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-aarch64-linux-gnu.so differ diff --git a/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-x86_64-linux-gnu.so b/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-x86_64-linux-gnu.so new file mode 100644 index 0000000..af6999f Binary files /dev/null and b/dist/ba_data/python-site-packages/_cffi_backend.cpython-310-x86_64-linux-gnu.so differ diff --git a/dist/ba_data/python-site-packages/_yaml/__init__.py b/dist/ba_data/python-site-packages/_yaml/__init__.py new file mode 100644 index 0000000..7baa8c4 --- /dev/null +++ b/dist/ba_data/python-site-packages/_yaml/__init__.py @@ -0,0 +1,33 @@ +# This is a stub package designed to roughly emulate the _yaml +# extension module, which previously existed as a standalone module +# and has been moved into the `yaml` package namespace. +# It does not perfectly mimic its old counterpart, but should get +# close enough for anyone who's relying on it even when they shouldn't. +import yaml + +# in some circumstances, the yaml module we imoprted may be from a different version, so we need +# to tread carefully when poking at it here (it may not have the attributes we expect) +if not getattr(yaml, '__with_libyaml__', False): + from sys import version_info + + exc = ModuleNotFoundError if version_info >= (3, 6) else ImportError + raise exc("No module named '_yaml'") +else: + from yaml._yaml import * + import warnings + warnings.warn( + 'The _yaml extension module is now located at yaml._yaml' + ' and its location is subject to change. To use the' + ' LibYAML-based parser and emitter, import from `yaml`:' + ' `from yaml import CLoader as Loader, CDumper as Dumper`.', + DeprecationWarning + ) + del warnings + # Don't `del yaml` here because yaml is actually an existing + # namespace member of _yaml. + +__name__ = '_yaml' +# If the module is top-level (i.e. not a part of any specific package) +# then the attribute should be set to ''. +# https://docs.python.org/3.8/library/types.html +__package__ = '' diff --git a/dist/ba_data/python-site-packages/_yaml/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/_yaml/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..0581a21 Binary files /dev/null and b/dist/ba_data/python-site-packages/_yaml/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_cparser.pxd.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_cparser.pxd.hash new file mode 100644 index 0000000..5d76497 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_cparser.pxd.hash @@ -0,0 +1 @@ +c6fb0b975dd95d7c871b26f652ced6b0b9dc9dd42bc61c860782979ef6ec46d4 *D:/a/aiohttp/aiohttp/aiohttp/_cparser.pxd diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_find_header.pxd.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_find_header.pxd.hash new file mode 100644 index 0000000..8af9f81 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_find_header.pxd.hash @@ -0,0 +1 @@ +0455129b185e981b5b96ac738f31f7c74dc57f1696953cae0083b3f18679fe73 *D:/a/aiohttp/aiohttp/aiohttp/_find_header.pxd diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_frozenlist.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_frozenlist.pyx.hash new file mode 100644 index 0000000..01fdf2b --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_frozenlist.pyx.hash @@ -0,0 +1 @@ +481f39d4a9ad5a9889d99074e53a68e3ce795640b246d80cb3ce375b3f2415e8 *D:/a/aiohttp/aiohttp/aiohttp/_frozenlist.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyi.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyi.hash new file mode 100644 index 0000000..82a670d --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyi.hash @@ -0,0 +1 @@ +d87779202d197f8613109e35dacbb2ca1b21d64572543bf9838b2d832a362ac7 *D:/a/aiohttp/aiohttp/aiohttp/_helpers.pyi diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyx.hash new file mode 100644 index 0000000..251b846 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_helpers.pyx.hash @@ -0,0 +1 @@ +b6097b7d987440c4fa7237f88d227c89a3ba0dd403dc638ddbe487e0de7f1138 *D:/a/aiohttp/aiohttp/aiohttp/_helpers.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_http_parser.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_http_parser.pyx.hash new file mode 100644 index 0000000..5c431a9 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_http_parser.pyx.hash @@ -0,0 +1 @@ +83c05185224ad57f133f7fd5d56c331f4f9e101cd52f91237e7b6568b5459e1c *D:/a/aiohttp/aiohttp/aiohttp/_http_parser.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_http_writer.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_http_writer.pyx.hash new file mode 100644 index 0000000..e2a14a8 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_http_writer.pyx.hash @@ -0,0 +1 @@ +ac1cdb93ec6b2163b6843d242a8e482ca48ab16fd4f177f5e4800f9ea487db74 *D:/a/aiohttp/aiohttp/aiohttp/_http_writer.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/_websocket.pyx.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/_websocket.pyx.hash new file mode 100644 index 0000000..1a3346e --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/_websocket.pyx.hash @@ -0,0 +1 @@ +a3d27bca2f5cdbe8d3063137754917c610d62af456273e4665fc8bb202506b7f *D:/a/aiohttp/aiohttp/aiohttp/_websocket.pyx diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/frozenlist.pyi.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/frozenlist.pyi.hash new file mode 100644 index 0000000..918409f --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/frozenlist.pyi.hash @@ -0,0 +1 @@ +9011bd27ad72982aa252f064ae3b1119599f6a49a4ce4e8a1e665b76044b0996 *D:/a/aiohttp/aiohttp/aiohttp/frozenlist.pyi diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/hdrs.py.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/hdrs.py.hash new file mode 100644 index 0000000..b69b16a --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/hdrs.py.hash @@ -0,0 +1 @@ +5f2bdc50368865ef87528ae8fd6820c8b35677209c5430b669c8857abedb9e94 *D:/a/aiohttp/aiohttp/aiohttp/hdrs.py diff --git a/dist/ba_data/python-site-packages/aiohttp/.hash/signals.pyi.hash b/dist/ba_data/python-site-packages/aiohttp/.hash/signals.pyi.hash new file mode 100644 index 0000000..fc136a6 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/.hash/signals.pyi.hash @@ -0,0 +1 @@ +1273686ce37b6b3150d5f1d28a496f6ebbd07d05273993e2de7ffaa4a1335e83 *D:/a/aiohttp/aiohttp/aiohttp/signals.pyi diff --git a/dist/ba_data/python-site-packages/aiohttp/__init__.py b/dist/ba_data/python-site-packages/aiohttp/__init__.py new file mode 100644 index 0000000..12c73f4 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/__init__.py @@ -0,0 +1,217 @@ +__version__ = "3.7.4.post0" + +from typing import Tuple + +from . import hdrs as hdrs +from .client import ( + BaseConnector as BaseConnector, + ClientConnectionError as ClientConnectionError, + ClientConnectorCertificateError as ClientConnectorCertificateError, + ClientConnectorError as ClientConnectorError, + ClientConnectorSSLError as ClientConnectorSSLError, + ClientError as ClientError, + ClientHttpProxyError as ClientHttpProxyError, + ClientOSError as ClientOSError, + ClientPayloadError as ClientPayloadError, + ClientProxyConnectionError as ClientProxyConnectionError, + ClientRequest as ClientRequest, + ClientResponse as ClientResponse, + ClientResponseError as ClientResponseError, + ClientSession as ClientSession, + ClientSSLError as ClientSSLError, + ClientTimeout as ClientTimeout, + ClientWebSocketResponse as ClientWebSocketResponse, + ContentTypeError as ContentTypeError, + Fingerprint as Fingerprint, + InvalidURL as InvalidURL, + NamedPipeConnector as NamedPipeConnector, + RequestInfo as RequestInfo, + ServerConnectionError as ServerConnectionError, + ServerDisconnectedError as ServerDisconnectedError, + ServerFingerprintMismatch as ServerFingerprintMismatch, + ServerTimeoutError as ServerTimeoutError, + TCPConnector as TCPConnector, + TooManyRedirects as TooManyRedirects, + UnixConnector as UnixConnector, + WSServerHandshakeError as WSServerHandshakeError, + request as request, +) +from .cookiejar import CookieJar as CookieJar, DummyCookieJar as DummyCookieJar +from .formdata import FormData as FormData +from .helpers import BasicAuth as BasicAuth, ChainMapProxy as ChainMapProxy +from .http import ( + HttpVersion as HttpVersion, + HttpVersion10 as HttpVersion10, + HttpVersion11 as HttpVersion11, + WebSocketError as WebSocketError, + WSCloseCode as WSCloseCode, + WSMessage as WSMessage, + WSMsgType as WSMsgType, +) +from .multipart import ( + BadContentDispositionHeader as BadContentDispositionHeader, + BadContentDispositionParam as BadContentDispositionParam, + BodyPartReader as BodyPartReader, + MultipartReader as MultipartReader, + MultipartWriter as MultipartWriter, + content_disposition_filename as content_disposition_filename, + parse_content_disposition as parse_content_disposition, +) +from .payload import ( + PAYLOAD_REGISTRY as PAYLOAD_REGISTRY, + AsyncIterablePayload as AsyncIterablePayload, + BufferedReaderPayload as BufferedReaderPayload, + BytesIOPayload as BytesIOPayload, + BytesPayload as BytesPayload, + IOBasePayload as IOBasePayload, + JsonPayload as JsonPayload, + Payload as Payload, + StringIOPayload as StringIOPayload, + StringPayload as StringPayload, + TextIOPayload as TextIOPayload, + get_payload as get_payload, + payload_type as payload_type, +) +from .payload_streamer import streamer as streamer +from .resolver import ( + AsyncResolver as AsyncResolver, + DefaultResolver as DefaultResolver, + ThreadedResolver as ThreadedResolver, +) +from .signals import Signal as Signal +from .streams import ( + EMPTY_PAYLOAD as EMPTY_PAYLOAD, + DataQueue as DataQueue, + EofStream as EofStream, + FlowControlDataQueue as FlowControlDataQueue, + StreamReader as StreamReader, +) +from .tracing import ( + TraceConfig as TraceConfig, + TraceConnectionCreateEndParams as TraceConnectionCreateEndParams, + TraceConnectionCreateStartParams as TraceConnectionCreateStartParams, + TraceConnectionQueuedEndParams as TraceConnectionQueuedEndParams, + TraceConnectionQueuedStartParams as TraceConnectionQueuedStartParams, + TraceConnectionReuseconnParams as TraceConnectionReuseconnParams, + TraceDnsCacheHitParams as TraceDnsCacheHitParams, + TraceDnsCacheMissParams as TraceDnsCacheMissParams, + TraceDnsResolveHostEndParams as TraceDnsResolveHostEndParams, + TraceDnsResolveHostStartParams as TraceDnsResolveHostStartParams, + TraceRequestChunkSentParams as TraceRequestChunkSentParams, + TraceRequestEndParams as TraceRequestEndParams, + TraceRequestExceptionParams as TraceRequestExceptionParams, + TraceRequestRedirectParams as TraceRequestRedirectParams, + TraceRequestStartParams as TraceRequestStartParams, + TraceResponseChunkReceivedParams as TraceResponseChunkReceivedParams, +) + +__all__: Tuple[str, ...] = ( + "hdrs", + # client + "BaseConnector", + "ClientConnectionError", + "ClientConnectorCertificateError", + "ClientConnectorError", + "ClientConnectorSSLError", + "ClientError", + "ClientHttpProxyError", + "ClientOSError", + "ClientPayloadError", + "ClientProxyConnectionError", + "ClientResponse", + "ClientRequest", + "ClientResponseError", + "ClientSSLError", + "ClientSession", + "ClientTimeout", + "ClientWebSocketResponse", + "ContentTypeError", + "Fingerprint", + "InvalidURL", + "RequestInfo", + "ServerConnectionError", + "ServerDisconnectedError", + "ServerFingerprintMismatch", + "ServerTimeoutError", + "TCPConnector", + "TooManyRedirects", + "UnixConnector", + "NamedPipeConnector", + "WSServerHandshakeError", + "request", + # cookiejar + "CookieJar", + "DummyCookieJar", + # formdata + "FormData", + # helpers + "BasicAuth", + "ChainMapProxy", + # http + "HttpVersion", + "HttpVersion10", + "HttpVersion11", + "WSMsgType", + "WSCloseCode", + "WSMessage", + "WebSocketError", + # multipart + "BadContentDispositionHeader", + "BadContentDispositionParam", + "BodyPartReader", + "MultipartReader", + "MultipartWriter", + "content_disposition_filename", + "parse_content_disposition", + # payload + "AsyncIterablePayload", + "BufferedReaderPayload", + "BytesIOPayload", + "BytesPayload", + "IOBasePayload", + "JsonPayload", + "PAYLOAD_REGISTRY", + "Payload", + "StringIOPayload", + "StringPayload", + "TextIOPayload", + "get_payload", + "payload_type", + # payload_streamer + "streamer", + # resolver + "AsyncResolver", + "DefaultResolver", + "ThreadedResolver", + # signals + "Signal", + "DataQueue", + "EMPTY_PAYLOAD", + "EofStream", + "FlowControlDataQueue", + "StreamReader", + # tracing + "TraceConfig", + "TraceConnectionCreateEndParams", + "TraceConnectionCreateStartParams", + "TraceConnectionQueuedEndParams", + "TraceConnectionQueuedStartParams", + "TraceConnectionReuseconnParams", + "TraceDnsCacheHitParams", + "TraceDnsCacheMissParams", + "TraceDnsResolveHostEndParams", + "TraceDnsResolveHostStartParams", + "TraceRequestChunkSentParams", + "TraceRequestEndParams", + "TraceRequestExceptionParams", + "TraceRequestRedirectParams", + "TraceRequestStartParams", + "TraceResponseChunkReceivedParams", +) + +try: + from .worker import GunicornUVLoopWebWorker, GunicornWebWorker + + __all__ += ("GunicornWebWorker", "GunicornUVLoopWebWorker") +except ImportError: # pragma: no cover + pass diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..823dff8 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/abc.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/abc.cpython-310.opt-1.pyc new file mode 100644 index 0000000..bf06031 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/abc.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/base_protocol.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/base_protocol.cpython-310.opt-1.pyc new file mode 100644 index 0000000..3fa4e76 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/base_protocol.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/client.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client.cpython-310.opt-1.pyc new file mode 100644 index 0000000..137166d Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_exceptions.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_exceptions.cpython-310.opt-1.pyc new file mode 100644 index 0000000..f674ff1 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_exceptions.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_proto.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_proto.cpython-310.opt-1.pyc new file mode 100644 index 0000000..dadc886 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_proto.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_reqrep.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_reqrep.cpython-310.opt-1.pyc new file mode 100644 index 0000000..19077a3 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_reqrep.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_ws.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_ws.cpython-310.opt-1.pyc new file mode 100644 index 0000000..353269a Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/client_ws.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/connector.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/connector.cpython-310.opt-1.pyc new file mode 100644 index 0000000..f78abe0 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/connector.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/cookiejar.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/cookiejar.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8098a4f Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/cookiejar.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/formdata.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/formdata.cpython-310.opt-1.pyc new file mode 100644 index 0000000..08be881 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/formdata.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/frozenlist.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/frozenlist.cpython-310.opt-1.pyc new file mode 100644 index 0000000..db9efbc Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/frozenlist.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/hdrs.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/hdrs.cpython-310.opt-1.pyc new file mode 100644 index 0000000..ca68df8 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/hdrs.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/helpers.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/helpers.cpython-310.opt-1.pyc new file mode 100644 index 0000000..395b8df Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/helpers.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/http.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http.cpython-310.opt-1.pyc new file mode 100644 index 0000000..f1bc3eb Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_exceptions.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_exceptions.cpython-310.opt-1.pyc new file mode 100644 index 0000000..409c4c9 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_exceptions.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_parser.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_parser.cpython-310.opt-1.pyc new file mode 100644 index 0000000..2f554a0 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_parser.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_websocket.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_websocket.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9dc3156 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_websocket.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_writer.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_writer.cpython-310.opt-1.pyc new file mode 100644 index 0000000..e6212c3 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/http_writer.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/locks.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/locks.cpython-310.opt-1.pyc new file mode 100644 index 0000000..c109b50 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/locks.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/log.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/log.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d7a0a91 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/log.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/multipart.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/multipart.cpython-310.opt-1.pyc new file mode 100644 index 0000000..023913f Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/multipart.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/payload.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/payload.cpython-310.opt-1.pyc new file mode 100644 index 0000000..97f7c5b Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/payload.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/payload_streamer.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/payload_streamer.cpython-310.opt-1.pyc new file mode 100644 index 0000000..fd0e8f7 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/payload_streamer.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/resolver.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/resolver.cpython-310.opt-1.pyc new file mode 100644 index 0000000..921c039 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/resolver.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/signals.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/signals.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9e8840a Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/signals.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/streams.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/streams.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9784773 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/streams.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/tcp_helpers.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/tcp_helpers.cpython-310.opt-1.pyc new file mode 100644 index 0000000..729cde7 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/tcp_helpers.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/tracing.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/tracing.cpython-310.opt-1.pyc new file mode 100644 index 0000000..c8c3275 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/tracing.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/typedefs.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/typedefs.cpython-310.opt-1.pyc new file mode 100644 index 0000000..a45b887 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/typedefs.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/__pycache__/worker.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/aiohttp/__pycache__/worker.cpython-310.opt-1.pyc new file mode 100644 index 0000000..1d695a6 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/__pycache__/worker.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_cparser.pxd b/dist/ba_data/python-site-packages/aiohttp/_cparser.pxd new file mode 100644 index 0000000..0f9fc00 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_cparser.pxd @@ -0,0 +1,140 @@ +from libc.stdint cimport uint16_t, uint32_t, uint64_t + + +cdef extern from "../vendor/http-parser/http_parser.h": + ctypedef int (*http_data_cb) (http_parser*, + const char *at, + size_t length) except -1 + + ctypedef int (*http_cb) (http_parser*) except -1 + + struct http_parser: + unsigned int type + unsigned int flags + unsigned int state + unsigned int header_state + unsigned int index + + uint32_t nread + uint64_t content_length + + unsigned short http_major + unsigned short http_minor + unsigned int status_code + unsigned int method + unsigned int http_errno + + unsigned int upgrade + + void *data + + struct http_parser_settings: + http_cb on_message_begin + http_data_cb on_url + http_data_cb on_status + http_data_cb on_header_field + http_data_cb on_header_value + http_cb on_headers_complete + http_data_cb on_body + http_cb on_message_complete + http_cb on_chunk_header + http_cb on_chunk_complete + + enum http_parser_type: + HTTP_REQUEST, + HTTP_RESPONSE, + HTTP_BOTH + + enum http_errno: + HPE_OK, + HPE_CB_message_begin, + HPE_CB_url, + HPE_CB_header_field, + HPE_CB_header_value, + HPE_CB_headers_complete, + HPE_CB_body, + HPE_CB_message_complete, + HPE_CB_status, + HPE_CB_chunk_header, + HPE_CB_chunk_complete, + HPE_INVALID_EOF_STATE, + HPE_HEADER_OVERFLOW, + HPE_CLOSED_CONNECTION, + HPE_INVALID_VERSION, + HPE_INVALID_STATUS, + HPE_INVALID_METHOD, + HPE_INVALID_URL, + HPE_INVALID_HOST, + HPE_INVALID_PORT, + HPE_INVALID_PATH, + HPE_INVALID_QUERY_STRING, + HPE_INVALID_FRAGMENT, + HPE_LF_EXPECTED, + HPE_INVALID_HEADER_TOKEN, + HPE_INVALID_CONTENT_LENGTH, + HPE_INVALID_CHUNK_SIZE, + HPE_INVALID_CONSTANT, + HPE_INVALID_INTERNAL_STATE, + HPE_STRICT, + HPE_PAUSED, + HPE_UNKNOWN + + enum flags: + F_CHUNKED, + F_CONNECTION_KEEP_ALIVE, + F_CONNECTION_CLOSE, + F_CONNECTION_UPGRADE, + F_TRAILING, + F_UPGRADE, + F_SKIPBODY, + F_CONTENTLENGTH + + enum http_method: + DELETE, GET, HEAD, POST, PUT, CONNECT, OPTIONS, TRACE, COPY, + LOCK, MKCOL, MOVE, PROPFIND, PROPPATCH, SEARCH, UNLOCK, BIND, + REBIND, UNBIND, ACL, REPORT, MKACTIVITY, CHECKOUT, MERGE, + MSEARCH, NOTIFY, SUBSCRIBE, UNSUBSCRIBE, PATCH, PURGE, MKCALENDAR, + LINK, UNLINK + + void http_parser_init(http_parser *parser, http_parser_type type) + + size_t http_parser_execute(http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len) + + int http_should_keep_alive(const http_parser *parser) + + void http_parser_settings_init(http_parser_settings *settings) + + const char *http_errno_name(http_errno err) + const char *http_errno_description(http_errno err) + const char *http_method_str(http_method m) + + # URL Parser + + enum http_parser_url_fields: + UF_SCHEMA = 0, + UF_HOST = 1, + UF_PORT = 2, + UF_PATH = 3, + UF_QUERY = 4, + UF_FRAGMENT = 5, + UF_USERINFO = 6, + UF_MAX = 7 + + struct http_parser_url_field_data: + uint16_t off + uint16_t len + + struct http_parser_url: + uint16_t field_set + uint16_t port + http_parser_url_field_data[UF_MAX] field_data + + void http_parser_url_init(http_parser_url *u) + + int http_parser_parse_url(const char *buf, + size_t buflen, + int is_connect, + http_parser_url *u) diff --git a/dist/ba_data/python-site-packages/aiohttp/_find_header.c b/dist/ba_data/python-site-packages/aiohttp/_find_header.c new file mode 100644 index 0000000..012cba3 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_find_header.c @@ -0,0 +1,9870 @@ +/* The file is autogenerated from aiohttp/hdrs.py +Run ./tools/gen.py to update it after the origin changing. */ + +#include "_find_header.h" + +#define NEXT_CHAR() \ +{ \ + count++; \ + if (count == size) { \ + /* end of search */ \ + return -1; \ + } \ + pchar++; \ + ch = *pchar; \ + last = (count == size -1); \ +} while(0); + +int +find_header(const char *str, int size) +{ + char *pchar = str; + int last; + char ch; + int count = -1; + pchar--; + + + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto A; + case 'a': + if (last) { + return -1; + } + goto A; + case 'C': + if (last) { + return -1; + } + goto C; + case 'c': + if (last) { + return -1; + } + goto C; + case 'D': + if (last) { + return -1; + } + goto D; + case 'd': + if (last) { + return -1; + } + goto D; + case 'E': + if (last) { + return -1; + } + goto E; + case 'e': + if (last) { + return -1; + } + goto E; + case 'F': + if (last) { + return -1; + } + goto F; + case 'f': + if (last) { + return -1; + } + goto F; + case 'H': + if (last) { + return -1; + } + goto H; + case 'h': + if (last) { + return -1; + } + goto H; + case 'I': + if (last) { + return -1; + } + goto I; + case 'i': + if (last) { + return -1; + } + goto I; + case 'K': + if (last) { + return -1; + } + goto K; + case 'k': + if (last) { + return -1; + } + goto K; + case 'L': + if (last) { + return -1; + } + goto L; + case 'l': + if (last) { + return -1; + } + goto L; + case 'M': + if (last) { + return -1; + } + goto M; + case 'm': + if (last) { + return -1; + } + goto M; + case 'O': + if (last) { + return -1; + } + goto O; + case 'o': + if (last) { + return -1; + } + goto O; + case 'P': + if (last) { + return -1; + } + goto P; + case 'p': + if (last) { + return -1; + } + goto P; + case 'R': + if (last) { + return -1; + } + goto R; + case 'r': + if (last) { + return -1; + } + goto R; + case 'S': + if (last) { + return -1; + } + goto S; + case 's': + if (last) { + return -1; + } + goto S; + case 'T': + if (last) { + return -1; + } + goto T; + case 't': + if (last) { + return -1; + } + goto T; + case 'U': + if (last) { + return -1; + } + goto U; + case 'u': + if (last) { + return -1; + } + goto U; + case 'V': + if (last) { + return -1; + } + goto V; + case 'v': + if (last) { + return -1; + } + goto V; + case 'W': + if (last) { + return -1; + } + goto W; + case 'w': + if (last) { + return -1; + } + goto W; + case 'X': + if (last) { + return -1; + } + goto X; + case 'x': + if (last) { + return -1; + } + goto X; + default: + return -1; + } + +A: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto AC; + case 'c': + if (last) { + return -1; + } + goto AC; + case 'G': + if (last) { + return -1; + } + goto AG; + case 'g': + if (last) { + return -1; + } + goto AG; + case 'L': + if (last) { + return -1; + } + goto AL; + case 'l': + if (last) { + return -1; + } + goto AL; + case 'U': + if (last) { + return -1; + } + goto AU; + case 'u': + if (last) { + return -1; + } + goto AU; + default: + return -1; + } + +AC: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto ACC; + case 'c': + if (last) { + return -1; + } + goto ACC; + default: + return -1; + } + +ACC: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCE; + case 'e': + if (last) { + return -1; + } + goto ACCE; + default: + return -1; + } + +ACCE: + NEXT_CHAR(); + switch (ch) { + case 'P': + if (last) { + return -1; + } + goto ACCEP; + case 'p': + if (last) { + return -1; + } + goto ACCEP; + case 'S': + if (last) { + return -1; + } + goto ACCES; + case 's': + if (last) { + return -1; + } + goto ACCES; + default: + return -1; + } + +ACCEP: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return 0; + } + goto ACCEPT; + case 't': + if (last) { + return 0; + } + goto ACCEPT; + default: + return -1; + } + +ACCEPT: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto ACCEPT_; + default: + return -1; + } + +ACCEPT_: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto ACCEPT_C; + case 'c': + if (last) { + return -1; + } + goto ACCEPT_C; + case 'E': + if (last) { + return -1; + } + goto ACCEPT_E; + case 'e': + if (last) { + return -1; + } + goto ACCEPT_E; + case 'L': + if (last) { + return -1; + } + goto ACCEPT_L; + case 'l': + if (last) { + return -1; + } + goto ACCEPT_L; + case 'R': + if (last) { + return -1; + } + goto ACCEPT_R; + case 'r': + if (last) { + return -1; + } + goto ACCEPT_R; + default: + return -1; + } + +ACCEPT_C: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return -1; + } + goto ACCEPT_CH; + case 'h': + if (last) { + return -1; + } + goto ACCEPT_CH; + default: + return -1; + } + +ACCEPT_CH: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCEPT_CHA; + case 'a': + if (last) { + return -1; + } + goto ACCEPT_CHA; + default: + return -1; + } + +ACCEPT_CHA: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto ACCEPT_CHAR; + case 'r': + if (last) { + return -1; + } + goto ACCEPT_CHAR; + default: + return -1; + } + +ACCEPT_CHAR: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto ACCEPT_CHARS; + case 's': + if (last) { + return -1; + } + goto ACCEPT_CHARS; + default: + return -1; + } + +ACCEPT_CHARS: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCEPT_CHARSE; + case 'e': + if (last) { + return -1; + } + goto ACCEPT_CHARSE; + default: + return -1; + } + +ACCEPT_CHARSE: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return 1; + } + goto ACCEPT_CHARSET; + case 't': + if (last) { + return 1; + } + goto ACCEPT_CHARSET; + default: + return -1; + } + +ACCEPT_E: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto ACCEPT_EN; + case 'n': + if (last) { + return -1; + } + goto ACCEPT_EN; + default: + return -1; + } + +ACCEPT_EN: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto ACCEPT_ENC; + case 'c': + if (last) { + return -1; + } + goto ACCEPT_ENC; + default: + return -1; + } + +ACCEPT_ENC: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto ACCEPT_ENCO; + case 'o': + if (last) { + return -1; + } + goto ACCEPT_ENCO; + default: + return -1; + } + +ACCEPT_ENCO: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto ACCEPT_ENCOD; + case 'd': + if (last) { + return -1; + } + goto ACCEPT_ENCOD; + default: + return -1; + } + +ACCEPT_ENCOD: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto ACCEPT_ENCODI; + case 'i': + if (last) { + return -1; + } + goto ACCEPT_ENCODI; + default: + return -1; + } + +ACCEPT_ENCODI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto ACCEPT_ENCODIN; + case 'n': + if (last) { + return -1; + } + goto ACCEPT_ENCODIN; + default: + return -1; + } + +ACCEPT_ENCODIN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return 2; + } + goto ACCEPT_ENCODING; + case 'g': + if (last) { + return 2; + } + goto ACCEPT_ENCODING; + default: + return -1; + } + +ACCEPT_L: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCEPT_LA; + case 'a': + if (last) { + return -1; + } + goto ACCEPT_LA; + default: + return -1; + } + +ACCEPT_LA: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto ACCEPT_LAN; + case 'n': + if (last) { + return -1; + } + goto ACCEPT_LAN; + default: + return -1; + } + +ACCEPT_LAN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto ACCEPT_LANG; + case 'g': + if (last) { + return -1; + } + goto ACCEPT_LANG; + default: + return -1; + } + +ACCEPT_LANG: + NEXT_CHAR(); + switch (ch) { + case 'U': + if (last) { + return -1; + } + goto ACCEPT_LANGU; + case 'u': + if (last) { + return -1; + } + goto ACCEPT_LANGU; + default: + return -1; + } + +ACCEPT_LANGU: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCEPT_LANGUA; + case 'a': + if (last) { + return -1; + } + goto ACCEPT_LANGUA; + default: + return -1; + } + +ACCEPT_LANGUA: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto ACCEPT_LANGUAG; + case 'g': + if (last) { + return -1; + } + goto ACCEPT_LANGUAG; + default: + return -1; + } + +ACCEPT_LANGUAG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 3; + } + goto ACCEPT_LANGUAGE; + case 'e': + if (last) { + return 3; + } + goto ACCEPT_LANGUAGE; + default: + return -1; + } + +ACCEPT_R: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCEPT_RA; + case 'a': + if (last) { + return -1; + } + goto ACCEPT_RA; + default: + return -1; + } + +ACCEPT_RA: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto ACCEPT_RAN; + case 'n': + if (last) { + return -1; + } + goto ACCEPT_RAN; + default: + return -1; + } + +ACCEPT_RAN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto ACCEPT_RANG; + case 'g': + if (last) { + return -1; + } + goto ACCEPT_RANG; + default: + return -1; + } + +ACCEPT_RANG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCEPT_RANGE; + case 'e': + if (last) { + return -1; + } + goto ACCEPT_RANGE; + default: + return -1; + } + +ACCEPT_RANGE: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return 4; + } + goto ACCEPT_RANGES; + case 's': + if (last) { + return 4; + } + goto ACCEPT_RANGES; + default: + return -1; + } + +ACCES: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto ACCESS; + case 's': + if (last) { + return -1; + } + goto ACCESS; + default: + return -1; + } + +ACCESS: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto ACCESS_; + default: + return -1; + } + +ACCESS_: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto ACCESS_C; + case 'c': + if (last) { + return -1; + } + goto ACCESS_C; + default: + return -1; + } + +ACCESS_C: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto ACCESS_CO; + case 'o': + if (last) { + return -1; + } + goto ACCESS_CO; + default: + return -1; + } + +ACCESS_CO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto ACCESS_CON; + case 'n': + if (last) { + return -1; + } + goto ACCESS_CON; + default: + return -1; + } + +ACCESS_CON: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto ACCESS_CONT; + case 't': + if (last) { + return -1; + } + goto ACCESS_CONT; + default: + return -1; + } + +ACCESS_CONT: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto ACCESS_CONTR; + case 'r': + if (last) { + return -1; + } + goto ACCESS_CONTR; + default: + return -1; + } + +ACCESS_CONTR: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto ACCESS_CONTRO; + case 'o': + if (last) { + return -1; + } + goto ACCESS_CONTRO; + default: + return -1; + } + +ACCESS_CONTRO: + NEXT_CHAR(); + switch (ch) { + case 'L': + if (last) { + return -1; + } + goto ACCESS_CONTROL; + case 'l': + if (last) { + return -1; + } + goto ACCESS_CONTROL; + default: + return -1; + } + +ACCESS_CONTROL: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto ACCESS_CONTROL_; + default: + return -1; + } + +ACCESS_CONTROL_: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCESS_CONTROL_A; + case 'a': + if (last) { + return -1; + } + goto ACCESS_CONTROL_A; + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_E; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_E; + case 'M': + if (last) { + return -1; + } + goto ACCESS_CONTROL_M; + case 'm': + if (last) { + return -1; + } + goto ACCESS_CONTROL_M; + case 'R': + if (last) { + return -1; + } + goto ACCESS_CONTROL_R; + case 'r': + if (last) { + return -1; + } + goto ACCESS_CONTROL_R; + default: + return -1; + } + +ACCESS_CONTROL_A: + NEXT_CHAR(); + switch (ch) { + case 'L': + if (last) { + return -1; + } + goto ACCESS_CONTROL_AL; + case 'l': + if (last) { + return -1; + } + goto ACCESS_CONTROL_AL; + default: + return -1; + } + +ACCESS_CONTROL_AL: + NEXT_CHAR(); + switch (ch) { + case 'L': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALL; + case 'l': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALL; + default: + return -1; + } + +ACCESS_CONTROL_ALL: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLO; + case 'o': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLO; + default: + return -1; + } + +ACCESS_CONTROL_ALLO: + NEXT_CHAR(); + switch (ch) { + case 'W': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW; + case 'w': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_C; + case 'c': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_C; + case 'H': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_H; + case 'h': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_H; + case 'M': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_M; + case 'm': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_M; + case 'O': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_O; + case 'o': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_O; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_C: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CR; + case 'r': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CR; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_CR: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CRE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CRE; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_CRE: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CRED; + case 'd': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CRED; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_CRED: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDE; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_CREDE: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDEN; + case 'n': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDEN; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_CREDEN: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDENT; + case 't': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDENT; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_CREDENT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDENTI; + case 'i': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDENTI; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_CREDENTI: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDENTIA; + case 'a': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDENTIA; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_CREDENTIA: + NEXT_CHAR(); + switch (ch) { + case 'L': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDENTIAL; + case 'l': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_CREDENTIAL; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_CREDENTIAL: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return 5; + } + goto ACCESS_CONTROL_ALLOW_CREDENTIALS; + case 's': + if (last) { + return 5; + } + goto ACCESS_CONTROL_ALLOW_CREDENTIALS; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_H: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HE; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_HE: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HEA; + case 'a': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HEA; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_HEA: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HEAD; + case 'd': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HEAD; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_HEAD: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HEADE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HEADE; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_HEADE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HEADER; + case 'r': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_HEADER; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_HEADER: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return 6; + } + goto ACCESS_CONTROL_ALLOW_HEADERS; + case 's': + if (last) { + return 6; + } + goto ACCESS_CONTROL_ALLOW_HEADERS; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_M: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_ME; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_ME; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_ME: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_MET; + case 't': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_MET; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_MET: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_METH; + case 'h': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_METH; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_METH: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_METHO; + case 'o': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_METHO; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_METHO: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_METHOD; + case 'd': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_METHOD; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_METHOD: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return 7; + } + goto ACCESS_CONTROL_ALLOW_METHODS; + case 's': + if (last) { + return 7; + } + goto ACCESS_CONTROL_ALLOW_METHODS; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_O: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_OR; + case 'r': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_OR; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_OR: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_ORI; + case 'i': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_ORI; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_ORI: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_ORIG; + case 'g': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_ORIG; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_ORIG: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_ORIGI; + case 'i': + if (last) { + return -1; + } + goto ACCESS_CONTROL_ALLOW_ORIGI; + default: + return -1; + } + +ACCESS_CONTROL_ALLOW_ORIGI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 8; + } + goto ACCESS_CONTROL_ALLOW_ORIGIN; + case 'n': + if (last) { + return 8; + } + goto ACCESS_CONTROL_ALLOW_ORIGIN; + default: + return -1; + } + +ACCESS_CONTROL_E: + NEXT_CHAR(); + switch (ch) { + case 'X': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EX; + case 'x': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EX; + default: + return -1; + } + +ACCESS_CONTROL_EX: + NEXT_CHAR(); + switch (ch) { + case 'P': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXP; + case 'p': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXP; + default: + return -1; + } + +ACCESS_CONTROL_EXP: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPO; + case 'o': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPO; + default: + return -1; + } + +ACCESS_CONTROL_EXPO: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOS; + case 's': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOS; + default: + return -1; + } + +ACCESS_CONTROL_EXPOS: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE; + default: + return -1; + } + +ACCESS_CONTROL_EXPOSE: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_; + default: + return -1; + } + +ACCESS_CONTROL_EXPOSE_: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_H; + case 'h': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_H; + default: + return -1; + } + +ACCESS_CONTROL_EXPOSE_H: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HE; + default: + return -1; + } + +ACCESS_CONTROL_EXPOSE_HE: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HEA; + case 'a': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HEA; + default: + return -1; + } + +ACCESS_CONTROL_EXPOSE_HEA: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HEAD; + case 'd': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HEAD; + default: + return -1; + } + +ACCESS_CONTROL_EXPOSE_HEAD: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HEADE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HEADE; + default: + return -1; + } + +ACCESS_CONTROL_EXPOSE_HEADE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HEADER; + case 'r': + if (last) { + return -1; + } + goto ACCESS_CONTROL_EXPOSE_HEADER; + default: + return -1; + } + +ACCESS_CONTROL_EXPOSE_HEADER: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return 9; + } + goto ACCESS_CONTROL_EXPOSE_HEADERS; + case 's': + if (last) { + return 9; + } + goto ACCESS_CONTROL_EXPOSE_HEADERS; + default: + return -1; + } + +ACCESS_CONTROL_M: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCESS_CONTROL_MA; + case 'a': + if (last) { + return -1; + } + goto ACCESS_CONTROL_MA; + default: + return -1; + } + +ACCESS_CONTROL_MA: + NEXT_CHAR(); + switch (ch) { + case 'X': + if (last) { + return -1; + } + goto ACCESS_CONTROL_MAX; + case 'x': + if (last) { + return -1; + } + goto ACCESS_CONTROL_MAX; + default: + return -1; + } + +ACCESS_CONTROL_MAX: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto ACCESS_CONTROL_MAX_; + default: + return -1; + } + +ACCESS_CONTROL_MAX_: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCESS_CONTROL_MAX_A; + case 'a': + if (last) { + return -1; + } + goto ACCESS_CONTROL_MAX_A; + default: + return -1; + } + +ACCESS_CONTROL_MAX_A: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto ACCESS_CONTROL_MAX_AG; + case 'g': + if (last) { + return -1; + } + goto ACCESS_CONTROL_MAX_AG; + default: + return -1; + } + +ACCESS_CONTROL_MAX_AG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 10; + } + goto ACCESS_CONTROL_MAX_AGE; + case 'e': + if (last) { + return 10; + } + goto ACCESS_CONTROL_MAX_AGE; + default: + return -1; + } + +ACCESS_CONTROL_R: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_RE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_RE; + default: + return -1; + } + +ACCESS_CONTROL_RE: + NEXT_CHAR(); + switch (ch) { + case 'Q': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQ; + case 'q': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQ; + default: + return -1; + } + +ACCESS_CONTROL_REQ: + NEXT_CHAR(); + switch (ch) { + case 'U': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQU; + case 'u': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQU; + default: + return -1; + } + +ACCESS_CONTROL_REQU: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUE; + default: + return -1; + } + +ACCESS_CONTROL_REQUE: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUES; + case 's': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUES; + default: + return -1; + } + +ACCESS_CONTROL_REQUES: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST; + case 't': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_H; + case 'h': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_H; + case 'M': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_M; + case 'm': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_M; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_H: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HE; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_HE: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HEA; + case 'a': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HEA; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_HEA: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HEAD; + case 'd': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HEAD; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_HEAD: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HEADE; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HEADE; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_HEADE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HEADER; + case 'r': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_HEADER; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_HEADER: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return 11; + } + goto ACCESS_CONTROL_REQUEST_HEADERS; + case 's': + if (last) { + return 11; + } + goto ACCESS_CONTROL_REQUEST_HEADERS; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_M: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_ME; + case 'e': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_ME; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_ME: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_MET; + case 't': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_MET; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_MET: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_METH; + case 'h': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_METH; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_METH: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_METHO; + case 'o': + if (last) { + return -1; + } + goto ACCESS_CONTROL_REQUEST_METHO; + default: + return -1; + } + +ACCESS_CONTROL_REQUEST_METHO: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return 12; + } + goto ACCESS_CONTROL_REQUEST_METHOD; + case 'd': + if (last) { + return 12; + } + goto ACCESS_CONTROL_REQUEST_METHOD; + default: + return -1; + } + +AG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 13; + } + goto AGE; + case 'e': + if (last) { + return 13; + } + goto AGE; + default: + return -1; + } + +AL: + NEXT_CHAR(); + switch (ch) { + case 'L': + if (last) { + return -1; + } + goto ALL; + case 'l': + if (last) { + return -1; + } + goto ALL; + default: + return -1; + } + +ALL: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto ALLO; + case 'o': + if (last) { + return -1; + } + goto ALLO; + default: + return -1; + } + +ALLO: + NEXT_CHAR(); + switch (ch) { + case 'W': + if (last) { + return 14; + } + goto ALLOW; + case 'w': + if (last) { + return 14; + } + goto ALLOW; + default: + return -1; + } + +AU: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto AUT; + case 't': + if (last) { + return -1; + } + goto AUT; + default: + return -1; + } + +AUT: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return -1; + } + goto AUTH; + case 'h': + if (last) { + return -1; + } + goto AUTH; + default: + return -1; + } + +AUTH: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto AUTHO; + case 'o': + if (last) { + return -1; + } + goto AUTHO; + default: + return -1; + } + +AUTHO: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto AUTHOR; + case 'r': + if (last) { + return -1; + } + goto AUTHOR; + default: + return -1; + } + +AUTHOR: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto AUTHORI; + case 'i': + if (last) { + return -1; + } + goto AUTHORI; + default: + return -1; + } + +AUTHORI: + NEXT_CHAR(); + switch (ch) { + case 'Z': + if (last) { + return -1; + } + goto AUTHORIZ; + case 'z': + if (last) { + return -1; + } + goto AUTHORIZ; + default: + return -1; + } + +AUTHORIZ: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto AUTHORIZA; + case 'a': + if (last) { + return -1; + } + goto AUTHORIZA; + default: + return -1; + } + +AUTHORIZA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto AUTHORIZAT; + case 't': + if (last) { + return -1; + } + goto AUTHORIZAT; + default: + return -1; + } + +AUTHORIZAT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto AUTHORIZATI; + case 'i': + if (last) { + return -1; + } + goto AUTHORIZATI; + default: + return -1; + } + +AUTHORIZATI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto AUTHORIZATIO; + case 'o': + if (last) { + return -1; + } + goto AUTHORIZATIO; + default: + return -1; + } + +AUTHORIZATIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 15; + } + goto AUTHORIZATION; + case 'n': + if (last) { + return 15; + } + goto AUTHORIZATION; + default: + return -1; + } + +C: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto CA; + case 'a': + if (last) { + return -1; + } + goto CA; + case 'O': + if (last) { + return -1; + } + goto CO; + case 'o': + if (last) { + return -1; + } + goto CO; + default: + return -1; + } + +CA: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto CAC; + case 'c': + if (last) { + return -1; + } + goto CAC; + default: + return -1; + } + +CAC: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return -1; + } + goto CACH; + case 'h': + if (last) { + return -1; + } + goto CACH; + default: + return -1; + } + +CACH: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto CACHE; + case 'e': + if (last) { + return -1; + } + goto CACHE; + default: + return -1; + } + +CACHE: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto CACHE_; + default: + return -1; + } + +CACHE_: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto CACHE_C; + case 'c': + if (last) { + return -1; + } + goto CACHE_C; + default: + return -1; + } + +CACHE_C: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto CACHE_CO; + case 'o': + if (last) { + return -1; + } + goto CACHE_CO; + default: + return -1; + } + +CACHE_CO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CACHE_CON; + case 'n': + if (last) { + return -1; + } + goto CACHE_CON; + default: + return -1; + } + +CACHE_CON: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto CACHE_CONT; + case 't': + if (last) { + return -1; + } + goto CACHE_CONT; + default: + return -1; + } + +CACHE_CONT: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto CACHE_CONTR; + case 'r': + if (last) { + return -1; + } + goto CACHE_CONTR; + default: + return -1; + } + +CACHE_CONTR: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto CACHE_CONTRO; + case 'o': + if (last) { + return -1; + } + goto CACHE_CONTRO; + default: + return -1; + } + +CACHE_CONTRO: + NEXT_CHAR(); + switch (ch) { + case 'L': + if (last) { + return 16; + } + goto CACHE_CONTROL; + case 'l': + if (last) { + return 16; + } + goto CACHE_CONTROL; + default: + return -1; + } + +CO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CON; + case 'n': + if (last) { + return -1; + } + goto CON; + case 'O': + if (last) { + return -1; + } + goto COO; + case 'o': + if (last) { + return -1; + } + goto COO; + default: + return -1; + } + +CON: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONN; + case 'n': + if (last) { + return -1; + } + goto CONN; + case 'T': + if (last) { + return -1; + } + goto CONT; + case 't': + if (last) { + return -1; + } + goto CONT; + default: + return -1; + } + +CONN: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto CONNE; + case 'e': + if (last) { + return -1; + } + goto CONNE; + default: + return -1; + } + +CONNE: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto CONNEC; + case 'c': + if (last) { + return -1; + } + goto CONNEC; + default: + return -1; + } + +CONNEC: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto CONNECT; + case 't': + if (last) { + return -1; + } + goto CONNECT; + default: + return -1; + } + +CONNECT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto CONNECTI; + case 'i': + if (last) { + return -1; + } + goto CONNECTI; + default: + return -1; + } + +CONNECTI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto CONNECTIO; + case 'o': + if (last) { + return -1; + } + goto CONNECTIO; + default: + return -1; + } + +CONNECTIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 17; + } + goto CONNECTION; + case 'n': + if (last) { + return 17; + } + goto CONNECTION; + default: + return -1; + } + +CONT: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto CONTE; + case 'e': + if (last) { + return -1; + } + goto CONTE; + default: + return -1; + } + +CONTE: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONTEN; + case 'n': + if (last) { + return -1; + } + goto CONTEN; + default: + return -1; + } + +CONTEN: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto CONTENT; + case 't': + if (last) { + return -1; + } + goto CONTENT; + default: + return -1; + } + +CONTENT: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto CONTENT_; + default: + return -1; + } + +CONTENT_: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto CONTENT_D; + case 'd': + if (last) { + return -1; + } + goto CONTENT_D; + case 'E': + if (last) { + return -1; + } + goto CONTENT_E; + case 'e': + if (last) { + return -1; + } + goto CONTENT_E; + case 'L': + if (last) { + return -1; + } + goto CONTENT_L; + case 'l': + if (last) { + return -1; + } + goto CONTENT_L; + case 'M': + if (last) { + return -1; + } + goto CONTENT_M; + case 'm': + if (last) { + return -1; + } + goto CONTENT_M; + case 'R': + if (last) { + return -1; + } + goto CONTENT_R; + case 'r': + if (last) { + return -1; + } + goto CONTENT_R; + case 'T': + if (last) { + return -1; + } + goto CONTENT_T; + case 't': + if (last) { + return -1; + } + goto CONTENT_T; + default: + return -1; + } + +CONTENT_D: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto CONTENT_DI; + case 'i': + if (last) { + return -1; + } + goto CONTENT_DI; + default: + return -1; + } + +CONTENT_DI: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto CONTENT_DIS; + case 's': + if (last) { + return -1; + } + goto CONTENT_DIS; + default: + return -1; + } + +CONTENT_DIS: + NEXT_CHAR(); + switch (ch) { + case 'P': + if (last) { + return -1; + } + goto CONTENT_DISP; + case 'p': + if (last) { + return -1; + } + goto CONTENT_DISP; + default: + return -1; + } + +CONTENT_DISP: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto CONTENT_DISPO; + case 'o': + if (last) { + return -1; + } + goto CONTENT_DISPO; + default: + return -1; + } + +CONTENT_DISPO: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto CONTENT_DISPOS; + case 's': + if (last) { + return -1; + } + goto CONTENT_DISPOS; + default: + return -1; + } + +CONTENT_DISPOS: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto CONTENT_DISPOSI; + case 'i': + if (last) { + return -1; + } + goto CONTENT_DISPOSI; + default: + return -1; + } + +CONTENT_DISPOSI: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto CONTENT_DISPOSIT; + case 't': + if (last) { + return -1; + } + goto CONTENT_DISPOSIT; + default: + return -1; + } + +CONTENT_DISPOSIT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto CONTENT_DISPOSITI; + case 'i': + if (last) { + return -1; + } + goto CONTENT_DISPOSITI; + default: + return -1; + } + +CONTENT_DISPOSITI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto CONTENT_DISPOSITIO; + case 'o': + if (last) { + return -1; + } + goto CONTENT_DISPOSITIO; + default: + return -1; + } + +CONTENT_DISPOSITIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 18; + } + goto CONTENT_DISPOSITION; + case 'n': + if (last) { + return 18; + } + goto CONTENT_DISPOSITION; + default: + return -1; + } + +CONTENT_E: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONTENT_EN; + case 'n': + if (last) { + return -1; + } + goto CONTENT_EN; + default: + return -1; + } + +CONTENT_EN: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto CONTENT_ENC; + case 'c': + if (last) { + return -1; + } + goto CONTENT_ENC; + default: + return -1; + } + +CONTENT_ENC: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto CONTENT_ENCO; + case 'o': + if (last) { + return -1; + } + goto CONTENT_ENCO; + default: + return -1; + } + +CONTENT_ENCO: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto CONTENT_ENCOD; + case 'd': + if (last) { + return -1; + } + goto CONTENT_ENCOD; + default: + return -1; + } + +CONTENT_ENCOD: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto CONTENT_ENCODI; + case 'i': + if (last) { + return -1; + } + goto CONTENT_ENCODI; + default: + return -1; + } + +CONTENT_ENCODI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONTENT_ENCODIN; + case 'n': + if (last) { + return -1; + } + goto CONTENT_ENCODIN; + default: + return -1; + } + +CONTENT_ENCODIN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return 19; + } + goto CONTENT_ENCODING; + case 'g': + if (last) { + return 19; + } + goto CONTENT_ENCODING; + default: + return -1; + } + +CONTENT_L: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto CONTENT_LA; + case 'a': + if (last) { + return -1; + } + goto CONTENT_LA; + case 'E': + if (last) { + return -1; + } + goto CONTENT_LE; + case 'e': + if (last) { + return -1; + } + goto CONTENT_LE; + case 'O': + if (last) { + return -1; + } + goto CONTENT_LO; + case 'o': + if (last) { + return -1; + } + goto CONTENT_LO; + default: + return -1; + } + +CONTENT_LA: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONTENT_LAN; + case 'n': + if (last) { + return -1; + } + goto CONTENT_LAN; + default: + return -1; + } + +CONTENT_LAN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto CONTENT_LANG; + case 'g': + if (last) { + return -1; + } + goto CONTENT_LANG; + default: + return -1; + } + +CONTENT_LANG: + NEXT_CHAR(); + switch (ch) { + case 'U': + if (last) { + return -1; + } + goto CONTENT_LANGU; + case 'u': + if (last) { + return -1; + } + goto CONTENT_LANGU; + default: + return -1; + } + +CONTENT_LANGU: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto CONTENT_LANGUA; + case 'a': + if (last) { + return -1; + } + goto CONTENT_LANGUA; + default: + return -1; + } + +CONTENT_LANGUA: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto CONTENT_LANGUAG; + case 'g': + if (last) { + return -1; + } + goto CONTENT_LANGUAG; + default: + return -1; + } + +CONTENT_LANGUAG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 20; + } + goto CONTENT_LANGUAGE; + case 'e': + if (last) { + return 20; + } + goto CONTENT_LANGUAGE; + default: + return -1; + } + +CONTENT_LE: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONTENT_LEN; + case 'n': + if (last) { + return -1; + } + goto CONTENT_LEN; + default: + return -1; + } + +CONTENT_LEN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto CONTENT_LENG; + case 'g': + if (last) { + return -1; + } + goto CONTENT_LENG; + default: + return -1; + } + +CONTENT_LENG: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto CONTENT_LENGT; + case 't': + if (last) { + return -1; + } + goto CONTENT_LENGT; + default: + return -1; + } + +CONTENT_LENGT: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return 21; + } + goto CONTENT_LENGTH; + case 'h': + if (last) { + return 21; + } + goto CONTENT_LENGTH; + default: + return -1; + } + +CONTENT_LO: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto CONTENT_LOC; + case 'c': + if (last) { + return -1; + } + goto CONTENT_LOC; + default: + return -1; + } + +CONTENT_LOC: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto CONTENT_LOCA; + case 'a': + if (last) { + return -1; + } + goto CONTENT_LOCA; + default: + return -1; + } + +CONTENT_LOCA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto CONTENT_LOCAT; + case 't': + if (last) { + return -1; + } + goto CONTENT_LOCAT; + default: + return -1; + } + +CONTENT_LOCAT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto CONTENT_LOCATI; + case 'i': + if (last) { + return -1; + } + goto CONTENT_LOCATI; + default: + return -1; + } + +CONTENT_LOCATI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto CONTENT_LOCATIO; + case 'o': + if (last) { + return -1; + } + goto CONTENT_LOCATIO; + default: + return -1; + } + +CONTENT_LOCATIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 22; + } + goto CONTENT_LOCATION; + case 'n': + if (last) { + return 22; + } + goto CONTENT_LOCATION; + default: + return -1; + } + +CONTENT_M: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto CONTENT_MD; + case 'd': + if (last) { + return -1; + } + goto CONTENT_MD; + default: + return -1; + } + +CONTENT_MD: + NEXT_CHAR(); + switch (ch) { + case '5': + if (last) { + return 23; + } + goto CONTENT_MD5; + default: + return -1; + } + +CONTENT_R: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto CONTENT_RA; + case 'a': + if (last) { + return -1; + } + goto CONTENT_RA; + default: + return -1; + } + +CONTENT_RA: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONTENT_RAN; + case 'n': + if (last) { + return -1; + } + goto CONTENT_RAN; + default: + return -1; + } + +CONTENT_RAN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto CONTENT_RANG; + case 'g': + if (last) { + return -1; + } + goto CONTENT_RANG; + default: + return -1; + } + +CONTENT_RANG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 24; + } + goto CONTENT_RANGE; + case 'e': + if (last) { + return 24; + } + goto CONTENT_RANGE; + default: + return -1; + } + +CONTENT_T: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto CONTENT_TR; + case 'r': + if (last) { + return -1; + } + goto CONTENT_TR; + case 'Y': + if (last) { + return -1; + } + goto CONTENT_TY; + case 'y': + if (last) { + return -1; + } + goto CONTENT_TY; + default: + return -1; + } + +CONTENT_TR: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto CONTENT_TRA; + case 'a': + if (last) { + return -1; + } + goto CONTENT_TRA; + default: + return -1; + } + +CONTENT_TRA: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONTENT_TRAN; + case 'n': + if (last) { + return -1; + } + goto CONTENT_TRAN; + default: + return -1; + } + +CONTENT_TRAN: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto CONTENT_TRANS; + case 's': + if (last) { + return -1; + } + goto CONTENT_TRANS; + default: + return -1; + } + +CONTENT_TRANS: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto CONTENT_TRANSF; + case 'f': + if (last) { + return -1; + } + goto CONTENT_TRANSF; + default: + return -1; + } + +CONTENT_TRANSF: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto CONTENT_TRANSFE; + case 'e': + if (last) { + return -1; + } + goto CONTENT_TRANSFE; + default: + return -1; + } + +CONTENT_TRANSFE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto CONTENT_TRANSFER; + case 'r': + if (last) { + return -1; + } + goto CONTENT_TRANSFER; + default: + return -1; + } + +CONTENT_TRANSFER: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_; + default: + return -1; + } + +CONTENT_TRANSFER_: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_E; + case 'e': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_E; + default: + return -1; + } + +CONTENT_TRANSFER_E: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_EN; + case 'n': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_EN; + default: + return -1; + } + +CONTENT_TRANSFER_EN: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENC; + case 'c': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENC; + default: + return -1; + } + +CONTENT_TRANSFER_ENC: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENCO; + case 'o': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENCO; + default: + return -1; + } + +CONTENT_TRANSFER_ENCO: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENCOD; + case 'd': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENCOD; + default: + return -1; + } + +CONTENT_TRANSFER_ENCOD: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENCODI; + case 'i': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENCODI; + default: + return -1; + } + +CONTENT_TRANSFER_ENCODI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENCODIN; + case 'n': + if (last) { + return -1; + } + goto CONTENT_TRANSFER_ENCODIN; + default: + return -1; + } + +CONTENT_TRANSFER_ENCODIN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return 25; + } + goto CONTENT_TRANSFER_ENCODING; + case 'g': + if (last) { + return 25; + } + goto CONTENT_TRANSFER_ENCODING; + default: + return -1; + } + +CONTENT_TY: + NEXT_CHAR(); + switch (ch) { + case 'P': + if (last) { + return -1; + } + goto CONTENT_TYP; + case 'p': + if (last) { + return -1; + } + goto CONTENT_TYP; + default: + return -1; + } + +CONTENT_TYP: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 26; + } + goto CONTENT_TYPE; + case 'e': + if (last) { + return 26; + } + goto CONTENT_TYPE; + default: + return -1; + } + +COO: + NEXT_CHAR(); + switch (ch) { + case 'K': + if (last) { + return -1; + } + goto COOK; + case 'k': + if (last) { + return -1; + } + goto COOK; + default: + return -1; + } + +COOK: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto COOKI; + case 'i': + if (last) { + return -1; + } + goto COOKI; + default: + return -1; + } + +COOKI: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 27; + } + goto COOKIE; + case 'e': + if (last) { + return 27; + } + goto COOKIE; + default: + return -1; + } + +D: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto DA; + case 'a': + if (last) { + return -1; + } + goto DA; + case 'E': + if (last) { + return -1; + } + goto DE; + case 'e': + if (last) { + return -1; + } + goto DE; + case 'I': + if (last) { + return -1; + } + goto DI; + case 'i': + if (last) { + return -1; + } + goto DI; + default: + return -1; + } + +DA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto DAT; + case 't': + if (last) { + return -1; + } + goto DAT; + default: + return -1; + } + +DAT: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 28; + } + goto DATE; + case 'e': + if (last) { + return 28; + } + goto DATE; + default: + return -1; + } + +DE: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto DES; + case 's': + if (last) { + return -1; + } + goto DES; + default: + return -1; + } + +DES: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto DEST; + case 't': + if (last) { + return -1; + } + goto DEST; + default: + return -1; + } + +DEST: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto DESTI; + case 'i': + if (last) { + return -1; + } + goto DESTI; + default: + return -1; + } + +DESTI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto DESTIN; + case 'n': + if (last) { + return -1; + } + goto DESTIN; + default: + return -1; + } + +DESTIN: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto DESTINA; + case 'a': + if (last) { + return -1; + } + goto DESTINA; + default: + return -1; + } + +DESTINA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto DESTINAT; + case 't': + if (last) { + return -1; + } + goto DESTINAT; + default: + return -1; + } + +DESTINAT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto DESTINATI; + case 'i': + if (last) { + return -1; + } + goto DESTINATI; + default: + return -1; + } + +DESTINATI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto DESTINATIO; + case 'o': + if (last) { + return -1; + } + goto DESTINATIO; + default: + return -1; + } + +DESTINATIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 29; + } + goto DESTINATION; + case 'n': + if (last) { + return 29; + } + goto DESTINATION; + default: + return -1; + } + +DI: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto DIG; + case 'g': + if (last) { + return -1; + } + goto DIG; + default: + return -1; + } + +DIG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto DIGE; + case 'e': + if (last) { + return -1; + } + goto DIGE; + default: + return -1; + } + +DIGE: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto DIGES; + case 's': + if (last) { + return -1; + } + goto DIGES; + default: + return -1; + } + +DIGES: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return 30; + } + goto DIGEST; + case 't': + if (last) { + return 30; + } + goto DIGEST; + default: + return -1; + } + +E: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto ET; + case 't': + if (last) { + return -1; + } + goto ET; + case 'X': + if (last) { + return -1; + } + goto EX; + case 'x': + if (last) { + return -1; + } + goto EX; + default: + return -1; + } + +ET: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto ETA; + case 'a': + if (last) { + return -1; + } + goto ETA; + default: + return -1; + } + +ETA: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return 31; + } + goto ETAG; + case 'g': + if (last) { + return 31; + } + goto ETAG; + default: + return -1; + } + +EX: + NEXT_CHAR(); + switch (ch) { + case 'P': + if (last) { + return -1; + } + goto EXP; + case 'p': + if (last) { + return -1; + } + goto EXP; + default: + return -1; + } + +EXP: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto EXPE; + case 'e': + if (last) { + return -1; + } + goto EXPE; + case 'I': + if (last) { + return -1; + } + goto EXPI; + case 'i': + if (last) { + return -1; + } + goto EXPI; + default: + return -1; + } + +EXPE: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto EXPEC; + case 'c': + if (last) { + return -1; + } + goto EXPEC; + default: + return -1; + } + +EXPEC: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return 32; + } + goto EXPECT; + case 't': + if (last) { + return 32; + } + goto EXPECT; + default: + return -1; + } + +EXPI: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto EXPIR; + case 'r': + if (last) { + return -1; + } + goto EXPIR; + default: + return -1; + } + +EXPIR: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto EXPIRE; + case 'e': + if (last) { + return -1; + } + goto EXPIRE; + default: + return -1; + } + +EXPIRE: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return 33; + } + goto EXPIRES; + case 's': + if (last) { + return 33; + } + goto EXPIRES; + default: + return -1; + } + +F: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto FO; + case 'o': + if (last) { + return -1; + } + goto FO; + case 'R': + if (last) { + return -1; + } + goto FR; + case 'r': + if (last) { + return -1; + } + goto FR; + default: + return -1; + } + +FO: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto FOR; + case 'r': + if (last) { + return -1; + } + goto FOR; + default: + return -1; + } + +FOR: + NEXT_CHAR(); + switch (ch) { + case 'W': + if (last) { + return -1; + } + goto FORW; + case 'w': + if (last) { + return -1; + } + goto FORW; + default: + return -1; + } + +FORW: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto FORWA; + case 'a': + if (last) { + return -1; + } + goto FORWA; + default: + return -1; + } + +FORWA: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto FORWAR; + case 'r': + if (last) { + return -1; + } + goto FORWAR; + default: + return -1; + } + +FORWAR: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto FORWARD; + case 'd': + if (last) { + return -1; + } + goto FORWARD; + default: + return -1; + } + +FORWARD: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto FORWARDE; + case 'e': + if (last) { + return -1; + } + goto FORWARDE; + default: + return -1; + } + +FORWARDE: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return 34; + } + goto FORWARDED; + case 'd': + if (last) { + return 34; + } + goto FORWARDED; + default: + return -1; + } + +FR: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto FRO; + case 'o': + if (last) { + return -1; + } + goto FRO; + default: + return -1; + } + +FRO: + NEXT_CHAR(); + switch (ch) { + case 'M': + if (last) { + return 35; + } + goto FROM; + case 'm': + if (last) { + return 35; + } + goto FROM; + default: + return -1; + } + +H: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto HO; + case 'o': + if (last) { + return -1; + } + goto HO; + default: + return -1; + } + +HO: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto HOS; + case 's': + if (last) { + return -1; + } + goto HOS; + default: + return -1; + } + +HOS: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return 36; + } + goto HOST; + case 't': + if (last) { + return 36; + } + goto HOST; + default: + return -1; + } + +I: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto IF; + case 'f': + if (last) { + return -1; + } + goto IF; + default: + return -1; + } + +IF: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto IF_; + default: + return -1; + } + +IF_: + NEXT_CHAR(); + switch (ch) { + case 'M': + if (last) { + return -1; + } + goto IF_M; + case 'm': + if (last) { + return -1; + } + goto IF_M; + case 'N': + if (last) { + return -1; + } + goto IF_N; + case 'n': + if (last) { + return -1; + } + goto IF_N; + case 'R': + if (last) { + return -1; + } + goto IF_R; + case 'r': + if (last) { + return -1; + } + goto IF_R; + case 'U': + if (last) { + return -1; + } + goto IF_U; + case 'u': + if (last) { + return -1; + } + goto IF_U; + default: + return -1; + } + +IF_M: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto IF_MA; + case 'a': + if (last) { + return -1; + } + goto IF_MA; + case 'O': + if (last) { + return -1; + } + goto IF_MO; + case 'o': + if (last) { + return -1; + } + goto IF_MO; + default: + return -1; + } + +IF_MA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto IF_MAT; + case 't': + if (last) { + return -1; + } + goto IF_MAT; + default: + return -1; + } + +IF_MAT: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto IF_MATC; + case 'c': + if (last) { + return -1; + } + goto IF_MATC; + default: + return -1; + } + +IF_MATC: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return 37; + } + goto IF_MATCH; + case 'h': + if (last) { + return 37; + } + goto IF_MATCH; + default: + return -1; + } + +IF_MO: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto IF_MOD; + case 'd': + if (last) { + return -1; + } + goto IF_MOD; + default: + return -1; + } + +IF_MOD: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto IF_MODI; + case 'i': + if (last) { + return -1; + } + goto IF_MODI; + default: + return -1; + } + +IF_MODI: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto IF_MODIF; + case 'f': + if (last) { + return -1; + } + goto IF_MODIF; + default: + return -1; + } + +IF_MODIF: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto IF_MODIFI; + case 'i': + if (last) { + return -1; + } + goto IF_MODIFI; + default: + return -1; + } + +IF_MODIFI: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto IF_MODIFIE; + case 'e': + if (last) { + return -1; + } + goto IF_MODIFIE; + default: + return -1; + } + +IF_MODIFIE: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto IF_MODIFIED; + case 'd': + if (last) { + return -1; + } + goto IF_MODIFIED; + default: + return -1; + } + +IF_MODIFIED: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto IF_MODIFIED_; + default: + return -1; + } + +IF_MODIFIED_: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto IF_MODIFIED_S; + case 's': + if (last) { + return -1; + } + goto IF_MODIFIED_S; + default: + return -1; + } + +IF_MODIFIED_S: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto IF_MODIFIED_SI; + case 'i': + if (last) { + return -1; + } + goto IF_MODIFIED_SI; + default: + return -1; + } + +IF_MODIFIED_SI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto IF_MODIFIED_SIN; + case 'n': + if (last) { + return -1; + } + goto IF_MODIFIED_SIN; + default: + return -1; + } + +IF_MODIFIED_SIN: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto IF_MODIFIED_SINC; + case 'c': + if (last) { + return -1; + } + goto IF_MODIFIED_SINC; + default: + return -1; + } + +IF_MODIFIED_SINC: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 38; + } + goto IF_MODIFIED_SINCE; + case 'e': + if (last) { + return 38; + } + goto IF_MODIFIED_SINCE; + default: + return -1; + } + +IF_N: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto IF_NO; + case 'o': + if (last) { + return -1; + } + goto IF_NO; + default: + return -1; + } + +IF_NO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto IF_NON; + case 'n': + if (last) { + return -1; + } + goto IF_NON; + default: + return -1; + } + +IF_NON: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto IF_NONE; + case 'e': + if (last) { + return -1; + } + goto IF_NONE; + default: + return -1; + } + +IF_NONE: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto IF_NONE_; + default: + return -1; + } + +IF_NONE_: + NEXT_CHAR(); + switch (ch) { + case 'M': + if (last) { + return -1; + } + goto IF_NONE_M; + case 'm': + if (last) { + return -1; + } + goto IF_NONE_M; + default: + return -1; + } + +IF_NONE_M: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto IF_NONE_MA; + case 'a': + if (last) { + return -1; + } + goto IF_NONE_MA; + default: + return -1; + } + +IF_NONE_MA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto IF_NONE_MAT; + case 't': + if (last) { + return -1; + } + goto IF_NONE_MAT; + default: + return -1; + } + +IF_NONE_MAT: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto IF_NONE_MATC; + case 'c': + if (last) { + return -1; + } + goto IF_NONE_MATC; + default: + return -1; + } + +IF_NONE_MATC: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return 39; + } + goto IF_NONE_MATCH; + case 'h': + if (last) { + return 39; + } + goto IF_NONE_MATCH; + default: + return -1; + } + +IF_R: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto IF_RA; + case 'a': + if (last) { + return -1; + } + goto IF_RA; + default: + return -1; + } + +IF_RA: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto IF_RAN; + case 'n': + if (last) { + return -1; + } + goto IF_RAN; + default: + return -1; + } + +IF_RAN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto IF_RANG; + case 'g': + if (last) { + return -1; + } + goto IF_RANG; + default: + return -1; + } + +IF_RANG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 40; + } + goto IF_RANGE; + case 'e': + if (last) { + return 40; + } + goto IF_RANGE; + default: + return -1; + } + +IF_U: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto IF_UN; + case 'n': + if (last) { + return -1; + } + goto IF_UN; + default: + return -1; + } + +IF_UN: + NEXT_CHAR(); + switch (ch) { + case 'M': + if (last) { + return -1; + } + goto IF_UNM; + case 'm': + if (last) { + return -1; + } + goto IF_UNM; + default: + return -1; + } + +IF_UNM: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto IF_UNMO; + case 'o': + if (last) { + return -1; + } + goto IF_UNMO; + default: + return -1; + } + +IF_UNMO: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto IF_UNMOD; + case 'd': + if (last) { + return -1; + } + goto IF_UNMOD; + default: + return -1; + } + +IF_UNMOD: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto IF_UNMODI; + case 'i': + if (last) { + return -1; + } + goto IF_UNMODI; + default: + return -1; + } + +IF_UNMODI: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto IF_UNMODIF; + case 'f': + if (last) { + return -1; + } + goto IF_UNMODIF; + default: + return -1; + } + +IF_UNMODIF: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto IF_UNMODIFI; + case 'i': + if (last) { + return -1; + } + goto IF_UNMODIFI; + default: + return -1; + } + +IF_UNMODIFI: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto IF_UNMODIFIE; + case 'e': + if (last) { + return -1; + } + goto IF_UNMODIFIE; + default: + return -1; + } + +IF_UNMODIFIE: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto IF_UNMODIFIED; + case 'd': + if (last) { + return -1; + } + goto IF_UNMODIFIED; + default: + return -1; + } + +IF_UNMODIFIED: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto IF_UNMODIFIED_; + default: + return -1; + } + +IF_UNMODIFIED_: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto IF_UNMODIFIED_S; + case 's': + if (last) { + return -1; + } + goto IF_UNMODIFIED_S; + default: + return -1; + } + +IF_UNMODIFIED_S: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto IF_UNMODIFIED_SI; + case 'i': + if (last) { + return -1; + } + goto IF_UNMODIFIED_SI; + default: + return -1; + } + +IF_UNMODIFIED_SI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto IF_UNMODIFIED_SIN; + case 'n': + if (last) { + return -1; + } + goto IF_UNMODIFIED_SIN; + default: + return -1; + } + +IF_UNMODIFIED_SIN: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto IF_UNMODIFIED_SINC; + case 'c': + if (last) { + return -1; + } + goto IF_UNMODIFIED_SINC; + default: + return -1; + } + +IF_UNMODIFIED_SINC: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 41; + } + goto IF_UNMODIFIED_SINCE; + case 'e': + if (last) { + return 41; + } + goto IF_UNMODIFIED_SINCE; + default: + return -1; + } + +K: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto KE; + case 'e': + if (last) { + return -1; + } + goto KE; + default: + return -1; + } + +KE: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto KEE; + case 'e': + if (last) { + return -1; + } + goto KEE; + default: + return -1; + } + +KEE: + NEXT_CHAR(); + switch (ch) { + case 'P': + if (last) { + return -1; + } + goto KEEP; + case 'p': + if (last) { + return -1; + } + goto KEEP; + default: + return -1; + } + +KEEP: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto KEEP_; + default: + return -1; + } + +KEEP_: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto KEEP_A; + case 'a': + if (last) { + return -1; + } + goto KEEP_A; + default: + return -1; + } + +KEEP_A: + NEXT_CHAR(); + switch (ch) { + case 'L': + if (last) { + return -1; + } + goto KEEP_AL; + case 'l': + if (last) { + return -1; + } + goto KEEP_AL; + default: + return -1; + } + +KEEP_AL: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto KEEP_ALI; + case 'i': + if (last) { + return -1; + } + goto KEEP_ALI; + default: + return -1; + } + +KEEP_ALI: + NEXT_CHAR(); + switch (ch) { + case 'V': + if (last) { + return -1; + } + goto KEEP_ALIV; + case 'v': + if (last) { + return -1; + } + goto KEEP_ALIV; + default: + return -1; + } + +KEEP_ALIV: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 42; + } + goto KEEP_ALIVE; + case 'e': + if (last) { + return 42; + } + goto KEEP_ALIVE; + default: + return -1; + } + +L: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto LA; + case 'a': + if (last) { + return -1; + } + goto LA; + case 'I': + if (last) { + return -1; + } + goto LI; + case 'i': + if (last) { + return -1; + } + goto LI; + case 'O': + if (last) { + return -1; + } + goto LO; + case 'o': + if (last) { + return -1; + } + goto LO; + default: + return -1; + } + +LA: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto LAS; + case 's': + if (last) { + return -1; + } + goto LAS; + default: + return -1; + } + +LAS: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto LAST; + case 't': + if (last) { + return -1; + } + goto LAST; + default: + return -1; + } + +LAST: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto LAST_; + default: + return -1; + } + +LAST_: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto LAST_E; + case 'e': + if (last) { + return -1; + } + goto LAST_E; + case 'M': + if (last) { + return -1; + } + goto LAST_M; + case 'm': + if (last) { + return -1; + } + goto LAST_M; + default: + return -1; + } + +LAST_E: + NEXT_CHAR(); + switch (ch) { + case 'V': + if (last) { + return -1; + } + goto LAST_EV; + case 'v': + if (last) { + return -1; + } + goto LAST_EV; + default: + return -1; + } + +LAST_EV: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto LAST_EVE; + case 'e': + if (last) { + return -1; + } + goto LAST_EVE; + default: + return -1; + } + +LAST_EVE: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto LAST_EVEN; + case 'n': + if (last) { + return -1; + } + goto LAST_EVEN; + default: + return -1; + } + +LAST_EVEN: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto LAST_EVENT; + case 't': + if (last) { + return -1; + } + goto LAST_EVENT; + default: + return -1; + } + +LAST_EVENT: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto LAST_EVENT_; + default: + return -1; + } + +LAST_EVENT_: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto LAST_EVENT_I; + case 'i': + if (last) { + return -1; + } + goto LAST_EVENT_I; + default: + return -1; + } + +LAST_EVENT_I: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return 43; + } + goto LAST_EVENT_ID; + case 'd': + if (last) { + return 43; + } + goto LAST_EVENT_ID; + default: + return -1; + } + +LAST_M: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto LAST_MO; + case 'o': + if (last) { + return -1; + } + goto LAST_MO; + default: + return -1; + } + +LAST_MO: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto LAST_MOD; + case 'd': + if (last) { + return -1; + } + goto LAST_MOD; + default: + return -1; + } + +LAST_MOD: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto LAST_MODI; + case 'i': + if (last) { + return -1; + } + goto LAST_MODI; + default: + return -1; + } + +LAST_MODI: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto LAST_MODIF; + case 'f': + if (last) { + return -1; + } + goto LAST_MODIF; + default: + return -1; + } + +LAST_MODIF: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto LAST_MODIFI; + case 'i': + if (last) { + return -1; + } + goto LAST_MODIFI; + default: + return -1; + } + +LAST_MODIFI: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto LAST_MODIFIE; + case 'e': + if (last) { + return -1; + } + goto LAST_MODIFIE; + default: + return -1; + } + +LAST_MODIFIE: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return 44; + } + goto LAST_MODIFIED; + case 'd': + if (last) { + return 44; + } + goto LAST_MODIFIED; + default: + return -1; + } + +LI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto LIN; + case 'n': + if (last) { + return -1; + } + goto LIN; + default: + return -1; + } + +LIN: + NEXT_CHAR(); + switch (ch) { + case 'K': + if (last) { + return 45; + } + goto LINK; + case 'k': + if (last) { + return 45; + } + goto LINK; + default: + return -1; + } + +LO: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto LOC; + case 'c': + if (last) { + return -1; + } + goto LOC; + default: + return -1; + } + +LOC: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto LOCA; + case 'a': + if (last) { + return -1; + } + goto LOCA; + default: + return -1; + } + +LOCA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto LOCAT; + case 't': + if (last) { + return -1; + } + goto LOCAT; + default: + return -1; + } + +LOCAT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto LOCATI; + case 'i': + if (last) { + return -1; + } + goto LOCATI; + default: + return -1; + } + +LOCATI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto LOCATIO; + case 'o': + if (last) { + return -1; + } + goto LOCATIO; + default: + return -1; + } + +LOCATIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 46; + } + goto LOCATION; + case 'n': + if (last) { + return 46; + } + goto LOCATION; + default: + return -1; + } + +M: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto MA; + case 'a': + if (last) { + return -1; + } + goto MA; + default: + return -1; + } + +MA: + NEXT_CHAR(); + switch (ch) { + case 'X': + if (last) { + return -1; + } + goto MAX; + case 'x': + if (last) { + return -1; + } + goto MAX; + default: + return -1; + } + +MAX: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto MAX_; + default: + return -1; + } + +MAX_: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto MAX_F; + case 'f': + if (last) { + return -1; + } + goto MAX_F; + default: + return -1; + } + +MAX_F: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto MAX_FO; + case 'o': + if (last) { + return -1; + } + goto MAX_FO; + default: + return -1; + } + +MAX_FO: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto MAX_FOR; + case 'r': + if (last) { + return -1; + } + goto MAX_FOR; + default: + return -1; + } + +MAX_FOR: + NEXT_CHAR(); + switch (ch) { + case 'W': + if (last) { + return -1; + } + goto MAX_FORW; + case 'w': + if (last) { + return -1; + } + goto MAX_FORW; + default: + return -1; + } + +MAX_FORW: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto MAX_FORWA; + case 'a': + if (last) { + return -1; + } + goto MAX_FORWA; + default: + return -1; + } + +MAX_FORWA: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto MAX_FORWAR; + case 'r': + if (last) { + return -1; + } + goto MAX_FORWAR; + default: + return -1; + } + +MAX_FORWAR: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto MAX_FORWARD; + case 'd': + if (last) { + return -1; + } + goto MAX_FORWARD; + default: + return -1; + } + +MAX_FORWARD: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return 47; + } + goto MAX_FORWARDS; + case 's': + if (last) { + return 47; + } + goto MAX_FORWARDS; + default: + return -1; + } + +O: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto OR; + case 'r': + if (last) { + return -1; + } + goto OR; + default: + return -1; + } + +OR: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto ORI; + case 'i': + if (last) { + return -1; + } + goto ORI; + default: + return -1; + } + +ORI: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto ORIG; + case 'g': + if (last) { + return -1; + } + goto ORIG; + default: + return -1; + } + +ORIG: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto ORIGI; + case 'i': + if (last) { + return -1; + } + goto ORIGI; + default: + return -1; + } + +ORIGI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 48; + } + goto ORIGIN; + case 'n': + if (last) { + return 48; + } + goto ORIGIN; + default: + return -1; + } + +P: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto PR; + case 'r': + if (last) { + return -1; + } + goto PR; + default: + return -1; + } + +PR: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto PRA; + case 'a': + if (last) { + return -1; + } + goto PRA; + case 'O': + if (last) { + return -1; + } + goto PRO; + case 'o': + if (last) { + return -1; + } + goto PRO; + default: + return -1; + } + +PRA: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto PRAG; + case 'g': + if (last) { + return -1; + } + goto PRAG; + default: + return -1; + } + +PRAG: + NEXT_CHAR(); + switch (ch) { + case 'M': + if (last) { + return -1; + } + goto PRAGM; + case 'm': + if (last) { + return -1; + } + goto PRAGM; + default: + return -1; + } + +PRAGM: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return 49; + } + goto PRAGMA; + case 'a': + if (last) { + return 49; + } + goto PRAGMA; + default: + return -1; + } + +PRO: + NEXT_CHAR(); + switch (ch) { + case 'X': + if (last) { + return -1; + } + goto PROX; + case 'x': + if (last) { + return -1; + } + goto PROX; + default: + return -1; + } + +PROX: + NEXT_CHAR(); + switch (ch) { + case 'Y': + if (last) { + return -1; + } + goto PROXY; + case 'y': + if (last) { + return -1; + } + goto PROXY; + default: + return -1; + } + +PROXY: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto PROXY_; + default: + return -1; + } + +PROXY_: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto PROXY_A; + case 'a': + if (last) { + return -1; + } + goto PROXY_A; + default: + return -1; + } + +PROXY_A: + NEXT_CHAR(); + switch (ch) { + case 'U': + if (last) { + return -1; + } + goto PROXY_AU; + case 'u': + if (last) { + return -1; + } + goto PROXY_AU; + default: + return -1; + } + +PROXY_AU: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto PROXY_AUT; + case 't': + if (last) { + return -1; + } + goto PROXY_AUT; + default: + return -1; + } + +PROXY_AUT: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return -1; + } + goto PROXY_AUTH; + case 'h': + if (last) { + return -1; + } + goto PROXY_AUTH; + default: + return -1; + } + +PROXY_AUTH: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto PROXY_AUTHE; + case 'e': + if (last) { + return -1; + } + goto PROXY_AUTHE; + case 'O': + if (last) { + return -1; + } + goto PROXY_AUTHO; + case 'o': + if (last) { + return -1; + } + goto PROXY_AUTHO; + default: + return -1; + } + +PROXY_AUTHE: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto PROXY_AUTHEN; + case 'n': + if (last) { + return -1; + } + goto PROXY_AUTHEN; + default: + return -1; + } + +PROXY_AUTHEN: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto PROXY_AUTHENT; + case 't': + if (last) { + return -1; + } + goto PROXY_AUTHENT; + default: + return -1; + } + +PROXY_AUTHENT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto PROXY_AUTHENTI; + case 'i': + if (last) { + return -1; + } + goto PROXY_AUTHENTI; + default: + return -1; + } + +PROXY_AUTHENTI: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto PROXY_AUTHENTIC; + case 'c': + if (last) { + return -1; + } + goto PROXY_AUTHENTIC; + default: + return -1; + } + +PROXY_AUTHENTIC: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto PROXY_AUTHENTICA; + case 'a': + if (last) { + return -1; + } + goto PROXY_AUTHENTICA; + default: + return -1; + } + +PROXY_AUTHENTICA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto PROXY_AUTHENTICAT; + case 't': + if (last) { + return -1; + } + goto PROXY_AUTHENTICAT; + default: + return -1; + } + +PROXY_AUTHENTICAT: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 50; + } + goto PROXY_AUTHENTICATE; + case 'e': + if (last) { + return 50; + } + goto PROXY_AUTHENTICATE; + default: + return -1; + } + +PROXY_AUTHO: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto PROXY_AUTHOR; + case 'r': + if (last) { + return -1; + } + goto PROXY_AUTHOR; + default: + return -1; + } + +PROXY_AUTHOR: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto PROXY_AUTHORI; + case 'i': + if (last) { + return -1; + } + goto PROXY_AUTHORI; + default: + return -1; + } + +PROXY_AUTHORI: + NEXT_CHAR(); + switch (ch) { + case 'Z': + if (last) { + return -1; + } + goto PROXY_AUTHORIZ; + case 'z': + if (last) { + return -1; + } + goto PROXY_AUTHORIZ; + default: + return -1; + } + +PROXY_AUTHORIZ: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto PROXY_AUTHORIZA; + case 'a': + if (last) { + return -1; + } + goto PROXY_AUTHORIZA; + default: + return -1; + } + +PROXY_AUTHORIZA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto PROXY_AUTHORIZAT; + case 't': + if (last) { + return -1; + } + goto PROXY_AUTHORIZAT; + default: + return -1; + } + +PROXY_AUTHORIZAT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto PROXY_AUTHORIZATI; + case 'i': + if (last) { + return -1; + } + goto PROXY_AUTHORIZATI; + default: + return -1; + } + +PROXY_AUTHORIZATI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto PROXY_AUTHORIZATIO; + case 'o': + if (last) { + return -1; + } + goto PROXY_AUTHORIZATIO; + default: + return -1; + } + +PROXY_AUTHORIZATIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 51; + } + goto PROXY_AUTHORIZATION; + case 'n': + if (last) { + return 51; + } + goto PROXY_AUTHORIZATION; + default: + return -1; + } + +R: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto RA; + case 'a': + if (last) { + return -1; + } + goto RA; + case 'E': + if (last) { + return -1; + } + goto RE; + case 'e': + if (last) { + return -1; + } + goto RE; + default: + return -1; + } + +RA: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto RAN; + case 'n': + if (last) { + return -1; + } + goto RAN; + default: + return -1; + } + +RAN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto RANG; + case 'g': + if (last) { + return -1; + } + goto RANG; + default: + return -1; + } + +RANG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 52; + } + goto RANGE; + case 'e': + if (last) { + return 52; + } + goto RANGE; + default: + return -1; + } + +RE: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto REF; + case 'f': + if (last) { + return -1; + } + goto REF; + case 'T': + if (last) { + return -1; + } + goto RET; + case 't': + if (last) { + return -1; + } + goto RET; + default: + return -1; + } + +REF: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto REFE; + case 'e': + if (last) { + return -1; + } + goto REFE; + default: + return -1; + } + +REFE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto REFER; + case 'r': + if (last) { + return -1; + } + goto REFER; + default: + return -1; + } + +REFER: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto REFERE; + case 'e': + if (last) { + return -1; + } + goto REFERE; + default: + return -1; + } + +REFERE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return 53; + } + goto REFERER; + case 'r': + if (last) { + return 53; + } + goto REFERER; + default: + return -1; + } + +RET: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto RETR; + case 'r': + if (last) { + return -1; + } + goto RETR; + default: + return -1; + } + +RETR: + NEXT_CHAR(); + switch (ch) { + case 'Y': + if (last) { + return -1; + } + goto RETRY; + case 'y': + if (last) { + return -1; + } + goto RETRY; + default: + return -1; + } + +RETRY: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto RETRY_; + default: + return -1; + } + +RETRY_: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto RETRY_A; + case 'a': + if (last) { + return -1; + } + goto RETRY_A; + default: + return -1; + } + +RETRY_A: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto RETRY_AF; + case 'f': + if (last) { + return -1; + } + goto RETRY_AF; + default: + return -1; + } + +RETRY_AF: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto RETRY_AFT; + case 't': + if (last) { + return -1; + } + goto RETRY_AFT; + default: + return -1; + } + +RETRY_AFT: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto RETRY_AFTE; + case 'e': + if (last) { + return -1; + } + goto RETRY_AFTE; + default: + return -1; + } + +RETRY_AFTE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return 54; + } + goto RETRY_AFTER; + case 'r': + if (last) { + return 54; + } + goto RETRY_AFTER; + default: + return -1; + } + +S: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto SE; + case 'e': + if (last) { + return -1; + } + goto SE; + default: + return -1; + } + +SE: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto SEC; + case 'c': + if (last) { + return -1; + } + goto SEC; + case 'R': + if (last) { + return -1; + } + goto SER; + case 'r': + if (last) { + return -1; + } + goto SER; + case 'T': + if (last) { + return -1; + } + goto SET; + case 't': + if (last) { + return -1; + } + goto SET; + default: + return -1; + } + +SEC: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto SEC_; + default: + return -1; + } + +SEC_: + NEXT_CHAR(); + switch (ch) { + case 'W': + if (last) { + return -1; + } + goto SEC_W; + case 'w': + if (last) { + return -1; + } + goto SEC_W; + default: + return -1; + } + +SEC_W: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto SEC_WE; + case 'e': + if (last) { + return -1; + } + goto SEC_WE; + default: + return -1; + } + +SEC_WE: + NEXT_CHAR(); + switch (ch) { + case 'B': + if (last) { + return -1; + } + goto SEC_WEB; + case 'b': + if (last) { + return -1; + } + goto SEC_WEB; + default: + return -1; + } + +SEC_WEB: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto SEC_WEBS; + case 's': + if (last) { + return -1; + } + goto SEC_WEBS; + default: + return -1; + } + +SEC_WEBS: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto SEC_WEBSO; + case 'o': + if (last) { + return -1; + } + goto SEC_WEBSO; + default: + return -1; + } + +SEC_WEBSO: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto SEC_WEBSOC; + case 'c': + if (last) { + return -1; + } + goto SEC_WEBSOC; + default: + return -1; + } + +SEC_WEBSOC: + NEXT_CHAR(); + switch (ch) { + case 'K': + if (last) { + return -1; + } + goto SEC_WEBSOCK; + case 'k': + if (last) { + return -1; + } + goto SEC_WEBSOCK; + default: + return -1; + } + +SEC_WEBSOCK: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto SEC_WEBSOCKE; + case 'e': + if (last) { + return -1; + } + goto SEC_WEBSOCKE; + default: + return -1; + } + +SEC_WEBSOCKE: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto SEC_WEBSOCKET; + case 't': + if (last) { + return -1; + } + goto SEC_WEBSOCKET; + default: + return -1; + } + +SEC_WEBSOCKET: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_; + default: + return -1; + } + +SEC_WEBSOCKET_: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_A; + case 'a': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_A; + case 'E': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_E; + case 'e': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_E; + case 'K': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_K; + case 'k': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_K; + case 'P': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_P; + case 'p': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_P; + case 'V': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_V; + case 'v': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_V; + default: + return -1; + } + +SEC_WEBSOCKET_A: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_AC; + case 'c': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_AC; + default: + return -1; + } + +SEC_WEBSOCKET_AC: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_ACC; + case 'c': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_ACC; + default: + return -1; + } + +SEC_WEBSOCKET_ACC: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_ACCE; + case 'e': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_ACCE; + default: + return -1; + } + +SEC_WEBSOCKET_ACCE: + NEXT_CHAR(); + switch (ch) { + case 'P': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_ACCEP; + case 'p': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_ACCEP; + default: + return -1; + } + +SEC_WEBSOCKET_ACCEP: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return 55; + } + goto SEC_WEBSOCKET_ACCEPT; + case 't': + if (last) { + return 55; + } + goto SEC_WEBSOCKET_ACCEPT; + default: + return -1; + } + +SEC_WEBSOCKET_E: + NEXT_CHAR(); + switch (ch) { + case 'X': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EX; + case 'x': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EX; + default: + return -1; + } + +SEC_WEBSOCKET_EX: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXT; + case 't': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXT; + default: + return -1; + } + +SEC_WEBSOCKET_EXT: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTE; + case 'e': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTE; + default: + return -1; + } + +SEC_WEBSOCKET_EXTE: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTEN; + case 'n': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTEN; + default: + return -1; + } + +SEC_WEBSOCKET_EXTEN: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTENS; + case 's': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTENS; + default: + return -1; + } + +SEC_WEBSOCKET_EXTENS: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTENSI; + case 'i': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTENSI; + default: + return -1; + } + +SEC_WEBSOCKET_EXTENSI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTENSIO; + case 'o': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTENSIO; + default: + return -1; + } + +SEC_WEBSOCKET_EXTENSIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTENSION; + case 'n': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_EXTENSION; + default: + return -1; + } + +SEC_WEBSOCKET_EXTENSION: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return 56; + } + goto SEC_WEBSOCKET_EXTENSIONS; + case 's': + if (last) { + return 56; + } + goto SEC_WEBSOCKET_EXTENSIONS; + default: + return -1; + } + +SEC_WEBSOCKET_K: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_KE; + case 'e': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_KE; + default: + return -1; + } + +SEC_WEBSOCKET_KE: + NEXT_CHAR(); + switch (ch) { + case 'Y': + if (last) { + return 57; + } + goto SEC_WEBSOCKET_KEY; + case 'y': + if (last) { + return 57; + } + goto SEC_WEBSOCKET_KEY; + default: + return -1; + } + +SEC_WEBSOCKET_KEY: + NEXT_CHAR(); + switch (ch) { + case '1': + if (last) { + return 58; + } + goto SEC_WEBSOCKET_KEY1; + default: + return -1; + } + +SEC_WEBSOCKET_P: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PR; + case 'r': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PR; + default: + return -1; + } + +SEC_WEBSOCKET_PR: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PRO; + case 'o': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PRO; + default: + return -1; + } + +SEC_WEBSOCKET_PRO: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PROT; + case 't': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PROT; + default: + return -1; + } + +SEC_WEBSOCKET_PROT: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PROTO; + case 'o': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PROTO; + default: + return -1; + } + +SEC_WEBSOCKET_PROTO: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PROTOC; + case 'c': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PROTOC; + default: + return -1; + } + +SEC_WEBSOCKET_PROTOC: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PROTOCO; + case 'o': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_PROTOCO; + default: + return -1; + } + +SEC_WEBSOCKET_PROTOCO: + NEXT_CHAR(); + switch (ch) { + case 'L': + if (last) { + return 59; + } + goto SEC_WEBSOCKET_PROTOCOL; + case 'l': + if (last) { + return 59; + } + goto SEC_WEBSOCKET_PROTOCOL; + default: + return -1; + } + +SEC_WEBSOCKET_V: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VE; + case 'e': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VE; + default: + return -1; + } + +SEC_WEBSOCKET_VE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VER; + case 'r': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VER; + default: + return -1; + } + +SEC_WEBSOCKET_VER: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VERS; + case 's': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VERS; + default: + return -1; + } + +SEC_WEBSOCKET_VERS: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VERSI; + case 'i': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VERSI; + default: + return -1; + } + +SEC_WEBSOCKET_VERSI: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VERSIO; + case 'o': + if (last) { + return -1; + } + goto SEC_WEBSOCKET_VERSIO; + default: + return -1; + } + +SEC_WEBSOCKET_VERSIO: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return 60; + } + goto SEC_WEBSOCKET_VERSION; + case 'n': + if (last) { + return 60; + } + goto SEC_WEBSOCKET_VERSION; + default: + return -1; + } + +SER: + NEXT_CHAR(); + switch (ch) { + case 'V': + if (last) { + return -1; + } + goto SERV; + case 'v': + if (last) { + return -1; + } + goto SERV; + default: + return -1; + } + +SERV: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto SERVE; + case 'e': + if (last) { + return -1; + } + goto SERVE; + default: + return -1; + } + +SERVE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return 61; + } + goto SERVER; + case 'r': + if (last) { + return 61; + } + goto SERVER; + default: + return -1; + } + +SET: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto SET_; + default: + return -1; + } + +SET_: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto SET_C; + case 'c': + if (last) { + return -1; + } + goto SET_C; + default: + return -1; + } + +SET_C: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto SET_CO; + case 'o': + if (last) { + return -1; + } + goto SET_CO; + default: + return -1; + } + +SET_CO: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto SET_COO; + case 'o': + if (last) { + return -1; + } + goto SET_COO; + default: + return -1; + } + +SET_COO: + NEXT_CHAR(); + switch (ch) { + case 'K': + if (last) { + return -1; + } + goto SET_COOK; + case 'k': + if (last) { + return -1; + } + goto SET_COOK; + default: + return -1; + } + +SET_COOK: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto SET_COOKI; + case 'i': + if (last) { + return -1; + } + goto SET_COOKI; + default: + return -1; + } + +SET_COOKI: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 62; + } + goto SET_COOKIE; + case 'e': + if (last) { + return 62; + } + goto SET_COOKIE; + default: + return -1; + } + +T: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 63; + } + goto TE; + case 'e': + if (last) { + return 63; + } + goto TE; + case 'R': + if (last) { + return -1; + } + goto TR; + case 'r': + if (last) { + return -1; + } + goto TR; + default: + return -1; + } + +TR: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto TRA; + case 'a': + if (last) { + return -1; + } + goto TRA; + default: + return -1; + } + +TRA: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto TRAI; + case 'i': + if (last) { + return -1; + } + goto TRAI; + case 'N': + if (last) { + return -1; + } + goto TRAN; + case 'n': + if (last) { + return -1; + } + goto TRAN; + default: + return -1; + } + +TRAI: + NEXT_CHAR(); + switch (ch) { + case 'L': + if (last) { + return -1; + } + goto TRAIL; + case 'l': + if (last) { + return -1; + } + goto TRAIL; + default: + return -1; + } + +TRAIL: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto TRAILE; + case 'e': + if (last) { + return -1; + } + goto TRAILE; + default: + return -1; + } + +TRAILE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return 64; + } + goto TRAILER; + case 'r': + if (last) { + return 64; + } + goto TRAILER; + default: + return -1; + } + +TRAN: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto TRANS; + case 's': + if (last) { + return -1; + } + goto TRANS; + default: + return -1; + } + +TRANS: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto TRANSF; + case 'f': + if (last) { + return -1; + } + goto TRANSF; + default: + return -1; + } + +TRANSF: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto TRANSFE; + case 'e': + if (last) { + return -1; + } + goto TRANSFE; + default: + return -1; + } + +TRANSFE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto TRANSFER; + case 'r': + if (last) { + return -1; + } + goto TRANSFER; + default: + return -1; + } + +TRANSFER: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto TRANSFER_; + default: + return -1; + } + +TRANSFER_: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto TRANSFER_E; + case 'e': + if (last) { + return -1; + } + goto TRANSFER_E; + default: + return -1; + } + +TRANSFER_E: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto TRANSFER_EN; + case 'n': + if (last) { + return -1; + } + goto TRANSFER_EN; + default: + return -1; + } + +TRANSFER_EN: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto TRANSFER_ENC; + case 'c': + if (last) { + return -1; + } + goto TRANSFER_ENC; + default: + return -1; + } + +TRANSFER_ENC: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto TRANSFER_ENCO; + case 'o': + if (last) { + return -1; + } + goto TRANSFER_ENCO; + default: + return -1; + } + +TRANSFER_ENCO: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto TRANSFER_ENCOD; + case 'd': + if (last) { + return -1; + } + goto TRANSFER_ENCOD; + default: + return -1; + } + +TRANSFER_ENCOD: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto TRANSFER_ENCODI; + case 'i': + if (last) { + return -1; + } + goto TRANSFER_ENCODI; + default: + return -1; + } + +TRANSFER_ENCODI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto TRANSFER_ENCODIN; + case 'n': + if (last) { + return -1; + } + goto TRANSFER_ENCODIN; + default: + return -1; + } + +TRANSFER_ENCODIN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return 65; + } + goto TRANSFER_ENCODING; + case 'g': + if (last) { + return 65; + } + goto TRANSFER_ENCODING; + default: + return -1; + } + +U: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto UR; + case 'r': + if (last) { + return -1; + } + goto UR; + case 'P': + if (last) { + return -1; + } + goto UP; + case 'p': + if (last) { + return -1; + } + goto UP; + case 'S': + if (last) { + return -1; + } + goto US; + case 's': + if (last) { + return -1; + } + goto US; + default: + return -1; + } + +UR: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return 66; + } + goto URI; + case 'i': + if (last) { + return 66; + } + goto URI; + default: + return -1; + } + +UP: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto UPG; + case 'g': + if (last) { + return -1; + } + goto UPG; + default: + return -1; + } + +UPG: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto UPGR; + case 'r': + if (last) { + return -1; + } + goto UPGR; + default: + return -1; + } + +UPGR: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto UPGRA; + case 'a': + if (last) { + return -1; + } + goto UPGRA; + default: + return -1; + } + +UPGRA: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto UPGRAD; + case 'd': + if (last) { + return -1; + } + goto UPGRAD; + default: + return -1; + } + +UPGRAD: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 67; + } + goto UPGRADE; + case 'e': + if (last) { + return 67; + } + goto UPGRADE; + default: + return -1; + } + +US: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto USE; + case 'e': + if (last) { + return -1; + } + goto USE; + default: + return -1; + } + +USE: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto USER; + case 'r': + if (last) { + return -1; + } + goto USER; + default: + return -1; + } + +USER: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto USER_; + default: + return -1; + } + +USER_: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto USER_A; + case 'a': + if (last) { + return -1; + } + goto USER_A; + default: + return -1; + } + +USER_A: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto USER_AG; + case 'g': + if (last) { + return -1; + } + goto USER_AG; + default: + return -1; + } + +USER_AG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto USER_AGE; + case 'e': + if (last) { + return -1; + } + goto USER_AGE; + default: + return -1; + } + +USER_AGE: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto USER_AGEN; + case 'n': + if (last) { + return -1; + } + goto USER_AGEN; + default: + return -1; + } + +USER_AGEN: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return 68; + } + goto USER_AGENT; + case 't': + if (last) { + return 68; + } + goto USER_AGENT; + default: + return -1; + } + +V: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto VA; + case 'a': + if (last) { + return -1; + } + goto VA; + case 'I': + if (last) { + return -1; + } + goto VI; + case 'i': + if (last) { + return -1; + } + goto VI; + default: + return -1; + } + +VA: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto VAR; + case 'r': + if (last) { + return -1; + } + goto VAR; + default: + return -1; + } + +VAR: + NEXT_CHAR(); + switch (ch) { + case 'Y': + if (last) { + return 69; + } + goto VARY; + case 'y': + if (last) { + return 69; + } + goto VARY; + default: + return -1; + } + +VI: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return 70; + } + goto VIA; + case 'a': + if (last) { + return 70; + } + goto VIA; + default: + return -1; + } + +W: + NEXT_CHAR(); + switch (ch) { + case 'W': + if (last) { + return -1; + } + goto WW; + case 'w': + if (last) { + return -1; + } + goto WW; + case 'A': + if (last) { + return -1; + } + goto WA; + case 'a': + if (last) { + return -1; + } + goto WA; + default: + return -1; + } + +WW: + NEXT_CHAR(); + switch (ch) { + case 'W': + if (last) { + return -1; + } + goto WWW; + case 'w': + if (last) { + return -1; + } + goto WWW; + default: + return -1; + } + +WWW: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto WWW_; + default: + return -1; + } + +WWW_: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto WWW_A; + case 'a': + if (last) { + return -1; + } + goto WWW_A; + default: + return -1; + } + +WWW_A: + NEXT_CHAR(); + switch (ch) { + case 'U': + if (last) { + return -1; + } + goto WWW_AU; + case 'u': + if (last) { + return -1; + } + goto WWW_AU; + default: + return -1; + } + +WWW_AU: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto WWW_AUT; + case 't': + if (last) { + return -1; + } + goto WWW_AUT; + default: + return -1; + } + +WWW_AUT: + NEXT_CHAR(); + switch (ch) { + case 'H': + if (last) { + return -1; + } + goto WWW_AUTH; + case 'h': + if (last) { + return -1; + } + goto WWW_AUTH; + default: + return -1; + } + +WWW_AUTH: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto WWW_AUTHE; + case 'e': + if (last) { + return -1; + } + goto WWW_AUTHE; + default: + return -1; + } + +WWW_AUTHE: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto WWW_AUTHEN; + case 'n': + if (last) { + return -1; + } + goto WWW_AUTHEN; + default: + return -1; + } + +WWW_AUTHEN: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto WWW_AUTHENT; + case 't': + if (last) { + return -1; + } + goto WWW_AUTHENT; + default: + return -1; + } + +WWW_AUTHENT: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto WWW_AUTHENTI; + case 'i': + if (last) { + return -1; + } + goto WWW_AUTHENTI; + default: + return -1; + } + +WWW_AUTHENTI: + NEXT_CHAR(); + switch (ch) { + case 'C': + if (last) { + return -1; + } + goto WWW_AUTHENTIC; + case 'c': + if (last) { + return -1; + } + goto WWW_AUTHENTIC; + default: + return -1; + } + +WWW_AUTHENTIC: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto WWW_AUTHENTICA; + case 'a': + if (last) { + return -1; + } + goto WWW_AUTHENTICA; + default: + return -1; + } + +WWW_AUTHENTICA: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto WWW_AUTHENTICAT; + case 't': + if (last) { + return -1; + } + goto WWW_AUTHENTICAT; + default: + return -1; + } + +WWW_AUTHENTICAT: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return 71; + } + goto WWW_AUTHENTICATE; + case 'e': + if (last) { + return 71; + } + goto WWW_AUTHENTICATE; + default: + return -1; + } + +WA: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto WAN; + case 'n': + if (last) { + return -1; + } + goto WAN; + case 'R': + if (last) { + return -1; + } + goto WAR; + case 'r': + if (last) { + return -1; + } + goto WAR; + default: + return -1; + } + +WAN: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto WANT; + case 't': + if (last) { + return -1; + } + goto WANT; + default: + return -1; + } + +WANT: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto WANT_; + default: + return -1; + } + +WANT_: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto WANT_D; + case 'd': + if (last) { + return -1; + } + goto WANT_D; + default: + return -1; + } + +WANT_D: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto WANT_DI; + case 'i': + if (last) { + return -1; + } + goto WANT_DI; + default: + return -1; + } + +WANT_DI: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return -1; + } + goto WANT_DIG; + case 'g': + if (last) { + return -1; + } + goto WANT_DIG; + default: + return -1; + } + +WANT_DIG: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto WANT_DIGE; + case 'e': + if (last) { + return -1; + } + goto WANT_DIGE; + default: + return -1; + } + +WANT_DIGE: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto WANT_DIGES; + case 's': + if (last) { + return -1; + } + goto WANT_DIGES; + default: + return -1; + } + +WANT_DIGES: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return 72; + } + goto WANT_DIGEST; + case 't': + if (last) { + return 72; + } + goto WANT_DIGEST; + default: + return -1; + } + +WAR: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto WARN; + case 'n': + if (last) { + return -1; + } + goto WARN; + default: + return -1; + } + +WARN: + NEXT_CHAR(); + switch (ch) { + case 'I': + if (last) { + return -1; + } + goto WARNI; + case 'i': + if (last) { + return -1; + } + goto WARNI; + default: + return -1; + } + +WARNI: + NEXT_CHAR(); + switch (ch) { + case 'N': + if (last) { + return -1; + } + goto WARNIN; + case 'n': + if (last) { + return -1; + } + goto WARNIN; + default: + return -1; + } + +WARNIN: + NEXT_CHAR(); + switch (ch) { + case 'G': + if (last) { + return 73; + } + goto WARNING; + case 'g': + if (last) { + return 73; + } + goto WARNING; + default: + return -1; + } + +X: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto X_; + default: + return -1; + } + +X_: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto X_F; + case 'f': + if (last) { + return -1; + } + goto X_F; + default: + return -1; + } + +X_F: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto X_FO; + case 'o': + if (last) { + return -1; + } + goto X_FO; + default: + return -1; + } + +X_FO: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto X_FOR; + case 'r': + if (last) { + return -1; + } + goto X_FOR; + default: + return -1; + } + +X_FOR: + NEXT_CHAR(); + switch (ch) { + case 'W': + if (last) { + return -1; + } + goto X_FORW; + case 'w': + if (last) { + return -1; + } + goto X_FORW; + default: + return -1; + } + +X_FORW: + NEXT_CHAR(); + switch (ch) { + case 'A': + if (last) { + return -1; + } + goto X_FORWA; + case 'a': + if (last) { + return -1; + } + goto X_FORWA; + default: + return -1; + } + +X_FORWA: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto X_FORWAR; + case 'r': + if (last) { + return -1; + } + goto X_FORWAR; + default: + return -1; + } + +X_FORWAR: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto X_FORWARD; + case 'd': + if (last) { + return -1; + } + goto X_FORWARD; + default: + return -1; + } + +X_FORWARD: + NEXT_CHAR(); + switch (ch) { + case 'E': + if (last) { + return -1; + } + goto X_FORWARDE; + case 'e': + if (last) { + return -1; + } + goto X_FORWARDE; + default: + return -1; + } + +X_FORWARDE: + NEXT_CHAR(); + switch (ch) { + case 'D': + if (last) { + return -1; + } + goto X_FORWARDED; + case 'd': + if (last) { + return -1; + } + goto X_FORWARDED; + default: + return -1; + } + +X_FORWARDED: + NEXT_CHAR(); + switch (ch) { + case '-': + if (last) { + return -1; + } + goto X_FORWARDED_; + default: + return -1; + } + +X_FORWARDED_: + NEXT_CHAR(); + switch (ch) { + case 'F': + if (last) { + return -1; + } + goto X_FORWARDED_F; + case 'f': + if (last) { + return -1; + } + goto X_FORWARDED_F; + case 'H': + if (last) { + return -1; + } + goto X_FORWARDED_H; + case 'h': + if (last) { + return -1; + } + goto X_FORWARDED_H; + case 'P': + if (last) { + return -1; + } + goto X_FORWARDED_P; + case 'p': + if (last) { + return -1; + } + goto X_FORWARDED_P; + default: + return -1; + } + +X_FORWARDED_F: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto X_FORWARDED_FO; + case 'o': + if (last) { + return -1; + } + goto X_FORWARDED_FO; + default: + return -1; + } + +X_FORWARDED_FO: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return 74; + } + goto X_FORWARDED_FOR; + case 'r': + if (last) { + return 74; + } + goto X_FORWARDED_FOR; + default: + return -1; + } + +X_FORWARDED_H: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto X_FORWARDED_HO; + case 'o': + if (last) { + return -1; + } + goto X_FORWARDED_HO; + default: + return -1; + } + +X_FORWARDED_HO: + NEXT_CHAR(); + switch (ch) { + case 'S': + if (last) { + return -1; + } + goto X_FORWARDED_HOS; + case 's': + if (last) { + return -1; + } + goto X_FORWARDED_HOS; + default: + return -1; + } + +X_FORWARDED_HOS: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return 75; + } + goto X_FORWARDED_HOST; + case 't': + if (last) { + return 75; + } + goto X_FORWARDED_HOST; + default: + return -1; + } + +X_FORWARDED_P: + NEXT_CHAR(); + switch (ch) { + case 'R': + if (last) { + return -1; + } + goto X_FORWARDED_PR; + case 'r': + if (last) { + return -1; + } + goto X_FORWARDED_PR; + default: + return -1; + } + +X_FORWARDED_PR: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return -1; + } + goto X_FORWARDED_PRO; + case 'o': + if (last) { + return -1; + } + goto X_FORWARDED_PRO; + default: + return -1; + } + +X_FORWARDED_PRO: + NEXT_CHAR(); + switch (ch) { + case 'T': + if (last) { + return -1; + } + goto X_FORWARDED_PROT; + case 't': + if (last) { + return -1; + } + goto X_FORWARDED_PROT; + default: + return -1; + } + +X_FORWARDED_PROT: + NEXT_CHAR(); + switch (ch) { + case 'O': + if (last) { + return 76; + } + goto X_FORWARDED_PROTO; + case 'o': + if (last) { + return 76; + } + goto X_FORWARDED_PROTO; + default: + return -1; + } + +ACCEPT_CHARSET: +ACCEPT_ENCODING: +ACCEPT_LANGUAGE: +ACCEPT_RANGES: +ACCESS_CONTROL_ALLOW_CREDENTIALS: +ACCESS_CONTROL_ALLOW_HEADERS: +ACCESS_CONTROL_ALLOW_METHODS: +ACCESS_CONTROL_ALLOW_ORIGIN: +ACCESS_CONTROL_EXPOSE_HEADERS: +ACCESS_CONTROL_MAX_AGE: +ACCESS_CONTROL_REQUEST_HEADERS: +ACCESS_CONTROL_REQUEST_METHOD: +AGE: +ALLOW: +AUTHORIZATION: +CACHE_CONTROL: +CONNECTION: +CONTENT_DISPOSITION: +CONTENT_ENCODING: +CONTENT_LANGUAGE: +CONTENT_LENGTH: +CONTENT_LOCATION: +CONTENT_MD5: +CONTENT_RANGE: +CONTENT_TRANSFER_ENCODING: +CONTENT_TYPE: +COOKIE: +DATE: +DESTINATION: +DIGEST: +ETAG: +EXPECT: +EXPIRES: +FORWARDED: +FROM: +HOST: +IF_MATCH: +IF_MODIFIED_SINCE: +IF_NONE_MATCH: +IF_RANGE: +IF_UNMODIFIED_SINCE: +KEEP_ALIVE: +LAST_EVENT_ID: +LAST_MODIFIED: +LINK: +LOCATION: +MAX_FORWARDS: +ORIGIN: +PRAGMA: +PROXY_AUTHENTICATE: +PROXY_AUTHORIZATION: +RANGE: +REFERER: +RETRY_AFTER: +SEC_WEBSOCKET_ACCEPT: +SEC_WEBSOCKET_EXTENSIONS: +SEC_WEBSOCKET_KEY1: +SEC_WEBSOCKET_PROTOCOL: +SEC_WEBSOCKET_VERSION: +SERVER: +SET_COOKIE: +TE: +TRAILER: +TRANSFER_ENCODING: +UPGRADE: +URI: +USER_AGENT: +VARY: +VIA: +WANT_DIGEST: +WARNING: +WWW_AUTHENTICATE: +X_FORWARDED_FOR: +X_FORWARDED_HOST: +X_FORWARDED_PROTO: +missing: + /* nothing found */ + return -1; +} diff --git a/dist/ba_data/python-site-packages/aiohttp/_find_header.h b/dist/ba_data/python-site-packages/aiohttp/_find_header.h new file mode 100644 index 0000000..99b7b4f --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_find_header.h @@ -0,0 +1,14 @@ +#ifndef _FIND_HEADERS_H +#define _FIND_HEADERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +int find_header(const char *str, int size); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/dist/ba_data/python-site-packages/aiohttp/_find_header.pxd b/dist/ba_data/python-site-packages/aiohttp/_find_header.pxd new file mode 100644 index 0000000..37a6c37 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_find_header.pxd @@ -0,0 +1,2 @@ +cdef extern from "_find_header.h": + int find_header(char *, int) diff --git a/dist/ba_data/python-site-packages/aiohttp/_frozenlist.c b/dist/ba_data/python-site-packages/aiohttp/_frozenlist.c new file mode 100644 index 0000000..8588a95 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_frozenlist.c @@ -0,0 +1,7512 @@ +/* Generated by Cython 0.29.21 */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.6+ or Python 3.3+. +#else +#define CYTHON_ABI "0_29_21" +#define CYTHON_HEX_VERSION 0x001D15F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #if PY_VERSION_HEX >= 0x02070000 + #define HAVE_LONG_LONG + #endif +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#elif defined(PYSTON_VERSION) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int32 uint32_t; + #endif + #endif +#else + #include +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) && __cplusplus >= 201103L + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #elif __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__ ) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" +#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_FAST_PYCCALL +#define __Pyx_PyFastCFunction_Check(func)\ + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) +#else +#define __Pyx_PyFastCFunction_Check(func) 0 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif +#if CYTHON_COMPILING_IN_PYSTON + #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +#else +#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) +#else + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__aiohttp___frozenlist +#define __PYX_HAVE_API__aiohttp___frozenlist +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +static PyObject *__pyx_m = NULL; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_cython_runtime = NULL; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + + +static const char *__pyx_f[] = { + "aiohttp\\_frozenlist.pyx", + "stringsource", +}; + +/*--- Type declarations ---*/ +struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList; + +/* "aiohttp/_frozenlist.pyx":4 + * + * + * cdef class FrozenList: # <<<<<<<<<<<<<< + * + * cdef readonly bint frozen + */ +struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList { + PyObject_HEAD + struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *__pyx_vtab; + int frozen; + PyObject *_items; +}; + + + +struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList { + PyObject *(*_check_frozen)(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *); + PyObject *(*_fast_len)(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *); +}; +static struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *__pyx_vtabptr_7aiohttp_11_frozenlist_FrozenList; +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *); + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* ObjectGetItem.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key); +#else +#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#else +#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectCallNoArg.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); +#else +#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) +#endif + +/* PyCFunctionFastCall.proto */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); +#else +#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* PyIntCompare.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, long intval, long inplace); + +/* PySequenceContains.proto */ +static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { + int result = PySequence_Contains(seq, item); + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* PyObjectCall2Args.proto */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +/* PyObjectCallMethod1.proto */ +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); + +/* pop_index.proto */ +static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix); +static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix); +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix); +#define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) (\ + (likely(PyList_CheckExact(L) && __Pyx_fits_Py_ssize_t(ix, type, is_signed))) ?\ + __Pyx__PyList_PopIndex(L, py_ix, ix) : (\ + (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) :\ + __Pyx__PyObject_PopIndex(L, py_ix))) +#define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) (\ + __Pyx_fits_Py_ssize_t(ix, type, is_signed) ?\ + __Pyx__PyList_PopIndex(L, py_ix, ix) : (\ + (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) :\ + __Pyx__PyObject_PopIndex(L, py_ix))) +#else +#define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func)\ + __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) +#define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) (\ + (unlikely((py_ix) == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) :\ + __Pyx__PyObject_PopIndex(L, py_ix)) +#endif + +/* ListAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { + Py_INCREF(x); + PyList_SET_ITEM(list, len, x); + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) +#endif + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* GetAttr.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); + +/* GetAttr3.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* HasAttr.proto */ +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); + +/* PyObject_GenericGetAttrNoDict.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr +#endif + +/* PyObject_GenericGetAttr.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr +#endif + +/* SetVTable.proto */ +static int __Pyx_SetVtable(PyObject *dict, void *vtable); + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* SetupReduce.proto */ +static int __Pyx_setup_reduce(PyObject* type_obj); + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + +static PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__check_frozen(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto*/ + +/* Module declarations from 'aiohttp._frozenlist' */ +static PyTypeObject *__pyx_ptype_7aiohttp_11_frozenlist_FrozenList = 0; +static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *, PyObject *); /*proto*/ +#define __Pyx_MODULE_NAME "aiohttp._frozenlist" +extern int __pyx_module_is_main_aiohttp___frozenlist; +int __pyx_module_is_main_aiohttp___frozenlist = 0; + +/* Implementation of 'aiohttp._frozenlist' */ +static PyObject *__pyx_builtin_RuntimeError; +static const char __pyx_k_new[] = "__new__"; +static const char __pyx_k_pop[] = "pop"; +static const char __pyx_k_pos[] = "pos"; +static const char __pyx_k_dict[] = "__dict__"; +static const char __pyx_k_item[] = "item"; +static const char __pyx_k_iter[] = "__iter__"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_clear[] = "clear"; +static const char __pyx_k_count[] = "count"; +static const char __pyx_k_index[] = "index"; +static const char __pyx_k_items[] = "items"; +static const char __pyx_k_format[] = "format"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_pickle[] = "pickle"; +static const char __pyx_k_reduce[] = "__reduce__"; +static const char __pyx_k_remove[] = "remove"; +static const char __pyx_k_update[] = "update"; +static const char __pyx_k_getstate[] = "__getstate__"; +static const char __pyx_k_pyx_type[] = "__pyx_type"; +static const char __pyx_k_register[] = "register"; +static const char __pyx_k_reversed[] = "__reversed__"; +static const char __pyx_k_setstate[] = "__setstate__"; +static const char __pyx_k_pyx_state[] = "__pyx_state"; +static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; +static const char __pyx_k_FrozenList[] = "FrozenList"; +static const char __pyx_k_pyx_result[] = "__pyx_result"; +static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; +static const char __pyx_k_PickleError[] = "PickleError"; +static const char __pyx_k_RuntimeError[] = "RuntimeError"; +static const char __pyx_k_pyx_checksum[] = "__pyx_checksum"; +static const char __pyx_k_stringsource[] = "stringsource"; +static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; +static const char __pyx_k_MutableSequence[] = "MutableSequence"; +static const char __pyx_k_collections_abc[] = "collections.abc"; +static const char __pyx_k_pyx_PickleError[] = "__pyx_PickleError"; +static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_FrozenList_frozen_r[] = ""; +static const char __pyx_k_aiohttp__frozenlist[] = "aiohttp._frozenlist"; +static const char __pyx_k_pyx_unpickle_FrozenList[] = "__pyx_unpickle_FrozenList"; +static const char __pyx_k_Cannot_modify_frozen_list[] = "Cannot modify frozen list."; +static const char __pyx_k_Incompatible_checksums_s_vs_0x94[] = "Incompatible checksums (%s vs 0x949a143 = (_items, frozen))"; +static PyObject *__pyx_kp_u_Cannot_modify_frozen_list; +static PyObject *__pyx_n_s_FrozenList; +static PyObject *__pyx_kp_u_FrozenList_frozen_r; +static PyObject *__pyx_kp_s_Incompatible_checksums_s_vs_0x94; +static PyObject *__pyx_n_s_MutableSequence; +static PyObject *__pyx_n_s_PickleError; +static PyObject *__pyx_n_s_RuntimeError; +static PyObject *__pyx_n_s_aiohttp__frozenlist; +static PyObject *__pyx_n_s_clear; +static PyObject *__pyx_n_s_cline_in_traceback; +static PyObject *__pyx_n_s_collections_abc; +static PyObject *__pyx_n_s_count; +static PyObject *__pyx_n_s_dict; +static PyObject *__pyx_n_s_format; +static PyObject *__pyx_n_s_getstate; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_n_s_index; +static PyObject *__pyx_n_s_item; +static PyObject *__pyx_n_s_items; +static PyObject *__pyx_n_s_iter; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_name; +static PyObject *__pyx_n_s_new; +static PyObject *__pyx_n_s_pickle; +static PyObject *__pyx_n_s_pop; +static PyObject *__pyx_n_s_pos; +static PyObject *__pyx_n_s_pyx_PickleError; +static PyObject *__pyx_n_s_pyx_checksum; +static PyObject *__pyx_n_s_pyx_result; +static PyObject *__pyx_n_s_pyx_state; +static PyObject *__pyx_n_s_pyx_type; +static PyObject *__pyx_n_s_pyx_unpickle_FrozenList; +static PyObject *__pyx_n_s_pyx_vtable; +static PyObject *__pyx_n_s_reduce; +static PyObject *__pyx_n_s_reduce_cython; +static PyObject *__pyx_n_s_reduce_ex; +static PyObject *__pyx_n_s_register; +static PyObject *__pyx_n_s_remove; +static PyObject *__pyx_n_s_reversed; +static PyObject *__pyx_n_s_setstate; +static PyObject *__pyx_n_s_setstate_cython; +static PyObject *__pyx_kp_s_stringsource; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_n_s_update; +static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList___init__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_2freeze(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_4__getitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index); /* proto */ +static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6__setitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */ +static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_8__delitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index); /* proto */ +static Py_ssize_t __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_10__len__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_12__iter__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_14__reversed__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_16__richcmp__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_18insert(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_pos, PyObject *__pyx_v_item); /* proto */ +static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_20__contains__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_22__iadd__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_24index(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_26remove(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_28clear(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_30extend(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_32reverse(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_34pop(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_36append(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_38count(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_40__repr__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6frozen___get__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_44__setstate_cython__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v___pyx_state); /* proto */ +static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state); /* proto */ +static PyObject *__pyx_tp_new_7aiohttp_11_frozenlist_FrozenList(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_int_0; +static PyObject *__pyx_int_1; +static PyObject *__pyx_int_2; +static PyObject *__pyx_int_3; +static PyObject *__pyx_int_4; +static PyObject *__pyx_int_5; +static PyObject *__pyx_int_155820355; +static PyObject *__pyx_int_neg_1; +static PyObject *__pyx_tuple_; +static PyObject *__pyx_tuple__2; +static PyObject *__pyx_codeobj__3; +/* Late includes */ + +/* "aiohttp/_frozenlist.pyx":9 + * cdef list _items + * + * def __init__(self, items=None): # <<<<<<<<<<<<<< + * self.frozen = False + * if items is not None: + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_items = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_items,0}; + PyObject* values[1] = {0}; + values[0] = ((PyObject *)Py_None); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_items); + if (value) { values[0] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 9, __pyx_L3_error) + } + } else { + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_items = values[0]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 9, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList___init__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), __pyx_v_items); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList___init__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items) { + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + __Pyx_INCREF(__pyx_v_items); + + /* "aiohttp/_frozenlist.pyx":10 + * + * def __init__(self, items=None): + * self.frozen = False # <<<<<<<<<<<<<< + * if items is not None: + * items = list(items) + */ + __pyx_v_self->frozen = 0; + + /* "aiohttp/_frozenlist.pyx":11 + * def __init__(self, items=None): + * self.frozen = False + * if items is not None: # <<<<<<<<<<<<<< + * items = list(items) + * else: + */ + __pyx_t_1 = (__pyx_v_items != Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "aiohttp/_frozenlist.pyx":12 + * self.frozen = False + * if items is not None: + * items = list(items) # <<<<<<<<<<<<<< + * else: + * items = [] + */ + __pyx_t_3 = PySequence_List(__pyx_v_items); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_items, __pyx_t_3); + __pyx_t_3 = 0; + + /* "aiohttp/_frozenlist.pyx":11 + * def __init__(self, items=None): + * self.frozen = False + * if items is not None: # <<<<<<<<<<<<<< + * items = list(items) + * else: + */ + goto __pyx_L3; + } + + /* "aiohttp/_frozenlist.pyx":14 + * items = list(items) + * else: + * items = [] # <<<<<<<<<<<<<< + * self._items = items + * + */ + /*else*/ { + __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_items, __pyx_t_3); + __pyx_t_3 = 0; + } + __pyx_L3:; + + /* "aiohttp/_frozenlist.pyx":15 + * else: + * items = [] + * self._items = items # <<<<<<<<<<<<<< + * + * cdef object _check_frozen(self): + */ + if (!(likely(PyList_CheckExact(__pyx_v_items))||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_v_items)->tp_name), 0))) __PYX_ERR(0, 15, __pyx_L1_error) + __pyx_t_3 = __pyx_v_items; + __Pyx_INCREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_3); + __Pyx_GOTREF(__pyx_v_self->_items); + __Pyx_DECREF(__pyx_v_self->_items); + __pyx_v_self->_items = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "aiohttp/_frozenlist.pyx":9 + * cdef list _items + * + * def __init__(self, items=None): # <<<<<<<<<<<<<< + * self.frozen = False + * if items is not None: + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_items); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":17 + * self._items = items + * + * cdef object _check_frozen(self): # <<<<<<<<<<<<<< + * if self.frozen: + * raise RuntimeError("Cannot modify frozen list.") + */ + +static PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__check_frozen(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_check_frozen", 0); + + /* "aiohttp/_frozenlist.pyx":18 + * + * cdef object _check_frozen(self): + * if self.frozen: # <<<<<<<<<<<<<< + * raise RuntimeError("Cannot modify frozen list.") + * + */ + __pyx_t_1 = (__pyx_v_self->frozen != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_frozenlist.pyx":19 + * cdef object _check_frozen(self): + * if self.frozen: + * raise RuntimeError("Cannot modify frozen list.") # <<<<<<<<<<<<<< + * + * cdef inline object _fast_len(self): + */ + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_Raise(__pyx_t_2, 0, 0, 0); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __PYX_ERR(0, 19, __pyx_L1_error) + + /* "aiohttp/_frozenlist.pyx":18 + * + * cdef object _check_frozen(self): + * if self.frozen: # <<<<<<<<<<<<<< + * raise RuntimeError("Cannot modify frozen list.") + * + */ + } + + /* "aiohttp/_frozenlist.pyx":17 + * self._items = items + * + * cdef object _check_frozen(self): # <<<<<<<<<<<<<< + * if self.frozen: + * raise RuntimeError("Cannot modify frozen list.") + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList._check_frozen", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":21 + * raise RuntimeError("Cannot modify frozen list.") + * + * cdef inline object _fast_len(self): # <<<<<<<<<<<<<< + * return len(self._items) + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_fast_len", 0); + + /* "aiohttp/_frozenlist.pyx":22 + * + * cdef inline object _fast_len(self): + * return len(self._items) # <<<<<<<<<<<<<< + * + * def freeze(self): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_v_self->_items; + __Pyx_INCREF(__pyx_t_1); + if (unlikely(__pyx_t_1 == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(0, 22, __pyx_L1_error) + } + __pyx_t_2 = PyList_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 22, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":21 + * raise RuntimeError("Cannot modify frozen list.") + * + * cdef inline object _fast_len(self): # <<<<<<<<<<<<<< + * return len(self._items) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList._fast_len", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":24 + * return len(self._items) + * + * def freeze(self): # <<<<<<<<<<<<<< + * self.frozen = True + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_3freeze(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_3freeze(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("freeze (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_2freeze(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_2freeze(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("freeze", 0); + + /* "aiohttp/_frozenlist.pyx":25 + * + * def freeze(self): + * self.frozen = True # <<<<<<<<<<<<<< + * + * def __getitem__(self, index): + */ + __pyx_v_self->frozen = 1; + + /* "aiohttp/_frozenlist.pyx":24 + * return len(self._items) + * + * def freeze(self): # <<<<<<<<<<<<<< + * self.frozen = True + * + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":27 + * self.frozen = True + * + * def __getitem__(self, index): # <<<<<<<<<<<<<< + * return self._items[index] + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_4__getitem__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_index)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_4__getitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__getitem__", 0); + + /* "aiohttp/_frozenlist.pyx":28 + * + * def __getitem__(self, index): + * return self._items[index] # <<<<<<<<<<<<<< + * + * def __setitem__(self, index, value): + */ + __Pyx_XDECREF(__pyx_r); + if (unlikely(__pyx_v_self->_items == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(0, 28, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_self->_items, __pyx_v_index); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":27 + * self.frozen = True + * + * def __getitem__(self, index): # <<<<<<<<<<<<<< + * return self._items[index] + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":30 + * return self._items[index] + * + * def __setitem__(self, index, value): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items[index] = value + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_7__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/ +static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_7__setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6__setitem__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6__setitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setitem__", 0); + + /* "aiohttp/_frozenlist.pyx":31 + * + * def __setitem__(self, index, value): + * self._check_frozen() # <<<<<<<<<<<<<< + * self._items[index] = value + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":32 + * def __setitem__(self, index, value): + * self._check_frozen() + * self._items[index] = value # <<<<<<<<<<<<<< + * + * def __delitem__(self, index): + */ + if (unlikely(__pyx_v_self->_items == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(0, 32, __pyx_L1_error) + } + if (unlikely(PyObject_SetItem(__pyx_v_self->_items, __pyx_v_index, __pyx_v_value) < 0)) __PYX_ERR(0, 32, __pyx_L1_error) + + /* "aiohttp/_frozenlist.pyx":30 + * return self._items[index] + * + * def __setitem__(self, index, value): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items[index] = value + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":34 + * self._items[index] = value + * + * def __delitem__(self, index): # <<<<<<<<<<<<<< + * self._check_frozen() + * del self._items[index] + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_9__delitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/ +static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_9__delitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__delitem__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_8__delitem__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_index)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_8__delitem__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__delitem__", 0); + + /* "aiohttp/_frozenlist.pyx":35 + * + * def __delitem__(self, index): + * self._check_frozen() # <<<<<<<<<<<<<< + * del self._items[index] + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":36 + * def __delitem__(self, index): + * self._check_frozen() + * del self._items[index] # <<<<<<<<<<<<<< + * + * def __len__(self): + */ + if (unlikely(__pyx_v_self->_items == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(0, 36, __pyx_L1_error) + } + if (unlikely(PyObject_DelItem(__pyx_v_self->_items, __pyx_v_index) < 0)) __PYX_ERR(0, 36, __pyx_L1_error) + + /* "aiohttp/_frozenlist.pyx":34 + * self._items[index] = value + * + * def __delitem__(self, index): # <<<<<<<<<<<<<< + * self._check_frozen() + * del self._items[index] + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__delitem__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":38 + * del self._items[index] + * + * def __len__(self): # <<<<<<<<<<<<<< + * return self._fast_len() + * + */ + +/* Python wrapper */ +static Py_ssize_t __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_11__len__(PyObject *__pyx_v_self); /*proto*/ +static Py_ssize_t __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_11__len__(PyObject *__pyx_v_self) { + Py_ssize_t __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__len__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_10__len__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static Py_ssize_t __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_10__len__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + Py_ssize_t __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__len__", 0); + + /* "aiohttp/_frozenlist.pyx":39 + * + * def __len__(self): + * return self._fast_len() # <<<<<<<<<<<<<< + * + * def __iter__(self): + */ + __pyx_t_1 = __pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_2 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_2; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":38 + * del self._items[index] + * + * def __len__(self): # <<<<<<<<<<<<<< + * return self._fast_len() + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__len__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":41 + * return self._fast_len() + * + * def __iter__(self): # <<<<<<<<<<<<<< + * return self._items.__iter__() + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_13__iter__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_13__iter__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_12__iter__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_12__iter__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__iter__", 0); + + /* "aiohttp/_frozenlist.pyx":42 + * + * def __iter__(self): + * return self._items.__iter__() # <<<<<<<<<<<<<< + * + * def __reversed__(self): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_iter); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":41 + * return self._fast_len() + * + * def __iter__(self): # <<<<<<<<<<<<<< + * return self._items.__iter__() + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":44 + * return self._items.__iter__() + * + * def __reversed__(self): # <<<<<<<<<<<<<< + * return self._items.__reversed__() + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_15__reversed__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_15__reversed__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reversed__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_14__reversed__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_14__reversed__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reversed__", 0); + + /* "aiohttp/_frozenlist.pyx":45 + * + * def __reversed__(self): + * return self._items.__reversed__() # <<<<<<<<<<<<<< + * + * def __richcmp__(self, other, op): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_reversed); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":44 + * return self._items.__iter__() + * + * def __reversed__(self): # <<<<<<<<<<<<<< + * return self._items.__reversed__() + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__reversed__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":47 + * return self._items.__reversed__() + * + * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< + * if op == 0: # < + * return list(self) < other + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_17__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_17__richcmp__(PyObject *__pyx_v_self, PyObject *__pyx_v_other, int __pyx_arg_op) { + PyObject *__pyx_v_op = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__richcmp__ (wrapper)", 0); + __pyx_v_op = __Pyx_PyInt_From_int(__pyx_arg_op); if (unlikely(!__pyx_v_op)) __PYX_ERR(0, 47, __pyx_L3_error) + __Pyx_GOTREF(__pyx_v_op); + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_16__richcmp__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_other), ((PyObject *)__pyx_v_op)); + + /* function exit code */ + __Pyx_XDECREF(__pyx_v_op); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_16__richcmp__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_other, PyObject *__pyx_v_op) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__richcmp__", 0); + + /* "aiohttp/_frozenlist.pyx":48 + * + * def __richcmp__(self, other, op): + * if op == 0: # < # <<<<<<<<<<<<<< + * return list(self) < other + * if op == 1: # <= + */ + __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_0, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 48, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 48, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_2) { + + /* "aiohttp/_frozenlist.pyx":49 + * def __richcmp__(self, other, op): + * if op == 0: # < + * return list(self) < other # <<<<<<<<<<<<<< + * if op == 1: # <= + * return list(self) <= other + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_v_other, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 49, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":48 + * + * def __richcmp__(self, other, op): + * if op == 0: # < # <<<<<<<<<<<<<< + * return list(self) < other + * if op == 1: # <= + */ + } + + /* "aiohttp/_frozenlist.pyx":50 + * if op == 0: # < + * return list(self) < other + * if op == 1: # <= # <<<<<<<<<<<<<< + * return list(self) <= other + * if op == 2: # == + */ + __pyx_t_3 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_1, 1, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 50, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 50, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_2) { + + /* "aiohttp/_frozenlist.pyx":51 + * return list(self) < other + * if op == 1: # <= + * return list(self) <= other # <<<<<<<<<<<<<< + * if op == 2: # == + * return list(self) == other + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_other, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":50 + * if op == 0: # < + * return list(self) < other + * if op == 1: # <= # <<<<<<<<<<<<<< + * return list(self) <= other + * if op == 2: # == + */ + } + + /* "aiohttp/_frozenlist.pyx":52 + * if op == 1: # <= + * return list(self) <= other + * if op == 2: # == # <<<<<<<<<<<<<< + * return list(self) == other + * if op == 3: # != + */ + __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_2, 2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 52, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_2) { + + /* "aiohttp/_frozenlist.pyx":53 + * return list(self) <= other + * if op == 2: # == + * return list(self) == other # <<<<<<<<<<<<<< + * if op == 3: # != + * return list(self) != other + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_v_other, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 53, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":52 + * if op == 1: # <= + * return list(self) <= other + * if op == 2: # == # <<<<<<<<<<<<<< + * return list(self) == other + * if op == 3: # != + */ + } + + /* "aiohttp/_frozenlist.pyx":54 + * if op == 2: # == + * return list(self) == other + * if op == 3: # != # <<<<<<<<<<<<<< + * return list(self) != other + * if op == 4: # > + */ + __pyx_t_3 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_3, 3, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 54, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 54, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_2) { + + /* "aiohttp/_frozenlist.pyx":55 + * return list(self) == other + * if op == 3: # != + * return list(self) != other # <<<<<<<<<<<<<< + * if op == 4: # > + * return list(self) > other + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_other, Py_NE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":54 + * if op == 2: # == + * return list(self) == other + * if op == 3: # != # <<<<<<<<<<<<<< + * return list(self) != other + * if op == 4: # > + */ + } + + /* "aiohttp/_frozenlist.pyx":56 + * if op == 3: # != + * return list(self) != other + * if op == 4: # > # <<<<<<<<<<<<<< + * return list(self) > other + * if op == 5: # => + */ + __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_4, 4, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 56, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_2) { + + /* "aiohttp/_frozenlist.pyx":57 + * return list(self) != other + * if op == 4: # > + * return list(self) > other # <<<<<<<<<<<<<< + * if op == 5: # => + * return list(self) >= other + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyObject_RichCompare(__pyx_t_1, __pyx_v_other, Py_GT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":56 + * if op == 3: # != + * return list(self) != other + * if op == 4: # > # <<<<<<<<<<<<<< + * return list(self) > other + * if op == 5: # => + */ + } + + /* "aiohttp/_frozenlist.pyx":58 + * if op == 4: # > + * return list(self) > other + * if op == 5: # => # <<<<<<<<<<<<<< + * return list(self) >= other + * + */ + __pyx_t_3 = __Pyx_PyInt_EqObjC(__pyx_v_op, __pyx_int_5, 5, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 58, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_2) { + + /* "aiohttp/_frozenlist.pyx":59 + * return list(self) > other + * if op == 5: # => + * return list(self) >= other # <<<<<<<<<<<<<< + * + * def insert(self, pos, item): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PySequence_List(((PyObject *)__pyx_v_self)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 59, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = PyObject_RichCompare(__pyx_t_3, __pyx_v_other, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 59, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":58 + * if op == 4: # > + * return list(self) > other + * if op == 5: # => # <<<<<<<<<<<<<< + * return list(self) >= other + * + */ + } + + /* "aiohttp/_frozenlist.pyx":47 + * return self._items.__reversed__() + * + * def __richcmp__(self, other, op): # <<<<<<<<<<<<<< + * if op == 0: # < + * return list(self) < other + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__richcmp__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":61 + * return list(self) >= other + * + * def insert(self, pos, item): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items.insert(pos, item) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_19insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_19insert(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_pos = 0; + PyObject *__pyx_v_item = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("insert (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pos,&__pyx_n_s_item,0}; + PyObject* values[2] = {0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pos)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_item)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("insert", 1, 2, 2, 1); __PYX_ERR(0, 61, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "insert") < 0)) __PYX_ERR(0, 61, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + } + __pyx_v_pos = values[0]; + __pyx_v_item = values[1]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("insert", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 61, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.insert", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_18insert(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), __pyx_v_pos, __pyx_v_item); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_18insert(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_pos, PyObject *__pyx_v_item) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + int __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("insert", 0); + + /* "aiohttp/_frozenlist.pyx":62 + * + * def insert(self, pos, item): + * self._check_frozen() # <<<<<<<<<<<<<< + * self._items.insert(pos, item) + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":63 + * def insert(self, pos, item): + * self._check_frozen() + * self._items.insert(pos, item) # <<<<<<<<<<<<<< + * + * def __contains__(self, item): + */ + if (unlikely(__pyx_v_self->_items == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "insert"); + __PYX_ERR(0, 63, __pyx_L1_error) + } + __pyx_t_2 = __Pyx_PyIndex_AsSsize_t(__pyx_v_pos); if (unlikely((__pyx_t_2 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 63, __pyx_L1_error) + __pyx_t_3 = PyList_Insert(__pyx_v_self->_items, __pyx_t_2, __pyx_v_item); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 63, __pyx_L1_error) + + /* "aiohttp/_frozenlist.pyx":61 + * return list(self) >= other + * + * def insert(self, pos, item): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items.insert(pos, item) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.insert", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":65 + * self._items.insert(pos, item) + * + * def __contains__(self, item): # <<<<<<<<<<<<<< + * return item in self._items + * + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_21__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ +static int __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_21__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_20__contains__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_20__contains__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__contains__", 0); + + /* "aiohttp/_frozenlist.pyx":66 + * + * def __contains__(self, item): + * return item in self._items # <<<<<<<<<<<<<< + * + * def __iadd__(self, items): + */ + __pyx_t_1 = (__Pyx_PySequence_ContainsTF(__pyx_v_item, __pyx_v_self->_items, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 66, __pyx_L1_error) + __pyx_r = __pyx_t_1; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":65 + * self._items.insert(pos, item) + * + * def __contains__(self, item): # <<<<<<<<<<<<<< + * return item in self._items + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":68 + * return item in self._items + * + * def __iadd__(self, items): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items += list(items) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_23__iadd__(PyObject *__pyx_v_self, PyObject *__pyx_v_items); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_23__iadd__(PyObject *__pyx_v_self, PyObject *__pyx_v_items) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__iadd__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_22__iadd__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_items)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_22__iadd__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__iadd__", 0); + + /* "aiohttp/_frozenlist.pyx":69 + * + * def __iadd__(self, items): + * self._check_frozen() # <<<<<<<<<<<<<< + * self._items += list(items) + * return self + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 69, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":70 + * def __iadd__(self, items): + * self._check_frozen() + * self._items += list(items) # <<<<<<<<<<<<<< + * return self + * + */ + __pyx_t_1 = PySequence_List(__pyx_v_items); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_self->_items, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_v_self->_items); + __Pyx_DECREF(__pyx_v_self->_items); + __pyx_v_self->_items = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "aiohttp/_frozenlist.pyx":71 + * self._check_frozen() + * self._items += list(items) + * return self # <<<<<<<<<<<<<< + * + * def index(self, item): + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_self)); + __pyx_r = ((PyObject *)__pyx_v_self); + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":68 + * return item in self._items + * + * def __iadd__(self, items): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items += list(items) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__iadd__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":73 + * return self + * + * def index(self, item): # <<<<<<<<<<<<<< + * return self._items.index(item) + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_25index(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_25index(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("index (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_24index(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_24index(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("index", 0); + + /* "aiohttp/_frozenlist.pyx":74 + * + * def index(self, item): + * return self._items.index(item) # <<<<<<<<<<<<<< + * + * def remove(self, item): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_index); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_item) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":73 + * return self + * + * def index(self, item): # <<<<<<<<<<<<<< + * return self._items.index(item) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.index", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":76 + * return self._items.index(item) + * + * def remove(self, item): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items.remove(item) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_27remove(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_27remove(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("remove (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_26remove(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_26remove(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("remove", 0); + + /* "aiohttp/_frozenlist.pyx":77 + * + * def remove(self, item): + * self._check_frozen() # <<<<<<<<<<<<<< + * self._items.remove(item) + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":78 + * def remove(self, item): + * self._check_frozen() + * self._items.remove(item) # <<<<<<<<<<<<<< + * + * def clear(self): + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_remove); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_item) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":76 + * return self._items.index(item) + * + * def remove(self, item): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items.remove(item) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.remove", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":80 + * self._items.remove(item) + * + * def clear(self): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items.clear() + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_29clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_29clear(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("clear (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_28clear(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_28clear(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("clear", 0); + + /* "aiohttp/_frozenlist.pyx":81 + * + * def clear(self): + * self._check_frozen() # <<<<<<<<<<<<<< + * self._items.clear() + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":82 + * def clear(self): + * self._check_frozen() + * self._items.clear() # <<<<<<<<<<<<<< + * + * def extend(self, items): + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_clear); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":80 + * self._items.remove(item) + * + * def clear(self): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items.clear() + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.clear", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":84 + * self._items.clear() + * + * def extend(self, items): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items += list(items) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_31extend(PyObject *__pyx_v_self, PyObject *__pyx_v_items); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_31extend(PyObject *__pyx_v_self, PyObject *__pyx_v_items) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("extend (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_30extend(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_items)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_30extend(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_items) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("extend", 0); + + /* "aiohttp/_frozenlist.pyx":85 + * + * def extend(self, items): + * self._check_frozen() # <<<<<<<<<<<<<< + * self._items += list(items) + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":86 + * def extend(self, items): + * self._check_frozen() + * self._items += list(items) # <<<<<<<<<<<<<< + * + * def reverse(self): + */ + __pyx_t_1 = PySequence_List(__pyx_v_items); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 86, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_self->_items, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 86, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_v_self->_items); + __Pyx_DECREF(__pyx_v_self->_items); + __pyx_v_self->_items = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "aiohttp/_frozenlist.pyx":84 + * self._items.clear() + * + * def extend(self, items): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items += list(items) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.extend", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":88 + * self._items += list(items) + * + * def reverse(self): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items.reverse() + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_33reverse(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_33reverse(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("reverse (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_32reverse(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_32reverse(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("reverse", 0); + + /* "aiohttp/_frozenlist.pyx":89 + * + * def reverse(self): + * self._check_frozen() # <<<<<<<<<<<<<< + * self._items.reverse() + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":90 + * def reverse(self): + * self._check_frozen() + * self._items.reverse() # <<<<<<<<<<<<<< + * + * def pop(self, index=-1): + */ + if (unlikely(__pyx_v_self->_items == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "reverse"); + __PYX_ERR(0, 90, __pyx_L1_error) + } + __pyx_t_2 = PyList_Reverse(__pyx_v_self->_items); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 90, __pyx_L1_error) + + /* "aiohttp/_frozenlist.pyx":88 + * self._items += list(items) + * + * def reverse(self): # <<<<<<<<<<<<<< + * self._check_frozen() + * self._items.reverse() + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.reverse", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":92 + * self._items.reverse() + * + * def pop(self, index=-1): # <<<<<<<<<<<<<< + * self._check_frozen() + * return self._items.pop(index) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_35pop(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_35pop(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_index = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("pop (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_index,0}; + PyObject* values[1] = {0}; + values[0] = ((PyObject *)__pyx_int_neg_1); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_index); + if (value) { values[0] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "pop") < 0)) __PYX_ERR(0, 92, __pyx_L3_error) + } + } else { + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_index = values[0]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("pop", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 92, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.pop", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_34pop(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), __pyx_v_index); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_34pop(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_index) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("pop", 0); + + /* "aiohttp/_frozenlist.pyx":93 + * + * def pop(self, index=-1): + * self._check_frozen() # <<<<<<<<<<<<<< + * return self._items.pop(index) + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":94 + * def pop(self, index=-1): + * self._check_frozen() + * return self._items.pop(index) # <<<<<<<<<<<<<< + * + * def append(self, item): + */ + __Pyx_XDECREF(__pyx_r); + if (unlikely(__pyx_v_self->_items == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "pop"); + __PYX_ERR(0, 94, __pyx_L1_error) + } + __pyx_t_2 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_2 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 94, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyList_PopIndex(__pyx_v_self->_items, __pyx_v_index, __pyx_t_2, 1, Py_ssize_t, PyInt_FromSsize_t); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 94, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":92 + * self._items.reverse() + * + * def pop(self, index=-1): # <<<<<<<<<<<<<< + * self._check_frozen() + * return self._items.pop(index) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.pop", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":96 + * return self._items.pop(index) + * + * def append(self, item): # <<<<<<<<<<<<<< + * self._check_frozen() + * return self._items.append(item) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_37append(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_37append(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("append (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_36append(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_36append(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("append", 0); + + /* "aiohttp/_frozenlist.pyx":97 + * + * def append(self, item): + * self._check_frozen() # <<<<<<<<<<<<<< + * return self._items.append(item) + * + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self->__pyx_vtab)->_check_frozen(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 97, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_frozenlist.pyx":98 + * def append(self, item): + * self._check_frozen() + * return self._items.append(item) # <<<<<<<<<<<<<< + * + * def count(self, item): + */ + __Pyx_XDECREF(__pyx_r); + if (unlikely(__pyx_v_self->_items == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); + __PYX_ERR(0, 98, __pyx_L1_error) + } + __pyx_t_2 = __Pyx_PyList_Append(__pyx_v_self->_items, __pyx_v_item); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 98, __pyx_L1_error) + __pyx_t_1 = __Pyx_Owned_Py_None(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 98, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":96 + * return self._items.pop(index) + * + * def append(self, item): # <<<<<<<<<<<<<< + * self._check_frozen() + * return self._items.append(item) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.append", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":100 + * return self._items.append(item) + * + * def count(self, item): # <<<<<<<<<<<<<< + * return self._items.count(item) + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_39count(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_39count(PyObject *__pyx_v_self, PyObject *__pyx_v_item) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("count (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_38count(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v_item)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_38count(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v_item) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("count", 0); + + /* "aiohttp/_frozenlist.pyx":101 + * + * def count(self, item): + * return self._items.count(item) # <<<<<<<<<<<<<< + * + * def __repr__(self): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_items, __pyx_n_s_count); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_item) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_item); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 101, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":100 + * return self._items.append(item) + * + * def count(self, item): # <<<<<<<<<<<<<< + * return self._items.count(item) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.count", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":103 + * return self._items.count(item) + * + * def __repr__(self): # <<<<<<<<<<<<<< + * return ''.format(self.frozen, + * self._items) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_41__repr__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_41__repr__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_40__repr__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_40__repr__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__repr__", 0); + + /* "aiohttp/_frozenlist.pyx":104 + * + * def __repr__(self): + * return ''.format(self.frozen, # <<<<<<<<<<<<<< + * self._items) + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_FrozenList_frozen_r, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_self->frozen); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "aiohttp/_frozenlist.pyx":105 + * def __repr__(self): + * return ''.format(self.frozen, + * self._items) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_4 = NULL; + __pyx_t_5 = 0; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + __pyx_t_5 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_v_self->_items}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_3, __pyx_v_self->_items}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else + #endif + { + __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (__pyx_t_4) { + __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __pyx_t_4 = NULL; + } + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_t_3); + __Pyx_INCREF(__pyx_v_self->_items); + __Pyx_GIVEREF(__pyx_v_self->_items); + PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_self->_items); + __pyx_t_3 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_frozenlist.pyx":103 + * return self._items.count(item) + * + * def __repr__(self): # <<<<<<<<<<<<<< + * return ''.format(self.frozen, + * self._items) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_frozenlist.pyx":6 + * cdef class FrozenList: + * + * cdef readonly bint frozen # <<<<<<<<<<<<<< + * cdef list _items + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_6frozen_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_6frozen_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6frozen___get__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_6frozen___get__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->frozen); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.frozen.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_43__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_43__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_42__reduce_cython__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self) { + PyObject *__pyx_v_state = 0; + PyObject *__pyx_v__dict = 0; + int __pyx_v_use_setstate; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + int __pyx_t_4; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":5 + * cdef object _dict + * cdef bint use_setstate + * state = (self._items, self.frozen) # <<<<<<<<<<<<<< + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: + */ + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->frozen); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_self->_items); + __Pyx_GIVEREF(__pyx_v_self->_items); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_self->_items); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1); + __pyx_t_1 = 0; + __pyx_v_state = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "(tree fragment)":6 + * cdef bint use_setstate + * state = (self._items, self.frozen) + * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< + * if _dict is not None: + * state += (_dict,) + */ + __pyx_t_2 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v__dict = __pyx_t_2; + __pyx_t_2 = 0; + + /* "(tree fragment)":7 + * state = (self._items, self.frozen) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True + */ + __pyx_t_3 = (__pyx_v__dict != Py_None); + __pyx_t_4 = (__pyx_t_3 != 0); + if (__pyx_t_4) { + + /* "(tree fragment)":8 + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: + * state += (_dict,) # <<<<<<<<<<<<<< + * use_setstate = True + * else: + */ + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v__dict); + __Pyx_GIVEREF(__pyx_v__dict); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v__dict); + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_1)); + __pyx_t_1 = 0; + + /* "(tree fragment)":9 + * if _dict is not None: + * state += (_dict,) + * use_setstate = True # <<<<<<<<<<<<<< + * else: + * use_setstate = self._items is not None + */ + __pyx_v_use_setstate = 1; + + /* "(tree fragment)":7 + * state = (self._items, self.frozen) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True + */ + goto __pyx_L3; + } + + /* "(tree fragment)":11 + * use_setstate = True + * else: + * use_setstate = self._items is not None # <<<<<<<<<<<<<< + * if use_setstate: + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state + */ + /*else*/ { + __pyx_t_4 = (__pyx_v_self->_items != ((PyObject*)Py_None)); + __pyx_v_use_setstate = __pyx_t_4; + } + __pyx_L3:; + + /* "(tree fragment)":12 + * else: + * use_setstate = self._items is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state + * else: + */ + __pyx_t_4 = (__pyx_v_use_setstate != 0); + if (__pyx_t_4) { + + /* "(tree fragment)":13 + * use_setstate = self._items is not None + * if use_setstate: + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state # <<<<<<<<<<<<<< + * else: + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pyx_unpickle_FrozenList); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_INCREF(__pyx_int_155820355); + __Pyx_GIVEREF(__pyx_int_155820355); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_155820355); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + PyTuple_SET_ITEM(__pyx_t_2, 2, Py_None); + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_v_state); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "(tree fragment)":12 + * else: + * use_setstate = self._items is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state + * else: + */ + } + + /* "(tree fragment)":15 + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, None), state + * else: + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_FrozenList__set_state(self, __pyx_state) + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_pyx_unpickle_FrozenList); if (unlikely(!__pyx_t_5)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_INCREF(__pyx_int_155820355); + __Pyx_GIVEREF(__pyx_int_155820355); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_155820355); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_state); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2); + __pyx_t_5 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + } + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_state); + __Pyx_XDECREF(__pyx_v__dict); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":16 + * else: + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_FrozenList__set_state(self, __pyx_state) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_45__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_45__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist_10FrozenList_44__setstate_cython__(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist_10FrozenList_44__setstate_cython__(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":17 + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_FrozenList__set_state(self, __pyx_state) # <<<<<<<<<<<<<< + */ + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":16 + * else: + * return __pyx_unpickle_FrozenList, (type(self), 0x949a143, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_FrozenList__set_state(self, __pyx_state) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._frozenlist.FrozenList.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList = {"__pyx_unpickle_FrozenList", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v___pyx_type = 0; + long __pyx_v___pyx_checksum; + PyObject *__pyx_v___pyx_state = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__pyx_unpickle_FrozenList (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; + PyObject* values[3] = {0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_FrozenList", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_FrozenList", 1, 3, 3, 2); __PYX_ERR(1, 1, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_FrozenList") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + } + __pyx_v___pyx_type = values[0]; + __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) + __pyx_v___pyx_state = values[2]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_FrozenList", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(1, 1, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._frozenlist.__pyx_unpickle_FrozenList", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_v___pyx_PickleError = 0; + PyObject *__pyx_v___pyx_result = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_FrozenList", 0); + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum != 0x949a143: # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) + */ + __pyx_t_1 = ((__pyx_v___pyx_checksum != 0x949a143) != 0); + if (__pyx_t_1) { + + /* "(tree fragment)":5 + * cdef object __pyx_result + * if __pyx_checksum != 0x949a143: + * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) + * __pyx_result = FrozenList.__new__(__pyx_type) + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_PickleError); + __Pyx_GIVEREF(__pyx_n_s_PickleError); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_2); + __pyx_v___pyx_PickleError = __pyx_t_2; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":6 + * if __pyx_checksum != 0x949a143: + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) # <<<<<<<<<<<<<< + * __pyx_result = FrozenList.__new__(__pyx_type) + * if __pyx_state is not None: + */ + __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x94, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_INCREF(__pyx_v___pyx_PickleError); + __pyx_t_2 = __pyx_v___pyx_PickleError; __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 6, __pyx_L1_error) + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum != 0x949a143: # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) + */ + } + + /* "(tree fragment)":7 + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) + * __pyx_result = FrozenList.__new__(__pyx_type) # <<<<<<<<<<<<<< + * if __pyx_state is not None: + * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_11_frozenlist_FrozenList), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v___pyx_result = __pyx_t_3; + __pyx_t_3 = 0; + + /* "(tree fragment)":8 + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) + * __pyx_result = FrozenList.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) + * return __pyx_result + */ + __pyx_t_1 = (__pyx_v___pyx_state != Py_None); + __pyx_t_6 = (__pyx_t_1 != 0); + if (__pyx_t_6) { + + /* "(tree fragment)":9 + * __pyx_result = FrozenList.__new__(__pyx_type) + * if __pyx_state is not None: + * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< + * return __pyx_result + * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): + */ + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":8 + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x949a143 = (_items, frozen))" % __pyx_checksum) + * __pyx_result = FrozenList.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) + * return __pyx_result + */ + } + + /* "(tree fragment)":10 + * if __pyx_state is not None: + * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) + * return __pyx_result # <<<<<<<<<<<<<< + * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): + * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v___pyx_result); + __pyx_r = __pyx_v___pyx_result; + goto __pyx_L0; + + /* "(tree fragment)":1 + * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("aiohttp._frozenlist.__pyx_unpickle_FrozenList", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v___pyx_PickleError); + __Pyx_XDECREF(__pyx_v___pyx_result); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":11 + * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): + */ + +static PyObject *__pyx_f_7aiohttp_11_frozenlist___pyx_unpickle_FrozenList__set_state(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + Py_ssize_t __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_FrozenList__set_state", 0); + + /* "(tree fragment)":12 + * return __pyx_result + * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): + * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] # <<<<<<<<<<<<<< + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[2]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!(likely(PyList_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "list", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->_items); + __Pyx_DECREF(__pyx_v___pyx_result->_items); + __pyx_v___pyx_result->_items = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v___pyx_result->frozen = __pyx_t_2; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): + * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[2]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(1, 13, __pyx_L1_error) + } + __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_4 = ((__pyx_t_3 > 2) != 0); + if (__pyx_t_4) { + } else { + __pyx_t_2 = __pyx_t_4; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_5 = (__pyx_t_4 != 0); + __pyx_t_2 = __pyx_t_5; + __pyx_L4_bool_binop_done:; + if (__pyx_t_2) { + + /* "(tree fragment)":14 + * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[2]) # <<<<<<<<<<<<<< + */ + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 14, __pyx_L1_error) + } + __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_8)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + } + } + __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): + * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[2]) + */ + } + + /* "(tree fragment)":11 + * __pyx_unpickle_FrozenList__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_FrozenList__set_state(FrozenList __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result._items = __pyx_state[0]; __pyx_result.frozen = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("aiohttp._frozenlist.__pyx_unpickle_FrozenList__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static struct __pyx_vtabstruct_7aiohttp_11_frozenlist_FrozenList __pyx_vtable_7aiohttp_11_frozenlist_FrozenList; + +static PyObject *__pyx_tp_new_7aiohttp_11_frozenlist_FrozenList(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *p; + PyObject *o; + if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + p = ((struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)o); + p->__pyx_vtab = __pyx_vtabptr_7aiohttp_11_frozenlist_FrozenList; + p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); + return o; +} + +static void __pyx_tp_dealloc_7aiohttp_11_frozenlist_FrozenList(PyObject *o) { + struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *p = (struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->_items); + (*Py_TYPE(o)->tp_free)(o); +} + +static int __pyx_tp_traverse_7aiohttp_11_frozenlist_FrozenList(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *p = (struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)o; + if (p->_items) { + e = (*v)(p->_items, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_7aiohttp_11_frozenlist_FrozenList(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *p = (struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *)o; + tmp = ((PyObject*)p->_items); + p->_items = ((PyObject*)Py_None); Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} +static PyObject *__pyx_sq_item_7aiohttp_11_frozenlist_FrozenList(PyObject *o, Py_ssize_t i) { + PyObject *r; + PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0; + r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x); + Py_DECREF(x); + return r; +} + +static int __pyx_mp_ass_subscript_7aiohttp_11_frozenlist_FrozenList(PyObject *o, PyObject *i, PyObject *v) { + if (v) { + return __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_7__setitem__(o, i, v); + } + else { + return __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_9__delitem__(o, i); + } +} + +static PyObject *__pyx_getprop_7aiohttp_11_frozenlist_10FrozenList_frozen(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_6frozen_1__get__(o); +} + +static PyMethodDef __pyx_methods_7aiohttp_11_frozenlist_FrozenList[] = { + {"freeze", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_3freeze, METH_NOARGS, 0}, + {"__reversed__", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_15__reversed__, METH_NOARGS, 0}, + {"insert", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_19insert, METH_VARARGS|METH_KEYWORDS, 0}, + {"index", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_25index, METH_O, 0}, + {"remove", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_27remove, METH_O, 0}, + {"clear", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_29clear, METH_NOARGS, 0}, + {"extend", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_31extend, METH_O, 0}, + {"reverse", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_33reverse, METH_NOARGS, 0}, + {"pop", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_35pop, METH_VARARGS|METH_KEYWORDS, 0}, + {"append", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_37append, METH_O, 0}, + {"count", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_39count, METH_O, 0}, + {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_43__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_11_frozenlist_10FrozenList_45__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static struct PyGetSetDef __pyx_getsets_7aiohttp_11_frozenlist_FrozenList[] = { + {(char *)"frozen", __pyx_getprop_7aiohttp_11_frozenlist_10FrozenList_frozen, 0, (char *)0, 0}, + {0, 0, 0, 0, 0} +}; + +static PyNumberMethods __pyx_tp_as_number_FrozenList = { + 0, /*nb_add*/ + 0, /*nb_subtract*/ + 0, /*nb_multiply*/ + #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) + 0, /*nb_divide*/ + #endif + 0, /*nb_remainder*/ + 0, /*nb_divmod*/ + 0, /*nb_power*/ + 0, /*nb_negative*/ + 0, /*nb_positive*/ + 0, /*nb_absolute*/ + 0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) + 0, /*nb_coerce*/ + #endif + 0, /*nb_int*/ + #if PY_MAJOR_VERSION < 3 + 0, /*nb_long*/ + #else + 0, /*reserved*/ + #endif + 0, /*nb_float*/ + #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) + 0, /*nb_oct*/ + #endif + #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) + 0, /*nb_hex*/ + #endif + __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_23__iadd__, /*nb_inplace_add*/ + 0, /*nb_inplace_subtract*/ + 0, /*nb_inplace_multiply*/ + #if PY_MAJOR_VERSION < 3 || (CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03050000) + 0, /*nb_inplace_divide*/ + #endif + 0, /*nb_inplace_remainder*/ + 0, /*nb_inplace_power*/ + 0, /*nb_inplace_lshift*/ + 0, /*nb_inplace_rshift*/ + 0, /*nb_inplace_and*/ + 0, /*nb_inplace_xor*/ + 0, /*nb_inplace_or*/ + 0, /*nb_floor_divide*/ + 0, /*nb_true_divide*/ + 0, /*nb_inplace_floor_divide*/ + 0, /*nb_inplace_true_divide*/ + 0, /*nb_index*/ + #if PY_VERSION_HEX >= 0x03050000 + 0, /*nb_matrix_multiply*/ + #endif + #if PY_VERSION_HEX >= 0x03050000 + 0, /*nb_inplace_matrix_multiply*/ + #endif +}; + +static PySequenceMethods __pyx_tp_as_sequence_FrozenList = { + __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_11__len__, /*sq_length*/ + 0, /*sq_concat*/ + 0, /*sq_repeat*/ + __pyx_sq_item_7aiohttp_11_frozenlist_FrozenList, /*sq_item*/ + 0, /*sq_slice*/ + 0, /*sq_ass_item*/ + 0, /*sq_ass_slice*/ + __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_21__contains__, /*sq_contains*/ + 0, /*sq_inplace_concat*/ + 0, /*sq_inplace_repeat*/ +}; + +static PyMappingMethods __pyx_tp_as_mapping_FrozenList = { + __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_11__len__, /*mp_length*/ + __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_5__getitem__, /*mp_subscript*/ + __pyx_mp_ass_subscript_7aiohttp_11_frozenlist_FrozenList, /*mp_ass_subscript*/ +}; + +static PyTypeObject __pyx_type_7aiohttp_11_frozenlist_FrozenList = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._frozenlist.FrozenList", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_11_frozenlist_FrozenList, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_41__repr__, /*tp_repr*/ + &__pyx_tp_as_number_FrozenList, /*tp_as_number*/ + &__pyx_tp_as_sequence_FrozenList, /*tp_as_sequence*/ + &__pyx_tp_as_mapping_FrozenList, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_11_frozenlist_FrozenList, /*tp_traverse*/ + __pyx_tp_clear_7aiohttp_11_frozenlist_FrozenList, /*tp_clear*/ + __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_17__richcmp__, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_13__iter__, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7aiohttp_11_frozenlist_FrozenList, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_7aiohttp_11_frozenlist_FrozenList, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + __pyx_pw_7aiohttp_11_frozenlist_10FrozenList_1__init__, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_11_frozenlist_FrozenList, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec__frozenlist(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec__frozenlist}, + {0, NULL} +}; +#endif + +static struct PyModuleDef __pyx_moduledef = { + PyModuleDef_HEAD_INIT, + "_frozenlist", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_Cannot_modify_frozen_list, __pyx_k_Cannot_modify_frozen_list, sizeof(__pyx_k_Cannot_modify_frozen_list), 0, 1, 0, 0}, + {&__pyx_n_s_FrozenList, __pyx_k_FrozenList, sizeof(__pyx_k_FrozenList), 0, 0, 1, 1}, + {&__pyx_kp_u_FrozenList_frozen_r, __pyx_k_FrozenList_frozen_r, sizeof(__pyx_k_FrozenList_frozen_r), 0, 1, 0, 0}, + {&__pyx_kp_s_Incompatible_checksums_s_vs_0x94, __pyx_k_Incompatible_checksums_s_vs_0x94, sizeof(__pyx_k_Incompatible_checksums_s_vs_0x94), 0, 0, 1, 0}, + {&__pyx_n_s_MutableSequence, __pyx_k_MutableSequence, sizeof(__pyx_k_MutableSequence), 0, 0, 1, 1}, + {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, + {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1}, + {&__pyx_n_s_aiohttp__frozenlist, __pyx_k_aiohttp__frozenlist, sizeof(__pyx_k_aiohttp__frozenlist), 0, 0, 1, 1}, + {&__pyx_n_s_clear, __pyx_k_clear, sizeof(__pyx_k_clear), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_collections_abc, __pyx_k_collections_abc, sizeof(__pyx_k_collections_abc), 0, 0, 1, 1}, + {&__pyx_n_s_count, __pyx_k_count, sizeof(__pyx_k_count), 0, 0, 1, 1}, + {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, + {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, + {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1}, + {&__pyx_n_s_item, __pyx_k_item, sizeof(__pyx_k_item), 0, 0, 1, 1}, + {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1}, + {&__pyx_n_s_iter, __pyx_k_iter, sizeof(__pyx_k_iter), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, + {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, + {&__pyx_n_s_pop, __pyx_k_pop, sizeof(__pyx_k_pop), 0, 0, 1, 1}, + {&__pyx_n_s_pos, __pyx_k_pos, sizeof(__pyx_k_pos), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_unpickle_FrozenList, __pyx_k_pyx_unpickle_FrozenList, sizeof(__pyx_k_pyx_unpickle_FrozenList), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, + {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, + {&__pyx_n_s_register, __pyx_k_register, sizeof(__pyx_k_register), 0, 0, 1, 1}, + {&__pyx_n_s_remove, __pyx_k_remove, sizeof(__pyx_k_remove), 0, 0, 1, 1}, + {&__pyx_n_s_reversed, __pyx_k_reversed, sizeof(__pyx_k_reversed), 0, 0, 1, 1}, + {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, + {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, + {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 19, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "aiohttp/_frozenlist.pyx":19 + * cdef object _check_frozen(self): + * if self.frozen: + * raise RuntimeError("Cannot modify frozen list.") # <<<<<<<<<<<<<< + * + * cdef inline object _fast_len(self): + */ + __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_Cannot_modify_frozen_list); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "(tree fragment)":1 + * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + __pyx_tuple__2 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + __pyx_codeobj__3 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__2, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_FrozenList, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__3)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_155820355 = PyInt_FromLong(155820355L); if (unlikely(!__pyx_int_155820355)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __pyx_vtabptr_7aiohttp_11_frozenlist_FrozenList = &__pyx_vtable_7aiohttp_11_frozenlist_FrozenList; + __pyx_vtable_7aiohttp_11_frozenlist_FrozenList._check_frozen = (PyObject *(*)(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *))__pyx_f_7aiohttp_11_frozenlist_10FrozenList__check_frozen; + __pyx_vtable_7aiohttp_11_frozenlist_FrozenList._fast_len = (PyObject *(*)(struct __pyx_obj_7aiohttp_11_frozenlist_FrozenList *))__pyx_f_7aiohttp_11_frozenlist_10FrozenList__fast_len; + if (PyType_Ready(&__pyx_type_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_dictoffset && __pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + if (__Pyx_SetVtable(__pyx_type_7aiohttp_11_frozenlist_FrozenList.tp_dict, __pyx_vtabptr_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_FrozenList, (PyObject *)&__pyx_type_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_11_frozenlist_FrozenList) < 0) __PYX_ERR(0, 4, __pyx_L1_error) + __pyx_ptype_7aiohttp_11_frozenlist_FrozenList = &__pyx_type_7aiohttp_11_frozenlist_FrozenList; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC init_frozenlist(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC init_frozenlist(void) +#else +__Pyx_PyMODINIT_FUNC PyInit__frozenlist(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit__frozenlist(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec__frozenlist(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_frozenlist' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__frozenlist(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("_frozenlist", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_b); + __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_cython_runtime); + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_aiohttp___frozenlist) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "aiohttp._frozenlist")) { + if (unlikely(PyDict_SetItemString(modules, "aiohttp._frozenlist", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_type_import_code(); + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "aiohttp/_frozenlist.pyx":1 + * from collections.abc import MutableSequence # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_s_MutableSequence); + __Pyx_GIVEREF(__pyx_n_s_MutableSequence); + PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_MutableSequence); + __pyx_t_2 = __Pyx_Import(__pyx_n_s_collections_abc, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_MutableSequence); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_MutableSequence, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_frozenlist.pyx":108 + * + * + * MutableSequence.register(FrozenList) # <<<<<<<<<<<<<< + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_MutableSequence); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_register); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, ((PyObject *)__pyx_ptype_7aiohttp_11_frozenlist_FrozenList)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 108, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "(tree fragment)":1 + * def __pyx_unpickle_FrozenList(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_11_frozenlist_1__pyx_unpickle_FrozenList, NULL, __pyx_n_s_aiohttp__frozenlist); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_FrozenList, __pyx_t_2) < 0) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_frozenlist.pyx":1 + * from collections.abc import MutableSequence # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init aiohttp._frozenlist", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_CLEAR(__pyx_m); + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init aiohttp._frozenlist"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* RaiseDoubleKeywords */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + __Pyx_PyThreadState_declare + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if CYTHON_COMPILING_IN_PYPY + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#else + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (!j) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (likely(m && m->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { + Py_ssize_t l = m->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return m->sq_item(o, i); + } + } +#else + if (is_list || PySequence_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* ObjectGetItem */ +#if CYTHON_USE_TYPE_SLOTS +static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) { + PyObject *runerr; + Py_ssize_t key_value; + PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence; + if (unlikely(!(m && m->sq_item))) { + PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name); + return NULL; + } + key_value = __Pyx_PyIndex_AsSsize_t(index); + if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { + return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); + } + if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, "cannot fit '%.200s' into an index-sized integer", Py_TYPE(index)->tp_name); + } + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { + PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping; + if (likely(m && m->mp_subscript)) { + return m->mp_subscript(obj, key); + } + return __Pyx_PyObject_GetIndex(obj, key); +} +#endif + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { + return NULL; + } + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = PyCFunction_GET_FUNCTION(func); + self = PyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallNoArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, NULL, 0); + } +#endif +#ifdef __Pyx_CyFunction_USED + if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) +#else + if (likely(PyCFunction_Check(func))) +#endif + { + if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { + return __Pyx_PyObject_CallMethO(func, NULL); + } + } + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); +} +#endif + +/* PyCFunctionFastCall */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { + PyCFunctionObject *func = (PyCFunctionObject*)func_obj; + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + int flags = PyCFunction_GET_FLAGS(func); + assert(PyCFunction_Check(func)); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + /* _PyCFunction_FastCallDict() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); + } else { + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); + } +} +#endif + +/* PyObjectCallOneArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, &arg, 1); + } +#endif + if (likely(PyCFunction_Check(func))) { + if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { + return __Pyx_PyObject_CallMethO(func, arg); +#if CYTHON_FAST_PYCCALL + } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { + return __Pyx_PyCFunction_FastCall(func, &arg, 1); +#endif + } + } + return __Pyx__PyObject_CallOneArg(func, arg); +} +#else +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_Pack(1, arg); + if (unlikely(!args)) return NULL; + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +#endif + +/* PyIntCompare */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED long inplace) { + if (op1 == op2) { + Py_RETURN_TRUE; + } + #if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(op1))) { + const long b = intval; + long a = PyInt_AS_LONG(op1); + if (a == b) Py_RETURN_TRUE; else Py_RETURN_FALSE; + } + #endif + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(PyLong_CheckExact(op1))) { + int unequal; + unsigned long uintval; + Py_ssize_t size = Py_SIZE(op1); + const digit* digits = ((PyLongObject*)op1)->ob_digit; + if (intval == 0) { + if (size == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; + } else if (intval < 0) { + if (size >= 0) + Py_RETURN_FALSE; + intval = -intval; + size = -size; + } else { + if (size <= 0) + Py_RETURN_FALSE; + } + uintval = (unsigned long) intval; +#if PyLong_SHIFT * 4 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 4)) { + unequal = (size != 5) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[4] != ((uintval >> (4 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 3 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 3)) { + unequal = (size != 4) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[3] != ((uintval >> (3 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 2 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 2)) { + unequal = (size != 3) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)) | (digits[2] != ((uintval >> (2 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif +#if PyLong_SHIFT * 1 < SIZEOF_LONG*8 + if (uintval >> (PyLong_SHIFT * 1)) { + unequal = (size != 2) || (digits[0] != (uintval & (unsigned long) PyLong_MASK)) + | (digits[1] != ((uintval >> (1 * PyLong_SHIFT)) & (unsigned long) PyLong_MASK)); + } else +#endif + unequal = (size != 1) || (((unsigned long) digits[0]) != (uintval & (unsigned long) PyLong_MASK)); + if (unequal == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; + } + #endif + if (PyFloat_CheckExact(op1)) { + const long b = intval; + double a = PyFloat_AS_DOUBLE(op1); + if ((double)a == (double)b) Py_RETURN_TRUE; else Py_RETURN_FALSE; + } + return ( + PyObject_RichCompare(op1, op2, Py_EQ)); +} + +/* PyObjectCall2Args */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args, *result = NULL; + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyFunction_FastCall(function, args, 2); + } + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyCFunction_FastCall(function, args, 2); + } + #endif + args = PyTuple_New(2); + if (unlikely(!args)) goto done; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + Py_INCREF(function); + result = __Pyx_PyObject_Call(function, args, NULL); + Py_DECREF(args); + Py_DECREF(function); +done: + return result; +} + +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (descr != NULL) { + *method = descr; + return 0; + } + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(name)); +#endif + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} + +/* PyObjectCallMethod1 */ +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); + return result; +} +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) return NULL; + return __Pyx__PyObject_CallMethod1(method, arg); +} + +/* pop_index */ +static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix) { + PyObject *r; + if (unlikely(!py_ix)) return NULL; + r = __Pyx__PyObject_PopIndex(L, py_ix); + Py_DECREF(py_ix); + return r; +} +static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix) { + return __Pyx_PyObject_CallMethod1(L, __pyx_n_s_pop, py_ix); +} +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix) { + Py_ssize_t size = PyList_GET_SIZE(L); + if (likely(size > (((PyListObject*)L)->allocated >> 1))) { + Py_ssize_t cix = ix; + if (cix < 0) { + cix += size; + } + if (likely(__Pyx_is_valid_index(cix, size))) { + PyObject* v = PyList_GET_ITEM(L, cix); + __Pyx_SET_SIZE(L, Py_SIZE(L) - 1); + size -= 1; + memmove(&PyList_GET_ITEM(L, cix), &PyList_GET_ITEM(L, cix+1), (size_t)(size-cix)*sizeof(PyObject*)); + return v; + } + } + if (py_ix == Py_None) { + return __Pyx__PyObject_PopNewIndex(L, PyInt_FromSsize_t(ix)); + } else { + return __Pyx__PyObject_PopIndex(L, py_ix); + } +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; icurexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; + if (unlikely(PyTuple_Check(err))) + return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); +} +#endif + +/* GetAttr */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { +#if CYTHON_USE_TYPE_SLOTS +#if PY_MAJOR_VERSION >= 3 + if (likely(PyUnicode_Check(n))) +#else + if (likely(PyString_Check(n))) +#endif + return __Pyx_PyObject_GetAttrStr(o, n); +#endif + return PyObject_GetAttr(o, n); +} + +/* GetAttr3 */ +static PyObject *__Pyx_GetAttr3Default(PyObject *d) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + return NULL; + __Pyx_PyErr_Clear(); + Py_INCREF(d); + return d; +} +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { + PyObject *r = __Pyx_GetAttr(o, n); + return (likely(r)) ? r : __Pyx_GetAttr3Default(d); +} + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; + } +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* HasAttr */ +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { + PyObject *r; + if (unlikely(!__Pyx_PyBaseString_Check(n))) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return -1; + } + r = __Pyx_GetAttr(o, n); + if (unlikely(!r)) { + PyErr_Clear(); + return 0; + } else { + Py_DECREF(r); + return 1; + } +} + +/* PyObject_GenericGetAttrNoDict */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, attr_name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(attr_name)); +#endif + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { + PyObject *descr; + PyTypeObject *tp = Py_TYPE(obj); + if (unlikely(!PyString_Check(attr_name))) { + return PyObject_GenericGetAttr(obj, attr_name); + } + assert(!tp->tp_dictoffset); + descr = _PyType_Lookup(tp, attr_name); + if (unlikely(!descr)) { + return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + } + Py_INCREF(descr); + #if PY_MAJOR_VERSION < 3 + if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) + #endif + { + descrgetfunc f = Py_TYPE(descr)->tp_descr_get; + if (unlikely(f)) { + PyObject *res = f(descr, obj, (PyObject *)tp); + Py_DECREF(descr); + return res; + } + } + return descr; +} +#endif + +/* PyObject_GenericGetAttr */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { + if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { + return PyObject_GenericGetAttr(obj, attr_name); + } + return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); +} +#endif + +/* SetVTable */ +static int __Pyx_SetVtable(PyObject *dict, void *vtable) { +#if PY_VERSION_HEX >= 0x02070000 + PyObject *ob = PyCapsule_New(vtable, 0, 0); +#else + PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); +#endif + if (!ob) + goto bad; + if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) + goto bad; + Py_DECREF(ob); + return 0; +bad: + Py_XDECREF(ob); + return -1; +} + +/* PyObjectGetAttrStrNoError */ +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +} + +/* SetupReduce */ +static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { + int ret; + PyObject *name_attr; + name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name); + if (likely(name_attr)) { + ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); + } else { + ret = -1; + } + if (unlikely(ret < 0)) { + PyErr_Clear(); + ret = 0; + } + Py_XDECREF(name_attr); + return ret; +} +static int __Pyx_setup_reduce(PyObject* type_obj) { + int ret = 0; + PyObject *object_reduce = NULL; + PyObject *object_reduce_ex = NULL; + PyObject *reduce = NULL; + PyObject *reduce_ex = NULL; + PyObject *reduce_cython = NULL; + PyObject *setstate = NULL; + PyObject *setstate_cython = NULL; +#if CYTHON_USE_PYTYPE_LOOKUP + if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; +#else + if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; +#endif +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#else + object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#endif + reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; + if (reduce_ex == object_reduce_ex) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#else + object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#endif + reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; + if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { + reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); + if (likely(reduce_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (reduce == object_reduce || PyErr_Occurred()) { + goto __PYX_BAD; + } + setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); + if (!setstate) PyErr_Clear(); + if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { + setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); + if (likely(setstate_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (!setstate || PyErr_Occurred()) { + goto __PYX_BAD; + } + } + PyType_Modified((PyTypeObject*)type_obj); + } + } + goto __PYX_GOOD; +__PYX_BAD: + if (!PyErr_Occurred()) + PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); + ret = -1; +__PYX_GOOD: +#if !CYTHON_USE_PYTYPE_LOOKUP + Py_XDECREF(object_reduce); + Py_XDECREF(object_reduce_ex); +#endif + Py_XDECREF(reduce); + Py_XDECREF(reduce_ex); + Py_XDECREF(reduce_cython); + Py_XDECREF(setstate); + Py_XDECREF(setstate_cython); + return ret; +} + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); + } +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = a->tp_base; + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; + if (!res) { + res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } + return res; +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; ip) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + type_name, type_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_frozenlist.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_frozenlist.cp39-win_amd64.pyd new file mode 100644 index 0000000..db45bd9 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/_frozenlist.cp39-win_amd64.pyd differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_frozenlist.pyx b/dist/ba_data/python-site-packages/aiohttp/_frozenlist.pyx new file mode 100644 index 0000000..b130577 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_frozenlist.pyx @@ -0,0 +1,108 @@ +from collections.abc import MutableSequence + + +cdef class FrozenList: + + cdef readonly bint frozen + cdef list _items + + def __init__(self, items=None): + self.frozen = False + if items is not None: + items = list(items) + else: + items = [] + self._items = items + + cdef object _check_frozen(self): + if self.frozen: + raise RuntimeError("Cannot modify frozen list.") + + cdef inline object _fast_len(self): + return len(self._items) + + def freeze(self): + self.frozen = True + + def __getitem__(self, index): + return self._items[index] + + def __setitem__(self, index, value): + self._check_frozen() + self._items[index] = value + + def __delitem__(self, index): + self._check_frozen() + del self._items[index] + + def __len__(self): + return self._fast_len() + + def __iter__(self): + return self._items.__iter__() + + def __reversed__(self): + return self._items.__reversed__() + + def __richcmp__(self, other, op): + if op == 0: # < + return list(self) < other + if op == 1: # <= + return list(self) <= other + if op == 2: # == + return list(self) == other + if op == 3: # != + return list(self) != other + if op == 4: # > + return list(self) > other + if op == 5: # => + return list(self) >= other + + def insert(self, pos, item): + self._check_frozen() + self._items.insert(pos, item) + + def __contains__(self, item): + return item in self._items + + def __iadd__(self, items): + self._check_frozen() + self._items += list(items) + return self + + def index(self, item): + return self._items.index(item) + + def remove(self, item): + self._check_frozen() + self._items.remove(item) + + def clear(self): + self._check_frozen() + self._items.clear() + + def extend(self, items): + self._check_frozen() + self._items += list(items) + + def reverse(self): + self._check_frozen() + self._items.reverse() + + def pop(self, index=-1): + self._check_frozen() + return self._items.pop(index) + + def append(self, item): + self._check_frozen() + return self._items.append(item) + + def count(self, item): + return self._items.count(item) + + def __repr__(self): + return ''.format(self.frozen, + self._items) + + +MutableSequence.register(FrozenList) diff --git a/dist/ba_data/python-site-packages/aiohttp/_headers.pxi b/dist/ba_data/python-site-packages/aiohttp/_headers.pxi new file mode 100644 index 0000000..3744721 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_headers.pxi @@ -0,0 +1,83 @@ +# The file is autogenerated from aiohttp/hdrs.py +# Run ./tools/gen.py to update it after the origin changing. + +from . import hdrs +cdef tuple headers = ( + hdrs.ACCEPT, + hdrs.ACCEPT_CHARSET, + hdrs.ACCEPT_ENCODING, + hdrs.ACCEPT_LANGUAGE, + hdrs.ACCEPT_RANGES, + hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, + hdrs.ACCESS_CONTROL_ALLOW_HEADERS, + hdrs.ACCESS_CONTROL_ALLOW_METHODS, + hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, + hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, + hdrs.ACCESS_CONTROL_MAX_AGE, + hdrs.ACCESS_CONTROL_REQUEST_HEADERS, + hdrs.ACCESS_CONTROL_REQUEST_METHOD, + hdrs.AGE, + hdrs.ALLOW, + hdrs.AUTHORIZATION, + hdrs.CACHE_CONTROL, + hdrs.CONNECTION, + hdrs.CONTENT_DISPOSITION, + hdrs.CONTENT_ENCODING, + hdrs.CONTENT_LANGUAGE, + hdrs.CONTENT_LENGTH, + hdrs.CONTENT_LOCATION, + hdrs.CONTENT_MD5, + hdrs.CONTENT_RANGE, + hdrs.CONTENT_TRANSFER_ENCODING, + hdrs.CONTENT_TYPE, + hdrs.COOKIE, + hdrs.DATE, + hdrs.DESTINATION, + hdrs.DIGEST, + hdrs.ETAG, + hdrs.EXPECT, + hdrs.EXPIRES, + hdrs.FORWARDED, + hdrs.FROM, + hdrs.HOST, + hdrs.IF_MATCH, + hdrs.IF_MODIFIED_SINCE, + hdrs.IF_NONE_MATCH, + hdrs.IF_RANGE, + hdrs.IF_UNMODIFIED_SINCE, + hdrs.KEEP_ALIVE, + hdrs.LAST_EVENT_ID, + hdrs.LAST_MODIFIED, + hdrs.LINK, + hdrs.LOCATION, + hdrs.MAX_FORWARDS, + hdrs.ORIGIN, + hdrs.PRAGMA, + hdrs.PROXY_AUTHENTICATE, + hdrs.PROXY_AUTHORIZATION, + hdrs.RANGE, + hdrs.REFERER, + hdrs.RETRY_AFTER, + hdrs.SEC_WEBSOCKET_ACCEPT, + hdrs.SEC_WEBSOCKET_EXTENSIONS, + hdrs.SEC_WEBSOCKET_KEY, + hdrs.SEC_WEBSOCKET_KEY1, + hdrs.SEC_WEBSOCKET_PROTOCOL, + hdrs.SEC_WEBSOCKET_VERSION, + hdrs.SERVER, + hdrs.SET_COOKIE, + hdrs.TE, + hdrs.TRAILER, + hdrs.TRANSFER_ENCODING, + hdrs.URI, + hdrs.UPGRADE, + hdrs.USER_AGENT, + hdrs.VARY, + hdrs.VIA, + hdrs.WWW_AUTHENTICATE, + hdrs.WANT_DIGEST, + hdrs.WARNING, + hdrs.X_FORWARDED_FOR, + hdrs.X_FORWARDED_HOST, + hdrs.X_FORWARDED_PROTO, +) diff --git a/dist/ba_data/python-site-packages/aiohttp/_helpers.c b/dist/ba_data/python-site-packages/aiohttp/_helpers.c new file mode 100644 index 0000000..e25f5ec --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_helpers.c @@ -0,0 +1,5433 @@ +/* Generated by Cython 0.29.21 */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.6+ or Python 3.3+. +#else +#define CYTHON_ABI "0_29_21" +#define CYTHON_HEX_VERSION 0x001D15F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #if PY_VERSION_HEX >= 0x02070000 + #define HAVE_LONG_LONG + #endif +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#elif defined(PYSTON_VERSION) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int32 uint32_t; + #endif + #endif +#else + #include +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) && __cplusplus >= 201103L + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #elif __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__ ) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" +#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_FAST_PYCCALL +#define __Pyx_PyFastCFunction_Check(func)\ + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) +#else +#define __Pyx_PyFastCFunction_Check(func) 0 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif +#if CYTHON_COMPILING_IN_PYSTON + #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +#else +#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) +#else + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__aiohttp___helpers +#define __PYX_HAVE_API__aiohttp___helpers +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +static PyObject *__pyx_m = NULL; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_cython_runtime = NULL; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + + +static const char *__pyx_f[] = { + "aiohttp\\_helpers.pyx", + "stringsource", +}; + +/*--- Type declarations ---*/ +struct __pyx_obj_7aiohttp_8_helpers_reify; + +/* "aiohttp/_helpers.pyx":1 + * cdef class reify: # <<<<<<<<<<<<<< + * """Use as a class method decorator. It operates almost exactly like + * the Python `@property` decorator, but it puts the result of the + */ +struct __pyx_obj_7aiohttp_8_helpers_reify { + PyObject_HEAD + PyObject *wrapped; + PyObject *name; +}; + + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* ObjectGetItem.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key); +#else +#define __Pyx_PyObject_GetItem(obj, key) PyObject_GetItem(obj, key) +#endif + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() PyErr_Occurred() +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* PyCFunctionFastCall.proto */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); +#else +#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#else +#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCall2Args.proto */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* GetAttr.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); + +/* GetAttr3.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* HasAttr.proto */ +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); + +/* PyObject_GenericGetAttrNoDict.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr +#endif + +/* PyObject_GenericGetAttr.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr +#endif + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* SetupReduce.proto */ +static int __Pyx_setup_reduce(PyObject* type_obj); + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'aiohttp._helpers' */ +static PyTypeObject *__pyx_ptype_7aiohttp_8_helpers_reify = 0; +static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(struct __pyx_obj_7aiohttp_8_helpers_reify *, PyObject *); /*proto*/ +#define __Pyx_MODULE_NAME "aiohttp._helpers" +extern int __pyx_module_is_main_aiohttp___helpers; +int __pyx_module_is_main_aiohttp___helpers = 0; + +/* Implementation of 'aiohttp._helpers' */ +static PyObject *__pyx_builtin_KeyError; +static PyObject *__pyx_builtin_AttributeError; +static const char __pyx_k_doc[] = "__doc__"; +static const char __pyx_k_new[] = "__new__"; +static const char __pyx_k_dict[] = "__dict__"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_cache[] = "_cache"; +static const char __pyx_k_reify[] = "reify"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_pickle[] = "pickle"; +static const char __pyx_k_reduce[] = "__reduce__"; +static const char __pyx_k_update[] = "update"; +static const char __pyx_k_wrapped[] = "wrapped"; +static const char __pyx_k_KeyError[] = "KeyError"; +static const char __pyx_k_getstate[] = "__getstate__"; +static const char __pyx_k_pyx_type[] = "__pyx_type"; +static const char __pyx_k_setstate[] = "__setstate__"; +static const char __pyx_k_pyx_state[] = "__pyx_state"; +static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; +static const char __pyx_k_pyx_result[] = "__pyx_result"; +static const char __pyx_k_PickleError[] = "PickleError"; +static const char __pyx_k_pyx_checksum[] = "__pyx_checksum"; +static const char __pyx_k_stringsource[] = "stringsource"; +static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; +static const char __pyx_k_AttributeError[] = "AttributeError"; +static const char __pyx_k_pyx_PickleError[] = "__pyx_PickleError"; +static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; +static const char __pyx_k_aiohttp__helpers[] = "aiohttp._helpers"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_pyx_unpickle_reify[] = "__pyx_unpickle_reify"; +static const char __pyx_k_reified_property_is_read_only[] = "reified property is read-only"; +static const char __pyx_k_Incompatible_checksums_s_vs_0x77[] = "Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))"; +static PyObject *__pyx_n_s_AttributeError; +static PyObject *__pyx_kp_s_Incompatible_checksums_s_vs_0x77; +static PyObject *__pyx_n_s_KeyError; +static PyObject *__pyx_n_s_PickleError; +static PyObject *__pyx_n_s_aiohttp__helpers; +static PyObject *__pyx_n_s_cache; +static PyObject *__pyx_n_s_cline_in_traceback; +static PyObject *__pyx_n_s_dict; +static PyObject *__pyx_n_s_doc; +static PyObject *__pyx_n_s_getstate; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_name; +static PyObject *__pyx_n_s_new; +static PyObject *__pyx_n_s_pickle; +static PyObject *__pyx_n_s_pyx_PickleError; +static PyObject *__pyx_n_s_pyx_checksum; +static PyObject *__pyx_n_s_pyx_result; +static PyObject *__pyx_n_s_pyx_state; +static PyObject *__pyx_n_s_pyx_type; +static PyObject *__pyx_n_s_pyx_unpickle_reify; +static PyObject *__pyx_n_s_reduce; +static PyObject *__pyx_n_s_reduce_cython; +static PyObject *__pyx_n_s_reduce_ex; +static PyObject *__pyx_kp_u_reified_property_is_read_only; +static PyObject *__pyx_n_s_reify; +static PyObject *__pyx_n_s_setstate; +static PyObject *__pyx_n_s_setstate_cython; +static PyObject *__pyx_kp_s_stringsource; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_n_s_update; +static PyObject *__pyx_n_s_wrapped; +static int __pyx_pf_7aiohttp_8_helpers_5reify___init__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v_wrapped); /* proto */ +static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_7__doc_____get__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_2__get__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v_inst, CYTHON_UNUSED PyObject *__pyx_v_owner); /* proto */ +static int __pyx_pf_7aiohttp_8_helpers_5reify_4__set__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_inst, CYTHON_UNUSED PyObject *__pyx_v_value); /* proto */ +static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self); /* proto */ +static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_8__setstate_cython__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v___pyx_state); /* proto */ +static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state); /* proto */ +static PyObject *__pyx_tp_new_7aiohttp_8_helpers_reify(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ +static PyObject *__pyx_int_124832655; +static PyObject *__pyx_tuple_; +static PyObject *__pyx_tuple__2; +static PyObject *__pyx_codeobj__3; +/* Late includes */ + +/* "aiohttp/_helpers.pyx":13 + * cdef object name + * + * def __init__(self, wrapped): # <<<<<<<<<<<<<< + * self.wrapped = wrapped + * self.name = wrapped.__name__ + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_8_helpers_5reify_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7aiohttp_8_helpers_5reify_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_wrapped = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_wrapped,0}; + PyObject* values[1] = {0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_wrapped)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 13, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 1) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + } + __pyx_v_wrapped = values[0]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 13, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._helpers.reify.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify___init__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self), __pyx_v_wrapped); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_8_helpers_5reify___init__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v_wrapped) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + + /* "aiohttp/_helpers.pyx":14 + * + * def __init__(self, wrapped): + * self.wrapped = wrapped # <<<<<<<<<<<<<< + * self.name = wrapped.__name__ + * + */ + __Pyx_INCREF(__pyx_v_wrapped); + __Pyx_GIVEREF(__pyx_v_wrapped); + __Pyx_GOTREF(__pyx_v_self->wrapped); + __Pyx_DECREF(__pyx_v_self->wrapped); + __pyx_v_self->wrapped = __pyx_v_wrapped; + + /* "aiohttp/_helpers.pyx":15 + * def __init__(self, wrapped): + * self.wrapped = wrapped + * self.name = wrapped.__name__ # <<<<<<<<<<<<<< + * + * @property + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_wrapped, __pyx_n_s_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_self->name); + __Pyx_DECREF(__pyx_v_self->name); + __pyx_v_self->name = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_helpers.pyx":13 + * cdef object name + * + * def __init__(self, wrapped): # <<<<<<<<<<<<<< + * self.wrapped = wrapped + * self.name = wrapped.__name__ + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._helpers.reify.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_helpers.pyx":18 + * + * @property + * def __doc__(self): # <<<<<<<<<<<<<< + * return self.wrapped.__doc__ + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_7__doc___1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_7__doc___1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_7__doc_____get__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_7__doc_____get__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + + /* "aiohttp/_helpers.pyx":19 + * @property + * def __doc__(self): + * return self.wrapped.__doc__ # <<<<<<<<<<<<<< + * + * def __get__(self, inst, owner): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->wrapped, __pyx_n_s_doc); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_helpers.pyx":18 + * + * @property + * def __doc__(self): # <<<<<<<<<<<<<< + * return self.wrapped.__doc__ + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._helpers.reify.__doc__.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_helpers.pyx":21 + * return self.wrapped.__doc__ + * + * def __get__(self, inst, owner): # <<<<<<<<<<<<<< + * try: + * try: + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_3__get__(PyObject *__pyx_v_self, PyObject *__pyx_v_inst, PyObject *__pyx_v_owner); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_3__get__(PyObject *__pyx_v_self, PyObject *__pyx_v_inst, PyObject *__pyx_v_owner) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_2__get__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self), ((PyObject *)__pyx_v_inst), ((PyObject *)__pyx_v_owner)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_2__get__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v_inst, CYTHON_UNUSED PyObject *__pyx_v_owner) { + PyObject *__pyx_v_val = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + int __pyx_t_14; + int __pyx_t_15; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + + /* "aiohttp/_helpers.pyx":22 + * + * def __get__(self, inst, owner): + * try: # <<<<<<<<<<<<<< + * try: + * return inst._cache[self.name] + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "aiohttp/_helpers.pyx":23 + * def __get__(self, inst, owner): + * try: + * try: # <<<<<<<<<<<<<< + * return inst._cache[self.name] + * except KeyError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + /*try:*/ { + + /* "aiohttp/_helpers.pyx":24 + * try: + * try: + * return inst._cache[self.name] # <<<<<<<<<<<<<< + * except KeyError: + * val = self.wrapped(inst) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_inst, __pyx_n_s_cache); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 24, __pyx_L9_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyObject_GetItem(__pyx_t_7, __pyx_v_self->name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 24, __pyx_L9_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_r = __pyx_t_8; + __pyx_t_8 = 0; + goto __pyx_L13_try_return; + + /* "aiohttp/_helpers.pyx":23 + * def __get__(self, inst, owner): + * try: + * try: # <<<<<<<<<<<<<< + * return inst._cache[self.name] + * except KeyError: + */ + } + __pyx_L9_error:; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "aiohttp/_helpers.pyx":25 + * try: + * return inst._cache[self.name] + * except KeyError: # <<<<<<<<<<<<<< + * val = self.wrapped(inst) + * inst._cache[self.name] = val + */ + __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); + if (__pyx_t_9) { + __Pyx_AddTraceback("aiohttp._helpers.reify.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_7, &__pyx_t_10) < 0) __PYX_ERR(0, 25, __pyx_L11_except_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GOTREF(__pyx_t_10); + + /* "aiohttp/_helpers.pyx":26 + * return inst._cache[self.name] + * except KeyError: + * val = self.wrapped(inst) # <<<<<<<<<<<<<< + * inst._cache[self.name] = val + * return val + */ + __Pyx_INCREF(__pyx_v_self->wrapped); + __pyx_t_12 = __pyx_v_self->wrapped; __pyx_t_13 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_12))) { + __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_12); + if (likely(__pyx_t_13)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_12); + __Pyx_INCREF(__pyx_t_13); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_12, function); + } + } + __pyx_t_11 = (__pyx_t_13) ? __Pyx_PyObject_Call2Args(__pyx_t_12, __pyx_t_13, __pyx_v_inst) : __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_v_inst); + __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 26, __pyx_L11_except_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + __pyx_v_val = __pyx_t_11; + __pyx_t_11 = 0; + + /* "aiohttp/_helpers.pyx":27 + * except KeyError: + * val = self.wrapped(inst) + * inst._cache[self.name] = val # <<<<<<<<<<<<<< + * return val + * except AttributeError: + */ + __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_inst, __pyx_n_s_cache); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 27, __pyx_L11_except_error) + __Pyx_GOTREF(__pyx_t_11); + if (unlikely(PyObject_SetItem(__pyx_t_11, __pyx_v_self->name, __pyx_v_val) < 0)) __PYX_ERR(0, 27, __pyx_L11_except_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + + /* "aiohttp/_helpers.pyx":28 + * val = self.wrapped(inst) + * inst._cache[self.name] = val + * return val # <<<<<<<<<<<<<< + * except AttributeError: + * if inst is None: + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_val); + __pyx_r = __pyx_v_val; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L12_except_return; + } + goto __pyx_L11_except_error; + __pyx_L11_except_error:; + + /* "aiohttp/_helpers.pyx":23 + * def __get__(self, inst, owner): + * try: + * try: # <<<<<<<<<<<<<< + * return inst._cache[self.name] + * except KeyError: + */ + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); + goto __pyx_L3_error; + __pyx_L13_try_return:; + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); + goto __pyx_L7_try_return; + __pyx_L12_except_return:; + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6); + goto __pyx_L7_try_return; + } + + /* "aiohttp/_helpers.pyx":22 + * + * def __get__(self, inst, owner): + * try: # <<<<<<<<<<<<<< + * try: + * return inst._cache[self.name] + */ + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + + /* "aiohttp/_helpers.pyx":29 + * inst._cache[self.name] = val + * return val + * except AttributeError: # <<<<<<<<<<<<<< + * if inst is None: + * return self + */ + __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_AttributeError); + if (__pyx_t_9) { + __Pyx_AddTraceback("aiohttp._helpers.reify.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_10, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(0, 29, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GOTREF(__pyx_t_8); + + /* "aiohttp/_helpers.pyx":30 + * return val + * except AttributeError: + * if inst is None: # <<<<<<<<<<<<<< + * return self + * raise + */ + __pyx_t_14 = (__pyx_v_inst == Py_None); + __pyx_t_15 = (__pyx_t_14 != 0); + if (__pyx_t_15) { + + /* "aiohttp/_helpers.pyx":31 + * except AttributeError: + * if inst is None: + * return self # <<<<<<<<<<<<<< + * raise + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_self)); + __pyx_r = ((PyObject *)__pyx_v_self); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L6_except_return; + + /* "aiohttp/_helpers.pyx":30 + * return val + * except AttributeError: + * if inst is None: # <<<<<<<<<<<<<< + * return self + * raise + */ + } + + /* "aiohttp/_helpers.pyx":32 + * if inst is None: + * return self + * raise # <<<<<<<<<<<<<< + * + * def __set__(self, inst, value): + */ + __Pyx_GIVEREF(__pyx_t_10); + __Pyx_GIVEREF(__pyx_t_7); + __Pyx_XGIVEREF(__pyx_t_8); + __Pyx_ErrRestoreWithState(__pyx_t_10, __pyx_t_7, __pyx_t_8); + __pyx_t_10 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; + __PYX_ERR(0, 32, __pyx_L5_except_error) + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_helpers.pyx":22 + * + * def __get__(self, inst, owner): + * try: # <<<<<<<<<<<<<< + * try: + * return inst._cache[self.name] + */ + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L7_try_return:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L0; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L0; + } + + /* "aiohttp/_helpers.pyx":21 + * return self.wrapped.__doc__ + * + * def __get__(self, inst, owner): # <<<<<<<<<<<<<< + * try: + * try: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_AddTraceback("aiohttp._helpers.reify.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_val); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_helpers.pyx":34 + * raise + * + * def __set__(self, inst, value): # <<<<<<<<<<<<<< + * raise AttributeError("reified property is read-only") + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_8_helpers_5reify_5__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_inst, PyObject *__pyx_v_value); /*proto*/ +static int __pyx_pw_7aiohttp_8_helpers_5reify_5__set__(PyObject *__pyx_v_self, PyObject *__pyx_v_inst, PyObject *__pyx_v_value) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__set__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_4__set__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self), ((PyObject *)__pyx_v_inst), ((PyObject *)__pyx_v_value)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_8_helpers_5reify_4__set__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_inst, CYTHON_UNUSED PyObject *__pyx_v_value) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__set__", 0); + + /* "aiohttp/_helpers.pyx":35 + * + * def __set__(self, inst, value): + * raise AttributeError("reified property is read-only") # <<<<<<<<<<<<<< + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_AttributeError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 35, __pyx_L1_error) + + /* "aiohttp/_helpers.pyx":34 + * raise + * + * def __set__(self, inst, value): # <<<<<<<<<<<<<< + * raise AttributeError("reified property is read-only") + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._helpers.reify.__set__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_7__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_7__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_6__reduce_cython__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self) { + PyObject *__pyx_v_state = 0; + PyObject *__pyx_v__dict = 0; + int __pyx_v_use_setstate; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":5 + * cdef object _dict + * cdef bint use_setstate + * state = (self.name, self.wrapped) # <<<<<<<<<<<<<< + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_self->name); + __Pyx_GIVEREF(__pyx_v_self->name); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->name); + __Pyx_INCREF(__pyx_v_self->wrapped); + __Pyx_GIVEREF(__pyx_v_self->wrapped); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->wrapped); + __pyx_v_state = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "(tree fragment)":6 + * cdef bint use_setstate + * state = (self.name, self.wrapped) + * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< + * if _dict is not None: + * state += (_dict,) + */ + __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v__dict = __pyx_t_1; + __pyx_t_1 = 0; + + /* "(tree fragment)":7 + * state = (self.name, self.wrapped) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True + */ + __pyx_t_2 = (__pyx_v__dict != Py_None); + __pyx_t_3 = (__pyx_t_2 != 0); + if (__pyx_t_3) { + + /* "(tree fragment)":8 + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: + * state += (_dict,) # <<<<<<<<<<<<<< + * use_setstate = True + * else: + */ + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v__dict); + __Pyx_GIVEREF(__pyx_v__dict); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict); + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_4)); + __pyx_t_4 = 0; + + /* "(tree fragment)":9 + * if _dict is not None: + * state += (_dict,) + * use_setstate = True # <<<<<<<<<<<<<< + * else: + * use_setstate = self.name is not None or self.wrapped is not None + */ + __pyx_v_use_setstate = 1; + + /* "(tree fragment)":7 + * state = (self.name, self.wrapped) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True + */ + goto __pyx_L3; + } + + /* "(tree fragment)":11 + * use_setstate = True + * else: + * use_setstate = self.name is not None or self.wrapped is not None # <<<<<<<<<<<<<< + * if use_setstate: + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state + */ + /*else*/ { + __pyx_t_2 = (__pyx_v_self->name != Py_None); + __pyx_t_5 = (__pyx_t_2 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_3 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->wrapped != Py_None); + __pyx_t_2 = (__pyx_t_5 != 0); + __pyx_t_3 = __pyx_t_2; + __pyx_L4_bool_binop_done:; + __pyx_v_use_setstate = __pyx_t_3; + } + __pyx_L3:; + + /* "(tree fragment)":12 + * else: + * use_setstate = self.name is not None or self.wrapped is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state + * else: + */ + __pyx_t_3 = (__pyx_v_use_setstate != 0); + if (__pyx_t_3) { + + /* "(tree fragment)":13 + * use_setstate = self.name is not None or self.wrapped is not None + * if use_setstate: + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state # <<<<<<<<<<<<<< + * else: + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_reify); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_INCREF(__pyx_int_124832655); + __Pyx_GIVEREF(__pyx_int_124832655); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_124832655); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None); + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_1); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_v_state); + __pyx_t_4 = 0; + __pyx_t_1 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "(tree fragment)":12 + * else: + * use_setstate = self.name is not None or self.wrapped is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state + * else: + */ + } + + /* "(tree fragment)":15 + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, None), state + * else: + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_reify__set_state(self, __pyx_state) + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pyx_unpickle_reify); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_INCREF(__pyx_int_124832655); + __Pyx_GIVEREF(__pyx_int_124832655); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_124832655); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state); + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1); + __pyx_t_6 = 0; + __pyx_t_1 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + } + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("aiohttp._helpers.reify.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_state); + __Pyx_XDECREF(__pyx_v__dict); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":16 + * else: + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_reify__set_state(self, __pyx_state) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_9__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_8_helpers_5reify_9__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_8_helpers_5reify_8__setstate_cython__(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_8_helpers_5reify_8__setstate_cython__(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":17 + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_reify__set_state(self, __pyx_state) # <<<<<<<<<<<<<< + */ + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":16 + * else: + * return __pyx_unpickle_reify, (type(self), 0x770cb8f, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_reify__set_state(self, __pyx_state) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._helpers.reify.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_7aiohttp_8_helpers_1__pyx_unpickle_reify = {"__pyx_unpickle_reify", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_7aiohttp_8_helpers_1__pyx_unpickle_reify(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v___pyx_type = 0; + long __pyx_v___pyx_checksum; + PyObject *__pyx_v___pyx_state = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__pyx_unpickle_reify (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; + PyObject* values[3] = {0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_reify", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_reify", 1, 3, 3, 2); __PYX_ERR(1, 1, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_reify") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + } + __pyx_v___pyx_type = values[0]; + __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) + __pyx_v___pyx_state = values[2]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_reify", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(1, 1, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._helpers.__pyx_unpickle_reify", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_8_helpers___pyx_unpickle_reify(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_v___pyx_PickleError = 0; + PyObject *__pyx_v___pyx_result = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_reify", 0); + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum != 0x770cb8f: # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) + */ + __pyx_t_1 = ((__pyx_v___pyx_checksum != 0x770cb8f) != 0); + if (__pyx_t_1) { + + /* "(tree fragment)":5 + * cdef object __pyx_result + * if __pyx_checksum != 0x770cb8f: + * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) + * __pyx_result = reify.__new__(__pyx_type) + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_PickleError); + __Pyx_GIVEREF(__pyx_n_s_PickleError); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_2); + __pyx_v___pyx_PickleError = __pyx_t_2; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":6 + * if __pyx_checksum != 0x770cb8f: + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) # <<<<<<<<<<<<<< + * __pyx_result = reify.__new__(__pyx_type) + * if __pyx_state is not None: + */ + __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x77, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_INCREF(__pyx_v___pyx_PickleError); + __pyx_t_2 = __pyx_v___pyx_PickleError; __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 6, __pyx_L1_error) + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum != 0x770cb8f: # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) + */ + } + + /* "(tree fragment)":7 + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) + * __pyx_result = reify.__new__(__pyx_type) # <<<<<<<<<<<<<< + * if __pyx_state is not None: + * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_8_helpers_reify), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v___pyx_result = __pyx_t_3; + __pyx_t_3 = 0; + + /* "(tree fragment)":8 + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) + * __pyx_result = reify.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) + * return __pyx_result + */ + __pyx_t_1 = (__pyx_v___pyx_state != Py_None); + __pyx_t_6 = (__pyx_t_1 != 0); + if (__pyx_t_6) { + + /* "(tree fragment)":9 + * __pyx_result = reify.__new__(__pyx_type) + * if __pyx_state is not None: + * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< + * return __pyx_result + * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): + */ + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(((struct __pyx_obj_7aiohttp_8_helpers_reify *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":8 + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x770cb8f = (name, wrapped))" % __pyx_checksum) + * __pyx_result = reify.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) + * return __pyx_result + */ + } + + /* "(tree fragment)":10 + * if __pyx_state is not None: + * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) + * return __pyx_result # <<<<<<<<<<<<<< + * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): + * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v___pyx_result); + __pyx_r = __pyx_v___pyx_result; + goto __pyx_L0; + + /* "(tree fragment)":1 + * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("aiohttp._helpers.__pyx_unpickle_reify", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v___pyx_PickleError); + __Pyx_XDECREF(__pyx_v___pyx_result); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":11 + * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): + */ + +static PyObject *__pyx_f_7aiohttp_8_helpers___pyx_unpickle_reify__set_state(struct __pyx_obj_7aiohttp_8_helpers_reify *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + Py_ssize_t __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_reify__set_state", 0); + + /* "(tree fragment)":12 + * return __pyx_result + * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): + * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] # <<<<<<<<<<<<<< + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[2]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->name); + __Pyx_DECREF(__pyx_v___pyx_result->name); + __pyx_v___pyx_result->name = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->wrapped); + __Pyx_DECREF(__pyx_v___pyx_result->wrapped); + __pyx_v___pyx_result->wrapped = __pyx_t_1; + __pyx_t_1 = 0; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): + * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[2]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(1, 13, __pyx_L1_error) + } + __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_4 = ((__pyx_t_3 > 2) != 0); + if (__pyx_t_4) { + } else { + __pyx_t_2 = __pyx_t_4; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_5 = (__pyx_t_4 != 0); + __pyx_t_2 = __pyx_t_5; + __pyx_L4_bool_binop_done:; + if (__pyx_t_2) { + + /* "(tree fragment)":14 + * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[2]) # <<<<<<<<<<<<<< + */ + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 14, __pyx_L1_error) + } + __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_8)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + } + } + __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): + * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[2]) + */ + } + + /* "(tree fragment)":11 + * __pyx_unpickle_reify__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_reify__set_state(reify __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result.name = __pyx_state[0]; __pyx_result.wrapped = __pyx_state[1] + * if len(__pyx_state) > 2 and hasattr(__pyx_result, '__dict__'): + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("aiohttp._helpers.__pyx_unpickle_reify__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_tp_new_7aiohttp_8_helpers_reify(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + struct __pyx_obj_7aiohttp_8_helpers_reify *p; + PyObject *o; + if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + p = ((struct __pyx_obj_7aiohttp_8_helpers_reify *)o); + p->wrapped = Py_None; Py_INCREF(Py_None); + p->name = Py_None; Py_INCREF(Py_None); + return o; +} + +static void __pyx_tp_dealloc_7aiohttp_8_helpers_reify(PyObject *o) { + struct __pyx_obj_7aiohttp_8_helpers_reify *p = (struct __pyx_obj_7aiohttp_8_helpers_reify *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->wrapped); + Py_CLEAR(p->name); + (*Py_TYPE(o)->tp_free)(o); +} + +static int __pyx_tp_traverse_7aiohttp_8_helpers_reify(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7aiohttp_8_helpers_reify *p = (struct __pyx_obj_7aiohttp_8_helpers_reify *)o; + if (p->wrapped) { + e = (*v)(p->wrapped, a); if (e) return e; + } + if (p->name) { + e = (*v)(p->name, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_7aiohttp_8_helpers_reify(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_7aiohttp_8_helpers_reify *p = (struct __pyx_obj_7aiohttp_8_helpers_reify *)o; + tmp = ((PyObject*)p->wrapped); + p->wrapped = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->name); + p->name = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} + +static PyObject *__pyx_tp_descr_get_7aiohttp_8_helpers_reify(PyObject *o, PyObject *i, PyObject *c) { + PyObject *r = 0; + if (!i) i = Py_None; + if (!c) c = Py_None; + r = __pyx_pw_7aiohttp_8_helpers_5reify_3__get__(o, i, c); + return r; +} + +static int __pyx_tp_descr_set_7aiohttp_8_helpers_reify(PyObject *o, PyObject *i, PyObject *v) { + if (v) { + return __pyx_pw_7aiohttp_8_helpers_5reify_5__set__(o, i, v); + } + else { + PyErr_SetString(PyExc_NotImplementedError, "__delete__"); + return -1; + } +} + +static PyObject *__pyx_getprop_7aiohttp_8_helpers_5reify___doc__(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_8_helpers_5reify_7__doc___1__get__(o); +} + +static PyMethodDef __pyx_methods_7aiohttp_8_helpers_reify[] = { + {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_8_helpers_5reify_7__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_8_helpers_5reify_9__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static struct PyGetSetDef __pyx_getsets_7aiohttp_8_helpers_reify[] = { + {(char *)"__doc__", __pyx_getprop_7aiohttp_8_helpers_5reify___doc__, 0, (char *)0, 0}, + {0, 0, 0, 0, 0} +}; + +static PyTypeObject __pyx_type_7aiohttp_8_helpers_reify = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._helpers.reify", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_8_helpers_reify), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_8_helpers_reify, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + "Use as a class method decorator. It operates almost exactly like\n the Python `@property` decorator, but it puts the result of the\n method it decorates into the instance dict after the first call,\n effectively replacing the function it decorates with an instance\n variable. It is, in Python parlance, a data descriptor.\n\n ", /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_8_helpers_reify, /*tp_traverse*/ + __pyx_tp_clear_7aiohttp_8_helpers_reify, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7aiohttp_8_helpers_reify, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_7aiohttp_8_helpers_reify, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + __pyx_tp_descr_get_7aiohttp_8_helpers_reify, /*tp_descr_get*/ + __pyx_tp_descr_set_7aiohttp_8_helpers_reify, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + __pyx_pw_7aiohttp_8_helpers_5reify_1__init__, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_8_helpers_reify, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec__helpers(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec__helpers}, + {0, NULL} +}; +#endif + +static struct PyModuleDef __pyx_moduledef = { + PyModuleDef_HEAD_INIT, + "_helpers", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1}, + {&__pyx_kp_s_Incompatible_checksums_s_vs_0x77, __pyx_k_Incompatible_checksums_s_vs_0x77, sizeof(__pyx_k_Incompatible_checksums_s_vs_0x77), 0, 0, 1, 0}, + {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1}, + {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, + {&__pyx_n_s_aiohttp__helpers, __pyx_k_aiohttp__helpers, sizeof(__pyx_k_aiohttp__helpers), 0, 0, 1, 1}, + {&__pyx_n_s_cache, __pyx_k_cache, sizeof(__pyx_k_cache), 0, 0, 1, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, + {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1}, + {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, + {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_unpickle_reify, __pyx_k_pyx_unpickle_reify, sizeof(__pyx_k_pyx_unpickle_reify), 0, 0, 1, 1}, + {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, + {&__pyx_kp_u_reified_property_is_read_only, __pyx_k_reified_property_is_read_only, sizeof(__pyx_k_reified_property_is_read_only), 0, 1, 0, 0}, + {&__pyx_n_s_reify, __pyx_k_reify, sizeof(__pyx_k_reify), 0, 0, 1, 1}, + {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, + {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, + {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, + {&__pyx_n_s_wrapped, __pyx_k_wrapped, sizeof(__pyx_k_wrapped), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 25, __pyx_L1_error) + __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) __PYX_ERR(0, 29, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "aiohttp/_helpers.pyx":35 + * + * def __set__(self, inst, value): + * raise AttributeError("reified property is read-only") # <<<<<<<<<<<<<< + */ + __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_u_reified_property_is_read_only); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + + /* "(tree fragment)":1 + * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + __pyx_tuple__2 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__2); + __Pyx_GIVEREF(__pyx_tuple__2); + __pyx_codeobj__3 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__2, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_reify, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__3)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_int_124832655 = PyInt_FromLong(124832655L); if (unlikely(!__pyx_int_124832655)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + if (PyType_Ready(&__pyx_type_7aiohttp_8_helpers_reify) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_8_helpers_reify.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_8_helpers_reify.tp_dictoffset && __pyx_type_7aiohttp_8_helpers_reify.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_8_helpers_reify.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_reify, (PyObject *)&__pyx_type_7aiohttp_8_helpers_reify) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_8_helpers_reify) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_ptype_7aiohttp_8_helpers_reify = &__pyx_type_7aiohttp_8_helpers_reify; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC init_helpers(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC init_helpers(void) +#else +__Pyx_PyMODINIT_FUNC PyInit__helpers(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit__helpers(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec__helpers(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_helpers' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__helpers(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("_helpers", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_b); + __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_cython_runtime); + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_aiohttp___helpers) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "aiohttp._helpers")) { + if (unlikely(PyDict_SetItemString(modules, "aiohttp._helpers", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_type_import_code(); + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "(tree fragment)":1 + * def __pyx_unpickle_reify(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_8_helpers_1__pyx_unpickle_reify, NULL, __pyx_n_s_aiohttp__helpers); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_reify, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_helpers.pyx":1 + * cdef class reify: # <<<<<<<<<<<<<< + * """Use as a class method decorator. It operates almost exactly like + * the Python `@property` decorator, but it puts the result of the + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init aiohttp._helpers", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_CLEAR(__pyx_m); + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init aiohttp._helpers"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* RaiseDoubleKeywords */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (!j) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (likely(m && m->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { + Py_ssize_t l = m->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return m->sq_item(o, i); + } + } +#else + if (is_list || PySequence_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* ObjectGetItem */ +#if CYTHON_USE_TYPE_SLOTS +static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) { + PyObject *runerr; + Py_ssize_t key_value; + PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence; + if (unlikely(!(m && m->sq_item))) { + PyErr_Format(PyExc_TypeError, "'%.200s' object is not subscriptable", Py_TYPE(obj)->tp_name); + return NULL; + } + key_value = __Pyx_PyIndex_AsSsize_t(index); + if (likely(key_value != -1 || !(runerr = PyErr_Occurred()))) { + return __Pyx_GetItemInt_Fast(obj, key_value, 0, 1, 1); + } + if (PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) { + PyErr_Clear(); + PyErr_Format(PyExc_IndexError, "cannot fit '%.200s' into an index-sized integer", Py_TYPE(index)->tp_name); + } + return NULL; +} +static PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* key) { + PyMappingMethods *m = Py_TYPE(obj)->tp_as_mapping; + if (likely(m && m->mp_subscript)) { + return m->mp_subscript(obj, key); + } + return __Pyx_PyObject_GetIndex(obj, key); +} +#endif + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + #endif + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; icurexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; + if (unlikely(PyTuple_Check(err))) + return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); +} +#endif + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type, *local_value, *local_tb; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* PyCFunctionFastCall */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { + PyCFunctionObject *func = (PyCFunctionObject*)func_obj; + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + int flags = PyCFunction_GET_FLAGS(func); + assert(PyCFunction_Check(func)); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + /* _PyCFunction_FastCallDict() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); + } else { + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); + } +} +#endif + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { + return NULL; + } + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif +#endif + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCall2Args */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args, *result = NULL; + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyFunction_FastCall(function, args, 2); + } + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyCFunction_FastCall(function, args, 2); + } + #endif + args = PyTuple_New(2); + if (unlikely(!args)) goto done; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + Py_INCREF(function); + result = __Pyx_PyObject_Call(function, args, NULL); + Py_DECREF(args); + Py_DECREF(function); +done: + return result; +} + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = PyCFunction_GET_FUNCTION(func); + self = PyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallOneArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, &arg, 1); + } +#endif + if (likely(PyCFunction_Check(func))) { + if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { + return __Pyx_PyObject_CallMethO(func, arg); +#if CYTHON_FAST_PYCCALL + } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { + return __Pyx_PyCFunction_FastCall(func, &arg, 1); +#endif + } + } + return __Pyx__PyObject_CallOneArg(func, arg); +} +#else +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_Pack(1, arg); + if (unlikely(!args)) return NULL; + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + __Pyx_PyThreadState_declare + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if CYTHON_COMPILING_IN_PYPY + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#else + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* GetAttr */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { +#if CYTHON_USE_TYPE_SLOTS +#if PY_MAJOR_VERSION >= 3 + if (likely(PyUnicode_Check(n))) +#else + if (likely(PyString_Check(n))) +#endif + return __Pyx_PyObject_GetAttrStr(o, n); +#endif + return PyObject_GetAttr(o, n); +} + +/* GetAttr3 */ +static PyObject *__Pyx_GetAttr3Default(PyObject *d) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + return NULL; + __Pyx_PyErr_Clear(); + Py_INCREF(d); + return d; +} +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { + PyObject *r = __Pyx_GetAttr(o, n); + return (likely(r)) ? r : __Pyx_GetAttr3Default(d); +} + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; + } +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* HasAttr */ +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { + PyObject *r; + if (unlikely(!__Pyx_PyBaseString_Check(n))) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return -1; + } + r = __Pyx_GetAttr(o, n); + if (unlikely(!r)) { + PyErr_Clear(); + return 0; + } else { + Py_DECREF(r); + return 1; + } +} + +/* PyObject_GenericGetAttrNoDict */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, attr_name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(attr_name)); +#endif + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { + PyObject *descr; + PyTypeObject *tp = Py_TYPE(obj); + if (unlikely(!PyString_Check(attr_name))) { + return PyObject_GenericGetAttr(obj, attr_name); + } + assert(!tp->tp_dictoffset); + descr = _PyType_Lookup(tp, attr_name); + if (unlikely(!descr)) { + return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + } + Py_INCREF(descr); + #if PY_MAJOR_VERSION < 3 + if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) + #endif + { + descrgetfunc f = Py_TYPE(descr)->tp_descr_get; + if (unlikely(f)) { + PyObject *res = f(descr, obj, (PyObject *)tp); + Py_DECREF(descr); + return res; + } + } + return descr; +} +#endif + +/* PyObject_GenericGetAttr */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { + if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { + return PyObject_GenericGetAttr(obj, attr_name); + } + return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +} + +/* SetupReduce */ +static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { + int ret; + PyObject *name_attr; + name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name); + if (likely(name_attr)) { + ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); + } else { + ret = -1; + } + if (unlikely(ret < 0)) { + PyErr_Clear(); + ret = 0; + } + Py_XDECREF(name_attr); + return ret; +} +static int __Pyx_setup_reduce(PyObject* type_obj) { + int ret = 0; + PyObject *object_reduce = NULL; + PyObject *object_reduce_ex = NULL; + PyObject *reduce = NULL; + PyObject *reduce_ex = NULL; + PyObject *reduce_cython = NULL; + PyObject *setstate = NULL; + PyObject *setstate_cython = NULL; +#if CYTHON_USE_PYTYPE_LOOKUP + if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; +#else + if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; +#endif +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#else + object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#endif + reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; + if (reduce_ex == object_reduce_ex) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#else + object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#endif + reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; + if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { + reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); + if (likely(reduce_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (reduce == object_reduce || PyErr_Occurred()) { + goto __PYX_BAD; + } + setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); + if (!setstate) PyErr_Clear(); + if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { + setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); + if (likely(setstate_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (!setstate || PyErr_Occurred()) { + goto __PYX_BAD; + } + } + PyType_Modified((PyTypeObject*)type_obj); + } + } + goto __PYX_GOOD; +__PYX_BAD: + if (!PyErr_Occurred()) + PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); + ret = -1; +__PYX_GOOD: +#if !CYTHON_USE_PYTYPE_LOOKUP + Py_XDECREF(object_reduce); + Py_XDECREF(object_reduce_ex); +#endif + Py_XDECREF(reduce); + Py_XDECREF(reduce_ex); + Py_XDECREF(reduce_cython); + Py_XDECREF(setstate); + Py_XDECREF(setstate_cython); + return ret; +} + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = a->tp_base; + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; + if (!res) { + res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } + return res; +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; ip) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + type_name, type_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_helpers.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_helpers.cp39-win_amd64.pyd new file mode 100644 index 0000000..46b55ca Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/_helpers.cp39-win_amd64.pyd differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_helpers.pyi b/dist/ba_data/python-site-packages/aiohttp/_helpers.pyi new file mode 100644 index 0000000..1e35893 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_helpers.pyi @@ -0,0 +1,6 @@ +from typing import Any + +class reify: + def __init__(self, wrapped: Any) -> None: ... + def __get__(self, inst: Any, owner: Any) -> Any: ... + def __set__(self, inst: Any, value: Any) -> None: ... diff --git a/dist/ba_data/python-site-packages/aiohttp/_helpers.pyx b/dist/ba_data/python-site-packages/aiohttp/_helpers.pyx new file mode 100644 index 0000000..665f367 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_helpers.pyx @@ -0,0 +1,35 @@ +cdef class reify: + """Use as a class method decorator. It operates almost exactly like + the Python `@property` decorator, but it puts the result of the + method it decorates into the instance dict after the first call, + effectively replacing the function it decorates with an instance + variable. It is, in Python parlance, a data descriptor. + + """ + + cdef object wrapped + cdef object name + + def __init__(self, wrapped): + self.wrapped = wrapped + self.name = wrapped.__name__ + + @property + def __doc__(self): + return self.wrapped.__doc__ + + def __get__(self, inst, owner): + try: + try: + return inst._cache[self.name] + except KeyError: + val = self.wrapped(inst) + inst._cache[self.name] = val + return val + except AttributeError: + if inst is None: + return self + raise + + def __set__(self, inst, value): + raise AttributeError("reified property is read-only") diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_parser.c b/dist/ba_data/python-site-packages/aiohttp/_http_parser.c new file mode 100644 index 0000000..9920ca9 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_http_parser.c @@ -0,0 +1,24607 @@ +/* Generated by Cython 0.29.21 */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.6+ or Python 3.3+. +#else +#define CYTHON_ABI "0_29_21" +#define CYTHON_HEX_VERSION 0x001D15F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #if PY_VERSION_HEX >= 0x02070000 + #define HAVE_LONG_LONG + #endif +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#elif defined(PYSTON_VERSION) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int32 uint32_t; + #endif + #endif +#else + #include +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) && __cplusplus >= 201103L + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #elif __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__ ) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" +#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_FAST_PYCCALL +#define __Pyx_PyFastCFunction_Check(func)\ + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) +#else +#define __Pyx_PyFastCFunction_Check(func) 0 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif +#if CYTHON_COMPILING_IN_PYSTON + #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +#else +#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) +#else + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__aiohttp___http_parser +#define __PYX_HAVE_API__aiohttp___http_parser +/* Early includes */ +#include +#include +#include "pythread.h" +#include +#include +#include "../vendor/http-parser/http_parser.h" +#include "_find_header.h" +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +static PyObject *__pyx_m = NULL; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_cython_runtime = NULL; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + + +static const char *__pyx_f[] = { + "aiohttp\\_http_parser.pyx", + "stringsource", + "type.pxd", + "bool.pxd", + "complex.pxd", + "aiohttp\\_headers.pxi", +}; + +/*--- Type declarations ---*/ +struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage; +struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage; +struct __pyx_obj_7aiohttp_12_http_parser_HttpParser; +struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser; +struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser; +struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__; +struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr; +struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__; +struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr; +struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init; + +/* "aiohttp/_http_parser.pyx":327 + * PyMem_Free(self._csettings) + * + * cdef _init(self, cparser.http_parser_type mode, # <<<<<<<<<<<<<< + * object protocol, object loop, int limit, + * object timer=None, + */ +struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init { + int __pyx_n; + PyObject *timer; + size_t max_line_size; + size_t max_headers; + size_t max_field_size; + PyObject *payload_exception; + int response_with_body; + int read_until_eof; + int auto_decompress; +}; + +/* "aiohttp/_http_parser.pyx":110 + * + * @cython.freelist(DEFAULT_FREELIST_SIZE) + * cdef class RawRequestMessage: # <<<<<<<<<<<<<< + * cdef readonly str method + * cdef readonly str path + */ +struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage { + PyObject_HEAD + PyObject *method; + PyObject *path; + PyObject *version; + PyObject *headers; + PyObject *raw_headers; + PyObject *should_close; + PyObject *compression; + PyObject *upgrade; + PyObject *chunked; + PyObject *url; +}; + + +/* "aiohttp/_http_parser.pyx":210 + * + * @cython.freelist(DEFAULT_FREELIST_SIZE) + * cdef class RawResponseMessage: # <<<<<<<<<<<<<< + * cdef readonly object version # HttpVersion + * cdef readonly int code + */ +struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage { + PyObject_HEAD + PyObject *version; + int code; + PyObject *reason; + PyObject *headers; + PyObject *raw_headers; + PyObject *should_close; + PyObject *compression; + PyObject *upgrade; + PyObject *chunked; +}; + + +/* "aiohttp/_http_parser.pyx":272 + * + * @cython.internal + * cdef class HttpParser: # <<<<<<<<<<<<<< + * + * cdef: + */ +struct __pyx_obj_7aiohttp_12_http_parser_HttpParser { + PyObject_HEAD + struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *__pyx_vtab; + struct http_parser *_cparser; + struct http_parser_settings *_csettings; + PyObject *_raw_name; + PyObject *_raw_value; + int _has_value; + PyObject *_protocol; + PyObject *_loop; + PyObject *_timer; + size_t _max_line_size; + size_t _max_field_size; + size_t _max_headers; + int _response_with_body; + int _read_until_eof; + int _started; + PyObject *_url; + PyObject *_buf; + PyObject *_path; + PyObject *_reason; + PyObject *_headers; + PyObject *_raw_headers; + int _upgraded; + PyObject *_messages; + PyObject *_payload; + int _payload_error; + PyObject *_payload_exception; + PyObject *_last_error; + int _auto_decompress; + int _limit; + PyObject *_content_encoding; + Py_buffer py_buf; +}; + + +/* "aiohttp/_http_parser.pyx":563 + * + * + * cdef class HttpRequestParser(HttpParser): # <<<<<<<<<<<<<< + * + * def __init__(self, protocol, loop, int limit, timer=None, + */ +struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser __pyx_base; +}; + + +/* "aiohttp/_http_parser.pyx":591 + * + * + * cdef class HttpResponseParser(HttpParser): # <<<<<<<<<<<<<< + * + * def __init__(self, protocol, loop, int limit, timer=None, + */ +struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser __pyx_base; +}; + + +/* "aiohttp/_http_parser.pyx":135 + * self.url = url + * + * def __repr__(self): # <<<<<<<<<<<<<< + * info = [] + * info.append(("method", self.method)) + */ +struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ { + PyObject_HEAD + PyObject *__pyx_v_info; +}; + + +/* "aiohttp/_http_parser.pyx":147 + * info.append(("chunked", self.chunked)) + * info.append(("url", self.url)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< + * return '' + * + */ +struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr { + PyObject_HEAD + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *__pyx_outer_scope; + PyObject *__pyx_v_name; + PyObject *__pyx_v_val; +}; + + +/* "aiohttp/_http_parser.pyx":233 + * self.chunked = chunked + * + * def __repr__(self): # <<<<<<<<<<<<<< + * info = [] + * info.append(("version", self.version)) + */ +struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ { + PyObject_HEAD + PyObject *__pyx_v_info; +}; + + +/* "aiohttp/_http_parser.pyx":244 + * info.append(("upgrade", self.upgrade)) + * info.append(("chunked", self.chunked)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< + * return '' + * + */ +struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr { + PyObject_HEAD + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *__pyx_outer_scope; + PyObject *__pyx_v_name; + PyObject *__pyx_v_val; +}; + + + +/* "aiohttp/_http_parser.pyx":272 + * + * @cython.internal + * cdef class HttpParser: # <<<<<<<<<<<<<< + * + * cdef: + */ + +struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser { + PyObject *(*_init)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, enum http_parser_type, PyObject *, PyObject *, int, struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init *__pyx_optional_args); + PyObject *(*_process_header)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); + PyObject *(*_on_header_field)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, char *, size_t); + PyObject *(*_on_header_value)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, char *, size_t); + PyObject *(*_on_headers_complete)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); + PyObject *(*_on_message_complete)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); + PyObject *(*_on_chunk_header)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); + PyObject *(*_on_chunk_complete)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); + PyObject *(*_on_status_complete)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); + PyObject *(*http_version)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); +}; +static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *__pyx_vtabptr_7aiohttp_12_http_parser_HttpParser; +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *); + + +/* "aiohttp/_http_parser.pyx":563 + * + * + * cdef class HttpRequestParser(HttpParser): # <<<<<<<<<<<<<< + * + * def __init__(self, protocol, loop, int limit, timer=None, + */ + +struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpRequestParser { + struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser __pyx_base; +}; +static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpRequestParser *__pyx_vtabptr_7aiohttp_12_http_parser_HttpRequestParser; + + +/* "aiohttp/_http_parser.pyx":591 + * + * + * cdef class HttpResponseParser(HttpParser): # <<<<<<<<<<<<<< + * + * def __init__(self, protocol, loop, int limit, timer=None, + */ + +struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpResponseParser { + struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser __pyx_base; +}; +static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpResponseParser *__pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser; + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* GetItemInt.proto */ +#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\ + (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\ + __Pyx_GetItemInt_Generic(o, to_py_func(i)))) +#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\ + (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\ + __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\ + (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL)) +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + int wraparound, int boundscheck); +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, + int is_list, int wraparound, int boundscheck); + +/* decode_c_string_utf16.proto */ +static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16(const char *s, Py_ssize_t size, const char *errors) { + int byteorder = 0; + return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); +} +static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16LE(const char *s, Py_ssize_t size, const char *errors) { + int byteorder = -1; + return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); +} +static CYTHON_INLINE PyObject *__Pyx_PyUnicode_DecodeUTF16BE(const char *s, Py_ssize_t size, const char *errors) { + int byteorder = 1; + return PyUnicode_DecodeUTF16(s, size, errors, &byteorder); +} + +/* decode_c_bytes.proto */ +static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( + const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, + const char* encoding, const char* errors, + PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); + +/* decode_bytes.proto */ +static CYTHON_INLINE PyObject* __Pyx_decode_bytes( + PyObject* string, Py_ssize_t start, Py_ssize_t stop, + const char* encoding, const char* errors, + PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { + return __Pyx_decode_c_bytes( + PyBytes_AS_STRING(string), PyBytes_GET_SIZE(string), + start, stop, encoding, errors, decode_func); +} + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* None.proto */ +static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname); + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* ListCompAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len)) { + Py_INCREF(x); + PyList_SET_ITEM(list, len, x); + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) +#endif + +/* ListAppend.proto */ +#if CYTHON_USE_PYLIST_INTERNALS && CYTHON_ASSUME_SAFE_MACROS +static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { + PyListObject* L = (PyListObject*) list; + Py_ssize_t len = Py_SIZE(list); + if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { + Py_INCREF(x); + PyList_SET_ITEM(list, len, x); + __Pyx_SET_SIZE(list, len + 1); + return 0; + } + return PyList_Append(list, x); +} +#else +#define __Pyx_PyList_Append(L,x) PyList_Append(L,x) +#endif + +/* KeywordStringCheck.proto */ +static int __Pyx_CheckKeywordStrings(PyObject *kwdict, const char* function_name, int kw_allowed); + +/* ExtTypeTest.proto */ +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); + +/* PyDictContains.proto */ +static CYTHON_INLINE int __Pyx_PyDict_ContainsTF(PyObject* item, PyObject* dict, int eq) { + int result = PyDict_Contains(dict, item); + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* DictGetItem.proto */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key); +#define __Pyx_PyObject_Dict_GetItem(obj, name)\ + (likely(PyDict_CheckExact(obj)) ?\ + __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name)) +#else +#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) +#define __Pyx_PyObject_Dict_GetItem(obj, name) PyObject_GetItem(obj, name) +#endif + +/* PyErrExceptionMatches.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* GetAttr.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); + +/* GetAttr3.proto */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#else +#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectCallNoArg.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); +#else +#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) +#endif + +/* PyCFunctionFastCall.proto */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); +#else +#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* PyObjectCall2Args.proto */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PySequenceContains.proto */ +static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { + int result = PySequence_Contains(seq, item); + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* IncludeStringH.proto */ +#include + +/* BytesEquals.proto */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* SliceObject.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice( + PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop, + PyObject** py_start, PyObject** py_stop, PyObject** py_slice, + int has_cstart, int has_cstop, int wraparound); + +/* decode_bytearray.proto */ +static CYTHON_INLINE PyObject* __Pyx_decode_bytearray( + PyObject* string, Py_ssize_t start, Py_ssize_t stop, + const char* encoding, const char* errors, + PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { + return __Pyx_decode_c_bytes( + PyByteArray_AS_STRING(string), PyByteArray_GET_SIZE(string), + start, stop, encoding, errors, decode_func); +} + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* SwapException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* decode_c_string.proto */ +static CYTHON_INLINE PyObject* __Pyx_decode_c_string( + const char* cstring, Py_ssize_t start, Py_ssize_t stop, + const char* encoding, const char* errors, + PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); + +/* UnpackUnboundCMethod.proto */ +typedef struct { + PyObject *type; + PyObject **method_name; + PyCFunction func; + PyObject *method; + int flag; +} __Pyx_CachedCFunction; + +/* CallUnboundCMethod1.proto */ +static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); +#else +#define __Pyx_CallUnboundCMethod1(cfunc, self, arg) __Pyx__CallUnboundCMethod1(cfunc, self, arg) +#endif + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* HasAttr.proto */ +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); + +/* PyObject_GenericGetAttrNoDict.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttrNoDict PyObject_GenericGetAttr +#endif + +/* PyObject_GenericGetAttr.proto */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GenericGetAttr PyObject_GenericGetAttr +#endif + +/* PyObjectGetAttrStrNoError.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* SetupReduce.proto */ +static int __Pyx_setup_reduce(PyObject* type_obj); + +/* SetVTable.proto */ +static int __Pyx_SetVtable(PyObject *dict, void *vtable); + +/* TypeImport.proto */ +#ifndef __PYX_HAVE_RT_ImportType_proto +#define __PYX_HAVE_RT_ImportType_proto +enum __Pyx_ImportType_CheckSize { + __Pyx_ImportType_CheckSize_Error = 0, + __Pyx_ImportType_CheckSize_Warn = 1, + __Pyx_ImportType_CheckSize_Ignore = 2 +}; +static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); +#endif + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint16_t(uint16_t value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE enum http_method __Pyx_PyInt_As_enum__http_method(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* FetchCommonType.proto */ +static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +/* PyObjectCallMethod1.proto */ +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); + +/* CoroutineBase.proto */ +typedef PyObject *(*__pyx_coroutine_body_t)(PyObject *, PyThreadState *, PyObject *); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_ExcInfoStruct _PyErr_StackItem +#else +typedef struct { + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_traceback; +} __Pyx_ExcInfoStruct; +#endif +typedef struct { + PyObject_HEAD + __pyx_coroutine_body_t body; + PyObject *closure; + __Pyx_ExcInfoStruct gi_exc_state; + PyObject *gi_weakreflist; + PyObject *classobj; + PyObject *yieldfrom; + PyObject *gi_name; + PyObject *gi_qualname; + PyObject *gi_modulename; + PyObject *gi_code; + int resume_label; + char is_running; +} __pyx_CoroutineObject; +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name); +static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *self); +static int __Pyx_Coroutine_clear(PyObject *self); +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); +static PyObject *__Pyx_Coroutine_Close(PyObject *self); +static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); +#if CYTHON_USE_EXC_INFO_STACK +#define __Pyx_Coroutine_SwapException(self) +#define __Pyx_Coroutine_ResetAndClearException(self) __Pyx_Coroutine_ExceptionClear(&(self)->gi_exc_state) +#else +#define __Pyx_Coroutine_SwapException(self) {\ + __Pyx_ExceptionSwap(&(self)->gi_exc_state.exc_type, &(self)->gi_exc_state.exc_value, &(self)->gi_exc_state.exc_traceback);\ + __Pyx_Coroutine_ResetFrameBackpointer(&(self)->gi_exc_state);\ + } +#define __Pyx_Coroutine_ResetAndClearException(self) {\ + __Pyx_ExceptionReset((self)->gi_exc_state.exc_type, (self)->gi_exc_state.exc_value, (self)->gi_exc_state.exc_traceback);\ + (self)->gi_exc_state.exc_type = (self)->gi_exc_state.exc_value = (self)->gi_exc_state.exc_traceback = NULL;\ + } +#endif +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__pyx_tstate, pvalue) +#else +#define __Pyx_PyGen_FetchStopIterationValue(pvalue)\ + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, pvalue) +#endif +static int __Pyx_PyGen__FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue); +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state); + +/* PatchModuleWithCoroutine.proto */ +static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); + +/* PatchGeneratorABC.proto */ +static int __Pyx_patch_abc(void); + +/* Generator.proto */ +#define __Pyx_Generator_USED +static PyTypeObject *__pyx_GeneratorType = 0; +#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType) +#define __Pyx_Generator_New(body, code, closure, name, qualname, module_name)\ + __Pyx__Coroutine_New(__pyx_GeneratorType, body, code, closure, name, qualname, module_name) +static PyObject *__Pyx_Generator_Next(PyObject *self); +static int __pyx_Generator_init(void); + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__init(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, enum http_parser_type __pyx_v_mode, PyObject *__pyx_v_protocol, PyObject *__pyx_v_loop, int __pyx_v_limit, struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init *__pyx_optional_args); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__process_header(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_field(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, char *__pyx_v_at, size_t __pyx_v_length); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_value(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, char *__pyx_v_at, size_t __pyx_v_length); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_message_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_header(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_status_complete(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self); /* proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_18HttpResponseParser__on_status_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self); /* proto*/ + +/* Module declarations from 'cpython.version' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.type' */ +static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from 'cpython.object' */ + +/* Module declarations from 'cpython.ref' */ + +/* Module declarations from 'cpython.exc' */ + +/* Module declarations from 'cpython.module' */ + +/* Module declarations from 'cpython.mem' */ + +/* Module declarations from 'cpython.tuple' */ + +/* Module declarations from 'cpython.list' */ + +/* Module declarations from 'cpython.sequence' */ + +/* Module declarations from 'cpython.mapping' */ + +/* Module declarations from 'cpython.iterator' */ + +/* Module declarations from 'cpython.number' */ + +/* Module declarations from 'cpython.int' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.bool' */ +static PyTypeObject *__pyx_ptype_7cpython_4bool_bool = 0; + +/* Module declarations from 'cpython.long' */ + +/* Module declarations from 'cpython.float' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.complex' */ +static PyTypeObject *__pyx_ptype_7cpython_7complex_complex = 0; + +/* Module declarations from 'cpython.string' */ + +/* Module declarations from 'cpython.unicode' */ + +/* Module declarations from 'cpython.dict' */ + +/* Module declarations from 'cpython.instance' */ + +/* Module declarations from 'cpython.function' */ + +/* Module declarations from 'cpython.method' */ + +/* Module declarations from 'cpython.weakref' */ + +/* Module declarations from 'cpython.getargs' */ + +/* Module declarations from 'cpython.pythread' */ + +/* Module declarations from 'cpython.pystate' */ + +/* Module declarations from 'cpython.cobject' */ + +/* Module declarations from 'cpython.oldbuffer' */ + +/* Module declarations from 'cpython.set' */ + +/* Module declarations from 'cpython.buffer' */ + +/* Module declarations from 'cpython.bytes' */ + +/* Module declarations from 'cpython.pycapsule' */ + +/* Module declarations from 'cpython' */ + +/* Module declarations from 'libc.limits' */ + +/* Module declarations from 'cython' */ + +/* Module declarations from 'aiohttp' */ + +/* Module declarations from 'libc.stdint' */ + +/* Module declarations from 'aiohttp._cparser' */ + +/* Module declarations from 'aiohttp._find_header' */ + +/* Module declarations from 'aiohttp._http_parser' */ +static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage = 0; +static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage = 0; +static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_HttpParser = 0; +static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_HttpRequestParser = 0; +static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser_HttpResponseParser = 0; +static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct____repr__ = 0; +static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr = 0; +static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ = 0; +static PyTypeObject *__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_headers = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_URL = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_URL_build = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_CIMultiDict = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_HttpVersion = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_HttpVersion10 = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_HttpVersion11 = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1 = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_StreamReader = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser_DeflateBuffer = 0; +static PyObject *__pyx_v_7aiohttp_12_http_parser__http_method = 0; +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_extend(PyObject *, char const *, size_t); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_http_method_str(int); /*proto*/ +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_find_header(PyObject *); /*proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser__new_request_message(PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *, int, int, PyObject *); /*proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser__new_response_message(PyObject *, int, PyObject *, PyObject *, PyObject *, int, PyObject *, int, int); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_message_begin(struct http_parser *); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_url(struct http_parser *, char const *, size_t); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_status(struct http_parser *, char const *, size_t); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_field(struct http_parser *, char const *, size_t); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_value(struct http_parser *, char const *, size_t); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_headers_complete(struct http_parser *); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *, char const *, size_t); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_message_complete(struct http_parser *); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_header(struct http_parser *); /*proto*/ +static int __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_complete(struct http_parser *); /*proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum http_errno); /*proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *, size_t); /*proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *, PyObject *); /*proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *, PyObject *); /*proto*/ +#define __Pyx_MODULE_NAME "aiohttp._http_parser" +extern int __pyx_module_is_main_aiohttp___http_parser; +int __pyx_module_is_main_aiohttp___http_parser = 0; + +/* Implementation of 'aiohttp._http_parser' */ +static PyObject *__pyx_builtin_range; +static PyObject *__pyx_builtin_MemoryError; +static PyObject *__pyx_builtin_TypeError; +static PyObject *__pyx_builtin_BaseException; +static const char __pyx_k_[] = "="; +static const char __pyx_k_i[] = "i"; +static const char __pyx_k_TE[] = "TE"; +static const char __pyx_k__2[] = ", "; +static const char __pyx_k__3[] = ")>"; +static const char __pyx_k__4[] = ""; +static const char __pyx_k_br[] = "br"; +static const char __pyx_k_AGE[] = "AGE"; +static const char __pyx_k_URI[] = "URI"; +static const char __pyx_k_URL[] = "URL"; +static const char __pyx_k_VIA[] = "VIA"; +static const char __pyx_k__11[] = ":"; +static const char __pyx_k_add[] = "add"; +static const char __pyx_k_all[] = "__all__"; +static const char __pyx_k_new[] = "__new__"; +static const char __pyx_k_url[] = "url"; +static const char __pyx_k_DATE[] = "DATE"; +static const char __pyx_k_ETAG[] = "ETAG"; +static const char __pyx_k_FROM[] = "FROM"; +static const char __pyx_k_HOST[] = "HOST"; +static const char __pyx_k_LINK[] = "LINK"; +static const char __pyx_k_VARY[] = "VARY"; +static const char __pyx_k_args[] = "args"; +static const char __pyx_k_code[] = "code"; +static const char __pyx_k_dict[] = "__dict__"; +static const char __pyx_k_gzip[] = "gzip"; +static const char __pyx_k_hdrs[] = "hdrs"; +static const char __pyx_k_host[] = "host"; +static const char __pyx_k_loop[] = "loop"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_path[] = "path"; +static const char __pyx_k_port[] = "port"; +static const char __pyx_k_send[] = "send"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_user[] = "user"; +static const char __pyx_k_yarl[] = "yarl"; +static const char __pyx_k_ALLOW[] = "ALLOW"; +static const char __pyx_k_RANGE[] = "RANGE"; +static const char __pyx_k_URL_2[] = "_URL"; +static const char __pyx_k_build[] = "build"; +static const char __pyx_k_close[] = "close"; +static const char __pyx_k_limit[] = "limit"; +static const char __pyx_k_lower[] = "lower"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_throw[] = "throw"; +static const char __pyx_k_timer[] = "timer"; +static const char __pyx_k_ACCEPT[] = "ACCEPT"; +static const char __pyx_k_COOKIE[] = "COOKIE"; +static const char __pyx_k_DIGEST[] = "DIGEST"; +static const char __pyx_k_EXPECT[] = "EXPECT"; +static const char __pyx_k_ORIGIN[] = "ORIGIN"; +static const char __pyx_k_PRAGMA[] = "PRAGMA"; +static const char __pyx_k_SERVER[] = "SERVER"; +static const char __pyx_k_format[] = "format"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_method[] = "method"; +static const char __pyx_k_pickle[] = "pickle"; +static const char __pyx_k_py_buf[] = "py_buf"; +static const char __pyx_k_reason[] = "reason"; +static const char __pyx_k_reduce[] = "__reduce__"; +static const char __pyx_k_scheme[] = "scheme"; +static const char __pyx_k_update[] = "update"; +static const char __pyx_k_EXPIRES[] = "EXPIRES"; +static const char __pyx_k_REFERER[] = "REFERER"; +static const char __pyx_k_TRAILER[] = "TRAILER"; +static const char __pyx_k_UPGRADE[] = "UPGRADE"; +static const char __pyx_k_WARNING[] = "WARNING"; +static const char __pyx_k_aiohttp[] = "aiohttp"; +static const char __pyx_k_chunked[] = "chunked"; +static const char __pyx_k_deflate[] = "deflate"; +static const char __pyx_k_encoded[] = "encoded"; +static const char __pyx_k_genexpr[] = "genexpr"; +static const char __pyx_k_headers[] = "headers"; +static const char __pyx_k_streams[] = "streams"; +static const char __pyx_k_unknown[] = ""; +static const char __pyx_k_upgrade[] = "upgrade"; +static const char __pyx_k_version[] = "version"; +static const char __pyx_k_IF_MATCH[] = "IF_MATCH"; +static const char __pyx_k_IF_RANGE[] = "IF_RANGE"; +static const char __pyx_k_LOCATION[] = "LOCATION"; +static const char __pyx_k_buf_data[] = "buf_data"; +static const char __pyx_k_feed_eof[] = "feed_eof"; +static const char __pyx_k_fragment[] = "fragment"; +static const char __pyx_k_getstate[] = "__getstate__"; +static const char __pyx_k_password[] = "password"; +static const char __pyx_k_protocol[] = "protocol"; +static const char __pyx_k_pyx_type[] = "__pyx_type"; +static const char __pyx_k_setstate[] = "__setstate__"; +static const char __pyx_k_FORWARDED[] = "FORWARDED"; +static const char __pyx_k_TypeError[] = "TypeError"; +static const char __pyx_k_feed_data[] = "feed_data"; +static const char __pyx_k_multidict[] = "multidict"; +static const char __pyx_k_parse_url[] = "parse_url"; +static const char __pyx_k_partition[] = "partition"; +static const char __pyx_k_pyx_state[] = "__pyx_state"; +static const char __pyx_k_reduce_ex[] = "__reduce_ex__"; +static const char __pyx_k_CONNECTION[] = "CONNECTION"; +static const char __pyx_k_KEEP_ALIVE[] = "KEEP_ALIVE"; +static const char __pyx_k_SET_COOKIE[] = "SET_COOKIE"; +static const char __pyx_k_USER_AGENT[] = "USER_AGENT"; +static const char __pyx_k_pyx_result[] = "__pyx_result"; +static const char __pyx_k_pyx_vtable[] = "__pyx_vtable__"; +static const char __pyx_k_CIMultiDict[] = "CIMultiDict"; +static const char __pyx_k_CONTENT_MD5[] = "CONTENT_MD5"; +static const char __pyx_k_DESTINATION[] = "DESTINATION"; +static const char __pyx_k_HttpVersion[] = "HttpVersion"; +static const char __pyx_k_LineTooLong[] = "LineTooLong"; +static const char __pyx_k_MemoryError[] = "MemoryError"; +static const char __pyx_k_PickleError[] = "PickleError"; +static const char __pyx_k_RETRY_AFTER[] = "RETRY_AFTER"; +static const char __pyx_k_WANT_DIGEST[] = "WANT_DIGEST"; +static const char __pyx_k_compression[] = "compression"; +static const char __pyx_k_http_parser[] = "http_parser"; +static const char __pyx_k_http_writer[] = "http_writer"; +static const char __pyx_k_max_headers[] = "max_headers"; +static const char __pyx_k_raw_headers[] = "raw_headers"; +static const char __pyx_k_CONTENT_TYPE[] = "CONTENT_TYPE"; +static const char __pyx_k_MAX_FORWARDS[] = "MAX_FORWARDS"; +static const char __pyx_k_StreamReader[] = "StreamReader"; +static const char __pyx_k_pyx_checksum[] = "__pyx_checksum"; +static const char __pyx_k_query_string[] = "query_string"; +static const char __pyx_k_should_close[] = "should_close"; +static const char __pyx_k_stringsource[] = "stringsource"; +static const char __pyx_k_ACCEPT_RANGES[] = "ACCEPT_RANGES"; +static const char __pyx_k_AUTHORIZATION[] = "AUTHORIZATION"; +static const char __pyx_k_BadStatusLine[] = "BadStatusLine"; +static const char __pyx_k_BaseException[] = "BaseException"; +static const char __pyx_k_CACHE_CONTROL[] = "CACHE_CONTROL"; +static const char __pyx_k_CIMultiDict_2[] = "_CIMultiDict"; +static const char __pyx_k_CONTENT_RANGE[] = "CONTENT_RANGE"; +static const char __pyx_k_DeflateBuffer[] = "DeflateBuffer"; +static const char __pyx_k_EMPTY_PAYLOAD[] = "EMPTY_PAYLOAD"; +static const char __pyx_k_HttpVersion10[] = "HttpVersion10"; +static const char __pyx_k_HttpVersion11[] = "HttpVersion11"; +static const char __pyx_k_HttpVersion_2[] = "_HttpVersion"; +static const char __pyx_k_IF_NONE_MATCH[] = "IF_NONE_MATCH"; +static const char __pyx_k_InvalidHeader[] = "InvalidHeader"; +static const char __pyx_k_LAST_EVENT_ID[] = "LAST_EVENT_ID"; +static const char __pyx_k_LAST_MODIFIED[] = "LAST_MODIFIED"; +static const char __pyx_k_invalid_url_r[] = "invalid url {!r}"; +static const char __pyx_k_max_line_size[] = "max_line_size"; +static const char __pyx_k_reduce_cython[] = "__reduce_cython__"; +static const char __pyx_k_set_exception[] = "set_exception"; +static const char __pyx_k_ACCEPT_CHARSET[] = "ACCEPT_CHARSET"; +static const char __pyx_k_BadHttpMessage[] = "BadHttpMessage"; +static const char __pyx_k_CONTENT_LENGTH[] = "CONTENT_LENGTH"; +static const char __pyx_k_StreamReader_2[] = "_StreamReader"; +static const char __pyx_k_max_field_size[] = "max_field_size"; +static const char __pyx_k_read_until_eof[] = "read_until_eof"; +static const char __pyx_k_ACCEPT_ENCODING[] = "ACCEPT_ENCODING"; +static const char __pyx_k_ACCEPT_LANGUAGE[] = "ACCEPT_LANGUAGE"; +static const char __pyx_k_DeflateBuffer_2[] = "_DeflateBuffer"; +static const char __pyx_k_EMPTY_PAYLOAD_2[] = "_EMPTY_PAYLOAD"; +static const char __pyx_k_HttpVersion10_2[] = "_HttpVersion10"; +static const char __pyx_k_HttpVersion11_2[] = "_HttpVersion11"; +static const char __pyx_k_InvalidURLError[] = "InvalidURLError"; +static const char __pyx_k_X_FORWARDED_FOR[] = "X_FORWARDED_FOR"; +static const char __pyx_k_auto_decompress[] = "auto_decompress"; +static const char __pyx_k_http_exceptions[] = "http_exceptions"; +static const char __pyx_k_pyx_PickleError[] = "__pyx_PickleError"; +static const char __pyx_k_setstate_cython[] = "__setstate_cython__"; +static const char __pyx_k_CIMultiDictProxy[] = "CIMultiDictProxy"; +static const char __pyx_k_CONTENT_ENCODING[] = "CONTENT_ENCODING"; +static const char __pyx_k_CONTENT_LANGUAGE[] = "CONTENT_LANGUAGE"; +static const char __pyx_k_CONTENT_LOCATION[] = "CONTENT_LOCATION"; +static const char __pyx_k_WWW_AUTHENTICATE[] = "WWW_AUTHENTICATE"; +static const char __pyx_k_X_FORWARDED_HOST[] = "X_FORWARDED_HOST"; +static const char __pyx_k_HttpRequestParser[] = "HttpRequestParser"; +static const char __pyx_k_IF_MODIFIED_SINCE[] = "IF_MODIFIED_SINCE"; +static const char __pyx_k_RawRequestMessage[] = "_http_method[i] + */ + +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_http_method_str(int __pyx_v_i) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("http_method_str", 0); + + /* "aiohttp/_http_parser.pyx":93 + * + * cdef inline str http_method_str(int i): + * if i < METHODS_COUNT: # <<<<<<<<<<<<<< + * return _http_method[i] + * else: + */ + __pyx_t_1 = ((__pyx_v_i < 34) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":94 + * cdef inline str http_method_str(int i): + * if i < METHODS_COUNT: + * return _http_method[i] # <<<<<<<<<<<<<< + * else: + * return "" + */ + __Pyx_XDECREF(__pyx_r); + if (unlikely(__pyx_v_7aiohttp_12_http_parser__http_method == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(0, 94, __pyx_L1_error) + } + __pyx_t_2 = __Pyx_GetItemInt_List(__pyx_v_7aiohttp_12_http_parser__http_method, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 94, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(((PyObject*)__pyx_t_2)); + __pyx_r = ((PyObject*)__pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":93 + * + * cdef inline str http_method_str(int i): + * if i < METHODS_COUNT: # <<<<<<<<<<<<<< + * return _http_method[i] + * else: + */ + } + + /* "aiohttp/_http_parser.pyx":96 + * return _http_method[i] + * else: + * return "" # <<<<<<<<<<<<<< + * + * cdef inline object find_header(bytes raw_header): + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_kp_u_unknown); + __pyx_r = __pyx_kp_u_unknown; + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":92 + * + * + * cdef inline str http_method_str(int i): # <<<<<<<<<<<<<< + * if i < METHODS_COUNT: + * return _http_method[i] + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("aiohttp._http_parser.http_method_str", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":98 + * return "" + * + * cdef inline object find_header(bytes raw_header): # <<<<<<<<<<<<<< + * cdef Py_ssize_t size + * cdef char *buf + */ + +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_find_header(PyObject *__pyx_v_raw_header) { + Py_ssize_t __pyx_v_size; + char *__pyx_v_buf; + int __pyx_v_idx; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("find_header", 0); + + /* "aiohttp/_http_parser.pyx":102 + * cdef char *buf + * cdef int idx + * PyBytes_AsStringAndSize(raw_header, &buf, &size) # <<<<<<<<<<<<<< + * idx = _find_header.find_header(buf, size) + * if idx == -1: + */ + __pyx_t_1 = PyBytes_AsStringAndSize(__pyx_v_raw_header, (&__pyx_v_buf), (&__pyx_v_size)); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 102, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":103 + * cdef int idx + * PyBytes_AsStringAndSize(raw_header, &buf, &size) + * idx = _find_header.find_header(buf, size) # <<<<<<<<<<<<<< + * if idx == -1: + * return raw_header.decode('utf-8', 'surrogateescape') + */ + __pyx_v_idx = find_header(__pyx_v_buf, __pyx_v_size); + + /* "aiohttp/_http_parser.pyx":104 + * PyBytes_AsStringAndSize(raw_header, &buf, &size) + * idx = _find_header.find_header(buf, size) + * if idx == -1: # <<<<<<<<<<<<<< + * return raw_header.decode('utf-8', 'surrogateescape') + * return headers[idx] + */ + __pyx_t_2 = ((__pyx_v_idx == -1L) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_parser.pyx":105 + * idx = _find_header.find_header(buf, size) + * if idx == -1: + * return raw_header.decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * return headers[idx] + * + */ + __Pyx_XDECREF(__pyx_r); + if (unlikely(__pyx_v_raw_header == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "decode"); + __PYX_ERR(0, 105, __pyx_L1_error) + } + __pyx_t_3 = __Pyx_decode_bytes(__pyx_v_raw_header, 0, PY_SSIZE_T_MAX, NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 105, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":104 + * PyBytes_AsStringAndSize(raw_header, &buf, &size) + * idx = _find_header.find_header(buf, size) + * if idx == -1: # <<<<<<<<<<<<<< + * return raw_header.decode('utf-8', 'surrogateescape') + * return headers[idx] + */ + } + + /* "aiohttp/_http_parser.pyx":106 + * if idx == -1: + * return raw_header.decode('utf-8', 'surrogateescape') + * return headers[idx] # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + if (unlikely(__pyx_v_7aiohttp_12_http_parser_headers == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(0, 106, __pyx_L1_error) + } + __pyx_t_3 = __Pyx_GetItemInt_Tuple(__pyx_v_7aiohttp_12_http_parser_headers, __pyx_v_idx, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 106, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":98 + * return "" + * + * cdef inline object find_header(bytes raw_header): # <<<<<<<<<<<<<< + * cdef Py_ssize_t size + * cdef char *buf + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._http_parser.find_header", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":122 + * cdef readonly object url # yarl.URL + * + * def __init__(self, method, path, version, headers, raw_headers, # <<<<<<<<<<<<<< + * should_close, compression, upgrade, chunked, url): + * self.method = method + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_method = 0; + PyObject *__pyx_v_path = 0; + PyObject *__pyx_v_version = 0; + PyObject *__pyx_v_headers = 0; + PyObject *__pyx_v_raw_headers = 0; + PyObject *__pyx_v_should_close = 0; + PyObject *__pyx_v_compression = 0; + PyObject *__pyx_v_upgrade = 0; + PyObject *__pyx_v_chunked = 0; + PyObject *__pyx_v_url = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_method,&__pyx_n_s_path,&__pyx_n_s_version,&__pyx_n_s_headers,&__pyx_n_s_raw_headers,&__pyx_n_s_should_close,&__pyx_n_s_compression,&__pyx_n_s_upgrade,&__pyx_n_s_chunked,&__pyx_n_s_url,0}; + PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + CYTHON_FALLTHROUGH; + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_method)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_path)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 1); __PYX_ERR(0, 122, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_version)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 2); __PYX_ERR(0, 122, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_headers)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 3); __PYX_ERR(0, 122, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_raw_headers)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 4); __PYX_ERR(0, 122, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_should_close)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 5); __PYX_ERR(0, 122, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_compression)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 6); __PYX_ERR(0, 122, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_upgrade)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 7); __PYX_ERR(0, 122, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_chunked)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 8); __PYX_ERR(0, 122, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 9: + if (likely((values[9] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_url)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, 9); __PYX_ERR(0, 122, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 122, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 10) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + } + __pyx_v_method = values[0]; + __pyx_v_path = values[1]; + __pyx_v_version = values[2]; + __pyx_v_headers = values[3]; + __pyx_v_raw_headers = values[4]; + __pyx_v_should_close = values[5]; + __pyx_v_compression = values[6]; + __pyx_v_upgrade = values[7]; + __pyx_v_chunked = values[8]; + __pyx_v_url = values[9]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 1, 10, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 122, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage___init__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self), __pyx_v_method, __pyx_v_path, __pyx_v_version, __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_compression, __pyx_v_upgrade, __pyx_v_chunked, __pyx_v_url); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage___init__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self, PyObject *__pyx_v_method, PyObject *__pyx_v_path, PyObject *__pyx_v_version, PyObject *__pyx_v_headers, PyObject *__pyx_v_raw_headers, PyObject *__pyx_v_should_close, PyObject *__pyx_v_compression, PyObject *__pyx_v_upgrade, PyObject *__pyx_v_chunked, PyObject *__pyx_v_url) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + + /* "aiohttp/_http_parser.pyx":124 + * def __init__(self, method, path, version, headers, raw_headers, + * should_close, compression, upgrade, chunked, url): + * self.method = method # <<<<<<<<<<<<<< + * self.path = path + * self.version = version + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_method))||((__pyx_v_method) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_method)->tp_name), 0))) __PYX_ERR(0, 124, __pyx_L1_error) + __pyx_t_1 = __pyx_v_method; + __Pyx_INCREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_self->method); + __Pyx_DECREF(__pyx_v_self->method); + __pyx_v_self->method = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":125 + * should_close, compression, upgrade, chunked, url): + * self.method = method + * self.path = path # <<<<<<<<<<<<<< + * self.version = version + * self.headers = headers + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_path))||((__pyx_v_path) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_path)->tp_name), 0))) __PYX_ERR(0, 125, __pyx_L1_error) + __pyx_t_1 = __pyx_v_path; + __Pyx_INCREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_self->path); + __Pyx_DECREF(__pyx_v_self->path); + __pyx_v_self->path = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":126 + * self.method = method + * self.path = path + * self.version = version # <<<<<<<<<<<<<< + * self.headers = headers + * self.raw_headers = raw_headers + */ + __Pyx_INCREF(__pyx_v_version); + __Pyx_GIVEREF(__pyx_v_version); + __Pyx_GOTREF(__pyx_v_self->version); + __Pyx_DECREF(__pyx_v_self->version); + __pyx_v_self->version = __pyx_v_version; + + /* "aiohttp/_http_parser.pyx":127 + * self.path = path + * self.version = version + * self.headers = headers # <<<<<<<<<<<<<< + * self.raw_headers = raw_headers + * self.should_close = should_close + */ + __Pyx_INCREF(__pyx_v_headers); + __Pyx_GIVEREF(__pyx_v_headers); + __Pyx_GOTREF(__pyx_v_self->headers); + __Pyx_DECREF(__pyx_v_self->headers); + __pyx_v_self->headers = __pyx_v_headers; + + /* "aiohttp/_http_parser.pyx":128 + * self.version = version + * self.headers = headers + * self.raw_headers = raw_headers # <<<<<<<<<<<<<< + * self.should_close = should_close + * self.compression = compression + */ + __Pyx_INCREF(__pyx_v_raw_headers); + __Pyx_GIVEREF(__pyx_v_raw_headers); + __Pyx_GOTREF(__pyx_v_self->raw_headers); + __Pyx_DECREF(__pyx_v_self->raw_headers); + __pyx_v_self->raw_headers = __pyx_v_raw_headers; + + /* "aiohttp/_http_parser.pyx":129 + * self.headers = headers + * self.raw_headers = raw_headers + * self.should_close = should_close # <<<<<<<<<<<<<< + * self.compression = compression + * self.upgrade = upgrade + */ + __Pyx_INCREF(__pyx_v_should_close); + __Pyx_GIVEREF(__pyx_v_should_close); + __Pyx_GOTREF(__pyx_v_self->should_close); + __Pyx_DECREF(__pyx_v_self->should_close); + __pyx_v_self->should_close = __pyx_v_should_close; + + /* "aiohttp/_http_parser.pyx":130 + * self.raw_headers = raw_headers + * self.should_close = should_close + * self.compression = compression # <<<<<<<<<<<<<< + * self.upgrade = upgrade + * self.chunked = chunked + */ + __Pyx_INCREF(__pyx_v_compression); + __Pyx_GIVEREF(__pyx_v_compression); + __Pyx_GOTREF(__pyx_v_self->compression); + __Pyx_DECREF(__pyx_v_self->compression); + __pyx_v_self->compression = __pyx_v_compression; + + /* "aiohttp/_http_parser.pyx":131 + * self.should_close = should_close + * self.compression = compression + * self.upgrade = upgrade # <<<<<<<<<<<<<< + * self.chunked = chunked + * self.url = url + */ + __Pyx_INCREF(__pyx_v_upgrade); + __Pyx_GIVEREF(__pyx_v_upgrade); + __Pyx_GOTREF(__pyx_v_self->upgrade); + __Pyx_DECREF(__pyx_v_self->upgrade); + __pyx_v_self->upgrade = __pyx_v_upgrade; + + /* "aiohttp/_http_parser.pyx":132 + * self.compression = compression + * self.upgrade = upgrade + * self.chunked = chunked # <<<<<<<<<<<<<< + * self.url = url + * + */ + __Pyx_INCREF(__pyx_v_chunked); + __Pyx_GIVEREF(__pyx_v_chunked); + __Pyx_GOTREF(__pyx_v_self->chunked); + __Pyx_DECREF(__pyx_v_self->chunked); + __pyx_v_self->chunked = __pyx_v_chunked; + + /* "aiohttp/_http_parser.pyx":133 + * self.upgrade = upgrade + * self.chunked = chunked + * self.url = url # <<<<<<<<<<<<<< + * + * def __repr__(self): + */ + __Pyx_INCREF(__pyx_v_url); + __Pyx_GIVEREF(__pyx_v_url); + __Pyx_GOTREF(__pyx_v_self->url); + __Pyx_DECREF(__pyx_v_self->url); + __pyx_v_self->url = __pyx_v_url; + + /* "aiohttp/_http_parser.pyx":122 + * cdef readonly object url # yarl.URL + * + * def __init__(self, method, path, version, headers, raw_headers, # <<<<<<<<<<<<<< + * should_close, compression, upgrade, chunked, url): + * self.method = method + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":135 + * self.url = url + * + * def __repr__(self): # <<<<<<<<<<<<<< + * info = [] + * info.append(("method", self.method)) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3__repr__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3__repr__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_2__repr__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "aiohttp/_http_parser.pyx":147 + * info.append(("chunked", self.chunked)) + * info.append(("url", self.url)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< + * return '' + * + */ + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___genexpr(PyObject *__pyx_self) { + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr(__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 147, __pyx_L1_error) + } else { + __Pyx_GOTREF(__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *) __pyx_self; + __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope)); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___2generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_repr___locals_genexpr, __pyx_n_s_aiohttp__http_parser); if (unlikely(!gen)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__repr__.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF(((PyObject *)__pyx_cur_scope)); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *__pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 147, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_info)) { __Pyx_RaiseClosureNameError("info"); __PYX_ERR(0, 147, __pyx_L1_error) } + if (unlikely(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_info == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + __PYX_ERR(0, 147, __pyx_L1_error) + } + __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_info; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; + for (;;) { + if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 147, __pyx_L1_error) + #else + __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 147, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_4 = PyList_GET_ITEM(sequence, 0); + __pyx_t_5 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + #else + __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = Py_TYPE(__pyx_t_6)->tp_iternext; + index = 0; __pyx_t_4 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_4)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + index = 1; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 2) < 0) __PYX_ERR(0, 147, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 147, __pyx_L1_error) + __pyx_L7_unpacking_done:; + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_name); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_name, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_val); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_val, __pyx_t_5); + __Pyx_GIVEREF(__pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_cur_scope->__pyx_v_name, __pyx_kp_u_); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyObject_Repr(__pyx_cur_scope->__pyx_v_val); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = PyNumber_Add(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":135 + * self.url = url + * + * def __repr__(self): # <<<<<<<<<<<<<< + * info = [] + * info.append(("method", self.method)) + */ + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_2__repr__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *__pyx_cur_scope; + PyObject *__pyx_v_sinfo = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__repr__", 0); + __pyx_cur_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct____repr__(__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct____repr__, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 135, __pyx_L1_error) + } else { + __Pyx_GOTREF(__pyx_cur_scope); + } + + /* "aiohttp/_http_parser.pyx":136 + * + * def __repr__(self): + * info = [] # <<<<<<<<<<<<<< + * info.append(("method", self.method)) + * info.append(("path", self.path)) + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 136, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_cur_scope->__pyx_v_info = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":137 + * def __repr__(self): + * info = [] + * info.append(("method", self.method)) # <<<<<<<<<<<<<< + * info.append(("path", self.path)) + * info.append(("version", self.version)) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_method); + __Pyx_GIVEREF(__pyx_n_u_method); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_method); + __Pyx_INCREF(__pyx_v_self->method); + __Pyx_GIVEREF(__pyx_v_self->method); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->method); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 137, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":138 + * info = [] + * info.append(("method", self.method)) + * info.append(("path", self.path)) # <<<<<<<<<<<<<< + * info.append(("version", self.version)) + * info.append(("headers", self.headers)) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 138, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_path); + __Pyx_GIVEREF(__pyx_n_u_path); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_path); + __Pyx_INCREF(__pyx_v_self->path); + __Pyx_GIVEREF(__pyx_v_self->path); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->path); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 138, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":139 + * info.append(("method", self.method)) + * info.append(("path", self.path)) + * info.append(("version", self.version)) # <<<<<<<<<<<<<< + * info.append(("headers", self.headers)) + * info.append(("raw_headers", self.raw_headers)) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 139, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_version); + __Pyx_GIVEREF(__pyx_n_u_version); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_version); + __Pyx_INCREF(__pyx_v_self->version); + __Pyx_GIVEREF(__pyx_v_self->version); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->version); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 139, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":140 + * info.append(("path", self.path)) + * info.append(("version", self.version)) + * info.append(("headers", self.headers)) # <<<<<<<<<<<<<< + * info.append(("raw_headers", self.raw_headers)) + * info.append(("should_close", self.should_close)) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_headers); + __Pyx_GIVEREF(__pyx_n_u_headers); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_headers); + __Pyx_INCREF(__pyx_v_self->headers); + __Pyx_GIVEREF(__pyx_v_self->headers); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->headers); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 140, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":141 + * info.append(("version", self.version)) + * info.append(("headers", self.headers)) + * info.append(("raw_headers", self.raw_headers)) # <<<<<<<<<<<<<< + * info.append(("should_close", self.should_close)) + * info.append(("compression", self.compression)) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_raw_headers); + __Pyx_GIVEREF(__pyx_n_u_raw_headers); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_raw_headers); + __Pyx_INCREF(__pyx_v_self->raw_headers); + __Pyx_GIVEREF(__pyx_v_self->raw_headers); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->raw_headers); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 141, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":142 + * info.append(("headers", self.headers)) + * info.append(("raw_headers", self.raw_headers)) + * info.append(("should_close", self.should_close)) # <<<<<<<<<<<<<< + * info.append(("compression", self.compression)) + * info.append(("upgrade", self.upgrade)) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_should_close); + __Pyx_GIVEREF(__pyx_n_u_should_close); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_should_close); + __Pyx_INCREF(__pyx_v_self->should_close); + __Pyx_GIVEREF(__pyx_v_self->should_close); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->should_close); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 142, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":143 + * info.append(("raw_headers", self.raw_headers)) + * info.append(("should_close", self.should_close)) + * info.append(("compression", self.compression)) # <<<<<<<<<<<<<< + * info.append(("upgrade", self.upgrade)) + * info.append(("chunked", self.chunked)) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 143, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_compression); + __Pyx_GIVEREF(__pyx_n_u_compression); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_compression); + __Pyx_INCREF(__pyx_v_self->compression); + __Pyx_GIVEREF(__pyx_v_self->compression); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->compression); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 143, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":144 + * info.append(("should_close", self.should_close)) + * info.append(("compression", self.compression)) + * info.append(("upgrade", self.upgrade)) # <<<<<<<<<<<<<< + * info.append(("chunked", self.chunked)) + * info.append(("url", self.url)) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 144, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_upgrade); + __Pyx_GIVEREF(__pyx_n_u_upgrade); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_upgrade); + __Pyx_INCREF(__pyx_v_self->upgrade); + __Pyx_GIVEREF(__pyx_v_self->upgrade); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->upgrade); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 144, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":145 + * info.append(("compression", self.compression)) + * info.append(("upgrade", self.upgrade)) + * info.append(("chunked", self.chunked)) # <<<<<<<<<<<<<< + * info.append(("url", self.url)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_chunked); + __Pyx_GIVEREF(__pyx_n_u_chunked); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_chunked); + __Pyx_INCREF(__pyx_v_self->chunked); + __Pyx_GIVEREF(__pyx_v_self->chunked); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->chunked); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 145, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":146 + * info.append(("upgrade", self.upgrade)) + * info.append(("chunked", self.chunked)) + * info.append(("url", self.url)) # <<<<<<<<<<<<<< + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + * return '' + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_url); + __Pyx_GIVEREF(__pyx_n_u_url); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_url); + __Pyx_INCREF(__pyx_v_self->url); + __Pyx_GIVEREF(__pyx_v_self->url); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->url); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 146, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":147 + * info.append(("chunked", self.chunked)) + * info.append(("url", self.url)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< + * return '' + * + */ + __pyx_t_1 = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_8__repr___genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_Generator_Next(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyUnicode_Join(__pyx_kp_u__2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 147, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_sinfo = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":148 + * info.append(("url", self.url)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + * return '' # <<<<<<<<<<<<<< + * + * def _replace(self, **dct): + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyUnicode_ConcatSafe(__pyx_kp_u_RawRequestMessage, __pyx_v_sinfo); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_t_1, __pyx_kp_u__3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 148, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":135 + * self.url = url + * + * def __repr__(self): # <<<<<<<<<<<<<< + * info = [] + * info.append(("method", self.method)) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_sinfo); + __Pyx_DECREF(((PyObject *)__pyx_cur_scope)); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":150 + * return '' + * + * def _replace(self, **dct): # <<<<<<<<<<<<<< + * cdef RawRequestMessage ret + * ret = _new_request_message(self.method, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_5_replace(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_5_replace(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_dct = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_replace (wrapper)", 0); + if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) { + __Pyx_RaiseArgtupleInvalid("_replace", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return NULL;} + if (__pyx_kwds && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "_replace", 1))) return NULL; + __pyx_v_dct = (__pyx_kwds) ? PyDict_Copy(__pyx_kwds) : PyDict_New(); if (unlikely(!__pyx_v_dct)) return NULL; + __Pyx_GOTREF(__pyx_v_dct); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_4_replace(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self), __pyx_v_dct); + + /* function exit code */ + __Pyx_XDECREF(__pyx_v_dct); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_4_replace(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self, PyObject *__pyx_v_dct) { + struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_ret = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_replace", 0); + + /* "aiohttp/_http_parser.pyx":152 + * def _replace(self, **dct): + * cdef RawRequestMessage ret + * ret = _new_request_message(self.method, # <<<<<<<<<<<<<< + * self.path, + * self.version, + */ + __pyx_t_1 = __pyx_v_self->method; + __Pyx_INCREF(__pyx_t_1); + + /* "aiohttp/_http_parser.pyx":153 + * cdef RawRequestMessage ret + * ret = _new_request_message(self.method, + * self.path, # <<<<<<<<<<<<<< + * self.version, + * self.headers, + */ + __pyx_t_2 = __pyx_v_self->path; + __Pyx_INCREF(__pyx_t_2); + + /* "aiohttp/_http_parser.pyx":154 + * ret = _new_request_message(self.method, + * self.path, + * self.version, # <<<<<<<<<<<<<< + * self.headers, + * self.raw_headers, + */ + __pyx_t_3 = __pyx_v_self->version; + __Pyx_INCREF(__pyx_t_3); + + /* "aiohttp/_http_parser.pyx":155 + * self.path, + * self.version, + * self.headers, # <<<<<<<<<<<<<< + * self.raw_headers, + * self.should_close, + */ + __pyx_t_4 = __pyx_v_self->headers; + __Pyx_INCREF(__pyx_t_4); + + /* "aiohttp/_http_parser.pyx":156 + * self.version, + * self.headers, + * self.raw_headers, # <<<<<<<<<<<<<< + * self.should_close, + * self.compression, + */ + __pyx_t_5 = __pyx_v_self->raw_headers; + __Pyx_INCREF(__pyx_t_5); + + /* "aiohttp/_http_parser.pyx":157 + * self.headers, + * self.raw_headers, + * self.should_close, # <<<<<<<<<<<<<< + * self.compression, + * self.upgrade, + */ + __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_self->should_close); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 157, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":158 + * self.raw_headers, + * self.should_close, + * self.compression, # <<<<<<<<<<<<<< + * self.upgrade, + * self.chunked, + */ + __pyx_t_7 = __pyx_v_self->compression; + __Pyx_INCREF(__pyx_t_7); + + /* "aiohttp/_http_parser.pyx":159 + * self.should_close, + * self.compression, + * self.upgrade, # <<<<<<<<<<<<<< + * self.chunked, + * self.url) + */ + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_v_self->upgrade); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 159, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":160 + * self.compression, + * self.upgrade, + * self.chunked, # <<<<<<<<<<<<<< + * self.url) + * if "method" in dct: + */ + __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_v_self->chunked); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 160, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":161 + * self.upgrade, + * self.chunked, + * self.url) # <<<<<<<<<<<<<< + * if "method" in dct: + * ret.method = dct["method"] + */ + __pyx_t_10 = __pyx_v_self->url; + __Pyx_INCREF(__pyx_t_10); + + /* "aiohttp/_http_parser.pyx":152 + * def _replace(self, **dct): + * cdef RawRequestMessage ret + * ret = _new_request_message(self.method, # <<<<<<<<<<<<<< + * self.path, + * self.version, + */ + __pyx_t_11 = __pyx_f_7aiohttp_12_http_parser__new_request_message(((PyObject*)__pyx_t_1), ((PyObject*)__pyx_t_2), __pyx_t_3, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7, __pyx_t_8, __pyx_t_9, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 152, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (!(likely(((__pyx_t_11) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_11, __pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage))))) __PYX_ERR(0, 152, __pyx_L1_error) + __pyx_v_ret = ((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_t_11); + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":162 + * self.chunked, + * self.url) + * if "method" in dct: # <<<<<<<<<<<<<< + * ret.method = dct["method"] + * if "path" in dct: + */ + __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_method, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 162, __pyx_L1_error) + __pyx_t_8 = (__pyx_t_9 != 0); + if (__pyx_t_8) { + + /* "aiohttp/_http_parser.pyx":163 + * self.url) + * if "method" in dct: + * ret.method = dct["method"] # <<<<<<<<<<<<<< + * if "path" in dct: + * ret.path = dct["path"] + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_method); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 163, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + if (!(likely(PyUnicode_CheckExact(__pyx_t_11))||((__pyx_t_11) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_11)->tp_name), 0))) __PYX_ERR(0, 163, __pyx_L1_error) + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->method); + __Pyx_DECREF(__pyx_v_ret->method); + __pyx_v_ret->method = ((PyObject*)__pyx_t_11); + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":162 + * self.chunked, + * self.url) + * if "method" in dct: # <<<<<<<<<<<<<< + * ret.method = dct["method"] + * if "path" in dct: + */ + } + + /* "aiohttp/_http_parser.pyx":164 + * if "method" in dct: + * ret.method = dct["method"] + * if "path" in dct: # <<<<<<<<<<<<<< + * ret.path = dct["path"] + * if "version" in dct: + */ + __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_path, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 164, __pyx_L1_error) + __pyx_t_9 = (__pyx_t_8 != 0); + if (__pyx_t_9) { + + /* "aiohttp/_http_parser.pyx":165 + * ret.method = dct["method"] + * if "path" in dct: + * ret.path = dct["path"] # <<<<<<<<<<<<<< + * if "version" in dct: + * ret.version = dct["version"] + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_path); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 165, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + if (!(likely(PyUnicode_CheckExact(__pyx_t_11))||((__pyx_t_11) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_11)->tp_name), 0))) __PYX_ERR(0, 165, __pyx_L1_error) + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->path); + __Pyx_DECREF(__pyx_v_ret->path); + __pyx_v_ret->path = ((PyObject*)__pyx_t_11); + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":164 + * if "method" in dct: + * ret.method = dct["method"] + * if "path" in dct: # <<<<<<<<<<<<<< + * ret.path = dct["path"] + * if "version" in dct: + */ + } + + /* "aiohttp/_http_parser.pyx":166 + * if "path" in dct: + * ret.path = dct["path"] + * if "version" in dct: # <<<<<<<<<<<<<< + * ret.version = dct["version"] + * if "headers" in dct: + */ + __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_version, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 166, __pyx_L1_error) + __pyx_t_8 = (__pyx_t_9 != 0); + if (__pyx_t_8) { + + /* "aiohttp/_http_parser.pyx":167 + * ret.path = dct["path"] + * if "version" in dct: + * ret.version = dct["version"] # <<<<<<<<<<<<<< + * if "headers" in dct: + * ret.headers = dct["headers"] + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_version); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 167, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->version); + __Pyx_DECREF(__pyx_v_ret->version); + __pyx_v_ret->version = __pyx_t_11; + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":166 + * if "path" in dct: + * ret.path = dct["path"] + * if "version" in dct: # <<<<<<<<<<<<<< + * ret.version = dct["version"] + * if "headers" in dct: + */ + } + + /* "aiohttp/_http_parser.pyx":168 + * if "version" in dct: + * ret.version = dct["version"] + * if "headers" in dct: # <<<<<<<<<<<<<< + * ret.headers = dct["headers"] + * if "raw_headers" in dct: + */ + __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_headers, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 168, __pyx_L1_error) + __pyx_t_9 = (__pyx_t_8 != 0); + if (__pyx_t_9) { + + /* "aiohttp/_http_parser.pyx":169 + * ret.version = dct["version"] + * if "headers" in dct: + * ret.headers = dct["headers"] # <<<<<<<<<<<<<< + * if "raw_headers" in dct: + * ret.raw_headers = dct["raw_headers"] + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_headers); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 169, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->headers); + __Pyx_DECREF(__pyx_v_ret->headers); + __pyx_v_ret->headers = __pyx_t_11; + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":168 + * if "version" in dct: + * ret.version = dct["version"] + * if "headers" in dct: # <<<<<<<<<<<<<< + * ret.headers = dct["headers"] + * if "raw_headers" in dct: + */ + } + + /* "aiohttp/_http_parser.pyx":170 + * if "headers" in dct: + * ret.headers = dct["headers"] + * if "raw_headers" in dct: # <<<<<<<<<<<<<< + * ret.raw_headers = dct["raw_headers"] + * if "should_close" in dct: + */ + __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_raw_headers, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 170, __pyx_L1_error) + __pyx_t_8 = (__pyx_t_9 != 0); + if (__pyx_t_8) { + + /* "aiohttp/_http_parser.pyx":171 + * ret.headers = dct["headers"] + * if "raw_headers" in dct: + * ret.raw_headers = dct["raw_headers"] # <<<<<<<<<<<<<< + * if "should_close" in dct: + * ret.should_close = dct["should_close"] + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_raw_headers); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 171, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->raw_headers); + __Pyx_DECREF(__pyx_v_ret->raw_headers); + __pyx_v_ret->raw_headers = __pyx_t_11; + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":170 + * if "headers" in dct: + * ret.headers = dct["headers"] + * if "raw_headers" in dct: # <<<<<<<<<<<<<< + * ret.raw_headers = dct["raw_headers"] + * if "should_close" in dct: + */ + } + + /* "aiohttp/_http_parser.pyx":172 + * if "raw_headers" in dct: + * ret.raw_headers = dct["raw_headers"] + * if "should_close" in dct: # <<<<<<<<<<<<<< + * ret.should_close = dct["should_close"] + * if "compression" in dct: + */ + __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_should_close, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 172, __pyx_L1_error) + __pyx_t_9 = (__pyx_t_8 != 0); + if (__pyx_t_9) { + + /* "aiohttp/_http_parser.pyx":173 + * ret.raw_headers = dct["raw_headers"] + * if "should_close" in dct: + * ret.should_close = dct["should_close"] # <<<<<<<<<<<<<< + * if "compression" in dct: + * ret.compression = dct["compression"] + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_should_close); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 173, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->should_close); + __Pyx_DECREF(__pyx_v_ret->should_close); + __pyx_v_ret->should_close = __pyx_t_11; + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":172 + * if "raw_headers" in dct: + * ret.raw_headers = dct["raw_headers"] + * if "should_close" in dct: # <<<<<<<<<<<<<< + * ret.should_close = dct["should_close"] + * if "compression" in dct: + */ + } + + /* "aiohttp/_http_parser.pyx":174 + * if "should_close" in dct: + * ret.should_close = dct["should_close"] + * if "compression" in dct: # <<<<<<<<<<<<<< + * ret.compression = dct["compression"] + * if "upgrade" in dct: + */ + __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_compression, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 174, __pyx_L1_error) + __pyx_t_8 = (__pyx_t_9 != 0); + if (__pyx_t_8) { + + /* "aiohttp/_http_parser.pyx":175 + * ret.should_close = dct["should_close"] + * if "compression" in dct: + * ret.compression = dct["compression"] # <<<<<<<<<<<<<< + * if "upgrade" in dct: + * ret.upgrade = dct["upgrade"] + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_compression); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 175, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->compression); + __Pyx_DECREF(__pyx_v_ret->compression); + __pyx_v_ret->compression = __pyx_t_11; + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":174 + * if "should_close" in dct: + * ret.should_close = dct["should_close"] + * if "compression" in dct: # <<<<<<<<<<<<<< + * ret.compression = dct["compression"] + * if "upgrade" in dct: + */ + } + + /* "aiohttp/_http_parser.pyx":176 + * if "compression" in dct: + * ret.compression = dct["compression"] + * if "upgrade" in dct: # <<<<<<<<<<<<<< + * ret.upgrade = dct["upgrade"] + * if "chunked" in dct: + */ + __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_upgrade, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 176, __pyx_L1_error) + __pyx_t_9 = (__pyx_t_8 != 0); + if (__pyx_t_9) { + + /* "aiohttp/_http_parser.pyx":177 + * ret.compression = dct["compression"] + * if "upgrade" in dct: + * ret.upgrade = dct["upgrade"] # <<<<<<<<<<<<<< + * if "chunked" in dct: + * ret.chunked = dct["chunked"] + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_upgrade); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 177, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->upgrade); + __Pyx_DECREF(__pyx_v_ret->upgrade); + __pyx_v_ret->upgrade = __pyx_t_11; + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":176 + * if "compression" in dct: + * ret.compression = dct["compression"] + * if "upgrade" in dct: # <<<<<<<<<<<<<< + * ret.upgrade = dct["upgrade"] + * if "chunked" in dct: + */ + } + + /* "aiohttp/_http_parser.pyx":178 + * if "upgrade" in dct: + * ret.upgrade = dct["upgrade"] + * if "chunked" in dct: # <<<<<<<<<<<<<< + * ret.chunked = dct["chunked"] + * if "url" in dct: + */ + __pyx_t_9 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_chunked, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 178, __pyx_L1_error) + __pyx_t_8 = (__pyx_t_9 != 0); + if (__pyx_t_8) { + + /* "aiohttp/_http_parser.pyx":179 + * ret.upgrade = dct["upgrade"] + * if "chunked" in dct: + * ret.chunked = dct["chunked"] # <<<<<<<<<<<<<< + * if "url" in dct: + * ret.url = dct["url"] + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_chunked); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 179, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->chunked); + __Pyx_DECREF(__pyx_v_ret->chunked); + __pyx_v_ret->chunked = __pyx_t_11; + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":178 + * if "upgrade" in dct: + * ret.upgrade = dct["upgrade"] + * if "chunked" in dct: # <<<<<<<<<<<<<< + * ret.chunked = dct["chunked"] + * if "url" in dct: + */ + } + + /* "aiohttp/_http_parser.pyx":180 + * if "chunked" in dct: + * ret.chunked = dct["chunked"] + * if "url" in dct: # <<<<<<<<<<<<<< + * ret.url = dct["url"] + * return ret + */ + __pyx_t_8 = (__Pyx_PyDict_ContainsTF(__pyx_n_u_url, __pyx_v_dct, Py_EQ)); if (unlikely(__pyx_t_8 < 0)) __PYX_ERR(0, 180, __pyx_L1_error) + __pyx_t_9 = (__pyx_t_8 != 0); + if (__pyx_t_9) { + + /* "aiohttp/_http_parser.pyx":181 + * ret.chunked = dct["chunked"] + * if "url" in dct: + * ret.url = dct["url"] # <<<<<<<<<<<<<< + * return ret + * + */ + __pyx_t_11 = __Pyx_PyDict_GetItem(__pyx_v_dct, __pyx_n_u_url); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 181, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_GIVEREF(__pyx_t_11); + __Pyx_GOTREF(__pyx_v_ret->url); + __Pyx_DECREF(__pyx_v_ret->url); + __pyx_v_ret->url = __pyx_t_11; + __pyx_t_11 = 0; + + /* "aiohttp/_http_parser.pyx":180 + * if "chunked" in dct: + * ret.chunked = dct["chunked"] + * if "url" in dct: # <<<<<<<<<<<<<< + * ret.url = dct["url"] + * return ret + */ + } + + /* "aiohttp/_http_parser.pyx":182 + * if "url" in dct: + * ret.url = dct["url"] + * return ret # <<<<<<<<<<<<<< + * + * cdef _new_request_message(str method, + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_ret)); + __pyx_r = ((PyObject *)__pyx_v_ret); + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":150 + * return '' + * + * def _replace(self, **dct): # <<<<<<<<<<<<<< + * cdef RawRequestMessage ret + * ret = _new_request_message(self.method, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage._replace", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_ret); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":111 + * @cython.freelist(DEFAULT_FREELIST_SIZE) + * cdef class RawRequestMessage: + * cdef readonly str method # <<<<<<<<<<<<<< + * cdef readonly str path + * cdef readonly object version # HttpVersion + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_6method_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_6method_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6method___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6method___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->method); + __pyx_r = __pyx_v_self->method; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":112 + * cdef class RawRequestMessage: + * cdef readonly str method + * cdef readonly str path # <<<<<<<<<<<<<< + * cdef readonly object version # HttpVersion + * cdef readonly object headers # CIMultiDict + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_4path_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_4path_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_4path___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_4path___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->path); + __pyx_r = __pyx_v_self->path; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":113 + * cdef readonly str method + * cdef readonly str path + * cdef readonly object version # HttpVersion # <<<<<<<<<<<<<< + * cdef readonly object headers # CIMultiDict + * cdef readonly object raw_headers # tuple + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7version_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7version_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7version___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7version___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->version); + __pyx_r = __pyx_v_self->version; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":114 + * cdef readonly str path + * cdef readonly object version # HttpVersion + * cdef readonly object headers # CIMultiDict # <<<<<<<<<<<<<< + * cdef readonly object raw_headers # tuple + * cdef readonly object should_close + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7headers_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7headers_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7headers___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7headers___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->headers); + __pyx_r = __pyx_v_self->headers; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":115 + * cdef readonly object version # HttpVersion + * cdef readonly object headers # CIMultiDict + * cdef readonly object raw_headers # tuple # <<<<<<<<<<<<<< + * cdef readonly object should_close + * cdef readonly object compression + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->raw_headers); + __pyx_r = __pyx_v_self->raw_headers; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":116 + * cdef readonly object headers # CIMultiDict + * cdef readonly object raw_headers # tuple + * cdef readonly object should_close # <<<<<<<<<<<<<< + * cdef readonly object compression + * cdef readonly object upgrade + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_12should_close_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_12should_close_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_12should_close___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_12should_close___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->should_close); + __pyx_r = __pyx_v_self->should_close; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":117 + * cdef readonly object raw_headers # tuple + * cdef readonly object should_close + * cdef readonly object compression # <<<<<<<<<<<<<< + * cdef readonly object upgrade + * cdef readonly object chunked + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11compression_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11compression_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_11compression___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_11compression___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->compression); + __pyx_r = __pyx_v_self->compression; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":118 + * cdef readonly object should_close + * cdef readonly object compression + * cdef readonly object upgrade # <<<<<<<<<<<<<< + * cdef readonly object chunked + * cdef readonly object url # yarl.URL + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->upgrade); + __pyx_r = __pyx_v_self->upgrade; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":119 + * cdef readonly object compression + * cdef readonly object upgrade + * cdef readonly object chunked # <<<<<<<<<<<<<< + * cdef readonly object url # yarl.URL + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7chunked_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7chunked_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7chunked___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_7chunked___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->chunked); + __pyx_r = __pyx_v_self->chunked; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":120 + * cdef readonly object upgrade + * cdef readonly object chunked + * cdef readonly object url # yarl.URL # <<<<<<<<<<<<<< + * + * def __init__(self, method, path, version, headers, raw_headers, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3url_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3url_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_3url___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_3url___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->url); + __pyx_r = __pyx_v_self->url; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_6__reduce_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self) { + PyObject *__pyx_v_state = 0; + PyObject *__pyx_v__dict = 0; + int __pyx_v_use_setstate; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":5 + * cdef object _dict + * cdef bint use_setstate + * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) # <<<<<<<<<<<<<< + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: + */ + __pyx_t_1 = PyTuple_New(10); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v_self->chunked); + __Pyx_GIVEREF(__pyx_v_self->chunked); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->chunked); + __Pyx_INCREF(__pyx_v_self->compression); + __Pyx_GIVEREF(__pyx_v_self->compression); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->compression); + __Pyx_INCREF(__pyx_v_self->headers); + __Pyx_GIVEREF(__pyx_v_self->headers); + PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_self->headers); + __Pyx_INCREF(__pyx_v_self->method); + __Pyx_GIVEREF(__pyx_v_self->method); + PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_v_self->method); + __Pyx_INCREF(__pyx_v_self->path); + __Pyx_GIVEREF(__pyx_v_self->path); + PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_v_self->path); + __Pyx_INCREF(__pyx_v_self->raw_headers); + __Pyx_GIVEREF(__pyx_v_self->raw_headers); + PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_v_self->raw_headers); + __Pyx_INCREF(__pyx_v_self->should_close); + __Pyx_GIVEREF(__pyx_v_self->should_close); + PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_v_self->should_close); + __Pyx_INCREF(__pyx_v_self->upgrade); + __Pyx_GIVEREF(__pyx_v_self->upgrade); + PyTuple_SET_ITEM(__pyx_t_1, 7, __pyx_v_self->upgrade); + __Pyx_INCREF(__pyx_v_self->url); + __Pyx_GIVEREF(__pyx_v_self->url); + PyTuple_SET_ITEM(__pyx_t_1, 8, __pyx_v_self->url); + __Pyx_INCREF(__pyx_v_self->version); + __Pyx_GIVEREF(__pyx_v_self->version); + PyTuple_SET_ITEM(__pyx_t_1, 9, __pyx_v_self->version); + __pyx_v_state = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "(tree fragment)":6 + * cdef bint use_setstate + * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) + * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< + * if _dict is not None: + * state += (_dict,) + */ + __pyx_t_1 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v__dict = __pyx_t_1; + __pyx_t_1 = 0; + + /* "(tree fragment)":7 + * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True + */ + __pyx_t_2 = (__pyx_v__dict != Py_None); + __pyx_t_3 = (__pyx_t_2 != 0); + if (__pyx_t_3) { + + /* "(tree fragment)":8 + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: + * state += (_dict,) # <<<<<<<<<<<<<< + * use_setstate = True + * else: + */ + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_v__dict); + __Pyx_GIVEREF(__pyx_v__dict); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v__dict); + __pyx_t_4 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_4)); + __pyx_t_4 = 0; + + /* "(tree fragment)":9 + * if _dict is not None: + * state += (_dict,) + * use_setstate = True # <<<<<<<<<<<<<< + * else: + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None + */ + __pyx_v_use_setstate = 1; + + /* "(tree fragment)":7 + * state = (self.chunked, self.compression, self.headers, self.method, self.path, self.raw_headers, self.should_close, self.upgrade, self.url, self.version) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True + */ + goto __pyx_L3; + } + + /* "(tree fragment)":11 + * use_setstate = True + * else: + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None # <<<<<<<<<<<<<< + * if use_setstate: + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state + */ + /*else*/ { + __pyx_t_2 = (__pyx_v_self->chunked != Py_None); + __pyx_t_5 = (__pyx_t_2 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_3 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->compression != Py_None); + __pyx_t_2 = (__pyx_t_5 != 0); + if (!__pyx_t_2) { + } else { + __pyx_t_3 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = (__pyx_v_self->headers != Py_None); + __pyx_t_5 = (__pyx_t_2 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_3 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->method != ((PyObject*)Py_None)); + __pyx_t_2 = (__pyx_t_5 != 0); + if (!__pyx_t_2) { + } else { + __pyx_t_3 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = (__pyx_v_self->path != ((PyObject*)Py_None)); + __pyx_t_5 = (__pyx_t_2 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_3 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->raw_headers != Py_None); + __pyx_t_2 = (__pyx_t_5 != 0); + if (!__pyx_t_2) { + } else { + __pyx_t_3 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = (__pyx_v_self->should_close != Py_None); + __pyx_t_5 = (__pyx_t_2 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_3 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->upgrade != Py_None); + __pyx_t_2 = (__pyx_t_5 != 0); + if (!__pyx_t_2) { + } else { + __pyx_t_3 = __pyx_t_2; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_2 = (__pyx_v_self->url != Py_None); + __pyx_t_5 = (__pyx_t_2 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_3 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->version != Py_None); + __pyx_t_2 = (__pyx_t_5 != 0); + __pyx_t_3 = __pyx_t_2; + __pyx_L4_bool_binop_done:; + __pyx_v_use_setstate = __pyx_t_3; + } + __pyx_L3:; + + /* "(tree fragment)":12 + * else: + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state + * else: + */ + __pyx_t_3 = (__pyx_v_use_setstate != 0); + if (__pyx_t_3) { + + /* "(tree fragment)":13 + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None + * if use_setstate: + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state # <<<<<<<<<<<<<< + * else: + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyx_unpickle_RawRequestMessage); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_INCREF(__pyx_int_21004882); + __Pyx_GIVEREF(__pyx_int_21004882); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_21004882); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + PyTuple_SET_ITEM(__pyx_t_1, 2, Py_None); + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_1); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_v_state); + __pyx_t_4 = 0; + __pyx_t_1 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "(tree fragment)":12 + * else: + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.method is not None or self.path is not None or self.raw_headers is not None or self.should_close is not None or self.upgrade is not None or self.url is not None or self.version is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state + * else: + */ + } + + /* "(tree fragment)":15 + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, None), state + * else: + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_RawRequestMessage__set_state(self, __pyx_state) + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pyx_unpickle_RawRequestMessage); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_INCREF(__pyx_int_21004882); + __Pyx_GIVEREF(__pyx_int_21004882); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_21004882); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_v_state); + __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_1); + __pyx_t_6 = 0; + __pyx_t_1 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + } + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_state); + __Pyx_XDECREF(__pyx_v__dict); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":16 + * else: + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_RawRequestMessage__set_state(self, __pyx_state) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_9__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_9__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_8__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17RawRequestMessage_8__setstate_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":17 + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_RawRequestMessage__set_state(self, __pyx_state) # <<<<<<<<<<<<<< + */ + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":16 + * else: + * return __pyx_unpickle_RawRequestMessage, (type(self), 0x1408252, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_RawRequestMessage__set_state(self, __pyx_state) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.RawRequestMessage.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":184 + * return ret + * + * cdef _new_request_message(str method, # <<<<<<<<<<<<<< + * str path, + * object version, + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser__new_request_message(PyObject *__pyx_v_method, PyObject *__pyx_v_path, PyObject *__pyx_v_version, PyObject *__pyx_v_headers, PyObject *__pyx_v_raw_headers, int __pyx_v_should_close, PyObject *__pyx_v_compression, int __pyx_v_upgrade, int __pyx_v_chunked, PyObject *__pyx_v_url) { + struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v_ret = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_new_request_message", 0); + + /* "aiohttp/_http_parser.pyx":195 + * object url): + * cdef RawRequestMessage ret + * ret = RawRequestMessage.__new__(RawRequestMessage) # <<<<<<<<<<<<<< + * ret.method = method + * ret.path = path + */ + __pyx_t_1 = ((PyObject *)__pyx_tp_new_7aiohttp_12_http_parser_RawRequestMessage(((PyTypeObject *)__pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 195, __pyx_L1_error) + __Pyx_GOTREF(((PyObject *)__pyx_t_1)); + __pyx_v_ret = ((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":196 + * cdef RawRequestMessage ret + * ret = RawRequestMessage.__new__(RawRequestMessage) + * ret.method = method # <<<<<<<<<<<<<< + * ret.path = path + * ret.version = version + */ + __Pyx_INCREF(__pyx_v_method); + __Pyx_GIVEREF(__pyx_v_method); + __Pyx_GOTREF(__pyx_v_ret->method); + __Pyx_DECREF(__pyx_v_ret->method); + __pyx_v_ret->method = __pyx_v_method; + + /* "aiohttp/_http_parser.pyx":197 + * ret = RawRequestMessage.__new__(RawRequestMessage) + * ret.method = method + * ret.path = path # <<<<<<<<<<<<<< + * ret.version = version + * ret.headers = headers + */ + __Pyx_INCREF(__pyx_v_path); + __Pyx_GIVEREF(__pyx_v_path); + __Pyx_GOTREF(__pyx_v_ret->path); + __Pyx_DECREF(__pyx_v_ret->path); + __pyx_v_ret->path = __pyx_v_path; + + /* "aiohttp/_http_parser.pyx":198 + * ret.method = method + * ret.path = path + * ret.version = version # <<<<<<<<<<<<<< + * ret.headers = headers + * ret.raw_headers = raw_headers + */ + __Pyx_INCREF(__pyx_v_version); + __Pyx_GIVEREF(__pyx_v_version); + __Pyx_GOTREF(__pyx_v_ret->version); + __Pyx_DECREF(__pyx_v_ret->version); + __pyx_v_ret->version = __pyx_v_version; + + /* "aiohttp/_http_parser.pyx":199 + * ret.path = path + * ret.version = version + * ret.headers = headers # <<<<<<<<<<<<<< + * ret.raw_headers = raw_headers + * ret.should_close = should_close + */ + __Pyx_INCREF(__pyx_v_headers); + __Pyx_GIVEREF(__pyx_v_headers); + __Pyx_GOTREF(__pyx_v_ret->headers); + __Pyx_DECREF(__pyx_v_ret->headers); + __pyx_v_ret->headers = __pyx_v_headers; + + /* "aiohttp/_http_parser.pyx":200 + * ret.version = version + * ret.headers = headers + * ret.raw_headers = raw_headers # <<<<<<<<<<<<<< + * ret.should_close = should_close + * ret.compression = compression + */ + __Pyx_INCREF(__pyx_v_raw_headers); + __Pyx_GIVEREF(__pyx_v_raw_headers); + __Pyx_GOTREF(__pyx_v_ret->raw_headers); + __Pyx_DECREF(__pyx_v_ret->raw_headers); + __pyx_v_ret->raw_headers = __pyx_v_raw_headers; + + /* "aiohttp/_http_parser.pyx":201 + * ret.headers = headers + * ret.raw_headers = raw_headers + * ret.should_close = should_close # <<<<<<<<<<<<<< + * ret.compression = compression + * ret.upgrade = upgrade + */ + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_should_close); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 201, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_ret->should_close); + __Pyx_DECREF(__pyx_v_ret->should_close); + __pyx_v_ret->should_close = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":202 + * ret.raw_headers = raw_headers + * ret.should_close = should_close + * ret.compression = compression # <<<<<<<<<<<<<< + * ret.upgrade = upgrade + * ret.chunked = chunked + */ + __Pyx_INCREF(__pyx_v_compression); + __Pyx_GIVEREF(__pyx_v_compression); + __Pyx_GOTREF(__pyx_v_ret->compression); + __Pyx_DECREF(__pyx_v_ret->compression); + __pyx_v_ret->compression = __pyx_v_compression; + + /* "aiohttp/_http_parser.pyx":203 + * ret.should_close = should_close + * ret.compression = compression + * ret.upgrade = upgrade # <<<<<<<<<<<<<< + * ret.chunked = chunked + * ret.url = url + */ + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_upgrade); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 203, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_ret->upgrade); + __Pyx_DECREF(__pyx_v_ret->upgrade); + __pyx_v_ret->upgrade = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":204 + * ret.compression = compression + * ret.upgrade = upgrade + * ret.chunked = chunked # <<<<<<<<<<<<<< + * ret.url = url + * return ret + */ + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_chunked); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 204, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_ret->chunked); + __Pyx_DECREF(__pyx_v_ret->chunked); + __pyx_v_ret->chunked = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":205 + * ret.upgrade = upgrade + * ret.chunked = chunked + * ret.url = url # <<<<<<<<<<<<<< + * return ret + * + */ + __Pyx_INCREF(__pyx_v_url); + __Pyx_GIVEREF(__pyx_v_url); + __Pyx_GOTREF(__pyx_v_ret->url); + __Pyx_DECREF(__pyx_v_ret->url); + __pyx_v_ret->url = __pyx_v_url; + + /* "aiohttp/_http_parser.pyx":206 + * ret.chunked = chunked + * ret.url = url + * return ret # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_ret)); + __pyx_r = ((PyObject *)__pyx_v_ret); + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":184 + * return ret + * + * cdef _new_request_message(str method, # <<<<<<<<<<<<<< + * str path, + * object version, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser._new_request_message", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_ret); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":221 + * cdef readonly object chunked + * + * def __init__(self, version, code, reason, headers, raw_headers, # <<<<<<<<<<<<<< + * should_close, compression, upgrade, chunked): + * self.version = version + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_version = 0; + PyObject *__pyx_v_code = 0; + PyObject *__pyx_v_reason = 0; + PyObject *__pyx_v_headers = 0; + PyObject *__pyx_v_raw_headers = 0; + PyObject *__pyx_v_should_close = 0; + PyObject *__pyx_v_compression = 0; + PyObject *__pyx_v_upgrade = 0; + PyObject *__pyx_v_chunked = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_version,&__pyx_n_s_code,&__pyx_n_s_reason,&__pyx_n_s_headers,&__pyx_n_s_raw_headers,&__pyx_n_s_should_close,&__pyx_n_s_compression,&__pyx_n_s_upgrade,&__pyx_n_s_chunked,0}; + PyObject* values[9] = {0,0,0,0,0,0,0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_version)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_code)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 1); __PYX_ERR(0, 221, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_reason)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 2); __PYX_ERR(0, 221, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_headers)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 3); __PYX_ERR(0, 221, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 4: + if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_raw_headers)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 4); __PYX_ERR(0, 221, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 5: + if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_should_close)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 5); __PYX_ERR(0, 221, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 6: + if (likely((values[6] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_compression)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 6); __PYX_ERR(0, 221, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 7: + if (likely((values[7] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_upgrade)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 7); __PYX_ERR(0, 221, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 8: + if (likely((values[8] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_chunked)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, 8); __PYX_ERR(0, 221, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 221, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 9) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + } + __pyx_v_version = values[0]; + __pyx_v_code = values[1]; + __pyx_v_reason = values[2]; + __pyx_v_headers = values[3]; + __pyx_v_raw_headers = values[4]; + __pyx_v_should_close = values[5]; + __pyx_v_compression = values[6]; + __pyx_v_upgrade = values[7]; + __pyx_v_chunked = values[8]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 221, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage___init__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self), __pyx_v_version, __pyx_v_code, __pyx_v_reason, __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_compression, __pyx_v_upgrade, __pyx_v_chunked); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage___init__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self, PyObject *__pyx_v_version, PyObject *__pyx_v_code, PyObject *__pyx_v_reason, PyObject *__pyx_v_headers, PyObject *__pyx_v_raw_headers, PyObject *__pyx_v_should_close, PyObject *__pyx_v_compression, PyObject *__pyx_v_upgrade, PyObject *__pyx_v_chunked) { + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + + /* "aiohttp/_http_parser.pyx":223 + * def __init__(self, version, code, reason, headers, raw_headers, + * should_close, compression, upgrade, chunked): + * self.version = version # <<<<<<<<<<<<<< + * self.code = code + * self.reason = reason + */ + __Pyx_INCREF(__pyx_v_version); + __Pyx_GIVEREF(__pyx_v_version); + __Pyx_GOTREF(__pyx_v_self->version); + __Pyx_DECREF(__pyx_v_self->version); + __pyx_v_self->version = __pyx_v_version; + + /* "aiohttp/_http_parser.pyx":224 + * should_close, compression, upgrade, chunked): + * self.version = version + * self.code = code # <<<<<<<<<<<<<< + * self.reason = reason + * self.headers = headers + */ + __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_code); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 224, __pyx_L1_error) + __pyx_v_self->code = __pyx_t_1; + + /* "aiohttp/_http_parser.pyx":225 + * self.version = version + * self.code = code + * self.reason = reason # <<<<<<<<<<<<<< + * self.headers = headers + * self.raw_headers = raw_headers + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_reason))||((__pyx_v_reason) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_reason)->tp_name), 0))) __PYX_ERR(0, 225, __pyx_L1_error) + __pyx_t_2 = __pyx_v_reason; + __Pyx_INCREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_v_self->reason); + __Pyx_DECREF(__pyx_v_self->reason); + __pyx_v_self->reason = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":226 + * self.code = code + * self.reason = reason + * self.headers = headers # <<<<<<<<<<<<<< + * self.raw_headers = raw_headers + * self.should_close = should_close + */ + __Pyx_INCREF(__pyx_v_headers); + __Pyx_GIVEREF(__pyx_v_headers); + __Pyx_GOTREF(__pyx_v_self->headers); + __Pyx_DECREF(__pyx_v_self->headers); + __pyx_v_self->headers = __pyx_v_headers; + + /* "aiohttp/_http_parser.pyx":227 + * self.reason = reason + * self.headers = headers + * self.raw_headers = raw_headers # <<<<<<<<<<<<<< + * self.should_close = should_close + * self.compression = compression + */ + __Pyx_INCREF(__pyx_v_raw_headers); + __Pyx_GIVEREF(__pyx_v_raw_headers); + __Pyx_GOTREF(__pyx_v_self->raw_headers); + __Pyx_DECREF(__pyx_v_self->raw_headers); + __pyx_v_self->raw_headers = __pyx_v_raw_headers; + + /* "aiohttp/_http_parser.pyx":228 + * self.headers = headers + * self.raw_headers = raw_headers + * self.should_close = should_close # <<<<<<<<<<<<<< + * self.compression = compression + * self.upgrade = upgrade + */ + __Pyx_INCREF(__pyx_v_should_close); + __Pyx_GIVEREF(__pyx_v_should_close); + __Pyx_GOTREF(__pyx_v_self->should_close); + __Pyx_DECREF(__pyx_v_self->should_close); + __pyx_v_self->should_close = __pyx_v_should_close; + + /* "aiohttp/_http_parser.pyx":229 + * self.raw_headers = raw_headers + * self.should_close = should_close + * self.compression = compression # <<<<<<<<<<<<<< + * self.upgrade = upgrade + * self.chunked = chunked + */ + __Pyx_INCREF(__pyx_v_compression); + __Pyx_GIVEREF(__pyx_v_compression); + __Pyx_GOTREF(__pyx_v_self->compression); + __Pyx_DECREF(__pyx_v_self->compression); + __pyx_v_self->compression = __pyx_v_compression; + + /* "aiohttp/_http_parser.pyx":230 + * self.should_close = should_close + * self.compression = compression + * self.upgrade = upgrade # <<<<<<<<<<<<<< + * self.chunked = chunked + * + */ + __Pyx_INCREF(__pyx_v_upgrade); + __Pyx_GIVEREF(__pyx_v_upgrade); + __Pyx_GOTREF(__pyx_v_self->upgrade); + __Pyx_DECREF(__pyx_v_self->upgrade); + __pyx_v_self->upgrade = __pyx_v_upgrade; + + /* "aiohttp/_http_parser.pyx":231 + * self.compression = compression + * self.upgrade = upgrade + * self.chunked = chunked # <<<<<<<<<<<<<< + * + * def __repr__(self): + */ + __Pyx_INCREF(__pyx_v_chunked); + __Pyx_GIVEREF(__pyx_v_chunked); + __Pyx_GOTREF(__pyx_v_self->chunked); + __Pyx_DECREF(__pyx_v_self->chunked); + __pyx_v_self->chunked = __pyx_v_chunked; + + /* "aiohttp/_http_parser.pyx":221 + * cdef readonly object chunked + * + * def __init__(self, version, code, reason, headers, raw_headers, # <<<<<<<<<<<<<< + * should_close, compression, upgrade, chunked): + * self.version = version + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":233 + * self.chunked = chunked + * + * def __repr__(self): # <<<<<<<<<<<<<< + * info = [] + * info.append(("version", self.version)) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_3__repr__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_3__repr__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_2__repr__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +static PyObject *__pyx_gb_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */ + +/* "aiohttp/_http_parser.pyx":244 + * info.append(("upgrade", self.upgrade)) + * info.append(("chunked", self.chunked)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< + * return '' + * + */ + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___genexpr(PyObject *__pyx_self) { + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *__pyx_cur_scope; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("genexpr", 0); + __pyx_cur_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr(__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 244, __pyx_L1_error) + } else { + __Pyx_GOTREF(__pyx_cur_scope); + } + __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *) __pyx_self; + __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope)); + __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope); + { + __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___2generator1, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_repr___locals_genexpr, __pyx_n_s_aiohttp__http_parser); if (unlikely(!gen)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_DECREF(__pyx_cur_scope); + __Pyx_RefNannyFinishContext(); + return (PyObject *) gen; + } + + /* function exit code */ + __pyx_L1_error:; + __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__repr__.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_DECREF(((PyObject *)__pyx_cur_scope)); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_gb_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */ +{ + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *__pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)__pyx_generator->closure); + PyObject *__pyx_r = NULL; + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *(*__pyx_t_7)(PyObject *); + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("genexpr", 0); + switch (__pyx_generator->resume_label) { + case 0: goto __pyx_L3_first_run; + default: /* CPython raises the right error here */ + __Pyx_RefNannyFinishContext(); + return NULL; + } + __pyx_L3_first_run:; + if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 244, __pyx_L1_error) + __pyx_r = PyList_New(0); if (unlikely(!__pyx_r)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_r); + if (unlikely(!__pyx_cur_scope->__pyx_outer_scope->__pyx_v_info)) { __Pyx_RaiseClosureNameError("info"); __PYX_ERR(0, 244, __pyx_L1_error) } + if (unlikely(__pyx_cur_scope->__pyx_outer_scope->__pyx_v_info == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + __PYX_ERR(0, 244, __pyx_L1_error) + } + __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_info; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0; + for (;;) { + if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + __pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) __PYX_ERR(0, 244, __pyx_L1_error) + #else + __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + #endif + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 244, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); + } else { + __pyx_t_4 = PyList_GET_ITEM(sequence, 0); + __pyx_t_5 = PyList_GET_ITEM(sequence, 1); + } + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + #else + __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_6 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_7 = Py_TYPE(__pyx_t_6)->tp_iternext; + index = 0; __pyx_t_4 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_4)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + index = 1; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 2) < 0) __PYX_ERR(0, 244, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L7_unpacking_done; + __pyx_L6_unpacking_failed:; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 244, __pyx_L1_error) + __pyx_L7_unpacking_done:; + } + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_name); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_name, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __pyx_t_4 = 0; + __Pyx_XGOTREF(__pyx_cur_scope->__pyx_v_val); + __Pyx_XDECREF_SET(__pyx_cur_scope->__pyx_v_val, __pyx_t_5); + __Pyx_GIVEREF(__pyx_t_5); + __pyx_t_5 = 0; + __pyx_t_3 = PyNumber_Add(__pyx_cur_scope->__pyx_v_name, __pyx_kp_u_); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = PyObject_Repr(__pyx_cur_scope->__pyx_v_val); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_4 = PyNumber_Add(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(__Pyx_ListComp_Append(__pyx_r, (PyObject*)__pyx_t_4))) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_r); __pyx_r = 0; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + #if !CYTHON_USE_EXC_INFO_STACK + __Pyx_Coroutine_ResetAndClearException(__pyx_generator); + #endif + __pyx_generator->resume_label = -1; + __Pyx_Coroutine_clear((PyObject*)__pyx_generator); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":233 + * self.chunked = chunked + * + * def __repr__(self): # <<<<<<<<<<<<<< + * info = [] + * info.append(("version", self.version)) + */ + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_2__repr__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *__pyx_cur_scope; + PyObject *__pyx_v_sinfo = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__repr__", 0); + __pyx_cur_scope = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(__pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, __pyx_empty_tuple, NULL); + if (unlikely(!__pyx_cur_scope)) { + __pyx_cur_scope = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)Py_None); + __Pyx_INCREF(Py_None); + __PYX_ERR(0, 233, __pyx_L1_error) + } else { + __Pyx_GOTREF(__pyx_cur_scope); + } + + /* "aiohttp/_http_parser.pyx":234 + * + * def __repr__(self): + * info = [] # <<<<<<<<<<<<<< + * info.append(("version", self.version)) + * info.append(("code", self.code)) + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 234, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_cur_scope->__pyx_v_info = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":235 + * def __repr__(self): + * info = [] + * info.append(("version", self.version)) # <<<<<<<<<<<<<< + * info.append(("code", self.code)) + * info.append(("reason", self.reason)) + */ + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 235, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_u_version); + __Pyx_GIVEREF(__pyx_n_u_version); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_n_u_version); + __Pyx_INCREF(__pyx_v_self->version); + __Pyx_GIVEREF(__pyx_v_self->version); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self->version); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 235, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":236 + * info = [] + * info.append(("version", self.version)) + * info.append(("code", self.code)) # <<<<<<<<<<<<<< + * info.append(("reason", self.reason)) + * info.append(("headers", self.headers)) + */ + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->code); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_u_code); + __Pyx_GIVEREF(__pyx_n_u_code); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_code); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1); + __pyx_t_1 = 0; + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":237 + * info.append(("version", self.version)) + * info.append(("code", self.code)) + * info.append(("reason", self.reason)) # <<<<<<<<<<<<<< + * info.append(("headers", self.headers)) + * info.append(("raw_headers", self.raw_headers)) + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 237, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_u_reason); + __Pyx_GIVEREF(__pyx_n_u_reason); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_reason); + __Pyx_INCREF(__pyx_v_self->reason); + __Pyx_GIVEREF(__pyx_v_self->reason); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->reason); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 237, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":238 + * info.append(("code", self.code)) + * info.append(("reason", self.reason)) + * info.append(("headers", self.headers)) # <<<<<<<<<<<<<< + * info.append(("raw_headers", self.raw_headers)) + * info.append(("should_close", self.should_close)) + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_u_headers); + __Pyx_GIVEREF(__pyx_n_u_headers); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_headers); + __Pyx_INCREF(__pyx_v_self->headers); + __Pyx_GIVEREF(__pyx_v_self->headers); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->headers); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 238, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":239 + * info.append(("reason", self.reason)) + * info.append(("headers", self.headers)) + * info.append(("raw_headers", self.raw_headers)) # <<<<<<<<<<<<<< + * info.append(("should_close", self.should_close)) + * info.append(("compression", self.compression)) + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 239, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_u_raw_headers); + __Pyx_GIVEREF(__pyx_n_u_raw_headers); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_raw_headers); + __Pyx_INCREF(__pyx_v_self->raw_headers); + __Pyx_GIVEREF(__pyx_v_self->raw_headers); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->raw_headers); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 239, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":240 + * info.append(("headers", self.headers)) + * info.append(("raw_headers", self.raw_headers)) + * info.append(("should_close", self.should_close)) # <<<<<<<<<<<<<< + * info.append(("compression", self.compression)) + * info.append(("upgrade", self.upgrade)) + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 240, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_u_should_close); + __Pyx_GIVEREF(__pyx_n_u_should_close); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_should_close); + __Pyx_INCREF(__pyx_v_self->should_close); + __Pyx_GIVEREF(__pyx_v_self->should_close); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->should_close); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 240, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":241 + * info.append(("raw_headers", self.raw_headers)) + * info.append(("should_close", self.should_close)) + * info.append(("compression", self.compression)) # <<<<<<<<<<<<<< + * info.append(("upgrade", self.upgrade)) + * info.append(("chunked", self.chunked)) + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 241, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_u_compression); + __Pyx_GIVEREF(__pyx_n_u_compression); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_compression); + __Pyx_INCREF(__pyx_v_self->compression); + __Pyx_GIVEREF(__pyx_v_self->compression); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->compression); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 241, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":242 + * info.append(("should_close", self.should_close)) + * info.append(("compression", self.compression)) + * info.append(("upgrade", self.upgrade)) # <<<<<<<<<<<<<< + * info.append(("chunked", self.chunked)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_u_upgrade); + __Pyx_GIVEREF(__pyx_n_u_upgrade); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_upgrade); + __Pyx_INCREF(__pyx_v_self->upgrade); + __Pyx_GIVEREF(__pyx_v_self->upgrade); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->upgrade); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 242, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":243 + * info.append(("compression", self.compression)) + * info.append(("upgrade", self.upgrade)) + * info.append(("chunked", self.chunked)) # <<<<<<<<<<<<<< + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + * return '' + */ + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 243, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_n_u_chunked); + __Pyx_GIVEREF(__pyx_n_u_chunked); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_n_u_chunked); + __Pyx_INCREF(__pyx_v_self->chunked); + __Pyx_GIVEREF(__pyx_v_self->chunked); + PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self->chunked); + __pyx_t_2 = __Pyx_PyList_Append(__pyx_cur_scope->__pyx_v_info, __pyx_t_3); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 243, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":244 + * info.append(("upgrade", self.upgrade)) + * info.append(("chunked", self.chunked)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) # <<<<<<<<<<<<<< + * return '' + * + */ + __pyx_t_3 = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_8__repr___genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_Generator_Next(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyUnicode_Join(__pyx_kp_u__2, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 244, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_sinfo = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":245 + * info.append(("chunked", self.chunked)) + * sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + * return '' # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __Pyx_PyUnicode_ConcatSafe(__pyx_kp_u_RawResponseMessage, __pyx_v_sinfo); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_kp_u__3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 245, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":233 + * self.chunked = chunked + * + * def __repr__(self): # <<<<<<<<<<<<<< + * info = [] + * info.append(("version", self.version)) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_sinfo); + __Pyx_DECREF(((PyObject *)__pyx_cur_scope)); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":211 + * @cython.freelist(DEFAULT_FREELIST_SIZE) + * cdef class RawResponseMessage: + * cdef readonly object version # HttpVersion # <<<<<<<<<<<<<< + * cdef readonly int code + * cdef readonly str reason + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7version_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7version_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7version___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7version___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->version); + __pyx_r = __pyx_v_self->version; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":212 + * cdef class RawResponseMessage: + * cdef readonly object version # HttpVersion + * cdef readonly int code # <<<<<<<<<<<<<< + * cdef readonly str reason + * cdef readonly object headers # CIMultiDict + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_4code_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_4code_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4code___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4code___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->code); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 212, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.code.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":213 + * cdef readonly object version # HttpVersion + * cdef readonly int code + * cdef readonly str reason # <<<<<<<<<<<<<< + * cdef readonly object headers # CIMultiDict + * cdef readonly object raw_headers # tuple + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_6reason_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_6reason_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_6reason___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_6reason___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->reason); + __pyx_r = __pyx_v_self->reason; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":214 + * cdef readonly int code + * cdef readonly str reason + * cdef readonly object headers # CIMultiDict # <<<<<<<<<<<<<< + * cdef readonly object raw_headers # tuple + * cdef readonly object should_close + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7headers_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7headers_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7headers___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7headers___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->headers); + __pyx_r = __pyx_v_self->headers; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":215 + * cdef readonly str reason + * cdef readonly object headers # CIMultiDict + * cdef readonly object raw_headers # tuple # <<<<<<<<<<<<<< + * cdef readonly object should_close + * cdef readonly object compression + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->raw_headers); + __pyx_r = __pyx_v_self->raw_headers; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":216 + * cdef readonly object headers # CIMultiDict + * cdef readonly object raw_headers # tuple + * cdef readonly object should_close # <<<<<<<<<<<<<< + * cdef readonly object compression + * cdef readonly object upgrade + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_12should_close_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_12should_close_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_12should_close___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_12should_close___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->should_close); + __pyx_r = __pyx_v_self->should_close; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":217 + * cdef readonly object raw_headers # tuple + * cdef readonly object should_close + * cdef readonly object compression # <<<<<<<<<<<<<< + * cdef readonly object upgrade + * cdef readonly object chunked + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11compression_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11compression_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_11compression___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_11compression___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->compression); + __pyx_r = __pyx_v_self->compression; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":218 + * cdef readonly object should_close + * cdef readonly object compression + * cdef readonly object upgrade # <<<<<<<<<<<<<< + * cdef readonly object chunked + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->upgrade); + __pyx_r = __pyx_v_self->upgrade; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":219 + * cdef readonly object compression + * cdef readonly object upgrade + * cdef readonly object chunked # <<<<<<<<<<<<<< + * + * def __init__(self, version, code, reason, headers, raw_headers, + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7chunked_1__get__(PyObject *__pyx_v_self); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7chunked_1__get__(PyObject *__pyx_v_self) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7chunked___get__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_7chunked___get__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__get__", 0); + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_self->chunked); + __pyx_r = __pyx_v_self->chunked; + goto __pyx_L0; + + /* function exit code */ + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_5__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_4__reduce_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self) { + PyObject *__pyx_v_state = 0; + PyObject *__pyx_v__dict = 0; + int __pyx_v_use_setstate; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":5 + * cdef object _dict + * cdef bint use_setstate + * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) # <<<<<<<<<<<<<< + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: + */ + __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->code); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(9); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_self->chunked); + __Pyx_GIVEREF(__pyx_v_self->chunked); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_self->chunked); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_1); + __Pyx_INCREF(__pyx_v_self->compression); + __Pyx_GIVEREF(__pyx_v_self->compression); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_self->compression); + __Pyx_INCREF(__pyx_v_self->headers); + __Pyx_GIVEREF(__pyx_v_self->headers); + PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_v_self->headers); + __Pyx_INCREF(__pyx_v_self->raw_headers); + __Pyx_GIVEREF(__pyx_v_self->raw_headers); + PyTuple_SET_ITEM(__pyx_t_2, 4, __pyx_v_self->raw_headers); + __Pyx_INCREF(__pyx_v_self->reason); + __Pyx_GIVEREF(__pyx_v_self->reason); + PyTuple_SET_ITEM(__pyx_t_2, 5, __pyx_v_self->reason); + __Pyx_INCREF(__pyx_v_self->should_close); + __Pyx_GIVEREF(__pyx_v_self->should_close); + PyTuple_SET_ITEM(__pyx_t_2, 6, __pyx_v_self->should_close); + __Pyx_INCREF(__pyx_v_self->upgrade); + __Pyx_GIVEREF(__pyx_v_self->upgrade); + PyTuple_SET_ITEM(__pyx_t_2, 7, __pyx_v_self->upgrade); + __Pyx_INCREF(__pyx_v_self->version); + __Pyx_GIVEREF(__pyx_v_self->version); + PyTuple_SET_ITEM(__pyx_t_2, 8, __pyx_v_self->version); + __pyx_t_1 = 0; + __pyx_v_state = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "(tree fragment)":6 + * cdef bint use_setstate + * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) + * _dict = getattr(self, '__dict__', None) # <<<<<<<<<<<<<< + * if _dict is not None: + * state += (_dict,) + */ + __pyx_t_2 = __Pyx_GetAttr3(((PyObject *)__pyx_v_self), __pyx_n_s_dict, Py_None); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v__dict = __pyx_t_2; + __pyx_t_2 = 0; + + /* "(tree fragment)":7 + * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True + */ + __pyx_t_3 = (__pyx_v__dict != Py_None); + __pyx_t_4 = (__pyx_t_3 != 0); + if (__pyx_t_4) { + + /* "(tree fragment)":8 + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: + * state += (_dict,) # <<<<<<<<<<<<<< + * use_setstate = True + * else: + */ + __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v__dict); + __Pyx_GIVEREF(__pyx_v__dict); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v__dict); + __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_state, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_state, ((PyObject*)__pyx_t_1)); + __pyx_t_1 = 0; + + /* "(tree fragment)":9 + * if _dict is not None: + * state += (_dict,) + * use_setstate = True # <<<<<<<<<<<<<< + * else: + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None + */ + __pyx_v_use_setstate = 1; + + /* "(tree fragment)":7 + * state = (self.chunked, self.code, self.compression, self.headers, self.raw_headers, self.reason, self.should_close, self.upgrade, self.version) + * _dict = getattr(self, '__dict__', None) + * if _dict is not None: # <<<<<<<<<<<<<< + * state += (_dict,) + * use_setstate = True + */ + goto __pyx_L3; + } + + /* "(tree fragment)":11 + * use_setstate = True + * else: + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None # <<<<<<<<<<<<<< + * if use_setstate: + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state + */ + /*else*/ { + __pyx_t_3 = (__pyx_v_self->chunked != Py_None); + __pyx_t_5 = (__pyx_t_3 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_4 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->compression != Py_None); + __pyx_t_3 = (__pyx_t_5 != 0); + if (!__pyx_t_3) { + } else { + __pyx_t_4 = __pyx_t_3; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_3 = (__pyx_v_self->headers != Py_None); + __pyx_t_5 = (__pyx_t_3 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_4 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->raw_headers != Py_None); + __pyx_t_3 = (__pyx_t_5 != 0); + if (!__pyx_t_3) { + } else { + __pyx_t_4 = __pyx_t_3; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_3 = (__pyx_v_self->reason != ((PyObject*)Py_None)); + __pyx_t_5 = (__pyx_t_3 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_4 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->should_close != Py_None); + __pyx_t_3 = (__pyx_t_5 != 0); + if (!__pyx_t_3) { + } else { + __pyx_t_4 = __pyx_t_3; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_3 = (__pyx_v_self->upgrade != Py_None); + __pyx_t_5 = (__pyx_t_3 != 0); + if (!__pyx_t_5) { + } else { + __pyx_t_4 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->version != Py_None); + __pyx_t_3 = (__pyx_t_5 != 0); + __pyx_t_4 = __pyx_t_3; + __pyx_L4_bool_binop_done:; + __pyx_v_use_setstate = __pyx_t_4; + } + __pyx_L3:; + + /* "(tree fragment)":12 + * else: + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state + * else: + */ + __pyx_t_4 = (__pyx_v_use_setstate != 0); + if (__pyx_t_4) { + + /* "(tree fragment)":13 + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None + * if use_setstate: + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state # <<<<<<<<<<<<<< + * else: + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pyx_unpickle_RawResponseMessag); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_INCREF(__pyx_int_209127132); + __Pyx_GIVEREF(__pyx_int_209127132); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_209127132); + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + PyTuple_SET_ITEM(__pyx_t_2, 2, Py_None); + __pyx_t_6 = PyTuple_New(3); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GIVEREF(__pyx_t_1); + PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_2); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_v_state); + __pyx_t_1 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L0; + + /* "(tree fragment)":12 + * else: + * use_setstate = self.chunked is not None or self.compression is not None or self.headers is not None or self.raw_headers is not None or self.reason is not None or self.should_close is not None or self.upgrade is not None or self.version is not None + * if use_setstate: # <<<<<<<<<<<<<< + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state + * else: + */ + } + + /* "(tree fragment)":15 + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, None), state + * else: + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_RawResponseMessage__set_state(self, __pyx_state) + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_pyx_unpickle_RawResponseMessag); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_2 = PyTuple_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_GIVEREF(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self)))); + __Pyx_INCREF(__pyx_int_209127132); + __Pyx_GIVEREF(__pyx_int_209127132); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_int_209127132); + __Pyx_INCREF(__pyx_v_state); + __Pyx_GIVEREF(__pyx_v_state); + PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_v_state); + __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2); + __pyx_t_6 = 0; + __pyx_t_2 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + } + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * cdef tuple state + * cdef object _dict + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_state); + __Pyx_XDECREF(__pyx_v__dict); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":16 + * else: + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_RawResponseMessage__set_state(self, __pyx_state) + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_6__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18RawResponseMessage_6__setstate_cython__(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":17 + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) + * def __setstate_cython__(self, __pyx_state): + * __pyx_unpickle_RawResponseMessage__set_state(self, __pyx_state) # <<<<<<<<<<<<<< + */ + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 17, __pyx_L1_error) + __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(__pyx_v_self, ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":16 + * else: + * return __pyx_unpickle_RawResponseMessage, (type(self), 0xc7706dc, state) + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * __pyx_unpickle_RawResponseMessage__set_state(self, __pyx_state) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.RawResponseMessage.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":248 + * + * + * cdef _new_response_message(object version, # <<<<<<<<<<<<<< + * int code, + * str reason, + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser__new_response_message(PyObject *__pyx_v_version, int __pyx_v_code, PyObject *__pyx_v_reason, PyObject *__pyx_v_headers, PyObject *__pyx_v_raw_headers, int __pyx_v_should_close, PyObject *__pyx_v_compression, int __pyx_v_upgrade, int __pyx_v_chunked) { + struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v_ret = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_new_response_message", 0); + + /* "aiohttp/_http_parser.pyx":258 + * bint chunked): + * cdef RawResponseMessage ret + * ret = RawResponseMessage.__new__(RawResponseMessage) # <<<<<<<<<<<<<< + * ret.version = version + * ret.code = code + */ + __pyx_t_1 = ((PyObject *)__pyx_tp_new_7aiohttp_12_http_parser_RawResponseMessage(((PyTypeObject *)__pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage), __pyx_empty_tuple, NULL)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 258, __pyx_L1_error) + __Pyx_GOTREF(((PyObject *)__pyx_t_1)); + __pyx_v_ret = ((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":259 + * cdef RawResponseMessage ret + * ret = RawResponseMessage.__new__(RawResponseMessage) + * ret.version = version # <<<<<<<<<<<<<< + * ret.code = code + * ret.reason = reason + */ + __Pyx_INCREF(__pyx_v_version); + __Pyx_GIVEREF(__pyx_v_version); + __Pyx_GOTREF(__pyx_v_ret->version); + __Pyx_DECREF(__pyx_v_ret->version); + __pyx_v_ret->version = __pyx_v_version; + + /* "aiohttp/_http_parser.pyx":260 + * ret = RawResponseMessage.__new__(RawResponseMessage) + * ret.version = version + * ret.code = code # <<<<<<<<<<<<<< + * ret.reason = reason + * ret.headers = headers + */ + __pyx_v_ret->code = __pyx_v_code; + + /* "aiohttp/_http_parser.pyx":261 + * ret.version = version + * ret.code = code + * ret.reason = reason # <<<<<<<<<<<<<< + * ret.headers = headers + * ret.raw_headers = raw_headers + */ + __Pyx_INCREF(__pyx_v_reason); + __Pyx_GIVEREF(__pyx_v_reason); + __Pyx_GOTREF(__pyx_v_ret->reason); + __Pyx_DECREF(__pyx_v_ret->reason); + __pyx_v_ret->reason = __pyx_v_reason; + + /* "aiohttp/_http_parser.pyx":262 + * ret.code = code + * ret.reason = reason + * ret.headers = headers # <<<<<<<<<<<<<< + * ret.raw_headers = raw_headers + * ret.should_close = should_close + */ + __Pyx_INCREF(__pyx_v_headers); + __Pyx_GIVEREF(__pyx_v_headers); + __Pyx_GOTREF(__pyx_v_ret->headers); + __Pyx_DECREF(__pyx_v_ret->headers); + __pyx_v_ret->headers = __pyx_v_headers; + + /* "aiohttp/_http_parser.pyx":263 + * ret.reason = reason + * ret.headers = headers + * ret.raw_headers = raw_headers # <<<<<<<<<<<<<< + * ret.should_close = should_close + * ret.compression = compression + */ + __Pyx_INCREF(__pyx_v_raw_headers); + __Pyx_GIVEREF(__pyx_v_raw_headers); + __Pyx_GOTREF(__pyx_v_ret->raw_headers); + __Pyx_DECREF(__pyx_v_ret->raw_headers); + __pyx_v_ret->raw_headers = __pyx_v_raw_headers; + + /* "aiohttp/_http_parser.pyx":264 + * ret.headers = headers + * ret.raw_headers = raw_headers + * ret.should_close = should_close # <<<<<<<<<<<<<< + * ret.compression = compression + * ret.upgrade = upgrade + */ + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_should_close); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 264, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_ret->should_close); + __Pyx_DECREF(__pyx_v_ret->should_close); + __pyx_v_ret->should_close = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":265 + * ret.raw_headers = raw_headers + * ret.should_close = should_close + * ret.compression = compression # <<<<<<<<<<<<<< + * ret.upgrade = upgrade + * ret.chunked = chunked + */ + __Pyx_INCREF(__pyx_v_compression); + __Pyx_GIVEREF(__pyx_v_compression); + __Pyx_GOTREF(__pyx_v_ret->compression); + __Pyx_DECREF(__pyx_v_ret->compression); + __pyx_v_ret->compression = __pyx_v_compression; + + /* "aiohttp/_http_parser.pyx":266 + * ret.should_close = should_close + * ret.compression = compression + * ret.upgrade = upgrade # <<<<<<<<<<<<<< + * ret.chunked = chunked + * return ret + */ + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_upgrade); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 266, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_ret->upgrade); + __Pyx_DECREF(__pyx_v_ret->upgrade); + __pyx_v_ret->upgrade = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":267 + * ret.compression = compression + * ret.upgrade = upgrade + * ret.chunked = chunked # <<<<<<<<<<<<<< + * return ret + * + */ + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_chunked); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 267, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_ret->chunked); + __Pyx_DECREF(__pyx_v_ret->chunked); + __pyx_v_ret->chunked = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":268 + * ret.upgrade = upgrade + * ret.chunked = chunked + * return ret # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject *)__pyx_v_ret)); + __pyx_r = ((PyObject *)__pyx_v_ret); + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":248 + * + * + * cdef _new_response_message(object version, # <<<<<<<<<<<<<< + * int code, + * str reason, + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser._new_response_message", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_ret); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":312 + * Py_buffer py_buf + * + * def __cinit__(self): # <<<<<<<<<<<<<< + * self._cparser = \ + * PyMem_Malloc(sizeof(cparser.http_parser)) + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_12_http_parser_10HttpParser_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7aiohttp_12_http_parser_10HttpParser_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0); + if (unlikely(PyTuple_GET_SIZE(__pyx_args) > 0)) { + __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 0, 0, PyTuple_GET_SIZE(__pyx_args)); return -1;} + if (unlikely(__pyx_kwds) && unlikely(PyDict_Size(__pyx_kwds) > 0) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "__cinit__", 0))) return -1; + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser___cinit__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_12_http_parser_10HttpParser___cinit__(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__cinit__", 0); + + /* "aiohttp/_http_parser.pyx":313 + * + * def __cinit__(self): + * self._cparser = \ # <<<<<<<<<<<<<< + * PyMem_Malloc(sizeof(cparser.http_parser)) + * if self._cparser is NULL: + */ + __pyx_v_self->_cparser = ((struct http_parser *)PyMem_Malloc((sizeof(struct http_parser)))); + + /* "aiohttp/_http_parser.pyx":315 + * self._cparser = \ + * PyMem_Malloc(sizeof(cparser.http_parser)) + * if self._cparser is NULL: # <<<<<<<<<<<<<< + * raise MemoryError() + * + */ + __pyx_t_1 = ((__pyx_v_self->_cparser == NULL) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_parser.pyx":316 + * PyMem_Malloc(sizeof(cparser.http_parser)) + * if self._cparser is NULL: + * raise MemoryError() # <<<<<<<<<<<<<< + * + * self._csettings = \ + */ + PyErr_NoMemory(); __PYX_ERR(0, 316, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":315 + * self._cparser = \ + * PyMem_Malloc(sizeof(cparser.http_parser)) + * if self._cparser is NULL: # <<<<<<<<<<<<<< + * raise MemoryError() + * + */ + } + + /* "aiohttp/_http_parser.pyx":318 + * raise MemoryError() + * + * self._csettings = \ # <<<<<<<<<<<<<< + * PyMem_Malloc(sizeof(cparser.http_parser_settings)) + * if self._csettings is NULL: + */ + __pyx_v_self->_csettings = ((struct http_parser_settings *)PyMem_Malloc((sizeof(struct http_parser_settings)))); + + /* "aiohttp/_http_parser.pyx":320 + * self._csettings = \ + * PyMem_Malloc(sizeof(cparser.http_parser_settings)) + * if self._csettings is NULL: # <<<<<<<<<<<<<< + * raise MemoryError() + * + */ + __pyx_t_1 = ((__pyx_v_self->_csettings == NULL) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_parser.pyx":321 + * PyMem_Malloc(sizeof(cparser.http_parser_settings)) + * if self._csettings is NULL: + * raise MemoryError() # <<<<<<<<<<<<<< + * + * def __dealloc__(self): + */ + PyErr_NoMemory(); __PYX_ERR(0, 321, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":320 + * self._csettings = \ + * PyMem_Malloc(sizeof(cparser.http_parser_settings)) + * if self._csettings is NULL: # <<<<<<<<<<<<<< + * raise MemoryError() + * + */ + } + + /* "aiohttp/_http_parser.pyx":312 + * Py_buffer py_buf + * + * def __cinit__(self): # <<<<<<<<<<<<<< + * self._cparser = \ + * PyMem_Malloc(sizeof(cparser.http_parser)) + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":323 + * raise MemoryError() + * + * def __dealloc__(self): # <<<<<<<<<<<<<< + * PyMem_Free(self._cparser) + * PyMem_Free(self._csettings) + */ + +/* Python wrapper */ +static void __pyx_pw_7aiohttp_12_http_parser_10HttpParser_3__dealloc__(PyObject *__pyx_v_self); /*proto*/ +static void __pyx_pw_7aiohttp_12_http_parser_10HttpParser_3__dealloc__(PyObject *__pyx_v_self) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0); + __pyx_pf_7aiohttp_12_http_parser_10HttpParser_2__dealloc__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +static void __pyx_pf_7aiohttp_12_http_parser_10HttpParser_2__dealloc__(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__dealloc__", 0); + + /* "aiohttp/_http_parser.pyx":324 + * + * def __dealloc__(self): + * PyMem_Free(self._cparser) # <<<<<<<<<<<<<< + * PyMem_Free(self._csettings) + * + */ + PyMem_Free(__pyx_v_self->_cparser); + + /* "aiohttp/_http_parser.pyx":325 + * def __dealloc__(self): + * PyMem_Free(self._cparser) + * PyMem_Free(self._csettings) # <<<<<<<<<<<<<< + * + * cdef _init(self, cparser.http_parser_type mode, + */ + PyMem_Free(__pyx_v_self->_csettings); + + /* "aiohttp/_http_parser.pyx":323 + * raise MemoryError() + * + * def __dealloc__(self): # <<<<<<<<<<<<<< + * PyMem_Free(self._cparser) + * PyMem_Free(self._csettings) + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "aiohttp/_http_parser.pyx":327 + * PyMem_Free(self._csettings) + * + * cdef _init(self, cparser.http_parser_type mode, # <<<<<<<<<<<<<< + * object protocol, object loop, int limit, + * object timer=None, + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__init(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, enum http_parser_type __pyx_v_mode, PyObject *__pyx_v_protocol, PyObject *__pyx_v_loop, int __pyx_v_limit, struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init *__pyx_optional_args) { + + /* "aiohttp/_http_parser.pyx":329 + * cdef _init(self, cparser.http_parser_type mode, + * object protocol, object loop, int limit, + * object timer=None, # <<<<<<<<<<<<<< + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + */ + PyObject *__pyx_v_timer = ((PyObject *)Py_None); + size_t __pyx_v_max_line_size = ((size_t)0x1FFE); + size_t __pyx_v_max_headers = ((size_t)0x8000); + size_t __pyx_v_max_field_size = ((size_t)0x1FFE); + + /* "aiohttp/_http_parser.pyx":331 + * object timer=None, + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, # <<<<<<<<<<<<<< + * bint response_with_body=True, bint read_until_eof=False, + * bint auto_decompress=True): + */ + PyObject *__pyx_v_payload_exception = ((PyObject *)Py_None); + + /* "aiohttp/_http_parser.pyx":332 + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + * bint response_with_body=True, bint read_until_eof=False, # <<<<<<<<<<<<<< + * bint auto_decompress=True): + * cparser.http_parser_init(self._cparser, mode) + */ + int __pyx_v_response_with_body = ((int)1); + int __pyx_v_read_until_eof = ((int)0); + + /* "aiohttp/_http_parser.pyx":333 + * size_t max_field_size=8190, payload_exception=None, + * bint response_with_body=True, bint read_until_eof=False, + * bint auto_decompress=True): # <<<<<<<<<<<<<< + * cparser.http_parser_init(self._cparser, mode) + * self._cparser.data = self + */ + int __pyx_v_auto_decompress = ((int)1); + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_init", 0); + if (__pyx_optional_args) { + if (__pyx_optional_args->__pyx_n > 0) { + __pyx_v_timer = __pyx_optional_args->timer; + if (__pyx_optional_args->__pyx_n > 1) { + __pyx_v_max_line_size = __pyx_optional_args->max_line_size; + if (__pyx_optional_args->__pyx_n > 2) { + __pyx_v_max_headers = __pyx_optional_args->max_headers; + if (__pyx_optional_args->__pyx_n > 3) { + __pyx_v_max_field_size = __pyx_optional_args->max_field_size; + if (__pyx_optional_args->__pyx_n > 4) { + __pyx_v_payload_exception = __pyx_optional_args->payload_exception; + if (__pyx_optional_args->__pyx_n > 5) { + __pyx_v_response_with_body = __pyx_optional_args->response_with_body; + if (__pyx_optional_args->__pyx_n > 6) { + __pyx_v_read_until_eof = __pyx_optional_args->read_until_eof; + if (__pyx_optional_args->__pyx_n > 7) { + __pyx_v_auto_decompress = __pyx_optional_args->auto_decompress; + } + } + } + } + } + } + } + } + } + + /* "aiohttp/_http_parser.pyx":334 + * bint response_with_body=True, bint read_until_eof=False, + * bint auto_decompress=True): + * cparser.http_parser_init(self._cparser, mode) # <<<<<<<<<<<<<< + * self._cparser.data = self + * self._cparser.content_length = 0 + */ + http_parser_init(__pyx_v_self->_cparser, __pyx_v_mode); + + /* "aiohttp/_http_parser.pyx":335 + * bint auto_decompress=True): + * cparser.http_parser_init(self._cparser, mode) + * self._cparser.data = self # <<<<<<<<<<<<<< + * self._cparser.content_length = 0 + * + */ + __pyx_v_self->_cparser->data = ((void *)__pyx_v_self); + + /* "aiohttp/_http_parser.pyx":336 + * cparser.http_parser_init(self._cparser, mode) + * self._cparser.data = self + * self._cparser.content_length = 0 # <<<<<<<<<<<<<< + * + * cparser.http_parser_settings_init(self._csettings) + */ + __pyx_v_self->_cparser->content_length = 0; + + /* "aiohttp/_http_parser.pyx":338 + * self._cparser.content_length = 0 + * + * cparser.http_parser_settings_init(self._csettings) # <<<<<<<<<<<<<< + * + * self._protocol = protocol + */ + http_parser_settings_init(__pyx_v_self->_csettings); + + /* "aiohttp/_http_parser.pyx":340 + * cparser.http_parser_settings_init(self._csettings) + * + * self._protocol = protocol # <<<<<<<<<<<<<< + * self._loop = loop + * self._timer = timer + */ + __Pyx_INCREF(__pyx_v_protocol); + __Pyx_GIVEREF(__pyx_v_protocol); + __Pyx_GOTREF(__pyx_v_self->_protocol); + __Pyx_DECREF(__pyx_v_self->_protocol); + __pyx_v_self->_protocol = __pyx_v_protocol; + + /* "aiohttp/_http_parser.pyx":341 + * + * self._protocol = protocol + * self._loop = loop # <<<<<<<<<<<<<< + * self._timer = timer + * + */ + __Pyx_INCREF(__pyx_v_loop); + __Pyx_GIVEREF(__pyx_v_loop); + __Pyx_GOTREF(__pyx_v_self->_loop); + __Pyx_DECREF(__pyx_v_self->_loop); + __pyx_v_self->_loop = __pyx_v_loop; + + /* "aiohttp/_http_parser.pyx":342 + * self._protocol = protocol + * self._loop = loop + * self._timer = timer # <<<<<<<<<<<<<< + * + * self._buf = bytearray() + */ + __Pyx_INCREF(__pyx_v_timer); + __Pyx_GIVEREF(__pyx_v_timer); + __Pyx_GOTREF(__pyx_v_self->_timer); + __Pyx_DECREF(__pyx_v_self->_timer); + __pyx_v_self->_timer = __pyx_v_timer; + + /* "aiohttp/_http_parser.pyx":344 + * self._timer = timer + * + * self._buf = bytearray() # <<<<<<<<<<<<<< + * self._payload = None + * self._payload_error = 0 + */ + __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)(&PyByteArray_Type))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 344, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_self->_buf); + __Pyx_DECREF(__pyx_v_self->_buf); + __pyx_v_self->_buf = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":345 + * + * self._buf = bytearray() + * self._payload = None # <<<<<<<<<<<<<< + * self._payload_error = 0 + * self._payload_exception = payload_exception + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_payload); + __Pyx_DECREF(__pyx_v_self->_payload); + __pyx_v_self->_payload = Py_None; + + /* "aiohttp/_http_parser.pyx":346 + * self._buf = bytearray() + * self._payload = None + * self._payload_error = 0 # <<<<<<<<<<<<<< + * self._payload_exception = payload_exception + * self._messages = [] + */ + __pyx_v_self->_payload_error = 0; + + /* "aiohttp/_http_parser.pyx":347 + * self._payload = None + * self._payload_error = 0 + * self._payload_exception = payload_exception # <<<<<<<<<<<<<< + * self._messages = [] + * + */ + __Pyx_INCREF(__pyx_v_payload_exception); + __Pyx_GIVEREF(__pyx_v_payload_exception); + __Pyx_GOTREF(__pyx_v_self->_payload_exception); + __Pyx_DECREF(__pyx_v_self->_payload_exception); + __pyx_v_self->_payload_exception = __pyx_v_payload_exception; + + /* "aiohttp/_http_parser.pyx":348 + * self._payload_error = 0 + * self._payload_exception = payload_exception + * self._messages = [] # <<<<<<<<<<<<<< + * + * self._raw_name = bytearray() + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 348, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_self->_messages); + __Pyx_DECREF(__pyx_v_self->_messages); + __pyx_v_self->_messages = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":350 + * self._messages = [] + * + * self._raw_name = bytearray() # <<<<<<<<<<<<<< + * self._raw_value = bytearray() + * self._has_value = False + */ + __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)(&PyByteArray_Type))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 350, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_self->_raw_name); + __Pyx_DECREF(__pyx_v_self->_raw_name); + __pyx_v_self->_raw_name = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":351 + * + * self._raw_name = bytearray() + * self._raw_value = bytearray() # <<<<<<<<<<<<<< + * self._has_value = False + * + */ + __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)(&PyByteArray_Type))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 351, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_self->_raw_value); + __Pyx_DECREF(__pyx_v_self->_raw_value); + __pyx_v_self->_raw_value = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":352 + * self._raw_name = bytearray() + * self._raw_value = bytearray() + * self._has_value = False # <<<<<<<<<<<<<< + * + * self._max_line_size = max_line_size + */ + __pyx_v_self->_has_value = 0; + + /* "aiohttp/_http_parser.pyx":354 + * self._has_value = False + * + * self._max_line_size = max_line_size # <<<<<<<<<<<<<< + * self._max_headers = max_headers + * self._max_field_size = max_field_size + */ + __pyx_v_self->_max_line_size = __pyx_v_max_line_size; + + /* "aiohttp/_http_parser.pyx":355 + * + * self._max_line_size = max_line_size + * self._max_headers = max_headers # <<<<<<<<<<<<<< + * self._max_field_size = max_field_size + * self._response_with_body = response_with_body + */ + __pyx_v_self->_max_headers = __pyx_v_max_headers; + + /* "aiohttp/_http_parser.pyx":356 + * self._max_line_size = max_line_size + * self._max_headers = max_headers + * self._max_field_size = max_field_size # <<<<<<<<<<<<<< + * self._response_with_body = response_with_body + * self._read_until_eof = read_until_eof + */ + __pyx_v_self->_max_field_size = __pyx_v_max_field_size; + + /* "aiohttp/_http_parser.pyx":357 + * self._max_headers = max_headers + * self._max_field_size = max_field_size + * self._response_with_body = response_with_body # <<<<<<<<<<<<<< + * self._read_until_eof = read_until_eof + * self._upgraded = False + */ + __pyx_v_self->_response_with_body = __pyx_v_response_with_body; + + /* "aiohttp/_http_parser.pyx":358 + * self._max_field_size = max_field_size + * self._response_with_body = response_with_body + * self._read_until_eof = read_until_eof # <<<<<<<<<<<<<< + * self._upgraded = False + * self._auto_decompress = auto_decompress + */ + __pyx_v_self->_read_until_eof = __pyx_v_read_until_eof; + + /* "aiohttp/_http_parser.pyx":359 + * self._response_with_body = response_with_body + * self._read_until_eof = read_until_eof + * self._upgraded = False # <<<<<<<<<<<<<< + * self._auto_decompress = auto_decompress + * self._content_encoding = None + */ + __pyx_v_self->_upgraded = 0; + + /* "aiohttp/_http_parser.pyx":360 + * self._read_until_eof = read_until_eof + * self._upgraded = False + * self._auto_decompress = auto_decompress # <<<<<<<<<<<<<< + * self._content_encoding = None + * + */ + __pyx_v_self->_auto_decompress = __pyx_v_auto_decompress; + + /* "aiohttp/_http_parser.pyx":361 + * self._upgraded = False + * self._auto_decompress = auto_decompress + * self._content_encoding = None # <<<<<<<<<<<<<< + * + * self._csettings.on_url = cb_on_url + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_content_encoding); + __Pyx_DECREF(__pyx_v_self->_content_encoding); + __pyx_v_self->_content_encoding = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":363 + * self._content_encoding = None + * + * self._csettings.on_url = cb_on_url # <<<<<<<<<<<<<< + * self._csettings.on_status = cb_on_status + * self._csettings.on_header_field = cb_on_header_field + */ + __pyx_v_self->_csettings->on_url = __pyx_f_7aiohttp_12_http_parser_cb_on_url; + + /* "aiohttp/_http_parser.pyx":364 + * + * self._csettings.on_url = cb_on_url + * self._csettings.on_status = cb_on_status # <<<<<<<<<<<<<< + * self._csettings.on_header_field = cb_on_header_field + * self._csettings.on_header_value = cb_on_header_value + */ + __pyx_v_self->_csettings->on_status = __pyx_f_7aiohttp_12_http_parser_cb_on_status; + + /* "aiohttp/_http_parser.pyx":365 + * self._csettings.on_url = cb_on_url + * self._csettings.on_status = cb_on_status + * self._csettings.on_header_field = cb_on_header_field # <<<<<<<<<<<<<< + * self._csettings.on_header_value = cb_on_header_value + * self._csettings.on_headers_complete = cb_on_headers_complete + */ + __pyx_v_self->_csettings->on_header_field = __pyx_f_7aiohttp_12_http_parser_cb_on_header_field; + + /* "aiohttp/_http_parser.pyx":366 + * self._csettings.on_status = cb_on_status + * self._csettings.on_header_field = cb_on_header_field + * self._csettings.on_header_value = cb_on_header_value # <<<<<<<<<<<<<< + * self._csettings.on_headers_complete = cb_on_headers_complete + * self._csettings.on_body = cb_on_body + */ + __pyx_v_self->_csettings->on_header_value = __pyx_f_7aiohttp_12_http_parser_cb_on_header_value; + + /* "aiohttp/_http_parser.pyx":367 + * self._csettings.on_header_field = cb_on_header_field + * self._csettings.on_header_value = cb_on_header_value + * self._csettings.on_headers_complete = cb_on_headers_complete # <<<<<<<<<<<<<< + * self._csettings.on_body = cb_on_body + * self._csettings.on_message_begin = cb_on_message_begin + */ + __pyx_v_self->_csettings->on_headers_complete = __pyx_f_7aiohttp_12_http_parser_cb_on_headers_complete; + + /* "aiohttp/_http_parser.pyx":368 + * self._csettings.on_header_value = cb_on_header_value + * self._csettings.on_headers_complete = cb_on_headers_complete + * self._csettings.on_body = cb_on_body # <<<<<<<<<<<<<< + * self._csettings.on_message_begin = cb_on_message_begin + * self._csettings.on_message_complete = cb_on_message_complete + */ + __pyx_v_self->_csettings->on_body = __pyx_f_7aiohttp_12_http_parser_cb_on_body; + + /* "aiohttp/_http_parser.pyx":369 + * self._csettings.on_headers_complete = cb_on_headers_complete + * self._csettings.on_body = cb_on_body + * self._csettings.on_message_begin = cb_on_message_begin # <<<<<<<<<<<<<< + * self._csettings.on_message_complete = cb_on_message_complete + * self._csettings.on_chunk_header = cb_on_chunk_header + */ + __pyx_v_self->_csettings->on_message_begin = __pyx_f_7aiohttp_12_http_parser_cb_on_message_begin; + + /* "aiohttp/_http_parser.pyx":370 + * self._csettings.on_body = cb_on_body + * self._csettings.on_message_begin = cb_on_message_begin + * self._csettings.on_message_complete = cb_on_message_complete # <<<<<<<<<<<<<< + * self._csettings.on_chunk_header = cb_on_chunk_header + * self._csettings.on_chunk_complete = cb_on_chunk_complete + */ + __pyx_v_self->_csettings->on_message_complete = __pyx_f_7aiohttp_12_http_parser_cb_on_message_complete; + + /* "aiohttp/_http_parser.pyx":371 + * self._csettings.on_message_begin = cb_on_message_begin + * self._csettings.on_message_complete = cb_on_message_complete + * self._csettings.on_chunk_header = cb_on_chunk_header # <<<<<<<<<<<<<< + * self._csettings.on_chunk_complete = cb_on_chunk_complete + * + */ + __pyx_v_self->_csettings->on_chunk_header = __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_header; + + /* "aiohttp/_http_parser.pyx":372 + * self._csettings.on_message_complete = cb_on_message_complete + * self._csettings.on_chunk_header = cb_on_chunk_header + * self._csettings.on_chunk_complete = cb_on_chunk_complete # <<<<<<<<<<<<<< + * + * self._last_error = None + */ + __pyx_v_self->_csettings->on_chunk_complete = __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_complete; + + /* "aiohttp/_http_parser.pyx":374 + * self._csettings.on_chunk_complete = cb_on_chunk_complete + * + * self._last_error = None # <<<<<<<<<<<<<< + * self._limit = limit + * + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_last_error); + __Pyx_DECREF(__pyx_v_self->_last_error); + __pyx_v_self->_last_error = Py_None; + + /* "aiohttp/_http_parser.pyx":375 + * + * self._last_error = None + * self._limit = limit # <<<<<<<<<<<<<< + * + * cdef _process_header(self): + */ + __pyx_v_self->_limit = __pyx_v_limit; + + /* "aiohttp/_http_parser.pyx":327 + * PyMem_Free(self._csettings) + * + * cdef _init(self, cparser.http_parser_type mode, # <<<<<<<<<<<<<< + * object protocol, object loop, int limit, + * object timer=None, + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._init", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":377 + * self._limit = limit + * + * cdef _process_header(self): # <<<<<<<<<<<<<< + * if self._raw_name: + * raw_name = bytes(self._raw_name) + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__process_header(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + PyObject *__pyx_v_raw_name = NULL; + PyObject *__pyx_v_raw_value = NULL; + PyObject *__pyx_v_name = NULL; + PyObject *__pyx_v_value = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + int __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_process_header", 0); + + /* "aiohttp/_http_parser.pyx":378 + * + * cdef _process_header(self): + * if self._raw_name: # <<<<<<<<<<<<<< + * raw_name = bytes(self._raw_name) + * raw_value = bytes(self._raw_value) + */ + __pyx_t_1 = (__pyx_v_self->_raw_name != Py_None)&&(PyByteArray_GET_SIZE(__pyx_v_self->_raw_name) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":379 + * cdef _process_header(self): + * if self._raw_name: + * raw_name = bytes(self._raw_name) # <<<<<<<<<<<<<< + * raw_value = bytes(self._raw_value) + * + */ + __pyx_t_2 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_v_self->_raw_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 379, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_raw_name = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":380 + * if self._raw_name: + * raw_name = bytes(self._raw_name) + * raw_value = bytes(self._raw_value) # <<<<<<<<<<<<<< + * + * name = find_header(raw_name) + */ + __pyx_t_2 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_v_self->_raw_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 380, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_raw_value = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":382 + * raw_value = bytes(self._raw_value) + * + * name = find_header(raw_name) # <<<<<<<<<<<<<< + * value = raw_value.decode('utf-8', 'surrogateescape') + * + */ + __pyx_t_2 = __pyx_f_7aiohttp_12_http_parser_find_header(__pyx_v_raw_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 382, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_name = __pyx_t_2; + __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":383 + * + * name = find_header(raw_name) + * value = raw_value.decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * + * self._headers.add(name, value) + */ + __pyx_t_2 = __Pyx_decode_bytes(__pyx_v_raw_value, 0, PY_SSIZE_T_MAX, NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 383, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_v_value = __pyx_t_2; + __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":385 + * value = raw_value.decode('utf-8', 'surrogateescape') + * + * self._headers.add(name, value) # <<<<<<<<<<<<<< + * + * if name is CONTENT_ENCODING: + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_headers, __pyx_n_s_add); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 385, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = NULL; + __pyx_t_5 = 0; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + __pyx_t_5 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_3)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_name, __pyx_v_value}; + __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 385, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_2); + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) { + PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_v_name, __pyx_v_value}; + __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_5, 2+__pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 385, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GOTREF(__pyx_t_2); + } else + #endif + { + __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 385, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + if (__pyx_t_4) { + __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __pyx_t_4 = NULL; + } + __Pyx_INCREF(__pyx_v_name); + __Pyx_GIVEREF(__pyx_v_name); + PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_v_name); + __Pyx_INCREF(__pyx_v_value); + __Pyx_GIVEREF(__pyx_v_value); + PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_value); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 385, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":387 + * self._headers.add(name, value) + * + * if name is CONTENT_ENCODING: # <<<<<<<<<<<<<< + * self._content_encoding = value + * + */ + __pyx_t_1 = (__pyx_v_name == __pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING); + __pyx_t_7 = (__pyx_t_1 != 0); + if (__pyx_t_7) { + + /* "aiohttp/_http_parser.pyx":388 + * + * if name is CONTENT_ENCODING: + * self._content_encoding = value # <<<<<<<<<<<<<< + * + * PyByteArray_Resize(self._raw_name, 0) + */ + if (!(likely(PyUnicode_CheckExact(__pyx_v_value))||((__pyx_v_value) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_v_value)->tp_name), 0))) __PYX_ERR(0, 388, __pyx_L1_error) + __pyx_t_2 = __pyx_v_value; + __Pyx_INCREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_v_self->_content_encoding); + __Pyx_DECREF(__pyx_v_self->_content_encoding); + __pyx_v_self->_content_encoding = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":387 + * self._headers.add(name, value) + * + * if name is CONTENT_ENCODING: # <<<<<<<<<<<<<< + * self._content_encoding = value + * + */ + } + + /* "aiohttp/_http_parser.pyx":390 + * self._content_encoding = value + * + * PyByteArray_Resize(self._raw_name, 0) # <<<<<<<<<<<<<< + * PyByteArray_Resize(self._raw_value, 0) + * self._has_value = False + */ + __pyx_t_2 = __pyx_v_self->_raw_name; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = PyByteArray_Resize(__pyx_t_2, 0); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(0, 390, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":391 + * + * PyByteArray_Resize(self._raw_name, 0) + * PyByteArray_Resize(self._raw_value, 0) # <<<<<<<<<<<<<< + * self._has_value = False + * self._raw_headers.append((raw_name, raw_value)) + */ + __pyx_t_2 = __pyx_v_self->_raw_value; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = PyByteArray_Resize(__pyx_t_2, 0); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(0, 391, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":392 + * PyByteArray_Resize(self._raw_name, 0) + * PyByteArray_Resize(self._raw_value, 0) + * self._has_value = False # <<<<<<<<<<<<<< + * self._raw_headers.append((raw_name, raw_value)) + * + */ + __pyx_v_self->_has_value = 0; + + /* "aiohttp/_http_parser.pyx":393 + * PyByteArray_Resize(self._raw_value, 0) + * self._has_value = False + * self._raw_headers.append((raw_name, raw_value)) # <<<<<<<<<<<<<< + * + * cdef _on_header_field(self, char* at, size_t length): + */ + if (unlikely(__pyx_v_self->_raw_headers == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); + __PYX_ERR(0, 393, __pyx_L1_error) + } + __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 393, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_raw_name); + __Pyx_GIVEREF(__pyx_v_raw_name); + PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_raw_name); + __Pyx_INCREF(__pyx_v_raw_value); + __Pyx_GIVEREF(__pyx_v_raw_value); + PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_raw_value); + __pyx_t_8 = __Pyx_PyList_Append(__pyx_v_self->_raw_headers, __pyx_t_2); if (unlikely(__pyx_t_8 == ((int)-1))) __PYX_ERR(0, 393, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":378 + * + * cdef _process_header(self): + * if self._raw_name: # <<<<<<<<<<<<<< + * raw_name = bytes(self._raw_name) + * raw_value = bytes(self._raw_value) + */ + } + + /* "aiohttp/_http_parser.pyx":377 + * self._limit = limit + * + * cdef _process_header(self): # <<<<<<<<<<<<<< + * if self._raw_name: + * raw_name = bytes(self._raw_name) + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._process_header", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_raw_name); + __Pyx_XDECREF(__pyx_v_raw_value); + __Pyx_XDECREF(__pyx_v_name); + __Pyx_XDECREF(__pyx_v_value); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":395 + * self._raw_headers.append((raw_name, raw_value)) + * + * cdef _on_header_field(self, char* at, size_t length): # <<<<<<<<<<<<<< + * cdef Py_ssize_t size + * cdef char *buf + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_field(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, char *__pyx_v_at, size_t __pyx_v_length) { + Py_ssize_t __pyx_v_size; + char *__pyx_v_buf; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + int __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_on_header_field", 0); + + /* "aiohttp/_http_parser.pyx":398 + * cdef Py_ssize_t size + * cdef char *buf + * if self._has_value: # <<<<<<<<<<<<<< + * self._process_header() + * + */ + __pyx_t_1 = (__pyx_v_self->_has_value != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":399 + * cdef char *buf + * if self._has_value: + * self._process_header() # <<<<<<<<<<<<<< + * + * size = PyByteArray_Size(self._raw_name) + */ + __pyx_t_2 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self->__pyx_vtab)->_process_header(__pyx_v_self); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 399, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":398 + * cdef Py_ssize_t size + * cdef char *buf + * if self._has_value: # <<<<<<<<<<<<<< + * self._process_header() + * + */ + } + + /* "aiohttp/_http_parser.pyx":401 + * self._process_header() + * + * size = PyByteArray_Size(self._raw_name) # <<<<<<<<<<<<<< + * PyByteArray_Resize(self._raw_name, size + length) + * buf = PyByteArray_AsString(self._raw_name) + */ + __pyx_t_2 = __pyx_v_self->_raw_name; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = PyByteArray_Size(__pyx_t_2); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1L))) __PYX_ERR(0, 401, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v_size = __pyx_t_3; + + /* "aiohttp/_http_parser.pyx":402 + * + * size = PyByteArray_Size(self._raw_name) + * PyByteArray_Resize(self._raw_name, size + length) # <<<<<<<<<<<<<< + * buf = PyByteArray_AsString(self._raw_name) + * memcpy(buf + size, at, length) + */ + __pyx_t_2 = __pyx_v_self->_raw_name; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_4 = PyByteArray_Resize(__pyx_t_2, (__pyx_v_size + __pyx_v_length)); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 402, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":403 + * size = PyByteArray_Size(self._raw_name) + * PyByteArray_Resize(self._raw_name, size + length) + * buf = PyByteArray_AsString(self._raw_name) # <<<<<<<<<<<<<< + * memcpy(buf + size, at, length) + * + */ + __pyx_t_2 = __pyx_v_self->_raw_name; + __Pyx_INCREF(__pyx_t_2); + __pyx_v_buf = PyByteArray_AsString(__pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":404 + * PyByteArray_Resize(self._raw_name, size + length) + * buf = PyByteArray_AsString(self._raw_name) + * memcpy(buf + size, at, length) # <<<<<<<<<<<<<< + * + * cdef _on_header_value(self, char* at, size_t length): + */ + (void)(memcpy((__pyx_v_buf + __pyx_v_size), __pyx_v_at, __pyx_v_length)); + + /* "aiohttp/_http_parser.pyx":395 + * self._raw_headers.append((raw_name, raw_value)) + * + * cdef _on_header_field(self, char* at, size_t length): # <<<<<<<<<<<<<< + * cdef Py_ssize_t size + * cdef char *buf + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_header_field", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":406 + * memcpy(buf + size, at, length) + * + * cdef _on_header_value(self, char* at, size_t length): # <<<<<<<<<<<<<< + * cdef Py_ssize_t size + * cdef char *buf + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_value(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, char *__pyx_v_at, size_t __pyx_v_length) { + Py_ssize_t __pyx_v_size; + char *__pyx_v_buf; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + int __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_on_header_value", 0); + + /* "aiohttp/_http_parser.pyx":410 + * cdef char *buf + * + * size = PyByteArray_Size(self._raw_value) # <<<<<<<<<<<<<< + * PyByteArray_Resize(self._raw_value, size + length) + * buf = PyByteArray_AsString(self._raw_value) + */ + __pyx_t_1 = __pyx_v_self->_raw_value; + __Pyx_INCREF(__pyx_t_1); + __pyx_t_2 = PyByteArray_Size(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1L))) __PYX_ERR(0, 410, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_size = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":411 + * + * size = PyByteArray_Size(self._raw_value) + * PyByteArray_Resize(self._raw_value, size + length) # <<<<<<<<<<<<<< + * buf = PyByteArray_AsString(self._raw_value) + * memcpy(buf + size, at, length) + */ + __pyx_t_1 = __pyx_v_self->_raw_value; + __Pyx_INCREF(__pyx_t_1); + __pyx_t_3 = PyByteArray_Resize(__pyx_t_1, (__pyx_v_size + __pyx_v_length)); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 411, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":412 + * size = PyByteArray_Size(self._raw_value) + * PyByteArray_Resize(self._raw_value, size + length) + * buf = PyByteArray_AsString(self._raw_value) # <<<<<<<<<<<<<< + * memcpy(buf + size, at, length) + * self._has_value = True + */ + __pyx_t_1 = __pyx_v_self->_raw_value; + __Pyx_INCREF(__pyx_t_1); + __pyx_v_buf = PyByteArray_AsString(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":413 + * PyByteArray_Resize(self._raw_value, size + length) + * buf = PyByteArray_AsString(self._raw_value) + * memcpy(buf + size, at, length) # <<<<<<<<<<<<<< + * self._has_value = True + * + */ + (void)(memcpy((__pyx_v_buf + __pyx_v_size), __pyx_v_at, __pyx_v_length)); + + /* "aiohttp/_http_parser.pyx":414 + * buf = PyByteArray_AsString(self._raw_value) + * memcpy(buf + size, at, length) + * self._has_value = True # <<<<<<<<<<<<<< + * + * cdef _on_headers_complete(self): + */ + __pyx_v_self->_has_value = 1; + + /* "aiohttp/_http_parser.pyx":406 + * memcpy(buf + size, at, length) + * + * cdef _on_header_value(self, char* at, size_t length): # <<<<<<<<<<<<<< + * cdef Py_ssize_t size + * cdef char *buf + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_header_value", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":416 + * self._has_value = True + * + * cdef _on_headers_complete(self): # <<<<<<<<<<<<<< + * self._process_header() + * + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + PyObject *__pyx_v_method = NULL; + int __pyx_v_should_close; + unsigned int __pyx_v_upgrade; + unsigned int __pyx_v_chunked; + PyObject *__pyx_v_raw_headers = NULL; + PyObject *__pyx_v_headers = NULL; + PyObject *__pyx_v_encoding = NULL; + PyObject *__pyx_v_enc = NULL; + PyObject *__pyx_v_msg = NULL; + PyObject *__pyx_v_payload = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + unsigned int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + int __pyx_t_9; + int __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_on_headers_complete", 0); + + /* "aiohttp/_http_parser.pyx":417 + * + * cdef _on_headers_complete(self): + * self._process_header() # <<<<<<<<<<<<<< + * + * method = http_method_str(self._cparser.method) + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self->__pyx_vtab)->_process_header(__pyx_v_self); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 417, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":419 + * self._process_header() + * + * method = http_method_str(self._cparser.method) # <<<<<<<<<<<<<< + * should_close = not cparser.http_should_keep_alive(self._cparser) + * upgrade = self._cparser.upgrade + */ + __pyx_t_1 = __pyx_f_7aiohttp_12_http_parser_http_method_str(__pyx_v_self->_cparser->method); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 419, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_method = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":420 + * + * method = http_method_str(self._cparser.method) + * should_close = not cparser.http_should_keep_alive(self._cparser) # <<<<<<<<<<<<<< + * upgrade = self._cparser.upgrade + * chunked = self._cparser.flags & cparser.F_CHUNKED + */ + __pyx_v_should_close = (!(http_should_keep_alive(__pyx_v_self->_cparser) != 0)); + + /* "aiohttp/_http_parser.pyx":421 + * method = http_method_str(self._cparser.method) + * should_close = not cparser.http_should_keep_alive(self._cparser) + * upgrade = self._cparser.upgrade # <<<<<<<<<<<<<< + * chunked = self._cparser.flags & cparser.F_CHUNKED + * + */ + __pyx_t_2 = __pyx_v_self->_cparser->upgrade; + __pyx_v_upgrade = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":422 + * should_close = not cparser.http_should_keep_alive(self._cparser) + * upgrade = self._cparser.upgrade + * chunked = self._cparser.flags & cparser.F_CHUNKED # <<<<<<<<<<<<<< + * + * raw_headers = tuple(self._raw_headers) + */ + __pyx_v_chunked = (__pyx_v_self->_cparser->flags & F_CHUNKED); + + /* "aiohttp/_http_parser.pyx":424 + * chunked = self._cparser.flags & cparser.F_CHUNKED + * + * raw_headers = tuple(self._raw_headers) # <<<<<<<<<<<<<< + * headers = CIMultiDictProxy(self._headers) + * + */ + if (unlikely(__pyx_v_self->_raw_headers == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); + __PYX_ERR(0, 424, __pyx_L1_error) + } + __pyx_t_1 = PyList_AsTuple(__pyx_v_self->_raw_headers); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 424, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_raw_headers = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":425 + * + * raw_headers = tuple(self._raw_headers) + * headers = CIMultiDictProxy(self._headers) # <<<<<<<<<<<<<< + * + * if upgrade or self._cparser.method == 5: # cparser.CONNECT: + */ + __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy); + __pyx_t_3 = __pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy; __pyx_t_4 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + } + } + __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_self->_headers) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_self->_headers); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 425, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_v_headers = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":427 + * headers = CIMultiDictProxy(self._headers) + * + * if upgrade or self._cparser.method == 5: # cparser.CONNECT: # <<<<<<<<<<<<<< + * self._upgraded = True + * + */ + __pyx_t_6 = (__pyx_v_upgrade != 0); + if (!__pyx_t_6) { + } else { + __pyx_t_5 = __pyx_t_6; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_6 = ((__pyx_v_self->_cparser->method == 5) != 0); + __pyx_t_5 = __pyx_t_6; + __pyx_L4_bool_binop_done:; + if (__pyx_t_5) { + + /* "aiohttp/_http_parser.pyx":428 + * + * if upgrade or self._cparser.method == 5: # cparser.CONNECT: + * self._upgraded = True # <<<<<<<<<<<<<< + * + * # do not support old websocket spec + */ + __pyx_v_self->_upgraded = 1; + + /* "aiohttp/_http_parser.pyx":427 + * headers = CIMultiDictProxy(self._headers) + * + * if upgrade or self._cparser.method == 5: # cparser.CONNECT: # <<<<<<<<<<<<<< + * self._upgraded = True + * + */ + } + + /* "aiohttp/_http_parser.pyx":431 + * + * # do not support old websocket spec + * if SEC_WEBSOCKET_KEY1 in headers: # <<<<<<<<<<<<<< + * raise InvalidHeader(SEC_WEBSOCKET_KEY1) + * + */ + __pyx_t_5 = (__Pyx_PySequence_ContainsTF(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1, __pyx_v_headers, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 431, __pyx_L1_error) + __pyx_t_6 = (__pyx_t_5 != 0); + if (unlikely(__pyx_t_6)) { + + /* "aiohttp/_http_parser.pyx":432 + * # do not support old websocket spec + * if SEC_WEBSOCKET_KEY1 in headers: + * raise InvalidHeader(SEC_WEBSOCKET_KEY1) # <<<<<<<<<<<<<< + * + * encoding = None + */ + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_InvalidHeader); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 432, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + } + } + __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 432, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 432, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":431 + * + * # do not support old websocket spec + * if SEC_WEBSOCKET_KEY1 in headers: # <<<<<<<<<<<<<< + * raise InvalidHeader(SEC_WEBSOCKET_KEY1) + * + */ + } + + /* "aiohttp/_http_parser.pyx":434 + * raise InvalidHeader(SEC_WEBSOCKET_KEY1) + * + * encoding = None # <<<<<<<<<<<<<< + * enc = self._content_encoding + * if enc is not None: + */ + __Pyx_INCREF(Py_None); + __pyx_v_encoding = Py_None; + + /* "aiohttp/_http_parser.pyx":435 + * + * encoding = None + * enc = self._content_encoding # <<<<<<<<<<<<<< + * if enc is not None: + * self._content_encoding = None + */ + __pyx_t_1 = __pyx_v_self->_content_encoding; + __Pyx_INCREF(__pyx_t_1); + __pyx_v_enc = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":436 + * encoding = None + * enc = self._content_encoding + * if enc is not None: # <<<<<<<<<<<<<< + * self._content_encoding = None + * enc = enc.lower() + */ + __pyx_t_6 = (__pyx_v_enc != Py_None); + __pyx_t_5 = (__pyx_t_6 != 0); + if (__pyx_t_5) { + + /* "aiohttp/_http_parser.pyx":437 + * enc = self._content_encoding + * if enc is not None: + * self._content_encoding = None # <<<<<<<<<<<<<< + * enc = enc.lower() + * if enc in ('gzip', 'deflate', 'br'): + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_content_encoding); + __Pyx_DECREF(__pyx_v_self->_content_encoding); + __pyx_v_self->_content_encoding = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":438 + * if enc is not None: + * self._content_encoding = None + * enc = enc.lower() # <<<<<<<<<<<<<< + * if enc in ('gzip', 'deflate', 'br'): + * encoding = enc + */ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_enc, __pyx_n_s_lower); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 438, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + } + } + __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 438, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF_SET(__pyx_v_enc, __pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":439 + * self._content_encoding = None + * enc = enc.lower() + * if enc in ('gzip', 'deflate', 'br'): # <<<<<<<<<<<<<< + * encoding = enc + * + */ + __Pyx_INCREF(__pyx_v_enc); + __pyx_t_1 = __pyx_v_enc; + __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_gzip, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 439, __pyx_L1_error) + if (!__pyx_t_6) { + } else { + __pyx_t_5 = __pyx_t_6; + goto __pyx_L9_bool_binop_done; + } + __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_deflate, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 439, __pyx_L1_error) + if (!__pyx_t_6) { + } else { + __pyx_t_5 = __pyx_t_6; + goto __pyx_L9_bool_binop_done; + } + __pyx_t_6 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_n_u_br, Py_EQ)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 439, __pyx_L1_error) + __pyx_t_5 = __pyx_t_6; + __pyx_L9_bool_binop_done:; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_6 = (__pyx_t_5 != 0); + if (__pyx_t_6) { + + /* "aiohttp/_http_parser.pyx":440 + * enc = enc.lower() + * if enc in ('gzip', 'deflate', 'br'): + * encoding = enc # <<<<<<<<<<<<<< + * + * if self._cparser.type == cparser.HTTP_REQUEST: + */ + __Pyx_INCREF(__pyx_v_enc); + __Pyx_DECREF_SET(__pyx_v_encoding, __pyx_v_enc); + + /* "aiohttp/_http_parser.pyx":439 + * self._content_encoding = None + * enc = enc.lower() + * if enc in ('gzip', 'deflate', 'br'): # <<<<<<<<<<<<<< + * encoding = enc + * + */ + } + + /* "aiohttp/_http_parser.pyx":436 + * encoding = None + * enc = self._content_encoding + * if enc is not None: # <<<<<<<<<<<<<< + * self._content_encoding = None + * enc = enc.lower() + */ + } + + /* "aiohttp/_http_parser.pyx":442 + * encoding = enc + * + * if self._cparser.type == cparser.HTTP_REQUEST: # <<<<<<<<<<<<<< + * msg = _new_request_message( + * method, self._path, + */ + __pyx_t_6 = ((__pyx_v_self->_cparser->type == HTTP_REQUEST) != 0); + if (__pyx_t_6) { + + /* "aiohttp/_http_parser.pyx":444 + * if self._cparser.type == cparser.HTTP_REQUEST: + * msg = _new_request_message( + * method, self._path, # <<<<<<<<<<<<<< + * self.http_version(), headers, raw_headers, + * should_close, encoding, upgrade, chunked, self._url) + */ + __pyx_t_1 = __pyx_v_self->_path; + __Pyx_INCREF(__pyx_t_1); + + /* "aiohttp/_http_parser.pyx":445 + * msg = _new_request_message( + * method, self._path, + * self.http_version(), headers, raw_headers, # <<<<<<<<<<<<<< + * should_close, encoding, upgrade, chunked, self._url) + * else: + */ + __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(__pyx_v_self); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 445, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + + /* "aiohttp/_http_parser.pyx":446 + * method, self._path, + * self.http_version(), headers, raw_headers, + * should_close, encoding, upgrade, chunked, self._url) # <<<<<<<<<<<<<< + * else: + * msg = _new_response_message( + */ + __pyx_t_4 = __pyx_v_self->_url; + __Pyx_INCREF(__pyx_t_4); + + /* "aiohttp/_http_parser.pyx":443 + * + * if self._cparser.type == cparser.HTTP_REQUEST: + * msg = _new_request_message( # <<<<<<<<<<<<<< + * method, self._path, + * self.http_version(), headers, raw_headers, + */ + __pyx_t_7 = __pyx_f_7aiohttp_12_http_parser__new_request_message(__pyx_v_method, ((PyObject*)__pyx_t_1), __pyx_t_3, __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_encoding, __pyx_v_upgrade, __pyx_v_chunked, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 443, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_msg = __pyx_t_7; + __pyx_t_7 = 0; + + /* "aiohttp/_http_parser.pyx":442 + * encoding = enc + * + * if self._cparser.type == cparser.HTTP_REQUEST: # <<<<<<<<<<<<<< + * msg = _new_request_message( + * method, self._path, + */ + goto __pyx_L12; + } + + /* "aiohttp/_http_parser.pyx":448 + * should_close, encoding, upgrade, chunked, self._url) + * else: + * msg = _new_response_message( # <<<<<<<<<<<<<< + * self.http_version(), self._cparser.status_code, self._reason, + * headers, raw_headers, should_close, encoding, + */ + /*else*/ { + + /* "aiohttp/_http_parser.pyx":449 + * else: + * msg = _new_response_message( + * self.http_version(), self._cparser.status_code, self._reason, # <<<<<<<<<<<<<< + * headers, raw_headers, should_close, encoding, + * upgrade, chunked) + */ + __pyx_t_7 = __pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(__pyx_v_self); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 449, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_4 = __pyx_v_self->_reason; + __Pyx_INCREF(__pyx_t_4); + + /* "aiohttp/_http_parser.pyx":448 + * should_close, encoding, upgrade, chunked, self._url) + * else: + * msg = _new_response_message( # <<<<<<<<<<<<<< + * self.http_version(), self._cparser.status_code, self._reason, + * headers, raw_headers, should_close, encoding, + */ + __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser__new_response_message(__pyx_t_7, __pyx_v_self->_cparser->status_code, ((PyObject*)__pyx_t_4), __pyx_v_headers, __pyx_v_raw_headers, __pyx_v_should_close, __pyx_v_encoding, __pyx_v_upgrade, __pyx_v_chunked); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 448, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_msg = __pyx_t_3; + __pyx_t_3 = 0; + } + __pyx_L12:; + + /* "aiohttp/_http_parser.pyx":453 + * upgrade, chunked) + * + * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or # <<<<<<<<<<<<<< + * self._cparser.method == 5 or # CONNECT: 5 + * (self._cparser.status_code >= 199 and + */ + __pyx_t_5 = (ULLONG_MAX > __pyx_v_self->_cparser->content_length); + if (__pyx_t_5) { + __pyx_t_5 = (__pyx_v_self->_cparser->content_length > 0); + } + __pyx_t_8 = (__pyx_t_5 != 0); + if (!__pyx_t_8) { + } else { + __pyx_t_6 = __pyx_t_8; + goto __pyx_L14_bool_binop_done; + } + __pyx_t_8 = (__pyx_v_chunked != 0); + if (!__pyx_t_8) { + } else { + __pyx_t_6 = __pyx_t_8; + goto __pyx_L14_bool_binop_done; + } + + /* "aiohttp/_http_parser.pyx":454 + * + * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or + * self._cparser.method == 5 or # CONNECT: 5 # <<<<<<<<<<<<<< + * (self._cparser.status_code >= 199 and + * self._cparser.content_length == ULLONG_MAX and + */ + __pyx_t_8 = ((__pyx_v_self->_cparser->method == 5) != 0); + if (!__pyx_t_8) { + } else { + __pyx_t_6 = __pyx_t_8; + goto __pyx_L14_bool_binop_done; + } + + /* "aiohttp/_http_parser.pyx":455 + * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or + * self._cparser.method == 5 or # CONNECT: 5 + * (self._cparser.status_code >= 199 and # <<<<<<<<<<<<<< + * self._cparser.content_length == ULLONG_MAX and + * self._read_until_eof) + */ + __pyx_t_8 = ((__pyx_v_self->_cparser->status_code >= 0xC7) != 0); + if (__pyx_t_8) { + } else { + __pyx_t_6 = __pyx_t_8; + goto __pyx_L14_bool_binop_done; + } + + /* "aiohttp/_http_parser.pyx":456 + * self._cparser.method == 5 or # CONNECT: 5 + * (self._cparser.status_code >= 199 and + * self._cparser.content_length == ULLONG_MAX and # <<<<<<<<<<<<<< + * self._read_until_eof) + * ): + */ + __pyx_t_8 = ((__pyx_v_self->_cparser->content_length == ULLONG_MAX) != 0); + if (__pyx_t_8) { + } else { + __pyx_t_6 = __pyx_t_8; + goto __pyx_L14_bool_binop_done; + } + + /* "aiohttp/_http_parser.pyx":457 + * (self._cparser.status_code >= 199 and + * self._cparser.content_length == ULLONG_MAX and + * self._read_until_eof) # <<<<<<<<<<<<<< + * ): + * payload = StreamReader( + */ + __pyx_t_8 = (__pyx_v_self->_read_until_eof != 0); + __pyx_t_6 = __pyx_t_8; + __pyx_L14_bool_binop_done:; + + /* "aiohttp/_http_parser.pyx":453 + * upgrade, chunked) + * + * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or # <<<<<<<<<<<<<< + * self._cparser.method == 5 or # CONNECT: 5 + * (self._cparser.status_code >= 199 and + */ + if (__pyx_t_6) { + + /* "aiohttp/_http_parser.pyx":459 + * self._read_until_eof) + * ): + * payload = StreamReader( # <<<<<<<<<<<<<< + * self._protocol, timer=self._timer, loop=self._loop, + * limit=self._limit) + */ + __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 459, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(__pyx_v_self->_protocol); + __Pyx_GIVEREF(__pyx_v_self->_protocol); + PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_self->_protocol); + + /* "aiohttp/_http_parser.pyx":460 + * ): + * payload = StreamReader( + * self._protocol, timer=self._timer, loop=self._loop, # <<<<<<<<<<<<<< + * limit=self._limit) + * else: + */ + __pyx_t_4 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 460, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_timer, __pyx_v_self->_timer) < 0) __PYX_ERR(0, 460, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_loop, __pyx_v_self->_loop) < 0) __PYX_ERR(0, 460, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":461 + * payload = StreamReader( + * self._protocol, timer=self._timer, loop=self._loop, + * limit=self._limit) # <<<<<<<<<<<<<< + * else: + * payload = EMPTY_PAYLOAD + */ + __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_self->_limit); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 461, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_limit, __pyx_t_7) < 0) __PYX_ERR(0, 460, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "aiohttp/_http_parser.pyx":459 + * self._read_until_eof) + * ): + * payload = StreamReader( # <<<<<<<<<<<<<< + * self._protocol, timer=self._timer, loop=self._loop, + * limit=self._limit) + */ + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_v_7aiohttp_12_http_parser_StreamReader, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 459, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_v_payload = __pyx_t_7; + __pyx_t_7 = 0; + + /* "aiohttp/_http_parser.pyx":453 + * upgrade, chunked) + * + * if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or # <<<<<<<<<<<<<< + * self._cparser.method == 5 or # CONNECT: 5 + * (self._cparser.status_code >= 199 and + */ + goto __pyx_L13; + } + + /* "aiohttp/_http_parser.pyx":463 + * limit=self._limit) + * else: + * payload = EMPTY_PAYLOAD # <<<<<<<<<<<<<< + * + * self._payload = payload + */ + /*else*/ { + __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD); + __pyx_v_payload = __pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD; + } + __pyx_L13:; + + /* "aiohttp/_http_parser.pyx":465 + * payload = EMPTY_PAYLOAD + * + * self._payload = payload # <<<<<<<<<<<<<< + * if encoding is not None and self._auto_decompress: + * self._payload = DeflateBuffer(payload, encoding) + */ + __Pyx_INCREF(__pyx_v_payload); + __Pyx_GIVEREF(__pyx_v_payload); + __Pyx_GOTREF(__pyx_v_self->_payload); + __Pyx_DECREF(__pyx_v_self->_payload); + __pyx_v_self->_payload = __pyx_v_payload; + + /* "aiohttp/_http_parser.pyx":466 + * + * self._payload = payload + * if encoding is not None and self._auto_decompress: # <<<<<<<<<<<<<< + * self._payload = DeflateBuffer(payload, encoding) + * + */ + __pyx_t_8 = (__pyx_v_encoding != Py_None); + __pyx_t_5 = (__pyx_t_8 != 0); + if (__pyx_t_5) { + } else { + __pyx_t_6 = __pyx_t_5; + goto __pyx_L21_bool_binop_done; + } + __pyx_t_5 = (__pyx_v_self->_auto_decompress != 0); + __pyx_t_6 = __pyx_t_5; + __pyx_L21_bool_binop_done:; + if (__pyx_t_6) { + + /* "aiohttp/_http_parser.pyx":467 + * self._payload = payload + * if encoding is not None and self._auto_decompress: + * self._payload = DeflateBuffer(payload, encoding) # <<<<<<<<<<<<<< + * + * if not self._response_with_body: + */ + __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_DeflateBuffer); + __pyx_t_4 = __pyx_v_7aiohttp_12_http_parser_DeflateBuffer; __pyx_t_3 = NULL; + __pyx_t_9 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + __pyx_t_9 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_4)) { + PyObject *__pyx_temp[3] = {__pyx_t_3, __pyx_v_payload, __pyx_v_encoding}; + __pyx_t_7 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 467, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GOTREF(__pyx_t_7); + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) { + PyObject *__pyx_temp[3] = {__pyx_t_3, __pyx_v_payload, __pyx_v_encoding}; + __pyx_t_7 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 467, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_GOTREF(__pyx_t_7); + } else + #endif + { + __pyx_t_1 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 467, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (__pyx_t_3) { + __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3); __pyx_t_3 = NULL; + } + __Pyx_INCREF(__pyx_v_payload); + __Pyx_GIVEREF(__pyx_v_payload); + PyTuple_SET_ITEM(__pyx_t_1, 0+__pyx_t_9, __pyx_v_payload); + __Pyx_INCREF(__pyx_v_encoding); + __Pyx_GIVEREF(__pyx_v_encoding); + PyTuple_SET_ITEM(__pyx_t_1, 1+__pyx_t_9, __pyx_v_encoding); + __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_1, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 467, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GIVEREF(__pyx_t_7); + __Pyx_GOTREF(__pyx_v_self->_payload); + __Pyx_DECREF(__pyx_v_self->_payload); + __pyx_v_self->_payload = __pyx_t_7; + __pyx_t_7 = 0; + + /* "aiohttp/_http_parser.pyx":466 + * + * self._payload = payload + * if encoding is not None and self._auto_decompress: # <<<<<<<<<<<<<< + * self._payload = DeflateBuffer(payload, encoding) + * + */ + } + + /* "aiohttp/_http_parser.pyx":469 + * self._payload = DeflateBuffer(payload, encoding) + * + * if not self._response_with_body: # <<<<<<<<<<<<<< + * payload = EMPTY_PAYLOAD + * + */ + __pyx_t_6 = ((!(__pyx_v_self->_response_with_body != 0)) != 0); + if (__pyx_t_6) { + + /* "aiohttp/_http_parser.pyx":470 + * + * if not self._response_with_body: + * payload = EMPTY_PAYLOAD # <<<<<<<<<<<<<< + * + * self._messages.append((msg, payload)) + */ + __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD); + __Pyx_DECREF_SET(__pyx_v_payload, __pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD); + + /* "aiohttp/_http_parser.pyx":469 + * self._payload = DeflateBuffer(payload, encoding) + * + * if not self._response_with_body: # <<<<<<<<<<<<<< + * payload = EMPTY_PAYLOAD + * + */ + } + + /* "aiohttp/_http_parser.pyx":472 + * payload = EMPTY_PAYLOAD + * + * self._messages.append((msg, payload)) # <<<<<<<<<<<<<< + * + * cdef _on_message_complete(self): + */ + if (unlikely(__pyx_v_self->_messages == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); + __PYX_ERR(0, 472, __pyx_L1_error) + } + __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 472, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_v_msg); + __Pyx_GIVEREF(__pyx_v_msg); + PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_msg); + __Pyx_INCREF(__pyx_v_payload); + __Pyx_GIVEREF(__pyx_v_payload); + PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_payload); + __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_self->_messages, __pyx_t_7); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 472, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + + /* "aiohttp/_http_parser.pyx":416 + * self._has_value = True + * + * cdef _on_headers_complete(self): # <<<<<<<<<<<<<< + * self._process_header() + * + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_headers_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_method); + __Pyx_XDECREF(__pyx_v_raw_headers); + __Pyx_XDECREF(__pyx_v_headers); + __Pyx_XDECREF(__pyx_v_encoding); + __Pyx_XDECREF(__pyx_v_enc); + __Pyx_XDECREF(__pyx_v_msg); + __Pyx_XDECREF(__pyx_v_payload); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":474 + * self._messages.append((msg, payload)) + * + * cdef _on_message_complete(self): # <<<<<<<<<<<<<< + * self._payload.feed_eof() + * self._payload = None + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_message_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_on_message_complete", 0); + + /* "aiohttp/_http_parser.pyx":475 + * + * cdef _on_message_complete(self): + * self._payload.feed_eof() # <<<<<<<<<<<<<< + * self._payload = None + * + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_payload, __pyx_n_s_feed_eof); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 475, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 475, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":476 + * cdef _on_message_complete(self): + * self._payload.feed_eof() + * self._payload = None # <<<<<<<<<<<<<< + * + * cdef _on_chunk_header(self): + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_payload); + __Pyx_DECREF(__pyx_v_self->_payload); + __pyx_v_self->_payload = Py_None; + + /* "aiohttp/_http_parser.pyx":474 + * self._messages.append((msg, payload)) + * + * cdef _on_message_complete(self): # <<<<<<<<<<<<<< + * self._payload.feed_eof() + * self._payload = None + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_message_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":478 + * self._payload = None + * + * cdef _on_chunk_header(self): # <<<<<<<<<<<<<< + * self._payload.begin_http_chunk_receiving() + * + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_header(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_on_chunk_header", 0); + + /* "aiohttp/_http_parser.pyx":479 + * + * cdef _on_chunk_header(self): + * self._payload.begin_http_chunk_receiving() # <<<<<<<<<<<<<< + * + * cdef _on_chunk_complete(self): + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_payload, __pyx_n_s_begin_http_chunk_receiving); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 479, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 479, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":478 + * self._payload = None + * + * cdef _on_chunk_header(self): # <<<<<<<<<<<<<< + * self._payload.begin_http_chunk_receiving() + * + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_chunk_header", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":481 + * self._payload.begin_http_chunk_receiving() + * + * cdef _on_chunk_complete(self): # <<<<<<<<<<<<<< + * self._payload.end_http_chunk_receiving() + * + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_on_chunk_complete", 0); + + /* "aiohttp/_http_parser.pyx":482 + * + * cdef _on_chunk_complete(self): + * self._payload.end_http_chunk_receiving() # <<<<<<<<<<<<<< + * + * cdef object _on_status_complete(self): + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_payload, __pyx_n_s_end_http_chunk_receiving); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 482, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 482, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":481 + * self._payload.begin_http_chunk_receiving() + * + * cdef _on_chunk_complete(self): # <<<<<<<<<<<<<< + * self._payload.end_http_chunk_receiving() + * + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser._on_chunk_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":484 + * self._payload.end_http_chunk_receiving() + * + * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< + * pass + * + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_status_complete(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_on_status_complete", 0); + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":487 + * pass + * + * cdef inline http_version(self): # <<<<<<<<<<<<<< + * cdef cparser.http_parser* parser = self._cparser + * + */ + +static CYTHON_INLINE PyObject *__pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + struct http_parser *__pyx_v_parser; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + struct http_parser *__pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("http_version", 0); + + /* "aiohttp/_http_parser.pyx":488 + * + * cdef inline http_version(self): + * cdef cparser.http_parser* parser = self._cparser # <<<<<<<<<<<<<< + * + * if parser.http_major == 1: + */ + __pyx_t_1 = __pyx_v_self->_cparser; + __pyx_v_parser = __pyx_t_1; + + /* "aiohttp/_http_parser.pyx":490 + * cdef cparser.http_parser* parser = self._cparser + * + * if parser.http_major == 1: # <<<<<<<<<<<<<< + * if parser.http_minor == 0: + * return HttpVersion10 + */ + __pyx_t_2 = ((__pyx_v_parser->http_major == 1) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_parser.pyx":491 + * + * if parser.http_major == 1: + * if parser.http_minor == 0: # <<<<<<<<<<<<<< + * return HttpVersion10 + * elif parser.http_minor == 1: + */ + switch (__pyx_v_parser->http_minor) { + case 0: + + /* "aiohttp/_http_parser.pyx":492 + * if parser.http_major == 1: + * if parser.http_minor == 0: + * return HttpVersion10 # <<<<<<<<<<<<<< + * elif parser.http_minor == 1: + * return HttpVersion11 + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion10); + __pyx_r = __pyx_v_7aiohttp_12_http_parser_HttpVersion10; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":491 + * + * if parser.http_major == 1: + * if parser.http_minor == 0: # <<<<<<<<<<<<<< + * return HttpVersion10 + * elif parser.http_minor == 1: + */ + break; + case 1: + + /* "aiohttp/_http_parser.pyx":494 + * return HttpVersion10 + * elif parser.http_minor == 1: + * return HttpVersion11 # <<<<<<<<<<<<<< + * + * return HttpVersion(parser.http_major, parser.http_minor) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion11); + __pyx_r = __pyx_v_7aiohttp_12_http_parser_HttpVersion11; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":493 + * if parser.http_minor == 0: + * return HttpVersion10 + * elif parser.http_minor == 1: # <<<<<<<<<<<<<< + * return HttpVersion11 + * + */ + break; + default: break; + } + + /* "aiohttp/_http_parser.pyx":490 + * cdef cparser.http_parser* parser = self._cparser + * + * if parser.http_major == 1: # <<<<<<<<<<<<<< + * if parser.http_minor == 0: + * return HttpVersion10 + */ + } + + /* "aiohttp/_http_parser.pyx":496 + * return HttpVersion11 + * + * return HttpVersion(parser.http_major, parser.http_minor) # <<<<<<<<<<<<<< + * + * ### Public API ### + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_4 = __Pyx_PyInt_From_unsigned_short(__pyx_v_parser->http_major); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 496, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_PyInt_From_unsigned_short(__pyx_v_parser->http_minor); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 496, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion); + __pyx_t_6 = __pyx_v_7aiohttp_12_http_parser_HttpVersion; __pyx_t_7 = NULL; + __pyx_t_8 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_7)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + __pyx_t_8 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_6)) { + PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_4, __pyx_t_5}; + __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 496, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) { + PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_t_4, __pyx_t_5}; + __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 496, __pyx_L1_error) + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + } else + #endif + { + __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 496, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + if (__pyx_t_7) { + __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL; + } + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_5); + __pyx_t_4 = 0; + __pyx_t_5 = 0; + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 496, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_r = __pyx_t_3; + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":487 + * pass + * + * cdef inline http_version(self): # <<<<<<<<<<<<<< + * cdef cparser.http_parser* parser = self._cparser + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.http_version", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":500 + * ### Public API ### + * + * def feed_eof(self): # <<<<<<<<<<<<<< + * cdef bytes desc + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_5feed_eof(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_5feed_eof(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("feed_eof (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_4feed_eof(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + PyObject *__pyx_v_desc = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("feed_eof", 0); + + /* "aiohttp/_http_parser.pyx":503 + * cdef bytes desc + * + * if self._payload is not None: # <<<<<<<<<<<<<< + * if self._cparser.flags & cparser.F_CHUNKED: + * raise TransferEncodingError( + */ + __pyx_t_1 = (__pyx_v_self->_payload != Py_None); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_parser.pyx":504 + * + * if self._payload is not None: + * if self._cparser.flags & cparser.F_CHUNKED: # <<<<<<<<<<<<<< + * raise TransferEncodingError( + * "Not enough data for satisfy transfer length header.") + */ + __pyx_t_2 = ((__pyx_v_self->_cparser->flags & F_CHUNKED) != 0); + if (unlikely(__pyx_t_2)) { + + /* "aiohttp/_http_parser.pyx":505 + * if self._payload is not None: + * if self._cparser.flags & cparser.F_CHUNKED: + * raise TransferEncodingError( # <<<<<<<<<<<<<< + * "Not enough data for satisfy transfer length header.") + * elif self._cparser.flags & cparser.F_CONTENTLENGTH: + */ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_TransferEncodingError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 505, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Not_enough_data_for_satisfy_tran) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Not_enough_data_for_satisfy_tran); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 505, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 505, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":504 + * + * if self._payload is not None: + * if self._cparser.flags & cparser.F_CHUNKED: # <<<<<<<<<<<<<< + * raise TransferEncodingError( + * "Not enough data for satisfy transfer length header.") + */ + } + + /* "aiohttp/_http_parser.pyx":507 + * raise TransferEncodingError( + * "Not enough data for satisfy transfer length header.") + * elif self._cparser.flags & cparser.F_CONTENTLENGTH: # <<<<<<<<<<<<<< + * raise ContentLengthError( + * "Not enough data for satisfy content length header.") + */ + __pyx_t_2 = ((__pyx_v_self->_cparser->flags & F_CONTENTLENGTH) != 0); + if (unlikely(__pyx_t_2)) { + + /* "aiohttp/_http_parser.pyx":508 + * "Not enough data for satisfy transfer length header.") + * elif self._cparser.flags & cparser.F_CONTENTLENGTH: + * raise ContentLengthError( # <<<<<<<<<<<<<< + * "Not enough data for satisfy content length header.") + * elif self._cparser.http_errno != cparser.HPE_OK: + */ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_ContentLengthError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 508, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_Not_enough_data_for_satisfy_cont) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Not_enough_data_for_satisfy_cont); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 508, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 508, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":507 + * raise TransferEncodingError( + * "Not enough data for satisfy transfer length header.") + * elif self._cparser.flags & cparser.F_CONTENTLENGTH: # <<<<<<<<<<<<<< + * raise ContentLengthError( + * "Not enough data for satisfy content length header.") + */ + } + + /* "aiohttp/_http_parser.pyx":510 + * raise ContentLengthError( + * "Not enough data for satisfy content length header.") + * elif self._cparser.http_errno != cparser.HPE_OK: # <<<<<<<<<<<<<< + * desc = cparser.http_errno_description( + * self._cparser.http_errno) + */ + __pyx_t_2 = ((__pyx_v_self->_cparser->http_errno != HPE_OK) != 0); + if (unlikely(__pyx_t_2)) { + + /* "aiohttp/_http_parser.pyx":511 + * "Not enough data for satisfy content length header.") + * elif self._cparser.http_errno != cparser.HPE_OK: + * desc = cparser.http_errno_description( # <<<<<<<<<<<<<< + * self._cparser.http_errno) + * raise PayloadEncodingError(desc.decode('latin-1')) + */ + __pyx_t_3 = __Pyx_PyBytes_FromString(http_errno_description(((enum http_errno)__pyx_v_self->_cparser->http_errno))); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 511, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_v_desc = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":513 + * desc = cparser.http_errno_description( + * self._cparser.http_errno) + * raise PayloadEncodingError(desc.decode('latin-1')) # <<<<<<<<<<<<<< + * else: + * self._payload.feed_eof() + */ + __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_PayloadEncodingError); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 513, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = __Pyx_decode_bytes(__pyx_v_desc, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeLatin1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 513, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_6)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_6); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_3 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 513, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(0, 513, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":510 + * raise ContentLengthError( + * "Not enough data for satisfy content length header.") + * elif self._cparser.http_errno != cparser.HPE_OK: # <<<<<<<<<<<<<< + * desc = cparser.http_errno_description( + * self._cparser.http_errno) + */ + } + + /* "aiohttp/_http_parser.pyx":515 + * raise PayloadEncodingError(desc.decode('latin-1')) + * else: + * self._payload.feed_eof() # <<<<<<<<<<<<<< + * elif self._started: + * self._on_headers_complete() + */ + /*else*/ { + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_payload, __pyx_n_s_feed_eof); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 515, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 515, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } + + /* "aiohttp/_http_parser.pyx":503 + * cdef bytes desc + * + * if self._payload is not None: # <<<<<<<<<<<<<< + * if self._cparser.flags & cparser.F_CHUNKED: + * raise TransferEncodingError( + */ + goto __pyx_L3; + } + + /* "aiohttp/_http_parser.pyx":516 + * else: + * self._payload.feed_eof() + * elif self._started: # <<<<<<<<<<<<<< + * self._on_headers_complete() + * if self._messages: + */ + __pyx_t_2 = (__pyx_v_self->_started != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_parser.pyx":517 + * self._payload.feed_eof() + * elif self._started: + * self._on_headers_complete() # <<<<<<<<<<<<<< + * if self._messages: + * return self._messages[-1][0] + */ + __pyx_t_3 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self->__pyx_vtab)->_on_headers_complete(__pyx_v_self); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 517, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":518 + * elif self._started: + * self._on_headers_complete() + * if self._messages: # <<<<<<<<<<<<<< + * return self._messages[-1][0] + * + */ + __pyx_t_2 = (__pyx_v_self->_messages != Py_None)&&(PyList_GET_SIZE(__pyx_v_self->_messages) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_parser.pyx":519 + * self._on_headers_complete() + * if self._messages: + * return self._messages[-1][0] # <<<<<<<<<<<<<< + * + * def feed_data(self, data): + */ + __Pyx_XDECREF(__pyx_r); + if (unlikely(__pyx_v_self->_messages == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(0, 519, __pyx_L1_error) + } + __pyx_t_3 = __Pyx_GetItemInt_List(__pyx_v_self->_messages, -1L, long, 1, __Pyx_PyInt_From_long, 1, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 519, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 519, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_4; + __pyx_t_4 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":518 + * elif self._started: + * self._on_headers_complete() + * if self._messages: # <<<<<<<<<<<<<< + * return self._messages[-1][0] + * + */ + } + + /* "aiohttp/_http_parser.pyx":516 + * else: + * self._payload.feed_eof() + * elif self._started: # <<<<<<<<<<<<<< + * self._on_headers_complete() + * if self._messages: + */ + } + __pyx_L3:; + + /* "aiohttp/_http_parser.pyx":500 + * ### Public API ### + * + * def feed_eof(self): # <<<<<<<<<<<<<< + * cdef bytes desc + * + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.feed_eof", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_desc); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":521 + * return self._messages[-1][0] + * + * def feed_data(self, data): # <<<<<<<<<<<<<< + * cdef: + * size_t data_len + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_7feed_data(PyObject *__pyx_v_self, PyObject *__pyx_v_data); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_7feed_data(PyObject *__pyx_v_self, PyObject *__pyx_v_data) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("feed_data (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_6feed_data(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), ((PyObject *)__pyx_v_data)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_6feed_data(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, PyObject *__pyx_v_data) { + size_t __pyx_v_data_len; + size_t __pyx_v_nb; + PyObject *__pyx_v_ex = NULL; + PyObject *__pyx_v_messages = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("feed_data", 0); + + /* "aiohttp/_http_parser.pyx":526 + * size_t nb + * + * PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE) # <<<<<<<<<<<<<< + * data_len = self.py_buf.len + * + */ + __pyx_t_1 = PyObject_GetBuffer(__pyx_v_data, (&__pyx_v_self->py_buf), PyBUF_SIMPLE); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 526, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":527 + * + * PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE) + * data_len = self.py_buf.len # <<<<<<<<<<<<<< + * + * nb = cparser.http_parser_execute( + */ + __pyx_v_data_len = ((size_t)__pyx_v_self->py_buf.len); + + /* "aiohttp/_http_parser.pyx":529 + * data_len = self.py_buf.len + * + * nb = cparser.http_parser_execute( # <<<<<<<<<<<<<< + * self._cparser, + * self._csettings, + */ + __pyx_v_nb = http_parser_execute(__pyx_v_self->_cparser, __pyx_v_self->_csettings, ((char *)__pyx_v_self->py_buf.buf), __pyx_v_data_len); + + /* "aiohttp/_http_parser.pyx":535 + * data_len) + * + * PyBuffer_Release(&self.py_buf) # <<<<<<<<<<<<<< + * + * if (self._cparser.http_errno != cparser.HPE_OK): + */ + PyBuffer_Release((&__pyx_v_self->py_buf)); + + /* "aiohttp/_http_parser.pyx":537 + * PyBuffer_Release(&self.py_buf) + * + * if (self._cparser.http_errno != cparser.HPE_OK): # <<<<<<<<<<<<<< + * if self._payload_error == 0: + * if self._last_error is not None: + */ + __pyx_t_2 = ((__pyx_v_self->_cparser->http_errno != HPE_OK) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_parser.pyx":538 + * + * if (self._cparser.http_errno != cparser.HPE_OK): + * if self._payload_error == 0: # <<<<<<<<<<<<<< + * if self._last_error is not None: + * ex = self._last_error + */ + __pyx_t_2 = ((__pyx_v_self->_payload_error == 0) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_parser.pyx":539 + * if (self._cparser.http_errno != cparser.HPE_OK): + * if self._payload_error == 0: + * if self._last_error is not None: # <<<<<<<<<<<<<< + * ex = self._last_error + * self._last_error = None + */ + __pyx_t_2 = (__pyx_v_self->_last_error != Py_None); + __pyx_t_3 = (__pyx_t_2 != 0); + if (__pyx_t_3) { + + /* "aiohttp/_http_parser.pyx":540 + * if self._payload_error == 0: + * if self._last_error is not None: + * ex = self._last_error # <<<<<<<<<<<<<< + * self._last_error = None + * else: + */ + __pyx_t_4 = __pyx_v_self->_last_error; + __Pyx_INCREF(__pyx_t_4); + __pyx_v_ex = __pyx_t_4; + __pyx_t_4 = 0; + + /* "aiohttp/_http_parser.pyx":541 + * if self._last_error is not None: + * ex = self._last_error + * self._last_error = None # <<<<<<<<<<<<<< + * else: + * ex = parser_error_from_errno( + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_last_error); + __Pyx_DECREF(__pyx_v_self->_last_error); + __pyx_v_self->_last_error = Py_None; + + /* "aiohttp/_http_parser.pyx":539 + * if (self._cparser.http_errno != cparser.HPE_OK): + * if self._payload_error == 0: + * if self._last_error is not None: # <<<<<<<<<<<<<< + * ex = self._last_error + * self._last_error = None + */ + goto __pyx_L5; + } + + /* "aiohttp/_http_parser.pyx":543 + * self._last_error = None + * else: + * ex = parser_error_from_errno( # <<<<<<<<<<<<<< + * self._cparser.http_errno) + * self._payload = None + */ + /*else*/ { + + /* "aiohttp/_http_parser.pyx":544 + * else: + * ex = parser_error_from_errno( + * self._cparser.http_errno) # <<<<<<<<<<<<<< + * self._payload = None + * raise ex + */ + __pyx_t_4 = __pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(((enum http_errno)__pyx_v_self->_cparser->http_errno)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 543, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_v_ex = __pyx_t_4; + __pyx_t_4 = 0; + } + __pyx_L5:; + + /* "aiohttp/_http_parser.pyx":545 + * ex = parser_error_from_errno( + * self._cparser.http_errno) + * self._payload = None # <<<<<<<<<<<<<< + * raise ex + * + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_self->_payload); + __Pyx_DECREF(__pyx_v_self->_payload); + __pyx_v_self->_payload = Py_None; + + /* "aiohttp/_http_parser.pyx":546 + * self._cparser.http_errno) + * self._payload = None + * raise ex # <<<<<<<<<<<<<< + * + * if self._messages: + */ + __Pyx_Raise(__pyx_v_ex, 0, 0, 0); + __PYX_ERR(0, 546, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":538 + * + * if (self._cparser.http_errno != cparser.HPE_OK): + * if self._payload_error == 0: # <<<<<<<<<<<<<< + * if self._last_error is not None: + * ex = self._last_error + */ + } + + /* "aiohttp/_http_parser.pyx":537 + * PyBuffer_Release(&self.py_buf) + * + * if (self._cparser.http_errno != cparser.HPE_OK): # <<<<<<<<<<<<<< + * if self._payload_error == 0: + * if self._last_error is not None: + */ + } + + /* "aiohttp/_http_parser.pyx":548 + * raise ex + * + * if self._messages: # <<<<<<<<<<<<<< + * messages = self._messages + * self._messages = [] + */ + __pyx_t_3 = (__pyx_v_self->_messages != Py_None)&&(PyList_GET_SIZE(__pyx_v_self->_messages) != 0); + if (__pyx_t_3) { + + /* "aiohttp/_http_parser.pyx":549 + * + * if self._messages: + * messages = self._messages # <<<<<<<<<<<<<< + * self._messages = [] + * else: + */ + __pyx_t_4 = __pyx_v_self->_messages; + __Pyx_INCREF(__pyx_t_4); + __pyx_v_messages = __pyx_t_4; + __pyx_t_4 = 0; + + /* "aiohttp/_http_parser.pyx":550 + * if self._messages: + * messages = self._messages + * self._messages = [] # <<<<<<<<<<<<<< + * else: + * messages = () + */ + __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 550, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GIVEREF(__pyx_t_4); + __Pyx_GOTREF(__pyx_v_self->_messages); + __Pyx_DECREF(__pyx_v_self->_messages); + __pyx_v_self->_messages = ((PyObject*)__pyx_t_4); + __pyx_t_4 = 0; + + /* "aiohttp/_http_parser.pyx":548 + * raise ex + * + * if self._messages: # <<<<<<<<<<<<<< + * messages = self._messages + * self._messages = [] + */ + goto __pyx_L6; + } + + /* "aiohttp/_http_parser.pyx":552 + * self._messages = [] + * else: + * messages = () # <<<<<<<<<<<<<< + * + * if self._upgraded: + */ + /*else*/ { + __Pyx_INCREF(__pyx_empty_tuple); + __pyx_v_messages = __pyx_empty_tuple; + } + __pyx_L6:; + + /* "aiohttp/_http_parser.pyx":554 + * messages = () + * + * if self._upgraded: # <<<<<<<<<<<<<< + * return messages, True, data[nb:] + * else: + */ + __pyx_t_3 = (__pyx_v_self->_upgraded != 0); + if (__pyx_t_3) { + + /* "aiohttp/_http_parser.pyx":555 + * + * if self._upgraded: + * return messages, True, data[nb:] # <<<<<<<<<<<<<< + * else: + * return messages, False, b'' + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_4 = __Pyx_PyObject_GetSlice(__pyx_v_data, __pyx_v_nb, 0, NULL, NULL, NULL, 1, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 555, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 555, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_messages); + __Pyx_GIVEREF(__pyx_v_messages); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_messages); + __Pyx_INCREF(Py_True); + __Pyx_GIVEREF(Py_True); + PyTuple_SET_ITEM(__pyx_t_5, 1, Py_True); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_4); + __pyx_t_4 = 0; + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":554 + * messages = () + * + * if self._upgraded: # <<<<<<<<<<<<<< + * return messages, True, data[nb:] + * else: + */ + } + + /* "aiohttp/_http_parser.pyx":557 + * return messages, True, data[nb:] + * else: + * return messages, False, b'' # <<<<<<<<<<<<<< + * + * def set_upgraded(self, val): + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 557, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_INCREF(__pyx_v_messages); + __Pyx_GIVEREF(__pyx_v_messages); + PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_messages); + __Pyx_INCREF(Py_False); + __Pyx_GIVEREF(Py_False); + PyTuple_SET_ITEM(__pyx_t_5, 1, Py_False); + __Pyx_INCREF(__pyx_kp_b__4); + __Pyx_GIVEREF(__pyx_kp_b__4); + PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_b__4); + __pyx_r = __pyx_t_5; + __pyx_t_5 = 0; + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":521 + * return self._messages[-1][0] + * + * def feed_data(self, data): # <<<<<<<<<<<<<< + * cdef: + * size_t data_len + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.feed_data", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_ex); + __Pyx_XDECREF(__pyx_v_messages); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":559 + * return messages, False, b'' + * + * def set_upgraded(self, val): # <<<<<<<<<<<<<< + * self._upgraded = val + * + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_9set_upgraded(PyObject *__pyx_v_self, PyObject *__pyx_v_val); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_9set_upgraded(PyObject *__pyx_v_self, PyObject *__pyx_v_val) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("set_upgraded (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_8set_upgraded(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), ((PyObject *)__pyx_v_val)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_8set_upgraded(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, PyObject *__pyx_v_val) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("set_upgraded", 0); + + /* "aiohttp/_http_parser.pyx":560 + * + * def set_upgraded(self, val): + * self._upgraded = val # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_val); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 560, __pyx_L1_error) + __pyx_v_self->_upgraded = __pyx_t_1; + + /* "aiohttp/_http_parser.pyx":559 + * return messages, False, b'' + * + * def set_upgraded(self, val): # <<<<<<<<<<<<<< + * self._upgraded = val + * + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.set_upgraded", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_11__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_11__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_10__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_10__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(1, 2, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_13__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_10HttpParser_13__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_10HttpParser_12__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_10HttpParser_12__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(1, 4, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpParser.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":565 + * cdef class HttpRequestParser(HttpParser): + * + * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_protocol = 0; + PyObject *__pyx_v_loop = 0; + int __pyx_v_limit; + PyObject *__pyx_v_timer = 0; + size_t __pyx_v_max_line_size; + size_t __pyx_v_max_headers; + size_t __pyx_v_max_field_size; + PyObject *__pyx_v_payload_exception = 0; + int __pyx_v_response_with_body; + int __pyx_v_read_until_eof; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_protocol,&__pyx_n_s_loop,&__pyx_n_s_limit,&__pyx_n_s_timer,&__pyx_n_s_max_line_size,&__pyx_n_s_max_headers,&__pyx_n_s_max_field_size,&__pyx_n_s_payload_exception,&__pyx_n_s_response_with_body,&__pyx_n_s_read_until_eof,0}; + PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0}; + values[3] = ((PyObject *)Py_None); + + /* "aiohttp/_http_parser.pyx":567 + * def __init__(self, protocol, loop, int limit, timer=None, + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, # <<<<<<<<<<<<<< + * bint response_with_body=True, bint read_until_eof=False, + * ): + */ + values[7] = ((PyObject *)Py_None); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + CYTHON_FALLTHROUGH; + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_protocol)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_loop)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 10, 1); __PYX_ERR(0, 565, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_limit)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 10, 2); __PYX_ERR(0, 565, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_timer); + if (value) { values[3] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 4: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_line_size); + if (value) { values[4] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 5: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_headers); + if (value) { values[5] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 6: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_field_size); + if (value) { values[6] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 7: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_payload_exception); + if (value) { values[7] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 8: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_response_with_body); + if (value) { values[8] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 9: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_read_until_eof); + if (value) { values[9] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 565, __pyx_L3_error) + } + } else { + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + CYTHON_FALLTHROUGH; + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_protocol = values[0]; + __pyx_v_loop = values[1]; + __pyx_v_limit = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_limit == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 565, __pyx_L3_error) + __pyx_v_timer = values[3]; + if (values[4]) { + __pyx_v_max_line_size = __Pyx_PyInt_As_size_t(values[4]); if (unlikely((__pyx_v_max_line_size == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 566, __pyx_L3_error) + } else { + __pyx_v_max_line_size = ((size_t)0x1FFE); + } + if (values[5]) { + __pyx_v_max_headers = __Pyx_PyInt_As_size_t(values[5]); if (unlikely((__pyx_v_max_headers == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 566, __pyx_L3_error) + } else { + __pyx_v_max_headers = ((size_t)0x8000); + } + if (values[6]) { + __pyx_v_max_field_size = __Pyx_PyInt_As_size_t(values[6]); if (unlikely((__pyx_v_max_field_size == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 567, __pyx_L3_error) + } else { + __pyx_v_max_field_size = ((size_t)0x1FFE); + } + __pyx_v_payload_exception = values[7]; + if (values[8]) { + __pyx_v_response_with_body = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_response_with_body == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 568, __pyx_L3_error) + } else { + + /* "aiohttp/_http_parser.pyx":568 + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + * bint response_with_body=True, bint read_until_eof=False, # <<<<<<<<<<<<<< + * ): + * self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer, + */ + __pyx_v_response_with_body = ((int)1); + } + if (values[9]) { + __pyx_v_read_until_eof = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_read_until_eof == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 568, __pyx_L3_error) + } else { + __pyx_v_read_until_eof = ((int)0); + } + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 10, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 565, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser___init__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *)__pyx_v_self), __pyx_v_protocol, __pyx_v_loop, __pyx_v_limit, __pyx_v_timer, __pyx_v_max_line_size, __pyx_v_max_headers, __pyx_v_max_field_size, __pyx_v_payload_exception, __pyx_v_response_with_body, __pyx_v_read_until_eof); + + /* "aiohttp/_http_parser.pyx":565 + * cdef class HttpRequestParser(HttpParser): + * + * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser___init__(struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self, PyObject *__pyx_v_protocol, PyObject *__pyx_v_loop, int __pyx_v_limit, PyObject *__pyx_v_timer, size_t __pyx_v_max_line_size, size_t __pyx_v_max_headers, size_t __pyx_v_max_field_size, PyObject *__pyx_v_payload_exception, int __pyx_v_response_with_body, int __pyx_v_read_until_eof) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + + /* "aiohttp/_http_parser.pyx":570 + * bint response_with_body=True, bint read_until_eof=False, + * ): + * self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer, # <<<<<<<<<<<<<< + * max_line_size, max_headers, max_field_size, + * payload_exception, response_with_body, read_until_eof) + */ + __pyx_t_2.__pyx_n = 7; + __pyx_t_2.timer = __pyx_v_timer; + __pyx_t_2.max_line_size = __pyx_v_max_line_size; + __pyx_t_2.max_headers = __pyx_v_max_headers; + __pyx_t_2.max_field_size = __pyx_v_max_field_size; + __pyx_t_2.payload_exception = __pyx_v_payload_exception; + __pyx_t_2.response_with_body = __pyx_v_response_with_body; + __pyx_t_2.read_until_eof = __pyx_v_read_until_eof; + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpRequestParser *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._init(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), HTTP_REQUEST, __pyx_v_protocol, __pyx_v_loop, __pyx_v_limit, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 570, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":565 + * cdef class HttpRequestParser(HttpParser): + * + * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":574 + * payload_exception, response_with_body, read_until_eof) + * + * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< + * cdef Py_buffer py_buf + * if not self._buf: + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self) { + Py_buffer __pyx_v_py_buf; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + int __pyx_t_7; + char const *__pyx_t_8; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + PyObject *__pyx_t_14 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_on_status_complete", 0); + + /* "aiohttp/_http_parser.pyx":576 + * cdef object _on_status_complete(self): + * cdef Py_buffer py_buf + * if not self._buf: # <<<<<<<<<<<<<< + * return + * self._path = self._buf.decode('utf-8', 'surrogateescape') + */ + __pyx_t_1 = (__pyx_v_self->__pyx_base._buf != Py_None)&&(PyByteArray_GET_SIZE(__pyx_v_self->__pyx_base._buf) != 0); + __pyx_t_2 = ((!__pyx_t_1) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_parser.pyx":577 + * cdef Py_buffer py_buf + * if not self._buf: + * return # <<<<<<<<<<<<<< + * self._path = self._buf.decode('utf-8', 'surrogateescape') + * if self._cparser.method == 5: # CONNECT + */ + __Pyx_XDECREF(__pyx_r); + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":576 + * cdef object _on_status_complete(self): + * cdef Py_buffer py_buf + * if not self._buf: # <<<<<<<<<<<<<< + * return + * self._path = self._buf.decode('utf-8', 'surrogateescape') + */ + } + + /* "aiohttp/_http_parser.pyx":578 + * if not self._buf: + * return + * self._path = self._buf.decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * if self._cparser.method == 5: # CONNECT + * self._url = URL(self._path) + */ + if (unlikely(__pyx_v_self->__pyx_base._buf == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "decode"); + __PYX_ERR(0, 578, __pyx_L1_error) + } + __pyx_t_3 = __Pyx_decode_bytearray(__pyx_v_self->__pyx_base._buf, 0, PY_SSIZE_T_MAX, NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 578, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_3); + __Pyx_GOTREF(__pyx_v_self->__pyx_base._path); + __Pyx_DECREF(__pyx_v_self->__pyx_base._path); + __pyx_v_self->__pyx_base._path = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":579 + * return + * self._path = self._buf.decode('utf-8', 'surrogateescape') + * if self._cparser.method == 5: # CONNECT # <<<<<<<<<<<<<< + * self._url = URL(self._path) + * else: + */ + __pyx_t_2 = ((__pyx_v_self->__pyx_base._cparser->method == 5) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_parser.pyx":580 + * self._path = self._buf.decode('utf-8', 'surrogateescape') + * if self._cparser.method == 5: # CONNECT + * self._url = URL(self._path) # <<<<<<<<<<<<<< + * else: + * PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) + */ + __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_URL); + __pyx_t_4 = __pyx_v_7aiohttp_12_http_parser_URL; __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_v_self->__pyx_base._path) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_self->__pyx_base._path); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 580, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_GIVEREF(__pyx_t_3); + __Pyx_GOTREF(__pyx_v_self->__pyx_base._url); + __Pyx_DECREF(__pyx_v_self->__pyx_base._url); + __pyx_v_self->__pyx_base._url = __pyx_t_3; + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":579 + * return + * self._path = self._buf.decode('utf-8', 'surrogateescape') + * if self._cparser.method == 5: # CONNECT # <<<<<<<<<<<<<< + * self._url = URL(self._path) + * else: + */ + goto __pyx_L4; + } + + /* "aiohttp/_http_parser.pyx":582 + * self._url = URL(self._path) + * else: + * PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) # <<<<<<<<<<<<<< + * try: + * self._url = _parse_url(py_buf.buf, + */ + /*else*/ { + __pyx_t_3 = __pyx_v_self->__pyx_base._buf; + __Pyx_INCREF(__pyx_t_3); + __pyx_t_6 = PyObject_GetBuffer(__pyx_t_3, (&__pyx_v_py_buf), PyBUF_SIMPLE); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(0, 582, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":583 + * else: + * PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) + * try: # <<<<<<<<<<<<<< + * self._url = _parse_url(py_buf.buf, + * py_buf.len) + */ + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":584 + * PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) + * try: + * self._url = _parse_url(py_buf.buf, # <<<<<<<<<<<<<< + * py_buf.len) + * finally: + */ + __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser__parse_url(((char *)__pyx_v_py_buf.buf), __pyx_v_py_buf.len); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 584, __pyx_L6_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GIVEREF(__pyx_t_3); + __Pyx_GOTREF(__pyx_v_self->__pyx_base._url); + __Pyx_DECREF(__pyx_v_self->__pyx_base._url); + __pyx_v_self->__pyx_base._url = __pyx_t_3; + __pyx_t_3 = 0; + } + + /* "aiohttp/_http_parser.pyx":587 + * py_buf.len) + * finally: + * PyBuffer_Release(&py_buf) # <<<<<<<<<<<<<< + * PyByteArray_Resize(self._buf, 0) + * + */ + /*finally:*/ { + /*normal exit:*/{ + PyBuffer_Release((&__pyx_v_py_buf)); + goto __pyx_L7; + } + __pyx_L6_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11) < 0)) __Pyx_ErrFetch(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11); + __Pyx_XGOTREF(__pyx_t_9); + __Pyx_XGOTREF(__pyx_t_10); + __Pyx_XGOTREF(__pyx_t_11); + __Pyx_XGOTREF(__pyx_t_12); + __Pyx_XGOTREF(__pyx_t_13); + __Pyx_XGOTREF(__pyx_t_14); + __pyx_t_6 = __pyx_lineno; __pyx_t_7 = __pyx_clineno; __pyx_t_8 = __pyx_filename; + { + PyBuffer_Release((&__pyx_v_py_buf)); + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_12); + __Pyx_XGIVEREF(__pyx_t_13); + __Pyx_XGIVEREF(__pyx_t_14); + __Pyx_ExceptionReset(__pyx_t_12, __pyx_t_13, __pyx_t_14); + } + __Pyx_XGIVEREF(__pyx_t_9); + __Pyx_XGIVEREF(__pyx_t_10); + __Pyx_XGIVEREF(__pyx_t_11); + __Pyx_ErrRestore(__pyx_t_9, __pyx_t_10, __pyx_t_11); + __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; + __pyx_lineno = __pyx_t_6; __pyx_clineno = __pyx_t_7; __pyx_filename = __pyx_t_8; + goto __pyx_L1_error; + } + __pyx_L7:; + } + } + __pyx_L4:; + + /* "aiohttp/_http_parser.pyx":588 + * finally: + * PyBuffer_Release(&py_buf) + * PyByteArray_Resize(self._buf, 0) # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_3 = __pyx_v_self->__pyx_base._buf; + __Pyx_INCREF(__pyx_t_3); + __pyx_t_7 = PyByteArray_Resize(__pyx_t_3, 0); if (unlikely(__pyx_t_7 == ((int)-1))) __PYX_ERR(0, 588, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":574 + * payload_exception, response_with_body, read_until_eof) + * + * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< + * cdef Py_buffer py_buf + * if not self._buf: + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser._on_status_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_3__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_3__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_2__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_2__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(1, 2, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_5__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_5__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_4__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_17HttpRequestParser_4__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(1, 4, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpRequestParser.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":593 + * cdef class HttpResponseParser(HttpParser): + * + * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + */ + +/* Python wrapper */ +static int __pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static int __pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_protocol = 0; + PyObject *__pyx_v_loop = 0; + int __pyx_v_limit; + PyObject *__pyx_v_timer = 0; + size_t __pyx_v_max_line_size; + size_t __pyx_v_max_headers; + size_t __pyx_v_max_field_size; + PyObject *__pyx_v_payload_exception = 0; + int __pyx_v_response_with_body; + int __pyx_v_read_until_eof; + int __pyx_v_auto_decompress; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__init__ (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_protocol,&__pyx_n_s_loop,&__pyx_n_s_limit,&__pyx_n_s_timer,&__pyx_n_s_max_line_size,&__pyx_n_s_max_headers,&__pyx_n_s_max_field_size,&__pyx_n_s_payload_exception,&__pyx_n_s_response_with_body,&__pyx_n_s_read_until_eof,&__pyx_n_s_auto_decompress,0}; + PyObject* values[11] = {0,0,0,0,0,0,0,0,0,0,0}; + values[3] = ((PyObject *)Py_None); + + /* "aiohttp/_http_parser.pyx":595 + * def __init__(self, protocol, loop, int limit, timer=None, + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, # <<<<<<<<<<<<<< + * bint response_with_body=True, bint read_until_eof=False, + * bint auto_decompress=True + */ + values[7] = ((PyObject *)Py_None); + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10); + CYTHON_FALLTHROUGH; + case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + CYTHON_FALLTHROUGH; + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_protocol)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_loop)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 11, 1); __PYX_ERR(0, 593, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_limit)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 11, 2); __PYX_ERR(0, 593, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 3: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_timer); + if (value) { values[3] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 4: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_line_size); + if (value) { values[4] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 5: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_headers); + if (value) { values[5] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 6: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_field_size); + if (value) { values[6] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 7: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_payload_exception); + if (value) { values[7] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 8: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_response_with_body); + if (value) { values[8] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 9: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_read_until_eof); + if (value) { values[9] = value; kw_args--; } + } + CYTHON_FALLTHROUGH; + case 10: + if (kw_args > 0) { + PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_auto_decompress); + if (value) { values[10] = value; kw_args--; } + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 593, __pyx_L3_error) + } + } else { + switch (PyTuple_GET_SIZE(__pyx_args)) { + case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10); + CYTHON_FALLTHROUGH; + case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9); + CYTHON_FALLTHROUGH; + case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8); + CYTHON_FALLTHROUGH; + case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7); + CYTHON_FALLTHROUGH; + case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6); + CYTHON_FALLTHROUGH; + case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5); + CYTHON_FALLTHROUGH; + case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); + CYTHON_FALLTHROUGH; + case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); + CYTHON_FALLTHROUGH; + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + break; + default: goto __pyx_L5_argtuple_error; + } + } + __pyx_v_protocol = values[0]; + __pyx_v_loop = values[1]; + __pyx_v_limit = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_limit == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 593, __pyx_L3_error) + __pyx_v_timer = values[3]; + if (values[4]) { + __pyx_v_max_line_size = __Pyx_PyInt_As_size_t(values[4]); if (unlikely((__pyx_v_max_line_size == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 594, __pyx_L3_error) + } else { + __pyx_v_max_line_size = ((size_t)0x1FFE); + } + if (values[5]) { + __pyx_v_max_headers = __Pyx_PyInt_As_size_t(values[5]); if (unlikely((__pyx_v_max_headers == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 594, __pyx_L3_error) + } else { + __pyx_v_max_headers = ((size_t)0x8000); + } + if (values[6]) { + __pyx_v_max_field_size = __Pyx_PyInt_As_size_t(values[6]); if (unlikely((__pyx_v_max_field_size == (size_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 595, __pyx_L3_error) + } else { + __pyx_v_max_field_size = ((size_t)0x1FFE); + } + __pyx_v_payload_exception = values[7]; + if (values[8]) { + __pyx_v_response_with_body = __Pyx_PyObject_IsTrue(values[8]); if (unlikely((__pyx_v_response_with_body == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 596, __pyx_L3_error) + } else { + + /* "aiohttp/_http_parser.pyx":596 + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + * bint response_with_body=True, bint read_until_eof=False, # <<<<<<<<<<<<<< + * bint auto_decompress=True + * ): + */ + __pyx_v_response_with_body = ((int)1); + } + if (values[9]) { + __pyx_v_read_until_eof = __Pyx_PyObject_IsTrue(values[9]); if (unlikely((__pyx_v_read_until_eof == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 596, __pyx_L3_error) + } else { + __pyx_v_read_until_eof = ((int)0); + } + if (values[10]) { + __pyx_v_auto_decompress = __Pyx_PyObject_IsTrue(values[10]); if (unlikely((__pyx_v_auto_decompress == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 597, __pyx_L3_error) + } else { + + /* "aiohttp/_http_parser.pyx":597 + * size_t max_field_size=8190, payload_exception=None, + * bint response_with_body=True, bint read_until_eof=False, + * bint auto_decompress=True # <<<<<<<<<<<<<< + * ): + * self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer, + */ + __pyx_v_auto_decompress = ((int)1); + } + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 11, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 593, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return -1; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser___init__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *)__pyx_v_self), __pyx_v_protocol, __pyx_v_loop, __pyx_v_limit, __pyx_v_timer, __pyx_v_max_line_size, __pyx_v_max_headers, __pyx_v_max_field_size, __pyx_v_payload_exception, __pyx_v_response_with_body, __pyx_v_read_until_eof, __pyx_v_auto_decompress); + + /* "aiohttp/_http_parser.pyx":593 + * cdef class HttpResponseParser(HttpParser): + * + * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static int __pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser___init__(struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self, PyObject *__pyx_v_protocol, PyObject *__pyx_v_loop, int __pyx_v_limit, PyObject *__pyx_v_timer, size_t __pyx_v_max_line_size, size_t __pyx_v_max_headers, size_t __pyx_v_max_field_size, PyObject *__pyx_v_payload_exception, int __pyx_v_response_with_body, int __pyx_v_read_until_eof, int __pyx_v_auto_decompress) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init __pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__init__", 0); + + /* "aiohttp/_http_parser.pyx":599 + * bint auto_decompress=True + * ): + * self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer, # <<<<<<<<<<<<<< + * max_line_size, max_headers, max_field_size, + * payload_exception, response_with_body, read_until_eof, + */ + __pyx_t_2.__pyx_n = 8; + __pyx_t_2.timer = __pyx_v_timer; + __pyx_t_2.max_line_size = __pyx_v_max_line_size; + __pyx_t_2.max_headers = __pyx_v_max_headers; + __pyx_t_2.max_field_size = __pyx_v_max_field_size; + __pyx_t_2.payload_exception = __pyx_v_payload_exception; + __pyx_t_2.response_with_body = __pyx_v_response_with_body; + __pyx_t_2.read_until_eof = __pyx_v_read_until_eof; + __pyx_t_2.auto_decompress = __pyx_v_auto_decompress; + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpResponseParser *)__pyx_v_self->__pyx_base.__pyx_vtab)->__pyx_base._init(((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_v_self), HTTP_RESPONSE, __pyx_v_protocol, __pyx_v_loop, __pyx_v_limit, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 599, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":593 + * cdef class HttpResponseParser(HttpParser): + * + * def __init__(self, protocol, loop, int limit, timer=None, # <<<<<<<<<<<<<< + * size_t max_line_size=8190, size_t max_headers=32768, + * size_t max_field_size=8190, payload_exception=None, + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":604 + * auto_decompress) + * + * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< + * if self._buf: + * self._reason = self._buf.decode('utf-8', 'surrogateescape') + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_18HttpResponseParser__on_status_complete(struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_on_status_complete", 0); + + /* "aiohttp/_http_parser.pyx":605 + * + * cdef object _on_status_complete(self): + * if self._buf: # <<<<<<<<<<<<<< + * self._reason = self._buf.decode('utf-8', 'surrogateescape') + * PyByteArray_Resize(self._buf, 0) + */ + __pyx_t_1 = (__pyx_v_self->__pyx_base._buf != Py_None)&&(PyByteArray_GET_SIZE(__pyx_v_self->__pyx_base._buf) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":606 + * cdef object _on_status_complete(self): + * if self._buf: + * self._reason = self._buf.decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * PyByteArray_Resize(self._buf, 0) + * else: + */ + if (unlikely(__pyx_v_self->__pyx_base._buf == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "decode"); + __PYX_ERR(0, 606, __pyx_L1_error) + } + __pyx_t_2 = __Pyx_decode_bytearray(__pyx_v_self->__pyx_base._buf, 0, PY_SSIZE_T_MAX, NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 606, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_v_self->__pyx_base._reason); + __Pyx_DECREF(__pyx_v_self->__pyx_base._reason); + __pyx_v_self->__pyx_base._reason = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":607 + * if self._buf: + * self._reason = self._buf.decode('utf-8', 'surrogateescape') + * PyByteArray_Resize(self._buf, 0) # <<<<<<<<<<<<<< + * else: + * self._reason = self._reason or '' + */ + __pyx_t_2 = __pyx_v_self->__pyx_base._buf; + __Pyx_INCREF(__pyx_t_2); + __pyx_t_3 = PyByteArray_Resize(__pyx_t_2, 0); if (unlikely(__pyx_t_3 == ((int)-1))) __PYX_ERR(0, 607, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":605 + * + * cdef object _on_status_complete(self): + * if self._buf: # <<<<<<<<<<<<<< + * self._reason = self._buf.decode('utf-8', 'surrogateescape') + * PyByteArray_Resize(self._buf, 0) + */ + goto __pyx_L3; + } + + /* "aiohttp/_http_parser.pyx":609 + * PyByteArray_Resize(self._buf, 0) + * else: + * self._reason = self._reason or '' # <<<<<<<<<<<<<< + * + * cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: + */ + /*else*/ { + __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->__pyx_base._reason); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 609, __pyx_L1_error) + if (!__pyx_t_1) { + } else { + __Pyx_INCREF(__pyx_v_self->__pyx_base._reason); + __pyx_t_2 = __pyx_v_self->__pyx_base._reason; + goto __pyx_L4_bool_binop_done; + } + __Pyx_INCREF(__pyx_kp_u__4); + __pyx_t_2 = __pyx_kp_u__4; + __pyx_L4_bool_binop_done:; + __Pyx_GIVEREF(__pyx_t_2); + __Pyx_GOTREF(__pyx_v_self->__pyx_base._reason); + __Pyx_DECREF(__pyx_v_self->__pyx_base._reason); + __pyx_v_self->__pyx_base._reason = ((PyObject*)__pyx_t_2); + __pyx_t_2 = 0; + } + __pyx_L3:; + + /* "aiohttp/_http_parser.pyx":604 + * auto_decompress) + * + * cdef object _on_status_complete(self): # <<<<<<<<<<<<<< + * if self._buf: + * self._reason = self._buf.decode('utf-8', 'surrogateescape') + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser._on_status_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_3__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_3__reduce_cython__(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__reduce_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_2__reduce_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *)__pyx_v_self)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_2__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__reduce_cython__", 0); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(1, 2, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __reduce_cython__(self): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_5__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_5__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_4__setstate_cython__(((struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_18HttpResponseParser_4__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__setstate_cython__", 0); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(1, 4, __pyx_L1_error) + + /* "(tree fragment)":3 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): # <<<<<<<<<<<<<< + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("aiohttp._http_parser.HttpResponseParser.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":611 + * self._reason = self._reason or '' + * + * cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_message_begin(struct http_parser *__pyx_v_parser) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + int __pyx_t_4; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_message_begin", 0); + + /* "aiohttp/_http_parser.pyx":612 + * + * cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * + * pyparser._started = True + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":614 + * cdef HttpParser pyparser = parser.data + * + * pyparser._started = True # <<<<<<<<<<<<<< + * pyparser._headers = CIMultiDict() + * pyparser._raw_headers = [] + */ + __pyx_v_pyparser->_started = 1; + + /* "aiohttp/_http_parser.pyx":615 + * + * pyparser._started = True + * pyparser._headers = CIMultiDict() # <<<<<<<<<<<<<< + * pyparser._raw_headers = [] + * PyByteArray_Resize(pyparser._buf, 0) + */ + __Pyx_INCREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDict); + __pyx_t_2 = __pyx_v_7aiohttp_12_http_parser_CIMultiDict; __pyx_t_3 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_3)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_3); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 615, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_pyparser->_headers); + __Pyx_DECREF(__pyx_v_pyparser->_headers); + __pyx_v_pyparser->_headers = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":616 + * pyparser._started = True + * pyparser._headers = CIMultiDict() + * pyparser._raw_headers = [] # <<<<<<<<<<<<<< + * PyByteArray_Resize(pyparser._buf, 0) + * pyparser._path = None + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 616, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v_pyparser->_raw_headers); + __Pyx_DECREF(__pyx_v_pyparser->_raw_headers); + __pyx_v_pyparser->_raw_headers = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":617 + * pyparser._headers = CIMultiDict() + * pyparser._raw_headers = [] + * PyByteArray_Resize(pyparser._buf, 0) # <<<<<<<<<<<<<< + * pyparser._path = None + * pyparser._reason = None + */ + __pyx_t_1 = __pyx_v_pyparser->_buf; + __Pyx_INCREF(__pyx_t_1); + __pyx_t_4 = PyByteArray_Resize(__pyx_t_1, 0); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(0, 617, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":618 + * pyparser._raw_headers = [] + * PyByteArray_Resize(pyparser._buf, 0) + * pyparser._path = None # <<<<<<<<<<<<<< + * pyparser._reason = None + * return 0 + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_pyparser->_path); + __Pyx_DECREF(__pyx_v_pyparser->_path); + __pyx_v_pyparser->_path = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":619 + * PyByteArray_Resize(pyparser._buf, 0) + * pyparser._path = None + * pyparser._reason = None # <<<<<<<<<<<<<< + * return 0 + * + */ + __Pyx_INCREF(Py_None); + __Pyx_GIVEREF(Py_None); + __Pyx_GOTREF(__pyx_v_pyparser->_reason); + __Pyx_DECREF(__pyx_v_pyparser->_reason); + __pyx_v_pyparser->_reason = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":620 + * pyparser._path = None + * pyparser._reason = None + * return 0 # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":611 + * self._reason = self._reason or '' + * + * cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_message_begin", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":623 + * + * + * cdef int cb_on_url(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_url(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + PyObject *__pyx_v_ex = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_url", 0); + + /* "aiohttp/_http_parser.pyx":625 + * cdef int cb_on_url(cparser.http_parser* parser, + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * try: + * if length > pyparser._max_line_size: + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":626 + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * if length > pyparser._max_line_size: + * raise LineTooLong( + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":627 + * cdef HttpParser pyparser = parser.data + * try: + * if length > pyparser._max_line_size: # <<<<<<<<<<<<<< + * raise LineTooLong( + * 'Status line is too long', pyparser._max_line_size, length) + */ + __pyx_t_5 = ((__pyx_v_length > __pyx_v_pyparser->_max_line_size) != 0); + if (unlikely(__pyx_t_5)) { + + /* "aiohttp/_http_parser.pyx":628 + * try: + * if length > pyparser._max_line_size: + * raise LineTooLong( # <<<<<<<<<<<<<< + * 'Status line is too long', pyparser._max_line_size, length) + * extend(pyparser._buf, at, length) + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 628, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "aiohttp/_http_parser.pyx":629 + * if length > pyparser._max_line_size: + * raise LineTooLong( + * 'Status line is too long', pyparser._max_line_size, length) # <<<<<<<<<<<<<< + * extend(pyparser._buf, at, length) + * except BaseException as ex: + */ + __pyx_t_7 = __Pyx_PyInt_FromSize_t(__pyx_v_pyparser->_max_line_size); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 629, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyInt_FromSize_t(__pyx_v_length); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 629, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = NULL; + __pyx_t_10 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_9)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + __pyx_t_10 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_6)) { + PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u_Status_line_is_too_long, __pyx_t_7, __pyx_t_8}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_10, 3+__pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) { + PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u_Status_line_is_too_long, __pyx_t_7, __pyx_t_8}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_10, 3+__pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else + #endif + { + __pyx_t_11 = PyTuple_New(3+__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 628, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_11); + if (__pyx_t_9) { + __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL; + } + __Pyx_INCREF(__pyx_kp_u_Status_line_is_too_long); + __Pyx_GIVEREF(__pyx_kp_u_Status_line_is_too_long); + PyTuple_SET_ITEM(__pyx_t_11, 0+__pyx_t_10, __pyx_kp_u_Status_line_is_too_long); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_10, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_11, 2+__pyx_t_10, __pyx_t_8); + __pyx_t_7 = 0; + __pyx_t_8 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_11, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 628, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 628, __pyx_L3_error) + + /* "aiohttp/_http_parser.pyx":627 + * cdef HttpParser pyparser = parser.data + * try: + * if length > pyparser._max_line_size: # <<<<<<<<<<<<<< + * raise LineTooLong( + * 'Status line is too long', pyparser._max_line_size, length) + */ + } + + /* "aiohttp/_http_parser.pyx":630 + * raise LineTooLong( + * 'Status line is too long', pyparser._max_line_size, length) + * extend(pyparser._buf, at, length) # <<<<<<<<<<<<<< + * except BaseException as ex: + * pyparser._last_error = ex + */ + __pyx_t_1 = __pyx_v_pyparser->_buf; + __Pyx_INCREF(__pyx_t_1); + __pyx_t_6 = __pyx_f_7aiohttp_12_http_parser_extend(__pyx_t_1, __pyx_v_at, __pyx_v_length); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 630, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "aiohttp/_http_parser.pyx":626 + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * if length > pyparser._max_line_size: + * raise LineTooLong( + */ + } + + /* "aiohttp/_http_parser.pyx":635 + * return -1 + * else: + * return 0 # <<<<<<<<<<<<<< + * + * + */ + /*else:*/ { + __pyx_r = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "aiohttp/_http_parser.pyx":631 + * 'Status line is too long', pyparser._max_line_size, length) + * extend(pyparser._buf, at, length) + * except BaseException as ex: # <<<<<<<<<<<<<< + * pyparser._last_error = ex + * return -1 + */ + __pyx_t_10 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); + if (__pyx_t_10) { + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_url", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_1, &__pyx_t_11) < 0) __PYX_ERR(0, 631, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_11); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_ex = __pyx_t_1; + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":632 + * extend(pyparser._buf, at, length) + * except BaseException as ex: + * pyparser._last_error = ex # <<<<<<<<<<<<<< + * return -1 + * else: + */ + __Pyx_INCREF(__pyx_v_ex); + __Pyx_GIVEREF(__pyx_v_ex); + __Pyx_GOTREF(__pyx_v_pyparser->_last_error); + __Pyx_DECREF(__pyx_v_pyparser->_last_error); + __pyx_v_pyparser->_last_error = __pyx_v_ex; + + /* "aiohttp/_http_parser.pyx":633 + * except BaseException as ex: + * pyparser._last_error = ex + * return -1 # <<<<<<<<<<<<<< + * else: + * return 0 + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + goto __pyx_L14_return; + } + + /* "aiohttp/_http_parser.pyx":631 + * 'Status line is too long', pyparser._max_line_size, length) + * extend(pyparser._buf, at, length) + * except BaseException as ex: # <<<<<<<<<<<<<< + * pyparser._last_error = ex + * return -1 + */ + /*finally:*/ { + __pyx_L14_return: { + __pyx_t_10 = __pyx_r; + __Pyx_DECREF(__pyx_v_ex); + __pyx_v_ex = NULL; + __pyx_r = __pyx_t_10; + goto __pyx_L6_except_return; + } + } + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_http_parser.pyx":626 + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * if length > pyparser._max_line_size: + * raise LineTooLong( + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":623 + * + * + * cdef int cb_on_url(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_url", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_XDECREF(__pyx_v_ex); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":638 + * + * + * cdef int cb_on_status(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_status(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + PyObject *__pyx_v_ex = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_status", 0); + + /* "aiohttp/_http_parser.pyx":640 + * cdef int cb_on_status(cparser.http_parser* parser, + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * cdef str reason + * try: + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":642 + * cdef HttpParser pyparser = parser.data + * cdef str reason + * try: # <<<<<<<<<<<<<< + * if length > pyparser._max_line_size: + * raise LineTooLong( + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":643 + * cdef str reason + * try: + * if length > pyparser._max_line_size: # <<<<<<<<<<<<<< + * raise LineTooLong( + * 'Status line is too long', pyparser._max_line_size, length) + */ + __pyx_t_5 = ((__pyx_v_length > __pyx_v_pyparser->_max_line_size) != 0); + if (unlikely(__pyx_t_5)) { + + /* "aiohttp/_http_parser.pyx":644 + * try: + * if length > pyparser._max_line_size: + * raise LineTooLong( # <<<<<<<<<<<<<< + * 'Status line is too long', pyparser._max_line_size, length) + * extend(pyparser._buf, at, length) + */ + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 644, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_6); + + /* "aiohttp/_http_parser.pyx":645 + * if length > pyparser._max_line_size: + * raise LineTooLong( + * 'Status line is too long', pyparser._max_line_size, length) # <<<<<<<<<<<<<< + * extend(pyparser._buf, at, length) + * except BaseException as ex: + */ + __pyx_t_7 = __Pyx_PyInt_FromSize_t(__pyx_v_pyparser->_max_line_size); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 645, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyInt_FromSize_t(__pyx_v_length); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 645, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = NULL; + __pyx_t_10 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_9)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + __pyx_t_10 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_6)) { + PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u_Status_line_is_too_long, __pyx_t_7, __pyx_t_8}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_10, 3+__pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 644, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) { + PyObject *__pyx_temp[4] = {__pyx_t_9, __pyx_kp_u_Status_line_is_too_long, __pyx_t_7, __pyx_t_8}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_10, 3+__pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 644, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + } else + #endif + { + __pyx_t_11 = PyTuple_New(3+__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 644, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_11); + if (__pyx_t_9) { + __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9); __pyx_t_9 = NULL; + } + __Pyx_INCREF(__pyx_kp_u_Status_line_is_too_long); + __Pyx_GIVEREF(__pyx_kp_u_Status_line_is_too_long); + PyTuple_SET_ITEM(__pyx_t_11, 0+__pyx_t_10, __pyx_kp_u_Status_line_is_too_long); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_10, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_11, 2+__pyx_t_10, __pyx_t_8); + __pyx_t_7 = 0; + __pyx_t_8 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_11, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 644, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + } + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 644, __pyx_L3_error) + + /* "aiohttp/_http_parser.pyx":643 + * cdef str reason + * try: + * if length > pyparser._max_line_size: # <<<<<<<<<<<<<< + * raise LineTooLong( + * 'Status line is too long', pyparser._max_line_size, length) + */ + } + + /* "aiohttp/_http_parser.pyx":646 + * raise LineTooLong( + * 'Status line is too long', pyparser._max_line_size, length) + * extend(pyparser._buf, at, length) # <<<<<<<<<<<<<< + * except BaseException as ex: + * pyparser._last_error = ex + */ + __pyx_t_1 = __pyx_v_pyparser->_buf; + __Pyx_INCREF(__pyx_t_1); + __pyx_t_6 = __pyx_f_7aiohttp_12_http_parser_extend(__pyx_t_1, __pyx_v_at, __pyx_v_length); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 646, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "aiohttp/_http_parser.pyx":642 + * cdef HttpParser pyparser = parser.data + * cdef str reason + * try: # <<<<<<<<<<<<<< + * if length > pyparser._max_line_size: + * raise LineTooLong( + */ + } + + /* "aiohttp/_http_parser.pyx":651 + * return -1 + * else: + * return 0 # <<<<<<<<<<<<<< + * + * + */ + /*else:*/ { + __pyx_r = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "aiohttp/_http_parser.pyx":647 + * 'Status line is too long', pyparser._max_line_size, length) + * extend(pyparser._buf, at, length) + * except BaseException as ex: # <<<<<<<<<<<<<< + * pyparser._last_error = ex + * return -1 + */ + __pyx_t_10 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); + if (__pyx_t_10) { + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_status", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_1, &__pyx_t_11) < 0) __PYX_ERR(0, 647, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_11); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_ex = __pyx_t_1; + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":648 + * extend(pyparser._buf, at, length) + * except BaseException as ex: + * pyparser._last_error = ex # <<<<<<<<<<<<<< + * return -1 + * else: + */ + __Pyx_INCREF(__pyx_v_ex); + __Pyx_GIVEREF(__pyx_v_ex); + __Pyx_GOTREF(__pyx_v_pyparser->_last_error); + __Pyx_DECREF(__pyx_v_pyparser->_last_error); + __pyx_v_pyparser->_last_error = __pyx_v_ex; + + /* "aiohttp/_http_parser.pyx":649 + * except BaseException as ex: + * pyparser._last_error = ex + * return -1 # <<<<<<<<<<<<<< + * else: + * return 0 + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + goto __pyx_L14_return; + } + + /* "aiohttp/_http_parser.pyx":647 + * 'Status line is too long', pyparser._max_line_size, length) + * extend(pyparser._buf, at, length) + * except BaseException as ex: # <<<<<<<<<<<<<< + * pyparser._last_error = ex + * return -1 + */ + /*finally:*/ { + __pyx_L14_return: { + __pyx_t_10 = __pyx_r; + __Pyx_DECREF(__pyx_v_ex); + __pyx_v_ex = NULL; + __pyx_r = __pyx_t_10; + goto __pyx_L6_except_return; + } + } + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_http_parser.pyx":642 + * cdef HttpParser pyparser = parser.data + * cdef str reason + * try: # <<<<<<<<<<<<<< + * if length > pyparser._max_line_size: + * raise LineTooLong( + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":638 + * + * + * cdef int cb_on_status(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_status", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_XDECREF(__pyx_v_ex); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":654 + * + * + * cdef int cb_on_header_field(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_field(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + Py_ssize_t __pyx_v_size; + PyObject *__pyx_v_ex = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + Py_ssize_t __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + int __pyx_t_11; + PyObject *__pyx_t_12 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_header_field", 0); + + /* "aiohttp/_http_parser.pyx":656 + * cdef int cb_on_header_field(cparser.http_parser* parser, + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * cdef Py_ssize_t size + * try: + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":658 + * cdef HttpParser pyparser = parser.data + * cdef Py_ssize_t size + * try: # <<<<<<<<<<<<<< + * pyparser._on_status_complete() + * size = len(pyparser._raw_name) + length + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":659 + * cdef Py_ssize_t size + * try: + * pyparser._on_status_complete() # <<<<<<<<<<<<<< + * size = len(pyparser._raw_name) + length + * if size > pyparser._max_field_size: + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_status_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 659, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":660 + * try: + * pyparser._on_status_complete() + * size = len(pyparser._raw_name) + length # <<<<<<<<<<<<<< + * if size > pyparser._max_field_size: + * raise LineTooLong( + */ + __pyx_t_1 = __pyx_v_pyparser->_raw_name; + __Pyx_INCREF(__pyx_t_1); + if (unlikely(__pyx_t_1 == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(0, 660, __pyx_L3_error) + } + __pyx_t_5 = PyByteArray_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(0, 660, __pyx_L3_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_size = (__pyx_t_5 + __pyx_v_length); + + /* "aiohttp/_http_parser.pyx":661 + * pyparser._on_status_complete() + * size = len(pyparser._raw_name) + length + * if size > pyparser._max_field_size: # <<<<<<<<<<<<<< + * raise LineTooLong( + * 'Header name is too long', pyparser._max_field_size, size) + */ + __pyx_t_6 = ((__pyx_v_size > __pyx_v_pyparser->_max_field_size) != 0); + if (unlikely(__pyx_t_6)) { + + /* "aiohttp/_http_parser.pyx":662 + * size = len(pyparser._raw_name) + length + * if size > pyparser._max_field_size: + * raise LineTooLong( # <<<<<<<<<<<<<< + * 'Header name is too long', pyparser._max_field_size, size) + * pyparser._on_header_field(at, length) + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 662, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_7); + + /* "aiohttp/_http_parser.pyx":663 + * if size > pyparser._max_field_size: + * raise LineTooLong( + * 'Header name is too long', pyparser._max_field_size, size) # <<<<<<<<<<<<<< + * pyparser._on_header_field(at, length) + * except BaseException as ex: + */ + __pyx_t_8 = __Pyx_PyInt_FromSize_t(__pyx_v_pyparser->_max_field_size); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 663, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_size); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 663, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = NULL; + __pyx_t_11 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + __pyx_t_11 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_7)) { + PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u_Header_name_is_too_long, __pyx_t_8, __pyx_t_9}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 662, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) { + PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u_Header_name_is_too_long, __pyx_t_8, __pyx_t_9}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 662, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } else + #endif + { + __pyx_t_12 = PyTuple_New(3+__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 662, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_12); + if (__pyx_t_10) { + __Pyx_GIVEREF(__pyx_t_10); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_10); __pyx_t_10 = NULL; + } + __Pyx_INCREF(__pyx_kp_u_Header_name_is_too_long); + __Pyx_GIVEREF(__pyx_kp_u_Header_name_is_too_long); + PyTuple_SET_ITEM(__pyx_t_12, 0+__pyx_t_11, __pyx_kp_u_Header_name_is_too_long); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_12, 1+__pyx_t_11, __pyx_t_8); + __Pyx_GIVEREF(__pyx_t_9); + PyTuple_SET_ITEM(__pyx_t_12, 2+__pyx_t_11, __pyx_t_9); + __pyx_t_8 = 0; + __pyx_t_9 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_12, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 662, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + } + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 662, __pyx_L3_error) + + /* "aiohttp/_http_parser.pyx":661 + * pyparser._on_status_complete() + * size = len(pyparser._raw_name) + length + * if size > pyparser._max_field_size: # <<<<<<<<<<<<<< + * raise LineTooLong( + * 'Header name is too long', pyparser._max_field_size, size) + */ + } + + /* "aiohttp/_http_parser.pyx":664 + * raise LineTooLong( + * 'Header name is too long', pyparser._max_field_size, size) + * pyparser._on_header_field(at, length) # <<<<<<<<<<<<<< + * except BaseException as ex: + * pyparser._last_error = ex + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_header_field(__pyx_v_pyparser, __pyx_v_at, __pyx_v_length); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 664, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":658 + * cdef HttpParser pyparser = parser.data + * cdef Py_ssize_t size + * try: # <<<<<<<<<<<<<< + * pyparser._on_status_complete() + * size = len(pyparser._raw_name) + length + */ + } + + /* "aiohttp/_http_parser.pyx":669 + * return -1 + * else: + * return 0 # <<<<<<<<<<<<<< + * + * + */ + /*else:*/ { + __pyx_r = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "aiohttp/_http_parser.pyx":665 + * 'Header name is too long', pyparser._max_field_size, size) + * pyparser._on_header_field(at, length) + * except BaseException as ex: # <<<<<<<<<<<<<< + * pyparser._last_error = ex + * return -1 + */ + __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); + if (__pyx_t_11) { + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_header_field", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_7, &__pyx_t_12) < 0) __PYX_ERR(0, 665, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GOTREF(__pyx_t_12); + __Pyx_INCREF(__pyx_t_7); + __pyx_v_ex = __pyx_t_7; + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":666 + * pyparser._on_header_field(at, length) + * except BaseException as ex: + * pyparser._last_error = ex # <<<<<<<<<<<<<< + * return -1 + * else: + */ + __Pyx_INCREF(__pyx_v_ex); + __Pyx_GIVEREF(__pyx_v_ex); + __Pyx_GOTREF(__pyx_v_pyparser->_last_error); + __Pyx_DECREF(__pyx_v_pyparser->_last_error); + __pyx_v_pyparser->_last_error = __pyx_v_ex; + + /* "aiohttp/_http_parser.pyx":667 + * except BaseException as ex: + * pyparser._last_error = ex + * return -1 # <<<<<<<<<<<<<< + * else: + * return 0 + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + goto __pyx_L14_return; + } + + /* "aiohttp/_http_parser.pyx":665 + * 'Header name is too long', pyparser._max_field_size, size) + * pyparser._on_header_field(at, length) + * except BaseException as ex: # <<<<<<<<<<<<<< + * pyparser._last_error = ex + * return -1 + */ + /*finally:*/ { + __pyx_L14_return: { + __pyx_t_11 = __pyx_r; + __Pyx_DECREF(__pyx_v_ex); + __pyx_v_ex = NULL; + __pyx_r = __pyx_t_11; + goto __pyx_L6_except_return; + } + } + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_http_parser.pyx":658 + * cdef HttpParser pyparser = parser.data + * cdef Py_ssize_t size + * try: # <<<<<<<<<<<<<< + * pyparser._on_status_complete() + * size = len(pyparser._raw_name) + length + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":654 + * + * + * cdef int cb_on_header_field(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_header_field", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_XDECREF(__pyx_v_ex); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":672 + * + * + * cdef int cb_on_header_value(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_header_value(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + Py_ssize_t __pyx_v_size; + PyObject *__pyx_v_ex = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + Py_ssize_t __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + int __pyx_t_11; + PyObject *__pyx_t_12 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_header_value", 0); + + /* "aiohttp/_http_parser.pyx":674 + * cdef int cb_on_header_value(cparser.http_parser* parser, + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * cdef Py_ssize_t size + * try: + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":676 + * cdef HttpParser pyparser = parser.data + * cdef Py_ssize_t size + * try: # <<<<<<<<<<<<<< + * size = len(pyparser._raw_value) + length + * if size > pyparser._max_field_size: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":677 + * cdef Py_ssize_t size + * try: + * size = len(pyparser._raw_value) + length # <<<<<<<<<<<<<< + * if size > pyparser._max_field_size: + * raise LineTooLong( + */ + __pyx_t_1 = __pyx_v_pyparser->_raw_value; + __Pyx_INCREF(__pyx_t_1); + if (unlikely(__pyx_t_1 == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(0, 677, __pyx_L3_error) + } + __pyx_t_5 = PyByteArray_GET_SIZE(__pyx_t_1); if (unlikely(__pyx_t_5 == ((Py_ssize_t)-1))) __PYX_ERR(0, 677, __pyx_L3_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v_size = (__pyx_t_5 + __pyx_v_length); + + /* "aiohttp/_http_parser.pyx":678 + * try: + * size = len(pyparser._raw_value) + length + * if size > pyparser._max_field_size: # <<<<<<<<<<<<<< + * raise LineTooLong( + * 'Header value is too long', pyparser._max_field_size, size) + */ + __pyx_t_6 = ((__pyx_v_size > __pyx_v_pyparser->_max_field_size) != 0); + if (unlikely(__pyx_t_6)) { + + /* "aiohttp/_http_parser.pyx":679 + * size = len(pyparser._raw_value) + length + * if size > pyparser._max_field_size: + * raise LineTooLong( # <<<<<<<<<<<<<< + * 'Header value is too long', pyparser._max_field_size, size) + * pyparser._on_header_value(at, length) + */ + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 679, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_7); + + /* "aiohttp/_http_parser.pyx":680 + * if size > pyparser._max_field_size: + * raise LineTooLong( + * 'Header value is too long', pyparser._max_field_size, size) # <<<<<<<<<<<<<< + * pyparser._on_header_value(at, length) + * except BaseException as ex: + */ + __pyx_t_8 = __Pyx_PyInt_FromSize_t(__pyx_v_pyparser->_max_field_size); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 680, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_8); + __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_size); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 680, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = NULL; + __pyx_t_11 = 0; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_10)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_10); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + __pyx_t_11 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_7)) { + PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u_Header_value_is_too_long, __pyx_t_8, __pyx_t_9}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_7)) { + PyObject *__pyx_temp[4] = {__pyx_t_10, __pyx_kp_u_Header_value_is_too_long, __pyx_t_8, __pyx_t_9}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_7, __pyx_temp+1-__pyx_t_11, 3+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } else + #endif + { + __pyx_t_12 = PyTuple_New(3+__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 679, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_12); + if (__pyx_t_10) { + __Pyx_GIVEREF(__pyx_t_10); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_10); __pyx_t_10 = NULL; + } + __Pyx_INCREF(__pyx_kp_u_Header_value_is_too_long); + __Pyx_GIVEREF(__pyx_kp_u_Header_value_is_too_long); + PyTuple_SET_ITEM(__pyx_t_12, 0+__pyx_t_11, __pyx_kp_u_Header_value_is_too_long); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_12, 1+__pyx_t_11, __pyx_t_8); + __Pyx_GIVEREF(__pyx_t_9); + PyTuple_SET_ITEM(__pyx_t_12, 2+__pyx_t_11, __pyx_t_9); + __pyx_t_8 = 0; + __pyx_t_9 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_12, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 679, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + } + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_Raise(__pyx_t_1, 0, 0, 0); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __PYX_ERR(0, 679, __pyx_L3_error) + + /* "aiohttp/_http_parser.pyx":678 + * try: + * size = len(pyparser._raw_value) + length + * if size > pyparser._max_field_size: # <<<<<<<<<<<<<< + * raise LineTooLong( + * 'Header value is too long', pyparser._max_field_size, size) + */ + } + + /* "aiohttp/_http_parser.pyx":681 + * raise LineTooLong( + * 'Header value is too long', pyparser._max_field_size, size) + * pyparser._on_header_value(at, length) # <<<<<<<<<<<<<< + * except BaseException as ex: + * pyparser._last_error = ex + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_header_value(__pyx_v_pyparser, __pyx_v_at, __pyx_v_length); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 681, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":676 + * cdef HttpParser pyparser = parser.data + * cdef Py_ssize_t size + * try: # <<<<<<<<<<<<<< + * size = len(pyparser._raw_value) + length + * if size > pyparser._max_field_size: + */ + } + + /* "aiohttp/_http_parser.pyx":686 + * return -1 + * else: + * return 0 # <<<<<<<<<<<<<< + * + * + */ + /*else:*/ { + __pyx_r = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "aiohttp/_http_parser.pyx":682 + * 'Header value is too long', pyparser._max_field_size, size) + * pyparser._on_header_value(at, length) + * except BaseException as ex: # <<<<<<<<<<<<<< + * pyparser._last_error = ex + * return -1 + */ + __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); + if (__pyx_t_11) { + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_header_value", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_7, &__pyx_t_12) < 0) __PYX_ERR(0, 682, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GOTREF(__pyx_t_12); + __Pyx_INCREF(__pyx_t_7); + __pyx_v_ex = __pyx_t_7; + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":683 + * pyparser._on_header_value(at, length) + * except BaseException as ex: + * pyparser._last_error = ex # <<<<<<<<<<<<<< + * return -1 + * else: + */ + __Pyx_INCREF(__pyx_v_ex); + __Pyx_GIVEREF(__pyx_v_ex); + __Pyx_GOTREF(__pyx_v_pyparser->_last_error); + __Pyx_DECREF(__pyx_v_pyparser->_last_error); + __pyx_v_pyparser->_last_error = __pyx_v_ex; + + /* "aiohttp/_http_parser.pyx":684 + * except BaseException as ex: + * pyparser._last_error = ex + * return -1 # <<<<<<<<<<<<<< + * else: + * return 0 + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + goto __pyx_L14_return; + } + + /* "aiohttp/_http_parser.pyx":682 + * 'Header value is too long', pyparser._max_field_size, size) + * pyparser._on_header_value(at, length) + * except BaseException as ex: # <<<<<<<<<<<<<< + * pyparser._last_error = ex + * return -1 + */ + /*finally:*/ { + __pyx_L14_return: { + __pyx_t_11 = __pyx_r; + __Pyx_DECREF(__pyx_v_ex); + __pyx_v_ex = NULL; + __pyx_r = __pyx_t_11; + goto __pyx_L6_except_return; + } + } + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_http_parser.pyx":676 + * cdef HttpParser pyparser = parser.data + * cdef Py_ssize_t size + * try: # <<<<<<<<<<<<<< + * size = len(pyparser._raw_value) + length + * if size > pyparser._max_field_size: + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":672 + * + * + * cdef int cb_on_header_value(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_header_value", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_XDECREF(__pyx_v_ex); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":689 + * + * + * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * try: + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_headers_complete(struct http_parser *__pyx_v_parser) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + PyObject *__pyx_v_exc = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + int __pyx_t_6; + int __pyx_t_7; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_headers_complete", 0); + + /* "aiohttp/_http_parser.pyx":690 + * + * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * try: + * pyparser._on_status_complete() + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":691 + * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._on_status_complete() + * pyparser._on_headers_complete() + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":692 + * cdef HttpParser pyparser = parser.data + * try: + * pyparser._on_status_complete() # <<<<<<<<<<<<<< + * pyparser._on_headers_complete() + * except BaseException as exc: + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_status_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 692, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":693 + * try: + * pyparser._on_status_complete() + * pyparser._on_headers_complete() # <<<<<<<<<<<<<< + * except BaseException as exc: + * pyparser._last_error = exc + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_headers_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 693, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":691 + * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._on_status_complete() + * pyparser._on_headers_complete() + */ + } + + /* "aiohttp/_http_parser.pyx":698 + * return -1 + * else: + * if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT # <<<<<<<<<<<<<< + * return 2 + * else: + */ + /*else:*/ { + __pyx_t_6 = (__pyx_v_pyparser->_cparser->upgrade != 0); + if (!__pyx_t_6) { + } else { + __pyx_t_5 = __pyx_t_6; + goto __pyx_L10_bool_binop_done; + } + __pyx_t_6 = ((__pyx_v_pyparser->_cparser->method == 5) != 0); + __pyx_t_5 = __pyx_t_6; + __pyx_L10_bool_binop_done:; + if (__pyx_t_5) { + + /* "aiohttp/_http_parser.pyx":699 + * else: + * if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT + * return 2 # <<<<<<<<<<<<<< + * else: + * return 0 + */ + __pyx_r = 2; + goto __pyx_L6_except_return; + + /* "aiohttp/_http_parser.pyx":698 + * return -1 + * else: + * if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT # <<<<<<<<<<<<<< + * return 2 + * else: + */ + } + + /* "aiohttp/_http_parser.pyx":701 + * return 2 + * else: + * return 0 # <<<<<<<<<<<<<< + * + * + */ + /*else*/ { + __pyx_r = 0; + goto __pyx_L6_except_return; + } + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":694 + * pyparser._on_status_complete() + * pyparser._on_headers_complete() + * except BaseException as exc: # <<<<<<<<<<<<<< + * pyparser._last_error = exc + * return -1 + */ + __pyx_t_7 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); + if (__pyx_t_7) { + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_headers_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 694, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_8); + __Pyx_GOTREF(__pyx_t_9); + __Pyx_INCREF(__pyx_t_8); + __pyx_v_exc = __pyx_t_8; + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":695 + * pyparser._on_headers_complete() + * except BaseException as exc: + * pyparser._last_error = exc # <<<<<<<<<<<<<< + * return -1 + * else: + */ + __Pyx_INCREF(__pyx_v_exc); + __Pyx_GIVEREF(__pyx_v_exc); + __Pyx_GOTREF(__pyx_v_pyparser->_last_error); + __Pyx_DECREF(__pyx_v_pyparser->_last_error); + __pyx_v_pyparser->_last_error = __pyx_v_exc; + + /* "aiohttp/_http_parser.pyx":696 + * except BaseException as exc: + * pyparser._last_error = exc + * return -1 # <<<<<<<<<<<<<< + * else: + * if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L16_return; + } + + /* "aiohttp/_http_parser.pyx":694 + * pyparser._on_status_complete() + * pyparser._on_headers_complete() + * except BaseException as exc: # <<<<<<<<<<<<<< + * pyparser._last_error = exc + * return -1 + */ + /*finally:*/ { + __pyx_L16_return: { + __pyx_t_7 = __pyx_r; + __Pyx_DECREF(__pyx_v_exc); + __pyx_v_exc = NULL; + __pyx_r = __pyx_t_7; + goto __pyx_L6_except_return; + } + } + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_http_parser.pyx":691 + * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._on_status_complete() + * pyparser._on_headers_complete() + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":689 + * + * + * cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * try: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_headers_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_XDECREF(__pyx_v_exc); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":704 + * + * + * cdef int cb_on_body(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_body(struct http_parser *__pyx_v_parser, char const *__pyx_v_at, size_t __pyx_v_length) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + PyObject *__pyx_v_body = 0; + PyObject *__pyx_v_exc = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_t_11; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + PyObject *__pyx_t_14 = NULL; + PyObject *__pyx_t_15 = NULL; + int __pyx_t_16; + char const *__pyx_t_17; + PyObject *__pyx_t_18 = NULL; + PyObject *__pyx_t_19 = NULL; + PyObject *__pyx_t_20 = NULL; + PyObject *__pyx_t_21 = NULL; + PyObject *__pyx_t_22 = NULL; + PyObject *__pyx_t_23 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_body", 0); + + /* "aiohttp/_http_parser.pyx":706 + * cdef int cb_on_body(cparser.http_parser* parser, + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * cdef bytes body = at[:length] + * try: + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":707 + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + * cdef bytes body = at[:length] # <<<<<<<<<<<<<< + * try: + * pyparser._payload.feed_data(body, length) + */ + __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_at + 0, __pyx_v_length - 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 707, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_body = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":708 + * cdef HttpParser pyparser = parser.data + * cdef bytes body = at[:length] + * try: # <<<<<<<<<<<<<< + * pyparser._payload.feed_data(body, length) + * except BaseException as exc: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":709 + * cdef bytes body = at[:length] + * try: + * pyparser._payload.feed_data(body, length) # <<<<<<<<<<<<<< + * except BaseException as exc: + * if pyparser._payload_exception is not None: + */ + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_pyparser->_payload, __pyx_n_s_feed_data); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 709, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyInt_FromSize_t(__pyx_v_length); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 709, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = NULL; + __pyx_t_8 = 0; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5); + if (likely(__pyx_t_7)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_7); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_5, function); + __pyx_t_8 = 1; + } + } + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(__pyx_t_5)) { + PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_v_body, __pyx_t_6}; + __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } else + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) { + PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_v_body, __pyx_t_6}; + __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_8, 2+__pyx_t_8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L3_error) + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } else + #endif + { + __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 709, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_9); + if (__pyx_t_7) { + __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __pyx_t_7 = NULL; + } + __Pyx_INCREF(__pyx_v_body); + __Pyx_GIVEREF(__pyx_v_body); + PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_v_body); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_6); + __pyx_t_6 = 0; + __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 709, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + } + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":708 + * cdef HttpParser pyparser = parser.data + * cdef bytes body = at[:length] + * try: # <<<<<<<<<<<<<< + * pyparser._payload.feed_data(body, length) + * except BaseException as exc: + */ + } + + /* "aiohttp/_http_parser.pyx":718 + * return -1 + * else: + * return 0 # <<<<<<<<<<<<<< + * + * + */ + /*else:*/ { + __pyx_r = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + + /* "aiohttp/_http_parser.pyx":710 + * try: + * pyparser._payload.feed_data(body, length) + * except BaseException as exc: # <<<<<<<<<<<<<< + * if pyparser._payload_exception is not None: + * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) + */ + __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); + if (__pyx_t_8) { + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_body", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) __PYX_ERR(0, 710, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_5); + __Pyx_GOTREF(__pyx_t_9); + __Pyx_INCREF(__pyx_t_5); + __pyx_v_exc = __pyx_t_5; + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":711 + * pyparser._payload.feed_data(body, length) + * except BaseException as exc: + * if pyparser._payload_exception is not None: # <<<<<<<<<<<<<< + * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) + * else: + */ + __pyx_t_10 = (__pyx_v_pyparser->_payload_exception != Py_None); + __pyx_t_11 = (__pyx_t_10 != 0); + if (__pyx_t_11) { + + /* "aiohttp/_http_parser.pyx":712 + * except BaseException as exc: + * if pyparser._payload_exception is not None: + * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) # <<<<<<<<<<<<<< + * else: + * pyparser._payload.set_exception(exc) + */ + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_pyparser->_payload, __pyx_n_s_set_exception); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 712, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_13 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_exc); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 712, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_INCREF(__pyx_v_pyparser->_payload_exception); + __pyx_t_14 = __pyx_v_pyparser->_payload_exception; __pyx_t_15 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_14))) { + __pyx_t_15 = PyMethod_GET_SELF(__pyx_t_14); + if (likely(__pyx_t_15)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_14); + __Pyx_INCREF(__pyx_t_15); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_14, function); + } + } + __pyx_t_12 = (__pyx_t_15) ? __Pyx_PyObject_Call2Args(__pyx_t_14, __pyx_t_15, __pyx_t_13) : __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_13); + __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; + __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; + if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 712, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; + __pyx_t_14 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_14 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_14)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_14); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + } + } + __pyx_t_6 = (__pyx_t_14) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_14, __pyx_t_12) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_12); + __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; + __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 712, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "aiohttp/_http_parser.pyx":711 + * pyparser._payload.feed_data(body, length) + * except BaseException as exc: + * if pyparser._payload_exception is not None: # <<<<<<<<<<<<<< + * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) + * else: + */ + goto __pyx_L16; + } + + /* "aiohttp/_http_parser.pyx":714 + * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) + * else: + * pyparser._payload.set_exception(exc) # <<<<<<<<<<<<<< + * pyparser._payload_error = 1 + * return -1 + */ + /*else*/ { + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_pyparser->_payload, __pyx_n_s_set_exception); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 714, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_12 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_12)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_12); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + } + } + __pyx_t_6 = (__pyx_t_12) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_12, __pyx_v_exc) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_exc); + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 714, __pyx_L14_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + } + __pyx_L16:; + + /* "aiohttp/_http_parser.pyx":715 + * else: + * pyparser._payload.set_exception(exc) + * pyparser._payload_error = 1 # <<<<<<<<<<<<<< + * return -1 + * else: + */ + __pyx_v_pyparser->_payload_error = 1; + + /* "aiohttp/_http_parser.pyx":716 + * pyparser._payload.set_exception(exc) + * pyparser._payload_error = 1 + * return -1 # <<<<<<<<<<<<<< + * else: + * return 0 + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + goto __pyx_L13_return; + } + + /* "aiohttp/_http_parser.pyx":710 + * try: + * pyparser._payload.feed_data(body, length) + * except BaseException as exc: # <<<<<<<<<<<<<< + * if pyparser._payload_exception is not None: + * pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) + */ + /*finally:*/ { + __pyx_L14_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; + __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; + __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; + __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; + __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_21, &__pyx_t_22, &__pyx_t_23); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20) < 0)) __Pyx_ErrFetch(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20); + __Pyx_XGOTREF(__pyx_t_18); + __Pyx_XGOTREF(__pyx_t_19); + __Pyx_XGOTREF(__pyx_t_20); + __Pyx_XGOTREF(__pyx_t_21); + __Pyx_XGOTREF(__pyx_t_22); + __Pyx_XGOTREF(__pyx_t_23); + __pyx_t_8 = __pyx_lineno; __pyx_t_16 = __pyx_clineno; __pyx_t_17 = __pyx_filename; + { + __Pyx_DECREF(__pyx_v_exc); + __pyx_v_exc = NULL; + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_21); + __Pyx_XGIVEREF(__pyx_t_22); + __Pyx_XGIVEREF(__pyx_t_23); + __Pyx_ExceptionReset(__pyx_t_21, __pyx_t_22, __pyx_t_23); + } + __Pyx_XGIVEREF(__pyx_t_18); + __Pyx_XGIVEREF(__pyx_t_19); + __Pyx_XGIVEREF(__pyx_t_20); + __Pyx_ErrRestore(__pyx_t_18, __pyx_t_19, __pyx_t_20); + __pyx_t_18 = 0; __pyx_t_19 = 0; __pyx_t_20 = 0; __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; + __pyx_lineno = __pyx_t_8; __pyx_clineno = __pyx_t_16; __pyx_filename = __pyx_t_17; + goto __pyx_L5_except_error; + } + __pyx_L13_return: { + __pyx_t_16 = __pyx_r; + __Pyx_DECREF(__pyx_v_exc); + __pyx_v_exc = NULL; + __pyx_r = __pyx_t_16; + goto __pyx_L6_except_return; + } + } + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_http_parser.pyx":708 + * cdef HttpParser pyparser = parser.data + * cdef bytes body = at[:length] + * try: # <<<<<<<<<<<<<< + * pyparser._payload.feed_data(body, length) + * except BaseException as exc: + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":704 + * + * + * cdef int cb_on_body(cparser.http_parser* parser, # <<<<<<<<<<<<<< + * const char *at, size_t length) except -1: + * cdef HttpParser pyparser = parser.data + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_XDECREF(__pyx_t_14); + __Pyx_XDECREF(__pyx_t_15); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_body", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_XDECREF(__pyx_v_body); + __Pyx_XDECREF(__pyx_v_exc); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":721 + * + * + * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * try: + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_message_complete(struct http_parser *__pyx_v_parser) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + PyObject *__pyx_v_exc = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_message_complete", 0); + + /* "aiohttp/_http_parser.pyx":722 + * + * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * try: + * pyparser._started = False + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":723 + * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._started = False + * pyparser._on_message_complete() + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":724 + * cdef HttpParser pyparser = parser.data + * try: + * pyparser._started = False # <<<<<<<<<<<<<< + * pyparser._on_message_complete() + * except BaseException as exc: + */ + __pyx_v_pyparser->_started = 0; + + /* "aiohttp/_http_parser.pyx":725 + * try: + * pyparser._started = False + * pyparser._on_message_complete() # <<<<<<<<<<<<<< + * except BaseException as exc: + * pyparser._last_error = exc + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_message_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 725, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":723 + * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._started = False + * pyparser._on_message_complete() + */ + } + + /* "aiohttp/_http_parser.pyx":730 + * return -1 + * else: + * return 0 # <<<<<<<<<<<<<< + * + * + */ + /*else:*/ { + __pyx_r = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":726 + * pyparser._started = False + * pyparser._on_message_complete() + * except BaseException as exc: # <<<<<<<<<<<<<< + * pyparser._last_error = exc + * return -1 + */ + __pyx_t_5 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); + if (__pyx_t_5) { + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_message_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 726, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_t_6); + __pyx_v_exc = __pyx_t_6; + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":727 + * pyparser._on_message_complete() + * except BaseException as exc: + * pyparser._last_error = exc # <<<<<<<<<<<<<< + * return -1 + * else: + */ + __Pyx_INCREF(__pyx_v_exc); + __Pyx_GIVEREF(__pyx_v_exc); + __Pyx_GOTREF(__pyx_v_pyparser->_last_error); + __Pyx_DECREF(__pyx_v_pyparser->_last_error); + __pyx_v_pyparser->_last_error = __pyx_v_exc; + + /* "aiohttp/_http_parser.pyx":728 + * except BaseException as exc: + * pyparser._last_error = exc + * return -1 # <<<<<<<<<<<<<< + * else: + * return 0 + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L13_return; + } + + /* "aiohttp/_http_parser.pyx":726 + * pyparser._started = False + * pyparser._on_message_complete() + * except BaseException as exc: # <<<<<<<<<<<<<< + * pyparser._last_error = exc + * return -1 + */ + /*finally:*/ { + __pyx_L13_return: { + __pyx_t_5 = __pyx_r; + __Pyx_DECREF(__pyx_v_exc); + __pyx_v_exc = NULL; + __pyx_r = __pyx_t_5; + goto __pyx_L6_except_return; + } + } + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_http_parser.pyx":723 + * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._started = False + * pyparser._on_message_complete() + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":721 + * + * + * cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * try: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_message_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_XDECREF(__pyx_v_exc); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":733 + * + * + * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * try: + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_header(struct http_parser *__pyx_v_parser) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + PyObject *__pyx_v_exc = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_chunk_header", 0); + + /* "aiohttp/_http_parser.pyx":734 + * + * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * try: + * pyparser._on_chunk_header() + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":735 + * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._on_chunk_header() + * except BaseException as exc: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":736 + * cdef HttpParser pyparser = parser.data + * try: + * pyparser._on_chunk_header() # <<<<<<<<<<<<<< + * except BaseException as exc: + * pyparser._last_error = exc + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_chunk_header(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 736, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":735 + * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._on_chunk_header() + * except BaseException as exc: + */ + } + + /* "aiohttp/_http_parser.pyx":741 + * return -1 + * else: + * return 0 # <<<<<<<<<<<<<< + * + * + */ + /*else:*/ { + __pyx_r = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":737 + * try: + * pyparser._on_chunk_header() + * except BaseException as exc: # <<<<<<<<<<<<<< + * pyparser._last_error = exc + * return -1 + */ + __pyx_t_5 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); + if (__pyx_t_5) { + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_chunk_header", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 737, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_t_6); + __pyx_v_exc = __pyx_t_6; + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":738 + * pyparser._on_chunk_header() + * except BaseException as exc: + * pyparser._last_error = exc # <<<<<<<<<<<<<< + * return -1 + * else: + */ + __Pyx_INCREF(__pyx_v_exc); + __Pyx_GIVEREF(__pyx_v_exc); + __Pyx_GOTREF(__pyx_v_pyparser->_last_error); + __Pyx_DECREF(__pyx_v_pyparser->_last_error); + __pyx_v_pyparser->_last_error = __pyx_v_exc; + + /* "aiohttp/_http_parser.pyx":739 + * except BaseException as exc: + * pyparser._last_error = exc + * return -1 # <<<<<<<<<<<<<< + * else: + * return 0 + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L13_return; + } + + /* "aiohttp/_http_parser.pyx":737 + * try: + * pyparser._on_chunk_header() + * except BaseException as exc: # <<<<<<<<<<<<<< + * pyparser._last_error = exc + * return -1 + */ + /*finally:*/ { + __pyx_L13_return: { + __pyx_t_5 = __pyx_r; + __Pyx_DECREF(__pyx_v_exc); + __pyx_v_exc = NULL; + __pyx_r = __pyx_t_5; + goto __pyx_L6_except_return; + } + } + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_http_parser.pyx":735 + * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._on_chunk_header() + * except BaseException as exc: + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":733 + * + * + * cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * try: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_chunk_header", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_XDECREF(__pyx_v_exc); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":744 + * + * + * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * try: + */ + +static int __pyx_f_7aiohttp_12_http_parser_cb_on_chunk_complete(struct http_parser *__pyx_v_parser) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *__pyx_v_pyparser = 0; + PyObject *__pyx_v_exc = NULL; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("cb_on_chunk_complete", 0); + + /* "aiohttp/_http_parser.pyx":745 + * + * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data # <<<<<<<<<<<<<< + * try: + * pyparser._on_chunk_complete() + */ + __pyx_t_1 = ((PyObject *)__pyx_v_parser->data); + __Pyx_INCREF(__pyx_t_1); + __pyx_v_pyparser = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":746 + * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._on_chunk_complete() + * except BaseException as exc: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_4); + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":747 + * cdef HttpParser pyparser = parser.data + * try: + * pyparser._on_chunk_complete() # <<<<<<<<<<<<<< + * except BaseException as exc: + * pyparser._last_error = exc + */ + __pyx_t_1 = ((struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser *)__pyx_v_pyparser->__pyx_vtab)->_on_chunk_complete(__pyx_v_pyparser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 747, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":746 + * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._on_chunk_complete() + * except BaseException as exc: + */ + } + + /* "aiohttp/_http_parser.pyx":752 + * return -1 + * else: + * return 0 # <<<<<<<<<<<<<< + * + * + */ + /*else:*/ { + __pyx_r = 0; + goto __pyx_L6_except_return; + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":748 + * try: + * pyparser._on_chunk_complete() + * except BaseException as exc: # <<<<<<<<<<<<<< + * pyparser._last_error = exc + * return -1 + */ + __pyx_t_5 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_BaseException); + if (__pyx_t_5) { + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_chunk_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(0, 748, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_t_6); + __pyx_v_exc = __pyx_t_6; + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":749 + * pyparser._on_chunk_complete() + * except BaseException as exc: + * pyparser._last_error = exc # <<<<<<<<<<<<<< + * return -1 + * else: + */ + __Pyx_INCREF(__pyx_v_exc); + __Pyx_GIVEREF(__pyx_v_exc); + __Pyx_GOTREF(__pyx_v_pyparser->_last_error); + __Pyx_DECREF(__pyx_v_pyparser->_last_error); + __pyx_v_pyparser->_last_error = __pyx_v_exc; + + /* "aiohttp/_http_parser.pyx":750 + * except BaseException as exc: + * pyparser._last_error = exc + * return -1 # <<<<<<<<<<<<<< + * else: + * return 0 + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L13_return; + } + + /* "aiohttp/_http_parser.pyx":748 + * try: + * pyparser._on_chunk_complete() + * except BaseException as exc: # <<<<<<<<<<<<<< + * pyparser._last_error = exc + * return -1 + */ + /*finally:*/ { + __pyx_L13_return: { + __pyx_t_5 = __pyx_r; + __Pyx_DECREF(__pyx_v_exc); + __pyx_v_exc = NULL; + __pyx_r = __pyx_t_5; + goto __pyx_L6_except_return; + } + } + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "aiohttp/_http_parser.pyx":746 + * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: + * cdef HttpParser pyparser = parser.data + * try: # <<<<<<<<<<<<<< + * pyparser._on_chunk_complete() + * except BaseException as exc: + */ + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L1_error; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_XGIVEREF(__pyx_t_4); + __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4); + goto __pyx_L0; + } + + /* "aiohttp/_http_parser.pyx":744 + * + * + * cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: # <<<<<<<<<<<<<< + * cdef HttpParser pyparser = parser.data + * try: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("aiohttp._http_parser.cb_on_chunk_complete", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = -1; + __pyx_L0:; + __Pyx_XDECREF((PyObject *)__pyx_v_pyparser); + __Pyx_XDECREF(__pyx_v_exc); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":755 + * + * + * cdef parser_error_from_errno(cparser.http_errno errno): # <<<<<<<<<<<<<< + * cdef bytes desc = cparser.http_errno_description(errno) + * + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser_parser_error_from_errno(enum http_errno __pyx_v_errno) { + PyObject *__pyx_v_desc = 0; + PyObject *__pyx_v_cls = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("parser_error_from_errno", 0); + + /* "aiohttp/_http_parser.pyx":756 + * + * cdef parser_error_from_errno(cparser.http_errno errno): + * cdef bytes desc = cparser.http_errno_description(errno) # <<<<<<<<<<<<<< + * + * if errno in (cparser.HPE_CB_message_begin, + */ + __pyx_t_1 = __Pyx_PyBytes_FromString(http_errno_description(__pyx_v_errno)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 756, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_desc = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":758 + * cdef bytes desc = cparser.http_errno_description(errno) + * + * if errno in (cparser.HPE_CB_message_begin, # <<<<<<<<<<<<<< + * cparser.HPE_CB_url, + * cparser.HPE_CB_header_field, + */ + switch (__pyx_v_errno) { + case HPE_CB_message_begin: + case HPE_CB_url: + + /* "aiohttp/_http_parser.pyx":759 + * + * if errno in (cparser.HPE_CB_message_begin, + * cparser.HPE_CB_url, # <<<<<<<<<<<<<< + * cparser.HPE_CB_header_field, + * cparser.HPE_CB_header_value, + */ + case HPE_CB_header_field: + + /* "aiohttp/_http_parser.pyx":760 + * if errno in (cparser.HPE_CB_message_begin, + * cparser.HPE_CB_url, + * cparser.HPE_CB_header_field, # <<<<<<<<<<<<<< + * cparser.HPE_CB_header_value, + * cparser.HPE_CB_headers_complete, + */ + case HPE_CB_header_value: + + /* "aiohttp/_http_parser.pyx":761 + * cparser.HPE_CB_url, + * cparser.HPE_CB_header_field, + * cparser.HPE_CB_header_value, # <<<<<<<<<<<<<< + * cparser.HPE_CB_headers_complete, + * cparser.HPE_CB_body, + */ + case HPE_CB_headers_complete: + + /* "aiohttp/_http_parser.pyx":762 + * cparser.HPE_CB_header_field, + * cparser.HPE_CB_header_value, + * cparser.HPE_CB_headers_complete, # <<<<<<<<<<<<<< + * cparser.HPE_CB_body, + * cparser.HPE_CB_message_complete, + */ + case HPE_CB_body: + + /* "aiohttp/_http_parser.pyx":763 + * cparser.HPE_CB_header_value, + * cparser.HPE_CB_headers_complete, + * cparser.HPE_CB_body, # <<<<<<<<<<<<<< + * cparser.HPE_CB_message_complete, + * cparser.HPE_CB_status, + */ + case HPE_CB_message_complete: + + /* "aiohttp/_http_parser.pyx":764 + * cparser.HPE_CB_headers_complete, + * cparser.HPE_CB_body, + * cparser.HPE_CB_message_complete, # <<<<<<<<<<<<<< + * cparser.HPE_CB_status, + * cparser.HPE_CB_chunk_header, + */ + case HPE_CB_status: + + /* "aiohttp/_http_parser.pyx":765 + * cparser.HPE_CB_body, + * cparser.HPE_CB_message_complete, + * cparser.HPE_CB_status, # <<<<<<<<<<<<<< + * cparser.HPE_CB_chunk_header, + * cparser.HPE_CB_chunk_complete): + */ + case HPE_CB_chunk_header: + + /* "aiohttp/_http_parser.pyx":766 + * cparser.HPE_CB_message_complete, + * cparser.HPE_CB_status, + * cparser.HPE_CB_chunk_header, # <<<<<<<<<<<<<< + * cparser.HPE_CB_chunk_complete): + * cls = BadHttpMessage + */ + case HPE_CB_chunk_complete: + + /* "aiohttp/_http_parser.pyx":768 + * cparser.HPE_CB_chunk_header, + * cparser.HPE_CB_chunk_complete): + * cls = BadHttpMessage # <<<<<<<<<<<<<< + * + * elif errno == cparser.HPE_INVALID_STATUS: + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 768, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_cls = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":758 + * cdef bytes desc = cparser.http_errno_description(errno) + * + * if errno in (cparser.HPE_CB_message_begin, # <<<<<<<<<<<<<< + * cparser.HPE_CB_url, + * cparser.HPE_CB_header_field, + */ + break; + case HPE_INVALID_STATUS: + + /* "aiohttp/_http_parser.pyx":771 + * + * elif errno == cparser.HPE_INVALID_STATUS: + * cls = BadStatusLine # <<<<<<<<<<<<<< + * + * elif errno == cparser.HPE_INVALID_METHOD: + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 771, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_cls = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":770 + * cls = BadHttpMessage + * + * elif errno == cparser.HPE_INVALID_STATUS: # <<<<<<<<<<<<<< + * cls = BadStatusLine + * + */ + break; + case HPE_INVALID_METHOD: + + /* "aiohttp/_http_parser.pyx":774 + * + * elif errno == cparser.HPE_INVALID_METHOD: + * cls = BadStatusLine # <<<<<<<<<<<<<< + * + * elif errno == cparser.HPE_INVALID_URL: + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 774, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_cls = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":773 + * cls = BadStatusLine + * + * elif errno == cparser.HPE_INVALID_METHOD: # <<<<<<<<<<<<<< + * cls = BadStatusLine + * + */ + break; + case HPE_INVALID_URL: + + /* "aiohttp/_http_parser.pyx":777 + * + * elif errno == cparser.HPE_INVALID_URL: + * cls = InvalidURLError # <<<<<<<<<<<<<< + * + * else: + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 777, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_cls = __pyx_t_1; + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":776 + * cls = BadStatusLine + * + * elif errno == cparser.HPE_INVALID_URL: # <<<<<<<<<<<<<< + * cls = InvalidURLError + * + */ + break; + default: + + /* "aiohttp/_http_parser.pyx":780 + * + * else: + * cls = BadHttpMessage # <<<<<<<<<<<<<< + * + * return cls(desc.decode('latin-1')) + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 780, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_cls = __pyx_t_1; + __pyx_t_1 = 0; + break; + } + + /* "aiohttp/_http_parser.pyx":782 + * cls = BadHttpMessage + * + * return cls(desc.decode('latin-1')) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __Pyx_decode_bytes(__pyx_v_desc, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeLatin1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 782, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_v_cls); + __pyx_t_3 = __pyx_v_cls; __pyx_t_4 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + } + } + __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 782, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_parser.pyx":755 + * + * + * cdef parser_error_from_errno(cparser.http_errno errno): # <<<<<<<<<<<<<< + * cdef bytes desc = cparser.http_errno_description(errno) + * + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("aiohttp._http_parser.parser_error_from_errno", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_desc); + __Pyx_XDECREF(__pyx_v_cls); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":785 + * + * + * def parse_url(url): # <<<<<<<<<<<<<< + * cdef: + * Py_buffer py_buf + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_1parse_url(PyObject *__pyx_self, PyObject *__pyx_v_url); /*proto*/ +static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_1parse_url = {"parse_url", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_1parse_url, METH_O, 0}; +static PyObject *__pyx_pw_7aiohttp_12_http_parser_1parse_url(PyObject *__pyx_self, PyObject *__pyx_v_url) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("parse_url (wrapper)", 0); + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_parse_url(__pyx_self, ((PyObject *)__pyx_v_url)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_parse_url(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_url) { + Py_buffer __pyx_v_py_buf; + char *__pyx_v_buf_data; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + int __pyx_t_3; + char const *__pyx_t_4; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("parse_url", 0); + + /* "aiohttp/_http_parser.pyx":790 + * char* buf_data + * + * PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE) # <<<<<<<<<<<<<< + * try: + * buf_data = py_buf.buf + */ + __pyx_t_1 = PyObject_GetBuffer(__pyx_v_url, (&__pyx_v_py_buf), PyBUF_SIMPLE); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(0, 790, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":791 + * + * PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE) + * try: # <<<<<<<<<<<<<< + * buf_data = py_buf.buf + * return _parse_url(buf_data, py_buf.len) + */ + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":792 + * PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE) + * try: + * buf_data = py_buf.buf # <<<<<<<<<<<<<< + * return _parse_url(buf_data, py_buf.len) + * finally: + */ + __pyx_v_buf_data = ((char *)__pyx_v_py_buf.buf); + + /* "aiohttp/_http_parser.pyx":793 + * try: + * buf_data = py_buf.buf + * return _parse_url(buf_data, py_buf.len) # <<<<<<<<<<<<<< + * finally: + * PyBuffer_Release(&py_buf) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = __pyx_f_7aiohttp_12_http_parser__parse_url(__pyx_v_buf_data, __pyx_v_py_buf.len); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 793, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L3_return; + } + + /* "aiohttp/_http_parser.pyx":795 + * return _parse_url(buf_data, py_buf.len) + * finally: + * PyBuffer_Release(&py_buf) # <<<<<<<<<<<<<< + * + * + */ + /*finally:*/ { + __pyx_L4_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0)) __Pyx_ErrFetch(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_5); + __Pyx_XGOTREF(__pyx_t_6); + __Pyx_XGOTREF(__pyx_t_7); + __Pyx_XGOTREF(__pyx_t_8); + __Pyx_XGOTREF(__pyx_t_9); + __Pyx_XGOTREF(__pyx_t_10); + __pyx_t_1 = __pyx_lineno; __pyx_t_3 = __pyx_clineno; __pyx_t_4 = __pyx_filename; + { + PyBuffer_Release((&__pyx_v_py_buf)); + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_8); + __Pyx_XGIVEREF(__pyx_t_9); + __Pyx_XGIVEREF(__pyx_t_10); + __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10); + } + __Pyx_XGIVEREF(__pyx_t_5); + __Pyx_XGIVEREF(__pyx_t_6); + __Pyx_XGIVEREF(__pyx_t_7); + __Pyx_ErrRestore(__pyx_t_5, __pyx_t_6, __pyx_t_7); + __pyx_t_5 = 0; __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; + __pyx_lineno = __pyx_t_1; __pyx_clineno = __pyx_t_3; __pyx_filename = __pyx_t_4; + goto __pyx_L1_error; + } + __pyx_L3_return: { + __pyx_t_10 = __pyx_r; + __pyx_r = 0; + PyBuffer_Release((&__pyx_v_py_buf)); + __pyx_r = __pyx_t_10; + __pyx_t_10 = 0; + goto __pyx_L0; + } + } + + /* "aiohttp/_http_parser.pyx":785 + * + * + * def parse_url(url): # <<<<<<<<<<<<<< + * cdef: + * Py_buffer py_buf + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_AddTraceback("aiohttp._http_parser.parse_url", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_parser.pyx":798 + * + * + * cdef _parse_url(char* buf_data, size_t length): # <<<<<<<<<<<<<< + * cdef: + * cparser.http_parser_url* parsed + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser__parse_url(char *__pyx_v_buf_data, size_t __pyx_v_length) { + struct http_parser_url *__pyx_v_parsed; + int __pyx_v_res; + PyObject *__pyx_v_schema = 0; + PyObject *__pyx_v_host = 0; + PyObject *__pyx_v_port = 0; + PyObject *__pyx_v_path = 0; + PyObject *__pyx_v_query = 0; + PyObject *__pyx_v_fragment = 0; + PyObject *__pyx_v_user = 0; + PyObject *__pyx_v_password = 0; + PyObject *__pyx_v_userinfo = 0; + CYTHON_UNUSED PyObject *__pyx_v_result = 0; + int __pyx_v_off; + int __pyx_v_ln; + CYTHON_UNUSED PyObject *__pyx_v_sep = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + uint16_t __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *(*__pyx_t_8)(PyObject *); + PyObject *__pyx_t_9 = NULL; + int __pyx_t_10; + int __pyx_t_11; + char const *__pyx_t_12; + PyObject *__pyx_t_13 = NULL; + PyObject *__pyx_t_14 = NULL; + PyObject *__pyx_t_15 = NULL; + PyObject *__pyx_t_16 = NULL; + PyObject *__pyx_t_17 = NULL; + PyObject *__pyx_t_18 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_parse_url", 0); + + /* "aiohttp/_http_parser.pyx":802 + * cparser.http_parser_url* parsed + * int res + * str schema = None # <<<<<<<<<<<<<< + * str host = None + * object port = None + */ + __Pyx_INCREF(Py_None); + __pyx_v_schema = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":803 + * int res + * str schema = None + * str host = None # <<<<<<<<<<<<<< + * object port = None + * str path = None + */ + __Pyx_INCREF(Py_None); + __pyx_v_host = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":804 + * str schema = None + * str host = None + * object port = None # <<<<<<<<<<<<<< + * str path = None + * str query = None + */ + __Pyx_INCREF(Py_None); + __pyx_v_port = Py_None; + + /* "aiohttp/_http_parser.pyx":805 + * str host = None + * object port = None + * str path = None # <<<<<<<<<<<<<< + * str query = None + * str fragment = None + */ + __Pyx_INCREF(Py_None); + __pyx_v_path = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":806 + * object port = None + * str path = None + * str query = None # <<<<<<<<<<<<<< + * str fragment = None + * str user = None + */ + __Pyx_INCREF(Py_None); + __pyx_v_query = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":807 + * str path = None + * str query = None + * str fragment = None # <<<<<<<<<<<<<< + * str user = None + * str password = None + */ + __Pyx_INCREF(Py_None); + __pyx_v_fragment = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":808 + * str query = None + * str fragment = None + * str user = None # <<<<<<<<<<<<<< + * str password = None + * str userinfo = None + */ + __Pyx_INCREF(Py_None); + __pyx_v_user = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":809 + * str fragment = None + * str user = None + * str password = None # <<<<<<<<<<<<<< + * str userinfo = None + * object result = None + */ + __Pyx_INCREF(Py_None); + __pyx_v_password = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":810 + * str user = None + * str password = None + * str userinfo = None # <<<<<<<<<<<<<< + * object result = None + * int off + */ + __Pyx_INCREF(Py_None); + __pyx_v_userinfo = ((PyObject*)Py_None); + + /* "aiohttp/_http_parser.pyx":811 + * str password = None + * str userinfo = None + * object result = None # <<<<<<<<<<<<<< + * int off + * int ln + */ + __Pyx_INCREF(Py_None); + __pyx_v_result = Py_None; + + /* "aiohttp/_http_parser.pyx":815 + * int ln + * + * parsed = \ # <<<<<<<<<<<<<< + * PyMem_Malloc(sizeof(cparser.http_parser_url)) + * if parsed is NULL: + */ + __pyx_v_parsed = ((struct http_parser_url *)PyMem_Malloc((sizeof(struct http_parser_url)))); + + /* "aiohttp/_http_parser.pyx":817 + * parsed = \ + * PyMem_Malloc(sizeof(cparser.http_parser_url)) + * if parsed is NULL: # <<<<<<<<<<<<<< + * raise MemoryError() + * cparser.http_parser_url_init(parsed) + */ + __pyx_t_1 = ((__pyx_v_parsed == NULL) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_parser.pyx":818 + * PyMem_Malloc(sizeof(cparser.http_parser_url)) + * if parsed is NULL: + * raise MemoryError() # <<<<<<<<<<<<<< + * cparser.http_parser_url_init(parsed) + * try: + */ + PyErr_NoMemory(); __PYX_ERR(0, 818, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":817 + * parsed = \ + * PyMem_Malloc(sizeof(cparser.http_parser_url)) + * if parsed is NULL: # <<<<<<<<<<<<<< + * raise MemoryError() + * cparser.http_parser_url_init(parsed) + */ + } + + /* "aiohttp/_http_parser.pyx":819 + * if parsed is NULL: + * raise MemoryError() + * cparser.http_parser_url_init(parsed) # <<<<<<<<<<<<<< + * try: + * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) + */ + http_parser_url_init(__pyx_v_parsed); + + /* "aiohttp/_http_parser.pyx":820 + * raise MemoryError() + * cparser.http_parser_url_init(parsed) + * try: # <<<<<<<<<<<<<< + * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) + * + */ + /*try:*/ { + + /* "aiohttp/_http_parser.pyx":821 + * cparser.http_parser_url_init(parsed) + * try: + * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) # <<<<<<<<<<<<<< + * + * if res == 0: + */ + __pyx_v_res = http_parser_parse_url(__pyx_v_buf_data, __pyx_v_length, 0, __pyx_v_parsed); + + /* "aiohttp/_http_parser.pyx":823 + * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) + * + * if res == 0: # <<<<<<<<<<<<<< + * if parsed.field_set & (1 << cparser.UF_SCHEMA): + * off = parsed.field_data[cparser.UF_SCHEMA].off + */ + __pyx_t_1 = ((__pyx_v_res == 0) != 0); + if (likely(__pyx_t_1)) { + + /* "aiohttp/_http_parser.pyx":824 + * + * if res == 0: + * if parsed.field_set & (1 << cparser.UF_SCHEMA): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_SCHEMA].off + * ln = parsed.field_data[cparser.UF_SCHEMA].len + */ + __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_SCHEMA)) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":825 + * if res == 0: + * if parsed.field_set & (1 << cparser.UF_SCHEMA): + * off = parsed.field_data[cparser.UF_SCHEMA].off # <<<<<<<<<<<<<< + * ln = parsed.field_data[cparser.UF_SCHEMA].len + * schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_SCHEMA)]).off; + __pyx_v_off = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":826 + * if parsed.field_set & (1 << cparser.UF_SCHEMA): + * off = parsed.field_data[cparser.UF_SCHEMA].off + * ln = parsed.field_data[cparser.UF_SCHEMA].len # <<<<<<<<<<<<<< + * schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_SCHEMA)]).len; + __pyx_v_ln = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":827 + * off = parsed.field_data[cparser.UF_SCHEMA].off + * ln = parsed.field_data[cparser.UF_SCHEMA].len + * schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * else: + * schema = '' + */ + __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 827, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_schema, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":824 + * + * if res == 0: + * if parsed.field_set & (1 << cparser.UF_SCHEMA): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_SCHEMA].off + * ln = parsed.field_data[cparser.UF_SCHEMA].len + */ + goto __pyx_L8; + } + + /* "aiohttp/_http_parser.pyx":829 + * schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + * schema = '' # <<<<<<<<<<<<<< + * + * if parsed.field_set & (1 << cparser.UF_HOST): + */ + /*else*/ { + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_schema, __pyx_kp_u__4); + } + __pyx_L8:; + + /* "aiohttp/_http_parser.pyx":831 + * schema = '' + * + * if parsed.field_set & (1 << cparser.UF_HOST): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_HOST].off + * ln = parsed.field_data[cparser.UF_HOST].len + */ + __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_HOST)) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":832 + * + * if parsed.field_set & (1 << cparser.UF_HOST): + * off = parsed.field_data[cparser.UF_HOST].off # <<<<<<<<<<<<<< + * ln = parsed.field_data[cparser.UF_HOST].len + * host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_HOST)]).off; + __pyx_v_off = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":833 + * if parsed.field_set & (1 << cparser.UF_HOST): + * off = parsed.field_data[cparser.UF_HOST].off + * ln = parsed.field_data[cparser.UF_HOST].len # <<<<<<<<<<<<<< + * host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_HOST)]).len; + __pyx_v_ln = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":834 + * off = parsed.field_data[cparser.UF_HOST].off + * ln = parsed.field_data[cparser.UF_HOST].len + * host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * else: + * host = '' + */ + __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 834, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_host, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":831 + * schema = '' + * + * if parsed.field_set & (1 << cparser.UF_HOST): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_HOST].off + * ln = parsed.field_data[cparser.UF_HOST].len + */ + goto __pyx_L9; + } + + /* "aiohttp/_http_parser.pyx":836 + * host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + * host = '' # <<<<<<<<<<<<<< + * + * if parsed.field_set & (1 << cparser.UF_PORT): + */ + /*else*/ { + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_host, __pyx_kp_u__4); + } + __pyx_L9:; + + /* "aiohttp/_http_parser.pyx":838 + * host = '' + * + * if parsed.field_set & (1 << cparser.UF_PORT): # <<<<<<<<<<<<<< + * port = parsed.port + * + */ + __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_PORT)) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":839 + * + * if parsed.field_set & (1 << cparser.UF_PORT): + * port = parsed.port # <<<<<<<<<<<<<< + * + * if parsed.field_set & (1 << cparser.UF_PATH): + */ + __pyx_t_3 = __Pyx_PyInt_From_uint16_t(__pyx_v_parsed->port); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 839, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_port, __pyx_t_3); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":838 + * host = '' + * + * if parsed.field_set & (1 << cparser.UF_PORT): # <<<<<<<<<<<<<< + * port = parsed.port + * + */ + } + + /* "aiohttp/_http_parser.pyx":841 + * port = parsed.port + * + * if parsed.field_set & (1 << cparser.UF_PATH): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_PATH].off + * ln = parsed.field_data[cparser.UF_PATH].len + */ + __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_PATH)) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":842 + * + * if parsed.field_set & (1 << cparser.UF_PATH): + * off = parsed.field_data[cparser.UF_PATH].off # <<<<<<<<<<<<<< + * ln = parsed.field_data[cparser.UF_PATH].len + * path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_PATH)]).off; + __pyx_v_off = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":843 + * if parsed.field_set & (1 << cparser.UF_PATH): + * off = parsed.field_data[cparser.UF_PATH].off + * ln = parsed.field_data[cparser.UF_PATH].len # <<<<<<<<<<<<<< + * path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_PATH)]).len; + __pyx_v_ln = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":844 + * off = parsed.field_data[cparser.UF_PATH].off + * ln = parsed.field_data[cparser.UF_PATH].len + * path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * else: + * path = '' + */ + __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 844, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_path, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":841 + * port = parsed.port + * + * if parsed.field_set & (1 << cparser.UF_PATH): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_PATH].off + * ln = parsed.field_data[cparser.UF_PATH].len + */ + goto __pyx_L11; + } + + /* "aiohttp/_http_parser.pyx":846 + * path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + * path = '' # <<<<<<<<<<<<<< + * + * if parsed.field_set & (1 << cparser.UF_QUERY): + */ + /*else*/ { + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_path, __pyx_kp_u__4); + } + __pyx_L11:; + + /* "aiohttp/_http_parser.pyx":848 + * path = '' + * + * if parsed.field_set & (1 << cparser.UF_QUERY): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_QUERY].off + * ln = parsed.field_data[cparser.UF_QUERY].len + */ + __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_QUERY)) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":849 + * + * if parsed.field_set & (1 << cparser.UF_QUERY): + * off = parsed.field_data[cparser.UF_QUERY].off # <<<<<<<<<<<<<< + * ln = parsed.field_data[cparser.UF_QUERY].len + * query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_QUERY)]).off; + __pyx_v_off = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":850 + * if parsed.field_set & (1 << cparser.UF_QUERY): + * off = parsed.field_data[cparser.UF_QUERY].off + * ln = parsed.field_data[cparser.UF_QUERY].len # <<<<<<<<<<<<<< + * query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_QUERY)]).len; + __pyx_v_ln = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":851 + * off = parsed.field_data[cparser.UF_QUERY].off + * ln = parsed.field_data[cparser.UF_QUERY].len + * query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * else: + * query = '' + */ + __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 851, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_query, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":848 + * path = '' + * + * if parsed.field_set & (1 << cparser.UF_QUERY): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_QUERY].off + * ln = parsed.field_data[cparser.UF_QUERY].len + */ + goto __pyx_L12; + } + + /* "aiohttp/_http_parser.pyx":853 + * query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + * query = '' # <<<<<<<<<<<<<< + * + * if parsed.field_set & (1 << cparser.UF_FRAGMENT): + */ + /*else*/ { + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_query, __pyx_kp_u__4); + } + __pyx_L12:; + + /* "aiohttp/_http_parser.pyx":855 + * query = '' + * + * if parsed.field_set & (1 << cparser.UF_FRAGMENT): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_FRAGMENT].off + * ln = parsed.field_data[cparser.UF_FRAGMENT].len + */ + __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_FRAGMENT)) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":856 + * + * if parsed.field_set & (1 << cparser.UF_FRAGMENT): + * off = parsed.field_data[cparser.UF_FRAGMENT].off # <<<<<<<<<<<<<< + * ln = parsed.field_data[cparser.UF_FRAGMENT].len + * fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_FRAGMENT)]).off; + __pyx_v_off = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":857 + * if parsed.field_set & (1 << cparser.UF_FRAGMENT): + * off = parsed.field_data[cparser.UF_FRAGMENT].off + * ln = parsed.field_data[cparser.UF_FRAGMENT].len # <<<<<<<<<<<<<< + * fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_FRAGMENT)]).len; + __pyx_v_ln = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":858 + * off = parsed.field_data[cparser.UF_FRAGMENT].off + * ln = parsed.field_data[cparser.UF_FRAGMENT].len + * fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * else: + * fragment = '' + */ + __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 858, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_fragment, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":855 + * query = '' + * + * if parsed.field_set & (1 << cparser.UF_FRAGMENT): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_FRAGMENT].off + * ln = parsed.field_data[cparser.UF_FRAGMENT].len + */ + goto __pyx_L13; + } + + /* "aiohttp/_http_parser.pyx":860 + * fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * else: + * fragment = '' # <<<<<<<<<<<<<< + * + * if parsed.field_set & (1 << cparser.UF_USERINFO): + */ + /*else*/ { + __Pyx_INCREF(__pyx_kp_u__4); + __Pyx_DECREF_SET(__pyx_v_fragment, __pyx_kp_u__4); + } + __pyx_L13:; + + /* "aiohttp/_http_parser.pyx":862 + * fragment = '' + * + * if parsed.field_set & (1 << cparser.UF_USERINFO): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_USERINFO].off + * ln = parsed.field_data[cparser.UF_USERINFO].len + */ + __pyx_t_1 = ((__pyx_v_parsed->field_set & (1 << UF_USERINFO)) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_parser.pyx":863 + * + * if parsed.field_set & (1 << cparser.UF_USERINFO): + * off = parsed.field_data[cparser.UF_USERINFO].off # <<<<<<<<<<<<<< + * ln = parsed.field_data[cparser.UF_USERINFO].len + * userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_USERINFO)]).off; + __pyx_v_off = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":864 + * if parsed.field_set & (1 << cparser.UF_USERINFO): + * off = parsed.field_data[cparser.UF_USERINFO].off + * ln = parsed.field_data[cparser.UF_USERINFO].len # <<<<<<<<<<<<<< + * userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * + */ + __pyx_t_2 = (__pyx_v_parsed->field_data[((int)UF_USERINFO)]).len; + __pyx_v_ln = __pyx_t_2; + + /* "aiohttp/_http_parser.pyx":865 + * off = parsed.field_data[cparser.UF_USERINFO].off + * ln = parsed.field_data[cparser.UF_USERINFO].len + * userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') # <<<<<<<<<<<<<< + * + * user, sep, password = userinfo.partition(':') + */ + __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_buf_data, __pyx_v_off, (__pyx_v_off + __pyx_v_ln), NULL, ((char const *)"surrogateescape"), PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 865, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF_SET(__pyx_v_userinfo, ((PyObject*)__pyx_t_3)); + __pyx_t_3 = 0; + + /* "aiohttp/_http_parser.pyx":867 + * userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + * + * user, sep, password = userinfo.partition(':') # <<<<<<<<<<<<<< + * + * return URL_build(scheme=schema, + */ + __pyx_t_3 = __Pyx_CallUnboundCMethod1(&__pyx_umethod_PyUnicode_Type_partition, __pyx_v_userinfo, __pyx_kp_u__11); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 867, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) { + PyObject* sequence = __pyx_t_3; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 3)) { + if (size > 3) __Pyx_RaiseTooManyValuesError(3); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 867, __pyx_L5_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); + __pyx_t_6 = PyTuple_GET_ITEM(sequence, 2); + } else { + __pyx_t_4 = PyList_GET_ITEM(sequence, 0); + __pyx_t_5 = PyList_GET_ITEM(sequence, 1); + __pyx_t_6 = PyList_GET_ITEM(sequence, 2); + } + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(__pyx_t_6); + #else + __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 867, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 867, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 867, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_6); + #endif + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_7 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 867, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_8 = Py_TYPE(__pyx_t_7)->tp_iternext; + index = 0; __pyx_t_4 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_4)) goto __pyx_L15_unpacking_failed; + __Pyx_GOTREF(__pyx_t_4); + index = 1; __pyx_t_5 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_5)) goto __pyx_L15_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + index = 2; __pyx_t_6 = __pyx_t_8(__pyx_t_7); if (unlikely(!__pyx_t_6)) goto __pyx_L15_unpacking_failed; + __Pyx_GOTREF(__pyx_t_6); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_8(__pyx_t_7), 3) < 0) __PYX_ERR(0, 867, __pyx_L5_error) + __pyx_t_8 = NULL; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + goto __pyx_L16_unpacking_done; + __pyx_L15_unpacking_failed:; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_8 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 867, __pyx_L5_error) + __pyx_L16_unpacking_done:; + } + if (!(likely(PyUnicode_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_4)->tp_name), 0))) __PYX_ERR(0, 867, __pyx_L5_error) + if (!(likely(PyUnicode_CheckExact(__pyx_t_6))||((__pyx_t_6) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_6)->tp_name), 0))) __PYX_ERR(0, 867, __pyx_L5_error) + __Pyx_DECREF_SET(__pyx_v_user, ((PyObject*)__pyx_t_4)); + __pyx_t_4 = 0; + __pyx_v_sep = __pyx_t_5; + __pyx_t_5 = 0; + __Pyx_DECREF_SET(__pyx_v_password, ((PyObject*)__pyx_t_6)); + __pyx_t_6 = 0; + + /* "aiohttp/_http_parser.pyx":862 + * fragment = '' + * + * if parsed.field_set & (1 << cparser.UF_USERINFO): # <<<<<<<<<<<<<< + * off = parsed.field_data[cparser.UF_USERINFO].off + * ln = parsed.field_data[cparser.UF_USERINFO].len + */ + } + + /* "aiohttp/_http_parser.pyx":869 + * user, sep, password = userinfo.partition(':') + * + * return URL_build(scheme=schema, # <<<<<<<<<<<<<< + * user=user, password=password, host=host, port=port, + * path=path, query_string=query, fragment=fragment, encoded=True) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __Pyx_PyDict_NewPresized(9); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 869, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_scheme, __pyx_v_schema) < 0) __PYX_ERR(0, 869, __pyx_L5_error) + + /* "aiohttp/_http_parser.pyx":870 + * + * return URL_build(scheme=schema, + * user=user, password=password, host=host, port=port, # <<<<<<<<<<<<<< + * path=path, query_string=query, fragment=fragment, encoded=True) + * else: + */ + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_user, __pyx_v_user) < 0) __PYX_ERR(0, 869, __pyx_L5_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_password, __pyx_v_password) < 0) __PYX_ERR(0, 869, __pyx_L5_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_host, __pyx_v_host) < 0) __PYX_ERR(0, 869, __pyx_L5_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_port, __pyx_v_port) < 0) __PYX_ERR(0, 869, __pyx_L5_error) + + /* "aiohttp/_http_parser.pyx":871 + * return URL_build(scheme=schema, + * user=user, password=password, host=host, port=port, + * path=path, query_string=query, fragment=fragment, encoded=True) # <<<<<<<<<<<<<< + * else: + * raise InvalidURLError("invalid url {!r}".format(buf_data)) + */ + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_path, __pyx_v_path) < 0) __PYX_ERR(0, 869, __pyx_L5_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_query_string, __pyx_v_query) < 0) __PYX_ERR(0, 869, __pyx_L5_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fragment, __pyx_v_fragment) < 0) __PYX_ERR(0, 869, __pyx_L5_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_encoded, Py_True) < 0) __PYX_ERR(0, 869, __pyx_L5_error) + + /* "aiohttp/_http_parser.pyx":869 + * user, sep, password = userinfo.partition(':') + * + * return URL_build(scheme=schema, # <<<<<<<<<<<<<< + * user=user, password=password, host=host, port=port, + * path=path, query_string=query, fragment=fragment, encoded=True) + */ + __pyx_t_6 = __Pyx_PyObject_Call(__pyx_v_7aiohttp_12_http_parser_URL_build, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 869, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_r = __pyx_t_6; + __pyx_t_6 = 0; + goto __pyx_L4_return; + + /* "aiohttp/_http_parser.pyx":823 + * res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) + * + * if res == 0: # <<<<<<<<<<<<<< + * if parsed.field_set & (1 << cparser.UF_SCHEMA): + * off = parsed.field_data[cparser.UF_SCHEMA].off + */ + } + + /* "aiohttp/_http_parser.pyx":873 + * path=path, query_string=query, fragment=fragment, encoded=True) + * else: + * raise InvalidURLError("invalid url {!r}".format(buf_data)) # <<<<<<<<<<<<<< + * finally: + * PyMem_Free(parsed) + */ + /*else*/ { + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 873, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_invalid_url_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 873, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_7 = __Pyx_PyBytes_FromString(__pyx_v_buf_data); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 873, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_9)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_5 = (__pyx_t_9) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_9, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 873, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_3, function); + } + } + __pyx_t_6 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 873, __pyx_L5_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_t_6, 0, 0, 0); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __PYX_ERR(0, 873, __pyx_L5_error) + } + } + + /* "aiohttp/_http_parser.pyx":875 + * raise InvalidURLError("invalid url {!r}".format(buf_data)) + * finally: + * PyMem_Free(parsed) # <<<<<<<<<<<<<< + */ + /*finally:*/ { + __pyx_L5_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; + __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_16, &__pyx_t_17, &__pyx_t_18); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15) < 0)) __Pyx_ErrFetch(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15); + __Pyx_XGOTREF(__pyx_t_13); + __Pyx_XGOTREF(__pyx_t_14); + __Pyx_XGOTREF(__pyx_t_15); + __Pyx_XGOTREF(__pyx_t_16); + __Pyx_XGOTREF(__pyx_t_17); + __Pyx_XGOTREF(__pyx_t_18); + __pyx_t_10 = __pyx_lineno; __pyx_t_11 = __pyx_clineno; __pyx_t_12 = __pyx_filename; + { + PyMem_Free(__pyx_v_parsed); + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_16); + __Pyx_XGIVEREF(__pyx_t_17); + __Pyx_XGIVEREF(__pyx_t_18); + __Pyx_ExceptionReset(__pyx_t_16, __pyx_t_17, __pyx_t_18); + } + __Pyx_XGIVEREF(__pyx_t_13); + __Pyx_XGIVEREF(__pyx_t_14); + __Pyx_XGIVEREF(__pyx_t_15); + __Pyx_ErrRestore(__pyx_t_13, __pyx_t_14, __pyx_t_15); + __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; __pyx_t_16 = 0; __pyx_t_17 = 0; __pyx_t_18 = 0; + __pyx_lineno = __pyx_t_10; __pyx_clineno = __pyx_t_11; __pyx_filename = __pyx_t_12; + goto __pyx_L1_error; + } + __pyx_L4_return: { + __pyx_t_18 = __pyx_r; + __pyx_r = 0; + PyMem_Free(__pyx_v_parsed); + __pyx_r = __pyx_t_18; + __pyx_t_18 = 0; + goto __pyx_L0; + } + } + + /* "aiohttp/_http_parser.pyx":798 + * + * + * cdef _parse_url(char* buf_data, size_t length): # <<<<<<<<<<<<<< + * cdef: + * cparser.http_parser_url* parsed + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("aiohttp._http_parser._parse_url", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_schema); + __Pyx_XDECREF(__pyx_v_host); + __Pyx_XDECREF(__pyx_v_port); + __Pyx_XDECREF(__pyx_v_path); + __Pyx_XDECREF(__pyx_v_query); + __Pyx_XDECREF(__pyx_v_fragment); + __Pyx_XDECREF(__pyx_v_user); + __Pyx_XDECREF(__pyx_v_password); + __Pyx_XDECREF(__pyx_v_userinfo); + __Pyx_XDECREF(__pyx_v_result); + __Pyx_XDECREF(__pyx_v_sep); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage = {"__pyx_unpickle_RawRequestMessage", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v___pyx_type = 0; + long __pyx_v___pyx_checksum; + PyObject *__pyx_v___pyx_state = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__pyx_unpickle_RawRequestMessage (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; + PyObject* values[3] = {0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawRequestMessage", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawRequestMessage", 1, 3, 3, 2); __PYX_ERR(1, 1, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_RawRequestMessage") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + } + __pyx_v___pyx_type = values[0]; + __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) + __pyx_v___pyx_state = values[2]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawRequestMessage", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(1, 1, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawRequestMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMessage(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_2__pyx_unpickle_RawRequestMessage(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_v___pyx_PickleError = 0; + PyObject *__pyx_v___pyx_result = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_RawRequestMessage", 0); + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum != 0x1408252: # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) + */ + __pyx_t_1 = ((__pyx_v___pyx_checksum != 0x1408252) != 0); + if (__pyx_t_1) { + + /* "(tree fragment)":5 + * cdef object __pyx_result + * if __pyx_checksum != 0x1408252: + * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) + * __pyx_result = RawRequestMessage.__new__(__pyx_type) + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_PickleError); + __Pyx_GIVEREF(__pyx_n_s_PickleError); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_2); + __pyx_v___pyx_PickleError = __pyx_t_2; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":6 + * if __pyx_checksum != 0x1408252: + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) # <<<<<<<<<<<<<< + * __pyx_result = RawRequestMessage.__new__(__pyx_type) + * if __pyx_state is not None: + */ + __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0x14, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_INCREF(__pyx_v___pyx_PickleError); + __pyx_t_2 = __pyx_v___pyx_PickleError; __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 6, __pyx_L1_error) + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum != 0x1408252: # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) + */ + } + + /* "(tree fragment)":7 + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) + * __pyx_result = RawRequestMessage.__new__(__pyx_type) # <<<<<<<<<<<<<< + * if __pyx_state is not None: + * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v___pyx_result = __pyx_t_3; + __pyx_t_3 = 0; + + /* "(tree fragment)":8 + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) + * __pyx_result = RawRequestMessage.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result + */ + __pyx_t_1 = (__pyx_v___pyx_state != Py_None); + __pyx_t_6 = (__pyx_t_1 != 0); + if (__pyx_t_6) { + + /* "(tree fragment)":9 + * __pyx_result = RawRequestMessage.__new__(__pyx_type) + * if __pyx_state is not None: + * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< + * return __pyx_result + * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): + */ + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":8 + * raise __pyx_PickleError("Incompatible checksums (%s vs 0x1408252 = (chunked, compression, headers, method, path, raw_headers, should_close, upgrade, url, version))" % __pyx_checksum) + * __pyx_result = RawRequestMessage.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result + */ + } + + /* "(tree fragment)":10 + * if __pyx_state is not None: + * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result # <<<<<<<<<<<<<< + * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v___pyx_result); + __pyx_r = __pyx_v___pyx_result; + goto __pyx_L0; + + /* "(tree fragment)":1 + * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawRequestMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v___pyx_PickleError); + __Pyx_XDECREF(__pyx_v___pyx_result); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":11 + * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] + * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawRequestMessage__set_state(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + Py_ssize_t __pyx_t_3; + int __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_RawRequestMessage__set_state", 0); + + /* "(tree fragment)":12 + * return __pyx_result + * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] # <<<<<<<<<<<<<< + * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[10]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->chunked); + __Pyx_DECREF(__pyx_v___pyx_result->chunked); + __pyx_v___pyx_result->chunked = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->compression); + __Pyx_DECREF(__pyx_v___pyx_result->compression); + __pyx_v___pyx_result->compression = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->headers); + __Pyx_DECREF(__pyx_v___pyx_result->headers); + __pyx_v___pyx_result->headers = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->method); + __Pyx_DECREF(__pyx_v___pyx_result->method); + __pyx_v___pyx_result->method = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->path); + __Pyx_DECREF(__pyx_v___pyx_result->path); + __pyx_v___pyx_result->path = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 5, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->raw_headers); + __Pyx_DECREF(__pyx_v___pyx_result->raw_headers); + __pyx_v___pyx_result->raw_headers = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 6, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->should_close); + __Pyx_DECREF(__pyx_v___pyx_result->should_close); + __pyx_v___pyx_result->should_close = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 7, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->upgrade); + __Pyx_DECREF(__pyx_v___pyx_result->upgrade); + __pyx_v___pyx_result->upgrade = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 8, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->url); + __Pyx_DECREF(__pyx_v___pyx_result->url); + __pyx_v___pyx_result->url = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 9, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->version); + __Pyx_DECREF(__pyx_v___pyx_result->version); + __pyx_v___pyx_result->version = __pyx_t_1; + __pyx_t_1 = 0; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] + * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[10]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(1, 13, __pyx_L1_error) + } + __pyx_t_3 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_4 = ((__pyx_t_3 > 10) != 0); + if (__pyx_t_4) { + } else { + __pyx_t_2 = __pyx_t_4; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_4 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_5 = (__pyx_t_4 != 0); + __pyx_t_2 = __pyx_t_5; + __pyx_L4_bool_binop_done:; + if (__pyx_t_2) { + + /* "(tree fragment)":14 + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] + * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[10]) # <<<<<<<<<<<<<< + */ + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_update); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 14, __pyx_L1_error) + } + __pyx_t_6 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 10, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __pyx_t_8 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) { + __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7); + if (likely(__pyx_t_8)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7); + __Pyx_INCREF(__pyx_t_8); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_7, function); + } + } + __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_8, __pyx_t_6) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] + * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[10]) + */ + } + + /* "(tree fragment)":11 + * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] + * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawRequestMessage__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":1 + * def __pyx_unpickle_RawResponseMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage = {"__pyx_unpickle_RawResponseMessage", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v___pyx_type = 0; + long __pyx_v___pyx_checksum; + PyObject *__pyx_v___pyx_state = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__pyx_unpickle_RawResponseMessage (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pyx_type,&__pyx_n_s_pyx_checksum,&__pyx_n_s_pyx_state,0}; + PyObject* values[3] = {0,0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + CYTHON_FALLTHROUGH; + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_type)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_checksum)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawResponseMessage", 1, 3, 3, 1); __PYX_ERR(1, 1, __pyx_L3_error) + } + CYTHON_FALLTHROUGH; + case 2: + if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pyx_state)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawResponseMessage", 1, 3, 3, 2); __PYX_ERR(1, 1, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_unpickle_RawResponseMessage") < 0)) __PYX_ERR(1, 1, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 3) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + values[2] = PyTuple_GET_ITEM(__pyx_args, 2); + } + __pyx_v___pyx_type = values[0]; + __pyx_v___pyx_checksum = __Pyx_PyInt_As_long(values[1]); if (unlikely((__pyx_v___pyx_checksum == (long)-1) && PyErr_Occurred())) __PYX_ERR(1, 1, __pyx_L3_error) + __pyx_v___pyx_state = values[2]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("__pyx_unpickle_RawResponseMessage", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(1, 1, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawResponseMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMessage(__pyx_self, __pyx_v___pyx_type, __pyx_v___pyx_checksum, __pyx_v___pyx_state); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_parser_4__pyx_unpickle_RawResponseMessage(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v___pyx_type, long __pyx_v___pyx_checksum, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_v___pyx_PickleError = 0; + PyObject *__pyx_v___pyx_result = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_RawResponseMessage", 0); + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum != 0xc7706dc: # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) + */ + __pyx_t_1 = ((__pyx_v___pyx_checksum != 0xc7706dc) != 0); + if (__pyx_t_1) { + + /* "(tree fragment)":5 + * cdef object __pyx_result + * if __pyx_checksum != 0xc7706dc: + * from pickle import PickleError as __pyx_PickleError # <<<<<<<<<<<<<< + * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) + * __pyx_result = RawResponseMessage.__new__(__pyx_type) + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_PickleError); + __Pyx_GIVEREF(__pyx_n_s_PickleError); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_PickleError); + __pyx_t_3 = __Pyx_Import(__pyx_n_s_pickle, __pyx_t_2, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_3, __pyx_n_s_PickleError); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 5, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_2); + __pyx_v___pyx_PickleError = __pyx_t_2; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":6 + * if __pyx_checksum != 0xc7706dc: + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) # <<<<<<<<<<<<<< + * __pyx_result = RawResponseMessage.__new__(__pyx_type) + * if __pyx_state is not None: + */ + __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v___pyx_checksum); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Incompatible_checksums_s_vs_0xc7, __pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_INCREF(__pyx_v___pyx_PickleError); + __pyx_t_2 = __pyx_v___pyx_PickleError; __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_Raise(__pyx_t_3, 0, 0, 0); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __PYX_ERR(1, 6, __pyx_L1_error) + + /* "(tree fragment)":4 + * cdef object __pyx_PickleError + * cdef object __pyx_result + * if __pyx_checksum != 0xc7706dc: # <<<<<<<<<<<<<< + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) + */ + } + + /* "(tree fragment)":7 + * from pickle import PickleError as __pyx_PickleError + * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) + * __pyx_result = RawResponseMessage.__new__(__pyx_type) # <<<<<<<<<<<<<< + * if __pyx_state is not None: + * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) + */ + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage), __pyx_n_s_new); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_4 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); + if (likely(__pyx_t_4)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_2, function); + } + } + __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_4, __pyx_v___pyx_type) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v___pyx_type); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_v___pyx_result = __pyx_t_3; + __pyx_t_3 = 0; + + /* "(tree fragment)":8 + * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) + * __pyx_result = RawResponseMessage.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result + */ + __pyx_t_1 = (__pyx_v___pyx_state != Py_None); + __pyx_t_6 = (__pyx_t_1 != 0); + if (__pyx_t_6) { + + /* "(tree fragment)":9 + * __pyx_result = RawResponseMessage.__new__(__pyx_type) + * if __pyx_state is not None: + * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) # <<<<<<<<<<<<<< + * return __pyx_result + * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): + */ + if (!(likely(PyTuple_CheckExact(__pyx_v___pyx_state))||((__pyx_v___pyx_state) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_v___pyx_state)->tp_name), 0))) __PYX_ERR(1, 9, __pyx_L1_error) + __pyx_t_3 = __pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)__pyx_v___pyx_result), ((PyObject*)__pyx_v___pyx_state)); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "(tree fragment)":8 + * raise __pyx_PickleError("Incompatible checksums (%s vs 0xc7706dc = (chunked, code, compression, headers, raw_headers, reason, should_close, upgrade, version))" % __pyx_checksum) + * __pyx_result = RawResponseMessage.__new__(__pyx_type) + * if __pyx_state is not None: # <<<<<<<<<<<<<< + * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result + */ + } + + /* "(tree fragment)":10 + * if __pyx_state is not None: + * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result # <<<<<<<<<<<<<< + * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_v___pyx_result); + __pyx_r = __pyx_v___pyx_result; + goto __pyx_L0; + + /* "(tree fragment)":1 + * def __pyx_unpickle_RawResponseMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawResponseMessage", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v___pyx_PickleError); + __Pyx_XDECREF(__pyx_v___pyx_result); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "(tree fragment)":11 + * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] + * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): + */ + +static PyObject *__pyx_f_7aiohttp_12_http_parser___pyx_unpickle_RawResponseMessage__set_state(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_v___pyx_result, PyObject *__pyx_v___pyx_state) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + int __pyx_t_3; + Py_ssize_t __pyx_t_4; + int __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__pyx_unpickle_RawResponseMessage__set_state", 0); + + /* "(tree fragment)":12 + * return __pyx_result + * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] # <<<<<<<<<<<<<< + * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[9]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->chunked); + __Pyx_DECREF(__pyx_v___pyx_result->chunked); + __pyx_v___pyx_result->chunked = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_v___pyx_result->code = __pyx_t_2; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->compression); + __Pyx_DECREF(__pyx_v___pyx_result->compression); + __pyx_v___pyx_result->compression = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->headers); + __Pyx_DECREF(__pyx_v___pyx_result->headers); + __pyx_v___pyx_result->headers = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->raw_headers); + __Pyx_DECREF(__pyx_v___pyx_result->raw_headers); + __pyx_v___pyx_result->raw_headers = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 5, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->reason); + __Pyx_DECREF(__pyx_v___pyx_result->reason); + __pyx_v___pyx_result->reason = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 6, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->should_close); + __Pyx_DECREF(__pyx_v___pyx_result->should_close); + __pyx_v___pyx_result->should_close = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 7, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->upgrade); + __Pyx_DECREF(__pyx_v___pyx_result->upgrade); + __pyx_v___pyx_result->upgrade = __pyx_t_1; + __pyx_t_1 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 12, __pyx_L1_error) + } + __pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 8, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __Pyx_GOTREF(__pyx_v___pyx_result->version); + __Pyx_DECREF(__pyx_v___pyx_result->version); + __pyx_v___pyx_result->version = __pyx_t_1; + __pyx_t_1 = 0; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] + * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[9]) + */ + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()"); + __PYX_ERR(1, 13, __pyx_L1_error) + } + __pyx_t_4 = PyTuple_GET_SIZE(__pyx_v___pyx_state); if (unlikely(__pyx_t_4 == ((Py_ssize_t)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_5 = ((__pyx_t_4 > 9) != 0); + if (__pyx_t_5) { + } else { + __pyx_t_3 = __pyx_t_5; + goto __pyx_L4_bool_binop_done; + } + __pyx_t_5 = __Pyx_HasAttr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(__pyx_t_5 == ((int)-1))) __PYX_ERR(1, 13, __pyx_L1_error) + __pyx_t_6 = (__pyx_t_5 != 0); + __pyx_t_3 = __pyx_t_6; + __pyx_L4_bool_binop_done:; + if (__pyx_t_3) { + + /* "(tree fragment)":14 + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] + * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): + * __pyx_result.__dict__.update(__pyx_state[9]) # <<<<<<<<<<<<<< + */ + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v___pyx_result), __pyx_n_s_dict); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_update); if (unlikely(!__pyx_t_8)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(__pyx_v___pyx_state == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable"); + __PYX_ERR(1, 14, __pyx_L1_error) + } + __pyx_t_7 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 9, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_7)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_8))) { + __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_8); + if (likely(__pyx_t_9)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8); + __Pyx_INCREF(__pyx_t_9); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_8, function); + } + } + __pyx_t_1 = (__pyx_t_9) ? __Pyx_PyObject_Call2Args(__pyx_t_8, __pyx_t_9, __pyx_t_7) : __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":13 + * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] + * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): # <<<<<<<<<<<<<< + * __pyx_result.__dict__.update(__pyx_state[9]) + */ + } + + /* "(tree fragment)":11 + * __pyx_unpickle_RawResponseMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_RawResponseMessage__set_state(RawResponseMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.code = __pyx_state[1]; __pyx_result.compression = __pyx_state[2]; __pyx_result.headers = __pyx_state[3]; __pyx_result.raw_headers = __pyx_state[4]; __pyx_result.reason = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.version = __pyx_state[8] + * if len(__pyx_state) > 9 and hasattr(__pyx_result, '__dict__'): + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("aiohttp._http_parser.__pyx_unpickle_RawResponseMessage__set_state", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *__pyx_freelist_7aiohttp_12_http_parser_RawRequestMessage[250]; +static int __pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage = 0; + +static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_RawRequestMessage(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *p; + PyObject *o; + if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage)) & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0))) { + o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser_RawRequestMessage[--__pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage]; + memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else { + if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + } + p = ((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o); + p->method = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->path = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->version = Py_None; Py_INCREF(Py_None); + p->headers = Py_None; Py_INCREF(Py_None); + p->raw_headers = Py_None; Py_INCREF(Py_None); + p->should_close = Py_None; Py_INCREF(Py_None); + p->compression = Py_None; Py_INCREF(Py_None); + p->upgrade = Py_None; Py_INCREF(Py_None); + p->chunked = Py_None; Py_INCREF(Py_None); + p->url = Py_None; Py_INCREF(Py_None); + return o; +} + +static void __pyx_tp_dealloc_7aiohttp_12_http_parser_RawRequestMessage(PyObject *o) { + struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->method); + Py_CLEAR(p->path); + Py_CLEAR(p->version); + Py_CLEAR(p->headers); + Py_CLEAR(p->raw_headers); + Py_CLEAR(p->should_close); + Py_CLEAR(p->compression); + Py_CLEAR(p->upgrade); + Py_CLEAR(p->chunked); + Py_CLEAR(p->url); + if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage < 250) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage)) & ((Py_TYPE(o)->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0))) { + __pyx_freelist_7aiohttp_12_http_parser_RawRequestMessage[__pyx_freecount_7aiohttp_12_http_parser_RawRequestMessage++] = ((struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o); + } else { + (*Py_TYPE(o)->tp_free)(o); + } +} + +static int __pyx_tp_traverse_7aiohttp_12_http_parser_RawRequestMessage(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o; + if (p->version) { + e = (*v)(p->version, a); if (e) return e; + } + if (p->headers) { + e = (*v)(p->headers, a); if (e) return e; + } + if (p->raw_headers) { + e = (*v)(p->raw_headers, a); if (e) return e; + } + if (p->should_close) { + e = (*v)(p->should_close, a); if (e) return e; + } + if (p->compression) { + e = (*v)(p->compression, a); if (e) return e; + } + if (p->upgrade) { + e = (*v)(p->upgrade, a); if (e) return e; + } + if (p->chunked) { + e = (*v)(p->chunked, a); if (e) return e; + } + if (p->url) { + e = (*v)(p->url, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_7aiohttp_12_http_parser_RawRequestMessage(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage *)o; + tmp = ((PyObject*)p->version); + p->version = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->headers); + p->headers = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->raw_headers); + p->raw_headers = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->should_close); + p->should_close = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->compression); + p->compression = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->upgrade); + p->upgrade = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->chunked); + p->chunked = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->url); + p->url = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_method(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_6method_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_path(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_4path_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_version(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7version_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_headers(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7headers_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_raw_headers(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11raw_headers_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_should_close(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_12should_close_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_compression(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_11compression_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_upgrade(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7upgrade_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_chunked(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7chunked_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_url(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3url_1__get__(o); +} + +static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_RawRequestMessage[] = { + {"_replace", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_5_replace, METH_VARARGS|METH_KEYWORDS, 0}, + {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_7__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_9__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static struct PyGetSetDef __pyx_getsets_7aiohttp_12_http_parser_RawRequestMessage[] = { + {(char *)"method", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_method, 0, (char *)0, 0}, + {(char *)"path", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_path, 0, (char *)0, 0}, + {(char *)"version", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_version, 0, (char *)0, 0}, + {(char *)"headers", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_headers, 0, (char *)0, 0}, + {(char *)"raw_headers", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_raw_headers, 0, (char *)0, 0}, + {(char *)"should_close", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_should_close, 0, (char *)0, 0}, + {(char *)"compression", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_compression, 0, (char *)0, 0}, + {(char *)"upgrade", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_upgrade, 0, (char *)0, 0}, + {(char *)"chunked", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_chunked, 0, (char *)0, 0}, + {(char *)"url", __pyx_getprop_7aiohttp_12_http_parser_17RawRequestMessage_url, 0, (char *)0, 0}, + {0, 0, 0, 0, 0} +}; + +static PyTypeObject __pyx_type_7aiohttp_12_http_parser_RawRequestMessage = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._http_parser.RawRequestMessage", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawRequestMessage), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_12_http_parser_RawRequestMessage, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_3__repr__, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_12_http_parser_RawRequestMessage, /*tp_traverse*/ + __pyx_tp_clear_7aiohttp_12_http_parser_RawRequestMessage, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7aiohttp_12_http_parser_RawRequestMessage, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_7aiohttp_12_http_parser_RawRequestMessage, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + __pyx_pw_7aiohttp_12_http_parser_17RawRequestMessage_1__init__, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_12_http_parser_RawRequestMessage, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; + +static struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *__pyx_freelist_7aiohttp_12_http_parser_RawResponseMessage[250]; +static int __pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage = 0; + +static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_RawResponseMessage(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *p; + PyObject *o; + if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage)) & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0))) { + o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser_RawResponseMessage[--__pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage]; + memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else { + if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + } + p = ((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o); + p->version = Py_None; Py_INCREF(Py_None); + p->reason = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->headers = Py_None; Py_INCREF(Py_None); + p->raw_headers = Py_None; Py_INCREF(Py_None); + p->should_close = Py_None; Py_INCREF(Py_None); + p->compression = Py_None; Py_INCREF(Py_None); + p->upgrade = Py_None; Py_INCREF(Py_None); + p->chunked = Py_None; Py_INCREF(Py_None); + return o; +} + +static void __pyx_tp_dealloc_7aiohttp_12_http_parser_RawResponseMessage(PyObject *o) { + struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + #endif + PyObject_GC_UnTrack(o); + Py_CLEAR(p->version); + Py_CLEAR(p->reason); + Py_CLEAR(p->headers); + Py_CLEAR(p->raw_headers); + Py_CLEAR(p->should_close); + Py_CLEAR(p->compression); + Py_CLEAR(p->upgrade); + Py_CLEAR(p->chunked); + if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage < 250) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage)) & ((Py_TYPE(o)->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0))) { + __pyx_freelist_7aiohttp_12_http_parser_RawResponseMessage[__pyx_freecount_7aiohttp_12_http_parser_RawResponseMessage++] = ((struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o); + } else { + (*Py_TYPE(o)->tp_free)(o); + } +} + +static int __pyx_tp_traverse_7aiohttp_12_http_parser_RawResponseMessage(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o; + if (p->version) { + e = (*v)(p->version, a); if (e) return e; + } + if (p->headers) { + e = (*v)(p->headers, a); if (e) return e; + } + if (p->raw_headers) { + e = (*v)(p->raw_headers, a); if (e) return e; + } + if (p->should_close) { + e = (*v)(p->should_close, a); if (e) return e; + } + if (p->compression) { + e = (*v)(p->compression, a); if (e) return e; + } + if (p->upgrade) { + e = (*v)(p->upgrade, a); if (e) return e; + } + if (p->chunked) { + e = (*v)(p->chunked, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_7aiohttp_12_http_parser_RawResponseMessage(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *p = (struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage *)o; + tmp = ((PyObject*)p->version); + p->version = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->headers); + p->headers = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->raw_headers); + p->raw_headers = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->should_close); + p->should_close = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->compression); + p->compression = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->upgrade); + p->upgrade = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->chunked); + p->chunked = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_version(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7version_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_code(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_4code_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_reason(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_6reason_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_headers(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7headers_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_raw_headers(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11raw_headers_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_should_close(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_12should_close_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_compression(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_11compression_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_upgrade(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7upgrade_1__get__(o); +} + +static PyObject *__pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_chunked(PyObject *o, CYTHON_UNUSED void *x) { + return __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7chunked_1__get__(o); +} + +static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_RawResponseMessage[] = { + {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_5__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_7__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static struct PyGetSetDef __pyx_getsets_7aiohttp_12_http_parser_RawResponseMessage[] = { + {(char *)"version", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_version, 0, (char *)0, 0}, + {(char *)"code", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_code, 0, (char *)0, 0}, + {(char *)"reason", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_reason, 0, (char *)0, 0}, + {(char *)"headers", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_headers, 0, (char *)0, 0}, + {(char *)"raw_headers", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_raw_headers, 0, (char *)0, 0}, + {(char *)"should_close", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_should_close, 0, (char *)0, 0}, + {(char *)"compression", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_compression, 0, (char *)0, 0}, + {(char *)"upgrade", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_upgrade, 0, (char *)0, 0}, + {(char *)"chunked", __pyx_getprop_7aiohttp_12_http_parser_18RawResponseMessage_chunked, 0, (char *)0, 0}, + {0, 0, 0, 0, 0} +}; + +static PyTypeObject __pyx_type_7aiohttp_12_http_parser_RawResponseMessage = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._http_parser.RawResponseMessage", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_12_http_parser_RawResponseMessage), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_12_http_parser_RawResponseMessage, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_3__repr__, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_12_http_parser_RawResponseMessage, /*tp_traverse*/ + __pyx_tp_clear_7aiohttp_12_http_parser_RawResponseMessage, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7aiohttp_12_http_parser_RawResponseMessage, /*tp_methods*/ + 0, /*tp_members*/ + __pyx_getsets_7aiohttp_12_http_parser_RawResponseMessage, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + __pyx_pw_7aiohttp_12_http_parser_18RawResponseMessage_1__init__, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_12_http_parser_RawResponseMessage, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; +static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser __pyx_vtable_7aiohttp_12_http_parser_HttpParser; + +static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_HttpParser(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *p; + PyObject *o; + if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) { + o = (*t->tp_alloc)(t, 0); + } else { + o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0); + } + if (unlikely(!o)) return 0; + p = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)o); + p->__pyx_vtab = __pyx_vtabptr_7aiohttp_12_http_parser_HttpParser; + p->_raw_name = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->_raw_value = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->_protocol = Py_None; Py_INCREF(Py_None); + p->_loop = Py_None; Py_INCREF(Py_None); + p->_timer = Py_None; Py_INCREF(Py_None); + p->_url = Py_None; Py_INCREF(Py_None); + p->_buf = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->_path = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->_reason = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->_headers = Py_None; Py_INCREF(Py_None); + p->_raw_headers = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->_messages = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->_payload = Py_None; Py_INCREF(Py_None); + p->_payload_exception = Py_None; Py_INCREF(Py_None); + p->_last_error = Py_None; Py_INCREF(Py_None); + p->_content_encoding = ((PyObject*)Py_None); Py_INCREF(Py_None); + p->py_buf.obj = NULL; + if (unlikely(__pyx_pw_7aiohttp_12_http_parser_10HttpParser_1__cinit__(o, __pyx_empty_tuple, NULL) < 0)) goto bad; + return o; + bad: + Py_DECREF(o); o = 0; + return NULL; +} + +static void __pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser(PyObject *o) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *p = (struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)o; + #if CYTHON_USE_TP_FINALIZE + if (unlikely(PyType_HasFeature(Py_TYPE(o), Py_TPFLAGS_HAVE_FINALIZE) && Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) { + if (PyObject_CallFinalizerFromDealloc(o)) return; + } + #endif + PyObject_GC_UnTrack(o); + { + PyObject *etype, *eval, *etb; + PyErr_Fetch(&etype, &eval, &etb); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) + 1); + __pyx_pw_7aiohttp_12_http_parser_10HttpParser_3__dealloc__(o); + __Pyx_SET_REFCNT(o, Py_REFCNT(o) - 1); + PyErr_Restore(etype, eval, etb); + } + Py_CLEAR(p->_raw_name); + Py_CLEAR(p->_raw_value); + Py_CLEAR(p->_protocol); + Py_CLEAR(p->_loop); + Py_CLEAR(p->_timer); + Py_CLEAR(p->_url); + Py_CLEAR(p->_buf); + Py_CLEAR(p->_path); + Py_CLEAR(p->_reason); + Py_CLEAR(p->_headers); + Py_CLEAR(p->_raw_headers); + Py_CLEAR(p->_messages); + Py_CLEAR(p->_payload); + Py_CLEAR(p->_payload_exception); + Py_CLEAR(p->_last_error); + Py_CLEAR(p->_content_encoding); + (*Py_TYPE(o)->tp_free)(o); +} + +static int __pyx_tp_traverse_7aiohttp_12_http_parser_HttpParser(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *p = (struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)o; + if (p->_protocol) { + e = (*v)(p->_protocol, a); if (e) return e; + } + if (p->_loop) { + e = (*v)(p->_loop, a); if (e) return e; + } + if (p->_timer) { + e = (*v)(p->_timer, a); if (e) return e; + } + if (p->_url) { + e = (*v)(p->_url, a); if (e) return e; + } + if (p->_headers) { + e = (*v)(p->_headers, a); if (e) return e; + } + if (p->_raw_headers) { + e = (*v)(p->_raw_headers, a); if (e) return e; + } + if (p->_messages) { + e = (*v)(p->_messages, a); if (e) return e; + } + if (p->_payload) { + e = (*v)(p->_payload, a); if (e) return e; + } + if (p->_payload_exception) { + e = (*v)(p->_payload_exception, a); if (e) return e; + } + if (p->_last_error) { + e = (*v)(p->_last_error, a); if (e) return e; + } + if (p->py_buf.obj) { + e = (*v)(p->py_buf.obj, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_7aiohttp_12_http_parser_HttpParser(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *p = (struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *)o; + tmp = ((PyObject*)p->_protocol); + p->_protocol = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_loop); + p->_loop = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_timer); + p->_timer = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_url); + p->_url = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_headers); + p->_headers = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_raw_headers); + p->_raw_headers = ((PyObject*)Py_None); Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_messages); + p->_messages = ((PyObject*)Py_None); Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_payload); + p->_payload = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_payload_exception); + p->_payload_exception = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + tmp = ((PyObject*)p->_last_error); + p->_last_error = Py_None; Py_INCREF(Py_None); + Py_XDECREF(tmp); + Py_CLEAR(p->py_buf.obj); + return 0; +} + +static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_HttpParser[] = { + {"feed_eof", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_5feed_eof, METH_NOARGS, 0}, + {"feed_data", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_7feed_data, METH_O, 0}, + {"set_upgraded", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_9set_upgraded, METH_O, 0}, + {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_11__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_10HttpParser_13__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static PyTypeObject __pyx_type_7aiohttp_12_http_parser_HttpParser = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._http_parser.HttpParser", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_12_http_parser_HttpParser, /*tp_traverse*/ + __pyx_tp_clear_7aiohttp_12_http_parser_HttpParser, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7aiohttp_12_http_parser_HttpParser, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_12_http_parser_HttpParser, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; +static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpRequestParser __pyx_vtable_7aiohttp_12_http_parser_HttpRequestParser; + +static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_HttpRequestParser(PyTypeObject *t, PyObject *a, PyObject *k) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *p; + PyObject *o = __pyx_tp_new_7aiohttp_12_http_parser_HttpParser(t, a, k); + if (unlikely(!o)) return 0; + p = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser *)o); + p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser*)__pyx_vtabptr_7aiohttp_12_http_parser_HttpRequestParser; + return o; +} + +static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_HttpRequestParser[] = { + {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_3__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_5__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static PyTypeObject __pyx_type_7aiohttp_12_http_parser_HttpRequestParser = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._http_parser.HttpRequestParser", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_12_http_parser_HttpRequestParser), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_12_http_parser_HttpParser, /*tp_traverse*/ + __pyx_tp_clear_7aiohttp_12_http_parser_HttpParser, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7aiohttp_12_http_parser_HttpRequestParser, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + __pyx_pw_7aiohttp_12_http_parser_17HttpRequestParser_1__init__, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_12_http_parser_HttpRequestParser, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; +static struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpResponseParser __pyx_vtable_7aiohttp_12_http_parser_HttpResponseParser; + +static PyObject *__pyx_tp_new_7aiohttp_12_http_parser_HttpResponseParser(PyTypeObject *t, PyObject *a, PyObject *k) { + struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *p; + PyObject *o = __pyx_tp_new_7aiohttp_12_http_parser_HttpParser(t, a, k); + if (unlikely(!o)) return 0; + p = ((struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser *)o); + p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_7aiohttp_12_http_parser_HttpParser*)__pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser; + return o; +} + +static PyMethodDef __pyx_methods_7aiohttp_12_http_parser_HttpResponseParser[] = { + {"__reduce_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_3__reduce_cython__, METH_NOARGS, 0}, + {"__setstate_cython__", (PyCFunction)__pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_5__setstate_cython__, METH_O, 0}, + {0, 0, 0, 0} +}; + +static PyTypeObject __pyx_type_7aiohttp_12_http_parser_HttpResponseParser = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._http_parser.HttpResponseParser", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_12_http_parser_HttpResponseParser), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_12_http_parser_HttpParser, /*tp_traverse*/ + __pyx_tp_clear_7aiohttp_12_http_parser_HttpParser, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + __pyx_methods_7aiohttp_12_http_parser_HttpResponseParser, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + __pyx_pw_7aiohttp_12_http_parser_18HttpResponseParser_1__init__, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_12_http_parser_HttpResponseParser, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; + +static struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct____repr__[8]; +static int __pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__ = 0; + +static PyObject *__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct____repr__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__ > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__)))) { + o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct____repr__[--__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__]; + memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct____repr__(PyObject *o) { + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)o; + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_v_info); + if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__ < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__)))) { + __pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct____repr__[__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct____repr__++] = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)o); + } else { + (*Py_TYPE(o)->tp_free)(o); + } +} + +static int __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct____repr__(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)o; + if (p->__pyx_v_info) { + e = (*v)(p->__pyx_v_info, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_7aiohttp_12_http_parser___pyx_scope_struct____repr__(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__ *)o; + tmp = ((PyObject*)p->__pyx_v_info); + p->__pyx_v_info = ((PyObject*)Py_None); Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} + +static PyTypeObject __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__ = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._http_parser.__pyx_scope_struct____repr__", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct____repr__), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct____repr__, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct____repr__, /*tp_traverse*/ + __pyx_tp_clear_7aiohttp_12_http_parser___pyx_scope_struct____repr__, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct____repr__, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; + +static struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr[8]; +static int __pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr = 0; + +static PyObject *__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr)))) { + o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr[--__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr]; + memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr(PyObject *o) { + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)o; + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_outer_scope); + Py_CLEAR(p->__pyx_v_name); + Py_CLEAR(p->__pyx_v_val); + if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr)))) { + __pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr[__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr++] = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)o); + } else { + (*Py_TYPE(o)->tp_free)(o); + } +} + +static int __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr *)o; + if (p->__pyx_outer_scope) { + e = (*v)(((PyObject *)p->__pyx_outer_scope), a); if (e) return e; + } + if (p->__pyx_v_name) { + e = (*v)(p->__pyx_v_name, a); if (e) return e; + } + if (p->__pyx_v_val) { + e = (*v)(p->__pyx_v_val, a); if (e) return e; + } + return 0; +} + +static PyTypeObject __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._http_parser.__pyx_scope_struct_1_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; + +static struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__[8]; +static int __pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ = 0; + +static PyObject *__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__)))) { + o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__[--__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__]; + memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(PyObject *o) { + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)o; + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_v_info); + if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__)))) { + __pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__[__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__++] = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)o); + } else { + (*Py_TYPE(o)->tp_free)(o); + } +} + +static int __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)o; + if (p->__pyx_v_info) { + e = (*v)(p->__pyx_v_info, a); if (e) return e; + } + return 0; +} + +static int __pyx_tp_clear_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__(PyObject *o) { + PyObject* tmp; + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ *)o; + tmp = ((PyObject*)p->__pyx_v_info); + p->__pyx_v_info = ((PyObject*)Py_None); Py_INCREF(Py_None); + Py_XDECREF(tmp); + return 0; +} + +static PyTypeObject __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._http_parser.__pyx_scope_struct_2___repr__", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, /*tp_traverse*/ + __pyx_tp_clear_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; + +static struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr[8]; +static int __pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr = 0; + +static PyObject *__pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) { + PyObject *o; + if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr)))) { + o = (PyObject*)__pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr[--__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr]; + memset(o, 0, sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr)); + (void) PyObject_INIT(o, t); + PyObject_GC_Track(o); + } else { + o = (*t->tp_alloc)(t, 0); + if (unlikely(!o)) return 0; + } + return o; +} + +static void __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr(PyObject *o) { + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)o; + PyObject_GC_UnTrack(o); + Py_CLEAR(p->__pyx_outer_scope); + Py_CLEAR(p->__pyx_v_name); + Py_CLEAR(p->__pyx_v_val); + if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr)))) { + __pyx_freelist_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr[__pyx_freecount_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr++] = ((struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)o); + } else { + (*Py_TYPE(o)->tp_free)(o); + } +} + +static int __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr(PyObject *o, visitproc v, void *a) { + int e; + struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *p = (struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr *)o; + if (p->__pyx_outer_scope) { + e = (*v)(((PyObject *)p->__pyx_outer_scope), a); if (e) return e; + } + if (p->__pyx_v_name) { + e = (*v)(p->__pyx_v_name, a); if (e) return e; + } + if (p->__pyx_v_val) { + e = (*v)(p->__pyx_v_val, a); if (e) return e; + } + return 0; +} + +static PyTypeObject __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr = { + PyVarObject_HEAD_INIT(0, 0) + "aiohttp._http_parser.__pyx_scope_struct_3_genexpr", /*tp_name*/ + sizeof(struct __pyx_obj_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + __pyx_tp_dealloc_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr, /*tp_dealloc*/ + #if PY_VERSION_HEX < 0x030800b4 + 0, /*tp_print*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 + 0, /*tp_vectorcall_offset*/ + #endif + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + #if PY_MAJOR_VERSION < 3 + 0, /*tp_compare*/ + #endif + #if PY_MAJOR_VERSION >= 3 + 0, /*tp_as_async*/ + #endif + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + 0, /*tp_doc*/ + __pyx_tp_traverse_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + __pyx_tp_new_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr, /*tp_new*/ + 0, /*tp_free*/ + 0, /*tp_is_gc*/ + 0, /*tp_bases*/ + 0, /*tp_mro*/ + 0, /*tp_cache*/ + 0, /*tp_subclasses*/ + 0, /*tp_weaklist*/ + 0, /*tp_del*/ + 0, /*tp_version_tag*/ + #if PY_VERSION_HEX >= 0x030400a1 + 0, /*tp_finalize*/ + #endif + #if PY_VERSION_HEX >= 0x030800b1 + 0, /*tp_vectorcall*/ + #endif + #if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, /*tp_print*/ + #endif +}; + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec__http_parser(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec__http_parser}, + {0, NULL} +}; +#endif + +static struct PyModuleDef __pyx_moduledef = { + PyModuleDef_HEAD_INIT, + "_http_parser", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_, __pyx_k_, sizeof(__pyx_k_), 0, 1, 0, 0}, + {&__pyx_n_s_ACCEPT, __pyx_k_ACCEPT, sizeof(__pyx_k_ACCEPT), 0, 0, 1, 1}, + {&__pyx_n_s_ACCEPT_CHARSET, __pyx_k_ACCEPT_CHARSET, sizeof(__pyx_k_ACCEPT_CHARSET), 0, 0, 1, 1}, + {&__pyx_n_s_ACCEPT_ENCODING, __pyx_k_ACCEPT_ENCODING, sizeof(__pyx_k_ACCEPT_ENCODING), 0, 0, 1, 1}, + {&__pyx_n_s_ACCEPT_LANGUAGE, __pyx_k_ACCEPT_LANGUAGE, sizeof(__pyx_k_ACCEPT_LANGUAGE), 0, 0, 1, 1}, + {&__pyx_n_s_ACCEPT_RANGES, __pyx_k_ACCEPT_RANGES, sizeof(__pyx_k_ACCEPT_RANGES), 0, 0, 1, 1}, + {&__pyx_n_s_ACCESS_CONTROL_ALLOW_CREDENTIALS, __pyx_k_ACCESS_CONTROL_ALLOW_CREDENTIALS, sizeof(__pyx_k_ACCESS_CONTROL_ALLOW_CREDENTIALS), 0, 0, 1, 1}, + {&__pyx_n_s_ACCESS_CONTROL_ALLOW_HEADERS, __pyx_k_ACCESS_CONTROL_ALLOW_HEADERS, sizeof(__pyx_k_ACCESS_CONTROL_ALLOW_HEADERS), 0, 0, 1, 1}, + {&__pyx_n_s_ACCESS_CONTROL_ALLOW_METHODS, __pyx_k_ACCESS_CONTROL_ALLOW_METHODS, sizeof(__pyx_k_ACCESS_CONTROL_ALLOW_METHODS), 0, 0, 1, 1}, + {&__pyx_n_s_ACCESS_CONTROL_ALLOW_ORIGIN, __pyx_k_ACCESS_CONTROL_ALLOW_ORIGIN, sizeof(__pyx_k_ACCESS_CONTROL_ALLOW_ORIGIN), 0, 0, 1, 1}, + {&__pyx_n_s_ACCESS_CONTROL_EXPOSE_HEADERS, __pyx_k_ACCESS_CONTROL_EXPOSE_HEADERS, sizeof(__pyx_k_ACCESS_CONTROL_EXPOSE_HEADERS), 0, 0, 1, 1}, + {&__pyx_n_s_ACCESS_CONTROL_MAX_AGE, __pyx_k_ACCESS_CONTROL_MAX_AGE, sizeof(__pyx_k_ACCESS_CONTROL_MAX_AGE), 0, 0, 1, 1}, + {&__pyx_n_s_ACCESS_CONTROL_REQUEST_HEADERS, __pyx_k_ACCESS_CONTROL_REQUEST_HEADERS, sizeof(__pyx_k_ACCESS_CONTROL_REQUEST_HEADERS), 0, 0, 1, 1}, + {&__pyx_n_s_ACCESS_CONTROL_REQUEST_METHOD, __pyx_k_ACCESS_CONTROL_REQUEST_METHOD, sizeof(__pyx_k_ACCESS_CONTROL_REQUEST_METHOD), 0, 0, 1, 1}, + {&__pyx_n_s_AGE, __pyx_k_AGE, sizeof(__pyx_k_AGE), 0, 0, 1, 1}, + {&__pyx_n_s_ALLOW, __pyx_k_ALLOW, sizeof(__pyx_k_ALLOW), 0, 0, 1, 1}, + {&__pyx_n_s_AUTHORIZATION, __pyx_k_AUTHORIZATION, sizeof(__pyx_k_AUTHORIZATION), 0, 0, 1, 1}, + {&__pyx_n_s_BadHttpMessage, __pyx_k_BadHttpMessage, sizeof(__pyx_k_BadHttpMessage), 0, 0, 1, 1}, + {&__pyx_n_s_BadStatusLine, __pyx_k_BadStatusLine, sizeof(__pyx_k_BadStatusLine), 0, 0, 1, 1}, + {&__pyx_n_s_BaseException, __pyx_k_BaseException, sizeof(__pyx_k_BaseException), 0, 0, 1, 1}, + {&__pyx_n_s_CACHE_CONTROL, __pyx_k_CACHE_CONTROL, sizeof(__pyx_k_CACHE_CONTROL), 0, 0, 1, 1}, + {&__pyx_n_s_CIMultiDict, __pyx_k_CIMultiDict, sizeof(__pyx_k_CIMultiDict), 0, 0, 1, 1}, + {&__pyx_n_s_CIMultiDictProxy, __pyx_k_CIMultiDictProxy, sizeof(__pyx_k_CIMultiDictProxy), 0, 0, 1, 1}, + {&__pyx_n_s_CIMultiDictProxy_2, __pyx_k_CIMultiDictProxy_2, sizeof(__pyx_k_CIMultiDictProxy_2), 0, 0, 1, 1}, + {&__pyx_n_s_CIMultiDict_2, __pyx_k_CIMultiDict_2, sizeof(__pyx_k_CIMultiDict_2), 0, 0, 1, 1}, + {&__pyx_n_s_CONNECTION, __pyx_k_CONNECTION, sizeof(__pyx_k_CONNECTION), 0, 0, 1, 1}, + {&__pyx_n_s_CONTENT_DISPOSITION, __pyx_k_CONTENT_DISPOSITION, sizeof(__pyx_k_CONTENT_DISPOSITION), 0, 0, 1, 1}, + {&__pyx_n_s_CONTENT_ENCODING, __pyx_k_CONTENT_ENCODING, sizeof(__pyx_k_CONTENT_ENCODING), 0, 0, 1, 1}, + {&__pyx_n_s_CONTENT_LANGUAGE, __pyx_k_CONTENT_LANGUAGE, sizeof(__pyx_k_CONTENT_LANGUAGE), 0, 0, 1, 1}, + {&__pyx_n_s_CONTENT_LENGTH, __pyx_k_CONTENT_LENGTH, sizeof(__pyx_k_CONTENT_LENGTH), 0, 0, 1, 1}, + {&__pyx_n_s_CONTENT_LOCATION, __pyx_k_CONTENT_LOCATION, sizeof(__pyx_k_CONTENT_LOCATION), 0, 0, 1, 1}, + {&__pyx_n_s_CONTENT_MD5, __pyx_k_CONTENT_MD5, sizeof(__pyx_k_CONTENT_MD5), 0, 0, 1, 1}, + {&__pyx_n_s_CONTENT_RANGE, __pyx_k_CONTENT_RANGE, sizeof(__pyx_k_CONTENT_RANGE), 0, 0, 1, 1}, + {&__pyx_n_s_CONTENT_TRANSFER_ENCODING, __pyx_k_CONTENT_TRANSFER_ENCODING, sizeof(__pyx_k_CONTENT_TRANSFER_ENCODING), 0, 0, 1, 1}, + {&__pyx_n_s_CONTENT_TYPE, __pyx_k_CONTENT_TYPE, sizeof(__pyx_k_CONTENT_TYPE), 0, 0, 1, 1}, + {&__pyx_n_s_COOKIE, __pyx_k_COOKIE, sizeof(__pyx_k_COOKIE), 0, 0, 1, 1}, + {&__pyx_n_s_ContentLengthError, __pyx_k_ContentLengthError, sizeof(__pyx_k_ContentLengthError), 0, 0, 1, 1}, + {&__pyx_n_s_DATE, __pyx_k_DATE, sizeof(__pyx_k_DATE), 0, 0, 1, 1}, + {&__pyx_n_s_DESTINATION, __pyx_k_DESTINATION, sizeof(__pyx_k_DESTINATION), 0, 0, 1, 1}, + {&__pyx_n_s_DIGEST, __pyx_k_DIGEST, sizeof(__pyx_k_DIGEST), 0, 0, 1, 1}, + {&__pyx_n_s_DeflateBuffer, __pyx_k_DeflateBuffer, sizeof(__pyx_k_DeflateBuffer), 0, 0, 1, 1}, + {&__pyx_n_s_DeflateBuffer_2, __pyx_k_DeflateBuffer_2, sizeof(__pyx_k_DeflateBuffer_2), 0, 0, 1, 1}, + {&__pyx_n_s_EMPTY_PAYLOAD, __pyx_k_EMPTY_PAYLOAD, sizeof(__pyx_k_EMPTY_PAYLOAD), 0, 0, 1, 1}, + {&__pyx_n_s_EMPTY_PAYLOAD_2, __pyx_k_EMPTY_PAYLOAD_2, sizeof(__pyx_k_EMPTY_PAYLOAD_2), 0, 0, 1, 1}, + {&__pyx_n_s_ETAG, __pyx_k_ETAG, sizeof(__pyx_k_ETAG), 0, 0, 1, 1}, + {&__pyx_n_s_EXPECT, __pyx_k_EXPECT, sizeof(__pyx_k_EXPECT), 0, 0, 1, 1}, + {&__pyx_n_s_EXPIRES, __pyx_k_EXPIRES, sizeof(__pyx_k_EXPIRES), 0, 0, 1, 1}, + {&__pyx_n_s_FORWARDED, __pyx_k_FORWARDED, sizeof(__pyx_k_FORWARDED), 0, 0, 1, 1}, + {&__pyx_n_s_FROM, __pyx_k_FROM, sizeof(__pyx_k_FROM), 0, 0, 1, 1}, + {&__pyx_n_s_HOST, __pyx_k_HOST, sizeof(__pyx_k_HOST), 0, 0, 1, 1}, + {&__pyx_kp_u_Header_name_is_too_long, __pyx_k_Header_name_is_too_long, sizeof(__pyx_k_Header_name_is_too_long), 0, 1, 0, 0}, + {&__pyx_kp_u_Header_value_is_too_long, __pyx_k_Header_value_is_too_long, sizeof(__pyx_k_Header_value_is_too_long), 0, 1, 0, 0}, + {&__pyx_n_s_HttpRequestParser, __pyx_k_HttpRequestParser, sizeof(__pyx_k_HttpRequestParser), 0, 0, 1, 1}, + {&__pyx_n_u_HttpRequestParser, __pyx_k_HttpRequestParser, sizeof(__pyx_k_HttpRequestParser), 0, 1, 0, 1}, + {&__pyx_n_s_HttpResponseParser, __pyx_k_HttpResponseParser, sizeof(__pyx_k_HttpResponseParser), 0, 0, 1, 1}, + {&__pyx_n_u_HttpResponseParser, __pyx_k_HttpResponseParser, sizeof(__pyx_k_HttpResponseParser), 0, 1, 0, 1}, + {&__pyx_n_s_HttpVersion, __pyx_k_HttpVersion, sizeof(__pyx_k_HttpVersion), 0, 0, 1, 1}, + {&__pyx_n_s_HttpVersion10, __pyx_k_HttpVersion10, sizeof(__pyx_k_HttpVersion10), 0, 0, 1, 1}, + {&__pyx_n_s_HttpVersion10_2, __pyx_k_HttpVersion10_2, sizeof(__pyx_k_HttpVersion10_2), 0, 0, 1, 1}, + {&__pyx_n_s_HttpVersion11, __pyx_k_HttpVersion11, sizeof(__pyx_k_HttpVersion11), 0, 0, 1, 1}, + {&__pyx_n_s_HttpVersion11_2, __pyx_k_HttpVersion11_2, sizeof(__pyx_k_HttpVersion11_2), 0, 0, 1, 1}, + {&__pyx_n_s_HttpVersion_2, __pyx_k_HttpVersion_2, sizeof(__pyx_k_HttpVersion_2), 0, 0, 1, 1}, + {&__pyx_n_s_IF_MATCH, __pyx_k_IF_MATCH, sizeof(__pyx_k_IF_MATCH), 0, 0, 1, 1}, + {&__pyx_n_s_IF_MODIFIED_SINCE, __pyx_k_IF_MODIFIED_SINCE, sizeof(__pyx_k_IF_MODIFIED_SINCE), 0, 0, 1, 1}, + {&__pyx_n_s_IF_NONE_MATCH, __pyx_k_IF_NONE_MATCH, sizeof(__pyx_k_IF_NONE_MATCH), 0, 0, 1, 1}, + {&__pyx_n_s_IF_RANGE, __pyx_k_IF_RANGE, sizeof(__pyx_k_IF_RANGE), 0, 0, 1, 1}, + {&__pyx_n_s_IF_UNMODIFIED_SINCE, __pyx_k_IF_UNMODIFIED_SINCE, sizeof(__pyx_k_IF_UNMODIFIED_SINCE), 0, 0, 1, 1}, + {&__pyx_kp_s_Incompatible_checksums_s_vs_0x14, __pyx_k_Incompatible_checksums_s_vs_0x14, sizeof(__pyx_k_Incompatible_checksums_s_vs_0x14), 0, 0, 1, 0}, + {&__pyx_kp_s_Incompatible_checksums_s_vs_0xc7, __pyx_k_Incompatible_checksums_s_vs_0xc7, sizeof(__pyx_k_Incompatible_checksums_s_vs_0xc7), 0, 0, 1, 0}, + {&__pyx_n_s_InvalidHeader, __pyx_k_InvalidHeader, sizeof(__pyx_k_InvalidHeader), 0, 0, 1, 1}, + {&__pyx_n_s_InvalidURLError, __pyx_k_InvalidURLError, sizeof(__pyx_k_InvalidURLError), 0, 0, 1, 1}, + {&__pyx_n_s_KEEP_ALIVE, __pyx_k_KEEP_ALIVE, sizeof(__pyx_k_KEEP_ALIVE), 0, 0, 1, 1}, + {&__pyx_n_s_LAST_EVENT_ID, __pyx_k_LAST_EVENT_ID, sizeof(__pyx_k_LAST_EVENT_ID), 0, 0, 1, 1}, + {&__pyx_n_s_LAST_MODIFIED, __pyx_k_LAST_MODIFIED, sizeof(__pyx_k_LAST_MODIFIED), 0, 0, 1, 1}, + {&__pyx_n_s_LINK, __pyx_k_LINK, sizeof(__pyx_k_LINK), 0, 0, 1, 1}, + {&__pyx_n_s_LOCATION, __pyx_k_LOCATION, sizeof(__pyx_k_LOCATION), 0, 0, 1, 1}, + {&__pyx_n_s_LineTooLong, __pyx_k_LineTooLong, sizeof(__pyx_k_LineTooLong), 0, 0, 1, 1}, + {&__pyx_n_s_MAX_FORWARDS, __pyx_k_MAX_FORWARDS, sizeof(__pyx_k_MAX_FORWARDS), 0, 0, 1, 1}, + {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, + {&__pyx_kp_u_Not_enough_data_for_satisfy_cont, __pyx_k_Not_enough_data_for_satisfy_cont, sizeof(__pyx_k_Not_enough_data_for_satisfy_cont), 0, 1, 0, 0}, + {&__pyx_kp_u_Not_enough_data_for_satisfy_tran, __pyx_k_Not_enough_data_for_satisfy_tran, sizeof(__pyx_k_Not_enough_data_for_satisfy_tran), 0, 1, 0, 0}, + {&__pyx_n_s_ORIGIN, __pyx_k_ORIGIN, sizeof(__pyx_k_ORIGIN), 0, 0, 1, 1}, + {&__pyx_n_s_PRAGMA, __pyx_k_PRAGMA, sizeof(__pyx_k_PRAGMA), 0, 0, 1, 1}, + {&__pyx_n_s_PROXY_AUTHENTICATE, __pyx_k_PROXY_AUTHENTICATE, sizeof(__pyx_k_PROXY_AUTHENTICATE), 0, 0, 1, 1}, + {&__pyx_n_s_PROXY_AUTHORIZATION, __pyx_k_PROXY_AUTHORIZATION, sizeof(__pyx_k_PROXY_AUTHORIZATION), 0, 0, 1, 1}, + {&__pyx_n_s_PayloadEncodingError, __pyx_k_PayloadEncodingError, sizeof(__pyx_k_PayloadEncodingError), 0, 0, 1, 1}, + {&__pyx_n_s_PickleError, __pyx_k_PickleError, sizeof(__pyx_k_PickleError), 0, 0, 1, 1}, + {&__pyx_n_s_RANGE, __pyx_k_RANGE, sizeof(__pyx_k_RANGE), 0, 0, 1, 1}, + {&__pyx_n_s_REFERER, __pyx_k_REFERER, sizeof(__pyx_k_REFERER), 0, 0, 1, 1}, + {&__pyx_n_s_RETRY_AFTER, __pyx_k_RETRY_AFTER, sizeof(__pyx_k_RETRY_AFTER), 0, 0, 1, 1}, + {&__pyx_kp_u_RawRequestMessage, __pyx_k_RawRequestMessage, sizeof(__pyx_k_RawRequestMessage), 0, 1, 0, 0}, + {&__pyx_n_s_RawRequestMessage_2, __pyx_k_RawRequestMessage_2, sizeof(__pyx_k_RawRequestMessage_2), 0, 0, 1, 1}, + {&__pyx_n_u_RawRequestMessage_2, __pyx_k_RawRequestMessage_2, sizeof(__pyx_k_RawRequestMessage_2), 0, 1, 0, 1}, + {&__pyx_kp_u_RawResponseMessage, __pyx_k_RawResponseMessage, sizeof(__pyx_k_RawResponseMessage), 0, 1, 0, 0}, + {&__pyx_n_s_RawResponseMessage_2, __pyx_k_RawResponseMessage_2, sizeof(__pyx_k_RawResponseMessage_2), 0, 0, 1, 1}, + {&__pyx_n_u_RawResponseMessage_2, __pyx_k_RawResponseMessage_2, sizeof(__pyx_k_RawResponseMessage_2), 0, 1, 0, 1}, + {&__pyx_n_s_SEC_WEBSOCKET_ACCEPT, __pyx_k_SEC_WEBSOCKET_ACCEPT, sizeof(__pyx_k_SEC_WEBSOCKET_ACCEPT), 0, 0, 1, 1}, + {&__pyx_n_s_SEC_WEBSOCKET_EXTENSIONS, __pyx_k_SEC_WEBSOCKET_EXTENSIONS, sizeof(__pyx_k_SEC_WEBSOCKET_EXTENSIONS), 0, 0, 1, 1}, + {&__pyx_n_s_SEC_WEBSOCKET_KEY, __pyx_k_SEC_WEBSOCKET_KEY, sizeof(__pyx_k_SEC_WEBSOCKET_KEY), 0, 0, 1, 1}, + {&__pyx_n_s_SEC_WEBSOCKET_KEY1, __pyx_k_SEC_WEBSOCKET_KEY1, sizeof(__pyx_k_SEC_WEBSOCKET_KEY1), 0, 0, 1, 1}, + {&__pyx_n_s_SEC_WEBSOCKET_PROTOCOL, __pyx_k_SEC_WEBSOCKET_PROTOCOL, sizeof(__pyx_k_SEC_WEBSOCKET_PROTOCOL), 0, 0, 1, 1}, + {&__pyx_n_s_SEC_WEBSOCKET_VERSION, __pyx_k_SEC_WEBSOCKET_VERSION, sizeof(__pyx_k_SEC_WEBSOCKET_VERSION), 0, 0, 1, 1}, + {&__pyx_n_s_SERVER, __pyx_k_SERVER, sizeof(__pyx_k_SERVER), 0, 0, 1, 1}, + {&__pyx_n_s_SET_COOKIE, __pyx_k_SET_COOKIE, sizeof(__pyx_k_SET_COOKIE), 0, 0, 1, 1}, + {&__pyx_kp_u_Status_line_is_too_long, __pyx_k_Status_line_is_too_long, sizeof(__pyx_k_Status_line_is_too_long), 0, 1, 0, 0}, + {&__pyx_n_s_StreamReader, __pyx_k_StreamReader, sizeof(__pyx_k_StreamReader), 0, 0, 1, 1}, + {&__pyx_n_s_StreamReader_2, __pyx_k_StreamReader_2, sizeof(__pyx_k_StreamReader_2), 0, 0, 1, 1}, + {&__pyx_n_s_TE, __pyx_k_TE, sizeof(__pyx_k_TE), 0, 0, 1, 1}, + {&__pyx_n_s_TRAILER, __pyx_k_TRAILER, sizeof(__pyx_k_TRAILER), 0, 0, 1, 1}, + {&__pyx_n_s_TRANSFER_ENCODING, __pyx_k_TRANSFER_ENCODING, sizeof(__pyx_k_TRANSFER_ENCODING), 0, 0, 1, 1}, + {&__pyx_n_s_TransferEncodingError, __pyx_k_TransferEncodingError, sizeof(__pyx_k_TransferEncodingError), 0, 0, 1, 1}, + {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, + {&__pyx_n_s_UPGRADE, __pyx_k_UPGRADE, sizeof(__pyx_k_UPGRADE), 0, 0, 1, 1}, + {&__pyx_n_s_URI, __pyx_k_URI, sizeof(__pyx_k_URI), 0, 0, 1, 1}, + {&__pyx_n_s_URL, __pyx_k_URL, sizeof(__pyx_k_URL), 0, 0, 1, 1}, + {&__pyx_n_s_URL_2, __pyx_k_URL_2, sizeof(__pyx_k_URL_2), 0, 0, 1, 1}, + {&__pyx_n_s_USER_AGENT, __pyx_k_USER_AGENT, sizeof(__pyx_k_USER_AGENT), 0, 0, 1, 1}, + {&__pyx_n_s_VARY, __pyx_k_VARY, sizeof(__pyx_k_VARY), 0, 0, 1, 1}, + {&__pyx_n_s_VIA, __pyx_k_VIA, sizeof(__pyx_k_VIA), 0, 0, 1, 1}, + {&__pyx_n_s_WANT_DIGEST, __pyx_k_WANT_DIGEST, sizeof(__pyx_k_WANT_DIGEST), 0, 0, 1, 1}, + {&__pyx_n_s_WARNING, __pyx_k_WARNING, sizeof(__pyx_k_WARNING), 0, 0, 1, 1}, + {&__pyx_n_s_WWW_AUTHENTICATE, __pyx_k_WWW_AUTHENTICATE, sizeof(__pyx_k_WWW_AUTHENTICATE), 0, 0, 1, 1}, + {&__pyx_n_s_X_FORWARDED_FOR, __pyx_k_X_FORWARDED_FOR, sizeof(__pyx_k_X_FORWARDED_FOR), 0, 0, 1, 1}, + {&__pyx_n_s_X_FORWARDED_HOST, __pyx_k_X_FORWARDED_HOST, sizeof(__pyx_k_X_FORWARDED_HOST), 0, 0, 1, 1}, + {&__pyx_n_s_X_FORWARDED_PROTO, __pyx_k_X_FORWARDED_PROTO, sizeof(__pyx_k_X_FORWARDED_PROTO), 0, 0, 1, 1}, + {&__pyx_kp_u__11, __pyx_k__11, sizeof(__pyx_k__11), 0, 1, 0, 0}, + {&__pyx_kp_u__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 1, 0, 0}, + {&__pyx_kp_u__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 1, 0, 0}, + {&__pyx_n_s__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 0, 1, 1}, + {&__pyx_kp_b__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 0, 0, 0}, + {&__pyx_kp_u__4, __pyx_k__4, sizeof(__pyx_k__4), 0, 1, 0, 0}, + {&__pyx_n_s_add, __pyx_k_add, sizeof(__pyx_k_add), 0, 0, 1, 1}, + {&__pyx_n_s_aiohttp, __pyx_k_aiohttp, sizeof(__pyx_k_aiohttp), 0, 0, 1, 1}, + {&__pyx_n_s_aiohttp__http_parser, __pyx_k_aiohttp__http_parser, sizeof(__pyx_k_aiohttp__http_parser), 0, 0, 1, 1}, + {&__pyx_kp_s_aiohttp__http_parser_pyx, __pyx_k_aiohttp__http_parser_pyx, sizeof(__pyx_k_aiohttp__http_parser_pyx), 0, 0, 1, 0}, + {&__pyx_n_s_all, __pyx_k_all, sizeof(__pyx_k_all), 0, 0, 1, 1}, + {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1}, + {&__pyx_n_s_auto_decompress, __pyx_k_auto_decompress, sizeof(__pyx_k_auto_decompress), 0, 0, 1, 1}, + {&__pyx_n_s_begin_http_chunk_receiving, __pyx_k_begin_http_chunk_receiving, sizeof(__pyx_k_begin_http_chunk_receiving), 0, 0, 1, 1}, + {&__pyx_n_u_br, __pyx_k_br, sizeof(__pyx_k_br), 0, 1, 0, 1}, + {&__pyx_n_s_buf_data, __pyx_k_buf_data, sizeof(__pyx_k_buf_data), 0, 0, 1, 1}, + {&__pyx_n_s_build, __pyx_k_build, sizeof(__pyx_k_build), 0, 0, 1, 1}, + {&__pyx_n_s_chunked, __pyx_k_chunked, sizeof(__pyx_k_chunked), 0, 0, 1, 1}, + {&__pyx_n_u_chunked, __pyx_k_chunked, sizeof(__pyx_k_chunked), 0, 1, 0, 1}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1}, + {&__pyx_n_s_code, __pyx_k_code, sizeof(__pyx_k_code), 0, 0, 1, 1}, + {&__pyx_n_u_code, __pyx_k_code, sizeof(__pyx_k_code), 0, 1, 0, 1}, + {&__pyx_n_s_compression, __pyx_k_compression, sizeof(__pyx_k_compression), 0, 0, 1, 1}, + {&__pyx_n_u_compression, __pyx_k_compression, sizeof(__pyx_k_compression), 0, 1, 0, 1}, + {&__pyx_n_u_deflate, __pyx_k_deflate, sizeof(__pyx_k_deflate), 0, 1, 0, 1}, + {&__pyx_n_s_dict, __pyx_k_dict, sizeof(__pyx_k_dict), 0, 0, 1, 1}, + {&__pyx_n_s_encoded, __pyx_k_encoded, sizeof(__pyx_k_encoded), 0, 0, 1, 1}, + {&__pyx_n_s_end_http_chunk_receiving, __pyx_k_end_http_chunk_receiving, sizeof(__pyx_k_end_http_chunk_receiving), 0, 0, 1, 1}, + {&__pyx_n_s_feed_data, __pyx_k_feed_data, sizeof(__pyx_k_feed_data), 0, 0, 1, 1}, + {&__pyx_n_s_feed_eof, __pyx_k_feed_eof, sizeof(__pyx_k_feed_eof), 0, 0, 1, 1}, + {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, + {&__pyx_n_s_fragment, __pyx_k_fragment, sizeof(__pyx_k_fragment), 0, 0, 1, 1}, + {&__pyx_n_s_genexpr, __pyx_k_genexpr, sizeof(__pyx_k_genexpr), 0, 0, 1, 1}, + {&__pyx_n_s_getstate, __pyx_k_getstate, sizeof(__pyx_k_getstate), 0, 0, 1, 1}, + {&__pyx_n_u_gzip, __pyx_k_gzip, sizeof(__pyx_k_gzip), 0, 1, 0, 1}, + {&__pyx_n_s_hdrs, __pyx_k_hdrs, sizeof(__pyx_k_hdrs), 0, 0, 1, 1}, + {&__pyx_n_s_headers, __pyx_k_headers, sizeof(__pyx_k_headers), 0, 0, 1, 1}, + {&__pyx_n_u_headers, __pyx_k_headers, sizeof(__pyx_k_headers), 0, 1, 0, 1}, + {&__pyx_n_s_host, __pyx_k_host, sizeof(__pyx_k_host), 0, 0, 1, 1}, + {&__pyx_n_s_http_exceptions, __pyx_k_http_exceptions, sizeof(__pyx_k_http_exceptions), 0, 0, 1, 1}, + {&__pyx_n_s_http_parser, __pyx_k_http_parser, sizeof(__pyx_k_http_parser), 0, 0, 1, 1}, + {&__pyx_n_s_http_writer, __pyx_k_http_writer, sizeof(__pyx_k_http_writer), 0, 0, 1, 1}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_kp_u_invalid_url_r, __pyx_k_invalid_url_r, sizeof(__pyx_k_invalid_url_r), 0, 1, 0, 0}, + {&__pyx_n_s_limit, __pyx_k_limit, sizeof(__pyx_k_limit), 0, 0, 1, 1}, + {&__pyx_n_s_loop, __pyx_k_loop, sizeof(__pyx_k_loop), 0, 0, 1, 1}, + {&__pyx_n_s_lower, __pyx_k_lower, sizeof(__pyx_k_lower), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_max_field_size, __pyx_k_max_field_size, sizeof(__pyx_k_max_field_size), 0, 0, 1, 1}, + {&__pyx_n_s_max_headers, __pyx_k_max_headers, sizeof(__pyx_k_max_headers), 0, 0, 1, 1}, + {&__pyx_n_s_max_line_size, __pyx_k_max_line_size, sizeof(__pyx_k_max_line_size), 0, 0, 1, 1}, + {&__pyx_n_s_method, __pyx_k_method, sizeof(__pyx_k_method), 0, 0, 1, 1}, + {&__pyx_n_u_method, __pyx_k_method, sizeof(__pyx_k_method), 0, 1, 0, 1}, + {&__pyx_n_s_multidict, __pyx_k_multidict, sizeof(__pyx_k_multidict), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_new, __pyx_k_new, sizeof(__pyx_k_new), 0, 0, 1, 1}, + {&__pyx_kp_s_no_default___reduce___due_to_non, __pyx_k_no_default___reduce___due_to_non, sizeof(__pyx_k_no_default___reduce___due_to_non), 0, 0, 1, 0}, + {&__pyx_n_s_parse_url, __pyx_k_parse_url, sizeof(__pyx_k_parse_url), 0, 0, 1, 1}, + {&__pyx_n_s_partition, __pyx_k_partition, sizeof(__pyx_k_partition), 0, 0, 1, 1}, + {&__pyx_n_s_password, __pyx_k_password, sizeof(__pyx_k_password), 0, 0, 1, 1}, + {&__pyx_n_s_path, __pyx_k_path, sizeof(__pyx_k_path), 0, 0, 1, 1}, + {&__pyx_n_u_path, __pyx_k_path, sizeof(__pyx_k_path), 0, 1, 0, 1}, + {&__pyx_n_s_payload_exception, __pyx_k_payload_exception, sizeof(__pyx_k_payload_exception), 0, 0, 1, 1}, + {&__pyx_n_s_pickle, __pyx_k_pickle, sizeof(__pyx_k_pickle), 0, 0, 1, 1}, + {&__pyx_n_s_port, __pyx_k_port, sizeof(__pyx_k_port), 0, 0, 1, 1}, + {&__pyx_n_s_protocol, __pyx_k_protocol, sizeof(__pyx_k_protocol), 0, 0, 1, 1}, + {&__pyx_n_s_py_buf, __pyx_k_py_buf, sizeof(__pyx_k_py_buf), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_PickleError, __pyx_k_pyx_PickleError, sizeof(__pyx_k_pyx_PickleError), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_checksum, __pyx_k_pyx_checksum, sizeof(__pyx_k_pyx_checksum), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_result, __pyx_k_pyx_result, sizeof(__pyx_k_pyx_result), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_state, __pyx_k_pyx_state, sizeof(__pyx_k_pyx_state), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_type, __pyx_k_pyx_type, sizeof(__pyx_k_pyx_type), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_unpickle_RawRequestMessage, __pyx_k_pyx_unpickle_RawRequestMessage, sizeof(__pyx_k_pyx_unpickle_RawRequestMessage), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_unpickle_RawResponseMessag, __pyx_k_pyx_unpickle_RawResponseMessag, sizeof(__pyx_k_pyx_unpickle_RawResponseMessag), 0, 0, 1, 1}, + {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1}, + {&__pyx_n_s_query_string, __pyx_k_query_string, sizeof(__pyx_k_query_string), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_raw_headers, __pyx_k_raw_headers, sizeof(__pyx_k_raw_headers), 0, 0, 1, 1}, + {&__pyx_n_u_raw_headers, __pyx_k_raw_headers, sizeof(__pyx_k_raw_headers), 0, 1, 0, 1}, + {&__pyx_n_s_read_until_eof, __pyx_k_read_until_eof, sizeof(__pyx_k_read_until_eof), 0, 0, 1, 1}, + {&__pyx_n_s_reason, __pyx_k_reason, sizeof(__pyx_k_reason), 0, 0, 1, 1}, + {&__pyx_n_u_reason, __pyx_k_reason, sizeof(__pyx_k_reason), 0, 1, 0, 1}, + {&__pyx_n_s_reduce, __pyx_k_reduce, sizeof(__pyx_k_reduce), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_cython, __pyx_k_reduce_cython, sizeof(__pyx_k_reduce_cython), 0, 0, 1, 1}, + {&__pyx_n_s_reduce_ex, __pyx_k_reduce_ex, sizeof(__pyx_k_reduce_ex), 0, 0, 1, 1}, + {&__pyx_n_s_repr___locals_genexpr, __pyx_k_repr___locals_genexpr, sizeof(__pyx_k_repr___locals_genexpr), 0, 0, 1, 1}, + {&__pyx_n_s_response_with_body, __pyx_k_response_with_body, sizeof(__pyx_k_response_with_body), 0, 0, 1, 1}, + {&__pyx_n_s_scheme, __pyx_k_scheme, sizeof(__pyx_k_scheme), 0, 0, 1, 1}, + {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1}, + {&__pyx_n_s_set_exception, __pyx_k_set_exception, sizeof(__pyx_k_set_exception), 0, 0, 1, 1}, + {&__pyx_n_s_setstate, __pyx_k_setstate, sizeof(__pyx_k_setstate), 0, 0, 1, 1}, + {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1}, + {&__pyx_n_s_should_close, __pyx_k_should_close, sizeof(__pyx_k_should_close), 0, 0, 1, 1}, + {&__pyx_n_u_should_close, __pyx_k_should_close, sizeof(__pyx_k_should_close), 0, 1, 0, 1}, + {&__pyx_n_s_streams, __pyx_k_streams, sizeof(__pyx_k_streams), 0, 0, 1, 1}, + {&__pyx_kp_s_stringsource, __pyx_k_stringsource, sizeof(__pyx_k_stringsource), 0, 0, 1, 0}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1}, + {&__pyx_n_s_timer, __pyx_k_timer, sizeof(__pyx_k_timer), 0, 0, 1, 1}, + {&__pyx_kp_u_unknown, __pyx_k_unknown, sizeof(__pyx_k_unknown), 0, 1, 0, 0}, + {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1}, + {&__pyx_n_s_upgrade, __pyx_k_upgrade, sizeof(__pyx_k_upgrade), 0, 0, 1, 1}, + {&__pyx_n_u_upgrade, __pyx_k_upgrade, sizeof(__pyx_k_upgrade), 0, 1, 0, 1}, + {&__pyx_n_s_url, __pyx_k_url, sizeof(__pyx_k_url), 0, 0, 1, 1}, + {&__pyx_n_u_url, __pyx_k_url, sizeof(__pyx_k_url), 0, 1, 0, 1}, + {&__pyx_n_s_user, __pyx_k_user, sizeof(__pyx_k_user), 0, 0, 1, 1}, + {&__pyx_n_s_version, __pyx_k_version, sizeof(__pyx_k_version), 0, 0, 1, 1}, + {&__pyx_n_u_version, __pyx_k_version, sizeof(__pyx_k_version), 0, 1, 0, 1}, + {&__pyx_n_s_yarl, __pyx_k_yarl, sizeof(__pyx_k_yarl), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 87, __pyx_L1_error) + __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) __PYX_ERR(0, 316, __pyx_L1_error) + __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(1, 2, __pyx_L1_error) + __pyx_builtin_BaseException = __Pyx_GetBuiltinName(__pyx_n_s_BaseException); if (!__pyx_builtin_BaseException) __PYX_ERR(0, 631, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(1, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__5); + __Pyx_GIVEREF(__pyx_tuple__5); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__6); + __Pyx_GIVEREF(__pyx_tuple__6); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(1, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__7); + __Pyx_GIVEREF(__pyx_tuple__7); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__8)) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__8); + __Pyx_GIVEREF(__pyx_tuple__8); + + /* "(tree fragment)":2 + * def __reduce_cython__(self): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + */ + __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__9)) __PYX_ERR(1, 2, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__9); + __Pyx_GIVEREF(__pyx_tuple__9); + + /* "(tree fragment)":4 + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") + * def __setstate_cython__(self, __pyx_state): + * raise TypeError("no default __reduce__ due to non-trivial __cinit__") # <<<<<<<<<<<<<< + */ + __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(1, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__10); + __Pyx_GIVEREF(__pyx_tuple__10); + + /* "aiohttp/_http_parser.pyx":57 + * char* PyByteArray_AsString(object) + * + * __all__ = ('HttpRequestParser', 'HttpResponseParser', # <<<<<<<<<<<<<< + * 'RawRequestMessage', 'RawResponseMessage') + * + */ + __pyx_tuple__12 = PyTuple_Pack(4, __pyx_n_u_HttpRequestParser, __pyx_n_u_HttpResponseParser, __pyx_n_u_RawRequestMessage_2, __pyx_n_u_RawResponseMessage_2); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__12); + __Pyx_GIVEREF(__pyx_tuple__12); + + /* "aiohttp/_http_parser.pyx":785 + * + * + * def parse_url(url): # <<<<<<<<<<<<<< + * cdef: + * Py_buffer py_buf + */ + __pyx_tuple__13 = PyTuple_Pack(3, __pyx_n_s_url, __pyx_n_s_py_buf, __pyx_n_s_buf_data); if (unlikely(!__pyx_tuple__13)) __PYX_ERR(0, 785, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__13); + __Pyx_GIVEREF(__pyx_tuple__13); + __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_aiohttp__http_parser_pyx, __pyx_n_s_parse_url, 785, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 785, __pyx_L1_error) + + /* "(tree fragment)":1 + * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + __pyx_tuple__15 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__15); + __Pyx_GIVEREF(__pyx_tuple__15); + __pyx_codeobj__16 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_RawRequestMessage, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__16)) __PYX_ERR(1, 1, __pyx_L1_error) + __pyx_tuple__17 = PyTuple_Pack(5, __pyx_n_s_pyx_type, __pyx_n_s_pyx_checksum, __pyx_n_s_pyx_state, __pyx_n_s_pyx_PickleError, __pyx_n_s_pyx_result); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple__17); + __Pyx_GIVEREF(__pyx_tuple__17); + __pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(3, 0, 5, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_stringsource, __pyx_n_s_pyx_unpickle_RawResponseMessag, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + __pyx_umethod_PyUnicode_Type_partition.type = (PyObject*)&PyUnicode_Type; + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + __pyx_int_21004882 = PyInt_FromLong(21004882L); if (unlikely(!__pyx_int_21004882)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_int_209127132 = PyInt_FromLong(209127132L); if (unlikely(!__pyx_int_209127132)) __PYX_ERR(0, 1, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __pyx_v_7aiohttp_12_http_parser_headers = ((PyObject*)Py_None); Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_URL = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_URL_build = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_CIMultiDict = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_HttpVersion = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_HttpVersion10 = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_HttpVersion11 = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1 = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_StreamReader = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser_DeflateBuffer = Py_None; Py_INCREF(Py_None); + __pyx_v_7aiohttp_12_http_parser__http_method = ((PyObject*)Py_None); Py_INCREF(Py_None); + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_RawRequestMessage) < 0) __PYX_ERR(0, 110, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_12_http_parser_RawRequestMessage.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_RawRequestMessage_2, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_RawRequestMessage) < 0) __PYX_ERR(0, 110, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_RawRequestMessage) < 0) __PYX_ERR(0, 110, __pyx_L1_error) + __pyx_ptype_7aiohttp_12_http_parser_RawRequestMessage = &__pyx_type_7aiohttp_12_http_parser_RawRequestMessage; + if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 210, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_12_http_parser_RawResponseMessage.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_RawResponseMessage_2, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 210, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_RawResponseMessage) < 0) __PYX_ERR(0, 210, __pyx_L1_error) + __pyx_ptype_7aiohttp_12_http_parser_RawResponseMessage = &__pyx_type_7aiohttp_12_http_parser_RawResponseMessage; + __pyx_vtabptr_7aiohttp_12_http_parser_HttpParser = &__pyx_vtable_7aiohttp_12_http_parser_HttpParser; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser._init = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, enum http_parser_type, PyObject *, PyObject *, int, struct __pyx_opt_args_7aiohttp_12_http_parser_10HttpParser__init *__pyx_optional_args))__pyx_f_7aiohttp_12_http_parser_10HttpParser__init; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser._process_header = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__process_header; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_header_field = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, char *, size_t))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_field; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_header_value = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *, char *, size_t))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_header_value; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_headers_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_headers_complete; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_message_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_message_complete; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_chunk_header = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_header; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_chunk_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_chunk_complete; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser._on_status_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser__on_status_complete; + __pyx_vtable_7aiohttp_12_http_parser_HttpParser.http_version = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_10HttpParser_http_version; + if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_HttpParser) < 0) __PYX_ERR(0, 272, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_12_http_parser_HttpParser.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_HttpParser.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_HttpParser.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_12_http_parser_HttpParser.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + if (__Pyx_SetVtable(__pyx_type_7aiohttp_12_http_parser_HttpParser.tp_dict, __pyx_vtabptr_7aiohttp_12_http_parser_HttpParser) < 0) __PYX_ERR(0, 272, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_HttpParser) < 0) __PYX_ERR(0, 272, __pyx_L1_error) + __pyx_ptype_7aiohttp_12_http_parser_HttpParser = &__pyx_type_7aiohttp_12_http_parser_HttpParser; + __pyx_vtabptr_7aiohttp_12_http_parser_HttpRequestParser = &__pyx_vtable_7aiohttp_12_http_parser_HttpRequestParser; + __pyx_vtable_7aiohttp_12_http_parser_HttpRequestParser.__pyx_base = *__pyx_vtabptr_7aiohttp_12_http_parser_HttpParser; + __pyx_vtable_7aiohttp_12_http_parser_HttpRequestParser.__pyx_base._on_status_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_17HttpRequestParser__on_status_complete; + __pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_base = __pyx_ptype_7aiohttp_12_http_parser_HttpParser; + if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 563, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + if (__Pyx_SetVtable(__pyx_type_7aiohttp_12_http_parser_HttpRequestParser.tp_dict, __pyx_vtabptr_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 563, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_HttpRequestParser, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 563, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_HttpRequestParser) < 0) __PYX_ERR(0, 563, __pyx_L1_error) + __pyx_ptype_7aiohttp_12_http_parser_HttpRequestParser = &__pyx_type_7aiohttp_12_http_parser_HttpRequestParser; + __pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser = &__pyx_vtable_7aiohttp_12_http_parser_HttpResponseParser; + __pyx_vtable_7aiohttp_12_http_parser_HttpResponseParser.__pyx_base = *__pyx_vtabptr_7aiohttp_12_http_parser_HttpParser; + __pyx_vtable_7aiohttp_12_http_parser_HttpResponseParser.__pyx_base._on_status_complete = (PyObject *(*)(struct __pyx_obj_7aiohttp_12_http_parser_HttpParser *))__pyx_f_7aiohttp_12_http_parser_18HttpResponseParser__on_status_complete; + __pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_base = __pyx_ptype_7aiohttp_12_http_parser_HttpParser; + if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 591, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_getattro = __Pyx_PyObject_GenericGetAttr; + } + if (__Pyx_SetVtable(__pyx_type_7aiohttp_12_http_parser_HttpResponseParser.tp_dict, __pyx_vtabptr_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 591, __pyx_L1_error) + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_HttpResponseParser, (PyObject *)&__pyx_type_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 591, __pyx_L1_error) + if (__Pyx_setup_reduce((PyObject*)&__pyx_type_7aiohttp_12_http_parser_HttpResponseParser) < 0) __PYX_ERR(0, 591, __pyx_L1_error) + __pyx_ptype_7aiohttp_12_http_parser_HttpResponseParser = &__pyx_type_7aiohttp_12_http_parser_HttpResponseParser; + if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__) < 0) __PYX_ERR(0, 135, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + __pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct____repr__ = &__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct____repr__; + if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr) < 0) __PYX_ERR(0, 147, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + __pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr = &__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_1_genexpr; + if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__) < 0) __PYX_ERR(0, 233, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + __pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__ = &__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_2___repr__; + if (PyType_Ready(&__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr) < 0) __PYX_ERR(0, 244, __pyx_L1_error) + #if PY_VERSION_HEX < 0x030800B1 + __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr.tp_print = 0; + #endif + if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr.tp_dictoffset && __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr.tp_getattro == PyObject_GenericGetAttr)) { + __pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + } + __pyx_ptype_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr = &__pyx_type_7aiohttp_12_http_parser___pyx_scope_struct_3_genexpr; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", + #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 + sizeof(PyTypeObject), + #else + sizeof(PyHeapTypeObject), + #endif + __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(2, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4bool_bool) __PYX_ERR(3, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(4, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_7complex_complex) __PYX_ERR(4, 15, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC init_http_parser(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC init_http_parser(void) +#else +__Pyx_PyMODINIT_FUNC PyInit__http_parser(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit__http_parser(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec__http_parser(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + PyObject *__pyx_t_14 = NULL; + PyObject *__pyx_t_15 = NULL; + PyObject *__pyx_t_16 = NULL; + PyObject *__pyx_t_17 = NULL; + PyObject *__pyx_t_18 = NULL; + PyObject *__pyx_t_19 = NULL; + PyObject *__pyx_t_20 = NULL; + PyObject *__pyx_t_21 = NULL; + PyObject *__pyx_t_22 = NULL; + PyObject *__pyx_t_23 = NULL; + PyObject *__pyx_t_24 = NULL; + PyObject *__pyx_t_25 = NULL; + PyObject *__pyx_t_26 = NULL; + PyObject *__pyx_t_27 = NULL; + PyObject *__pyx_t_28 = NULL; + PyObject *__pyx_t_29 = NULL; + PyObject *__pyx_t_30 = NULL; + PyObject *__pyx_t_31 = NULL; + PyObject *__pyx_t_32 = NULL; + PyObject *__pyx_t_33 = NULL; + PyObject *__pyx_t_34 = NULL; + PyObject *__pyx_t_35 = NULL; + PyObject *__pyx_t_36 = NULL; + PyObject *__pyx_t_37 = NULL; + PyObject *__pyx_t_38 = NULL; + PyObject *__pyx_t_39 = NULL; + PyObject *__pyx_t_40 = NULL; + PyObject *__pyx_t_41 = NULL; + PyObject *__pyx_t_42 = NULL; + PyObject *__pyx_t_43 = NULL; + PyObject *__pyx_t_44 = NULL; + PyObject *__pyx_t_45 = NULL; + PyObject *__pyx_t_46 = NULL; + PyObject *__pyx_t_47 = NULL; + PyObject *__pyx_t_48 = NULL; + PyObject *__pyx_t_49 = NULL; + PyObject *__pyx_t_50 = NULL; + PyObject *__pyx_t_51 = NULL; + PyObject *__pyx_t_52 = NULL; + PyObject *__pyx_t_53 = NULL; + PyObject *__pyx_t_54 = NULL; + PyObject *__pyx_t_55 = NULL; + PyObject *__pyx_t_56 = NULL; + PyObject *__pyx_t_57 = NULL; + PyObject *__pyx_t_58 = NULL; + PyObject *__pyx_t_59 = NULL; + PyObject *__pyx_t_60 = NULL; + PyObject *__pyx_t_61 = NULL; + PyObject *__pyx_t_62 = NULL; + PyObject *__pyx_t_63 = NULL; + PyObject *__pyx_t_64 = NULL; + PyObject *__pyx_t_65 = NULL; + PyObject *__pyx_t_66 = NULL; + PyObject *__pyx_t_67 = NULL; + PyObject *__pyx_t_68 = NULL; + PyObject *__pyx_t_69 = NULL; + PyObject *__pyx_t_70 = NULL; + PyObject *__pyx_t_71 = NULL; + PyObject *__pyx_t_72 = NULL; + PyObject *__pyx_t_73 = NULL; + PyObject *__pyx_t_74 = NULL; + PyObject *__pyx_t_75 = NULL; + PyObject *__pyx_t_76 = NULL; + PyObject *__pyx_t_77 = NULL; + PyObject *__pyx_t_78 = NULL; + long __pyx_t_79; + enum http_method __pyx_t_80; + char const *__pyx_t_81; + int __pyx_t_82; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_http_parser' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__http_parser(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("_http_parser", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_b); + __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_cython_runtime); + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_aiohttp___http_parser) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "aiohttp._http_parser")) { + if (unlikely(PyDict_SetItemString(modules, "aiohttp._http_parser", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + if (unlikely(__Pyx_modinit_type_init_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "aiohttp/_http_parser.pyx":19 + * from libc.string cimport memcpy + * + * from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiDictProxy # <<<<<<<<<<<<<< + * from yarl import URL as _URL + * + */ + __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_s_CIMultiDict); + __Pyx_GIVEREF(__pyx_n_s_CIMultiDict); + PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_CIMultiDict); + __Pyx_INCREF(__pyx_n_s_CIMultiDictProxy); + __Pyx_GIVEREF(__pyx_n_s_CIMultiDictProxy); + PyList_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_CIMultiDictProxy); + __pyx_t_2 = __Pyx_Import(__pyx_n_s_multidict, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_CIMultiDict); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_CIMultiDict_2, __pyx_t_1) < 0) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_CIMultiDictProxy); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_CIMultiDictProxy_2, __pyx_t_1) < 0) __PYX_ERR(0, 19, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":20 + * + * from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiDictProxy + * from yarl import URL as _URL # <<<<<<<<<<<<<< + * + * from aiohttp import hdrs + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 20, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_URL); + __Pyx_GIVEREF(__pyx_n_s_URL); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_URL); + __pyx_t_1 = __Pyx_Import(__pyx_n_s_yarl, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 20, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_URL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 20, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_URL_2, __pyx_t_2) < 0) __PYX_ERR(0, 20, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":22 + * from yarl import URL as _URL + * + * from aiohttp import hdrs # <<<<<<<<<<<<<< + * + * from .http_exceptions import ( + */ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_s_hdrs); + __Pyx_GIVEREF(__pyx_n_s_hdrs); + PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_hdrs); + __pyx_t_2 = __Pyx_Import(__pyx_n_s_aiohttp, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_hdrs, __pyx_t_1) < 0) __PYX_ERR(0, 22, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":25 + * + * from .http_exceptions import ( + * BadHttpMessage, # <<<<<<<<<<<<<< + * BadStatusLine, + * ContentLengthError, + */ + __pyx_t_2 = PyList_New(8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_BadHttpMessage); + __Pyx_GIVEREF(__pyx_n_s_BadHttpMessage); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_BadHttpMessage); + __Pyx_INCREF(__pyx_n_s_BadStatusLine); + __Pyx_GIVEREF(__pyx_n_s_BadStatusLine); + PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_BadStatusLine); + __Pyx_INCREF(__pyx_n_s_ContentLengthError); + __Pyx_GIVEREF(__pyx_n_s_ContentLengthError); + PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_ContentLengthError); + __Pyx_INCREF(__pyx_n_s_InvalidHeader); + __Pyx_GIVEREF(__pyx_n_s_InvalidHeader); + PyList_SET_ITEM(__pyx_t_2, 3, __pyx_n_s_InvalidHeader); + __Pyx_INCREF(__pyx_n_s_InvalidURLError); + __Pyx_GIVEREF(__pyx_n_s_InvalidURLError); + PyList_SET_ITEM(__pyx_t_2, 4, __pyx_n_s_InvalidURLError); + __Pyx_INCREF(__pyx_n_s_LineTooLong); + __Pyx_GIVEREF(__pyx_n_s_LineTooLong); + PyList_SET_ITEM(__pyx_t_2, 5, __pyx_n_s_LineTooLong); + __Pyx_INCREF(__pyx_n_s_PayloadEncodingError); + __Pyx_GIVEREF(__pyx_n_s_PayloadEncodingError); + PyList_SET_ITEM(__pyx_t_2, 6, __pyx_n_s_PayloadEncodingError); + __Pyx_INCREF(__pyx_n_s_TransferEncodingError); + __Pyx_GIVEREF(__pyx_n_s_TransferEncodingError); + PyList_SET_ITEM(__pyx_t_2, 7, __pyx_n_s_TransferEncodingError); + + /* "aiohttp/_http_parser.pyx":24 + * from aiohttp import hdrs + * + * from .http_exceptions import ( # <<<<<<<<<<<<<< + * BadHttpMessage, + * BadStatusLine, + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_http_exceptions, __pyx_t_2, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_BadHttpMessage); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_BadHttpMessage, __pyx_t_2) < 0) __PYX_ERR(0, 25, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_BadStatusLine); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_BadStatusLine, __pyx_t_2) < 0) __PYX_ERR(0, 26, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_ContentLengthError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_ContentLengthError, __pyx_t_2) < 0) __PYX_ERR(0, 27, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_InvalidHeader); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_InvalidHeader, __pyx_t_2) < 0) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_InvalidURLError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_InvalidURLError, __pyx_t_2) < 0) __PYX_ERR(0, 29, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_LineTooLong); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_LineTooLong, __pyx_t_2) < 0) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_PayloadEncodingError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_PayloadEncodingError, __pyx_t_2) < 0) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_TransferEncodingError); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_TransferEncodingError, __pyx_t_2) < 0) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":34 + * TransferEncodingError, + * ) + * from .http_parser import DeflateBuffer as _DeflateBuffer # <<<<<<<<<<<<<< + * from .http_writer import ( + * HttpVersion as _HttpVersion, + */ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_s_DeflateBuffer); + __Pyx_GIVEREF(__pyx_n_s_DeflateBuffer); + PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_DeflateBuffer); + __pyx_t_2 = __Pyx_Import(__pyx_n_s_http_parser, __pyx_t_1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_DeflateBuffer); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_DeflateBuffer_2, __pyx_t_1) < 0) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_parser.pyx":36 + * from .http_parser import DeflateBuffer as _DeflateBuffer + * from .http_writer import ( + * HttpVersion as _HttpVersion, # <<<<<<<<<<<<<< + * HttpVersion10 as _HttpVersion10, + * HttpVersion11 as _HttpVersion11, + */ + __pyx_t_2 = PyList_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_HttpVersion); + __Pyx_GIVEREF(__pyx_n_s_HttpVersion); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_HttpVersion); + __Pyx_INCREF(__pyx_n_s_HttpVersion10); + __Pyx_GIVEREF(__pyx_n_s_HttpVersion10); + PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_HttpVersion10); + __Pyx_INCREF(__pyx_n_s_HttpVersion11); + __Pyx_GIVEREF(__pyx_n_s_HttpVersion11); + PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_HttpVersion11); + + /* "aiohttp/_http_parser.pyx":35 + * ) + * from .http_parser import DeflateBuffer as _DeflateBuffer + * from .http_writer import ( # <<<<<<<<<<<<<< + * HttpVersion as _HttpVersion, + * HttpVersion10 as _HttpVersion10, + */ + __pyx_t_1 = __Pyx_Import(__pyx_n_s_http_writer, __pyx_t_2, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_HttpVersion); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_HttpVersion_2, __pyx_t_2) < 0) __PYX_ERR(0, 36, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_HttpVersion10); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_HttpVersion10_2, __pyx_t_2) < 0) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_HttpVersion11); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_HttpVersion11_2, __pyx_t_2) < 0) __PYX_ERR(0, 38, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":40 + * HttpVersion11 as _HttpVersion11, + * ) + * from .streams import EMPTY_PAYLOAD as _EMPTY_PAYLOAD, StreamReader as _StreamReader # <<<<<<<<<<<<<< + * + * cimport cython + */ + __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_s_EMPTY_PAYLOAD); + __Pyx_GIVEREF(__pyx_n_s_EMPTY_PAYLOAD); + PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_EMPTY_PAYLOAD); + __Pyx_INCREF(__pyx_n_s_StreamReader); + __Pyx_GIVEREF(__pyx_n_s_StreamReader); + PyList_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_StreamReader); + __pyx_t_2 = __Pyx_Import(__pyx_n_s_streams, __pyx_t_1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_EMPTY_PAYLOAD); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_EMPTY_PAYLOAD_2, __pyx_t_1) < 0) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_StreamReader); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_StreamReader_2, __pyx_t_1) < 0) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_headers.pxi":4 + * # Run ./tools/gen.py to update it after the origin changing. + * + * from . import hdrs # <<<<<<<<<<<<<< + * cdef tuple headers = ( + * hdrs.ACCEPT, + */ + __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_INCREF(__pyx_n_s_hdrs); + __Pyx_GIVEREF(__pyx_n_s_hdrs); + PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_hdrs); + __pyx_t_1 = __Pyx_Import(__pyx_n_s__4, __pyx_t_2, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 4, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_hdrs, __pyx_t_2) < 0) __PYX_ERR(5, 4, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":6 + * from . import hdrs + * cdef tuple headers = ( + * hdrs.ACCEPT, # <<<<<<<<<<<<<< + * hdrs.ACCEPT_CHARSET, + * hdrs.ACCEPT_ENCODING, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT); if (unlikely(!__pyx_t_2)) __PYX_ERR(5, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":7 + * cdef tuple headers = ( + * hdrs.ACCEPT, + * hdrs.ACCEPT_CHARSET, # <<<<<<<<<<<<<< + * hdrs.ACCEPT_ENCODING, + * hdrs.ACCEPT_LANGUAGE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_CHARSET); if (unlikely(!__pyx_t_3)) __PYX_ERR(5, 7, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":8 + * hdrs.ACCEPT, + * hdrs.ACCEPT_CHARSET, + * hdrs.ACCEPT_ENCODING, # <<<<<<<<<<<<<< + * hdrs.ACCEPT_LANGUAGE, + * hdrs.ACCEPT_RANGES, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_ENCODING); if (unlikely(!__pyx_t_4)) __PYX_ERR(5, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":9 + * hdrs.ACCEPT_CHARSET, + * hdrs.ACCEPT_ENCODING, + * hdrs.ACCEPT_LANGUAGE, # <<<<<<<<<<<<<< + * hdrs.ACCEPT_RANGES, + * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_LANGUAGE); if (unlikely(!__pyx_t_5)) __PYX_ERR(5, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":10 + * hdrs.ACCEPT_ENCODING, + * hdrs.ACCEPT_LANGUAGE, + * hdrs.ACCEPT_RANGES, # <<<<<<<<<<<<<< + * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, + * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 10, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCEPT_RANGES); if (unlikely(!__pyx_t_6)) __PYX_ERR(5, 10, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":11 + * hdrs.ACCEPT_LANGUAGE, + * hdrs.ACCEPT_RANGES, + * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, # <<<<<<<<<<<<<< + * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, + * hdrs.ACCESS_CONTROL_ALLOW_METHODS, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 11, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_CREDENTIALS); if (unlikely(!__pyx_t_7)) __PYX_ERR(5, 11, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":12 + * hdrs.ACCEPT_RANGES, + * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, + * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, # <<<<<<<<<<<<<< + * hdrs.ACCESS_CONTROL_ALLOW_METHODS, + * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_HEADERS); if (unlikely(!__pyx_t_8)) __PYX_ERR(5, 12, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":13 + * hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, + * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, + * hdrs.ACCESS_CONTROL_ALLOW_METHODS, # <<<<<<<<<<<<<< + * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, + * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_METHODS); if (unlikely(!__pyx_t_9)) __PYX_ERR(5, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":14 + * hdrs.ACCESS_CONTROL_ALLOW_HEADERS, + * hdrs.ACCESS_CONTROL_ALLOW_METHODS, + * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, # <<<<<<<<<<<<<< + * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, + * hdrs.ACCESS_CONTROL_MAX_AGE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_ALLOW_ORIGIN); if (unlikely(!__pyx_t_10)) __PYX_ERR(5, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":15 + * hdrs.ACCESS_CONTROL_ALLOW_METHODS, + * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, + * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, # <<<<<<<<<<<<<< + * hdrs.ACCESS_CONTROL_MAX_AGE, + * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_EXPOSE_HEADERS); if (unlikely(!__pyx_t_11)) __PYX_ERR(5, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":16 + * hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, + * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, + * hdrs.ACCESS_CONTROL_MAX_AGE, # <<<<<<<<<<<<<< + * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, + * hdrs.ACCESS_CONTROL_REQUEST_METHOD, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 16, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_MAX_AGE); if (unlikely(!__pyx_t_12)) __PYX_ERR(5, 16, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_12); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":17 + * hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, + * hdrs.ACCESS_CONTROL_MAX_AGE, + * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, # <<<<<<<<<<<<<< + * hdrs.ACCESS_CONTROL_REQUEST_METHOD, + * hdrs.AGE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_REQUEST_HEADERS); if (unlikely(!__pyx_t_13)) __PYX_ERR(5, 17, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_13); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":18 + * hdrs.ACCESS_CONTROL_MAX_AGE, + * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, + * hdrs.ACCESS_CONTROL_REQUEST_METHOD, # <<<<<<<<<<<<<< + * hdrs.AGE, + * hdrs.ALLOW, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 18, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ACCESS_CONTROL_REQUEST_METHOD); if (unlikely(!__pyx_t_14)) __PYX_ERR(5, 18, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_14); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":19 + * hdrs.ACCESS_CONTROL_REQUEST_HEADERS, + * hdrs.ACCESS_CONTROL_REQUEST_METHOD, + * hdrs.AGE, # <<<<<<<<<<<<<< + * hdrs.ALLOW, + * hdrs.AUTHORIZATION, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_15 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_AGE); if (unlikely(!__pyx_t_15)) __PYX_ERR(5, 19, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_15); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":20 + * hdrs.ACCESS_CONTROL_REQUEST_METHOD, + * hdrs.AGE, + * hdrs.ALLOW, # <<<<<<<<<<<<<< + * hdrs.AUTHORIZATION, + * hdrs.CACHE_CONTROL, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 20, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ALLOW); if (unlikely(!__pyx_t_16)) __PYX_ERR(5, 20, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_16); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":21 + * hdrs.AGE, + * hdrs.ALLOW, + * hdrs.AUTHORIZATION, # <<<<<<<<<<<<<< + * hdrs.CACHE_CONTROL, + * hdrs.CONNECTION, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_AUTHORIZATION); if (unlikely(!__pyx_t_17)) __PYX_ERR(5, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_17); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":22 + * hdrs.ALLOW, + * hdrs.AUTHORIZATION, + * hdrs.CACHE_CONTROL, # <<<<<<<<<<<<<< + * hdrs.CONNECTION, + * hdrs.CONTENT_DISPOSITION, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 22, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_18 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CACHE_CONTROL); if (unlikely(!__pyx_t_18)) __PYX_ERR(5, 22, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_18); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":23 + * hdrs.AUTHORIZATION, + * hdrs.CACHE_CONTROL, + * hdrs.CONNECTION, # <<<<<<<<<<<<<< + * hdrs.CONTENT_DISPOSITION, + * hdrs.CONTENT_ENCODING, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 23, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_19 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONNECTION); if (unlikely(!__pyx_t_19)) __PYX_ERR(5, 23, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_19); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":24 + * hdrs.CACHE_CONTROL, + * hdrs.CONNECTION, + * hdrs.CONTENT_DISPOSITION, # <<<<<<<<<<<<<< + * hdrs.CONTENT_ENCODING, + * hdrs.CONTENT_LANGUAGE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_20 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_DISPOSITION); if (unlikely(!__pyx_t_20)) __PYX_ERR(5, 24, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_20); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":25 + * hdrs.CONNECTION, + * hdrs.CONTENT_DISPOSITION, + * hdrs.CONTENT_ENCODING, # <<<<<<<<<<<<<< + * hdrs.CONTENT_LANGUAGE, + * hdrs.CONTENT_LENGTH, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_21 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_ENCODING); if (unlikely(!__pyx_t_21)) __PYX_ERR(5, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_21); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":26 + * hdrs.CONTENT_DISPOSITION, + * hdrs.CONTENT_ENCODING, + * hdrs.CONTENT_LANGUAGE, # <<<<<<<<<<<<<< + * hdrs.CONTENT_LENGTH, + * hdrs.CONTENT_LOCATION, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 26, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_22 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_LANGUAGE); if (unlikely(!__pyx_t_22)) __PYX_ERR(5, 26, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_22); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":27 + * hdrs.CONTENT_ENCODING, + * hdrs.CONTENT_LANGUAGE, + * hdrs.CONTENT_LENGTH, # <<<<<<<<<<<<<< + * hdrs.CONTENT_LOCATION, + * hdrs.CONTENT_MD5, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 27, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_23 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_LENGTH); if (unlikely(!__pyx_t_23)) __PYX_ERR(5, 27, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_23); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":28 + * hdrs.CONTENT_LANGUAGE, + * hdrs.CONTENT_LENGTH, + * hdrs.CONTENT_LOCATION, # <<<<<<<<<<<<<< + * hdrs.CONTENT_MD5, + * hdrs.CONTENT_RANGE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_24 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_LOCATION); if (unlikely(!__pyx_t_24)) __PYX_ERR(5, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_24); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":29 + * hdrs.CONTENT_LENGTH, + * hdrs.CONTENT_LOCATION, + * hdrs.CONTENT_MD5, # <<<<<<<<<<<<<< + * hdrs.CONTENT_RANGE, + * hdrs.CONTENT_TRANSFER_ENCODING, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 29, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_25 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_MD5); if (unlikely(!__pyx_t_25)) __PYX_ERR(5, 29, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_25); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":30 + * hdrs.CONTENT_LOCATION, + * hdrs.CONTENT_MD5, + * hdrs.CONTENT_RANGE, # <<<<<<<<<<<<<< + * hdrs.CONTENT_TRANSFER_ENCODING, + * hdrs.CONTENT_TYPE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_26 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_RANGE); if (unlikely(!__pyx_t_26)) __PYX_ERR(5, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_26); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":31 + * hdrs.CONTENT_MD5, + * hdrs.CONTENT_RANGE, + * hdrs.CONTENT_TRANSFER_ENCODING, # <<<<<<<<<<<<<< + * hdrs.CONTENT_TYPE, + * hdrs.COOKIE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_27 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_TRANSFER_ENCODING); if (unlikely(!__pyx_t_27)) __PYX_ERR(5, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_27); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":32 + * hdrs.CONTENT_RANGE, + * hdrs.CONTENT_TRANSFER_ENCODING, + * hdrs.CONTENT_TYPE, # <<<<<<<<<<<<<< + * hdrs.COOKIE, + * hdrs.DATE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_28 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_CONTENT_TYPE); if (unlikely(!__pyx_t_28)) __PYX_ERR(5, 32, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_28); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":33 + * hdrs.CONTENT_TRANSFER_ENCODING, + * hdrs.CONTENT_TYPE, + * hdrs.COOKIE, # <<<<<<<<<<<<<< + * hdrs.DATE, + * hdrs.DESTINATION, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_29 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_COOKIE); if (unlikely(!__pyx_t_29)) __PYX_ERR(5, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_29); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":34 + * hdrs.CONTENT_TYPE, + * hdrs.COOKIE, + * hdrs.DATE, # <<<<<<<<<<<<<< + * hdrs.DESTINATION, + * hdrs.DIGEST, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_30 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_DATE); if (unlikely(!__pyx_t_30)) __PYX_ERR(5, 34, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_30); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":35 + * hdrs.COOKIE, + * hdrs.DATE, + * hdrs.DESTINATION, # <<<<<<<<<<<<<< + * hdrs.DIGEST, + * hdrs.ETAG, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_31 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_DESTINATION); if (unlikely(!__pyx_t_31)) __PYX_ERR(5, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_31); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":36 + * hdrs.DATE, + * hdrs.DESTINATION, + * hdrs.DIGEST, # <<<<<<<<<<<<<< + * hdrs.ETAG, + * hdrs.EXPECT, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_32 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_DIGEST); if (unlikely(!__pyx_t_32)) __PYX_ERR(5, 36, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_32); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":37 + * hdrs.DESTINATION, + * hdrs.DIGEST, + * hdrs.ETAG, # <<<<<<<<<<<<<< + * hdrs.EXPECT, + * hdrs.EXPIRES, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_33 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ETAG); if (unlikely(!__pyx_t_33)) __PYX_ERR(5, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_33); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":38 + * hdrs.DIGEST, + * hdrs.ETAG, + * hdrs.EXPECT, # <<<<<<<<<<<<<< + * hdrs.EXPIRES, + * hdrs.FORWARDED, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 38, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_34 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_EXPECT); if (unlikely(!__pyx_t_34)) __PYX_ERR(5, 38, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_34); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":39 + * hdrs.ETAG, + * hdrs.EXPECT, + * hdrs.EXPIRES, # <<<<<<<<<<<<<< + * hdrs.FORWARDED, + * hdrs.FROM, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 39, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_35 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_EXPIRES); if (unlikely(!__pyx_t_35)) __PYX_ERR(5, 39, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_35); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":40 + * hdrs.EXPECT, + * hdrs.EXPIRES, + * hdrs.FORWARDED, # <<<<<<<<<<<<<< + * hdrs.FROM, + * hdrs.HOST, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_36 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_FORWARDED); if (unlikely(!__pyx_t_36)) __PYX_ERR(5, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_36); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":41 + * hdrs.EXPIRES, + * hdrs.FORWARDED, + * hdrs.FROM, # <<<<<<<<<<<<<< + * hdrs.HOST, + * hdrs.IF_MATCH, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 41, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_37 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_FROM); if (unlikely(!__pyx_t_37)) __PYX_ERR(5, 41, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_37); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":42 + * hdrs.FORWARDED, + * hdrs.FROM, + * hdrs.HOST, # <<<<<<<<<<<<<< + * hdrs.IF_MATCH, + * hdrs.IF_MODIFIED_SINCE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_38 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_HOST); if (unlikely(!__pyx_t_38)) __PYX_ERR(5, 42, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_38); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":43 + * hdrs.FROM, + * hdrs.HOST, + * hdrs.IF_MATCH, # <<<<<<<<<<<<<< + * hdrs.IF_MODIFIED_SINCE, + * hdrs.IF_NONE_MATCH, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_39 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_MATCH); if (unlikely(!__pyx_t_39)) __PYX_ERR(5, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_39); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":44 + * hdrs.HOST, + * hdrs.IF_MATCH, + * hdrs.IF_MODIFIED_SINCE, # <<<<<<<<<<<<<< + * hdrs.IF_NONE_MATCH, + * hdrs.IF_RANGE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_40 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_MODIFIED_SINCE); if (unlikely(!__pyx_t_40)) __PYX_ERR(5, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_40); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":45 + * hdrs.IF_MATCH, + * hdrs.IF_MODIFIED_SINCE, + * hdrs.IF_NONE_MATCH, # <<<<<<<<<<<<<< + * hdrs.IF_RANGE, + * hdrs.IF_UNMODIFIED_SINCE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_41 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_NONE_MATCH); if (unlikely(!__pyx_t_41)) __PYX_ERR(5, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_41); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":46 + * hdrs.IF_MODIFIED_SINCE, + * hdrs.IF_NONE_MATCH, + * hdrs.IF_RANGE, # <<<<<<<<<<<<<< + * hdrs.IF_UNMODIFIED_SINCE, + * hdrs.KEEP_ALIVE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 46, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_42 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_RANGE); if (unlikely(!__pyx_t_42)) __PYX_ERR(5, 46, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_42); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":47 + * hdrs.IF_NONE_MATCH, + * hdrs.IF_RANGE, + * hdrs.IF_UNMODIFIED_SINCE, # <<<<<<<<<<<<<< + * hdrs.KEEP_ALIVE, + * hdrs.LAST_EVENT_ID, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 47, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_43 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_IF_UNMODIFIED_SINCE); if (unlikely(!__pyx_t_43)) __PYX_ERR(5, 47, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_43); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":48 + * hdrs.IF_RANGE, + * hdrs.IF_UNMODIFIED_SINCE, + * hdrs.KEEP_ALIVE, # <<<<<<<<<<<<<< + * hdrs.LAST_EVENT_ID, + * hdrs.LAST_MODIFIED, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 48, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_44 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_KEEP_ALIVE); if (unlikely(!__pyx_t_44)) __PYX_ERR(5, 48, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_44); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":49 + * hdrs.IF_UNMODIFIED_SINCE, + * hdrs.KEEP_ALIVE, + * hdrs.LAST_EVENT_ID, # <<<<<<<<<<<<<< + * hdrs.LAST_MODIFIED, + * hdrs.LINK, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_45 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LAST_EVENT_ID); if (unlikely(!__pyx_t_45)) __PYX_ERR(5, 49, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_45); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":50 + * hdrs.KEEP_ALIVE, + * hdrs.LAST_EVENT_ID, + * hdrs.LAST_MODIFIED, # <<<<<<<<<<<<<< + * hdrs.LINK, + * hdrs.LOCATION, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 50, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_46 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LAST_MODIFIED); if (unlikely(!__pyx_t_46)) __PYX_ERR(5, 50, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_46); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":51 + * hdrs.LAST_EVENT_ID, + * hdrs.LAST_MODIFIED, + * hdrs.LINK, # <<<<<<<<<<<<<< + * hdrs.LOCATION, + * hdrs.MAX_FORWARDS, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_47 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LINK); if (unlikely(!__pyx_t_47)) __PYX_ERR(5, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_47); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":52 + * hdrs.LAST_MODIFIED, + * hdrs.LINK, + * hdrs.LOCATION, # <<<<<<<<<<<<<< + * hdrs.MAX_FORWARDS, + * hdrs.ORIGIN, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_48 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_LOCATION); if (unlikely(!__pyx_t_48)) __PYX_ERR(5, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_48); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":53 + * hdrs.LINK, + * hdrs.LOCATION, + * hdrs.MAX_FORWARDS, # <<<<<<<<<<<<<< + * hdrs.ORIGIN, + * hdrs.PRAGMA, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 53, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_49 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_MAX_FORWARDS); if (unlikely(!__pyx_t_49)) __PYX_ERR(5, 53, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_49); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":54 + * hdrs.LOCATION, + * hdrs.MAX_FORWARDS, + * hdrs.ORIGIN, # <<<<<<<<<<<<<< + * hdrs.PRAGMA, + * hdrs.PROXY_AUTHENTICATE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 54, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_50 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ORIGIN); if (unlikely(!__pyx_t_50)) __PYX_ERR(5, 54, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_50); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":55 + * hdrs.MAX_FORWARDS, + * hdrs.ORIGIN, + * hdrs.PRAGMA, # <<<<<<<<<<<<<< + * hdrs.PROXY_AUTHENTICATE, + * hdrs.PROXY_AUTHORIZATION, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_51 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_PRAGMA); if (unlikely(!__pyx_t_51)) __PYX_ERR(5, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_51); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":56 + * hdrs.ORIGIN, + * hdrs.PRAGMA, + * hdrs.PROXY_AUTHENTICATE, # <<<<<<<<<<<<<< + * hdrs.PROXY_AUTHORIZATION, + * hdrs.RANGE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_52 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_PROXY_AUTHENTICATE); if (unlikely(!__pyx_t_52)) __PYX_ERR(5, 56, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_52); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":57 + * hdrs.PRAGMA, + * hdrs.PROXY_AUTHENTICATE, + * hdrs.PROXY_AUTHORIZATION, # <<<<<<<<<<<<<< + * hdrs.RANGE, + * hdrs.REFERER, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_53 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_PROXY_AUTHORIZATION); if (unlikely(!__pyx_t_53)) __PYX_ERR(5, 57, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_53); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":58 + * hdrs.PROXY_AUTHENTICATE, + * hdrs.PROXY_AUTHORIZATION, + * hdrs.RANGE, # <<<<<<<<<<<<<< + * hdrs.REFERER, + * hdrs.RETRY_AFTER, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_54 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_RANGE); if (unlikely(!__pyx_t_54)) __PYX_ERR(5, 58, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_54); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":59 + * hdrs.PROXY_AUTHORIZATION, + * hdrs.RANGE, + * hdrs.REFERER, # <<<<<<<<<<<<<< + * hdrs.RETRY_AFTER, + * hdrs.SEC_WEBSOCKET_ACCEPT, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 59, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_55 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_REFERER); if (unlikely(!__pyx_t_55)) __PYX_ERR(5, 59, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_55); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":60 + * hdrs.RANGE, + * hdrs.REFERER, + * hdrs.RETRY_AFTER, # <<<<<<<<<<<<<< + * hdrs.SEC_WEBSOCKET_ACCEPT, + * hdrs.SEC_WEBSOCKET_EXTENSIONS, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_56 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_RETRY_AFTER); if (unlikely(!__pyx_t_56)) __PYX_ERR(5, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_56); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":61 + * hdrs.REFERER, + * hdrs.RETRY_AFTER, + * hdrs.SEC_WEBSOCKET_ACCEPT, # <<<<<<<<<<<<<< + * hdrs.SEC_WEBSOCKET_EXTENSIONS, + * hdrs.SEC_WEBSOCKET_KEY, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 61, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_57 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_ACCEPT); if (unlikely(!__pyx_t_57)) __PYX_ERR(5, 61, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_57); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":62 + * hdrs.RETRY_AFTER, + * hdrs.SEC_WEBSOCKET_ACCEPT, + * hdrs.SEC_WEBSOCKET_EXTENSIONS, # <<<<<<<<<<<<<< + * hdrs.SEC_WEBSOCKET_KEY, + * hdrs.SEC_WEBSOCKET_KEY1, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_58 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_EXTENSIONS); if (unlikely(!__pyx_t_58)) __PYX_ERR(5, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_58); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":63 + * hdrs.SEC_WEBSOCKET_ACCEPT, + * hdrs.SEC_WEBSOCKET_EXTENSIONS, + * hdrs.SEC_WEBSOCKET_KEY, # <<<<<<<<<<<<<< + * hdrs.SEC_WEBSOCKET_KEY1, + * hdrs.SEC_WEBSOCKET_PROTOCOL, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 63, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_59 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_KEY); if (unlikely(!__pyx_t_59)) __PYX_ERR(5, 63, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_59); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":64 + * hdrs.SEC_WEBSOCKET_EXTENSIONS, + * hdrs.SEC_WEBSOCKET_KEY, + * hdrs.SEC_WEBSOCKET_KEY1, # <<<<<<<<<<<<<< + * hdrs.SEC_WEBSOCKET_PROTOCOL, + * hdrs.SEC_WEBSOCKET_VERSION, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_60 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_KEY1); if (unlikely(!__pyx_t_60)) __PYX_ERR(5, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_60); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":65 + * hdrs.SEC_WEBSOCKET_KEY, + * hdrs.SEC_WEBSOCKET_KEY1, + * hdrs.SEC_WEBSOCKET_PROTOCOL, # <<<<<<<<<<<<<< + * hdrs.SEC_WEBSOCKET_VERSION, + * hdrs.SERVER, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 65, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_61 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_PROTOCOL); if (unlikely(!__pyx_t_61)) __PYX_ERR(5, 65, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_61); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":66 + * hdrs.SEC_WEBSOCKET_KEY1, + * hdrs.SEC_WEBSOCKET_PROTOCOL, + * hdrs.SEC_WEBSOCKET_VERSION, # <<<<<<<<<<<<<< + * hdrs.SERVER, + * hdrs.SET_COOKIE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_62 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_VERSION); if (unlikely(!__pyx_t_62)) __PYX_ERR(5, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_62); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":67 + * hdrs.SEC_WEBSOCKET_PROTOCOL, + * hdrs.SEC_WEBSOCKET_VERSION, + * hdrs.SERVER, # <<<<<<<<<<<<<< + * hdrs.SET_COOKIE, + * hdrs.TE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 67, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_63 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SERVER); if (unlikely(!__pyx_t_63)) __PYX_ERR(5, 67, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_63); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":68 + * hdrs.SEC_WEBSOCKET_VERSION, + * hdrs.SERVER, + * hdrs.SET_COOKIE, # <<<<<<<<<<<<<< + * hdrs.TE, + * hdrs.TRAILER, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_64 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SET_COOKIE); if (unlikely(!__pyx_t_64)) __PYX_ERR(5, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_64); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":69 + * hdrs.SERVER, + * hdrs.SET_COOKIE, + * hdrs.TE, # <<<<<<<<<<<<<< + * hdrs.TRAILER, + * hdrs.TRANSFER_ENCODING, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 69, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_65 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_TE); if (unlikely(!__pyx_t_65)) __PYX_ERR(5, 69, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_65); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":70 + * hdrs.SET_COOKIE, + * hdrs.TE, + * hdrs.TRAILER, # <<<<<<<<<<<<<< + * hdrs.TRANSFER_ENCODING, + * hdrs.URI, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_66 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_TRAILER); if (unlikely(!__pyx_t_66)) __PYX_ERR(5, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_66); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":71 + * hdrs.TE, + * hdrs.TRAILER, + * hdrs.TRANSFER_ENCODING, # <<<<<<<<<<<<<< + * hdrs.URI, + * hdrs.UPGRADE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_67 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_TRANSFER_ENCODING); if (unlikely(!__pyx_t_67)) __PYX_ERR(5, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_67); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":72 + * hdrs.TRAILER, + * hdrs.TRANSFER_ENCODING, + * hdrs.URI, # <<<<<<<<<<<<<< + * hdrs.UPGRADE, + * hdrs.USER_AGENT, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 72, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_68 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_URI); if (unlikely(!__pyx_t_68)) __PYX_ERR(5, 72, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_68); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":73 + * hdrs.TRANSFER_ENCODING, + * hdrs.URI, + * hdrs.UPGRADE, # <<<<<<<<<<<<<< + * hdrs.USER_AGENT, + * hdrs.VARY, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_69 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_UPGRADE); if (unlikely(!__pyx_t_69)) __PYX_ERR(5, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_69); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":74 + * hdrs.URI, + * hdrs.UPGRADE, + * hdrs.USER_AGENT, # <<<<<<<<<<<<<< + * hdrs.VARY, + * hdrs.VIA, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_70 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_USER_AGENT); if (unlikely(!__pyx_t_70)) __PYX_ERR(5, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_70); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":75 + * hdrs.UPGRADE, + * hdrs.USER_AGENT, + * hdrs.VARY, # <<<<<<<<<<<<<< + * hdrs.VIA, + * hdrs.WWW_AUTHENTICATE, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_71 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_VARY); if (unlikely(!__pyx_t_71)) __PYX_ERR(5, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_71); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":76 + * hdrs.USER_AGENT, + * hdrs.VARY, + * hdrs.VIA, # <<<<<<<<<<<<<< + * hdrs.WWW_AUTHENTICATE, + * hdrs.WANT_DIGEST, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_72 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_VIA); if (unlikely(!__pyx_t_72)) __PYX_ERR(5, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_72); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":77 + * hdrs.VARY, + * hdrs.VIA, + * hdrs.WWW_AUTHENTICATE, # <<<<<<<<<<<<<< + * hdrs.WANT_DIGEST, + * hdrs.WARNING, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_73 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WWW_AUTHENTICATE); if (unlikely(!__pyx_t_73)) __PYX_ERR(5, 77, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_73); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":78 + * hdrs.VIA, + * hdrs.WWW_AUTHENTICATE, + * hdrs.WANT_DIGEST, # <<<<<<<<<<<<<< + * hdrs.WARNING, + * hdrs.X_FORWARDED_FOR, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_74 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WANT_DIGEST); if (unlikely(!__pyx_t_74)) __PYX_ERR(5, 78, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_74); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":79 + * hdrs.WWW_AUTHENTICATE, + * hdrs.WANT_DIGEST, + * hdrs.WARNING, # <<<<<<<<<<<<<< + * hdrs.X_FORWARDED_FOR, + * hdrs.X_FORWARDED_HOST, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_75 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_WARNING); if (unlikely(!__pyx_t_75)) __PYX_ERR(5, 79, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_75); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":80 + * hdrs.WANT_DIGEST, + * hdrs.WARNING, + * hdrs.X_FORWARDED_FOR, # <<<<<<<<<<<<<< + * hdrs.X_FORWARDED_HOST, + * hdrs.X_FORWARDED_PROTO, + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_76 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_X_FORWARDED_FOR); if (unlikely(!__pyx_t_76)) __PYX_ERR(5, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_76); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":81 + * hdrs.WARNING, + * hdrs.X_FORWARDED_FOR, + * hdrs.X_FORWARDED_HOST, # <<<<<<<<<<<<<< + * hdrs.X_FORWARDED_PROTO, + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_77 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_X_FORWARDED_HOST); if (unlikely(!__pyx_t_77)) __PYX_ERR(5, 81, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_77); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":82 + * hdrs.X_FORWARDED_FOR, + * hdrs.X_FORWARDED_HOST, + * hdrs.X_FORWARDED_PROTO, # <<<<<<<<<<<<<< + * ) + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_78 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_X_FORWARDED_PROTO); if (unlikely(!__pyx_t_78)) __PYX_ERR(5, 82, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_78); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_headers.pxi":6 + * from . import hdrs + * cdef tuple headers = ( + * hdrs.ACCEPT, # <<<<<<<<<<<<<< + * hdrs.ACCEPT_CHARSET, + * hdrs.ACCEPT_ENCODING, + */ + __pyx_t_1 = PyTuple_New(77); if (unlikely(!__pyx_t_1)) __PYX_ERR(5, 6, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_GIVEREF(__pyx_t_2); + PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2); + __Pyx_GIVEREF(__pyx_t_3); + PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3); + __Pyx_GIVEREF(__pyx_t_4); + PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_t_4); + __Pyx_GIVEREF(__pyx_t_5); + PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_t_5); + __Pyx_GIVEREF(__pyx_t_6); + PyTuple_SET_ITEM(__pyx_t_1, 4, __pyx_t_6); + __Pyx_GIVEREF(__pyx_t_7); + PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_t_7); + __Pyx_GIVEREF(__pyx_t_8); + PyTuple_SET_ITEM(__pyx_t_1, 6, __pyx_t_8); + __Pyx_GIVEREF(__pyx_t_9); + PyTuple_SET_ITEM(__pyx_t_1, 7, __pyx_t_9); + __Pyx_GIVEREF(__pyx_t_10); + PyTuple_SET_ITEM(__pyx_t_1, 8, __pyx_t_10); + __Pyx_GIVEREF(__pyx_t_11); + PyTuple_SET_ITEM(__pyx_t_1, 9, __pyx_t_11); + __Pyx_GIVEREF(__pyx_t_12); + PyTuple_SET_ITEM(__pyx_t_1, 10, __pyx_t_12); + __Pyx_GIVEREF(__pyx_t_13); + PyTuple_SET_ITEM(__pyx_t_1, 11, __pyx_t_13); + __Pyx_GIVEREF(__pyx_t_14); + PyTuple_SET_ITEM(__pyx_t_1, 12, __pyx_t_14); + __Pyx_GIVEREF(__pyx_t_15); + PyTuple_SET_ITEM(__pyx_t_1, 13, __pyx_t_15); + __Pyx_GIVEREF(__pyx_t_16); + PyTuple_SET_ITEM(__pyx_t_1, 14, __pyx_t_16); + __Pyx_GIVEREF(__pyx_t_17); + PyTuple_SET_ITEM(__pyx_t_1, 15, __pyx_t_17); + __Pyx_GIVEREF(__pyx_t_18); + PyTuple_SET_ITEM(__pyx_t_1, 16, __pyx_t_18); + __Pyx_GIVEREF(__pyx_t_19); + PyTuple_SET_ITEM(__pyx_t_1, 17, __pyx_t_19); + __Pyx_GIVEREF(__pyx_t_20); + PyTuple_SET_ITEM(__pyx_t_1, 18, __pyx_t_20); + __Pyx_GIVEREF(__pyx_t_21); + PyTuple_SET_ITEM(__pyx_t_1, 19, __pyx_t_21); + __Pyx_GIVEREF(__pyx_t_22); + PyTuple_SET_ITEM(__pyx_t_1, 20, __pyx_t_22); + __Pyx_GIVEREF(__pyx_t_23); + PyTuple_SET_ITEM(__pyx_t_1, 21, __pyx_t_23); + __Pyx_GIVEREF(__pyx_t_24); + PyTuple_SET_ITEM(__pyx_t_1, 22, __pyx_t_24); + __Pyx_GIVEREF(__pyx_t_25); + PyTuple_SET_ITEM(__pyx_t_1, 23, __pyx_t_25); + __Pyx_GIVEREF(__pyx_t_26); + PyTuple_SET_ITEM(__pyx_t_1, 24, __pyx_t_26); + __Pyx_GIVEREF(__pyx_t_27); + PyTuple_SET_ITEM(__pyx_t_1, 25, __pyx_t_27); + __Pyx_GIVEREF(__pyx_t_28); + PyTuple_SET_ITEM(__pyx_t_1, 26, __pyx_t_28); + __Pyx_GIVEREF(__pyx_t_29); + PyTuple_SET_ITEM(__pyx_t_1, 27, __pyx_t_29); + __Pyx_GIVEREF(__pyx_t_30); + PyTuple_SET_ITEM(__pyx_t_1, 28, __pyx_t_30); + __Pyx_GIVEREF(__pyx_t_31); + PyTuple_SET_ITEM(__pyx_t_1, 29, __pyx_t_31); + __Pyx_GIVEREF(__pyx_t_32); + PyTuple_SET_ITEM(__pyx_t_1, 30, __pyx_t_32); + __Pyx_GIVEREF(__pyx_t_33); + PyTuple_SET_ITEM(__pyx_t_1, 31, __pyx_t_33); + __Pyx_GIVEREF(__pyx_t_34); + PyTuple_SET_ITEM(__pyx_t_1, 32, __pyx_t_34); + __Pyx_GIVEREF(__pyx_t_35); + PyTuple_SET_ITEM(__pyx_t_1, 33, __pyx_t_35); + __Pyx_GIVEREF(__pyx_t_36); + PyTuple_SET_ITEM(__pyx_t_1, 34, __pyx_t_36); + __Pyx_GIVEREF(__pyx_t_37); + PyTuple_SET_ITEM(__pyx_t_1, 35, __pyx_t_37); + __Pyx_GIVEREF(__pyx_t_38); + PyTuple_SET_ITEM(__pyx_t_1, 36, __pyx_t_38); + __Pyx_GIVEREF(__pyx_t_39); + PyTuple_SET_ITEM(__pyx_t_1, 37, __pyx_t_39); + __Pyx_GIVEREF(__pyx_t_40); + PyTuple_SET_ITEM(__pyx_t_1, 38, __pyx_t_40); + __Pyx_GIVEREF(__pyx_t_41); + PyTuple_SET_ITEM(__pyx_t_1, 39, __pyx_t_41); + __Pyx_GIVEREF(__pyx_t_42); + PyTuple_SET_ITEM(__pyx_t_1, 40, __pyx_t_42); + __Pyx_GIVEREF(__pyx_t_43); + PyTuple_SET_ITEM(__pyx_t_1, 41, __pyx_t_43); + __Pyx_GIVEREF(__pyx_t_44); + PyTuple_SET_ITEM(__pyx_t_1, 42, __pyx_t_44); + __Pyx_GIVEREF(__pyx_t_45); + PyTuple_SET_ITEM(__pyx_t_1, 43, __pyx_t_45); + __Pyx_GIVEREF(__pyx_t_46); + PyTuple_SET_ITEM(__pyx_t_1, 44, __pyx_t_46); + __Pyx_GIVEREF(__pyx_t_47); + PyTuple_SET_ITEM(__pyx_t_1, 45, __pyx_t_47); + __Pyx_GIVEREF(__pyx_t_48); + PyTuple_SET_ITEM(__pyx_t_1, 46, __pyx_t_48); + __Pyx_GIVEREF(__pyx_t_49); + PyTuple_SET_ITEM(__pyx_t_1, 47, __pyx_t_49); + __Pyx_GIVEREF(__pyx_t_50); + PyTuple_SET_ITEM(__pyx_t_1, 48, __pyx_t_50); + __Pyx_GIVEREF(__pyx_t_51); + PyTuple_SET_ITEM(__pyx_t_1, 49, __pyx_t_51); + __Pyx_GIVEREF(__pyx_t_52); + PyTuple_SET_ITEM(__pyx_t_1, 50, __pyx_t_52); + __Pyx_GIVEREF(__pyx_t_53); + PyTuple_SET_ITEM(__pyx_t_1, 51, __pyx_t_53); + __Pyx_GIVEREF(__pyx_t_54); + PyTuple_SET_ITEM(__pyx_t_1, 52, __pyx_t_54); + __Pyx_GIVEREF(__pyx_t_55); + PyTuple_SET_ITEM(__pyx_t_1, 53, __pyx_t_55); + __Pyx_GIVEREF(__pyx_t_56); + PyTuple_SET_ITEM(__pyx_t_1, 54, __pyx_t_56); + __Pyx_GIVEREF(__pyx_t_57); + PyTuple_SET_ITEM(__pyx_t_1, 55, __pyx_t_57); + __Pyx_GIVEREF(__pyx_t_58); + PyTuple_SET_ITEM(__pyx_t_1, 56, __pyx_t_58); + __Pyx_GIVEREF(__pyx_t_59); + PyTuple_SET_ITEM(__pyx_t_1, 57, __pyx_t_59); + __Pyx_GIVEREF(__pyx_t_60); + PyTuple_SET_ITEM(__pyx_t_1, 58, __pyx_t_60); + __Pyx_GIVEREF(__pyx_t_61); + PyTuple_SET_ITEM(__pyx_t_1, 59, __pyx_t_61); + __Pyx_GIVEREF(__pyx_t_62); + PyTuple_SET_ITEM(__pyx_t_1, 60, __pyx_t_62); + __Pyx_GIVEREF(__pyx_t_63); + PyTuple_SET_ITEM(__pyx_t_1, 61, __pyx_t_63); + __Pyx_GIVEREF(__pyx_t_64); + PyTuple_SET_ITEM(__pyx_t_1, 62, __pyx_t_64); + __Pyx_GIVEREF(__pyx_t_65); + PyTuple_SET_ITEM(__pyx_t_1, 63, __pyx_t_65); + __Pyx_GIVEREF(__pyx_t_66); + PyTuple_SET_ITEM(__pyx_t_1, 64, __pyx_t_66); + __Pyx_GIVEREF(__pyx_t_67); + PyTuple_SET_ITEM(__pyx_t_1, 65, __pyx_t_67); + __Pyx_GIVEREF(__pyx_t_68); + PyTuple_SET_ITEM(__pyx_t_1, 66, __pyx_t_68); + __Pyx_GIVEREF(__pyx_t_69); + PyTuple_SET_ITEM(__pyx_t_1, 67, __pyx_t_69); + __Pyx_GIVEREF(__pyx_t_70); + PyTuple_SET_ITEM(__pyx_t_1, 68, __pyx_t_70); + __Pyx_GIVEREF(__pyx_t_71); + PyTuple_SET_ITEM(__pyx_t_1, 69, __pyx_t_71); + __Pyx_GIVEREF(__pyx_t_72); + PyTuple_SET_ITEM(__pyx_t_1, 70, __pyx_t_72); + __Pyx_GIVEREF(__pyx_t_73); + PyTuple_SET_ITEM(__pyx_t_1, 71, __pyx_t_73); + __Pyx_GIVEREF(__pyx_t_74); + PyTuple_SET_ITEM(__pyx_t_1, 72, __pyx_t_74); + __Pyx_GIVEREF(__pyx_t_75); + PyTuple_SET_ITEM(__pyx_t_1, 73, __pyx_t_75); + __Pyx_GIVEREF(__pyx_t_76); + PyTuple_SET_ITEM(__pyx_t_1, 74, __pyx_t_76); + __Pyx_GIVEREF(__pyx_t_77); + PyTuple_SET_ITEM(__pyx_t_1, 75, __pyx_t_77); + __Pyx_GIVEREF(__pyx_t_78); + PyTuple_SET_ITEM(__pyx_t_1, 76, __pyx_t_78); + __pyx_t_2 = 0; + __pyx_t_3 = 0; + __pyx_t_4 = 0; + __pyx_t_5 = 0; + __pyx_t_6 = 0; + __pyx_t_7 = 0; + __pyx_t_8 = 0; + __pyx_t_9 = 0; + __pyx_t_10 = 0; + __pyx_t_11 = 0; + __pyx_t_12 = 0; + __pyx_t_13 = 0; + __pyx_t_14 = 0; + __pyx_t_15 = 0; + __pyx_t_16 = 0; + __pyx_t_17 = 0; + __pyx_t_18 = 0; + __pyx_t_19 = 0; + __pyx_t_20 = 0; + __pyx_t_21 = 0; + __pyx_t_22 = 0; + __pyx_t_23 = 0; + __pyx_t_24 = 0; + __pyx_t_25 = 0; + __pyx_t_26 = 0; + __pyx_t_27 = 0; + __pyx_t_28 = 0; + __pyx_t_29 = 0; + __pyx_t_30 = 0; + __pyx_t_31 = 0; + __pyx_t_32 = 0; + __pyx_t_33 = 0; + __pyx_t_34 = 0; + __pyx_t_35 = 0; + __pyx_t_36 = 0; + __pyx_t_37 = 0; + __pyx_t_38 = 0; + __pyx_t_39 = 0; + __pyx_t_40 = 0; + __pyx_t_41 = 0; + __pyx_t_42 = 0; + __pyx_t_43 = 0; + __pyx_t_44 = 0; + __pyx_t_45 = 0; + __pyx_t_46 = 0; + __pyx_t_47 = 0; + __pyx_t_48 = 0; + __pyx_t_49 = 0; + __pyx_t_50 = 0; + __pyx_t_51 = 0; + __pyx_t_52 = 0; + __pyx_t_53 = 0; + __pyx_t_54 = 0; + __pyx_t_55 = 0; + __pyx_t_56 = 0; + __pyx_t_57 = 0; + __pyx_t_58 = 0; + __pyx_t_59 = 0; + __pyx_t_60 = 0; + __pyx_t_61 = 0; + __pyx_t_62 = 0; + __pyx_t_63 = 0; + __pyx_t_64 = 0; + __pyx_t_65 = 0; + __pyx_t_66 = 0; + __pyx_t_67 = 0; + __pyx_t_68 = 0; + __pyx_t_69 = 0; + __pyx_t_70 = 0; + __pyx_t_71 = 0; + __pyx_t_72 = 0; + __pyx_t_73 = 0; + __pyx_t_74 = 0; + __pyx_t_75 = 0; + __pyx_t_76 = 0; + __pyx_t_77 = 0; + __pyx_t_78 = 0; + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_headers); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_headers, ((PyObject*)__pyx_t_1)); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":57 + * char* PyByteArray_AsString(object) + * + * __all__ = ('HttpRequestParser', 'HttpResponseParser', # <<<<<<<<<<<<<< + * 'RawRequestMessage', 'RawResponseMessage') + * + */ + if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_tuple__12) < 0) __PYX_ERR(0, 57, __pyx_L1_error) + + /* "aiohttp/_http_parser.pyx":60 + * 'RawRequestMessage', 'RawResponseMessage') + * + * cdef object URL = _URL # <<<<<<<<<<<<<< + * cdef object URL_build = URL.build + * cdef object CIMultiDict = _CIMultiDict + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_URL_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_URL); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_URL, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":61 + * + * cdef object URL = _URL + * cdef object URL_build = URL.build # <<<<<<<<<<<<<< + * cdef object CIMultiDict = _CIMultiDict + * cdef object CIMultiDictProxy = _CIMultiDictProxy + */ + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_7aiohttp_12_http_parser_URL, __pyx_n_s_build); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 61, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_URL_build); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_URL_build, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":62 + * cdef object URL = _URL + * cdef object URL_build = URL.build + * cdef object CIMultiDict = _CIMultiDict # <<<<<<<<<<<<<< + * cdef object CIMultiDictProxy = _CIMultiDictProxy + * cdef object HttpVersion = _HttpVersion + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_CIMultiDict_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDict); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CIMultiDict, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":63 + * cdef object URL_build = URL.build + * cdef object CIMultiDict = _CIMultiDict + * cdef object CIMultiDictProxy = _CIMultiDictProxy # <<<<<<<<<<<<<< + * cdef object HttpVersion = _HttpVersion + * cdef object HttpVersion10 = _HttpVersion10 + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_CIMultiDictProxy_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 63, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CIMultiDictProxy, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":64 + * cdef object CIMultiDict = _CIMultiDict + * cdef object CIMultiDictProxy = _CIMultiDictProxy + * cdef object HttpVersion = _HttpVersion # <<<<<<<<<<<<<< + * cdef object HttpVersion10 = _HttpVersion10 + * cdef object HttpVersion11 = _HttpVersion11 + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_HttpVersion_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":65 + * cdef object CIMultiDictProxy = _CIMultiDictProxy + * cdef object HttpVersion = _HttpVersion + * cdef object HttpVersion10 = _HttpVersion10 # <<<<<<<<<<<<<< + * cdef object HttpVersion11 = _HttpVersion11 + * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_HttpVersion10_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 65, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion10); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion10, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":66 + * cdef object HttpVersion = _HttpVersion + * cdef object HttpVersion10 = _HttpVersion10 + * cdef object HttpVersion11 = _HttpVersion11 # <<<<<<<<<<<<<< + * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 + * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_HttpVersion11_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_HttpVersion11); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_HttpVersion11, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":67 + * cdef object HttpVersion10 = _HttpVersion10 + * cdef object HttpVersion11 = _HttpVersion11 + * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 # <<<<<<<<<<<<<< + * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING + * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 67, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_78 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_SEC_WEBSOCKET_KEY1); if (unlikely(!__pyx_t_78)) __PYX_ERR(0, 67, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_78); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_SEC_WEBSOCKET_KEY1, __pyx_t_78); + __Pyx_GIVEREF(__pyx_t_78); + __pyx_t_78 = 0; + + /* "aiohttp/_http_parser.pyx":68 + * cdef object HttpVersion11 = _HttpVersion11 + * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 + * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING # <<<<<<<<<<<<<< + * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD + * cdef object StreamReader = _StreamReader + */ + __Pyx_GetModuleGlobalName(__pyx_t_78, __pyx_n_s_hdrs); if (unlikely(!__pyx_t_78)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_78); + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_78, __pyx_n_s_CONTENT_ENCODING); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_78); __pyx_t_78 = 0; + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_CONTENT_ENCODING, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":69 + * cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 + * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING + * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD # <<<<<<<<<<<<<< + * cdef object StreamReader = _StreamReader + * cdef object DeflateBuffer = _DeflateBuffer + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_EMPTY_PAYLOAD_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 69, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_EMPTY_PAYLOAD, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":70 + * cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING + * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD + * cdef object StreamReader = _StreamReader # <<<<<<<<<<<<<< + * cdef object DeflateBuffer = _DeflateBuffer + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_StreamReader_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_StreamReader); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_StreamReader, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":71 + * cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD + * cdef object StreamReader = _StreamReader + * cdef object DeflateBuffer = _DeflateBuffer # <<<<<<<<<<<<<< + * + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_DeflateBuffer_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser_DeflateBuffer); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser_DeflateBuffer, __pyx_t_1); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":85 + * DEF METHODS_COUNT = 34; + * + * cdef list _http_method = [] # <<<<<<<<<<<<<< + * + * for i in range(METHODS_COUNT): + */ + __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 85, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_parser__http_method); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_parser__http_method, ((PyObject*)__pyx_t_1)); + __Pyx_GIVEREF(__pyx_t_1); + __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":87 + * cdef list _http_method = [] + * + * for i in range(METHODS_COUNT): # <<<<<<<<<<<<<< + * _http_method.append( + * cparser.http_method_str( i).decode('ascii')) + */ + for (__pyx_t_79 = 0; __pyx_t_79 < 34; __pyx_t_79+=1) { + __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_t_79); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_i, __pyx_t_1) < 0) __PYX_ERR(0, 87, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":88 + * + * for i in range(METHODS_COUNT): + * _http_method.append( # <<<<<<<<<<<<<< + * cparser.http_method_str( i).decode('ascii')) + * + */ + if (unlikely(__pyx_v_7aiohttp_12_http_parser__http_method == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "append"); + __PYX_ERR(0, 88, __pyx_L1_error) + } + + /* "aiohttp/_http_parser.pyx":89 + * for i in range(METHODS_COUNT): + * _http_method.append( + * cparser.http_method_str( i).decode('ascii')) # <<<<<<<<<<<<<< + * + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_80 = ((enum http_method)__Pyx_PyInt_As_enum__http_method(__pyx_t_1)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_81 = http_method_str(((enum http_method)__pyx_t_80)); + __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_81, 0, strlen(__pyx_t_81), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 89, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + + /* "aiohttp/_http_parser.pyx":88 + * + * for i in range(METHODS_COUNT): + * _http_method.append( # <<<<<<<<<<<<<< + * cparser.http_method_str( i).decode('ascii')) + * + */ + __pyx_t_82 = __Pyx_PyList_Append(__pyx_v_7aiohttp_12_http_parser__http_method, __pyx_t_1); if (unlikely(__pyx_t_82 == ((int)-1))) __PYX_ERR(0, 88, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } + + /* "aiohttp/_http_parser.pyx":785 + * + * + * def parse_url(url): # <<<<<<<<<<<<<< + * cdef: + * Py_buffer py_buf + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_1parse_url, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 785, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_parse_url, __pyx_t_1) < 0) __PYX_ERR(0, 785, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":1 + * def __pyx_unpickle_RawRequestMessage(__pyx_type, long __pyx_checksum, __pyx_state): # <<<<<<<<<<<<<< + * cdef object __pyx_PickleError + * cdef object __pyx_result + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_3__pyx_unpickle_RawRequestMessage, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_RawRequestMessage, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "(tree fragment)":11 + * __pyx_unpickle_RawRequestMessage__set_state( __pyx_result, __pyx_state) + * return __pyx_result + * cdef __pyx_unpickle_RawRequestMessage__set_state(RawRequestMessage __pyx_result, tuple __pyx_state): # <<<<<<<<<<<<<< + * __pyx_result.chunked = __pyx_state[0]; __pyx_result.compression = __pyx_state[1]; __pyx_result.headers = __pyx_state[2]; __pyx_result.method = __pyx_state[3]; __pyx_result.path = __pyx_state[4]; __pyx_result.raw_headers = __pyx_state[5]; __pyx_result.should_close = __pyx_state[6]; __pyx_result.upgrade = __pyx_state[7]; __pyx_result.url = __pyx_state[8]; __pyx_result.version = __pyx_state[9] + * if len(__pyx_state) > 10 and hasattr(__pyx_result, '__dict__'): + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_parser_5__pyx_unpickle_RawResponseMessage, NULL, __pyx_n_s_aiohttp__http_parser); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyx_unpickle_RawResponseMessag, __pyx_t_1) < 0) __PYX_ERR(1, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_parser.pyx":1 + * #cython: language_level=3 # <<<<<<<<<<<<<< + * # + * # Based on https://github.com/MagicStack/httptools + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); + __Pyx_XDECREF(__pyx_t_12); + __Pyx_XDECREF(__pyx_t_13); + __Pyx_XDECREF(__pyx_t_14); + __Pyx_XDECREF(__pyx_t_15); + __Pyx_XDECREF(__pyx_t_16); + __Pyx_XDECREF(__pyx_t_17); + __Pyx_XDECREF(__pyx_t_18); + __Pyx_XDECREF(__pyx_t_19); + __Pyx_XDECREF(__pyx_t_20); + __Pyx_XDECREF(__pyx_t_21); + __Pyx_XDECREF(__pyx_t_22); + __Pyx_XDECREF(__pyx_t_23); + __Pyx_XDECREF(__pyx_t_24); + __Pyx_XDECREF(__pyx_t_25); + __Pyx_XDECREF(__pyx_t_26); + __Pyx_XDECREF(__pyx_t_27); + __Pyx_XDECREF(__pyx_t_28); + __Pyx_XDECREF(__pyx_t_29); + __Pyx_XDECREF(__pyx_t_30); + __Pyx_XDECREF(__pyx_t_31); + __Pyx_XDECREF(__pyx_t_32); + __Pyx_XDECREF(__pyx_t_33); + __Pyx_XDECREF(__pyx_t_34); + __Pyx_XDECREF(__pyx_t_35); + __Pyx_XDECREF(__pyx_t_36); + __Pyx_XDECREF(__pyx_t_37); + __Pyx_XDECREF(__pyx_t_38); + __Pyx_XDECREF(__pyx_t_39); + __Pyx_XDECREF(__pyx_t_40); + __Pyx_XDECREF(__pyx_t_41); + __Pyx_XDECREF(__pyx_t_42); + __Pyx_XDECREF(__pyx_t_43); + __Pyx_XDECREF(__pyx_t_44); + __Pyx_XDECREF(__pyx_t_45); + __Pyx_XDECREF(__pyx_t_46); + __Pyx_XDECREF(__pyx_t_47); + __Pyx_XDECREF(__pyx_t_48); + __Pyx_XDECREF(__pyx_t_49); + __Pyx_XDECREF(__pyx_t_50); + __Pyx_XDECREF(__pyx_t_51); + __Pyx_XDECREF(__pyx_t_52); + __Pyx_XDECREF(__pyx_t_53); + __Pyx_XDECREF(__pyx_t_54); + __Pyx_XDECREF(__pyx_t_55); + __Pyx_XDECREF(__pyx_t_56); + __Pyx_XDECREF(__pyx_t_57); + __Pyx_XDECREF(__pyx_t_58); + __Pyx_XDECREF(__pyx_t_59); + __Pyx_XDECREF(__pyx_t_60); + __Pyx_XDECREF(__pyx_t_61); + __Pyx_XDECREF(__pyx_t_62); + __Pyx_XDECREF(__pyx_t_63); + __Pyx_XDECREF(__pyx_t_64); + __Pyx_XDECREF(__pyx_t_65); + __Pyx_XDECREF(__pyx_t_66); + __Pyx_XDECREF(__pyx_t_67); + __Pyx_XDECREF(__pyx_t_68); + __Pyx_XDECREF(__pyx_t_69); + __Pyx_XDECREF(__pyx_t_70); + __Pyx_XDECREF(__pyx_t_71); + __Pyx_XDECREF(__pyx_t_72); + __Pyx_XDECREF(__pyx_t_73); + __Pyx_XDECREF(__pyx_t_74); + __Pyx_XDECREF(__pyx_t_75); + __Pyx_XDECREF(__pyx_t_76); + __Pyx_XDECREF(__pyx_t_77); + __Pyx_XDECREF(__pyx_t_78); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init aiohttp._http_parser", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_CLEAR(__pyx_m); + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init aiohttp._http_parser"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* GetItemInt */ +static PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (!j) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyList_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyList_GET_SIZE(o)))) { + PyObject *r = PyList_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + Py_ssize_t wrapped_i = i; + if (wraparound & unlikely(i < 0)) { + wrapped_i += PyTuple_GET_SIZE(o); + } + if ((!boundscheck) || likely(__Pyx_is_valid_index(wrapped_i, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, wrapped_i); + Py_INCREF(r); + return r; + } + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +#else + return PySequence_GetItem(o, i); +#endif +} +static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, + CYTHON_NCP_UNUSED int wraparound, + CYTHON_NCP_UNUSED int boundscheck) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS && CYTHON_USE_TYPE_SLOTS + if (is_list || PyList_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); + if ((!boundscheck) || (likely(__Pyx_is_valid_index(n, PyList_GET_SIZE(o))))) { + PyObject *r = PyList_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } + else if (PyTuple_CheckExact(o)) { + Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); + if ((!boundscheck) || likely(__Pyx_is_valid_index(n, PyTuple_GET_SIZE(o)))) { + PyObject *r = PyTuple_GET_ITEM(o, n); + Py_INCREF(r); + return r; + } + } else { + PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; + if (likely(m && m->sq_item)) { + if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { + Py_ssize_t l = m->sq_length(o); + if (likely(l >= 0)) { + i += l; + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; + PyErr_Clear(); + } + } + return m->sq_item(o, i); + } + } +#else + if (is_list || PySequence_Check(o)) { + return PySequence_GetItem(o, i); + } +#endif + return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); +} + +/* decode_c_bytes */ +static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( + const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, + const char* encoding, const char* errors, + PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { + if (unlikely((start < 0) | (stop < 0))) { + if (start < 0) { + start += length; + if (start < 0) + start = 0; + } + if (stop < 0) + stop += length; + } + if (stop > length) + stop = length; + if (unlikely(stop <= start)) + return __Pyx_NewRef(__pyx_empty_unicode); + length = stop - start; + cstring += start; + if (decode_func) { + return decode_func(cstring, length, errors); + } else { + return PyUnicode_Decode(cstring, length, encoding, errors); + } +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* RaiseDoubleKeywords */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* None */ +static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) { + PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname); +} + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { +#if CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* exc_type = tstate->curexc_type; + if (unlikely(exc_type)) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) { + PyObject *exc_value, *exc_tb; + exc_value = tstate->curexc_value; + exc_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + Py_DECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + return 0; + } else { + return -1; + } + } + return 0; +#else + if (unlikely(PyErr_Occurred())) { + if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { + PyErr_Clear(); + return 0; + } else { + return -1; + } + } + return 0; +#endif +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } else { + return __Pyx_IterFinish(); + } + return 0; +} + +/* KeywordStringCheck */ +static int __Pyx_CheckKeywordStrings( + PyObject *kwdict, + const char* function_name, + int kw_allowed) +{ + PyObject* key = 0; + Py_ssize_t pos = 0; +#if CYTHON_COMPILING_IN_PYPY + if (!kw_allowed && PyDict_Next(kwdict, &pos, &key, 0)) + goto invalid_keyword; + return 1; +#else + while (PyDict_Next(kwdict, &pos, &key, 0)) { + #if PY_MAJOR_VERSION < 3 + if (unlikely(!PyString_Check(key))) + #endif + if (unlikely(!PyUnicode_Check(key))) + goto invalid_keyword_type; + } + if ((!kw_allowed) && unlikely(key)) + goto invalid_keyword; + return 1; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + return 0; +#endif +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif + return 0; +} + +/* ExtTypeTest */ +static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + if (likely(__Pyx_TypeCheck(obj, type))) + return 1; + PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", + Py_TYPE(obj)->tp_name, type->tp_name); + return 0; +} + +/* DictGetItem */ +#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { + PyObject *value; + value = PyDict_GetItemWithError(d, key); + if (unlikely(!value)) { + if (!PyErr_Occurred()) { + if (unlikely(PyTuple_Check(key))) { + PyObject* args = PyTuple_Pack(1, key); + if (likely(args)) { + PyErr_SetObject(PyExc_KeyError, args); + Py_DECREF(args); + } + } else { + PyErr_SetObject(PyExc_KeyError, key); + } + } + return NULL; + } + Py_INCREF(value); + return value; +} +#endif + +/* PyErrExceptionMatches */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; icurexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; + if (unlikely(PyTuple_Check(err))) + return __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + return __Pyx_PyErr_GivenExceptionMatches(exc_type, err); +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* GetAttr */ +static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { +#if CYTHON_USE_TYPE_SLOTS +#if PY_MAJOR_VERSION >= 3 + if (likely(PyUnicode_Check(n))) +#else + if (likely(PyString_Check(n))) +#endif + return __Pyx_PyObject_GetAttrStr(o, n); +#endif + return PyObject_GetAttr(o, n); +} + +/* GetAttr3 */ +static PyObject *__Pyx_GetAttr3Default(PyObject *d) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (unlikely(!__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + return NULL; + __Pyx_PyErr_Clear(); + Py_INCREF(d); + return d; +} +static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { + PyObject *r = __Pyx_GetAttr(o, n); + return (likely(r)) ? r : __Pyx_GetAttr3Default(d); +} + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; + } +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { + return NULL; + } + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif +#endif + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = PyCFunction_GET_FUNCTION(func); + self = PyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallNoArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, NULL, 0); + } +#endif +#ifdef __Pyx_CyFunction_USED + if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) +#else + if (likely(PyCFunction_Check(func))) +#endif + { + if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { + return __Pyx_PyObject_CallMethO(func, NULL); + } + } + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); +} +#endif + +/* PyCFunctionFastCall */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { + PyCFunctionObject *func = (PyCFunctionObject*)func_obj; + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + int flags = PyCFunction_GET_FLAGS(func); + assert(PyCFunction_Check(func)); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + /* _PyCFunction_FastCallDict() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); + } else { + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); + } +} +#endif + +/* PyObjectCallOneArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, &arg, 1); + } +#endif + if (likely(PyCFunction_Check(func))) { + if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { + return __Pyx_PyObject_CallMethO(func, arg); +#if CYTHON_FAST_PYCCALL + } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { + return __Pyx_PyCFunction_FastCall(func, &arg, 1); +#endif + } + } + return __Pyx__PyObject_CallOneArg(func, arg); +} +#else +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_Pack(1, arg); + if (unlikely(!args)) return NULL; + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +#endif + +/* PyObjectCall2Args */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args, *result = NULL; + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyFunction_FastCall(function, args, 2); + } + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyCFunction_FastCall(function, args, 2); + } + #endif + args = PyTuple_New(2); + if (unlikely(!args)) goto done; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + Py_INCREF(function); + result = __Pyx_PyObject_Call(function, args, NULL); + Py_DECREF(args); + Py_DECREF(function); +done: + return result; +} + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + __Pyx_PyThreadState_declare + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if CYTHON_COMPILING_IN_PYPY + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#else + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* BytesEquals */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY + return PyObject_RichCompareBool(s1, s2, equals); +#else +#if PY_MAJOR_VERSION < 3 + PyObject* owned_ref = NULL; +#endif + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); +#if PY_MAJOR_VERSION < 3 + if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { + owned_ref = PyUnicode_FromObject(s2); + if (unlikely(!owned_ref)) + return -1; + s2 = owned_ref; + s2_is_unicode = 1; + } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { + owned_ref = PyUnicode_FromObject(s1); + if (unlikely(!owned_ref)) + return -1; + s1 = owned_ref; + s1_is_unicode = 1; + } else if (((!s2_is_unicode) & (!s1_is_unicode))) { + return __Pyx_PyBytes_Equals(s1, s2, equals); + } +#endif + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length; + int kind; + void *data1, *data2; + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + length = __Pyx_PyUnicode_GET_LENGTH(s1); + if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + #if CYTHON_PEP393_ENABLED + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + #else + hash1 = ((PyUnicodeObject*)s1)->hash; + hash2 = ((PyUnicodeObject*)s2)->hash; + #endif + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_EQ); +return_ne: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(owned_ref); + #endif + return (equals == Py_NE); +#endif +} + +/* SliceObject */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj, + Py_ssize_t cstart, Py_ssize_t cstop, + PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice, + int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) { +#if CYTHON_USE_TYPE_SLOTS + PyMappingMethods* mp; +#if PY_MAJOR_VERSION < 3 + PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence; + if (likely(ms && ms->sq_slice)) { + if (!has_cstart) { + if (_py_start && (*_py_start != Py_None)) { + cstart = __Pyx_PyIndex_AsSsize_t(*_py_start); + if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; + } else + cstart = 0; + } + if (!has_cstop) { + if (_py_stop && (*_py_stop != Py_None)) { + cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop); + if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; + } else + cstop = PY_SSIZE_T_MAX; + } + if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) { + Py_ssize_t l = ms->sq_length(obj); + if (likely(l >= 0)) { + if (cstop < 0) { + cstop += l; + if (cstop < 0) cstop = 0; + } + if (cstart < 0) { + cstart += l; + if (cstart < 0) cstart = 0; + } + } else { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + goto bad; + PyErr_Clear(); + } + } + return ms->sq_slice(obj, cstart, cstop); + } +#endif + mp = Py_TYPE(obj)->tp_as_mapping; + if (likely(mp && mp->mp_subscript)) +#endif + { + PyObject* result; + PyObject *py_slice, *py_start, *py_stop; + if (_py_slice) { + py_slice = *_py_slice; + } else { + PyObject* owned_start = NULL; + PyObject* owned_stop = NULL; + if (_py_start) { + py_start = *_py_start; + } else { + if (has_cstart) { + owned_start = py_start = PyInt_FromSsize_t(cstart); + if (unlikely(!py_start)) goto bad; + } else + py_start = Py_None; + } + if (_py_stop) { + py_stop = *_py_stop; + } else { + if (has_cstop) { + owned_stop = py_stop = PyInt_FromSsize_t(cstop); + if (unlikely(!py_stop)) { + Py_XDECREF(owned_start); + goto bad; + } + } else + py_stop = Py_None; + } + py_slice = PySlice_New(py_start, py_stop, Py_None); + Py_XDECREF(owned_start); + Py_XDECREF(owned_stop); + if (unlikely(!py_slice)) goto bad; + } +#if CYTHON_USE_TYPE_SLOTS + result = mp->mp_subscript(obj, py_slice); +#else + result = PyObject_GetItem(obj, py_slice); +#endif + if (!_py_slice) { + Py_DECREF(py_slice); + } + return result; + } + PyErr_Format(PyExc_TypeError, + "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name); +bad: + return NULL; +} + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type, *local_value, *local_tb; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* SwapException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = *type; + tstate->exc_value = *value; + tstate->exc_traceback = *tb; + #endif + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); + PyErr_SetExcInfo(*type, *value, *tb); + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#endif + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + #endif + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +#endif + +/* decode_c_string */ +static CYTHON_INLINE PyObject* __Pyx_decode_c_string( + const char* cstring, Py_ssize_t start, Py_ssize_t stop, + const char* encoding, const char* errors, + PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { + Py_ssize_t length; + if (unlikely((start < 0) | (stop < 0))) { + size_t slen = strlen(cstring); + if (unlikely(slen > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, + "c-string too long to convert to Python"); + return NULL; + } + length = (Py_ssize_t) slen; + if (start < 0) { + start += length; + if (start < 0) + start = 0; + } + if (stop < 0) + stop += length; + } + if (unlikely(stop <= start)) + return __Pyx_NewRef(__pyx_empty_unicode); + length = stop - start; + cstring += start; + if (decode_func) { + return decode_func(cstring, length, errors); + } else { + return PyUnicode_Decode(cstring, length, encoding, errors); + } +} + +/* UnpackUnboundCMethod */ +static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { + PyObject *method; + method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); + if (unlikely(!method)) + return -1; + target->method = method; +#if CYTHON_COMPILING_IN_CPYTHON + #if PY_MAJOR_VERSION >= 3 + if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) + #endif + { + PyMethodDescrObject *descr = (PyMethodDescrObject*) method; + target->func = descr->d_method->ml_meth; + target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); + } +#endif + return 0; +} + +/* CallUnboundCMethod1 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg) { + if (likely(cfunc->func)) { + int flag = cfunc->flag; + if (flag == METH_O) { + return (*(cfunc->func))(self, arg); + } else if (PY_VERSION_HEX >= 0x030600B1 && flag == METH_FASTCALL) { + if (PY_VERSION_HEX >= 0x030700A0) { + return (*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)cfunc->func)(self, &arg, 1); + } else { + return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); + } + } else if (PY_VERSION_HEX >= 0x030700A0 && flag == (METH_FASTCALL | METH_KEYWORDS)) { + return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL); + } + } + return __Pyx__CallUnboundCMethod1(cfunc, self, arg); +} +#endif +static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg){ + PyObject *args, *result = NULL; + if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; +#if CYTHON_COMPILING_IN_CPYTHON + if (cfunc->func && (cfunc->flag & METH_VARARGS)) { + args = PyTuple_New(1); + if (unlikely(!args)) goto bad; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + if (cfunc->flag & METH_KEYWORDS) + result = (*(PyCFunctionWithKeywords)(void*)(PyCFunction)cfunc->func)(self, args, NULL); + else + result = (*cfunc->func)(self, args); + } else { + args = PyTuple_New(2); + if (unlikely(!args)) goto bad; + Py_INCREF(self); + PyTuple_SET_ITEM(args, 0, self); + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 1, arg); + result = __Pyx_PyObject_Call(cfunc->method, args, NULL); + } +#else + args = PyTuple_Pack(2, self, arg); + if (unlikely(!args)) goto bad; + result = __Pyx_PyObject_Call(cfunc->method, args, NULL); +#endif +bad: + Py_XDECREF(args); + return result; +} + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* HasAttr */ +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { + PyObject *r; + if (unlikely(!__Pyx_PyBaseString_Check(n))) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return -1; + } + r = __Pyx_GetAttr(o, n); + if (unlikely(!r)) { + PyErr_Clear(); + return 0; + } else { + Py_DECREF(r); + return 1; + } +} + +/* PyObject_GenericGetAttrNoDict */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject *attr_name) { + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, attr_name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(attr_name)); +#endif + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) { + PyObject *descr; + PyTypeObject *tp = Py_TYPE(obj); + if (unlikely(!PyString_Check(attr_name))) { + return PyObject_GenericGetAttr(obj, attr_name); + } + assert(!tp->tp_dictoffset); + descr = _PyType_Lookup(tp, attr_name); + if (unlikely(!descr)) { + return __Pyx_RaiseGenericGetAttributeError(tp, attr_name); + } + Py_INCREF(descr); + #if PY_MAJOR_VERSION < 3 + if (likely(PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_HAVE_CLASS))) + #endif + { + descrgetfunc f = Py_TYPE(descr)->tp_descr_get; + if (unlikely(f)) { + PyObject *res = f(descr, obj, (PyObject *)tp); + Py_DECREF(descr); + return res; + } + } + return descr; +} +#endif + +/* PyObject_GenericGetAttr */ +#if CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP && PY_VERSION_HEX < 0x03070000 +static PyObject* __Pyx_PyObject_GenericGetAttr(PyObject* obj, PyObject* attr_name) { + if (unlikely(Py_TYPE(obj)->tp_dictoffset)) { + return PyObject_GenericGetAttr(obj, attr_name); + } + return __Pyx_PyObject_GenericGetAttrNoDict(obj, attr_name); +} +#endif + +/* PyObjectGetAttrStrNoError */ +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS && PY_VERSION_HEX >= 0x030700B1 + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +} + +/* SetupReduce */ +static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { + int ret; + PyObject *name_attr; + name_attr = __Pyx_PyObject_GetAttrStr(meth, __pyx_n_s_name); + if (likely(name_attr)) { + ret = PyObject_RichCompareBool(name_attr, name, Py_EQ); + } else { + ret = -1; + } + if (unlikely(ret < 0)) { + PyErr_Clear(); + ret = 0; + } + Py_XDECREF(name_attr); + return ret; +} +static int __Pyx_setup_reduce(PyObject* type_obj) { + int ret = 0; + PyObject *object_reduce = NULL; + PyObject *object_reduce_ex = NULL; + PyObject *reduce = NULL; + PyObject *reduce_ex = NULL; + PyObject *reduce_cython = NULL; + PyObject *setstate = NULL; + PyObject *setstate_cython = NULL; +#if CYTHON_USE_PYTYPE_LOOKUP + if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; +#else + if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; +#endif +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#else + object_reduce_ex = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; +#endif + reduce_ex = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce_ex); if (unlikely(!reduce_ex)) goto __PYX_BAD; + if (reduce_ex == object_reduce_ex) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_reduce = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#else + object_reduce = __Pyx_PyObject_GetAttrStr((PyObject*)&PyBaseObject_Type, __pyx_n_s_reduce); if (!object_reduce) goto __PYX_BAD; +#endif + reduce = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_reduce); if (unlikely(!reduce)) goto __PYX_BAD; + if (reduce == object_reduce || __Pyx_setup_reduce_is_named(reduce, __pyx_n_s_reduce_cython)) { + reduce_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_reduce_cython); + if (likely(reduce_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce, reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_reduce_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (reduce == object_reduce || PyErr_Occurred()) { + goto __PYX_BAD; + } + setstate = __Pyx_PyObject_GetAttrStr(type_obj, __pyx_n_s_setstate); + if (!setstate) PyErr_Clear(); + if (!setstate || __Pyx_setup_reduce_is_named(setstate, __pyx_n_s_setstate_cython)) { + setstate_cython = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_setstate_cython); + if (likely(setstate_cython)) { + ret = PyDict_SetItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate, setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + ret = PyDict_DelItem(((PyTypeObject*)type_obj)->tp_dict, __pyx_n_s_setstate_cython); if (unlikely(ret < 0)) goto __PYX_BAD; + } else if (!setstate || PyErr_Occurred()) { + goto __PYX_BAD; + } + } + PyType_Modified((PyTypeObject*)type_obj); + } + } + goto __PYX_GOOD; +__PYX_BAD: + if (!PyErr_Occurred()) + PyErr_Format(PyExc_RuntimeError, "Unable to initialize pickling for %s", ((PyTypeObject*)type_obj)->tp_name); + ret = -1; +__PYX_GOOD: +#if !CYTHON_USE_PYTYPE_LOOKUP + Py_XDECREF(object_reduce); + Py_XDECREF(object_reduce_ex); +#endif + Py_XDECREF(reduce); + Py_XDECREF(reduce_ex); + Py_XDECREF(reduce_cython); + Py_XDECREF(setstate); + Py_XDECREF(setstate_cython); + return ret; +} + +/* SetVTable */ +static int __Pyx_SetVtable(PyObject *dict, void *vtable) { +#if PY_VERSION_HEX >= 0x02070000 + PyObject *ob = PyCapsule_New(vtable, 0, 0); +#else + PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); +#endif + if (!ob) + goto bad; + if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0) + goto bad; + Py_DECREF(ob); + return 0; +bad: + Py_XDECREF(ob); + return -1; +} + +/* TypeImport */ +#ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, + size_t size, enum __Pyx_ImportType_CheckSize check_size) +{ + PyObject *result = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + result = PyObject_GetAttrString(module, class_name); + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if ((size_t)basicsize < size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(result); + return NULL; +} +#endif + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(int), + little, !is_unsigned); + } +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) { + const unsigned int neg_one = (unsigned int) ((unsigned int) 0 - (unsigned int) 1), const_zero = (unsigned int) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(unsigned int) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(unsigned int) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(unsigned int) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(unsigned int) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(unsigned int) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(unsigned int), + little, !is_unsigned); + } +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value) { + const unsigned short neg_one = (unsigned short) ((unsigned short) 0 - (unsigned short) 1), const_zero = (unsigned short) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(unsigned short) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(unsigned short) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(unsigned short) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(unsigned short) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(unsigned short) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(unsigned short), + little, !is_unsigned); + } +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_uint16_t(uint16_t value) { + const uint16_t neg_one = (uint16_t) ((uint16_t) 0 - (uint16_t) 1), const_zero = (uint16_t) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(uint16_t) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(uint16_t) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(uint16_t) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(uint16_t) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(uint16_t) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(uint16_t), + little, !is_unsigned); + } +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE enum http_method __Pyx_PyInt_As_enum__http_method(PyObject *x) { + const enum http_method neg_one = (enum http_method) ((enum http_method) 0 - (enum http_method) 1), const_zero = (enum http_method) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(enum http_method) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(enum http_method, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (enum http_method) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (enum http_method) 0; + case 1: __PYX_VERIFY_RETURN_INT(enum http_method, digit, digits[0]) + case 2: + if (8 * sizeof(enum http_method) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(enum http_method) >= 2 * PyLong_SHIFT) { + return (enum http_method) (((((enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(enum http_method) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(enum http_method) >= 3 * PyLong_SHIFT) { + return (enum http_method) (((((((enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(enum http_method) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(enum http_method) >= 4 * PyLong_SHIFT) { + return (enum http_method) (((((((((enum http_method)digits[3]) << PyLong_SHIFT) | (enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (enum http_method) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(enum http_method) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(enum http_method, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(enum http_method) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(enum http_method, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (enum http_method) 0; + case -1: __PYX_VERIFY_RETURN_INT(enum http_method, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(enum http_method, digit, +digits[0]) + case -2: + if (8 * sizeof(enum http_method) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(enum http_method, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(enum http_method) - 1 > 2 * PyLong_SHIFT) { + return (enum http_method) (((enum http_method)-1)*(((((enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(enum http_method) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(enum http_method) - 1 > 2 * PyLong_SHIFT) { + return (enum http_method) ((((((enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(enum http_method) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(enum http_method, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(enum http_method) - 1 > 3 * PyLong_SHIFT) { + return (enum http_method) (((enum http_method)-1)*(((((((enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(enum http_method) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(enum http_method) - 1 > 3 * PyLong_SHIFT) { + return (enum http_method) ((((((((enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(enum http_method) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(enum http_method, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(enum http_method) - 1 > 4 * PyLong_SHIFT) { + return (enum http_method) (((enum http_method)-1)*(((((((((enum http_method)digits[3]) << PyLong_SHIFT) | (enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(enum http_method) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(enum http_method, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(enum http_method) - 1 > 4 * PyLong_SHIFT) { + return (enum http_method) ((((((((((enum http_method)digits[3]) << PyLong_SHIFT) | (enum http_method)digits[2]) << PyLong_SHIFT) | (enum http_method)digits[1]) << PyLong_SHIFT) | (enum http_method)digits[0]))); + } + } + break; + } +#endif + if (sizeof(enum http_method) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(enum http_method, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(enum http_method) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(enum http_method, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + enum http_method val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (enum http_method) -1; + } + } else { + enum http_method val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (enum http_method) -1; + val = __Pyx_PyInt_As_enum__http_method(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to enum http_method"); + return (enum http_method) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to enum http_method"); + return (enum http_method) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) { + const size_t neg_one = (size_t) ((size_t) 0 - (size_t) 1), const_zero = (size_t) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(size_t) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(size_t, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (size_t) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (size_t) 0; + case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, digits[0]) + case 2: + if (8 * sizeof(size_t) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) >= 2 * PyLong_SHIFT) { + return (size_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(size_t) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) >= 3 * PyLong_SHIFT) { + return (size_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(size_t) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) >= 4 * PyLong_SHIFT) { + return (size_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (size_t) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(size_t) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(size_t) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (size_t) 0; + case -1: __PYX_VERIFY_RETURN_INT(size_t, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, +digits[0]) + case -2: + if (8 * sizeof(size_t) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { + return (size_t) (((size_t)-1)*(((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(size_t) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { + return (size_t) ((((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(size_t) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { + return (size_t) (((size_t)-1)*(((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(size_t) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { + return (size_t) ((((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(size_t) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT) { + return (size_t) (((size_t)-1)*(((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(size_t) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(size_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(size_t) - 1 > 4 * PyLong_SHIFT) { + return (size_t) ((((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]))); + } + } + break; + } +#endif + if (sizeof(size_t) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(size_t) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(size_t, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + size_t val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (size_t) -1; + } + } else { + size_t val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (size_t) -1; + val = __Pyx_PyInt_As_size_t(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to size_t"); + return (size_t) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to size_t"); + return (size_t) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = a->tp_base; + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; + if (!res) { + res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } + return res; +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; itp_name); + if (cached_type) { + if (!PyType_Check((PyObject*)cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", + type->tp_name); + goto bad; + } + if (cached_type->tp_basicsize != type->tp_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + type->tp_name); + goto bad; + } + } else { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; + PyErr_Clear(); + if (PyType_Ready(type) < 0) goto bad; + if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0) + goto bad; + Py_INCREF(type); + cached_type = type; + } +done: + Py_DECREF(fake_module); + return cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} + +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (descr != NULL) { + *method = descr; + return 0; + } + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(name)); +#endif + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} + +/* PyObjectCallMethod1 */ +static PyObject* __Pyx__PyObject_CallMethod1(PyObject* method, PyObject* arg) { + PyObject *result = __Pyx_PyObject_CallOneArg(method, arg); + Py_DECREF(method); + return result; +} +static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { + PyObject *method = NULL, *result; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_Call2Args(method, obj, arg); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) return NULL; + return __Pyx__PyObject_CallMethod1(method, arg); +} + +/* CoroutineBase */ +#include +#include +#define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom) +static int __Pyx_PyGen__FetchStopIterationValue(CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject **pvalue) { + PyObject *et, *ev, *tb; + PyObject *value = NULL; + __Pyx_ErrFetch(&et, &ev, &tb); + if (!et) { + Py_XDECREF(tb); + Py_XDECREF(ev); + Py_INCREF(Py_None); + *pvalue = Py_None; + return 0; + } + if (likely(et == PyExc_StopIteration)) { + if (!ev) { + Py_INCREF(Py_None); + value = Py_None; + } +#if PY_VERSION_HEX >= 0x030300A0 + else if (Py_TYPE(ev) == (PyTypeObject*)PyExc_StopIteration) { + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); + } +#endif + else if (unlikely(PyTuple_Check(ev))) { + if (PyTuple_GET_SIZE(ev) >= 1) { +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + value = PyTuple_GET_ITEM(ev, 0); + Py_INCREF(value); +#else + value = PySequence_ITEM(ev, 0); +#endif + } else { + Py_INCREF(Py_None); + value = Py_None; + } + Py_DECREF(ev); + } + else if (!__Pyx_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) { + value = ev; + } + if (likely(value)) { + Py_XDECREF(tb); + Py_DECREF(et); + *pvalue = value; + return 0; + } + } else if (!__Pyx_PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + PyErr_NormalizeException(&et, &ev, &tb); + if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) { + __Pyx_ErrRestore(et, ev, tb); + return -1; + } + Py_XDECREF(tb); + Py_DECREF(et); +#if PY_VERSION_HEX >= 0x030300A0 + value = ((PyStopIterationObject *)ev)->value; + Py_INCREF(value); + Py_DECREF(ev); +#else + { + PyObject* args = __Pyx_PyObject_GetAttrStr(ev, __pyx_n_s_args); + Py_DECREF(ev); + if (likely(args)) { + value = PySequence_GetItem(args, 0); + Py_DECREF(args); + } + if (unlikely(!value)) { + __Pyx_ErrRestore(NULL, NULL, NULL); + Py_INCREF(Py_None); + value = Py_None; + } + } +#endif + *pvalue = value; + return 0; +} +static CYTHON_INLINE +void __Pyx_Coroutine_ExceptionClear(__Pyx_ExcInfoStruct *exc_state) { + PyObject *t, *v, *tb; + t = exc_state->exc_type; + v = exc_state->exc_value; + tb = exc_state->exc_traceback; + exc_state->exc_type = NULL; + exc_state->exc_value = NULL; + exc_state->exc_traceback = NULL; + Py_XDECREF(t); + Py_XDECREF(v); + Py_XDECREF(tb); +} +#define __Pyx_Coroutine_AlreadyRunningError(gen) (__Pyx__Coroutine_AlreadyRunningError(gen), (PyObject*)NULL) +static void __Pyx__Coroutine_AlreadyRunningError(CYTHON_UNUSED __pyx_CoroutineObject *gen) { + const char *msg; + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check((PyObject*)gen)) { + msg = "coroutine already executing"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact((PyObject*)gen)) { + msg = "async generator already executing"; + #endif + } else { + msg = "generator already executing"; + } + PyErr_SetString(PyExc_ValueError, msg); +} +#define __Pyx_Coroutine_NotStartedError(gen) (__Pyx__Coroutine_NotStartedError(gen), (PyObject*)NULL) +static void __Pyx__Coroutine_NotStartedError(CYTHON_UNUSED PyObject *gen) { + const char *msg; + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check(gen)) { + msg = "can't send non-None value to a just-started coroutine"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact(gen)) { + msg = "can't send non-None value to a just-started async generator"; + #endif + } else { + msg = "can't send non-None value to a just-started generator"; + } + PyErr_SetString(PyExc_TypeError, msg); +} +#define __Pyx_Coroutine_AlreadyTerminatedError(gen, value, closing) (__Pyx__Coroutine_AlreadyTerminatedError(gen, value, closing), (PyObject*)NULL) +static void __Pyx__Coroutine_AlreadyTerminatedError(CYTHON_UNUSED PyObject *gen, PyObject *value, CYTHON_UNUSED int closing) { + #ifdef __Pyx_Coroutine_USED + if (!closing && __Pyx_Coroutine_Check(gen)) { + PyErr_SetString(PyExc_RuntimeError, "cannot reuse already awaited coroutine"); + } else + #endif + if (value) { + #ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(gen)) + PyErr_SetNone(__Pyx_PyExc_StopAsyncIteration); + else + #endif + PyErr_SetNone(PyExc_StopIteration); + } +} +static +PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value, int closing) { + __Pyx_PyThreadState_declare + PyThreadState *tstate; + __Pyx_ExcInfoStruct *exc_state; + PyObject *retval; + assert(!self->is_running); + if (unlikely(self->resume_label == 0)) { + if (unlikely(value && value != Py_None)) { + return __Pyx_Coroutine_NotStartedError((PyObject*)self); + } + } + if (unlikely(self->resume_label == -1)) { + return __Pyx_Coroutine_AlreadyTerminatedError((PyObject*)self, value, closing); + } +#if CYTHON_FAST_THREAD_STATE + __Pyx_PyThreadState_assign + tstate = __pyx_tstate; +#else + tstate = __Pyx_PyThreadState_Current; +#endif + exc_state = &self->gi_exc_state; + if (exc_state->exc_type) { + #if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON + #else + if (exc_state->exc_traceback) { + PyTracebackObject *tb = (PyTracebackObject *) exc_state->exc_traceback; + PyFrameObject *f = tb->tb_frame; + Py_XINCREF(tstate->frame); + assert(f->f_back == NULL); + f->f_back = tstate->frame; + } + #endif + } +#if CYTHON_USE_EXC_INFO_STACK + exc_state->previous_item = tstate->exc_info; + tstate->exc_info = exc_state; +#else + if (exc_state->exc_type) { + __Pyx_ExceptionSwap(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } else { + __Pyx_Coroutine_ExceptionClear(exc_state); + __Pyx_ExceptionSave(&exc_state->exc_type, &exc_state->exc_value, &exc_state->exc_traceback); + } +#endif + self->is_running = 1; + retval = self->body((PyObject *) self, tstate, value); + self->is_running = 0; +#if CYTHON_USE_EXC_INFO_STACK + exc_state = &self->gi_exc_state; + tstate->exc_info = exc_state->previous_item; + exc_state->previous_item = NULL; + __Pyx_Coroutine_ResetFrameBackpointer(exc_state); +#endif + return retval; +} +static CYTHON_INLINE void __Pyx_Coroutine_ResetFrameBackpointer(__Pyx_ExcInfoStruct *exc_state) { + PyObject *exc_tb = exc_state->exc_traceback; + if (likely(exc_tb)) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON +#else + PyTracebackObject *tb = (PyTracebackObject *) exc_tb; + PyFrameObject *f = tb->tb_frame; + Py_CLEAR(f->f_back); +#endif + } +} +static CYTHON_INLINE +PyObject *__Pyx_Coroutine_MethodReturn(CYTHON_UNUSED PyObject* gen, PyObject *retval) { + if (unlikely(!retval)) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (!__Pyx_PyErr_Occurred()) { + PyObject *exc = PyExc_StopIteration; + #ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(gen)) + exc = __Pyx_PyExc_StopAsyncIteration; + #endif + __Pyx_PyErr_SetNone(exc); + } + } + return retval; +} +static CYTHON_INLINE +PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) { + PyObject *ret; + PyObject *val = NULL; + __Pyx_Coroutine_Undelegate(gen); + __Pyx_PyGen__FetchStopIterationValue(__Pyx_PyThreadState_Current, &val); + ret = __Pyx_Coroutine_SendEx(gen, val, 0); + Py_XDECREF(val); + return ret; +} +static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) { + PyObject *retval; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + gen->is_running = 1; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + ret = __Pyx_Coroutine_Send(yf, value); + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + ret = __Pyx_async_gen_asend_send(yf, value); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyGen_CheckExact(yf)) { + ret = _PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03050000 && defined(PyCoro_CheckExact) && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyCoro_CheckExact(yf)) { + ret = _PyGen_Send((PyGenObject*)yf, value == Py_None ? NULL : value); + } else + #endif + { + if (value == Py_None) + ret = Py_TYPE(yf)->tp_iternext(yf); + else + ret = __Pyx_PyObject_CallMethod1(yf, __pyx_n_s_send, value); + } + gen->is_running = 0; + if (likely(ret)) { + return ret; + } + retval = __Pyx_Coroutine_FinishDelegation(gen); + } else { + retval = __Pyx_Coroutine_SendEx(gen, value, 0); + } + return __Pyx_Coroutine_MethodReturn(self, retval); +} +static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) { + PyObject *retval = NULL; + int err = 0; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + retval = __Pyx_Coroutine_Close(yf); + if (!retval) + return -1; + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + retval = __Pyx_Coroutine_Close(yf); + if (!retval) + return -1; + } else + if (__Pyx_CoroutineAwait_CheckExact(yf)) { + retval = __Pyx_CoroutineAwait_Close((__pyx_CoroutineAwaitObject*)yf, NULL); + if (!retval) + return -1; + } else + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_PyAsyncGenASend_CheckExact(yf)) { + retval = __Pyx_async_gen_asend_close(yf, NULL); + } else + if (__pyx_PyAsyncGenAThrow_CheckExact(yf)) { + retval = __Pyx_async_gen_athrow_close(yf, NULL); + } else + #endif + { + PyObject *meth; + gen->is_running = 1; + meth = __Pyx_PyObject_GetAttrStr(yf, __pyx_n_s_close); + if (unlikely(!meth)) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_WriteUnraisable(yf); + } + PyErr_Clear(); + } else { + retval = PyObject_CallFunction(meth, NULL); + Py_DECREF(meth); + if (!retval) + err = -1; + } + gen->is_running = 0; + } + Py_XDECREF(retval); + return err; +} +static PyObject *__Pyx_Generator_Next(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + gen->is_running = 1; + #ifdef __Pyx_Generator_USED + if (__Pyx_Generator_CheckExact(yf)) { + ret = __Pyx_Generator_Next(yf); + } else + #endif + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03030000 && (defined(__linux__) || PY_VERSION_HEX >= 0x030600B3) + if (PyGen_CheckExact(yf)) { + ret = _PyGen_Send((PyGenObject*)yf, NULL); + } else + #endif + #ifdef __Pyx_Coroutine_USED + if (__Pyx_Coroutine_Check(yf)) { + ret = __Pyx_Coroutine_Send(yf, Py_None); + } else + #endif + ret = Py_TYPE(yf)->tp_iternext(yf); + gen->is_running = 0; + if (likely(ret)) { + return ret; + } + return __Pyx_Coroutine_FinishDelegation(gen); + } + return __Pyx_Coroutine_SendEx(gen, Py_None, 0); +} +static PyObject *__Pyx_Coroutine_Close_Method(PyObject *self, CYTHON_UNUSED PyObject *arg) { + return __Pyx_Coroutine_Close(self); +} +static PyObject *__Pyx_Coroutine_Close(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject *retval, *raised_exception; + PyObject *yf = gen->yieldfrom; + int err = 0; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + Py_INCREF(yf); + err = __Pyx_Coroutine_CloseIter(gen, yf); + __Pyx_Coroutine_Undelegate(gen); + Py_DECREF(yf); + } + if (err == 0) + PyErr_SetNone(PyExc_GeneratorExit); + retval = __Pyx_Coroutine_SendEx(gen, NULL, 1); + if (unlikely(retval)) { + const char *msg; + Py_DECREF(retval); + if ((0)) { + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_Coroutine_Check(self)) { + msg = "coroutine ignored GeneratorExit"; + #endif + #ifdef __Pyx_AsyncGen_USED + } else if (__Pyx_AsyncGen_CheckExact(self)) { +#if PY_VERSION_HEX < 0x03060000 + msg = "async generator ignored GeneratorExit - might require Python 3.6+ finalisation (PEP 525)"; +#else + msg = "async generator ignored GeneratorExit"; +#endif + #endif + } else { + msg = "generator ignored GeneratorExit"; + } + PyErr_SetString(PyExc_RuntimeError, msg); + return NULL; + } + raised_exception = PyErr_Occurred(); + if (likely(!raised_exception || __Pyx_PyErr_GivenExceptionMatches2(raised_exception, PyExc_GeneratorExit, PyExc_StopIteration))) { + if (raised_exception) PyErr_Clear(); + Py_INCREF(Py_None); + return Py_None; + } + return NULL; +} +static PyObject *__Pyx__Coroutine_Throw(PyObject *self, PyObject *typ, PyObject *val, PyObject *tb, + PyObject *args, int close_on_genexit) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject *yf = gen->yieldfrom; + if (unlikely(gen->is_running)) + return __Pyx_Coroutine_AlreadyRunningError(gen); + if (yf) { + PyObject *ret; + Py_INCREF(yf); + if (__Pyx_PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && close_on_genexit) { + int err = __Pyx_Coroutine_CloseIter(gen, yf); + Py_DECREF(yf); + __Pyx_Coroutine_Undelegate(gen); + if (err < 0) + return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); + goto throw_here; + } + gen->is_running = 1; + if (0 + #ifdef __Pyx_Generator_USED + || __Pyx_Generator_CheckExact(yf) + #endif + #ifdef __Pyx_Coroutine_USED + || __Pyx_Coroutine_Check(yf) + #endif + ) { + ret = __Pyx__Coroutine_Throw(yf, typ, val, tb, args, close_on_genexit); + #ifdef __Pyx_Coroutine_USED + } else if (__Pyx_CoroutineAwait_CheckExact(yf)) { + ret = __Pyx__Coroutine_Throw(((__pyx_CoroutineAwaitObject*)yf)->coroutine, typ, val, tb, args, close_on_genexit); + #endif + } else { + PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, __pyx_n_s_throw); + if (unlikely(!meth)) { + Py_DECREF(yf); + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + gen->is_running = 0; + return NULL; + } + PyErr_Clear(); + __Pyx_Coroutine_Undelegate(gen); + gen->is_running = 0; + goto throw_here; + } + if (likely(args)) { + ret = PyObject_CallObject(meth, args); + } else { + ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL); + } + Py_DECREF(meth); + } + gen->is_running = 0; + Py_DECREF(yf); + if (!ret) { + ret = __Pyx_Coroutine_FinishDelegation(gen); + } + return __Pyx_Coroutine_MethodReturn(self, ret); + } +throw_here: + __Pyx_Raise(typ, val, tb, NULL); + return __Pyx_Coroutine_MethodReturn(self, __Pyx_Coroutine_SendEx(gen, NULL, 0)); +} +static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) { + PyObject *typ; + PyObject *val = NULL; + PyObject *tb = NULL; + if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb)) + return NULL; + return __Pyx__Coroutine_Throw(self, typ, val, tb, args, 1); +} +static CYTHON_INLINE int __Pyx_Coroutine_traverse_excstate(__Pyx_ExcInfoStruct *exc_state, visitproc visit, void *arg) { + Py_VISIT(exc_state->exc_type); + Py_VISIT(exc_state->exc_value); + Py_VISIT(exc_state->exc_traceback); + return 0; +} +static int __Pyx_Coroutine_traverse(__pyx_CoroutineObject *gen, visitproc visit, void *arg) { + Py_VISIT(gen->closure); + Py_VISIT(gen->classobj); + Py_VISIT(gen->yieldfrom); + return __Pyx_Coroutine_traverse_excstate(&gen->gi_exc_state, visit, arg); +} +static int __Pyx_Coroutine_clear(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + Py_CLEAR(gen->closure); + Py_CLEAR(gen->classobj); + Py_CLEAR(gen->yieldfrom); + __Pyx_Coroutine_ExceptionClear(&gen->gi_exc_state); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + Py_CLEAR(((__pyx_PyAsyncGenObject*)gen)->ag_finalizer); + } +#endif + Py_CLEAR(gen->gi_code); + Py_CLEAR(gen->gi_name); + Py_CLEAR(gen->gi_qualname); + Py_CLEAR(gen->gi_modulename); + return 0; +} +static void __Pyx_Coroutine_dealloc(PyObject *self) { + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + PyObject_GC_UnTrack(gen); + if (gen->gi_weakreflist != NULL) + PyObject_ClearWeakRefs(self); + if (gen->resume_label >= 0) { + PyObject_GC_Track(self); +#if PY_VERSION_HEX >= 0x030400a1 && CYTHON_USE_TP_FINALIZE + if (PyObject_CallFinalizerFromDealloc(self)) +#else + Py_TYPE(gen)->tp_del(self); + if (self->ob_refcnt > 0) +#endif + { + return; + } + PyObject_GC_UnTrack(self); + } +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + /* We have to handle this case for asynchronous generators + right here, because this code has to be between UNTRACK + and GC_Del. */ + Py_CLEAR(((__pyx_PyAsyncGenObject*)self)->ag_finalizer); + } +#endif + __Pyx_Coroutine_clear(self); + PyObject_GC_Del(gen); +} +static void __Pyx_Coroutine_del(PyObject *self) { + PyObject *error_type, *error_value, *error_traceback; + __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; + __Pyx_PyThreadState_declare + if (gen->resume_label < 0) { + return; + } +#if !CYTHON_USE_TP_FINALIZE + assert(self->ob_refcnt == 0); + self->ob_refcnt = 1; +#endif + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&error_type, &error_value, &error_traceback); +#ifdef __Pyx_AsyncGen_USED + if (__Pyx_AsyncGen_CheckExact(self)) { + __pyx_PyAsyncGenObject *agen = (__pyx_PyAsyncGenObject*)self; + PyObject *finalizer = agen->ag_finalizer; + if (finalizer && !agen->ag_closed) { + PyObject *res = __Pyx_PyObject_CallOneArg(finalizer, self); + if (unlikely(!res)) { + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); + return; + } + } +#endif + if (unlikely(gen->resume_label == 0 && !error_value)) { +#ifdef __Pyx_Coroutine_USED +#ifdef __Pyx_Generator_USED + if (!__Pyx_Generator_CheckExact(self)) +#endif + { + PyObject_GC_UnTrack(self); +#if PY_MAJOR_VERSION >= 3 || defined(PyErr_WarnFormat) + if (unlikely(PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname) < 0)) + PyErr_WriteUnraisable(self); +#else + {PyObject *msg; + char *cmsg; + #if CYTHON_COMPILING_IN_PYPY + msg = NULL; + cmsg = (char*) "coroutine was never awaited"; + #else + char *cname; + PyObject *qualname; + qualname = gen->gi_qualname; + cname = PyString_AS_STRING(qualname); + msg = PyString_FromFormat("coroutine '%.50s' was never awaited", cname); + if (unlikely(!msg)) { + PyErr_Clear(); + cmsg = (char*) "coroutine was never awaited"; + } else { + cmsg = PyString_AS_STRING(msg); + } + #endif + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0)) + PyErr_WriteUnraisable(self); + Py_XDECREF(msg);} +#endif + PyObject_GC_Track(self); + } +#endif + } else { + PyObject *res = __Pyx_Coroutine_Close(self); + if (unlikely(!res)) { + if (PyErr_Occurred()) + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + } + __Pyx_ErrRestore(error_type, error_value, error_traceback); +#if !CYTHON_USE_TP_FINALIZE + assert(self->ob_refcnt > 0); + if (--self->ob_refcnt == 0) { + return; + } + { + Py_ssize_t refcnt = self->ob_refcnt; + _Py_NewReference(self); + self->ob_refcnt = refcnt; + } +#if CYTHON_COMPILING_IN_CPYTHON + assert(PyType_IS_GC(self->ob_type) && + _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED); + _Py_DEC_REFTOTAL; +#endif +#ifdef COUNT_ALLOCS + --Py_TYPE(self)->tp_frees; + --Py_TYPE(self)->tp_allocs; +#endif +#endif +} +static PyObject * +__Pyx_Coroutine_get_name(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context) +{ + PyObject *name = self->gi_name; + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context) +{ + PyObject *tmp; +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + tmp = self->gi_name; + Py_INCREF(value); + self->gi_name = value; + Py_XDECREF(tmp); + return 0; +} +static PyObject * +__Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self, CYTHON_UNUSED void *context) +{ + PyObject *name = self->gi_qualname; + if (unlikely(!name)) name = Py_None; + Py_INCREF(name); + return name; +} +static int +__Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value, CYTHON_UNUSED void *context) +{ + PyObject *tmp; +#if PY_MAJOR_VERSION >= 3 + if (unlikely(value == NULL || !PyUnicode_Check(value))) +#else + if (unlikely(value == NULL || !PyString_Check(value))) +#endif + { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + tmp = self->gi_qualname; + Py_INCREF(value); + self->gi_qualname = value; + Py_XDECREF(tmp); + return 0; +} +static __pyx_CoroutineObject *__Pyx__Coroutine_New( + PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type); + if (unlikely(!gen)) + return NULL; + return __Pyx__Coroutine_NewInit(gen, body, code, closure, name, qualname, module_name); +} +static __pyx_CoroutineObject *__Pyx__Coroutine_NewInit( + __pyx_CoroutineObject *gen, __pyx_coroutine_body_t body, PyObject *code, PyObject *closure, + PyObject *name, PyObject *qualname, PyObject *module_name) { + gen->body = body; + gen->closure = closure; + Py_XINCREF(closure); + gen->is_running = 0; + gen->resume_label = 0; + gen->classobj = NULL; + gen->yieldfrom = NULL; + gen->gi_exc_state.exc_type = NULL; + gen->gi_exc_state.exc_value = NULL; + gen->gi_exc_state.exc_traceback = NULL; +#if CYTHON_USE_EXC_INFO_STACK + gen->gi_exc_state.previous_item = NULL; +#endif + gen->gi_weakreflist = NULL; + Py_XINCREF(qualname); + gen->gi_qualname = qualname; + Py_XINCREF(name); + gen->gi_name = name; + Py_XINCREF(module_name); + gen->gi_modulename = module_name; + Py_XINCREF(code); + gen->gi_code = code; + PyObject_GC_Track(gen); + return gen; +} + +/* PatchModuleWithCoroutine */ +static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) { +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + int result; + PyObject *globals, *result_obj; + globals = PyDict_New(); if (unlikely(!globals)) goto ignore; + result = PyDict_SetItemString(globals, "_cython_coroutine_type", + #ifdef __Pyx_Coroutine_USED + (PyObject*)__pyx_CoroutineType); + #else + Py_None); + #endif + if (unlikely(result < 0)) goto ignore; + result = PyDict_SetItemString(globals, "_cython_generator_type", + #ifdef __Pyx_Generator_USED + (PyObject*)__pyx_GeneratorType); + #else + Py_None); + #endif + if (unlikely(result < 0)) goto ignore; + if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore; + if (unlikely(PyDict_SetItemString(globals, "__builtins__", __pyx_b) < 0)) goto ignore; + result_obj = PyRun_String(py_code, Py_file_input, globals, globals); + if (unlikely(!result_obj)) goto ignore; + Py_DECREF(result_obj); + Py_DECREF(globals); + return module; +ignore: + Py_XDECREF(globals); + PyErr_WriteUnraisable(module); + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) { + Py_DECREF(module); + module = NULL; + } +#else + py_code++; +#endif + return module; +} + +/* PatchGeneratorABC */ +#ifndef CYTHON_REGISTER_ABCS +#define CYTHON_REGISTER_ABCS 1 +#endif +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) +static PyObject* __Pyx_patch_abc_module(PyObject *module); +static PyObject* __Pyx_patch_abc_module(PyObject *module) { + module = __Pyx_Coroutine_patch_module( + module, "" +"if _cython_generator_type is not None:\n" +" try: Generator = _module.Generator\n" +" except AttributeError: pass\n" +" else: Generator.register(_cython_generator_type)\n" +"if _cython_coroutine_type is not None:\n" +" try: Coroutine = _module.Coroutine\n" +" except AttributeError: pass\n" +" else: Coroutine.register(_cython_coroutine_type)\n" + ); + return module; +} +#endif +static int __Pyx_patch_abc(void) { +#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + static int abc_patched = 0; + if (CYTHON_REGISTER_ABCS && !abc_patched) { + PyObject *module; + module = PyImport_ImportModule((PY_MAJOR_VERSION >= 3) ? "collections.abc" : "collections"); + if (!module) { + PyErr_WriteUnraisable(NULL); + if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, + ((PY_MAJOR_VERSION >= 3) ? + "Cython module failed to register with collections.abc module" : + "Cython module failed to register with collections module"), 1) < 0)) { + return -1; + } + } else { + module = __Pyx_patch_abc_module(module); + abc_patched = 1; + if (unlikely(!module)) + return -1; + Py_DECREF(module); + } + module = PyImport_ImportModule("backports_abc"); + if (module) { + module = __Pyx_patch_abc_module(module); + Py_XDECREF(module); + } + if (!module) { + PyErr_Clear(); + } + } +#else + if ((0)) __Pyx_Coroutine_patch_module(NULL, NULL); +#endif + return 0; +} + +/* Generator */ +static PyMethodDef __pyx_Generator_methods[] = { + {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, + (char*) PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")}, + {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, + (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")}, + {"close", (PyCFunction) __Pyx_Coroutine_Close_Method, METH_NOARGS, + (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")}, + {0, 0, 0, 0} +}; +static PyMemberDef __pyx_Generator_memberlist[] = { + {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL}, + {(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY, + (char*) PyDoc_STR("object being iterated by 'yield from', or None")}, + {(char*) "gi_code", T_OBJECT, offsetof(__pyx_CoroutineObject, gi_code), READONLY, NULL}, + {0, 0, 0, 0, 0} +}; +static PyGetSetDef __pyx_Generator_getsets[] = { + {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name, + (char*) PyDoc_STR("name of the generator"), 0}, + {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname, + (char*) PyDoc_STR("qualified name of the generator"), 0}, + {0, 0, 0, 0, 0} +}; +static PyTypeObject __pyx_GeneratorType_type = { + PyVarObject_HEAD_INIT(0, 0) + "generator", + sizeof(__pyx_CoroutineObject), + 0, + (destructor) __Pyx_Coroutine_dealloc, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + 0, + (traverseproc) __Pyx_Coroutine_traverse, + 0, + 0, + offsetof(__pyx_CoroutineObject, gi_weakreflist), + 0, + (iternextfunc) __Pyx_Generator_Next, + __pyx_Generator_methods, + __pyx_Generator_memberlist, + __pyx_Generator_getsets, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +#if CYTHON_USE_TP_FINALIZE + 0, +#else + __Pyx_Coroutine_del, +#endif + 0, +#if CYTHON_USE_TP_FINALIZE + __Pyx_Coroutine_del, +#elif PY_VERSION_HEX >= 0x030400a1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b1 + 0, +#endif +#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000 + 0, +#endif +}; +static int __pyx_Generator_init(void) { + __pyx_GeneratorType_type.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict; + __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter; + __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type); + if (unlikely(!__pyx_GeneratorType)) { + return -1; + } + return 0; +} + +/* CheckBinaryVersion */ +static int __Pyx_check_binary_version(void) { + char ctversion[4], rtversion[4]; + PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); + PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); + if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compiletime version %s of module '%.100s' " + "does not match runtime version %s", + ctversion, __Pyx_MODULE_NAME, rtversion); + return PyErr_WarnEx(NULL, message, 1); + } + return 0; +} + +/* InitStrings */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { + while (t->p) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + type_name, type_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_parser.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_http_parser.cp39-win_amd64.pyd new file mode 100644 index 0000000..61fc602 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/_http_parser.cp39-win_amd64.pyd differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_parser.pyx b/dist/ba_data/python-site-packages/aiohttp/_http_parser.pyx new file mode 100644 index 0000000..c24e310 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_http_parser.pyx @@ -0,0 +1,875 @@ +#cython: language_level=3 +# +# Based on https://github.com/MagicStack/httptools +# +from __future__ import absolute_import, print_function + +from cpython cimport ( + Py_buffer, + PyBUF_SIMPLE, + PyBuffer_Release, + PyBytes_AsString, + PyBytes_AsStringAndSize, + PyObject_GetBuffer, +) +from cpython.mem cimport PyMem_Free, PyMem_Malloc +from libc.limits cimport ULLONG_MAX +from libc.string cimport memcpy + +from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiDictProxy +from yarl import URL as _URL + +from aiohttp import hdrs + +from .http_exceptions import ( + BadHttpMessage, + BadStatusLine, + ContentLengthError, + InvalidHeader, + InvalidURLError, + LineTooLong, + PayloadEncodingError, + TransferEncodingError, +) +from .http_parser import DeflateBuffer as _DeflateBuffer +from .http_writer import ( + HttpVersion as _HttpVersion, + HttpVersion10 as _HttpVersion10, + HttpVersion11 as _HttpVersion11, +) +from .streams import EMPTY_PAYLOAD as _EMPTY_PAYLOAD, StreamReader as _StreamReader + +cimport cython + +from aiohttp cimport _cparser as cparser + +include "_headers.pxi" + +from aiohttp cimport _find_header + +DEF DEFAULT_FREELIST_SIZE = 250 + +cdef extern from "Python.h": + int PyByteArray_Resize(object, Py_ssize_t) except -1 + Py_ssize_t PyByteArray_Size(object) except -1 + char* PyByteArray_AsString(object) + +__all__ = ('HttpRequestParser', 'HttpResponseParser', + 'RawRequestMessage', 'RawResponseMessage') + +cdef object URL = _URL +cdef object URL_build = URL.build +cdef object CIMultiDict = _CIMultiDict +cdef object CIMultiDictProxy = _CIMultiDictProxy +cdef object HttpVersion = _HttpVersion +cdef object HttpVersion10 = _HttpVersion10 +cdef object HttpVersion11 = _HttpVersion11 +cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1 +cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING +cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD +cdef object StreamReader = _StreamReader +cdef object DeflateBuffer = _DeflateBuffer + + +cdef inline object extend(object buf, const char* at, size_t length): + cdef Py_ssize_t s + cdef char* ptr + s = PyByteArray_Size(buf) + PyByteArray_Resize(buf, s + length) + ptr = PyByteArray_AsString(buf) + memcpy(ptr + s, at, length) + + +DEF METHODS_COUNT = 34; + +cdef list _http_method = [] + +for i in range(METHODS_COUNT): + _http_method.append( + cparser.http_method_str( i).decode('ascii')) + + +cdef inline str http_method_str(int i): + if i < METHODS_COUNT: + return _http_method[i] + else: + return "" + +cdef inline object find_header(bytes raw_header): + cdef Py_ssize_t size + cdef char *buf + cdef int idx + PyBytes_AsStringAndSize(raw_header, &buf, &size) + idx = _find_header.find_header(buf, size) + if idx == -1: + return raw_header.decode('utf-8', 'surrogateescape') + return headers[idx] + + +@cython.freelist(DEFAULT_FREELIST_SIZE) +cdef class RawRequestMessage: + cdef readonly str method + cdef readonly str path + cdef readonly object version # HttpVersion + cdef readonly object headers # CIMultiDict + cdef readonly object raw_headers # tuple + cdef readonly object should_close + cdef readonly object compression + cdef readonly object upgrade + cdef readonly object chunked + cdef readonly object url # yarl.URL + + def __init__(self, method, path, version, headers, raw_headers, + should_close, compression, upgrade, chunked, url): + self.method = method + self.path = path + self.version = version + self.headers = headers + self.raw_headers = raw_headers + self.should_close = should_close + self.compression = compression + self.upgrade = upgrade + self.chunked = chunked + self.url = url + + def __repr__(self): + info = [] + info.append(("method", self.method)) + info.append(("path", self.path)) + info.append(("version", self.version)) + info.append(("headers", self.headers)) + info.append(("raw_headers", self.raw_headers)) + info.append(("should_close", self.should_close)) + info.append(("compression", self.compression)) + info.append(("upgrade", self.upgrade)) + info.append(("chunked", self.chunked)) + info.append(("url", self.url)) + sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + return '' + + def _replace(self, **dct): + cdef RawRequestMessage ret + ret = _new_request_message(self.method, + self.path, + self.version, + self.headers, + self.raw_headers, + self.should_close, + self.compression, + self.upgrade, + self.chunked, + self.url) + if "method" in dct: + ret.method = dct["method"] + if "path" in dct: + ret.path = dct["path"] + if "version" in dct: + ret.version = dct["version"] + if "headers" in dct: + ret.headers = dct["headers"] + if "raw_headers" in dct: + ret.raw_headers = dct["raw_headers"] + if "should_close" in dct: + ret.should_close = dct["should_close"] + if "compression" in dct: + ret.compression = dct["compression"] + if "upgrade" in dct: + ret.upgrade = dct["upgrade"] + if "chunked" in dct: + ret.chunked = dct["chunked"] + if "url" in dct: + ret.url = dct["url"] + return ret + +cdef _new_request_message(str method, + str path, + object version, + object headers, + object raw_headers, + bint should_close, + object compression, + bint upgrade, + bint chunked, + object url): + cdef RawRequestMessage ret + ret = RawRequestMessage.__new__(RawRequestMessage) + ret.method = method + ret.path = path + ret.version = version + ret.headers = headers + ret.raw_headers = raw_headers + ret.should_close = should_close + ret.compression = compression + ret.upgrade = upgrade + ret.chunked = chunked + ret.url = url + return ret + + +@cython.freelist(DEFAULT_FREELIST_SIZE) +cdef class RawResponseMessage: + cdef readonly object version # HttpVersion + cdef readonly int code + cdef readonly str reason + cdef readonly object headers # CIMultiDict + cdef readonly object raw_headers # tuple + cdef readonly object should_close + cdef readonly object compression + cdef readonly object upgrade + cdef readonly object chunked + + def __init__(self, version, code, reason, headers, raw_headers, + should_close, compression, upgrade, chunked): + self.version = version + self.code = code + self.reason = reason + self.headers = headers + self.raw_headers = raw_headers + self.should_close = should_close + self.compression = compression + self.upgrade = upgrade + self.chunked = chunked + + def __repr__(self): + info = [] + info.append(("version", self.version)) + info.append(("code", self.code)) + info.append(("reason", self.reason)) + info.append(("headers", self.headers)) + info.append(("raw_headers", self.raw_headers)) + info.append(("should_close", self.should_close)) + info.append(("compression", self.compression)) + info.append(("upgrade", self.upgrade)) + info.append(("chunked", self.chunked)) + sinfo = ', '.join(name + '=' + repr(val) for name, val in info) + return '' + + +cdef _new_response_message(object version, + int code, + str reason, + object headers, + object raw_headers, + bint should_close, + object compression, + bint upgrade, + bint chunked): + cdef RawResponseMessage ret + ret = RawResponseMessage.__new__(RawResponseMessage) + ret.version = version + ret.code = code + ret.reason = reason + ret.headers = headers + ret.raw_headers = raw_headers + ret.should_close = should_close + ret.compression = compression + ret.upgrade = upgrade + ret.chunked = chunked + return ret + + +@cython.internal +cdef class HttpParser: + + cdef: + cparser.http_parser* _cparser + cparser.http_parser_settings* _csettings + + bytearray _raw_name + bytearray _raw_value + bint _has_value + + object _protocol + object _loop + object _timer + + size_t _max_line_size + size_t _max_field_size + size_t _max_headers + bint _response_with_body + bint _read_until_eof + + bint _started + object _url + bytearray _buf + str _path + str _reason + object _headers + list _raw_headers + bint _upgraded + list _messages + object _payload + bint _payload_error + object _payload_exception + object _last_error + bint _auto_decompress + int _limit + + str _content_encoding + + Py_buffer py_buf + + def __cinit__(self): + self._cparser = \ + PyMem_Malloc(sizeof(cparser.http_parser)) + if self._cparser is NULL: + raise MemoryError() + + self._csettings = \ + PyMem_Malloc(sizeof(cparser.http_parser_settings)) + if self._csettings is NULL: + raise MemoryError() + + def __dealloc__(self): + PyMem_Free(self._cparser) + PyMem_Free(self._csettings) + + cdef _init(self, cparser.http_parser_type mode, + object protocol, object loop, int limit, + object timer=None, + size_t max_line_size=8190, size_t max_headers=32768, + size_t max_field_size=8190, payload_exception=None, + bint response_with_body=True, bint read_until_eof=False, + bint auto_decompress=True): + cparser.http_parser_init(self._cparser, mode) + self._cparser.data = self + self._cparser.content_length = 0 + + cparser.http_parser_settings_init(self._csettings) + + self._protocol = protocol + self._loop = loop + self._timer = timer + + self._buf = bytearray() + self._payload = None + self._payload_error = 0 + self._payload_exception = payload_exception + self._messages = [] + + self._raw_name = bytearray() + self._raw_value = bytearray() + self._has_value = False + + self._max_line_size = max_line_size + self._max_headers = max_headers + self._max_field_size = max_field_size + self._response_with_body = response_with_body + self._read_until_eof = read_until_eof + self._upgraded = False + self._auto_decompress = auto_decompress + self._content_encoding = None + + self._csettings.on_url = cb_on_url + self._csettings.on_status = cb_on_status + self._csettings.on_header_field = cb_on_header_field + self._csettings.on_header_value = cb_on_header_value + self._csettings.on_headers_complete = cb_on_headers_complete + self._csettings.on_body = cb_on_body + self._csettings.on_message_begin = cb_on_message_begin + self._csettings.on_message_complete = cb_on_message_complete + self._csettings.on_chunk_header = cb_on_chunk_header + self._csettings.on_chunk_complete = cb_on_chunk_complete + + self._last_error = None + self._limit = limit + + cdef _process_header(self): + if self._raw_name: + raw_name = bytes(self._raw_name) + raw_value = bytes(self._raw_value) + + name = find_header(raw_name) + value = raw_value.decode('utf-8', 'surrogateescape') + + self._headers.add(name, value) + + if name is CONTENT_ENCODING: + self._content_encoding = value + + PyByteArray_Resize(self._raw_name, 0) + PyByteArray_Resize(self._raw_value, 0) + self._has_value = False + self._raw_headers.append((raw_name, raw_value)) + + cdef _on_header_field(self, char* at, size_t length): + cdef Py_ssize_t size + cdef char *buf + if self._has_value: + self._process_header() + + size = PyByteArray_Size(self._raw_name) + PyByteArray_Resize(self._raw_name, size + length) + buf = PyByteArray_AsString(self._raw_name) + memcpy(buf + size, at, length) + + cdef _on_header_value(self, char* at, size_t length): + cdef Py_ssize_t size + cdef char *buf + + size = PyByteArray_Size(self._raw_value) + PyByteArray_Resize(self._raw_value, size + length) + buf = PyByteArray_AsString(self._raw_value) + memcpy(buf + size, at, length) + self._has_value = True + + cdef _on_headers_complete(self): + self._process_header() + + method = http_method_str(self._cparser.method) + should_close = not cparser.http_should_keep_alive(self._cparser) + upgrade = self._cparser.upgrade + chunked = self._cparser.flags & cparser.F_CHUNKED + + raw_headers = tuple(self._raw_headers) + headers = CIMultiDictProxy(self._headers) + + if upgrade or self._cparser.method == 5: # cparser.CONNECT: + self._upgraded = True + + # do not support old websocket spec + if SEC_WEBSOCKET_KEY1 in headers: + raise InvalidHeader(SEC_WEBSOCKET_KEY1) + + encoding = None + enc = self._content_encoding + if enc is not None: + self._content_encoding = None + enc = enc.lower() + if enc in ('gzip', 'deflate', 'br'): + encoding = enc + + if self._cparser.type == cparser.HTTP_REQUEST: + msg = _new_request_message( + method, self._path, + self.http_version(), headers, raw_headers, + should_close, encoding, upgrade, chunked, self._url) + else: + msg = _new_response_message( + self.http_version(), self._cparser.status_code, self._reason, + headers, raw_headers, should_close, encoding, + upgrade, chunked) + + if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or + self._cparser.method == 5 or # CONNECT: 5 + (self._cparser.status_code >= 199 and + self._cparser.content_length == ULLONG_MAX and + self._read_until_eof) + ): + payload = StreamReader( + self._protocol, timer=self._timer, loop=self._loop, + limit=self._limit) + else: + payload = EMPTY_PAYLOAD + + self._payload = payload + if encoding is not None and self._auto_decompress: + self._payload = DeflateBuffer(payload, encoding) + + if not self._response_with_body: + payload = EMPTY_PAYLOAD + + self._messages.append((msg, payload)) + + cdef _on_message_complete(self): + self._payload.feed_eof() + self._payload = None + + cdef _on_chunk_header(self): + self._payload.begin_http_chunk_receiving() + + cdef _on_chunk_complete(self): + self._payload.end_http_chunk_receiving() + + cdef object _on_status_complete(self): + pass + + cdef inline http_version(self): + cdef cparser.http_parser* parser = self._cparser + + if parser.http_major == 1: + if parser.http_minor == 0: + return HttpVersion10 + elif parser.http_minor == 1: + return HttpVersion11 + + return HttpVersion(parser.http_major, parser.http_minor) + + ### Public API ### + + def feed_eof(self): + cdef bytes desc + + if self._payload is not None: + if self._cparser.flags & cparser.F_CHUNKED: + raise TransferEncodingError( + "Not enough data for satisfy transfer length header.") + elif self._cparser.flags & cparser.F_CONTENTLENGTH: + raise ContentLengthError( + "Not enough data for satisfy content length header.") + elif self._cparser.http_errno != cparser.HPE_OK: + desc = cparser.http_errno_description( + self._cparser.http_errno) + raise PayloadEncodingError(desc.decode('latin-1')) + else: + self._payload.feed_eof() + elif self._started: + self._on_headers_complete() + if self._messages: + return self._messages[-1][0] + + def feed_data(self, data): + cdef: + size_t data_len + size_t nb + + PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE) + data_len = self.py_buf.len + + nb = cparser.http_parser_execute( + self._cparser, + self._csettings, + self.py_buf.buf, + data_len) + + PyBuffer_Release(&self.py_buf) + + if (self._cparser.http_errno != cparser.HPE_OK): + if self._payload_error == 0: + if self._last_error is not None: + ex = self._last_error + self._last_error = None + else: + ex = parser_error_from_errno( + self._cparser.http_errno) + self._payload = None + raise ex + + if self._messages: + messages = self._messages + self._messages = [] + else: + messages = () + + if self._upgraded: + return messages, True, data[nb:] + else: + return messages, False, b'' + + def set_upgraded(self, val): + self._upgraded = val + + +cdef class HttpRequestParser(HttpParser): + + def __init__(self, protocol, loop, int limit, timer=None, + size_t max_line_size=8190, size_t max_headers=32768, + size_t max_field_size=8190, payload_exception=None, + bint response_with_body=True, bint read_until_eof=False, + ): + self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer, + max_line_size, max_headers, max_field_size, + payload_exception, response_with_body, read_until_eof) + + cdef object _on_status_complete(self): + cdef Py_buffer py_buf + if not self._buf: + return + self._path = self._buf.decode('utf-8', 'surrogateescape') + if self._cparser.method == 5: # CONNECT + self._url = URL(self._path) + else: + PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE) + try: + self._url = _parse_url(py_buf.buf, + py_buf.len) + finally: + PyBuffer_Release(&py_buf) + PyByteArray_Resize(self._buf, 0) + + +cdef class HttpResponseParser(HttpParser): + + def __init__(self, protocol, loop, int limit, timer=None, + size_t max_line_size=8190, size_t max_headers=32768, + size_t max_field_size=8190, payload_exception=None, + bint response_with_body=True, bint read_until_eof=False, + bint auto_decompress=True + ): + self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer, + max_line_size, max_headers, max_field_size, + payload_exception, response_with_body, read_until_eof, + auto_decompress) + + cdef object _on_status_complete(self): + if self._buf: + self._reason = self._buf.decode('utf-8', 'surrogateescape') + PyByteArray_Resize(self._buf, 0) + else: + self._reason = self._reason or '' + +cdef int cb_on_message_begin(cparser.http_parser* parser) except -1: + cdef HttpParser pyparser = parser.data + + pyparser._started = True + pyparser._headers = CIMultiDict() + pyparser._raw_headers = [] + PyByteArray_Resize(pyparser._buf, 0) + pyparser._path = None + pyparser._reason = None + return 0 + + +cdef int cb_on_url(cparser.http_parser* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + try: + if length > pyparser._max_line_size: + raise LineTooLong( + 'Status line is too long', pyparser._max_line_size, length) + extend(pyparser._buf, at, length) + except BaseException as ex: + pyparser._last_error = ex + return -1 + else: + return 0 + + +cdef int cb_on_status(cparser.http_parser* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + cdef str reason + try: + if length > pyparser._max_line_size: + raise LineTooLong( + 'Status line is too long', pyparser._max_line_size, length) + extend(pyparser._buf, at, length) + except BaseException as ex: + pyparser._last_error = ex + return -1 + else: + return 0 + + +cdef int cb_on_header_field(cparser.http_parser* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + cdef Py_ssize_t size + try: + pyparser._on_status_complete() + size = len(pyparser._raw_name) + length + if size > pyparser._max_field_size: + raise LineTooLong( + 'Header name is too long', pyparser._max_field_size, size) + pyparser._on_header_field(at, length) + except BaseException as ex: + pyparser._last_error = ex + return -1 + else: + return 0 + + +cdef int cb_on_header_value(cparser.http_parser* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + cdef Py_ssize_t size + try: + size = len(pyparser._raw_value) + length + if size > pyparser._max_field_size: + raise LineTooLong( + 'Header value is too long', pyparser._max_field_size, size) + pyparser._on_header_value(at, length) + except BaseException as ex: + pyparser._last_error = ex + return -1 + else: + return 0 + + +cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1: + cdef HttpParser pyparser = parser.data + try: + pyparser._on_status_complete() + pyparser._on_headers_complete() + except BaseException as exc: + pyparser._last_error = exc + return -1 + else: + if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT + return 2 + else: + return 0 + + +cdef int cb_on_body(cparser.http_parser* parser, + const char *at, size_t length) except -1: + cdef HttpParser pyparser = parser.data + cdef bytes body = at[:length] + try: + pyparser._payload.feed_data(body, length) + except BaseException as exc: + if pyparser._payload_exception is not None: + pyparser._payload.set_exception(pyparser._payload_exception(str(exc))) + else: + pyparser._payload.set_exception(exc) + pyparser._payload_error = 1 + return -1 + else: + return 0 + + +cdef int cb_on_message_complete(cparser.http_parser* parser) except -1: + cdef HttpParser pyparser = parser.data + try: + pyparser._started = False + pyparser._on_message_complete() + except BaseException as exc: + pyparser._last_error = exc + return -1 + else: + return 0 + + +cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1: + cdef HttpParser pyparser = parser.data + try: + pyparser._on_chunk_header() + except BaseException as exc: + pyparser._last_error = exc + return -1 + else: + return 0 + + +cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1: + cdef HttpParser pyparser = parser.data + try: + pyparser._on_chunk_complete() + except BaseException as exc: + pyparser._last_error = exc + return -1 + else: + return 0 + + +cdef parser_error_from_errno(cparser.http_errno errno): + cdef bytes desc = cparser.http_errno_description(errno) + + if errno in (cparser.HPE_CB_message_begin, + cparser.HPE_CB_url, + cparser.HPE_CB_header_field, + cparser.HPE_CB_header_value, + cparser.HPE_CB_headers_complete, + cparser.HPE_CB_body, + cparser.HPE_CB_message_complete, + cparser.HPE_CB_status, + cparser.HPE_CB_chunk_header, + cparser.HPE_CB_chunk_complete): + cls = BadHttpMessage + + elif errno == cparser.HPE_INVALID_STATUS: + cls = BadStatusLine + + elif errno == cparser.HPE_INVALID_METHOD: + cls = BadStatusLine + + elif errno == cparser.HPE_INVALID_URL: + cls = InvalidURLError + + else: + cls = BadHttpMessage + + return cls(desc.decode('latin-1')) + + +def parse_url(url): + cdef: + Py_buffer py_buf + char* buf_data + + PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE) + try: + buf_data = py_buf.buf + return _parse_url(buf_data, py_buf.len) + finally: + PyBuffer_Release(&py_buf) + + +cdef _parse_url(char* buf_data, size_t length): + cdef: + cparser.http_parser_url* parsed + int res + str schema = None + str host = None + object port = None + str path = None + str query = None + str fragment = None + str user = None + str password = None + str userinfo = None + object result = None + int off + int ln + + parsed = \ + PyMem_Malloc(sizeof(cparser.http_parser_url)) + if parsed is NULL: + raise MemoryError() + cparser.http_parser_url_init(parsed) + try: + res = cparser.http_parser_parse_url(buf_data, length, 0, parsed) + + if res == 0: + if parsed.field_set & (1 << cparser.UF_SCHEMA): + off = parsed.field_data[cparser.UF_SCHEMA].off + ln = parsed.field_data[cparser.UF_SCHEMA].len + schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + else: + schema = '' + + if parsed.field_set & (1 << cparser.UF_HOST): + off = parsed.field_data[cparser.UF_HOST].off + ln = parsed.field_data[cparser.UF_HOST].len + host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + else: + host = '' + + if parsed.field_set & (1 << cparser.UF_PORT): + port = parsed.port + + if parsed.field_set & (1 << cparser.UF_PATH): + off = parsed.field_data[cparser.UF_PATH].off + ln = parsed.field_data[cparser.UF_PATH].len + path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + else: + path = '' + + if parsed.field_set & (1 << cparser.UF_QUERY): + off = parsed.field_data[cparser.UF_QUERY].off + ln = parsed.field_data[cparser.UF_QUERY].len + query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + else: + query = '' + + if parsed.field_set & (1 << cparser.UF_FRAGMENT): + off = parsed.field_data[cparser.UF_FRAGMENT].off + ln = parsed.field_data[cparser.UF_FRAGMENT].len + fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + else: + fragment = '' + + if parsed.field_set & (1 << cparser.UF_USERINFO): + off = parsed.field_data[cparser.UF_USERINFO].off + ln = parsed.field_data[cparser.UF_USERINFO].len + userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape') + + user, sep, password = userinfo.partition(':') + + return URL_build(scheme=schema, + user=user, password=password, host=host, port=port, + path=path, query_string=query, fragment=fragment, encoded=True) + else: + raise InvalidURLError("invalid url {!r}".format(buf_data)) + finally: + PyMem_Free(parsed) diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_writer.c b/dist/ba_data/python-site-packages/aiohttp/_http_writer.c new file mode 100644 index 0000000..770c93a --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_http_writer.c @@ -0,0 +1,5840 @@ +/* Generated by Cython 0.29.21 */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.6+ or Python 3.3+. +#else +#define CYTHON_ABI "0_29_21" +#define CYTHON_HEX_VERSION 0x001D15F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #if PY_VERSION_HEX >= 0x02070000 + #define HAVE_LONG_LONG + #endif +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#elif defined(PYSTON_VERSION) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int32 uint32_t; + #endif + #endif +#else + #include +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) && __cplusplus >= 201103L + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #elif __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__ ) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" +#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_FAST_PYCCALL +#define __Pyx_PyFastCFunction_Check(func)\ + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) +#else +#define __Pyx_PyFastCFunction_Check(func) 0 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif +#if CYTHON_COMPILING_IN_PYSTON + #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +#else +#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) +#else + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__aiohttp___http_writer +#define __PYX_HAVE_API__aiohttp___http_writer +/* Early includes */ +#include +#include +#include +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +static PyObject *__pyx_m = NULL; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_cython_runtime = NULL; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + + +static const char *__pyx_f[] = { + "aiohttp\\_http_writer.pyx", + "type.pxd", +}; + +/*--- Type declarations ---*/ +struct __pyx_t_7aiohttp_12_http_writer_Writer; + +/* "aiohttp/_http_writer.pyx":18 + * # ----------------- writer --------------------------- + * + * cdef struct Writer: # <<<<<<<<<<<<<< + * char *buf + * Py_ssize_t size + */ +struct __pyx_t_7aiohttp_12_http_writer_Writer { + char *buf; + Py_ssize_t size; + Py_ssize_t pos; +}; + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* WriteUnraisableException.proto */ +static void __Pyx_WriteUnraisable(const char *name, int clineno, + int lineno, const char *filename, + int full_traceback, int nogil); + +/* unicode_iter.proto */ +static CYTHON_INLINE int __Pyx_init_unicode_iteration( + PyObject* ustring, Py_ssize_t *length, void** data, int *kind); + +/* PyCFunctionFastCall.proto */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); +#else +#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#else +#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCall2Args.proto */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* RaiseException.proto */ +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* ArgTypeTest.proto */ +#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ + ((likely((Py_TYPE(obj) == type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + __Pyx__ArgTypeTest(obj, type, name, exact)) +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); + +/* GetTopmostException.proto */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate); +#endif + +/* ReRaiseException.proto */ +static CYTHON_INLINE void __Pyx_ReraiseException(void); + +/* IterFinish.proto */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* PyObjectCallNoArg.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); +#else +#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) +#endif + +/* PyObjectGetMethod.proto */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); + +/* PyObjectCallMethod0.proto */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* RaiseNeedMoreValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* RaiseTooManyValuesToUnpack.proto */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* UnpackItemEndCheck.proto */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* RaiseNoneIterError.proto */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); + +/* UnpackTupleError.proto */ +static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); + +/* UnpackTuple2.proto */ +#define __Pyx_unpack_tuple2(tuple, value1, value2, is_tuple, has_known_size, decref_tuple)\ + (likely(is_tuple || PyTuple_Check(tuple)) ?\ + (likely(has_known_size || PyTuple_GET_SIZE(tuple) == 2) ?\ + __Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple) :\ + (__Pyx_UnpackTupleError(tuple, 2), -1)) :\ + __Pyx_unpack_tuple2_generic(tuple, value1, value2, has_known_size, decref_tuple)) +static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( + PyObject* tuple, PyObject** value1, PyObject** value2, int decref_tuple); +static int __Pyx_unpack_tuple2_generic( + PyObject* tuple, PyObject** value1, PyObject** value2, int has_known_size, int decref_tuple); + +/* dict_iter.proto */ +static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name, + Py_ssize_t* p_orig_length, int* p_is_dict); +static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos, + PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict); + +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* SwapException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSwap(type, value, tb) __Pyx__ExceptionSwap(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); +#endif + +/* SaveResetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +#else +#define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) +#define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) +#endif + +/* TypeImport.proto */ +#ifndef __PYX_HAVE_RT_ImportType_proto +#define __PYX_HAVE_RT_ImportType_proto +enum __Pyx_ImportType_CheckSize { + __Pyx_ImportType_CheckSize_Error = 0, + __Pyx_ImportType_CheckSize_Warn = 1, + __Pyx_ImportType_CheckSize_Ignore = 2 +}; +static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); +#endif + +/* Import.proto */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +#define __Pyx_GetModuleGlobalNameUncached(var, name) {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.type' */ +static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; + +/* Module declarations from 'cpython' */ + +/* Module declarations from 'cpython.object' */ + +/* Module declarations from 'cpython.bytes' */ + +/* Module declarations from 'cpython.exc' */ + +/* Module declarations from 'cpython.mem' */ + +/* Module declarations from 'libc.stdint' */ + +/* Module declarations from 'aiohttp._http_writer' */ +static char __pyx_v_7aiohttp_12_http_writer_BUFFER[0x4000]; +static PyObject *__pyx_v_7aiohttp_12_http_writer__istr = 0; +static CYTHON_INLINE void __pyx_f_7aiohttp_12_http_writer__init_writer(struct __pyx_t_7aiohttp_12_http_writer_Writer *); /*proto*/ +static CYTHON_INLINE void __pyx_f_7aiohttp_12_http_writer__release_writer(struct __pyx_t_7aiohttp_12_http_writer_Writer *); /*proto*/ +static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_byte(struct __pyx_t_7aiohttp_12_http_writer_Writer *, uint8_t); /*proto*/ +static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_utf8(struct __pyx_t_7aiohttp_12_http_writer_Writer *, Py_UCS4); /*proto*/ +static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_str(struct __pyx_t_7aiohttp_12_http_writer_Writer *, PyObject *); /*proto*/ +static PyObject *__pyx_f_7aiohttp_12_http_writer_to_str(PyObject *); /*proto*/ +#define __Pyx_MODULE_NAME "aiohttp._http_writer" +extern int __pyx_module_is_main_aiohttp___http_writer; +int __pyx_module_is_main_aiohttp___http_writer = 0; + +/* Implementation of 'aiohttp._http_writer' */ +static PyObject *__pyx_builtin_TypeError; +static const char __pyx_k_key[] = "key"; +static const char __pyx_k_ret[] = "ret"; +static const char __pyx_k_val[] = "val"; +static const char __pyx_k_istr[] = "istr"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_items[] = "items"; +static const char __pyx_k_format[] = "format"; +static const char __pyx_k_import[] = "__import__"; +static const char __pyx_k_writer[] = "writer"; +static const char __pyx_k_headers[] = "headers"; +static const char __pyx_k_TypeError[] = "TypeError"; +static const char __pyx_k_multidict[] = "multidict"; +static const char __pyx_k_status_line[] = "status_line"; +static const char __pyx_k_serialize_headers[] = "_serialize_headers"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_aiohttp__http_writer[] = "aiohttp._http_writer"; +static const char __pyx_k_aiohttp__http_writer_pyx[] = "aiohttp\\_http_writer.pyx"; +static const char __pyx_k_Cannot_serialize_non_str_key_r[] = "Cannot serialize non-str key {!r}"; +static PyObject *__pyx_kp_u_Cannot_serialize_non_str_key_r; +static PyObject *__pyx_n_s_TypeError; +static PyObject *__pyx_n_s_aiohttp__http_writer; +static PyObject *__pyx_kp_s_aiohttp__http_writer_pyx; +static PyObject *__pyx_n_s_cline_in_traceback; +static PyObject *__pyx_n_s_format; +static PyObject *__pyx_n_s_headers; +static PyObject *__pyx_n_s_import; +static PyObject *__pyx_n_s_istr; +static PyObject *__pyx_n_s_items; +static PyObject *__pyx_n_s_key; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_multidict; +static PyObject *__pyx_n_s_name; +static PyObject *__pyx_n_s_ret; +static PyObject *__pyx_n_s_serialize_headers; +static PyObject *__pyx_n_s_status_line; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_n_s_val; +static PyObject *__pyx_n_s_writer; +static PyObject *__pyx_pf_7aiohttp_12_http_writer__serialize_headers(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_status_line, PyObject *__pyx_v_headers); /* proto */ +static PyObject *__pyx_tuple_; +static PyObject *__pyx_codeobj__2; +/* Late includes */ + +/* "aiohttp/_http_writer.pyx":24 + * + * + * cdef inline void _init_writer(Writer* writer): # <<<<<<<<<<<<<< + * writer.buf = &BUFFER[0] + * writer.size = BUF_SIZE + */ + +static CYTHON_INLINE void __pyx_f_7aiohttp_12_http_writer__init_writer(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_init_writer", 0); + + /* "aiohttp/_http_writer.pyx":25 + * + * cdef inline void _init_writer(Writer* writer): + * writer.buf = &BUFFER[0] # <<<<<<<<<<<<<< + * writer.size = BUF_SIZE + * writer.pos = 0 + */ + __pyx_v_writer->buf = (&(__pyx_v_7aiohttp_12_http_writer_BUFFER[0])); + + /* "aiohttp/_http_writer.pyx":26 + * cdef inline void _init_writer(Writer* writer): + * writer.buf = &BUFFER[0] + * writer.size = BUF_SIZE # <<<<<<<<<<<<<< + * writer.pos = 0 + * + */ + __pyx_v_writer->size = 0x4000; + + /* "aiohttp/_http_writer.pyx":27 + * writer.buf = &BUFFER[0] + * writer.size = BUF_SIZE + * writer.pos = 0 # <<<<<<<<<<<<<< + * + * + */ + __pyx_v_writer->pos = 0; + + /* "aiohttp/_http_writer.pyx":24 + * + * + * cdef inline void _init_writer(Writer* writer): # <<<<<<<<<<<<<< + * writer.buf = &BUFFER[0] + * writer.size = BUF_SIZE + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "aiohttp/_http_writer.pyx":30 + * + * + * cdef inline void _release_writer(Writer* writer): # <<<<<<<<<<<<<< + * if writer.buf != BUFFER: + * PyMem_Free(writer.buf) + */ + +static CYTHON_INLINE void __pyx_f_7aiohttp_12_http_writer__release_writer(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer) { + __Pyx_RefNannyDeclarations + int __pyx_t_1; + __Pyx_RefNannySetupContext("_release_writer", 0); + + /* "aiohttp/_http_writer.pyx":31 + * + * cdef inline void _release_writer(Writer* writer): + * if writer.buf != BUFFER: # <<<<<<<<<<<<<< + * PyMem_Free(writer.buf) + * + */ + __pyx_t_1 = ((__pyx_v_writer->buf != __pyx_v_7aiohttp_12_http_writer_BUFFER) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_writer.pyx":32 + * cdef inline void _release_writer(Writer* writer): + * if writer.buf != BUFFER: + * PyMem_Free(writer.buf) # <<<<<<<<<<<<<< + * + * + */ + PyMem_Free(__pyx_v_writer->buf); + + /* "aiohttp/_http_writer.pyx":31 + * + * cdef inline void _release_writer(Writer* writer): + * if writer.buf != BUFFER: # <<<<<<<<<<<<<< + * PyMem_Free(writer.buf) + * + */ + } + + /* "aiohttp/_http_writer.pyx":30 + * + * + * cdef inline void _release_writer(Writer* writer): # <<<<<<<<<<<<<< + * if writer.buf != BUFFER: + * PyMem_Free(writer.buf) + */ + + /* function exit code */ + __Pyx_RefNannyFinishContext(); +} + +/* "aiohttp/_http_writer.pyx":35 + * + * + * cdef inline int _write_byte(Writer* writer, uint8_t ch): # <<<<<<<<<<<<<< + * cdef char * buf + * cdef Py_ssize_t size + */ + +static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_byte(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer, uint8_t __pyx_v_ch) { + char *__pyx_v_buf; + Py_ssize_t __pyx_v_size; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_write_byte", 0); + + /* "aiohttp/_http_writer.pyx":39 + * cdef Py_ssize_t size + * + * if writer.pos == writer.size: # <<<<<<<<<<<<<< + * # reallocate + * size = writer.size + BUF_SIZE + */ + __pyx_t_1 = ((__pyx_v_writer->pos == __pyx_v_writer->size) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_writer.pyx":41 + * if writer.pos == writer.size: + * # reallocate + * size = writer.size + BUF_SIZE # <<<<<<<<<<<<<< + * if writer.buf == BUFFER: + * buf = PyMem_Malloc(size) + */ + __pyx_v_size = (__pyx_v_writer->size + 0x4000); + + /* "aiohttp/_http_writer.pyx":42 + * # reallocate + * size = writer.size + BUF_SIZE + * if writer.buf == BUFFER: # <<<<<<<<<<<<<< + * buf = PyMem_Malloc(size) + * if buf == NULL: + */ + __pyx_t_1 = ((__pyx_v_writer->buf == __pyx_v_7aiohttp_12_http_writer_BUFFER) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_writer.pyx":43 + * size = writer.size + BUF_SIZE + * if writer.buf == BUFFER: + * buf = PyMem_Malloc(size) # <<<<<<<<<<<<<< + * if buf == NULL: + * PyErr_NoMemory() + */ + __pyx_v_buf = ((char *)PyMem_Malloc(__pyx_v_size)); + + /* "aiohttp/_http_writer.pyx":44 + * if writer.buf == BUFFER: + * buf = PyMem_Malloc(size) + * if buf == NULL: # <<<<<<<<<<<<<< + * PyErr_NoMemory() + * return -1 + */ + __pyx_t_1 = ((__pyx_v_buf == NULL) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_writer.pyx":45 + * buf = PyMem_Malloc(size) + * if buf == NULL: + * PyErr_NoMemory() # <<<<<<<<<<<<<< + * return -1 + * memcpy(buf, writer.buf, writer.size) + */ + __pyx_t_2 = PyErr_NoMemory(); if (unlikely(__pyx_t_2 == ((PyObject *)NULL))) __PYX_ERR(0, 45, __pyx_L1_error) + + /* "aiohttp/_http_writer.pyx":46 + * if buf == NULL: + * PyErr_NoMemory() + * return -1 # <<<<<<<<<<<<<< + * memcpy(buf, writer.buf, writer.size) + * else: + */ + __pyx_r = -1; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":44 + * if writer.buf == BUFFER: + * buf = PyMem_Malloc(size) + * if buf == NULL: # <<<<<<<<<<<<<< + * PyErr_NoMemory() + * return -1 + */ + } + + /* "aiohttp/_http_writer.pyx":47 + * PyErr_NoMemory() + * return -1 + * memcpy(buf, writer.buf, writer.size) # <<<<<<<<<<<<<< + * else: + * buf = PyMem_Realloc(writer.buf, size) + */ + (void)(memcpy(__pyx_v_buf, __pyx_v_writer->buf, __pyx_v_writer->size)); + + /* "aiohttp/_http_writer.pyx":42 + * # reallocate + * size = writer.size + BUF_SIZE + * if writer.buf == BUFFER: # <<<<<<<<<<<<<< + * buf = PyMem_Malloc(size) + * if buf == NULL: + */ + goto __pyx_L4; + } + + /* "aiohttp/_http_writer.pyx":49 + * memcpy(buf, writer.buf, writer.size) + * else: + * buf = PyMem_Realloc(writer.buf, size) # <<<<<<<<<<<<<< + * if buf == NULL: + * PyErr_NoMemory() + */ + /*else*/ { + __pyx_v_buf = ((char *)PyMem_Realloc(__pyx_v_writer->buf, __pyx_v_size)); + + /* "aiohttp/_http_writer.pyx":50 + * else: + * buf = PyMem_Realloc(writer.buf, size) + * if buf == NULL: # <<<<<<<<<<<<<< + * PyErr_NoMemory() + * return -1 + */ + __pyx_t_1 = ((__pyx_v_buf == NULL) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_writer.pyx":51 + * buf = PyMem_Realloc(writer.buf, size) + * if buf == NULL: + * PyErr_NoMemory() # <<<<<<<<<<<<<< + * return -1 + * writer.buf = buf + */ + __pyx_t_2 = PyErr_NoMemory(); if (unlikely(__pyx_t_2 == ((PyObject *)NULL))) __PYX_ERR(0, 51, __pyx_L1_error) + + /* "aiohttp/_http_writer.pyx":52 + * if buf == NULL: + * PyErr_NoMemory() + * return -1 # <<<<<<<<<<<<<< + * writer.buf = buf + * writer.size = size + */ + __pyx_r = -1; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":50 + * else: + * buf = PyMem_Realloc(writer.buf, size) + * if buf == NULL: # <<<<<<<<<<<<<< + * PyErr_NoMemory() + * return -1 + */ + } + } + __pyx_L4:; + + /* "aiohttp/_http_writer.pyx":53 + * PyErr_NoMemory() + * return -1 + * writer.buf = buf # <<<<<<<<<<<<<< + * writer.size = size + * writer.buf[writer.pos] = ch + */ + __pyx_v_writer->buf = __pyx_v_buf; + + /* "aiohttp/_http_writer.pyx":54 + * return -1 + * writer.buf = buf + * writer.size = size # <<<<<<<<<<<<<< + * writer.buf[writer.pos] = ch + * writer.pos += 1 + */ + __pyx_v_writer->size = __pyx_v_size; + + /* "aiohttp/_http_writer.pyx":39 + * cdef Py_ssize_t size + * + * if writer.pos == writer.size: # <<<<<<<<<<<<<< + * # reallocate + * size = writer.size + BUF_SIZE + */ + } + + /* "aiohttp/_http_writer.pyx":55 + * writer.buf = buf + * writer.size = size + * writer.buf[writer.pos] = ch # <<<<<<<<<<<<<< + * writer.pos += 1 + * return 0 + */ + (__pyx_v_writer->buf[__pyx_v_writer->pos]) = ((char)__pyx_v_ch); + + /* "aiohttp/_http_writer.pyx":56 + * writer.size = size + * writer.buf[writer.pos] = ch + * writer.pos += 1 # <<<<<<<<<<<<<< + * return 0 + * + */ + __pyx_v_writer->pos = (__pyx_v_writer->pos + 1); + + /* "aiohttp/_http_writer.pyx":57 + * writer.buf[writer.pos] = ch + * writer.pos += 1 + * return 0 # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":35 + * + * + * cdef inline int _write_byte(Writer* writer, uint8_t ch): # <<<<<<<<<<<<<< + * cdef char * buf + * cdef Py_ssize_t size + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_WriteUnraisable("aiohttp._http_writer._write_byte", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_writer.pyx":60 + * + * + * cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol): # <<<<<<<<<<<<<< + * cdef uint64_t utf = symbol + * + */ + +static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_utf8(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer, Py_UCS4 __pyx_v_symbol) { + uint64_t __pyx_v_utf; + int __pyx_r; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + __Pyx_RefNannySetupContext("_write_utf8", 0); + + /* "aiohttp/_http_writer.pyx":61 + * + * cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol): + * cdef uint64_t utf = symbol # <<<<<<<<<<<<<< + * + * if utf < 0x80: + */ + __pyx_v_utf = ((uint64_t)__pyx_v_symbol); + + /* "aiohttp/_http_writer.pyx":63 + * cdef uint64_t utf = symbol + * + * if utf < 0x80: # <<<<<<<<<<<<<< + * return _write_byte(writer, utf) + * elif utf < 0x800: + */ + __pyx_t_1 = ((__pyx_v_utf < 0x80) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_writer.pyx":64 + * + * if utf < 0x80: + * return _write_byte(writer, utf) # <<<<<<<<<<<<<< + * elif utf < 0x800: + * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: + */ + __pyx_r = __pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)__pyx_v_utf)); + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":63 + * cdef uint64_t utf = symbol + * + * if utf < 0x80: # <<<<<<<<<<<<<< + * return _write_byte(writer, utf) + * elif utf < 0x800: + */ + } + + /* "aiohttp/_http_writer.pyx":65 + * if utf < 0x80: + * return _write_byte(writer, utf) + * elif utf < 0x800: # <<<<<<<<<<<<<< + * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: + * return -1 + */ + __pyx_t_1 = ((__pyx_v_utf < 0x800) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_writer.pyx":66 + * return _write_byte(writer, utf) + * elif utf < 0x800: + * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: # <<<<<<<<<<<<<< + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0xc0 | (__pyx_v_utf >> 6)))) < 0) != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_writer.pyx":67 + * elif utf < 0x800: + * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: + * return -1 # <<<<<<<<<<<<<< + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + * elif 0xD800 <= utf <= 0xDFFF: + */ + __pyx_r = -1; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":66 + * return _write_byte(writer, utf) + * elif utf < 0x800: + * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: # <<<<<<<<<<<<<< + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + */ + } + + /* "aiohttp/_http_writer.pyx":68 + * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) # <<<<<<<<<<<<<< + * elif 0xD800 <= utf <= 0xDFFF: + * # surogate pair, ignored + */ + __pyx_r = __pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | (__pyx_v_utf & 0x3f)))); + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":65 + * if utf < 0x80: + * return _write_byte(writer, utf) + * elif utf < 0x800: # <<<<<<<<<<<<<< + * if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: + * return -1 + */ + } + + /* "aiohttp/_http_writer.pyx":69 + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + * elif 0xD800 <= utf <= 0xDFFF: # <<<<<<<<<<<<<< + * # surogate pair, ignored + * return 0 + */ + __pyx_t_1 = (0xD800 <= __pyx_v_utf); + if (__pyx_t_1) { + __pyx_t_1 = (__pyx_v_utf <= 0xDFFF); + } + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_writer.pyx":71 + * elif 0xD800 <= utf <= 0xDFFF: + * # surogate pair, ignored + * return 0 # <<<<<<<<<<<<<< + * elif utf < 0x10000: + * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":69 + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + * elif 0xD800 <= utf <= 0xDFFF: # <<<<<<<<<<<<<< + * # surogate pair, ignored + * return 0 + */ + } + + /* "aiohttp/_http_writer.pyx":72 + * # surogate pair, ignored + * return 0 + * elif utf < 0x10000: # <<<<<<<<<<<<<< + * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: + * return -1 + */ + __pyx_t_2 = ((__pyx_v_utf < 0x10000) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_writer.pyx":73 + * return 0 + * elif utf < 0x10000: + * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: # <<<<<<<<<<<<<< + * return -1 + * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: + */ + __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0xe0 | (__pyx_v_utf >> 12)))) < 0) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_writer.pyx":74 + * elif utf < 0x10000: + * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: + * return -1 # <<<<<<<<<<<<<< + * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: + * return -1 + */ + __pyx_r = -1; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":73 + * return 0 + * elif utf < 0x10000: + * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: # <<<<<<<<<<<<<< + * return -1 + * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: + */ + } + + /* "aiohttp/_http_writer.pyx":75 + * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: + * return -1 + * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: # <<<<<<<<<<<<<< + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + */ + __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | ((__pyx_v_utf >> 6) & 0x3f)))) < 0) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_writer.pyx":76 + * return -1 + * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: + * return -1 # <<<<<<<<<<<<<< + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + * elif utf > 0x10FFFF: + */ + __pyx_r = -1; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":75 + * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: + * return -1 + * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: # <<<<<<<<<<<<<< + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + */ + } + + /* "aiohttp/_http_writer.pyx":77 + * if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) # <<<<<<<<<<<<<< + * elif utf > 0x10FFFF: + * # symbol is too large + */ + __pyx_r = __pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | (__pyx_v_utf & 0x3f)))); + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":72 + * # surogate pair, ignored + * return 0 + * elif utf < 0x10000: # <<<<<<<<<<<<<< + * if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: + * return -1 + */ + } + + /* "aiohttp/_http_writer.pyx":78 + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + * elif utf > 0x10FFFF: # <<<<<<<<<<<<<< + * # symbol is too large + * return 0 + */ + __pyx_t_2 = ((__pyx_v_utf > 0x10FFFF) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_writer.pyx":80 + * elif utf > 0x10FFFF: + * # symbol is too large + * return 0 # <<<<<<<<<<<<<< + * else: + * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: + */ + __pyx_r = 0; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":78 + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + * elif utf > 0x10FFFF: # <<<<<<<<<<<<<< + * # symbol is too large + * return 0 + */ + } + + /* "aiohttp/_http_writer.pyx":82 + * return 0 + * else: + * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: # <<<<<<<<<<<<<< + * return -1 + * if _write_byte(writer, + */ + /*else*/ { + __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0xf0 | (__pyx_v_utf >> 18)))) < 0) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_writer.pyx":83 + * else: + * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: + * return -1 # <<<<<<<<<<<<<< + * if _write_byte(writer, + * (0x80 | ((utf >> 12) & 0x3f))) < 0: + */ + __pyx_r = -1; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":82 + * return 0 + * else: + * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: # <<<<<<<<<<<<<< + * return -1 + * if _write_byte(writer, + */ + } + + /* "aiohttp/_http_writer.pyx":85 + * return -1 + * if _write_byte(writer, + * (0x80 | ((utf >> 12) & 0x3f))) < 0: # <<<<<<<<<<<<<< + * return -1 + * if _write_byte(writer, + */ + __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | ((__pyx_v_utf >> 12) & 0x3f)))) < 0) != 0); + + /* "aiohttp/_http_writer.pyx":84 + * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: + * return -1 + * if _write_byte(writer, # <<<<<<<<<<<<<< + * (0x80 | ((utf >> 12) & 0x3f))) < 0: + * return -1 + */ + if (__pyx_t_2) { + + /* "aiohttp/_http_writer.pyx":86 + * if _write_byte(writer, + * (0x80 | ((utf >> 12) & 0x3f))) < 0: + * return -1 # <<<<<<<<<<<<<< + * if _write_byte(writer, + * (0x80 | ((utf >> 6) & 0x3f))) < 0: + */ + __pyx_r = -1; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":84 + * if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: + * return -1 + * if _write_byte(writer, # <<<<<<<<<<<<<< + * (0x80 | ((utf >> 12) & 0x3f))) < 0: + * return -1 + */ + } + + /* "aiohttp/_http_writer.pyx":88 + * return -1 + * if _write_byte(writer, + * (0x80 | ((utf >> 6) & 0x3f))) < 0: # <<<<<<<<<<<<<< + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + */ + __pyx_t_2 = ((__pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | ((__pyx_v_utf >> 6) & 0x3f)))) < 0) != 0); + + /* "aiohttp/_http_writer.pyx":87 + * (0x80 | ((utf >> 12) & 0x3f))) < 0: + * return -1 + * if _write_byte(writer, # <<<<<<<<<<<<<< + * (0x80 | ((utf >> 6) & 0x3f))) < 0: + * return -1 + */ + if (__pyx_t_2) { + + /* "aiohttp/_http_writer.pyx":89 + * if _write_byte(writer, + * (0x80 | ((utf >> 6) & 0x3f))) < 0: + * return -1 # <<<<<<<<<<<<<< + * return _write_byte(writer, (0x80 | (utf & 0x3f))) + * + */ + __pyx_r = -1; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":87 + * (0x80 | ((utf >> 12) & 0x3f))) < 0: + * return -1 + * if _write_byte(writer, # <<<<<<<<<<<<<< + * (0x80 | ((utf >> 6) & 0x3f))) < 0: + * return -1 + */ + } + + /* "aiohttp/_http_writer.pyx":90 + * (0x80 | ((utf >> 6) & 0x3f))) < 0: + * return -1 + * return _write_byte(writer, (0x80 | (utf & 0x3f))) # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = __pyx_f_7aiohttp_12_http_writer__write_byte(__pyx_v_writer, ((uint8_t)(0x80 | (__pyx_v_utf & 0x3f)))); + goto __pyx_L0; + } + + /* "aiohttp/_http_writer.pyx":60 + * + * + * cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol): # <<<<<<<<<<<<<< + * cdef uint64_t utf = symbol + * + */ + + /* function exit code */ + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_writer.pyx":93 + * + * + * cdef inline int _write_str(Writer* writer, str s): # <<<<<<<<<<<<<< + * cdef Py_UCS4 ch + * for ch in s: + */ + +static CYTHON_INLINE int __pyx_f_7aiohttp_12_http_writer__write_str(struct __pyx_t_7aiohttp_12_http_writer_Writer *__pyx_v_writer, PyObject *__pyx_v_s) { + Py_UCS4 __pyx_v_ch; + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + Py_ssize_t __pyx_t_2; + Py_ssize_t __pyx_t_3; + void *__pyx_t_4; + int __pyx_t_5; + int __pyx_t_6; + Py_ssize_t __pyx_t_7; + int __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_write_str", 0); + + /* "aiohttp/_http_writer.pyx":95 + * cdef inline int _write_str(Writer* writer, str s): + * cdef Py_UCS4 ch + * for ch in s: # <<<<<<<<<<<<<< + * if _write_utf8(writer, ch) < 0: + * return -1 + */ + if (unlikely(__pyx_v_s == Py_None)) { + PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable"); + __PYX_ERR(0, 95, __pyx_L1_error) + } + __Pyx_INCREF(__pyx_v_s); + __pyx_t_1 = __pyx_v_s; + __pyx_t_6 = __Pyx_init_unicode_iteration(__pyx_t_1, (&__pyx_t_3), (&__pyx_t_4), (&__pyx_t_5)); if (unlikely(__pyx_t_6 == ((int)-1))) __PYX_ERR(0, 95, __pyx_L1_error) + for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_3; __pyx_t_7++) { + __pyx_t_2 = __pyx_t_7; + __pyx_v_ch = __Pyx_PyUnicode_READ(__pyx_t_5, __pyx_t_4, __pyx_t_2); + + /* "aiohttp/_http_writer.pyx":96 + * cdef Py_UCS4 ch + * for ch in s: + * if _write_utf8(writer, ch) < 0: # <<<<<<<<<<<<<< + * return -1 + * + */ + __pyx_t_8 = ((__pyx_f_7aiohttp_12_http_writer__write_utf8(__pyx_v_writer, __pyx_v_ch) < 0) != 0); + if (__pyx_t_8) { + + /* "aiohttp/_http_writer.pyx":97 + * for ch in s: + * if _write_utf8(writer, ch) < 0: + * return -1 # <<<<<<<<<<<<<< + * + * + */ + __pyx_r = -1; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":96 + * cdef Py_UCS4 ch + * for ch in s: + * if _write_utf8(writer, ch) < 0: # <<<<<<<<<<<<<< + * return -1 + * + */ + } + } + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_http_writer.pyx":93 + * + * + * cdef inline int _write_str(Writer* writer, str s): # <<<<<<<<<<<<<< + * cdef Py_UCS4 ch + * for ch in s: + */ + + /* function exit code */ + __pyx_r = 0; + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_WriteUnraisable("aiohttp._http_writer._write_str", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_writer.pyx":102 + * # --------------- _serialize_headers ---------------------- + * + * cdef str to_str(object s): # <<<<<<<<<<<<<< + * typ = type(s) + * if typ is str: + */ + +static PyObject *__pyx_f_7aiohttp_12_http_writer_to_str(PyObject *__pyx_v_s) { + PyTypeObject *__pyx_v_typ = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("to_str", 0); + + /* "aiohttp/_http_writer.pyx":103 + * + * cdef str to_str(object s): + * typ = type(s) # <<<<<<<<<<<<<< + * if typ is str: + * return s + */ + __Pyx_INCREF(((PyObject *)Py_TYPE(__pyx_v_s))); + __pyx_v_typ = ((PyTypeObject*)((PyObject *)Py_TYPE(__pyx_v_s))); + + /* "aiohttp/_http_writer.pyx":104 + * cdef str to_str(object s): + * typ = type(s) + * if typ is str: # <<<<<<<<<<<<<< + * return s + * elif typ is _istr: + */ + __pyx_t_1 = (__pyx_v_typ == (&PyUnicode_Type)); + __pyx_t_2 = (__pyx_t_1 != 0); + if (__pyx_t_2) { + + /* "aiohttp/_http_writer.pyx":105 + * typ = type(s) + * if typ is str: + * return s # <<<<<<<<<<<<<< + * elif typ is _istr: + * return PyObject_Str(s) + */ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(((PyObject*)__pyx_v_s)); + __pyx_r = ((PyObject*)__pyx_v_s); + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":104 + * cdef str to_str(object s): + * typ = type(s) + * if typ is str: # <<<<<<<<<<<<<< + * return s + * elif typ is _istr: + */ + } + + /* "aiohttp/_http_writer.pyx":106 + * if typ is str: + * return s + * elif typ is _istr: # <<<<<<<<<<<<<< + * return PyObject_Str(s) + * elif not isinstance(s, str): + */ + __pyx_t_2 = (__pyx_v_typ == ((PyTypeObject*)__pyx_v_7aiohttp_12_http_writer__istr)); + __pyx_t_1 = (__pyx_t_2 != 0); + if (__pyx_t_1) { + + /* "aiohttp/_http_writer.pyx":107 + * return s + * elif typ is _istr: + * return PyObject_Str(s) # <<<<<<<<<<<<<< + * elif not isinstance(s, str): + * raise TypeError("Cannot serialize non-str key {!r}".format(s)) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = PyObject_Str(__pyx_v_s); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 107, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + if (!(likely(PyUnicode_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(0, 107, __pyx_L1_error) + __pyx_r = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "aiohttp/_http_writer.pyx":106 + * if typ is str: + * return s + * elif typ is _istr: # <<<<<<<<<<<<<< + * return PyObject_Str(s) + * elif not isinstance(s, str): + */ + } + + /* "aiohttp/_http_writer.pyx":108 + * elif typ is _istr: + * return PyObject_Str(s) + * elif not isinstance(s, str): # <<<<<<<<<<<<<< + * raise TypeError("Cannot serialize non-str key {!r}".format(s)) + * else: + */ + __pyx_t_1 = PyUnicode_Check(__pyx_v_s); + __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0); + if (unlikely(__pyx_t_2)) { + + /* "aiohttp/_http_writer.pyx":109 + * return PyObject_Str(s) + * elif not isinstance(s, str): + * raise TypeError("Cannot serialize non-str key {!r}".format(s)) # <<<<<<<<<<<<<< + * else: + * return str(s) + */ + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_u_Cannot_serialize_non_str_key_r, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_4, function); + } + } + __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_v_s) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_s); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_builtin_TypeError, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 109, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_Raise(__pyx_t_4, 0, 0, 0); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __PYX_ERR(0, 109, __pyx_L1_error) + + /* "aiohttp/_http_writer.pyx":108 + * elif typ is _istr: + * return PyObject_Str(s) + * elif not isinstance(s, str): # <<<<<<<<<<<<<< + * raise TypeError("Cannot serialize non-str key {!r}".format(s)) + * else: + */ + } + + /* "aiohttp/_http_writer.pyx":111 + * raise TypeError("Cannot serialize non-str key {!r}".format(s)) + * else: + * return str(s) # <<<<<<<<<<<<<< + * + * + */ + /*else*/ { + __Pyx_XDECREF(__pyx_r); + __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_s); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 111, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __pyx_r = ((PyObject*)__pyx_t_4); + __pyx_t_4 = 0; + goto __pyx_L0; + } + + /* "aiohttp/_http_writer.pyx":102 + * # --------------- _serialize_headers ---------------------- + * + * cdef str to_str(object s): # <<<<<<<<<<<<<< + * typ = type(s) + * if typ is str: + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("aiohttp._http_writer.to_str", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = 0; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_typ); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "aiohttp/_http_writer.pyx":114 + * + * + * def _serialize_headers(str status_line, headers): # <<<<<<<<<<<<<< + * cdef Writer writer + * cdef object key + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static PyMethodDef __pyx_mdef_7aiohttp_12_http_writer_1_serialize_headers = {"_serialize_headers", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers, METH_VARARGS|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_7aiohttp_12_http_writer_1_serialize_headers(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_status_line = 0; + PyObject *__pyx_v_headers = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_serialize_headers (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_status_line,&__pyx_n_s_headers,0}; + PyObject* values[2] = {0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_status_line)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_headers)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_serialize_headers", 1, 2, 2, 1); __PYX_ERR(0, 114, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_serialize_headers") < 0)) __PYX_ERR(0, 114, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + } + __pyx_v_status_line = ((PyObject*)values[0]); + __pyx_v_headers = values[1]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_serialize_headers", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 114, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._http_writer._serialize_headers", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_status_line), (&PyUnicode_Type), 1, "status_line", 1))) __PYX_ERR(0, 114, __pyx_L1_error) + __pyx_r = __pyx_pf_7aiohttp_12_http_writer__serialize_headers(__pyx_self, __pyx_v_status_line, __pyx_v_headers); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_12_http_writer__serialize_headers(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_status_line, PyObject *__pyx_v_headers) { + struct __pyx_t_7aiohttp_12_http_writer_Writer __pyx_v_writer; + PyObject *__pyx_v_key = 0; + PyObject *__pyx_v_val = 0; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + Py_ssize_t __pyx_t_4; + int __pyx_t_5; + PyObject *__pyx_t_6 = NULL; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + char const *__pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; + PyObject *__pyx_t_12 = NULL; + PyObject *__pyx_t_13 = NULL; + PyObject *__pyx_t_14 = NULL; + PyObject *__pyx_t_15 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_serialize_headers", 0); + + /* "aiohttp/_http_writer.pyx":120 + * cdef bytes ret + * + * _init_writer(&writer) # <<<<<<<<<<<<<< + * + * try: + */ + __pyx_f_7aiohttp_12_http_writer__init_writer((&__pyx_v_writer)); + + /* "aiohttp/_http_writer.pyx":122 + * _init_writer(&writer) + * + * try: # <<<<<<<<<<<<<< + * if _write_str(&writer, status_line) < 0: + * raise + */ + /*try:*/ { + + /* "aiohttp/_http_writer.pyx":123 + * + * try: + * if _write_str(&writer, status_line) < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\r') < 0: + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_str((&__pyx_v_writer), __pyx_v_status_line) < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":124 + * try: + * if _write_str(&writer, status_line) < 0: + * raise # <<<<<<<<<<<<<< + * if _write_byte(&writer, b'\r') < 0: + * raise + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 124, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":123 + * + * try: + * if _write_str(&writer, status_line) < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\r') < 0: + */ + } + + /* "aiohttp/_http_writer.pyx":125 + * if _write_str(&writer, status_line) < 0: + * raise + * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\n') < 0: + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\r') < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":126 + * raise + * if _write_byte(&writer, b'\r') < 0: + * raise # <<<<<<<<<<<<<< + * if _write_byte(&writer, b'\n') < 0: + * raise + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 126, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":125 + * if _write_str(&writer, status_line) < 0: + * raise + * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\n') < 0: + */ + } + + /* "aiohttp/_http_writer.pyx":127 + * if _write_byte(&writer, b'\r') < 0: + * raise + * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< + * raise + * + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\n') < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":128 + * raise + * if _write_byte(&writer, b'\n') < 0: + * raise # <<<<<<<<<<<<<< + * + * for key, val in headers.items(): + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 128, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":127 + * if _write_byte(&writer, b'\r') < 0: + * raise + * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< + * raise + * + */ + } + + /* "aiohttp/_http_writer.pyx":130 + * raise + * + * for key, val in headers.items(): # <<<<<<<<<<<<<< + * if _write_str(&writer, to_str(key)) < 0: + * raise + */ + __pyx_t_3 = 0; + if (unlikely(__pyx_v_headers == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items"); + __PYX_ERR(0, 130, __pyx_L4_error) + } + __pyx_t_6 = __Pyx_dict_iterator(__pyx_v_headers, 0, __pyx_n_s_items, (&__pyx_t_4), (&__pyx_t_5)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 130, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_2); + __pyx_t_2 = __pyx_t_6; + __pyx_t_6 = 0; + while (1) { + __pyx_t_8 = __Pyx_dict_iter_next(__pyx_t_2, __pyx_t_4, &__pyx_t_3, &__pyx_t_6, &__pyx_t_7, NULL, __pyx_t_5); + if (unlikely(__pyx_t_8 == 0)) break; + if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(0, 130, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_7); + __Pyx_XDECREF_SET(__pyx_v_key, __pyx_t_6); + __pyx_t_6 = 0; + __Pyx_XDECREF_SET(__pyx_v_val, __pyx_t_7); + __pyx_t_7 = 0; + + /* "aiohttp/_http_writer.pyx":131 + * + * for key, val in headers.items(): + * if _write_str(&writer, to_str(key)) < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b':') < 0: + */ + __pyx_t_7 = __pyx_f_7aiohttp_12_http_writer_to_str(__pyx_v_key); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 131, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_str((&__pyx_v_writer), ((PyObject*)__pyx_t_7)) < 0) != 0); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":132 + * for key, val in headers.items(): + * if _write_str(&writer, to_str(key)) < 0: + * raise # <<<<<<<<<<<<<< + * if _write_byte(&writer, b':') < 0: + * raise + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 132, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":131 + * + * for key, val in headers.items(): + * if _write_str(&writer, to_str(key)) < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b':') < 0: + */ + } + + /* "aiohttp/_http_writer.pyx":133 + * if _write_str(&writer, to_str(key)) < 0: + * raise + * if _write_byte(&writer, b':') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b' ') < 0: + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), ':') < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":134 + * raise + * if _write_byte(&writer, b':') < 0: + * raise # <<<<<<<<<<<<<< + * if _write_byte(&writer, b' ') < 0: + * raise + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 134, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":133 + * if _write_str(&writer, to_str(key)) < 0: + * raise + * if _write_byte(&writer, b':') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b' ') < 0: + */ + } + + /* "aiohttp/_http_writer.pyx":135 + * if _write_byte(&writer, b':') < 0: + * raise + * if _write_byte(&writer, b' ') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_str(&writer, to_str(val)) < 0: + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), ' ') < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":136 + * raise + * if _write_byte(&writer, b' ') < 0: + * raise # <<<<<<<<<<<<<< + * if _write_str(&writer, to_str(val)) < 0: + * raise + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 136, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":135 + * if _write_byte(&writer, b':') < 0: + * raise + * if _write_byte(&writer, b' ') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_str(&writer, to_str(val)) < 0: + */ + } + + /* "aiohttp/_http_writer.pyx":137 + * if _write_byte(&writer, b' ') < 0: + * raise + * if _write_str(&writer, to_str(val)) < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\r') < 0: + */ + __pyx_t_7 = __pyx_f_7aiohttp_12_http_writer_to_str(__pyx_v_val); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 137, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_str((&__pyx_v_writer), ((PyObject*)__pyx_t_7)) < 0) != 0); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":138 + * raise + * if _write_str(&writer, to_str(val)) < 0: + * raise # <<<<<<<<<<<<<< + * if _write_byte(&writer, b'\r') < 0: + * raise + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 138, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":137 + * if _write_byte(&writer, b' ') < 0: + * raise + * if _write_str(&writer, to_str(val)) < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\r') < 0: + */ + } + + /* "aiohttp/_http_writer.pyx":139 + * if _write_str(&writer, to_str(val)) < 0: + * raise + * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\n') < 0: + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\r') < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":140 + * raise + * if _write_byte(&writer, b'\r') < 0: + * raise # <<<<<<<<<<<<<< + * if _write_byte(&writer, b'\n') < 0: + * raise + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 140, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":139 + * if _write_str(&writer, to_str(val)) < 0: + * raise + * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\n') < 0: + */ + } + + /* "aiohttp/_http_writer.pyx":141 + * if _write_byte(&writer, b'\r') < 0: + * raise + * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< + * raise + * + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\n') < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":142 + * raise + * if _write_byte(&writer, b'\n') < 0: + * raise # <<<<<<<<<<<<<< + * + * if _write_byte(&writer, b'\r') < 0: + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 142, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":141 + * if _write_byte(&writer, b'\r') < 0: + * raise + * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< + * raise + * + */ + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_writer.pyx":144 + * raise + * + * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\n') < 0: + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\r') < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":145 + * + * if _write_byte(&writer, b'\r') < 0: + * raise # <<<<<<<<<<<<<< + * if _write_byte(&writer, b'\n') < 0: + * raise + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 145, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":144 + * raise + * + * if _write_byte(&writer, b'\r') < 0: # <<<<<<<<<<<<<< + * raise + * if _write_byte(&writer, b'\n') < 0: + */ + } + + /* "aiohttp/_http_writer.pyx":146 + * if _write_byte(&writer, b'\r') < 0: + * raise + * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< + * raise + * + */ + __pyx_t_1 = ((__pyx_f_7aiohttp_12_http_writer__write_byte((&__pyx_v_writer), '\n') < 0) != 0); + if (unlikely(__pyx_t_1)) { + + /* "aiohttp/_http_writer.pyx":147 + * raise + * if _write_byte(&writer, b'\n') < 0: + * raise # <<<<<<<<<<<<<< + * + * return PyBytes_FromStringAndSize(writer.buf, writer.pos) + */ + __Pyx_ReraiseException(); __PYX_ERR(0, 147, __pyx_L4_error) + + /* "aiohttp/_http_writer.pyx":146 + * if _write_byte(&writer, b'\r') < 0: + * raise + * if _write_byte(&writer, b'\n') < 0: # <<<<<<<<<<<<<< + * raise + * + */ + } + + /* "aiohttp/_http_writer.pyx":149 + * raise + * + * return PyBytes_FromStringAndSize(writer.buf, writer.pos) # <<<<<<<<<<<<<< + * finally: + * _release_writer(&writer) + */ + __Pyx_XDECREF(__pyx_r); + __pyx_t_2 = PyBytes_FromStringAndSize(__pyx_v_writer.buf, __pyx_v_writer.pos); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 149, __pyx_L4_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; + goto __pyx_L3_return; + } + + /* "aiohttp/_http_writer.pyx":151 + * return PyBytes_FromStringAndSize(writer.buf, writer.pos) + * finally: + * _release_writer(&writer) # <<<<<<<<<<<<<< + */ + /*finally:*/ { + __pyx_L4_error:; + /*exception exit:*/{ + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; + if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_13, &__pyx_t_14, &__pyx_t_15); + if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12) < 0)) __Pyx_ErrFetch(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12); + __Pyx_XGOTREF(__pyx_t_10); + __Pyx_XGOTREF(__pyx_t_11); + __Pyx_XGOTREF(__pyx_t_12); + __Pyx_XGOTREF(__pyx_t_13); + __Pyx_XGOTREF(__pyx_t_14); + __Pyx_XGOTREF(__pyx_t_15); + __pyx_t_5 = __pyx_lineno; __pyx_t_8 = __pyx_clineno; __pyx_t_9 = __pyx_filename; + { + __pyx_f_7aiohttp_12_http_writer__release_writer((&__pyx_v_writer)); + } + if (PY_MAJOR_VERSION >= 3) { + __Pyx_XGIVEREF(__pyx_t_13); + __Pyx_XGIVEREF(__pyx_t_14); + __Pyx_XGIVEREF(__pyx_t_15); + __Pyx_ExceptionReset(__pyx_t_13, __pyx_t_14, __pyx_t_15); + } + __Pyx_XGIVEREF(__pyx_t_10); + __Pyx_XGIVEREF(__pyx_t_11); + __Pyx_XGIVEREF(__pyx_t_12); + __Pyx_ErrRestore(__pyx_t_10, __pyx_t_11, __pyx_t_12); + __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0; __pyx_t_13 = 0; __pyx_t_14 = 0; __pyx_t_15 = 0; + __pyx_lineno = __pyx_t_5; __pyx_clineno = __pyx_t_8; __pyx_filename = __pyx_t_9; + goto __pyx_L1_error; + } + __pyx_L3_return: { + __pyx_t_15 = __pyx_r; + __pyx_r = 0; + __pyx_f_7aiohttp_12_http_writer__release_writer((&__pyx_v_writer)); + __pyx_r = __pyx_t_15; + __pyx_t_15 = 0; + goto __pyx_L0; + } + } + + /* "aiohttp/_http_writer.pyx":114 + * + * + * def _serialize_headers(str status_line, headers): # <<<<<<<<<<<<<< + * cdef Writer writer + * cdef object key + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_AddTraceback("aiohttp._http_writer._serialize_headers", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_key); + __Pyx_XDECREF(__pyx_v_val); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec__http_writer(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec__http_writer}, + {0, NULL} +}; +#endif + +static struct PyModuleDef __pyx_moduledef = { + PyModuleDef_HEAD_INIT, + "_http_writer", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_kp_u_Cannot_serialize_non_str_key_r, __pyx_k_Cannot_serialize_non_str_key_r, sizeof(__pyx_k_Cannot_serialize_non_str_key_r), 0, 1, 0, 0}, + {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, + {&__pyx_n_s_aiohttp__http_writer, __pyx_k_aiohttp__http_writer, sizeof(__pyx_k_aiohttp__http_writer), 0, 0, 1, 1}, + {&__pyx_kp_s_aiohttp__http_writer_pyx, __pyx_k_aiohttp__http_writer_pyx, sizeof(__pyx_k_aiohttp__http_writer_pyx), 0, 0, 1, 0}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1}, + {&__pyx_n_s_headers, __pyx_k_headers, sizeof(__pyx_k_headers), 0, 0, 1, 1}, + {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1}, + {&__pyx_n_s_istr, __pyx_k_istr, sizeof(__pyx_k_istr), 0, 0, 1, 1}, + {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1}, + {&__pyx_n_s_key, __pyx_k_key, sizeof(__pyx_k_key), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_multidict, __pyx_k_multidict, sizeof(__pyx_k_multidict), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_ret, __pyx_k_ret, sizeof(__pyx_k_ret), 0, 0, 1, 1}, + {&__pyx_n_s_serialize_headers, __pyx_k_serialize_headers, sizeof(__pyx_k_serialize_headers), 0, 0, 1, 1}, + {&__pyx_n_s_status_line, __pyx_k_status_line, sizeof(__pyx_k_status_line), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_val, __pyx_k_val, sizeof(__pyx_k_val), 0, 0, 1, 1}, + {&__pyx_n_s_writer, __pyx_k_writer, sizeof(__pyx_k_writer), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 109, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "aiohttp/_http_writer.pyx":114 + * + * + * def _serialize_headers(str status_line, headers): # <<<<<<<<<<<<<< + * cdef Writer writer + * cdef object key + */ + __pyx_tuple_ = PyTuple_Pack(6, __pyx_n_s_status_line, __pyx_n_s_headers, __pyx_n_s_writer, __pyx_n_s_key, __pyx_n_s_val, __pyx_n_s_ret); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + __pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(2, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_aiohttp__http_writer_pyx, __pyx_n_s_serialize_headers, 114, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __pyx_v_7aiohttp_12_http_writer__istr = Py_None; Py_INCREF(Py_None); + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", + #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 + sizeof(PyTypeObject), + #else + sizeof(PyHeapTypeObject), + #endif + __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC init_http_writer(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC init_http_writer(void) +#else +__Pyx_PyMODINIT_FUNC PyInit__http_writer(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit__http_writer(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec__http_writer(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_http_writer' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__http_writer(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("_http_writer", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_b); + __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_cython_runtime); + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_aiohttp___http_writer) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "aiohttp._http_writer")) { + if (unlikely(PyDict_SetItemString(modules, "aiohttp._http_writer", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + (void)__Pyx_modinit_type_init_code(); + if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "aiohttp/_http_writer.pyx":8 + * from libc.string cimport memcpy + * + * from multidict import istr # <<<<<<<<<<<<<< + * + * DEF BUF_SIZE = 16 * 1024 # 16KiB + */ + __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_INCREF(__pyx_n_s_istr); + __Pyx_GIVEREF(__pyx_n_s_istr); + PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_istr); + __pyx_t_2 = __Pyx_Import(__pyx_n_s_multidict, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_istr); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_istr, __pyx_t_1) < 0) __PYX_ERR(0, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_writer.pyx":13 + * cdef char BUFFER[BUF_SIZE] + * + * cdef object _istr = istr # <<<<<<<<<<<<<< + * + * + */ + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_istr); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 13, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_v_7aiohttp_12_http_writer__istr); + __Pyx_DECREF_SET(__pyx_v_7aiohttp_12_http_writer__istr, __pyx_t_2); + __Pyx_GIVEREF(__pyx_t_2); + __pyx_t_2 = 0; + + /* "aiohttp/_http_writer.pyx":114 + * + * + * def _serialize_headers(str status_line, headers): # <<<<<<<<<<<<<< + * cdef Writer writer + * cdef object key + */ + __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_12_http_writer_1_serialize_headers, NULL, __pyx_n_s_aiohttp__http_writer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_serialize_headers, __pyx_t_2) < 0) __PYX_ERR(0, 114, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "aiohttp/_http_writer.pyx":1 + * from cpython.bytes cimport PyBytes_FromStringAndSize # <<<<<<<<<<<<<< + * from cpython.exc cimport PyErr_NoMemory + * from cpython.mem cimport PyMem_Free, PyMem_Malloc, PyMem_Realloc + */ + __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_2); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init aiohttp._http_writer", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_CLEAR(__pyx_m); + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init aiohttp._http_writer"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* WriteUnraisableException */ +static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, + CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename, + int full_traceback, CYTHON_UNUSED int nogil) { + PyObject *old_exc, *old_val, *old_tb; + PyObject *ctx; + __Pyx_PyThreadState_declare +#ifdef WITH_THREAD + PyGILState_STATE state; + if (nogil) + state = PyGILState_Ensure(); +#ifdef _MSC_VER + else state = (PyGILState_STATE)-1; +#endif +#endif + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); + if (full_traceback) { + Py_XINCREF(old_exc); + Py_XINCREF(old_val); + Py_XINCREF(old_tb); + __Pyx_ErrRestore(old_exc, old_val, old_tb); + PyErr_PrintEx(1); + } + #if PY_MAJOR_VERSION < 3 + ctx = PyString_FromString(name); + #else + ctx = PyUnicode_FromString(name); + #endif + __Pyx_ErrRestore(old_exc, old_val, old_tb); + if (!ctx) { + PyErr_WriteUnraisable(Py_None); + } else { + PyErr_WriteUnraisable(ctx); + Py_DECREF(ctx); + } +#ifdef WITH_THREAD + if (nogil) + PyGILState_Release(state); +#endif +} + +/* unicode_iter */ +static CYTHON_INLINE int __Pyx_init_unicode_iteration( + PyObject* ustring, Py_ssize_t *length, void** data, int *kind) { +#if CYTHON_PEP393_ENABLED + if (unlikely(__Pyx_PyUnicode_READY(ustring) < 0)) return -1; + *kind = PyUnicode_KIND(ustring); + *length = PyUnicode_GET_LENGTH(ustring); + *data = PyUnicode_DATA(ustring); +#else + *kind = 0; + *length = PyUnicode_GET_SIZE(ustring); + *data = (void*)PyUnicode_AS_UNICODE(ustring); +#endif + return 0; +} + +/* PyCFunctionFastCall */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { + PyCFunctionObject *func = (PyCFunctionObject*)func_obj; + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + int flags = PyCFunction_GET_FLAGS(func); + assert(PyCFunction_Check(func)); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + /* _PyCFunction_FastCallDict() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); + } else { + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); + } +} +#endif + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { + return NULL; + } + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif +#endif + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCall2Args */ +static CYTHON_UNUSED PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args, *result = NULL; + #if CYTHON_FAST_PYCALL + if (PyFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyFunction_FastCall(function, args, 2); + } + #endif + #if CYTHON_FAST_PYCCALL + if (__Pyx_PyFastCFunction_Check(function)) { + PyObject *args[2] = {arg1, arg2}; + return __Pyx_PyCFunction_FastCall(function, args, 2); + } + #endif + args = PyTuple_New(2); + if (unlikely(!args)) goto done; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + Py_INCREF(function); + result = __Pyx_PyObject_Call(function, args, NULL); + Py_DECREF(args); + Py_DECREF(function); +done: + return result; +} + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = PyCFunction_GET_FUNCTION(func); + self = PyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallOneArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, &arg, 1); + } +#endif + if (likely(PyCFunction_Check(func))) { + if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { + return __Pyx_PyObject_CallMethO(func, arg); +#if CYTHON_FAST_PYCCALL + } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { + return __Pyx_PyCFunction_FastCall(func, &arg, 1); +#endif + } + } + return __Pyx__PyObject_CallOneArg(func, arg); +} +#else +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_Pack(1, arg); + if (unlikely(!args)) return NULL; + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +#endif + +/* RaiseException */ +#if PY_MAJOR_VERSION < 3 +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, + CYTHON_UNUSED PyObject *cause) { + __Pyx_PyThreadState_declare + Py_XINCREF(type); + if (!value || value == Py_None) + value = NULL; + else + Py_INCREF(value); + if (!tb || tb == Py_None) + tb = NULL; + else { + Py_INCREF(tb); + if (!PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto raise_error; + } + } + if (PyType_Check(type)) { +#if CYTHON_COMPILING_IN_PYPY + if (!value) { + Py_INCREF(Py_None); + value = Py_None; + } +#endif + PyErr_NormalizeException(&type, &value, &tb); + } else { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto raise_error; + } + value = type; + type = (PyObject*) Py_TYPE(type); + Py_INCREF(type); + if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto raise_error; + } + } + __Pyx_PyThreadState_assign + __Pyx_ErrRestore(type, value, tb); + return; +raise_error: + Py_XDECREF(value); + Py_XDECREF(type); + Py_XDECREF(tb); + return; +} +#else +static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { + PyObject* owned_instance = NULL; + if (tb == Py_None) { + tb = 0; + } else if (tb && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "raise: arg 3 must be a traceback or None"); + goto bad; + } + if (value == Py_None) + value = 0; + if (PyExceptionInstance_Check(type)) { + if (value) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto bad; + } + value = type; + type = (PyObject*) Py_TYPE(value); + } else if (PyExceptionClass_Check(type)) { + PyObject *instance_class = NULL; + if (value && PyExceptionInstance_Check(value)) { + instance_class = (PyObject*) Py_TYPE(value); + if (instance_class != type) { + int is_subclass = PyObject_IsSubclass(instance_class, type); + if (!is_subclass) { + instance_class = NULL; + } else if (unlikely(is_subclass == -1)) { + goto bad; + } else { + type = instance_class; + } + } + } + if (!instance_class) { + PyObject *args; + if (!value) + args = PyTuple_New(0); + else if (PyTuple_Check(value)) { + Py_INCREF(value); + args = value; + } else + args = PyTuple_Pack(1, value); + if (!args) + goto bad; + owned_instance = PyObject_Call(type, args, NULL); + Py_DECREF(args); + if (!owned_instance) + goto bad; + value = owned_instance; + if (!PyExceptionInstance_Check(value)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %R", + type, Py_TYPE(value)); + goto bad; + } + } + } else { + PyErr_SetString(PyExc_TypeError, + "raise: exception class must be a subclass of BaseException"); + goto bad; + } + if (cause) { + PyObject *fixed_cause; + if (cause == Py_None) { + fixed_cause = NULL; + } else if (PyExceptionClass_Check(cause)) { + fixed_cause = PyObject_CallObject(cause, NULL); + if (fixed_cause == NULL) + goto bad; + } else if (PyExceptionInstance_Check(cause)) { + fixed_cause = cause; + Py_INCREF(fixed_cause); + } else { + PyErr_SetString(PyExc_TypeError, + "exception causes must derive from " + "BaseException"); + goto bad; + } + PyException_SetCause(value, fixed_cause); + } + PyErr_SetObject(type, value); + if (tb) { +#if CYTHON_COMPILING_IN_PYPY + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); + Py_INCREF(tb); + PyErr_Restore(tmp_type, tmp_value, tb); + Py_XDECREF(tmp_tb); +#else + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* tmp_tb = tstate->curexc_traceback; + if (tb != tmp_tb) { + Py_INCREF(tb); + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_tb); + } +#endif + } +bad: + Py_XDECREF(owned_instance); + return; +} +#endif + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* RaiseDoubleKeywords */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* ArgTypeTest */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (exact) { + #if PY_MAJOR_VERSION == 2 + if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; + #endif + } + else { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", + name, type->tp_name, Py_TYPE(obj)->tp_name); + return 0; +} + +/* GetTopmostException */ +#if CYTHON_USE_EXC_INFO_STACK +static _PyErr_StackItem * +__Pyx_PyErr_GetTopmostException(PyThreadState *tstate) +{ + _PyErr_StackItem *exc_info = tstate->exc_info; + while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) && + exc_info->previous_item != NULL) + { + exc_info = exc_info->previous_item; + } + return exc_info; +} +#endif + +/* ReRaiseException */ +static CYTHON_INLINE void __Pyx_ReraiseException(void) { + PyObject *type = NULL, *value = NULL, *tb = NULL; +#if CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = PyThreadState_GET(); + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + type = exc_info->exc_type; + value = exc_info->exc_value; + tb = exc_info->exc_traceback; + #else + type = tstate->exc_type; + value = tstate->exc_value; + tb = tstate->exc_traceback; + #endif +#else + PyErr_GetExcInfo(&type, &value, &tb); +#endif + if (!type || type == Py_None) { +#if !CYTHON_FAST_THREAD_STATE + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(tb); +#endif + PyErr_SetString(PyExc_RuntimeError, + "No active exception to reraise"); + } else { +#if CYTHON_FAST_THREAD_STATE + Py_INCREF(type); + Py_XINCREF(value); + Py_XINCREF(tb); +#endif + PyErr_Restore(type, value, tb); + } +} + +/* IterFinish */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { +#if CYTHON_FAST_THREAD_STATE + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject* exc_type = tstate->curexc_type; + if (unlikely(exc_type)) { + if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) { + PyObject *exc_value, *exc_tb; + exc_value = tstate->curexc_value; + exc_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; + Py_DECREF(exc_type); + Py_XDECREF(exc_value); + Py_XDECREF(exc_tb); + return 0; + } else { + return -1; + } + } + return 0; +#else + if (unlikely(PyErr_Occurred())) { + if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { + PyErr_Clear(); + return 0; + } else { + return -1; + } + } + return 0; +#endif +} + +/* PyObjectCallNoArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, NULL, 0); + } +#endif +#ifdef __Pyx_CyFunction_USED + if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func))) +#else + if (likely(PyCFunction_Check(func))) +#endif + { + if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { + return __Pyx_PyObject_CallMethO(func, NULL); + } + } + return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); +} +#endif + +/* PyObjectGetMethod */ +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if PY_MAJOR_VERSION >= 3 + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || (Py_TYPE(descr) == &PyMethodDescr_Type))) + #endif +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (descr != NULL) { + *method = descr; + return 0; + } + PyErr_Format(PyExc_AttributeError, +#if PY_MAJOR_VERSION >= 3 + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); +#else + "'%.50s' object has no attribute '%.400s'", + tp->tp_name, PyString_AS_STRING(name)); +#endif + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} + +/* PyObjectCallMethod0 */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; +} + +/* RaiseNeedMoreValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* RaiseTooManyValuesToUnpack */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* UnpackItemEndCheck */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } else { + return __Pyx_IterFinish(); + } + return 0; +} + +/* RaiseNoneIterError */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); +} + +/* UnpackTupleError */ +static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) { + if (t == Py_None) { + __Pyx_RaiseNoneNotIterableError(); + } else if (PyTuple_GET_SIZE(t) < index) { + __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t)); + } else { + __Pyx_RaiseTooManyValuesError(index); + } +} + +/* UnpackTuple2 */ +static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( + PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, int decref_tuple) { + PyObject *value1 = NULL, *value2 = NULL; +#if CYTHON_COMPILING_IN_PYPY + value1 = PySequence_ITEM(tuple, 0); if (unlikely(!value1)) goto bad; + value2 = PySequence_ITEM(tuple, 1); if (unlikely(!value2)) goto bad; +#else + value1 = PyTuple_GET_ITEM(tuple, 0); Py_INCREF(value1); + value2 = PyTuple_GET_ITEM(tuple, 1); Py_INCREF(value2); +#endif + if (decref_tuple) { + Py_DECREF(tuple); + } + *pvalue1 = value1; + *pvalue2 = value2; + return 0; +#if CYTHON_COMPILING_IN_PYPY +bad: + Py_XDECREF(value1); + Py_XDECREF(value2); + if (decref_tuple) { Py_XDECREF(tuple); } + return -1; +#endif +} +static int __Pyx_unpack_tuple2_generic(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, + int has_known_size, int decref_tuple) { + Py_ssize_t index; + PyObject *value1 = NULL, *value2 = NULL, *iter = NULL; + iternextfunc iternext; + iter = PyObject_GetIter(tuple); + if (unlikely(!iter)) goto bad; + if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; } + iternext = Py_TYPE(iter)->tp_iternext; + value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; } + value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; } + if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad; + Py_DECREF(iter); + *pvalue1 = value1; + *pvalue2 = value2; + return 0; +unpacking_failed: + if (!has_known_size && __Pyx_IterFinish() == 0) + __Pyx_RaiseNeedMoreValuesError(index); +bad: + Py_XDECREF(iter); + Py_XDECREF(value1); + Py_XDECREF(value2); + if (decref_tuple) { Py_XDECREF(tuple); } + return -1; +} + +/* dict_iter */ +static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name, + Py_ssize_t* p_orig_length, int* p_source_is_dict) { + is_dict = is_dict || likely(PyDict_CheckExact(iterable)); + *p_source_is_dict = is_dict; + if (is_dict) { +#if !CYTHON_COMPILING_IN_PYPY + *p_orig_length = PyDict_Size(iterable); + Py_INCREF(iterable); + return iterable; +#elif PY_MAJOR_VERSION >= 3 + static PyObject *py_items = NULL, *py_keys = NULL, *py_values = NULL; + PyObject **pp = NULL; + if (method_name) { + const char *name = PyUnicode_AsUTF8(method_name); + if (strcmp(name, "iteritems") == 0) pp = &py_items; + else if (strcmp(name, "iterkeys") == 0) pp = &py_keys; + else if (strcmp(name, "itervalues") == 0) pp = &py_values; + if (pp) { + if (!*pp) { + *pp = PyUnicode_FromString(name + 4); + if (!*pp) + return NULL; + } + method_name = *pp; + } + } +#endif + } + *p_orig_length = 0; + if (method_name) { + PyObject* iter; + iterable = __Pyx_PyObject_CallMethod0(iterable, method_name); + if (!iterable) + return NULL; +#if !CYTHON_COMPILING_IN_PYPY + if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable)) + return iterable; +#endif + iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + return iter; + } + return PyObject_GetIter(iterable); +} +static CYTHON_INLINE int __Pyx_dict_iter_next( + PyObject* iter_obj, CYTHON_NCP_UNUSED Py_ssize_t orig_length, CYTHON_NCP_UNUSED Py_ssize_t* ppos, + PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) { + PyObject* next_item; +#if !CYTHON_COMPILING_IN_PYPY + if (source_is_dict) { + PyObject *key, *value; + if (unlikely(orig_length != PyDict_Size(iter_obj))) { + PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); + return -1; + } + if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) { + return 0; + } + if (pitem) { + PyObject* tuple = PyTuple_New(2); + if (unlikely(!tuple)) { + return -1; + } + Py_INCREF(key); + Py_INCREF(value); + PyTuple_SET_ITEM(tuple, 0, key); + PyTuple_SET_ITEM(tuple, 1, value); + *pitem = tuple; + } else { + if (pkey) { + Py_INCREF(key); + *pkey = key; + } + if (pvalue) { + Py_INCREF(value); + *pvalue = value; + } + } + return 1; + } else if (PyTuple_CheckExact(iter_obj)) { + Py_ssize_t pos = *ppos; + if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0; + *ppos = pos + 1; + next_item = PyTuple_GET_ITEM(iter_obj, pos); + Py_INCREF(next_item); + } else if (PyList_CheckExact(iter_obj)) { + Py_ssize_t pos = *ppos; + if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0; + *ppos = pos + 1; + next_item = PyList_GET_ITEM(iter_obj, pos); + Py_INCREF(next_item); + } else +#endif + { + next_item = PyIter_Next(iter_obj); + if (unlikely(!next_item)) { + return __Pyx_IterFinish(); + } + } + if (pitem) { + *pitem = next_item; + } else if (pkey && pvalue) { + if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1)) + return -1; + } else if (pkey) { + *pkey = next_item; + } else { + *pvalue = next_item; + } + return 1; +} + +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type, *local_value, *local_tb; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + +/* SwapException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = *type; + exc_info->exc_value = *value; + exc_info->exc_traceback = *tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = *type; + tstate->exc_value = *value; + tstate->exc_traceback = *tb; + #endif + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#else +static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); + PyErr_SetExcInfo(*type, *value, *tb); + *type = tmp_type; + *value = tmp_value; + *tb = tmp_tb; +} +#endif + +/* SaveResetException */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate); + *type = exc_info->exc_type; + *value = exc_info->exc_value; + *tb = exc_info->exc_traceback; + #else + *type = tstate->exc_type; + *value = tstate->exc_value; + *tb = tstate->exc_traceback; + #endif + Py_XINCREF(*type); + Py_XINCREF(*value); + Py_XINCREF(*tb); +} +static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + #if CYTHON_USE_EXC_INFO_STACK + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = type; + exc_info->exc_value = value; + exc_info->exc_traceback = tb; + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = type; + tstate->exc_value = value; + tstate->exc_traceback = tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +#endif + +/* TypeImport */ +#ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, + size_t size, enum __Pyx_ImportType_CheckSize check_size) +{ + PyObject *result = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + result = PyObject_GetAttrString(module, class_name); + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if ((size_t)basicsize < size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(result); + return NULL; +} +#endif + +/* Import */ +static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { + PyObject *empty_list = 0; + PyObject *module = 0; + PyObject *global_dict = 0; + PyObject *empty_dict = 0; + PyObject *list; + #if PY_MAJOR_VERSION < 3 + PyObject *py_import; + py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import); + if (!py_import) + goto bad; + #endif + if (from_list) + list = from_list; + else { + empty_list = PyList_New(0); + if (!empty_list) + goto bad; + list = empty_list; + } + global_dict = PyModule_GetDict(__pyx_m); + if (!global_dict) + goto bad; + empty_dict = PyDict_New(); + if (!empty_dict) + goto bad; + { + #if PY_MAJOR_VERSION >= 3 + if (level == -1) { + if ((1) && (strchr(__Pyx_MODULE_NAME, '.'))) { + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, 1); + if (!module) { + if (!PyErr_ExceptionMatches(PyExc_ImportError)) + goto bad; + PyErr_Clear(); + } + } + level = 0; + } + #endif + if (!module) { + #if PY_MAJOR_VERSION < 3 + PyObject *py_level = PyInt_FromLong(level); + if (!py_level) + goto bad; + module = PyObject_CallFunctionObjArgs(py_import, + name, global_dict, empty_dict, list, py_level, (PyObject *)NULL); + Py_DECREF(py_level); + #else + module = PyImport_ImportModuleLevelObject( + name, global_dict, empty_dict, list, level); + #endif + } + } +bad: + #if PY_MAJOR_VERSION < 3 + Py_XDECREF(py_import); + #endif + Py_XDECREF(empty_list); + Py_XDECREF(empty_dict); + return module; +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Format(PyExc_ImportError, + #if PY_MAJOR_VERSION < 3 + "cannot import name %.230s", PyString_AS_STRING(name)); + #else + "cannot import name %S", name); + #endif + } + return value; +} + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if !CYTHON_AVOID_BORROWED_REFS +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 + result = _PyDict_GetItem_KnownHash(__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } else if (unlikely(PyErr_Occurred())) { + return NULL; + } +#else + result = PyDict_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } +#endif +#else + result = PyObject_GetItem(__pyx_d, name); + __PYX_UPDATE_DICT_CACHE(__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = a->tp_base; + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; + if (!res) { + res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } + return res; +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; ip) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + type_name, type_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_writer.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_http_writer.cp39-win_amd64.pyd new file mode 100644 index 0000000..698179f Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/_http_writer.cp39-win_amd64.pyd differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_http_writer.pyx b/dist/ba_data/python-site-packages/aiohttp/_http_writer.pyx new file mode 100644 index 0000000..84b42fa --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_http_writer.pyx @@ -0,0 +1,151 @@ +from cpython.bytes cimport PyBytes_FromStringAndSize +from cpython.exc cimport PyErr_NoMemory +from cpython.mem cimport PyMem_Free, PyMem_Malloc, PyMem_Realloc +from cpython.object cimport PyObject_Str +from libc.stdint cimport uint8_t, uint64_t +from libc.string cimport memcpy + +from multidict import istr + +DEF BUF_SIZE = 16 * 1024 # 16KiB +cdef char BUFFER[BUF_SIZE] + +cdef object _istr = istr + + +# ----------------- writer --------------------------- + +cdef struct Writer: + char *buf + Py_ssize_t size + Py_ssize_t pos + + +cdef inline void _init_writer(Writer* writer): + writer.buf = &BUFFER[0] + writer.size = BUF_SIZE + writer.pos = 0 + + +cdef inline void _release_writer(Writer* writer): + if writer.buf != BUFFER: + PyMem_Free(writer.buf) + + +cdef inline int _write_byte(Writer* writer, uint8_t ch): + cdef char * buf + cdef Py_ssize_t size + + if writer.pos == writer.size: + # reallocate + size = writer.size + BUF_SIZE + if writer.buf == BUFFER: + buf = PyMem_Malloc(size) + if buf == NULL: + PyErr_NoMemory() + return -1 + memcpy(buf, writer.buf, writer.size) + else: + buf = PyMem_Realloc(writer.buf, size) + if buf == NULL: + PyErr_NoMemory() + return -1 + writer.buf = buf + writer.size = size + writer.buf[writer.pos] = ch + writer.pos += 1 + return 0 + + +cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol): + cdef uint64_t utf = symbol + + if utf < 0x80: + return _write_byte(writer, utf) + elif utf < 0x800: + if _write_byte(writer, (0xc0 | (utf >> 6))) < 0: + return -1 + return _write_byte(writer, (0x80 | (utf & 0x3f))) + elif 0xD800 <= utf <= 0xDFFF: + # surogate pair, ignored + return 0 + elif utf < 0x10000: + if _write_byte(writer, (0xe0 | (utf >> 12))) < 0: + return -1 + if _write_byte(writer, (0x80 | ((utf >> 6) & 0x3f))) < 0: + return -1 + return _write_byte(writer, (0x80 | (utf & 0x3f))) + elif utf > 0x10FFFF: + # symbol is too large + return 0 + else: + if _write_byte(writer, (0xf0 | (utf >> 18))) < 0: + return -1 + if _write_byte(writer, + (0x80 | ((utf >> 12) & 0x3f))) < 0: + return -1 + if _write_byte(writer, + (0x80 | ((utf >> 6) & 0x3f))) < 0: + return -1 + return _write_byte(writer, (0x80 | (utf & 0x3f))) + + +cdef inline int _write_str(Writer* writer, str s): + cdef Py_UCS4 ch + for ch in s: + if _write_utf8(writer, ch) < 0: + return -1 + + +# --------------- _serialize_headers ---------------------- + +cdef str to_str(object s): + typ = type(s) + if typ is str: + return s + elif typ is _istr: + return PyObject_Str(s) + elif not isinstance(s, str): + raise TypeError("Cannot serialize non-str key {!r}".format(s)) + else: + return str(s) + + +def _serialize_headers(str status_line, headers): + cdef Writer writer + cdef object key + cdef object val + cdef bytes ret + + _init_writer(&writer) + + try: + if _write_str(&writer, status_line) < 0: + raise + if _write_byte(&writer, b'\r') < 0: + raise + if _write_byte(&writer, b'\n') < 0: + raise + + for key, val in headers.items(): + if _write_str(&writer, to_str(key)) < 0: + raise + if _write_byte(&writer, b':') < 0: + raise + if _write_byte(&writer, b' ') < 0: + raise + if _write_str(&writer, to_str(val)) < 0: + raise + if _write_byte(&writer, b'\r') < 0: + raise + if _write_byte(&writer, b'\n') < 0: + raise + + if _write_byte(&writer, b'\r') < 0: + raise + if _write_byte(&writer, b'\n') < 0: + raise + + return PyBytes_FromStringAndSize(writer.buf, writer.pos) + finally: + _release_writer(&writer) diff --git a/dist/ba_data/python-site-packages/aiohttp/_websocket.c b/dist/ba_data/python-site-packages/aiohttp/_websocket.c new file mode 100644 index 0000000..f3e5c32 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_websocket.c @@ -0,0 +1,3588 @@ +/* Generated by Cython 0.29.21 */ + +#define PY_SSIZE_T_CLEAN +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) + #error Cython requires Python 2.6+ or Python 3.3+. +#else +#define CYTHON_ABI "0_29_21" +#define CYTHON_HEX_VERSION 0x001D15F0 +#define CYTHON_FUTURE_DIVISION 1 +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef HAVE_LONG_LONG + #if PY_VERSION_HEX >= 0x02070000 + #define HAVE_LONG_LONG + #endif +#endif +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#ifdef PYPY_VERSION + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #if PY_VERSION_HEX < 0x03050000 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#elif defined(PYSTON_VERSION) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #elif !defined(CYTHON_USE_PYTYPE_LOOKUP) + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #if PY_MAJOR_VERSION < 3 + #undef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 0 + #elif !defined(CYTHON_USE_ASYNC_SLOTS) + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #if PY_VERSION_HEX < 0x02070000 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLONG_INTERNALS) + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #ifndef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if PY_VERSION_HEX < 0x030300F0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PY_VERSION_HEX >= 0x030400a1) + #endif + #ifndef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) + #endif +#endif +#if !defined(CYTHON_FAST_PYCCALL) +#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #include "longintrepr.h" + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_MAYBE_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_MAYBE_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#ifdef _MSC_VER + #ifndef _MSC_STDINT_H_ + #if _MSC_VER < 1300 + typedef unsigned char uint8_t; + typedef unsigned int uint32_t; + #else + typedef unsigned __int8 uint8_t; + typedef unsigned __int32 uint32_t; + #endif + #endif +#else + #include +#endif +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) && __cplusplus >= 201103L + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #elif __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__ ) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif + +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) + #define Py_OptimizeFlag 0 +#endif +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#if PY_MAJOR_VERSION < 3 + #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) + #define __Pyx_DefaultClassType PyClass_Type +#else + #define __Pyx_BUILTIN_MODULE_NAME "builtins" +#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2 + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif + #define __Pyx_DefaultClassType PyType_Type +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#if PY_VERSION_HEX <= 0x030700A3 || !defined(METH_FASTCALL) + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #define __Pyx_PyCFunctionFast _PyCFunctionFast + #define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords +#endif +#if CYTHON_FAST_PYCCALL +#define __Pyx_PyFastCFunction_Check(func)\ + ((PyCFunction_Check(func) && (METH_FASTCALL == (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))))) +#else +#define __Pyx_PyFastCFunction_Check(func) 0 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030400A1 + #define PyMem_RawMalloc(n) PyMem_Malloc(n) + #define PyMem_RawRealloc(p, n) PyMem_Realloc(p, n) + #define PyMem_RawFree(p) PyMem_Free(p) +#endif +#if CYTHON_COMPILING_IN_PYSTON + #define __Pyx_PyCode_HasFreeVars(co) PyCode_HasFreeVars(co) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) PyFrame_SetLineNumber(frame, lineno) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x03060000 + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#elif PY_VERSION_HEX >= 0x03000000 + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_Current +#endif +#if PY_VERSION_HEX < 0x030700A2 && !defined(PyThread_tss_create) && !defined(Py_tss_NEEDS_INIT) +#include "pythread.h" +#define Py_tss_NEEDS_INIT 0 +typedef int Py_tss_t; +static CYTHON_INLINE int PyThread_tss_create(Py_tss_t *key) { + *key = PyThread_create_key(); + return 0; +} +static CYTHON_INLINE Py_tss_t * PyThread_tss_alloc(void) { + Py_tss_t *key = (Py_tss_t *)PyObject_Malloc(sizeof(Py_tss_t)); + *key = Py_tss_NEEDS_INIT; + return key; +} +static CYTHON_INLINE void PyThread_tss_free(Py_tss_t *key) { + PyObject_Free(key); +} +static CYTHON_INLINE int PyThread_tss_is_created(Py_tss_t *key) { + return *key != Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE void PyThread_tss_delete(Py_tss_t *key) { + PyThread_delete_key(*key); + *key = Py_tss_NEEDS_INIT; +} +static CYTHON_INLINE int PyThread_tss_set(Py_tss_t *key, void *value) { + return PyThread_set_key_value(*key, value); +} +static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { + return PyThread_get_key_value(*key); +} +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#if PY_MAJOR_VERSION >= 3 || CYTHON_FUTURE_DIVISION + #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#else + #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) + #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500A1 && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStr(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +#else +#define __Pyx_PyDict_GetItemStr(dict, name) PyDict_GetItem(dict, name) +#endif +#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) + #define CYTHON_PEP393_ENABLED 1 + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, ch) + #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #endif +#else + #define CYTHON_PEP393_ENABLED 0 + #define PyUnicode_1BYTE_KIND 1 + #define PyUnicode_2BYTE_KIND 2 + #define PyUnicode_4BYTE_KIND 4 + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) + #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((sizeof(Py_UNICODE) == 2) ? 65535 : 1114111) + #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) + #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) (((void)(k)), ((Py_UNICODE*)d)[i] = ch) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) +#endif +#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyString_Check(b) && !PyString_CheckExact(b)))) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) +#else + #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) +#endif +#if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) + #define PyObject_ASCII(o) PyObject_Repr(o) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBaseString_Type PyUnicode_Type + #define PyStringObject PyUnicodeObject + #define PyString_Type PyUnicode_Type + #define PyString_Check PyUnicode_Check + #define PyString_CheckExact PyUnicode_CheckExact +#ifndef PyObject_Unicode + #define PyObject_Unicode PyObject_Str +#endif +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) + #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) +#else + #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) + #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) +#else + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyIntObject PyLongObject + #define PyInt_Type PyLong_Type + #define PyInt_Check(op) PyLong_Check(op) + #define PyInt_CheckExact(op) PyLong_CheckExact(op) + #define PyInt_FromString PyLong_FromString + #define PyInt_FromUnicode PyLong_FromUnicode + #define PyInt_FromLong PyLong_FromLong + #define PyInt_FromSize_t PyLong_FromSize_t + #define PyInt_FromSsize_t PyLong_FromSsize_t + #define PyInt_AsLong PyLong_AsLong + #define PyInt_AS_LONG PyLong_AS_LONG + #define PyInt_AsSsize_t PyLong_AsSsize_t + #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask + #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask + #define PyNumber_Int PyNumber_Long +#endif +#if PY_MAJOR_VERSION >= 3 + #define PyBoolObject PyLongObject +#endif +#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY + #ifndef PyUnicode_InternFromString + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) + #endif +#endif +#if PY_VERSION_HEX < 0x030200A4 + typedef long Py_hash_t; + #define __Pyx_PyInt_FromHash_t PyInt_FromLong + #define __Pyx_PyInt_AsHash_t PyInt_AsLong +#else + #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t + #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t +#endif +#if PY_MAJOR_VERSION >= 3 + #define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func)) +#else + #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) +#endif +#if CYTHON_USE_ASYNC_SLOTS + #if PY_VERSION_HEX >= 0x030500B1 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods + #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) + #else + #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) + #endif +#else + #define __Pyx_PyType_AsAsync(obj) NULL +#endif +#ifndef __Pyx_PyAsyncMethodsStruct + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } __Pyx_PyAsyncMethodsStruct; +#endif + +#if defined(WIN32) || defined(MS_WINDOWS) + #define _USE_MATH_DEFINES +#endif +#include +#ifdef NAN +#define __PYX_NAN() ((float) NAN) +#else +static CYTHON_INLINE float __PYX_NAN() { + float value; + memset(&value, 0xFF, sizeof(value)); + return value; +} +#endif +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#define __PYX_MARK_ERR_POS(f_index, lineno) \ + { __pyx_filename = __pyx_f[f_index]; (void)__pyx_filename; __pyx_lineno = lineno; (void)__pyx_lineno; __pyx_clineno = __LINE__; (void)__pyx_clineno; } +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifndef __PYX_EXTERN_C + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__aiohttp___websocket +#define __PYX_HAVE_API__aiohttp___websocket +/* Early includes */ +#include +#include +#include "pythread.h" +#include +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; + const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; + +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT (PY_MAJOR_VERSION >= 3 && __PYX_DEFAULT_STRING_ENCODING_IS_UTF8) +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if PY_MAJOR_VERSION < 3 + #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#else + #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString + #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize +#endif +#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) +#define __Pyx_PyObject_AsWritableString(s) ((char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { + const Py_UNICODE *u_end = u; + while (*u_end++) ; + return (size_t)(u_end - u - 1); +} +#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) +#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) +#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +#if CYTHON_ASSUME_SAFE_MACROS +#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#else +#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#endif +#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) +#if PY_MAJOR_VERSION >= 3 +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#else +#define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) +#endif +#define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII +static int __Pyx_sys_getdefaultencoding_not_ascii; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + PyObject* ascii_chars_u = NULL; + PyObject* ascii_chars_b = NULL; + const char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + if (strcmp(default_encoding_c, "ascii") == 0) { + __Pyx_sys_getdefaultencoding_not_ascii = 0; + } else { + char ascii_chars[128]; + int c; + for (c = 0; c < 128; c++) { + ascii_chars[c] = c; + } + __Pyx_sys_getdefaultencoding_not_ascii = 1; + ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); + if (!ascii_chars_u) goto bad; + ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); + if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { + PyErr_Format( + PyExc_ValueError, + "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", + default_encoding_c); + goto bad; + } + Py_DECREF(ascii_chars_u); + Py_DECREF(ascii_chars_b); + } + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + Py_XDECREF(ascii_chars_u); + Py_XDECREF(ascii_chars_b); + return -1; +} +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#else +#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +static char* __PYX_DEFAULT_STRING_ENCODING; +static int __Pyx_init_sys_getdefaultencoding_params(void) { + PyObject* sys; + PyObject* default_encoding = NULL; + char* default_encoding_c; + sys = PyImport_ImportModule("sys"); + if (!sys) goto bad; + default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); + Py_DECREF(sys); + if (!default_encoding) goto bad; + default_encoding_c = PyBytes_AsString(default_encoding); + if (!default_encoding_c) goto bad; + __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c) + 1); + if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; + strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); + Py_DECREF(default_encoding); + return 0; +bad: + Py_XDECREF(default_encoding); + return -1; +} +#endif +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } + +static PyObject *__pyx_m = NULL; +static PyObject *__pyx_d; +static PyObject *__pyx_b; +static PyObject *__pyx_cython_runtime = NULL; +static PyObject *__pyx_empty_tuple; +static PyObject *__pyx_empty_bytes; +static PyObject *__pyx_empty_unicode; +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * __pyx_cfilenm= __FILE__; +static const char *__pyx_filename; + + +static const char *__pyx_f[] = { + "aiohttp\\_websocket.pyx", + "type.pxd", + "bool.pxd", + "complex.pxd", +}; + +/*--- Type declarations ---*/ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*SetupContext)(const char*, int, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; +#ifdef WITH_THREAD + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ + } +#else + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) +#endif + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) + #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* PyObjectGetAttrStr.proto */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* GetBuiltinName.proto */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* RaiseDoubleKeywords.proto */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywords.proto */ +static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ + PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ + const char* function_name); + +/* PyCFunctionFastCall.proto */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject *__Pyx_PyCFunction_FastCall(PyObject *func, PyObject **args, Py_ssize_t nargs); +#else +#define __Pyx_PyCFunction_FastCall(func, args, nargs) (assert(0), NULL) +#endif + +/* PyFunctionFastCall.proto */ +#if CYTHON_FAST_PYCALL +#define __Pyx_PyFunction_FastCall(func, args, nargs)\ + __Pyx_PyFunction_FastCallDict((func), (args), (nargs), NULL) +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); +#else +#define __Pyx_PyFunction_FastCallDict(func, args, nargs, kwargs) _PyFunction_FastCallDict(func, args, nargs, kwargs) +#endif +#define __Pyx_BUILD_ASSERT_EXPR(cond)\ + (sizeof(char [1 - 2*!(cond)]) - 1) +#ifndef Py_MEMBER_SIZE +#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) +#endif + static size_t __pyx_pyframe_localsplus_offset = 0; + #include "frameobject.h" + #define __Pxy_PyFrame_Initialize_Offsets()\ + ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ + (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) + #define __Pyx_PyFrame_GetLocalsplus(frame)\ + (assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset)) +#endif + +/* PyObjectCall.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectCallOneArg.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* TypeImport.proto */ +#ifndef __PYX_HAVE_RT_ImportType_proto +#define __PYX_HAVE_RT_ImportType_proto +enum __Pyx_ImportType_CheckSize { + __Pyx_ImportType_CheckSize_Error = 0, + __Pyx_ImportType_CheckSize_Warn = 1, + __Pyx_ImportType_CheckSize_Ignore = 2 +}; +static PyTypeObject *__Pyx_ImportType(PyObject* module, const char *module_name, const char *class_name, size_t size, enum __Pyx_ImportType_CheckSize check_size); +#endif + +/* PyDictVersioning.proto */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __pyx_dict_cached_value;\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* PyThreadStateGet.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#define __Pyx_PyErr_Occurred() __pyx_tstate->curexc_type +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* CLineInTraceback.proto */ +#ifdef CYTHON_CLINE_IN_TRACEBACK +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#else +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#endif + +/* CodeObjectCache.proto */ +typedef struct { + PyCodeObject* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; +}; +static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static PyCodeObject *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +#define __Pyx_PyErr_GivenExceptionMatches2(err, type1, type2) (PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2)) +#endif +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(void); + +/* InitStrings.proto */ +static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); + + +/* Module declarations from 'cpython.version' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.type' */ +static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0; + +/* Module declarations from 'libc.string' */ + +/* Module declarations from 'libc.stdio' */ + +/* Module declarations from 'cpython.object' */ + +/* Module declarations from 'cpython.ref' */ + +/* Module declarations from 'cpython.exc' */ + +/* Module declarations from 'cpython.module' */ + +/* Module declarations from 'cpython.mem' */ + +/* Module declarations from 'cpython.tuple' */ + +/* Module declarations from 'cpython.list' */ + +/* Module declarations from 'cpython.sequence' */ + +/* Module declarations from 'cpython.mapping' */ + +/* Module declarations from 'cpython.iterator' */ + +/* Module declarations from 'cpython.number' */ + +/* Module declarations from 'cpython.int' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.bool' */ +static PyTypeObject *__pyx_ptype_7cpython_4bool_bool = 0; + +/* Module declarations from 'cpython.long' */ + +/* Module declarations from 'cpython.float' */ + +/* Module declarations from '__builtin__' */ + +/* Module declarations from 'cpython.complex' */ +static PyTypeObject *__pyx_ptype_7cpython_7complex_complex = 0; + +/* Module declarations from 'cpython.string' */ + +/* Module declarations from 'cpython.unicode' */ + +/* Module declarations from 'cpython.dict' */ + +/* Module declarations from 'cpython.instance' */ + +/* Module declarations from 'cpython.function' */ + +/* Module declarations from 'cpython.method' */ + +/* Module declarations from 'cpython.weakref' */ + +/* Module declarations from 'cpython.getargs' */ + +/* Module declarations from 'cpython.pythread' */ + +/* Module declarations from 'cpython.pystate' */ + +/* Module declarations from 'cpython.cobject' */ + +/* Module declarations from 'cpython.oldbuffer' */ + +/* Module declarations from 'cpython.set' */ + +/* Module declarations from 'cpython.buffer' */ + +/* Module declarations from 'cpython.bytes' */ + +/* Module declarations from 'cpython.pycapsule' */ + +/* Module declarations from 'cpython' */ + +/* Module declarations from 'libc.stdint' */ + +/* Module declarations from 'aiohttp._websocket' */ +#define __Pyx_MODULE_NAME "aiohttp._websocket" +extern int __pyx_module_is_main_aiohttp___websocket; +int __pyx_module_is_main_aiohttp___websocket = 0; + +/* Implementation of 'aiohttp._websocket' */ +static PyObject *__pyx_builtin_range; +static const char __pyx_k_i[] = "i"; +static const char __pyx_k_data[] = "data"; +static const char __pyx_k_main[] = "__main__"; +static const char __pyx_k_mask[] = "mask"; +static const char __pyx_k_name[] = "__name__"; +static const char __pyx_k_test[] = "__test__"; +static const char __pyx_k_range[] = "range"; +static const char __pyx_k_in_buf[] = "in_buf"; +static const char __pyx_k_data_len[] = "data_len"; +static const char __pyx_k_mask_buf[] = "mask_buf"; +static const char __pyx_k_uint32_msk[] = "uint32_msk"; +static const char __pyx_k_uint64_msk[] = "uint64_msk"; +static const char __pyx_k_aiohttp__websocket[] = "aiohttp._websocket"; +static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback"; +static const char __pyx_k_websocket_mask_cython[] = "_websocket_mask_cython"; +static const char __pyx_k_aiohttp__websocket_pyx[] = "aiohttp\\_websocket.pyx"; +static PyObject *__pyx_n_s_aiohttp__websocket; +static PyObject *__pyx_kp_s_aiohttp__websocket_pyx; +static PyObject *__pyx_n_s_cline_in_traceback; +static PyObject *__pyx_n_s_data; +static PyObject *__pyx_n_s_data_len; +static PyObject *__pyx_n_s_i; +static PyObject *__pyx_n_s_in_buf; +static PyObject *__pyx_n_s_main; +static PyObject *__pyx_n_s_mask; +static PyObject *__pyx_n_s_mask_buf; +static PyObject *__pyx_n_s_name; +static PyObject *__pyx_n_s_range; +static PyObject *__pyx_n_s_test; +static PyObject *__pyx_n_s_uint32_msk; +static PyObject *__pyx_n_s_uint64_msk; +static PyObject *__pyx_n_s_websocket_mask_cython; +static PyObject *__pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_mask, PyObject *__pyx_v_data); /* proto */ +static PyObject *__pyx_tuple_; +static PyObject *__pyx_codeobj__2; +/* Late includes */ + +/* "aiohttp/_websocket.pyx":11 + * + * + * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< + * """Note, this function mutates its `data` argument + * """ + */ + +/* Python wrapper */ +static PyObject *__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ +static char __pyx_doc_7aiohttp_10_websocket__websocket_mask_cython[] = "Note, this function mutates its `data` argument\n "; +static PyMethodDef __pyx_mdef_7aiohttp_10_websocket_1_websocket_mask_cython = {"_websocket_mask_cython", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7aiohttp_10_websocket__websocket_mask_cython}; +static PyObject *__pyx_pw_7aiohttp_10_websocket_1_websocket_mask_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { + PyObject *__pyx_v_mask = 0; + PyObject *__pyx_v_data = 0; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_websocket_mask_cython (wrapper)", 0); + { + static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_mask,&__pyx_n_s_data,0}; + PyObject* values[2] = {0,0}; + if (unlikely(__pyx_kwds)) { + Py_ssize_t kw_args; + const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); + switch (pos_args) { + case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + CYTHON_FALLTHROUGH; + case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + kw_args = PyDict_Size(__pyx_kwds); + switch (pos_args) { + case 0: + if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask)) != 0)) kw_args--; + else goto __pyx_L5_argtuple_error; + CYTHON_FALLTHROUGH; + case 1: + if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--; + else { + __Pyx_RaiseArgtupleInvalid("_websocket_mask_cython", 1, 2, 2, 1); __PYX_ERR(0, 11, __pyx_L3_error) + } + } + if (unlikely(kw_args > 0)) { + if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_websocket_mask_cython") < 0)) __PYX_ERR(0, 11, __pyx_L3_error) + } + } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = PyTuple_GET_ITEM(__pyx_args, 0); + values[1] = PyTuple_GET_ITEM(__pyx_args, 1); + } + __pyx_v_mask = values[0]; + __pyx_v_data = values[1]; + } + goto __pyx_L4_argument_unpacking_done; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("_websocket_mask_cython", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 11, __pyx_L3_error) + __pyx_L3_error:; + __Pyx_AddTraceback("aiohttp._websocket._websocket_mask_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + __pyx_r = __pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(__pyx_self, __pyx_v_mask, __pyx_v_data); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_7aiohttp_10_websocket__websocket_mask_cython(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_mask, PyObject *__pyx_v_data) { + Py_ssize_t __pyx_v_data_len; + Py_ssize_t __pyx_v_i; + unsigned char *__pyx_v_in_buf; + unsigned char const *__pyx_v_mask_buf; + uint32_t __pyx_v_uint32_msk; + uint64_t __pyx_v_uint64_msk; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + Py_ssize_t __pyx_t_1; + int __pyx_t_2; + int __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + char *__pyx_t_5; + uint64_t *__pyx_t_6; + long __pyx_t_7; + uint32_t *__pyx_t_8; + Py_ssize_t __pyx_t_9; + Py_ssize_t __pyx_t_10; + Py_ssize_t __pyx_t_11; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_websocket_mask_cython", 0); + __Pyx_INCREF(__pyx_v_mask); + __Pyx_INCREF(__pyx_v_data); + + /* "aiohttp/_websocket.pyx":22 + * uint64_t uint64_msk + * + * assert len(mask) == 4 # <<<<<<<<<<<<<< + * + * if not isinstance(mask, bytes): + */ + #ifndef CYTHON_WITHOUT_ASSERTIONS + if (unlikely(!Py_OptimizeFlag)) { + __pyx_t_1 = PyObject_Length(__pyx_v_mask); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 22, __pyx_L1_error) + if (unlikely(!((__pyx_t_1 == 4) != 0))) { + PyErr_SetNone(PyExc_AssertionError); + __PYX_ERR(0, 22, __pyx_L1_error) + } + } + #endif + + /* "aiohttp/_websocket.pyx":24 + * assert len(mask) == 4 + * + * if not isinstance(mask, bytes): # <<<<<<<<<<<<<< + * mask = bytes(mask) + * + */ + __pyx_t_2 = PyBytes_Check(__pyx_v_mask); + __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); + if (__pyx_t_3) { + + /* "aiohttp/_websocket.pyx":25 + * + * if not isinstance(mask, bytes): + * mask = bytes(mask) # <<<<<<<<<<<<<< + * + * if isinstance(data, bytearray): + */ + __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_v_mask); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF_SET(__pyx_v_mask, __pyx_t_4); + __pyx_t_4 = 0; + + /* "aiohttp/_websocket.pyx":24 + * assert len(mask) == 4 + * + * if not isinstance(mask, bytes): # <<<<<<<<<<<<<< + * mask = bytes(mask) + * + */ + } + + /* "aiohttp/_websocket.pyx":27 + * mask = bytes(mask) + * + * if isinstance(data, bytearray): # <<<<<<<<<<<<<< + * data = data + * else: + */ + __pyx_t_3 = PyByteArray_Check(__pyx_v_data); + __pyx_t_2 = (__pyx_t_3 != 0); + if (__pyx_t_2) { + + /* "aiohttp/_websocket.pyx":28 + * + * if isinstance(data, bytearray): + * data = data # <<<<<<<<<<<<<< + * else: + * data = bytearray(data) + */ + __pyx_t_4 = __pyx_v_data; + __Pyx_INCREF(__pyx_t_4); + __Pyx_DECREF_SET(__pyx_v_data, __pyx_t_4); + __pyx_t_4 = 0; + + /* "aiohttp/_websocket.pyx":27 + * mask = bytes(mask) + * + * if isinstance(data, bytearray): # <<<<<<<<<<<<<< + * data = data + * else: + */ + goto __pyx_L4; + } + + /* "aiohttp/_websocket.pyx":30 + * data = data + * else: + * data = bytearray(data) # <<<<<<<<<<<<<< + * + * data_len = len(data) + */ + /*else*/ { + __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyByteArray_Type)), __pyx_v_data); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF_SET(__pyx_v_data, __pyx_t_4); + __pyx_t_4 = 0; + } + __pyx_L4:; + + /* "aiohttp/_websocket.pyx":32 + * data = bytearray(data) + * + * data_len = len(data) # <<<<<<<<<<<<<< + * in_buf = PyByteArray_AsString(data) + * mask_buf = PyBytes_AsString(mask) + */ + __pyx_t_1 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_1 == ((Py_ssize_t)-1))) __PYX_ERR(0, 32, __pyx_L1_error) + __pyx_v_data_len = __pyx_t_1; + + /* "aiohttp/_websocket.pyx":33 + * + * data_len = len(data) + * in_buf = PyByteArray_AsString(data) # <<<<<<<<<<<<<< + * mask_buf = PyBytes_AsString(mask) + * uint32_msk = (mask_buf)[0] + */ + if (!(likely(PyByteArray_CheckExact(__pyx_v_data))||((__pyx_v_data) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytearray", Py_TYPE(__pyx_v_data)->tp_name), 0))) __PYX_ERR(0, 33, __pyx_L1_error) + __pyx_t_5 = PyByteArray_AsString(((PyObject*)__pyx_v_data)); if (unlikely(__pyx_t_5 == ((char *)NULL))) __PYX_ERR(0, 33, __pyx_L1_error) + __pyx_v_in_buf = ((unsigned char *)__pyx_t_5); + + /* "aiohttp/_websocket.pyx":34 + * data_len = len(data) + * in_buf = PyByteArray_AsString(data) + * mask_buf = PyBytes_AsString(mask) # <<<<<<<<<<<<<< + * uint32_msk = (mask_buf)[0] + * + */ + __pyx_t_5 = PyBytes_AsString(__pyx_v_mask); if (unlikely(__pyx_t_5 == ((char *)NULL))) __PYX_ERR(0, 34, __pyx_L1_error) + __pyx_v_mask_buf = ((unsigned char const *)__pyx_t_5); + + /* "aiohttp/_websocket.pyx":35 + * in_buf = PyByteArray_AsString(data) + * mask_buf = PyBytes_AsString(mask) + * uint32_msk = (mask_buf)[0] # <<<<<<<<<<<<<< + * + * # TODO: align in_data ptr to achieve even faster speeds + */ + __pyx_v_uint32_msk = (((uint32_t *)__pyx_v_mask_buf)[0]); + + /* "aiohttp/_websocket.pyx":40 + * # does it need in python ?! malloc() always aligns to sizeof(long) bytes + * + * if sizeof(size_t) >= 8: # <<<<<<<<<<<<<< + * uint64_msk = uint32_msk + * uint64_msk = (uint64_msk << 32) | uint32_msk + */ + __pyx_t_2 = (((sizeof(size_t)) >= 8) != 0); + if (__pyx_t_2) { + + /* "aiohttp/_websocket.pyx":41 + * + * if sizeof(size_t) >= 8: + * uint64_msk = uint32_msk # <<<<<<<<<<<<<< + * uint64_msk = (uint64_msk << 32) | uint32_msk + * + */ + __pyx_v_uint64_msk = __pyx_v_uint32_msk; + + /* "aiohttp/_websocket.pyx":42 + * if sizeof(size_t) >= 8: + * uint64_msk = uint32_msk + * uint64_msk = (uint64_msk << 32) | uint32_msk # <<<<<<<<<<<<<< + * + * while data_len >= 8: + */ + __pyx_v_uint64_msk = ((__pyx_v_uint64_msk << 32) | __pyx_v_uint32_msk); + + /* "aiohttp/_websocket.pyx":44 + * uint64_msk = (uint64_msk << 32) | uint32_msk + * + * while data_len >= 8: # <<<<<<<<<<<<<< + * (in_buf)[0] ^= uint64_msk + * in_buf += 8 + */ + while (1) { + __pyx_t_2 = ((__pyx_v_data_len >= 8) != 0); + if (!__pyx_t_2) break; + + /* "aiohttp/_websocket.pyx":45 + * + * while data_len >= 8: + * (in_buf)[0] ^= uint64_msk # <<<<<<<<<<<<<< + * in_buf += 8 + * data_len -= 8 + */ + __pyx_t_6 = ((uint64_t *)__pyx_v_in_buf); + __pyx_t_7 = 0; + (__pyx_t_6[__pyx_t_7]) = ((__pyx_t_6[__pyx_t_7]) ^ __pyx_v_uint64_msk); + + /* "aiohttp/_websocket.pyx":46 + * while data_len >= 8: + * (in_buf)[0] ^= uint64_msk + * in_buf += 8 # <<<<<<<<<<<<<< + * data_len -= 8 + * + */ + __pyx_v_in_buf = (__pyx_v_in_buf + 8); + + /* "aiohttp/_websocket.pyx":47 + * (in_buf)[0] ^= uint64_msk + * in_buf += 8 + * data_len -= 8 # <<<<<<<<<<<<<< + * + * + */ + __pyx_v_data_len = (__pyx_v_data_len - 8); + } + + /* "aiohttp/_websocket.pyx":40 + * # does it need in python ?! malloc() always aligns to sizeof(long) bytes + * + * if sizeof(size_t) >= 8: # <<<<<<<<<<<<<< + * uint64_msk = uint32_msk + * uint64_msk = (uint64_msk << 32) | uint32_msk + */ + } + + /* "aiohttp/_websocket.pyx":50 + * + * + * while data_len >= 4: # <<<<<<<<<<<<<< + * (in_buf)[0] ^= uint32_msk + * in_buf += 4 + */ + while (1) { + __pyx_t_2 = ((__pyx_v_data_len >= 4) != 0); + if (!__pyx_t_2) break; + + /* "aiohttp/_websocket.pyx":51 + * + * while data_len >= 4: + * (in_buf)[0] ^= uint32_msk # <<<<<<<<<<<<<< + * in_buf += 4 + * data_len -= 4 + */ + __pyx_t_8 = ((uint32_t *)__pyx_v_in_buf); + __pyx_t_7 = 0; + (__pyx_t_8[__pyx_t_7]) = ((__pyx_t_8[__pyx_t_7]) ^ __pyx_v_uint32_msk); + + /* "aiohttp/_websocket.pyx":52 + * while data_len >= 4: + * (in_buf)[0] ^= uint32_msk + * in_buf += 4 # <<<<<<<<<<<<<< + * data_len -= 4 + * + */ + __pyx_v_in_buf = (__pyx_v_in_buf + 4); + + /* "aiohttp/_websocket.pyx":53 + * (in_buf)[0] ^= uint32_msk + * in_buf += 4 + * data_len -= 4 # <<<<<<<<<<<<<< + * + * for i in range(0, data_len): + */ + __pyx_v_data_len = (__pyx_v_data_len - 4); + } + + /* "aiohttp/_websocket.pyx":55 + * data_len -= 4 + * + * for i in range(0, data_len): # <<<<<<<<<<<<<< + * in_buf[i] ^= mask_buf[i] + */ + __pyx_t_1 = __pyx_v_data_len; + __pyx_t_9 = __pyx_t_1; + for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) { + __pyx_v_i = __pyx_t_10; + + /* "aiohttp/_websocket.pyx":56 + * + * for i in range(0, data_len): + * in_buf[i] ^= mask_buf[i] # <<<<<<<<<<<<<< + */ + __pyx_t_11 = __pyx_v_i; + (__pyx_v_in_buf[__pyx_t_11]) = ((__pyx_v_in_buf[__pyx_t_11]) ^ (__pyx_v_mask_buf[__pyx_v_i])); + } + + /* "aiohttp/_websocket.pyx":11 + * + * + * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< + * """Note, this function mutates its `data` argument + * """ + */ + + /* function exit code */ + __pyx_r = Py_None; __Pyx_INCREF(Py_None); + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_AddTraceback("aiohttp._websocket._websocket_mask_cython", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_mask); + __Pyx_XDECREF(__pyx_v_data); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; + +#if PY_MAJOR_VERSION >= 3 +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec__websocket(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec__websocket}, + {0, NULL} +}; +#endif + +static struct PyModuleDef __pyx_moduledef = { + PyModuleDef_HEAD_INIT, + "_websocket", + 0, /* m_doc */ + #if CYTHON_PEP489_MULTI_PHASE_INIT + 0, /* m_size */ + #else + -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ +}; +#endif +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +static __Pyx_StringTabEntry __pyx_string_tab[] = { + {&__pyx_n_s_aiohttp__websocket, __pyx_k_aiohttp__websocket, sizeof(__pyx_k_aiohttp__websocket), 0, 0, 1, 1}, + {&__pyx_kp_s_aiohttp__websocket_pyx, __pyx_k_aiohttp__websocket_pyx, sizeof(__pyx_k_aiohttp__websocket_pyx), 0, 0, 1, 0}, + {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1}, + {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1}, + {&__pyx_n_s_data_len, __pyx_k_data_len, sizeof(__pyx_k_data_len), 0, 0, 1, 1}, + {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1}, + {&__pyx_n_s_in_buf, __pyx_k_in_buf, sizeof(__pyx_k_in_buf), 0, 0, 1, 1}, + {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, + {&__pyx_n_s_mask, __pyx_k_mask, sizeof(__pyx_k_mask), 0, 0, 1, 1}, + {&__pyx_n_s_mask_buf, __pyx_k_mask_buf, sizeof(__pyx_k_mask_buf), 0, 0, 1, 1}, + {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1}, + {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1}, + {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, + {&__pyx_n_s_uint32_msk, __pyx_k_uint32_msk, sizeof(__pyx_k_uint32_msk), 0, 0, 1, 1}, + {&__pyx_n_s_uint64_msk, __pyx_k_uint64_msk, sizeof(__pyx_k_uint64_msk), 0, 0, 1, 1}, + {&__pyx_n_s_websocket_mask_cython, __pyx_k_websocket_mask_cython, sizeof(__pyx_k_websocket_mask_cython), 0, 0, 1, 1}, + {0, 0, 0, 0, 0, 0, 0} +}; +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) { + __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) __PYX_ERR(0, 55, __pyx_L1_error) + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "aiohttp/_websocket.pyx":11 + * + * + * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< + * """Note, this function mutates its `data` argument + * """ + */ + __pyx_tuple_ = PyTuple_Pack(8, __pyx_n_s_mask, __pyx_n_s_data, __pyx_n_s_data_len, __pyx_n_s_i, __pyx_n_s_in_buf, __pyx_n_s_mask_buf, __pyx_n_s_uint32_msk, __pyx_n_s_uint64_msk); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 11, __pyx_L1_error) + __Pyx_GOTREF(__pyx_tuple_); + __Pyx_GIVEREF(__pyx_tuple_); + __pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(2, 0, 8, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_aiohttp__websocket_pyx, __pyx_n_s_websocket_mask_cython, 11, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) __PYX_ERR(0, 11, __pyx_L1_error) + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) { + if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + return 0; + __pyx_L1_error:; + return -1; +} + +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(void); /*proto*/ + +static int __Pyx_modinit_global_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(void) { + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", + #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 + sizeof(PyTypeObject), + #else + sizeof(PyHeapTypeObject), + #endif + __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4type_type) __PYX_ERR(1, 9, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 8, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_4bool_bool = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "bool", sizeof(PyBoolObject), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_4bool_bool) __PYX_ERR(2, 8, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 15, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_ptype_7cpython_7complex_complex = __Pyx_ImportType(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "complex", sizeof(PyComplexObject), __Pyx_ImportType_CheckSize_Warn); + if (!__pyx_ptype_7cpython_7complex_complex) __PYX_ERR(3, 15, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_RefNannyFinishContext(); + return -1; +} + +static int __Pyx_modinit_variable_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(void) { + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + + +#ifndef CYTHON_NO_PYINIT_EXPORT +#define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#elif PY_MAJOR_VERSION < 3 +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" void +#else +#define __Pyx_PyMODINIT_FUNC void +#endif +#else +#ifdef __cplusplus +#define __Pyx_PyMODINIT_FUNC extern "C" PyObject * +#else +#define __Pyx_PyMODINIT_FUNC PyObject * +#endif +#endif + + +#if PY_MAJOR_VERSION < 3 +__Pyx_PyMODINIT_FUNC init_websocket(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC init_websocket(void) +#else +__Pyx_PyMODINIT_FUNC PyInit__websocket(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit__websocket(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + #if PY_VERSION_HEX >= 0x030700A1 + static PY_INT64_T main_interpreter_id = -1; + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return (unlikely(current_id == -1)) ? -1 : 0; + } else if (unlikely(main_interpreter_id != current_id)) + #else + static PyInterpreterState *main_interpreter = NULL; + PyInterpreterState *current_interpreter = PyThreadState_Get()->interp; + if (!main_interpreter) { + main_interpreter = current_interpreter; + } else if (unlikely(main_interpreter != current_interpreter)) + #endif + { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) { + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, CYTHON_UNUSED PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + if (__Pyx_check_single_interpreter()) + return NULL; + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec__websocket(PyObject *__pyx_pyinit_module) +#endif +#endif +{ + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module '_websocket' has already been imported. Re-initialisation is not supported."); + return -1; + } + #elif PY_MAJOR_VERSION >= 3 + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + #if CYTHON_REFNANNY +__Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); +if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); +} +#endif + __Pyx_RefNannySetupContext("__Pyx_PyMODINIT_FUNC PyInit__websocket(void)", 0); + if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pxy_PyFrame_Initialize_Offsets + __Pxy_PyFrame_Initialize_Offsets(); + #endif + __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + #ifdef __Pyx_CyFunction_USED + if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_FusedFunction_USED + if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Coroutine_USED + if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_Generator_USED + if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_AsyncGen_USED + if (__pyx_AsyncGen_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #ifdef __Pyx_StopAsyncIteration_USED + if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + /*--- Library function declarations ---*/ + /*--- Threads initialization code ---*/ + #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS + #ifdef WITH_THREAD /* Python build with threading support? */ + PyEval_InitThreads(); + #endif + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_m = __pyx_pyinit_module; + Py_INCREF(__pyx_m); + #else + #if PY_MAJOR_VERSION < 3 + __pyx_m = Py_InitModule4("_websocket", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); + #else + __pyx_m = PyModule_Create(&__pyx_moduledef); + #endif + if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_d); + __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_b); + __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_cython_runtime); + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) + if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + if (__pyx_module_is_main_aiohttp___websocket) { + if (PyObject_SetAttr(__pyx_m, __pyx_n_s_name, __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + } + #if PY_MAJOR_VERSION >= 3 + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "aiohttp._websocket")) { + if (unlikely(PyDict_SetItemString(modules, "aiohttp._websocket", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #endif + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(); + (void)__Pyx_modinit_variable_export_code(); + (void)__Pyx_modinit_function_export_code(); + (void)__Pyx_modinit_type_init_code(); + if (unlikely(__Pyx_modinit_type_import_code() < 0)) __PYX_ERR(0, 1, __pyx_L1_error) + (void)__Pyx_modinit_variable_import_code(); + (void)__Pyx_modinit_function_import_code(); + /*--- Execution code ---*/ + #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) + if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + + /* "aiohttp/_websocket.pyx":11 + * + * + * def _websocket_mask_cython(object mask, object data): # <<<<<<<<<<<<<< + * """Note, this function mutates its `data` argument + * """ + */ + __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7aiohttp_10_websocket_1_websocket_mask_cython, NULL, __pyx_n_s_aiohttp__websocket); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 11, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_websocket_mask_cython, __pyx_t_1) < 0) __PYX_ERR(0, 11, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /* "aiohttp/_websocket.pyx":1 + * from cpython cimport PyBytes_AsString # <<<<<<<<<<<<<< + * + * + */ + __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + if (__pyx_m) { + if (__pyx_d) { + __Pyx_AddTraceback("init aiohttp._websocket", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + Py_CLEAR(__pyx_m); + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init aiohttp._websocket"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #elif PY_MAJOR_VERSION >= 3 + return __pyx_m; + #else + return; + #endif +} + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* PyObjectGetAttrStr */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); +#if PY_MAJOR_VERSION < 3 + if (likely(tp->tp_getattr)) + return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); +#endif + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* GetBuiltinName */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); + if (unlikely(!result)) { + PyErr_Format(PyExc_NameError, +#if PY_MAJOR_VERSION >= 3 + "name '%U' is not defined", name); +#else + "name '%.200s' is not defined", PyString_AS_STRING(name)); +#endif + } + return result; +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* RaiseDoubleKeywords */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION >= 3 + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); + #else + "%s() got multiple values for keyword argument '%s'", func_name, + PyString_AsString(kw_name)); + #endif +} + +/* ParseKeywords */ +static int __Pyx_ParseOptionalKeywords( + PyObject *kwds, + PyObject **argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject *key = 0, *value = 0; + Py_ssize_t pos = 0; + PyObject*** name; + PyObject*** first_kw_arg = argnames + num_pos_args; + while (PyDict_Next(kwds, &pos, &key, &value)) { + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; + continue; + } + name = first_kw_arg; + #if PY_MAJOR_VERSION < 3 + if (likely(PyString_Check(key))) { + while (*name) { + if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) + && _PyString_Eq(**name, key)) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + if ((**argname == key) || ( + (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) + && _PyString_Eq(**argname, key))) { + goto arg_passed_twice; + } + argname++; + } + } + } else + #endif + if (likely(PyUnicode_Check(key))) { + while (*name) { + int cmp = (**name == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**name) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**name, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + values[name-argnames] = value; + break; + } + name++; + } + if (*name) continue; + else { + PyObject*** argname = argnames; + while (argname != first_kw_arg) { + int cmp = (**argname == key) ? 0 : + #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 + (__Pyx_PyUnicode_GET_LENGTH(**argname) != __Pyx_PyUnicode_GET_LENGTH(key)) ? 1 : + #endif + PyUnicode_Compare(**argname, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + argname++; + } + } + } else + goto invalid_keyword_type; + if (kwds2) { + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else { + goto invalid_keyword; + } + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + #if PY_MAJOR_VERSION < 3 + "%.200s() got an unexpected keyword argument '%.200s'", + function_name, PyString_AsString(key)); + #else + "%s() got an unexpected keyword argument '%U'", + function_name, key); + #endif +bad: + return -1; +} + +/* PyCFunctionFastCall */ +#if CYTHON_FAST_PYCCALL +static CYTHON_INLINE PyObject * __Pyx_PyCFunction_FastCall(PyObject *func_obj, PyObject **args, Py_ssize_t nargs) { + PyCFunctionObject *func = (PyCFunctionObject*)func_obj; + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + int flags = PyCFunction_GET_FLAGS(func); + assert(PyCFunction_Check(func)); + assert(METH_FASTCALL == (flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_KEYWORDS | METH_STACKLESS))); + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + /* _PyCFunction_FastCallDict() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + if ((PY_VERSION_HEX < 0x030700A0) || unlikely(flags & METH_KEYWORDS)) { + return (*((__Pyx_PyCFunctionFastWithKeywords)(void*)meth)) (self, args, nargs, NULL); + } else { + return (*((__Pyx_PyCFunctionFast)(void*)meth)) (self, args, nargs); + } +} +#endif + +/* PyFunctionFastCall */ +#if CYTHON_FAST_PYCALL +static PyObject* __Pyx_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na, + PyObject *globals) { + PyFrameObject *f; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject **fastlocals; + Py_ssize_t i; + PyObject *result; + assert(globals != NULL); + /* XXX Perhaps we should create a specialized + PyFrame_New() that doesn't take locals, but does + take builtins without sanity checking them. + */ + assert(tstate != NULL); + f = PyFrame_New(tstate, co, globals, NULL); + if (f == NULL) { + return NULL; + } + fastlocals = __Pyx_PyFrame_GetLocalsplus(f); + for (i = 0; i < na; i++) { + Py_INCREF(*args); + fastlocals[i] = *args++; + } + result = PyEval_EvalFrameEx(f,0); + ++tstate->recursion_depth; + Py_DECREF(f); + --tstate->recursion_depth; + return result; +} +#if 1 || PY_VERSION_HEX < 0x030600B1 +static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { + PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject *closure; +#if PY_MAJOR_VERSION >= 3 + PyObject *kwdefs; +#endif + PyObject *kwtuple, **k; + PyObject **d; + Py_ssize_t nd; + Py_ssize_t nk; + PyObject *result; + assert(kwargs == NULL || PyDict_Check(kwargs)); + nk = kwargs ? PyDict_Size(kwargs) : 0; + if (Py_EnterRecursiveCall((char*)" while calling a Python object")) { + return NULL; + } + if ( +#if PY_MAJOR_VERSION >= 3 + co->co_kwonlyargcount == 0 && +#endif + likely(kwargs == NULL || nk == 0) && + co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) { + if (argdefs == NULL && co->co_argcount == nargs) { + result = __Pyx_PyFunction_FastCallNoKw(co, args, nargs, globals); + goto done; + } + else if (nargs == 0 && argdefs != NULL + && co->co_argcount == Py_SIZE(argdefs)) { + /* function called with no arguments, but all parameters have + a default value: use default values as arguments .*/ + args = &PyTuple_GET_ITEM(argdefs, 0); + result =__Pyx_PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs), globals); + goto done; + } + } + if (kwargs != NULL) { + Py_ssize_t pos, i; + kwtuple = PyTuple_New(2 * nk); + if (kwtuple == NULL) { + result = NULL; + goto done; + } + k = &PyTuple_GET_ITEM(kwtuple, 0); + pos = i = 0; + while (PyDict_Next(kwargs, &pos, &k[i], &k[i+1])) { + Py_INCREF(k[i]); + Py_INCREF(k[i+1]); + i += 2; + } + nk = i / 2; + } + else { + kwtuple = NULL; + k = NULL; + } + closure = PyFunction_GET_CLOSURE(func); +#if PY_MAJOR_VERSION >= 3 + kwdefs = PyFunction_GET_KW_DEFAULTS(func); +#endif + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = Py_SIZE(argdefs); + } + else { + d = NULL; + nd = 0; + } +#if PY_MAJOR_VERSION >= 3 + result = PyEval_EvalCodeEx((PyObject*)co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, kwdefs, closure); +#else + result = PyEval_EvalCodeEx(co, globals, (PyObject *)NULL, + args, (int)nargs, + k, (int)nk, + d, (int)nd, closure); +#endif + Py_XDECREF(kwtuple); +done: + Py_LeaveRecursiveCall(); + return result; +} +#endif +#endif + +/* PyObjectCall */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *result; + ternaryfunc call = func->ob_type->tp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = PyCFunction_GET_FUNCTION(func); + self = PyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallOneArg */ +#if CYTHON_COMPILING_IN_CPYTHON +static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { +#if CYTHON_FAST_PYCALL + if (PyFunction_Check(func)) { + return __Pyx_PyFunction_FastCall(func, &arg, 1); + } +#endif + if (likely(PyCFunction_Check(func))) { + if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { + return __Pyx_PyObject_CallMethO(func, arg); +#if CYTHON_FAST_PYCCALL + } else if (PyCFunction_GET_FLAGS(func) & METH_FASTCALL) { + return __Pyx_PyCFunction_FastCall(func, &arg, 1); +#endif + } + } + return __Pyx__PyObject_CallOneArg(func, arg); +} +#else +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *result; + PyObject *args = PyTuple_Pack(1, arg); + if (unlikely(!args)) return NULL; + result = __Pyx_PyObject_Call(func, args, NULL); + Py_DECREF(args); + return result; +} +#endif + +/* TypeImport */ +#ifndef __PYX_HAVE_RT_ImportType +#define __PYX_HAVE_RT_ImportType +static PyTypeObject *__Pyx_ImportType(PyObject *module, const char *module_name, const char *class_name, + size_t size, enum __Pyx_ImportType_CheckSize check_size) +{ + PyObject *result = 0; + char warning[200]; + Py_ssize_t basicsize; +#ifdef Py_LIMITED_API + PyObject *py_basicsize; +#endif + result = PyObject_GetAttrString(module, class_name); + if (!result) + goto bad; + if (!PyType_Check(result)) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s is not a type object", + module_name, class_name); + goto bad; + } +#ifndef Py_LIMITED_API + basicsize = ((PyTypeObject *)result)->tp_basicsize; +#else + py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); + if (!py_basicsize) + goto bad; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = 0; + if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) + goto bad; +#endif + if ((size_t)basicsize < size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + if (check_size == __Pyx_ImportType_CheckSize_Error && (size_t)basicsize != size) { + PyErr_Format(PyExc_ValueError, + "%.200s.%.200s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + goto bad; + } + else if (check_size == __Pyx_ImportType_CheckSize_Warn && (size_t)basicsize > size) { + PyOS_snprintf(warning, sizeof(warning), + "%s.%s size changed, may indicate binary incompatibility. " + "Expected %zd from C header, got %zd from PyObject", + module_name, class_name, size, basicsize); + if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; + } + return (PyTypeObject *)result; +bad: + Py_XDECREF(result); + return NULL; +} +#endif + +/* PyDictVersioning */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* PyErrFetchRestore */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +} +#endif + +/* CLineInTraceback */ +#ifndef CYTHON_CLINE_IN_TRACEBACK +static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) { + PyObject *use_cline; + PyObject *ptype, *pvalue, *ptraceback; +#if CYTHON_COMPILING_IN_CPYTHON + PyObject **cython_runtime_dict; +#endif + if (unlikely(!__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); +#if CYTHON_COMPILING_IN_CPYTHON + cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, *cython_runtime_dict, + __Pyx_PyDict_GetItemStr(*cython_runtime_dict, __pyx_n_s_cline_in_traceback)) + } else +#endif + { + PyObject *use_cline_obj = __Pyx_PyObject_GetAttrStr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback); + if (use_cline_obj) { + use_cline = PyObject_Not(use_cline_obj) ? Py_False : Py_True; + Py_DECREF(use_cline_obj); + } else { + PyErr_Clear(); + use_cline = NULL; + } + } + if (!use_cline) { + c_line = 0; + PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False); + } + else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static PyCodeObject *__pyx_find_code_object(int code_line) { + PyCodeObject* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { + return NULL; + } + code_object = __pyx_code_cache.entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = 64; + __pyx_code_cache.count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); + if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { + PyCodeObject* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_DECREF(tmp); + return; + } + if (__pyx_code_cache.count == __pyx_code_cache.max_count) { + int new_max = __pyx_code_cache.max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + __pyx_code_cache.entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + __pyx_code_cache.entries = entries; + __pyx_code_cache.max_count = new_max; + } + for (i=__pyx_code_cache.count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + __pyx_code_cache.count++; + Py_INCREF(code_object); +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + #if PY_MAJOR_VERSION < 3 + py_srcfile = PyString_FromString(filename); + #else + py_srcfile = PyUnicode_FromString(filename); + #endif + if (!py_srcfile) goto bad; + if (c_line) { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #else + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + #endif + } + else { + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + #else + py_funcname = PyUnicode_FromString(funcname); + #endif + } + if (!py_funcname) goto bad; + py_code = __Pyx_PyCode_New( + 0, + 0, + 0, + 0, + 0, + __pyx_empty_bytes, /*PyObject *code,*/ + __pyx_empty_tuple, /*PyObject *consts,*/ + __pyx_empty_tuple, /*PyObject *names,*/ + __pyx_empty_tuple, /*PyObject *varnames,*/ + __pyx_empty_tuple, /*PyObject *freevars,*/ + __pyx_empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + py_line, + __pyx_empty_bytes /*PyObject *lnotab*/ + ); + Py_DECREF(py_srcfile); + Py_DECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyInt_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyInt_FromLong((long) value); +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); +#endif + } + } + { + int one = 1; int little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&value; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); + } +} + +/* CIntFromPyVerify */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { + const long neg_one = (long) ((long) 0 - (long) 1), const_zero = (long) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(long) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (long) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(long) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (long) 0; + case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) + case -2: + if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(long) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(long) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(long) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } +#endif + if (sizeof(long) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + long val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (long) -1; + } + } else { + long val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (long) -1; + val = __Pyx_PyInt_As_long(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { + const int neg_one = (int) ((int) 0 - (int) 1), const_zero = (int) 0; + const int is_unsigned = neg_one > const_zero; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x))) { + if (sizeof(int) < sizeof(long)) { + __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) + } else { + long val = PyInt_AS_LONG(x); + if (is_unsigned && unlikely(val < 0)) { + goto raise_neg_overflow; + } + return (int) val; + } + } else +#endif + if (likely(PyLong_Check(x))) { + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if (sizeof(int) <= sizeof(unsigned long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) +#endif + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)x)->ob_digit; + switch (Py_SIZE(x)) { + case 0: return (int) 0; + case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) + case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) + case -2: + if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if (8 * sizeof(int) > 1 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if (8 * sizeof(int) > 2 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if (8 * sizeof(int) > 3 * PyLong_SHIFT) { + if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } +#endif + if (sizeof(int) <= sizeof(long)) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) +#ifdef HAVE_LONG_LONG + } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) +#endif + } + } + { +#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) + PyErr_SetString(PyExc_RuntimeError, + "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); +#else + int val; + PyObject *v = __Pyx_PyNumber_IntOrLong(x); + #if PY_MAJOR_VERSION < 3 + if (likely(v) && !PyLong_Check(v)) { + PyObject *tmp = v; + v = PyNumber_Long(tmp); + Py_DECREF(tmp); + } + #endif + if (likely(v)) { + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + int ret = _PyLong_AsByteArray((PyLongObject *)v, + bytes, sizeof(val), + is_little, !is_unsigned); + Py_DECREF(v); + if (likely(!ret)) + return val; + } +#endif + return (int) -1; + } + } else { + int val; + PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); + if (!tmp) return (int) -1; + val = __Pyx_PyInt_As_int(tmp); + Py_DECREF(tmp); + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = a->tp_base; + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +#if PY_MAJOR_VERSION == 2 +static int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject* exc_type2) { + PyObject *exception, *value, *tb; + int res; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ErrFetch(&exception, &value, &tb); + res = exc_type1 ? PyObject_IsSubclass(err, exc_type1) : 0; + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + if (!res) { + res = PyObject_IsSubclass(err, exc_type2); + if (unlikely(res == -1)) { + PyErr_WriteUnraisable(err); + res = 0; + } + } + __Pyx_ErrRestore(exception, value, tb); + return res; +} +#else +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + int res = exc_type1 ? __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type1) : 0; + if (!res) { + res = __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } + return res; +} +#endif +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); +#if PY_MAJOR_VERSION >= 3 + for (i=0; ip) { + #if PY_MAJOR_VERSION < 3 + if (t->is_unicode) { + *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); + } else if (t->intern) { + *t->p = PyString_InternFromString(t->s); + } else { + *t->p = PyString_FromStringAndSize(t->s, t->n - 1); + } + #else + if (t->is_unicode | t->is_str) { + if (t->intern) { + *t->p = PyUnicode_InternFromString(t->s); + } else if (t->encoding) { + *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); + } else { + *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); + } + } else { + *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); + } + #endif + if (!*t->p) + return -1; + if (PyObject_Hash(*t->p) == -1) + return -1; + ++t; + } + return 0; +} + +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT +#if !CYTHON_PEP393_ENABLED +static const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + char* defenc_c; + PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); + if (!defenc) return NULL; + defenc_c = PyBytes_AS_STRING(defenc); +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + { + char* end = defenc_c + PyBytes_GET_SIZE(defenc); + char* c; + for (c = defenc_c; c < end; c++) { + if ((unsigned char) (*c) >= 128) { + PyUnicode_AsASCIIString(o); + return NULL; + } + } + } +#endif + *length = PyBytes_GET_SIZE(defenc); + return defenc_c; +} +#else +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +} +#endif +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT + if ( +#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + __Pyx_sys_getdefaultencoding_not_ascii && +#endif + PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif +#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) + if (PyByteArray_Check(o)) { + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); + } else +#endif + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_IntOrLongWrongResultType(PyObject* result, const char* type_name) { +#if PY_MAJOR_VERSION >= 3 + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + Py_TYPE(result)->tp_name)) { + Py_DECREF(result); + return NULL; + } + return result; + } +#endif + PyErr_Format(PyExc_TypeError, + "__%.4s__ returned non-%.4s (type %.200s)", + type_name, type_name, Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + const char *name = NULL; + PyObject *res = NULL; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_Check(x) || PyLong_Check(x))) +#else + if (likely(PyLong_Check(x))) +#endif + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + #if PY_MAJOR_VERSION < 3 + if (m && m->nb_int) { + name = "int"; + res = m->nb_int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = m->nb_long(x); + } + #else + if (likely(m && m->nb_int)) { + name = "int"; + res = m->nb_int(x); + } + #endif +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Int(x); + } +#endif + if (likely(res)) { +#if PY_MAJOR_VERSION < 3 + if (unlikely(!PyInt_Check(res) && !PyLong_Check(res))) { +#else + if (unlikely(!PyLong_CheckExact(res))) { +#endif + return __Pyx_PyNumber_IntOrLongWrongResultType(res, name); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; +#if PY_MAJOR_VERSION < 3 + if (likely(PyInt_CheckExact(b))) { + if (sizeof(Py_ssize_t) >= sizeof(long)) + return PyInt_AS_LONG(b); + else + return PyInt_AsSsize_t(b); + } +#endif + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + const digit* digits = ((PyLongObject*)b)->ob_digit; + const Py_ssize_t size = Py_SIZE(b); + if (likely(__Pyx_sst_abs(size) <= 1)) { + ival = likely(size) ? digits[0] : 0; + if (size == -1) ival = -ival; + return ival; + } else { + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyInt_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { + return PyInt_FromSize_t(ival); +} + + +#endif /* Py_PYTHON_H */ diff --git a/dist/ba_data/python-site-packages/aiohttp/_websocket.cp39-win_amd64.pyd b/dist/ba_data/python-site-packages/aiohttp/_websocket.cp39-win_amd64.pyd new file mode 100644 index 0000000..d750da7 Binary files /dev/null and b/dist/ba_data/python-site-packages/aiohttp/_websocket.cp39-win_amd64.pyd differ diff --git a/dist/ba_data/python-site-packages/aiohttp/_websocket.pyx b/dist/ba_data/python-site-packages/aiohttp/_websocket.pyx new file mode 100644 index 0000000..94318d2 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/_websocket.pyx @@ -0,0 +1,56 @@ +from cpython cimport PyBytes_AsString + + +#from cpython cimport PyByteArray_AsString # cython still not exports that +cdef extern from "Python.h": + char* PyByteArray_AsString(bytearray ba) except NULL + +from libc.stdint cimport uint32_t, uint64_t, uintmax_t + + +def _websocket_mask_cython(object mask, object data): + """Note, this function mutates its `data` argument + """ + cdef: + Py_ssize_t data_len, i + # bit operations on signed integers are implementation-specific + unsigned char * in_buf + const unsigned char * mask_buf + uint32_t uint32_msk + uint64_t uint64_msk + + assert len(mask) == 4 + + if not isinstance(mask, bytes): + mask = bytes(mask) + + if isinstance(data, bytearray): + data = data + else: + data = bytearray(data) + + data_len = len(data) + in_buf = PyByteArray_AsString(data) + mask_buf = PyBytes_AsString(mask) + uint32_msk = (mask_buf)[0] + + # TODO: align in_data ptr to achieve even faster speeds + # does it need in python ?! malloc() always aligns to sizeof(long) bytes + + if sizeof(size_t) >= 8: + uint64_msk = uint32_msk + uint64_msk = (uint64_msk << 32) | uint32_msk + + while data_len >= 8: + (in_buf)[0] ^= uint64_msk + in_buf += 8 + data_len -= 8 + + + while data_len >= 4: + (in_buf)[0] ^= uint32_msk + in_buf += 4 + data_len -= 4 + + for i in range(0, data_len): + in_buf[i] ^= mask_buf[i] diff --git a/dist/ba_data/python-site-packages/aiohttp/abc.py b/dist/ba_data/python-site-packages/aiohttp/abc.py new file mode 100644 index 0000000..4abfd79 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/abc.py @@ -0,0 +1,200 @@ +import asyncio +import logging +from abc import ABC, abstractmethod +from collections.abc import Sized +from http.cookies import BaseCookie, Morsel +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Dict, + Generator, + Iterable, + List, + Optional, + Tuple, +) + +from multidict import CIMultiDict +from yarl import URL + +from .helpers import get_running_loop +from .typedefs import LooseCookies + +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application + from .web_exceptions import HTTPException + from .web_request import BaseRequest, Request + from .web_response import StreamResponse +else: + BaseRequest = Request = Application = StreamResponse = None + HTTPException = None + + +class AbstractRouter(ABC): + def __init__(self) -> None: + self._frozen = False + + def post_init(self, app: Application) -> None: + """Post init stage. + + Not an abstract method for sake of backward compatibility, + but if the router wants to be aware of the application + it can override this. + """ + + @property + def frozen(self) -> bool: + return self._frozen + + def freeze(self) -> None: + """Freeze router.""" + self._frozen = True + + @abstractmethod + async def resolve(self, request: Request) -> "AbstractMatchInfo": + """Return MATCH_INFO for given request""" + + +class AbstractMatchInfo(ABC): + @property # pragma: no branch + @abstractmethod + def handler(self) -> Callable[[Request], Awaitable[StreamResponse]]: + """Execute matched request handler""" + + @property + @abstractmethod + def expect_handler(self) -> Callable[[Request], Awaitable[None]]: + """Expect handler for 100-continue processing""" + + @property # pragma: no branch + @abstractmethod + def http_exception(self) -> Optional[HTTPException]: + """HTTPException instance raised on router's resolving, or None""" + + @abstractmethod # pragma: no branch + def get_info(self) -> Dict[str, Any]: + """Return a dict with additional info useful for introspection""" + + @property # pragma: no branch + @abstractmethod + def apps(self) -> Tuple[Application, ...]: + """Stack of nested applications. + + Top level application is left-most element. + + """ + + @abstractmethod + def add_app(self, app: Application) -> None: + """Add application to the nested apps stack.""" + + @abstractmethod + def freeze(self) -> None: + """Freeze the match info. + + The method is called after route resolution. + + After the call .add_app() is forbidden. + + """ + + +class AbstractView(ABC): + """Abstract class based view.""" + + def __init__(self, request: Request) -> None: + self._request = request + + @property + def request(self) -> Request: + """Request instance.""" + return self._request + + @abstractmethod + def __await__(self) -> Generator[Any, None, StreamResponse]: + """Execute the view handler.""" + + +class AbstractResolver(ABC): + """Abstract DNS resolver.""" + + @abstractmethod + async def resolve(self, host: str, port: int, family: int) -> List[Dict[str, Any]]: + """Return IP address for given hostname""" + + @abstractmethod + async def close(self) -> None: + """Release resolver""" + + +if TYPE_CHECKING: # pragma: no cover + IterableBase = Iterable[Morsel[str]] +else: + IterableBase = Iterable + + +class AbstractCookieJar(Sized, IterableBase): + """Abstract Cookie Jar.""" + + def __init__(self, *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: + self._loop = get_running_loop(loop) + + @abstractmethod + def clear(self) -> None: + """Clear all cookies.""" + + @abstractmethod + def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None: + """Update cookies.""" + + @abstractmethod + def filter_cookies(self, request_url: URL) -> "BaseCookie[str]": + """Return the jar's cookies filtered by their attributes.""" + + +class AbstractStreamWriter(ABC): + """Abstract stream writer.""" + + buffer_size = 0 + output_size = 0 + length = 0 # type: Optional[int] + + @abstractmethod + async def write(self, chunk: bytes) -> None: + """Write chunk into stream.""" + + @abstractmethod + async def write_eof(self, chunk: bytes = b"") -> None: + """Write last chunk.""" + + @abstractmethod + async def drain(self) -> None: + """Flush the write buffer.""" + + @abstractmethod + def enable_compression(self, encoding: str = "deflate") -> None: + """Enable HTTP body compression""" + + @abstractmethod + def enable_chunking(self) -> None: + """Enable HTTP chunked mode""" + + @abstractmethod + async def write_headers( + self, status_line: str, headers: "CIMultiDict[str]" + ) -> None: + """Write HTTP headers""" + + +class AbstractAccessLogger(ABC): + """Abstract writer to access log.""" + + def __init__(self, logger: logging.Logger, log_format: str) -> None: + self.logger = logger + self.log_format = log_format + + @abstractmethod + def log(self, request: BaseRequest, response: StreamResponse, time: float) -> None: + """Emit log to logger.""" diff --git a/dist/ba_data/python-site-packages/aiohttp/base_protocol.py b/dist/ba_data/python-site-packages/aiohttp/base_protocol.py new file mode 100644 index 0000000..01e1831 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/base_protocol.py @@ -0,0 +1,87 @@ +import asyncio +from typing import Optional, cast + +from .tcp_helpers import tcp_nodelay + + +class BaseProtocol(asyncio.Protocol): + __slots__ = ( + "_loop", + "_paused", + "_drain_waiter", + "_connection_lost", + "_reading_paused", + "transport", + ) + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + self._loop = loop # type: asyncio.AbstractEventLoop + self._paused = False + self._drain_waiter = None # type: Optional[asyncio.Future[None]] + self._connection_lost = False + self._reading_paused = False + + self.transport = None # type: Optional[asyncio.Transport] + + def pause_writing(self) -> None: + assert not self._paused + self._paused = True + + def resume_writing(self) -> None: + assert self._paused + self._paused = False + + waiter = self._drain_waiter + if waiter is not None: + self._drain_waiter = None + if not waiter.done(): + waiter.set_result(None) + + def pause_reading(self) -> None: + if not self._reading_paused and self.transport is not None: + try: + self.transport.pause_reading() + except (AttributeError, NotImplementedError, RuntimeError): + pass + self._reading_paused = True + + def resume_reading(self) -> None: + if self._reading_paused and self.transport is not None: + try: + self.transport.resume_reading() + except (AttributeError, NotImplementedError, RuntimeError): + pass + self._reading_paused = False + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + tr = cast(asyncio.Transport, transport) + tcp_nodelay(tr, True) + self.transport = tr + + def connection_lost(self, exc: Optional[BaseException]) -> None: + self._connection_lost = True + # Wake up the writer if currently paused. + self.transport = None + if not self._paused: + return + waiter = self._drain_waiter + if waiter is None: + return + self._drain_waiter = None + if waiter.done(): + return + if exc is None: + waiter.set_result(None) + else: + waiter.set_exception(exc) + + async def _drain_helper(self) -> None: + if self._connection_lost: + raise ConnectionResetError("Connection lost") + if not self._paused: + return + waiter = self._drain_waiter + assert waiter is None or waiter.cancelled() + waiter = self._loop.create_future() + self._drain_waiter = waiter + await waiter diff --git a/dist/ba_data/python-site-packages/aiohttp/client.py b/dist/ba_data/python-site-packages/aiohttp/client.py new file mode 100644 index 0000000..a9da8e1 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/client.py @@ -0,0 +1,1275 @@ +"""HTTP Client for asyncio.""" + +import asyncio +import base64 +import hashlib +import json +import os +import sys +import traceback +import warnings +from types import SimpleNamespace, TracebackType +from typing import ( + Any, + Awaitable, + Callable, + Coroutine, + FrozenSet, + Generator, + Generic, + Iterable, + List, + Mapping, + Optional, + Set, + Tuple, + Type, + TypeVar, + Union, +) + +import attr +from multidict import CIMultiDict, MultiDict, MultiDictProxy, istr +from yarl import URL + +from . import hdrs, http, payload +from .abc import AbstractCookieJar +from .client_exceptions import ( + ClientConnectionError as ClientConnectionError, + ClientConnectorCertificateError as ClientConnectorCertificateError, + ClientConnectorError as ClientConnectorError, + ClientConnectorSSLError as ClientConnectorSSLError, + ClientError as ClientError, + ClientHttpProxyError as ClientHttpProxyError, + ClientOSError as ClientOSError, + ClientPayloadError as ClientPayloadError, + ClientProxyConnectionError as ClientProxyConnectionError, + ClientResponseError as ClientResponseError, + ClientSSLError as ClientSSLError, + ContentTypeError as ContentTypeError, + InvalidURL as InvalidURL, + ServerConnectionError as ServerConnectionError, + ServerDisconnectedError as ServerDisconnectedError, + ServerFingerprintMismatch as ServerFingerprintMismatch, + ServerTimeoutError as ServerTimeoutError, + TooManyRedirects as TooManyRedirects, + WSServerHandshakeError as WSServerHandshakeError, +) +from .client_reqrep import ( + ClientRequest as ClientRequest, + ClientResponse as ClientResponse, + Fingerprint as Fingerprint, + RequestInfo as RequestInfo, + _merge_ssl_params, +) +from .client_ws import ClientWebSocketResponse as ClientWebSocketResponse +from .connector import ( + BaseConnector as BaseConnector, + NamedPipeConnector as NamedPipeConnector, + TCPConnector as TCPConnector, + UnixConnector as UnixConnector, +) +from .cookiejar import CookieJar +from .helpers import ( + DEBUG, + PY_36, + BasicAuth, + CeilTimeout, + TimeoutHandle, + get_running_loop, + proxies_from_env, + sentinel, + strip_auth_from_url, +) +from .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter +from .http_websocket import WSHandshakeError, WSMessage, ws_ext_gen, ws_ext_parse +from .streams import FlowControlDataQueue +from .tracing import Trace, TraceConfig +from .typedefs import JSONEncoder, LooseCookies, LooseHeaders, StrOrURL + +__all__ = ( + # client_exceptions + "ClientConnectionError", + "ClientConnectorCertificateError", + "ClientConnectorError", + "ClientConnectorSSLError", + "ClientError", + "ClientHttpProxyError", + "ClientOSError", + "ClientPayloadError", + "ClientProxyConnectionError", + "ClientResponseError", + "ClientSSLError", + "ContentTypeError", + "InvalidURL", + "ServerConnectionError", + "ServerDisconnectedError", + "ServerFingerprintMismatch", + "ServerTimeoutError", + "TooManyRedirects", + "WSServerHandshakeError", + # client_reqrep + "ClientRequest", + "ClientResponse", + "Fingerprint", + "RequestInfo", + # connector + "BaseConnector", + "TCPConnector", + "UnixConnector", + "NamedPipeConnector", + # client_ws + "ClientWebSocketResponse", + # client + "ClientSession", + "ClientTimeout", + "request", +) + + +try: + from ssl import SSLContext +except ImportError: # pragma: no cover + SSLContext = object # type: ignore + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class ClientTimeout: + total: Optional[float] = None + connect: Optional[float] = None + sock_read: Optional[float] = None + sock_connect: Optional[float] = None + + # pool_queue_timeout: Optional[float] = None + # dns_resolution_timeout: Optional[float] = None + # socket_connect_timeout: Optional[float] = None + # connection_acquiring_timeout: Optional[float] = None + # new_connection_timeout: Optional[float] = None + # http_header_timeout: Optional[float] = None + # response_body_timeout: Optional[float] = None + + # to create a timeout specific for a single request, either + # - create a completely new one to overwrite the default + # - or use http://www.attrs.org/en/stable/api.html#attr.evolve + # to overwrite the defaults + + +# 5 Minute default read timeout +DEFAULT_TIMEOUT = ClientTimeout(total=5 * 60) + +_RetType = TypeVar("_RetType") + + +class ClientSession: + """First-class interface for making HTTP requests.""" + + ATTRS = frozenset( + [ + "_source_traceback", + "_connector", + "requote_redirect_url", + "_loop", + "_cookie_jar", + "_connector_owner", + "_default_auth", + "_version", + "_json_serialize", + "_requote_redirect_url", + "_timeout", + "_raise_for_status", + "_auto_decompress", + "_trust_env", + "_default_headers", + "_skip_auto_headers", + "_request_class", + "_response_class", + "_ws_response_class", + "_trace_configs", + "_read_bufsize", + ] + ) + + _source_traceback = None + + def __init__( + self, + *, + connector: Optional[BaseConnector] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + cookies: Optional[LooseCookies] = None, + headers: Optional[LooseHeaders] = None, + skip_auto_headers: Optional[Iterable[str]] = None, + auth: Optional[BasicAuth] = None, + json_serialize: JSONEncoder = json.dumps, + request_class: Type[ClientRequest] = ClientRequest, + response_class: Type[ClientResponse] = ClientResponse, + ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse, + version: HttpVersion = http.HttpVersion11, + cookie_jar: Optional[AbstractCookieJar] = None, + connector_owner: bool = True, + raise_for_status: bool = False, + read_timeout: Union[float, object] = sentinel, + conn_timeout: Optional[float] = None, + timeout: Union[object, ClientTimeout] = sentinel, + auto_decompress: bool = True, + trust_env: bool = False, + requote_redirect_url: bool = True, + trace_configs: Optional[List[TraceConfig]] = None, + read_bufsize: int = 2 ** 16, + ) -> None: + + if loop is None: + if connector is not None: + loop = connector._loop + + loop = get_running_loop(loop) + + if connector is None: + connector = TCPConnector(loop=loop) + + if connector._loop is not loop: + raise RuntimeError("Session and connector has to use same event loop") + + self._loop = loop + + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + if cookie_jar is None: + cookie_jar = CookieJar(loop=loop) + self._cookie_jar = cookie_jar + + if cookies is not None: + self._cookie_jar.update_cookies(cookies) + + self._connector = connector # type: Optional[BaseConnector] + self._connector_owner = connector_owner + self._default_auth = auth + self._version = version + self._json_serialize = json_serialize + if timeout is sentinel: + self._timeout = DEFAULT_TIMEOUT + if read_timeout is not sentinel: + warnings.warn( + "read_timeout is deprecated, " "use timeout argument instead", + DeprecationWarning, + stacklevel=2, + ) + self._timeout = attr.evolve(self._timeout, total=read_timeout) + if conn_timeout is not None: + self._timeout = attr.evolve(self._timeout, connect=conn_timeout) + warnings.warn( + "conn_timeout is deprecated, " "use timeout argument instead", + DeprecationWarning, + stacklevel=2, + ) + else: + self._timeout = timeout # type: ignore + if read_timeout is not sentinel: + raise ValueError( + "read_timeout and timeout parameters " + "conflict, please setup " + "timeout.read" + ) + if conn_timeout is not None: + raise ValueError( + "conn_timeout and timeout parameters " + "conflict, please setup " + "timeout.connect" + ) + self._raise_for_status = raise_for_status + self._auto_decompress = auto_decompress + self._trust_env = trust_env + self._requote_redirect_url = requote_redirect_url + self._read_bufsize = read_bufsize + + # Convert to list of tuples + if headers: + real_headers = CIMultiDict(headers) # type: CIMultiDict[str] + else: + real_headers = CIMultiDict() + self._default_headers = real_headers # type: CIMultiDict[str] + if skip_auto_headers is not None: + self._skip_auto_headers = frozenset([istr(i) for i in skip_auto_headers]) + else: + self._skip_auto_headers = frozenset() + + self._request_class = request_class + self._response_class = response_class + self._ws_response_class = ws_response_class + + self._trace_configs = trace_configs or [] + for trace_config in self._trace_configs: + trace_config.freeze() + + def __init_subclass__(cls: Type["ClientSession"]) -> None: + warnings.warn( + "Inheritance class {} from ClientSession " + "is discouraged".format(cls.__name__), + DeprecationWarning, + stacklevel=2, + ) + + if DEBUG: + + def __setattr__(self, name: str, val: Any) -> None: + if name not in self.ATTRS: + warnings.warn( + "Setting custom ClientSession.{} attribute " + "is discouraged".format(name), + DeprecationWarning, + stacklevel=2, + ) + super().__setattr__(name, val) + + def __del__(self, _warnings: Any = warnings) -> None: + if not self.closed: + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + _warnings.warn( + f"Unclosed client session {self!r}", ResourceWarning, **kwargs + ) + context = {"client_session": self, "message": "Unclosed client session"} + if self._source_traceback is not None: + context["source_traceback"] = self._source_traceback + self._loop.call_exception_handler(context) + + def request( + self, method: str, url: StrOrURL, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP request.""" + return _RequestContextManager(self._request(method, url, **kwargs)) + + async def _request( + self, + method: str, + str_or_url: StrOrURL, + *, + params: Optional[Mapping[str, str]] = None, + data: Any = None, + json: Any = None, + cookies: Optional[LooseCookies] = None, + headers: Optional[LooseHeaders] = None, + skip_auto_headers: Optional[Iterable[str]] = None, + auth: Optional[BasicAuth] = None, + allow_redirects: bool = True, + max_redirects: int = 10, + compress: Optional[str] = None, + chunked: Optional[bool] = None, + expect100: bool = False, + raise_for_status: Optional[bool] = None, + read_until_eof: bool = True, + proxy: Optional[StrOrURL] = None, + proxy_auth: Optional[BasicAuth] = None, + timeout: Union[ClientTimeout, object] = sentinel, + verify_ssl: Optional[bool] = None, + fingerprint: Optional[bytes] = None, + ssl_context: Optional[SSLContext] = None, + ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None, + proxy_headers: Optional[LooseHeaders] = None, + trace_request_ctx: Optional[SimpleNamespace] = None, + read_bufsize: Optional[int] = None, + ) -> ClientResponse: + + # NOTE: timeout clamps existing connect and read timeouts. We cannot + # set the default to None because we need to detect if the user wants + # to use the existing timeouts by setting timeout to None. + + if self.closed: + raise RuntimeError("Session is closed") + + ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) + + if data is not None and json is not None: + raise ValueError( + "data and json parameters can not be used at the same time" + ) + elif json is not None: + data = payload.JsonPayload(json, dumps=self._json_serialize) + + if not isinstance(chunked, bool) and chunked is not None: + warnings.warn("Chunk size is deprecated #1615", DeprecationWarning) + + redirects = 0 + history = [] + version = self._version + + # Merge with default headers and transform to CIMultiDict + headers = self._prepare_headers(headers) + proxy_headers = self._prepare_headers(proxy_headers) + + try: + url = URL(str_or_url) + except ValueError as e: + raise InvalidURL(str_or_url) from e + + skip_headers = set(self._skip_auto_headers) + if skip_auto_headers is not None: + for i in skip_auto_headers: + skip_headers.add(istr(i)) + + if proxy is not None: + try: + proxy = URL(proxy) + except ValueError as e: + raise InvalidURL(proxy) from e + + if timeout is sentinel: + real_timeout = self._timeout # type: ClientTimeout + else: + if not isinstance(timeout, ClientTimeout): + real_timeout = ClientTimeout(total=timeout) # type: ignore + else: + real_timeout = timeout + # timeout is cumulative for all request operations + # (request, redirects, responses, data consuming) + tm = TimeoutHandle(self._loop, real_timeout.total) + handle = tm.start() + + if read_bufsize is None: + read_bufsize = self._read_bufsize + + traces = [ + Trace( + self, + trace_config, + trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx), + ) + for trace_config in self._trace_configs + ] + + for trace in traces: + await trace.send_request_start(method, url, headers) + + timer = tm.timer() + try: + with timer: + while True: + url, auth_from_url = strip_auth_from_url(url) + if auth and auth_from_url: + raise ValueError( + "Cannot combine AUTH argument with " + "credentials encoded in URL" + ) + + if auth is None: + auth = auth_from_url + if auth is None: + auth = self._default_auth + # It would be confusing if we support explicit + # Authorization header with auth argument + if ( + headers is not None + and auth is not None + and hdrs.AUTHORIZATION in headers + ): + raise ValueError( + "Cannot combine AUTHORIZATION header " + "with AUTH argument or credentials " + "encoded in URL" + ) + + all_cookies = self._cookie_jar.filter_cookies(url) + + if cookies is not None: + tmp_cookie_jar = CookieJar() + tmp_cookie_jar.update_cookies(cookies) + req_cookies = tmp_cookie_jar.filter_cookies(url) + if req_cookies: + all_cookies.load(req_cookies) + + if proxy is not None: + proxy = URL(proxy) + elif self._trust_env: + for scheme, proxy_info in proxies_from_env().items(): + if scheme == url.scheme: + proxy = proxy_info.proxy + proxy_auth = proxy_info.proxy_auth + break + + req = self._request_class( + method, + url, + params=params, + headers=headers, + skip_auto_headers=skip_headers, + data=data, + cookies=all_cookies, + auth=auth, + version=version, + compress=compress, + chunked=chunked, + expect100=expect100, + loop=self._loop, + response_class=self._response_class, + proxy=proxy, + proxy_auth=proxy_auth, + timer=timer, + session=self, + ssl=ssl, + proxy_headers=proxy_headers, + traces=traces, + ) + + # connection timeout + try: + with CeilTimeout(real_timeout.connect, loop=self._loop): + assert self._connector is not None + conn = await self._connector.connect( + req, traces=traces, timeout=real_timeout + ) + except asyncio.TimeoutError as exc: + raise ServerTimeoutError( + "Connection timeout " "to host {}".format(url) + ) from exc + + assert conn.transport is not None + + assert conn.protocol is not None + conn.protocol.set_response_params( + timer=timer, + skip_payload=method.upper() == "HEAD", + read_until_eof=read_until_eof, + auto_decompress=self._auto_decompress, + read_timeout=real_timeout.sock_read, + read_bufsize=read_bufsize, + ) + + try: + try: + resp = await req.send(conn) + try: + await resp.start(conn) + except BaseException: + resp.close() + raise + except BaseException: + conn.close() + raise + except ClientError: + raise + except OSError as exc: + raise ClientOSError(*exc.args) from exc + + self._cookie_jar.update_cookies(resp.cookies, resp.url) + + # redirects + if resp.status in (301, 302, 303, 307, 308) and allow_redirects: + + for trace in traces: + await trace.send_request_redirect( + method, url, headers, resp + ) + + redirects += 1 + history.append(resp) + if max_redirects and redirects >= max_redirects: + resp.close() + raise TooManyRedirects( + history[0].request_info, tuple(history) + ) + + # For 301 and 302, mimic IE, now changed in RFC + # https://github.com/kennethreitz/requests/pull/269 + if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or ( + resp.status in (301, 302) and resp.method == hdrs.METH_POST + ): + method = hdrs.METH_GET + data = None + if headers.get(hdrs.CONTENT_LENGTH): + headers.pop(hdrs.CONTENT_LENGTH) + + r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get( + hdrs.URI + ) + if r_url is None: + # see github.com/aio-libs/aiohttp/issues/2022 + break + else: + # reading from correct redirection + # response is forbidden + resp.release() + + try: + parsed_url = URL( + r_url, encoded=not self._requote_redirect_url + ) + + except ValueError as e: + raise InvalidURL(r_url) from e + + scheme = parsed_url.scheme + if scheme not in ("http", "https", ""): + resp.close() + raise ValueError("Can redirect only to http or https") + elif not scheme: + parsed_url = url.join(parsed_url) + + if url.origin() != parsed_url.origin(): + auth = None + headers.pop(hdrs.AUTHORIZATION, None) + + url = parsed_url + params = None + resp.release() + continue + + break + + # check response status + if raise_for_status is None: + raise_for_status = self._raise_for_status + if raise_for_status: + resp.raise_for_status() + + # register connection + if handle is not None: + if resp.connection is not None: + resp.connection.add_callback(handle.cancel) + else: + handle.cancel() + + resp._history = tuple(history) + + for trace in traces: + await trace.send_request_end(method, url, headers, resp) + return resp + + except BaseException as e: + # cleanup timer + tm.close() + if handle: + handle.cancel() + handle = None + + for trace in traces: + await trace.send_request_exception(method, url, headers, e) + raise + + def ws_connect( + self, + url: StrOrURL, + *, + method: str = hdrs.METH_GET, + protocols: Iterable[str] = (), + timeout: float = 10.0, + receive_timeout: Optional[float] = None, + autoclose: bool = True, + autoping: bool = True, + heartbeat: Optional[float] = None, + auth: Optional[BasicAuth] = None, + origin: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + proxy: Optional[StrOrURL] = None, + proxy_auth: Optional[BasicAuth] = None, + ssl: Union[SSLContext, bool, None, Fingerprint] = None, + verify_ssl: Optional[bool] = None, + fingerprint: Optional[bytes] = None, + ssl_context: Optional[SSLContext] = None, + proxy_headers: Optional[LooseHeaders] = None, + compress: int = 0, + max_msg_size: int = 4 * 1024 * 1024, + ) -> "_WSRequestContextManager": + """Initiate websocket connection.""" + return _WSRequestContextManager( + self._ws_connect( + url, + method=method, + protocols=protocols, + timeout=timeout, + receive_timeout=receive_timeout, + autoclose=autoclose, + autoping=autoping, + heartbeat=heartbeat, + auth=auth, + origin=origin, + headers=headers, + proxy=proxy, + proxy_auth=proxy_auth, + ssl=ssl, + verify_ssl=verify_ssl, + fingerprint=fingerprint, + ssl_context=ssl_context, + proxy_headers=proxy_headers, + compress=compress, + max_msg_size=max_msg_size, + ) + ) + + async def _ws_connect( + self, + url: StrOrURL, + *, + method: str = hdrs.METH_GET, + protocols: Iterable[str] = (), + timeout: float = 10.0, + receive_timeout: Optional[float] = None, + autoclose: bool = True, + autoping: bool = True, + heartbeat: Optional[float] = None, + auth: Optional[BasicAuth] = None, + origin: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + proxy: Optional[StrOrURL] = None, + proxy_auth: Optional[BasicAuth] = None, + ssl: Union[SSLContext, bool, None, Fingerprint] = None, + verify_ssl: Optional[bool] = None, + fingerprint: Optional[bytes] = None, + ssl_context: Optional[SSLContext] = None, + proxy_headers: Optional[LooseHeaders] = None, + compress: int = 0, + max_msg_size: int = 4 * 1024 * 1024, + ) -> ClientWebSocketResponse: + + if headers is None: + real_headers = CIMultiDict() # type: CIMultiDict[str] + else: + real_headers = CIMultiDict(headers) + + default_headers = { + hdrs.UPGRADE: "websocket", + hdrs.CONNECTION: "upgrade", + hdrs.SEC_WEBSOCKET_VERSION: "13", + } + + for key, value in default_headers.items(): + real_headers.setdefault(key, value) + + sec_key = base64.b64encode(os.urandom(16)) + real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode() + + if protocols: + real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = ",".join(protocols) + if origin is not None: + real_headers[hdrs.ORIGIN] = origin + if compress: + extstr = ws_ext_gen(compress=compress) + real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr + + ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) + + # send request + resp = await self.request( + method, + url, + headers=real_headers, + read_until_eof=False, + auth=auth, + proxy=proxy, + proxy_auth=proxy_auth, + ssl=ssl, + proxy_headers=proxy_headers, + ) + + try: + # check handshake + if resp.status != 101: + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message="Invalid response status", + status=resp.status, + headers=resp.headers, + ) + + if resp.headers.get(hdrs.UPGRADE, "").lower() != "websocket": + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message="Invalid upgrade header", + status=resp.status, + headers=resp.headers, + ) + + if resp.headers.get(hdrs.CONNECTION, "").lower() != "upgrade": + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message="Invalid connection header", + status=resp.status, + headers=resp.headers, + ) + + # key calculation + r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, "") + match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode() + if r_key != match: + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message="Invalid challenge response", + status=resp.status, + headers=resp.headers, + ) + + # websocket protocol + protocol = None + if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers: + resp_protocols = [ + proto.strip() + for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(",") + ] + + for proto in resp_protocols: + if proto in protocols: + protocol = proto + break + + # websocket compress + notakeover = False + if compress: + compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS) + if compress_hdrs: + try: + compress, notakeover = ws_ext_parse(compress_hdrs) + except WSHandshakeError as exc: + raise WSServerHandshakeError( + resp.request_info, + resp.history, + message=exc.args[0], + status=resp.status, + headers=resp.headers, + ) from exc + else: + compress = 0 + notakeover = False + + conn = resp.connection + assert conn is not None + conn_proto = conn.protocol + assert conn_proto is not None + transport = conn.transport + assert transport is not None + reader = FlowControlDataQueue( + conn_proto, 2 ** 16, loop=self._loop + ) # type: FlowControlDataQueue[WSMessage] + conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader) + writer = WebSocketWriter( + conn_proto, + transport, + use_mask=True, + compress=compress, + notakeover=notakeover, + ) + except BaseException: + resp.close() + raise + else: + return self._ws_response_class( + reader, + writer, + protocol, + resp, + timeout, + autoclose, + autoping, + self._loop, + receive_timeout=receive_timeout, + heartbeat=heartbeat, + compress=compress, + client_notakeover=notakeover, + ) + + def _prepare_headers(self, headers: Optional[LooseHeaders]) -> "CIMultiDict[str]": + """Add default headers and transform it to CIMultiDict""" + # Convert headers to MultiDict + result = CIMultiDict(self._default_headers) + if headers: + if not isinstance(headers, (MultiDictProxy, MultiDict)): + headers = CIMultiDict(headers) + added_names = set() # type: Set[str] + for key, value in headers.items(): + if key in added_names: + result.add(key, value) + else: + result[key] = value + added_names.add(key) + return result + + def get( + self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP GET request.""" + return _RequestContextManager( + self._request(hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs) + ) + + def options( + self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP OPTIONS request.""" + return _RequestContextManager( + self._request( + hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs + ) + ) + + def head( + self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP HEAD request.""" + return _RequestContextManager( + self._request( + hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs + ) + ) + + def post( + self, url: StrOrURL, *, data: Any = None, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP POST request.""" + return _RequestContextManager( + self._request(hdrs.METH_POST, url, data=data, **kwargs) + ) + + def put( + self, url: StrOrURL, *, data: Any = None, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP PUT request.""" + return _RequestContextManager( + self._request(hdrs.METH_PUT, url, data=data, **kwargs) + ) + + def patch( + self, url: StrOrURL, *, data: Any = None, **kwargs: Any + ) -> "_RequestContextManager": + """Perform HTTP PATCH request.""" + return _RequestContextManager( + self._request(hdrs.METH_PATCH, url, data=data, **kwargs) + ) + + def delete(self, url: StrOrURL, **kwargs: Any) -> "_RequestContextManager": + """Perform HTTP DELETE request.""" + return _RequestContextManager(self._request(hdrs.METH_DELETE, url, **kwargs)) + + async def close(self) -> None: + """Close underlying connector. + + Release all acquired resources. + """ + if not self.closed: + if self._connector is not None and self._connector_owner: + await self._connector.close() + self._connector = None + + @property + def closed(self) -> bool: + """Is client session closed. + + A readonly property. + """ + return self._connector is None or self._connector.closed + + @property + def connector(self) -> Optional[BaseConnector]: + """Connector instance used for the session.""" + return self._connector + + @property + def cookie_jar(self) -> AbstractCookieJar: + """The session cookies.""" + return self._cookie_jar + + @property + def version(self) -> Tuple[int, int]: + """The session HTTP protocol version.""" + return self._version + + @property + def requote_redirect_url(self) -> bool: + """Do URL requoting on redirection handling.""" + return self._requote_redirect_url + + @requote_redirect_url.setter + def requote_redirect_url(self, val: bool) -> None: + """Do URL requoting on redirection handling.""" + warnings.warn( + "session.requote_redirect_url modification " "is deprecated #2778", + DeprecationWarning, + stacklevel=2, + ) + self._requote_redirect_url = val + + @property + def loop(self) -> asyncio.AbstractEventLoop: + """Session's loop.""" + warnings.warn( + "client.loop property is deprecated", DeprecationWarning, stacklevel=2 + ) + return self._loop + + @property + def timeout(self) -> Union[object, ClientTimeout]: + """Timeout for the session.""" + return self._timeout + + @property + def headers(self) -> "CIMultiDict[str]": + """The default headers of the client session.""" + return self._default_headers + + @property + def skip_auto_headers(self) -> FrozenSet[istr]: + """Headers for which autogeneration should be skipped""" + return self._skip_auto_headers + + @property + def auth(self) -> Optional[BasicAuth]: + """An object that represents HTTP Basic Authorization""" + return self._default_auth + + @property + def json_serialize(self) -> JSONEncoder: + """Json serializer callable""" + return self._json_serialize + + @property + def connector_owner(self) -> bool: + """Should connector be closed on session closing""" + return self._connector_owner + + @property + def raise_for_status( + self, + ) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]: + """ + Should `ClientResponse.raise_for_status()` + be called for each response + """ + return self._raise_for_status + + @property + def auto_decompress(self) -> bool: + """Should the body response be automatically decompressed""" + return self._auto_decompress + + @property + def trust_env(self) -> bool: + """ + Should get proxies information + from HTTP_PROXY / HTTPS_PROXY environment variables + or ~/.netrc file if present + """ + return self._trust_env + + @property + def trace_configs(self) -> List[TraceConfig]: + """A list of TraceConfig instances used for client tracing""" + return self._trace_configs + + def detach(self) -> None: + """Detach connector from session without closing the former. + + Session is switched to closed state anyway. + """ + self._connector = None + + def __enter__(self) -> None: + raise TypeError("Use async with instead") + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + # __exit__ should exist in pair with __enter__ but never executed + pass # pragma: no cover + + async def __aenter__(self) -> "ClientSession": + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + await self.close() + + +class _BaseRequestContextManager(Coroutine[Any, Any, _RetType], Generic[_RetType]): + + __slots__ = ("_coro", "_resp") + + def __init__(self, coro: Coroutine["asyncio.Future[Any]", None, _RetType]) -> None: + self._coro = coro + + def send(self, arg: None) -> "asyncio.Future[Any]": + return self._coro.send(arg) + + def throw(self, arg: BaseException) -> None: # type: ignore + self._coro.throw(arg) + + def close(self) -> None: + return self._coro.close() + + def __await__(self) -> Generator[Any, None, _RetType]: + ret = self._coro.__await__() + return ret + + def __iter__(self) -> Generator[Any, None, _RetType]: + return self.__await__() + + async def __aenter__(self) -> _RetType: + self._resp = await self._coro + return self._resp + + +class _RequestContextManager(_BaseRequestContextManager[ClientResponse]): + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + # We're basing behavior on the exception as it can be caused by + # user code unrelated to the status of the connection. If you + # would like to close a connection you must do that + # explicitly. Otherwise connection error handling should kick in + # and close/recycle the connection as required. + self._resp.release() + + +class _WSRequestContextManager(_BaseRequestContextManager[ClientWebSocketResponse]): + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + await self._resp.close() + + +class _SessionRequestContextManager: + + __slots__ = ("_coro", "_resp", "_session") + + def __init__( + self, + coro: Coroutine["asyncio.Future[Any]", None, ClientResponse], + session: ClientSession, + ) -> None: + self._coro = coro + self._resp = None # type: Optional[ClientResponse] + self._session = session + + async def __aenter__(self) -> ClientResponse: + try: + self._resp = await self._coro + except BaseException: + await self._session.close() + raise + else: + return self._resp + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + assert self._resp is not None + self._resp.close() + await self._session.close() + + +def request( + method: str, + url: StrOrURL, + *, + params: Optional[Mapping[str, str]] = None, + data: Any = None, + json: Any = None, + headers: Optional[LooseHeaders] = None, + skip_auto_headers: Optional[Iterable[str]] = None, + auth: Optional[BasicAuth] = None, + allow_redirects: bool = True, + max_redirects: int = 10, + compress: Optional[str] = None, + chunked: Optional[bool] = None, + expect100: bool = False, + raise_for_status: Optional[bool] = None, + read_until_eof: bool = True, + proxy: Optional[StrOrURL] = None, + proxy_auth: Optional[BasicAuth] = None, + timeout: Union[ClientTimeout, object] = sentinel, + cookies: Optional[LooseCookies] = None, + version: HttpVersion = http.HttpVersion11, + connector: Optional[BaseConnector] = None, + read_bufsize: Optional[int] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, +) -> _SessionRequestContextManager: + """Constructs and sends a request. Returns response object. + method - HTTP method + url - request url + params - (optional) Dictionary or bytes to be sent in the query + string of the new request + data - (optional) Dictionary, bytes, or file-like object to + send in the body of the request + json - (optional) Any json compatible python object + headers - (optional) Dictionary of HTTP Headers to send with + the request + cookies - (optional) Dict object to send with the request + auth - (optional) BasicAuth named tuple represent HTTP Basic Auth + auth - aiohttp.helpers.BasicAuth + allow_redirects - (optional) If set to False, do not follow + redirects + version - Request HTTP version. + compress - Set to True if request has to be compressed + with deflate encoding. + chunked - Set to chunk size for chunked transfer encoding. + expect100 - Expect 100-continue response from server. + connector - BaseConnector sub-class instance to support + connection pooling. + read_until_eof - Read response until eof if response + does not have Content-Length header. + loop - Optional event loop. + timeout - Optional ClientTimeout settings structure, 5min + total timeout by default. + Usage:: + >>> import aiohttp + >>> resp = await aiohttp.request('GET', 'http://python.org/') + >>> resp + + >>> data = await resp.read() + """ + connector_owner = False + if connector is None: + connector_owner = True + connector = TCPConnector(loop=loop, force_close=True) + + session = ClientSession( + loop=loop, + cookies=cookies, + version=version, + timeout=timeout, + connector=connector, + connector_owner=connector_owner, + ) + + return _SessionRequestContextManager( + session._request( + method, + url, + params=params, + data=data, + json=json, + headers=headers, + skip_auto_headers=skip_auto_headers, + auth=auth, + allow_redirects=allow_redirects, + max_redirects=max_redirects, + compress=compress, + chunked=chunked, + expect100=expect100, + raise_for_status=raise_for_status, + read_until_eof=read_until_eof, + proxy=proxy, + proxy_auth=proxy_auth, + read_bufsize=read_bufsize, + ), + session, + ) diff --git a/dist/ba_data/python-site-packages/aiohttp/client_exceptions.py b/dist/ba_data/python-site-packages/aiohttp/client_exceptions.py new file mode 100644 index 0000000..f4be3bf --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/client_exceptions.py @@ -0,0 +1,317 @@ +"""HTTP related errors.""" + +import asyncio +import warnings +from typing import TYPE_CHECKING, Any, Optional, Tuple, Union + +from .typedefs import LooseHeaders + +try: + import ssl + + SSLContext = ssl.SSLContext +except ImportError: # pragma: no cover + ssl = SSLContext = None # type: ignore + + +if TYPE_CHECKING: # pragma: no cover + from .client_reqrep import ClientResponse, ConnectionKey, Fingerprint, RequestInfo +else: + RequestInfo = ClientResponse = ConnectionKey = None + +__all__ = ( + "ClientError", + "ClientConnectionError", + "ClientOSError", + "ClientConnectorError", + "ClientProxyConnectionError", + "ClientSSLError", + "ClientConnectorSSLError", + "ClientConnectorCertificateError", + "ServerConnectionError", + "ServerTimeoutError", + "ServerDisconnectedError", + "ServerFingerprintMismatch", + "ClientResponseError", + "ClientHttpProxyError", + "WSServerHandshakeError", + "ContentTypeError", + "ClientPayloadError", + "InvalidURL", +) + + +class ClientError(Exception): + """Base class for client connection errors.""" + + +class ClientResponseError(ClientError): + """Connection error during reading response. + + request_info: instance of RequestInfo + """ + + def __init__( + self, + request_info: RequestInfo, + history: Tuple[ClientResponse, ...], + *, + code: Optional[int] = None, + status: Optional[int] = None, + message: str = "", + headers: Optional[LooseHeaders] = None, + ) -> None: + self.request_info = request_info + if code is not None: + if status is not None: + raise ValueError( + "Both code and status arguments are provided; " + "code is deprecated, use status instead" + ) + warnings.warn( + "code argument is deprecated, use status instead", + DeprecationWarning, + stacklevel=2, + ) + if status is not None: + self.status = status + elif code is not None: + self.status = code + else: + self.status = 0 + self.message = message + self.headers = headers + self.history = history + self.args = (request_info, history) + + def __str__(self) -> str: + return "{}, message={!r}, url={!r}".format( + self.status, + self.message, + self.request_info.real_url, + ) + + def __repr__(self) -> str: + args = f"{self.request_info!r}, {self.history!r}" + if self.status != 0: + args += f", status={self.status!r}" + if self.message != "": + args += f", message={self.message!r}" + if self.headers is not None: + args += f", headers={self.headers!r}" + return "{}({})".format(type(self).__name__, args) + + @property + def code(self) -> int: + warnings.warn( + "code property is deprecated, use status instead", + DeprecationWarning, + stacklevel=2, + ) + return self.status + + @code.setter + def code(self, value: int) -> None: + warnings.warn( + "code property is deprecated, use status instead", + DeprecationWarning, + stacklevel=2, + ) + self.status = value + + +class ContentTypeError(ClientResponseError): + """ContentType found is not valid.""" + + +class WSServerHandshakeError(ClientResponseError): + """websocket server handshake error.""" + + +class ClientHttpProxyError(ClientResponseError): + """HTTP proxy error. + + Raised in :class:`aiohttp.connector.TCPConnector` if + proxy responds with status other than ``200 OK`` + on ``CONNECT`` request. + """ + + +class TooManyRedirects(ClientResponseError): + """Client was redirected too many times.""" + + +class ClientConnectionError(ClientError): + """Base class for client socket errors.""" + + +class ClientOSError(ClientConnectionError, OSError): + """OSError error.""" + + +class ClientConnectorError(ClientOSError): + """Client connector error. + + Raised in :class:`aiohttp.connector.TCPConnector` if + connection to proxy can not be established. + """ + + def __init__(self, connection_key: ConnectionKey, os_error: OSError) -> None: + self._conn_key = connection_key + self._os_error = os_error + super().__init__(os_error.errno, os_error.strerror) + self.args = (connection_key, os_error) + + @property + def os_error(self) -> OSError: + return self._os_error + + @property + def host(self) -> str: + return self._conn_key.host + + @property + def port(self) -> Optional[int]: + return self._conn_key.port + + @property + def ssl(self) -> Union[SSLContext, None, bool, "Fingerprint"]: + return self._conn_key.ssl + + def __str__(self) -> str: + return "Cannot connect to host {0.host}:{0.port} ssl:{1} [{2}]".format( + self, self.ssl if self.ssl is not None else "default", self.strerror + ) + + # OSError.__reduce__ does too much black magick + __reduce__ = BaseException.__reduce__ + + +class ClientProxyConnectionError(ClientConnectorError): + """Proxy connection error. + + Raised in :class:`aiohttp.connector.TCPConnector` if + connection to proxy can not be established. + """ + + +class ServerConnectionError(ClientConnectionError): + """Server connection errors.""" + + +class ServerDisconnectedError(ServerConnectionError): + """Server disconnected.""" + + def __init__(self, message: Optional[str] = None) -> None: + if message is None: + message = "Server disconnected" + + self.args = (message,) + self.message = message + + +class ServerTimeoutError(ServerConnectionError, asyncio.TimeoutError): + """Server timeout error.""" + + +class ServerFingerprintMismatch(ServerConnectionError): + """SSL certificate does not match expected fingerprint.""" + + def __init__(self, expected: bytes, got: bytes, host: str, port: int) -> None: + self.expected = expected + self.got = got + self.host = host + self.port = port + self.args = (expected, got, host, port) + + def __repr__(self) -> str: + return "<{} expected={!r} got={!r} host={!r} port={!r}>".format( + self.__class__.__name__, self.expected, self.got, self.host, self.port + ) + + +class ClientPayloadError(ClientError): + """Response payload error.""" + + +class InvalidURL(ClientError, ValueError): + """Invalid URL. + + URL used for fetching is malformed, e.g. it doesn't contains host + part.""" + + # Derive from ValueError for backward compatibility + + def __init__(self, url: Any) -> None: + # The type of url is not yarl.URL because the exception can be raised + # on URL(url) call + super().__init__(url) + + @property + def url(self) -> Any: + return self.args[0] + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.url}>" + + +class ClientSSLError(ClientConnectorError): + """Base error for ssl.*Errors.""" + + +if ssl is not None: + cert_errors = (ssl.CertificateError,) + cert_errors_bases = ( + ClientSSLError, + ssl.CertificateError, + ) + + ssl_errors = (ssl.SSLError,) + ssl_error_bases = (ClientSSLError, ssl.SSLError) +else: # pragma: no cover + cert_errors = tuple() + cert_errors_bases = ( + ClientSSLError, + ValueError, + ) + + ssl_errors = tuple() + ssl_error_bases = (ClientSSLError,) + + +class ClientConnectorSSLError(*ssl_error_bases): # type: ignore + """Response ssl error.""" + + +class ClientConnectorCertificateError(*cert_errors_bases): # type: ignore + """Response certificate error.""" + + def __init__( + self, connection_key: ConnectionKey, certificate_error: Exception + ) -> None: + self._conn_key = connection_key + self._certificate_error = certificate_error + self.args = (connection_key, certificate_error) + + @property + def certificate_error(self) -> Exception: + return self._certificate_error + + @property + def host(self) -> str: + return self._conn_key.host + + @property + def port(self) -> Optional[int]: + return self._conn_key.port + + @property + def ssl(self) -> bool: + return self._conn_key.is_ssl + + def __str__(self) -> str: + return ( + "Cannot connect to host {0.host}:{0.port} ssl:{0.ssl} " + "[{0.certificate_error.__class__.__name__}: " + "{0.certificate_error.args}]".format(self) + ) diff --git a/dist/ba_data/python-site-packages/aiohttp/client_proto.py b/dist/ba_data/python-site-packages/aiohttp/client_proto.py new file mode 100644 index 0000000..2973342 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/client_proto.py @@ -0,0 +1,251 @@ +import asyncio +from contextlib import suppress +from typing import Any, Optional, Tuple + +from .base_protocol import BaseProtocol +from .client_exceptions import ( + ClientOSError, + ClientPayloadError, + ServerDisconnectedError, + ServerTimeoutError, +) +from .helpers import BaseTimerContext +from .http import HttpResponseParser, RawResponseMessage +from .streams import EMPTY_PAYLOAD, DataQueue, StreamReader + + +class ResponseHandler(BaseProtocol, DataQueue[Tuple[RawResponseMessage, StreamReader]]): + """Helper class to adapt between Protocol and StreamReader.""" + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + BaseProtocol.__init__(self, loop=loop) + DataQueue.__init__(self, loop) + + self._should_close = False + + self._payload = None + self._skip_payload = False + self._payload_parser = None + + self._timer = None + + self._tail = b"" + self._upgraded = False + self._parser = None # type: Optional[HttpResponseParser] + + self._read_timeout = None # type: Optional[float] + self._read_timeout_handle = None # type: Optional[asyncio.TimerHandle] + + @property + def upgraded(self) -> bool: + return self._upgraded + + @property + def should_close(self) -> bool: + if self._payload is not None and not self._payload.is_eof() or self._upgraded: + return True + + return ( + self._should_close + or self._upgraded + or self.exception() is not None + or self._payload_parser is not None + or len(self) > 0 + or bool(self._tail) + ) + + def force_close(self) -> None: + self._should_close = True + + def close(self) -> None: + transport = self.transport + if transport is not None: + transport.close() + self.transport = None + self._payload = None + self._drop_timeout() + + def is_connected(self) -> bool: + return self.transport is not None and not self.transport.is_closing() + + def connection_lost(self, exc: Optional[BaseException]) -> None: + self._drop_timeout() + + if self._payload_parser is not None: + with suppress(Exception): + self._payload_parser.feed_eof() + + uncompleted = None + if self._parser is not None: + try: + uncompleted = self._parser.feed_eof() + except Exception: + if self._payload is not None: + self._payload.set_exception( + ClientPayloadError("Response payload is not completed") + ) + + if not self.is_eof(): + if isinstance(exc, OSError): + exc = ClientOSError(*exc.args) + if exc is None: + exc = ServerDisconnectedError(uncompleted) + # assigns self._should_close to True as side effect, + # we do it anyway below + self.set_exception(exc) + + self._should_close = True + self._parser = None + self._payload = None + self._payload_parser = None + self._reading_paused = False + + super().connection_lost(exc) + + def eof_received(self) -> None: + # should call parser.feed_eof() most likely + self._drop_timeout() + + def pause_reading(self) -> None: + super().pause_reading() + self._drop_timeout() + + def resume_reading(self) -> None: + super().resume_reading() + self._reschedule_timeout() + + def set_exception(self, exc: BaseException) -> None: + self._should_close = True + self._drop_timeout() + super().set_exception(exc) + + def set_parser(self, parser: Any, payload: Any) -> None: + # TODO: actual types are: + # parser: WebSocketReader + # payload: FlowControlDataQueue + # but they are not generi enough + # Need an ABC for both types + self._payload = payload + self._payload_parser = parser + + self._drop_timeout() + + if self._tail: + data, self._tail = self._tail, b"" + self.data_received(data) + + def set_response_params( + self, + *, + timer: Optional[BaseTimerContext] = None, + skip_payload: bool = False, + read_until_eof: bool = False, + auto_decompress: bool = True, + read_timeout: Optional[float] = None, + read_bufsize: int = 2 ** 16 + ) -> None: + self._skip_payload = skip_payload + + self._read_timeout = read_timeout + self._reschedule_timeout() + + self._parser = HttpResponseParser( + self, + self._loop, + read_bufsize, + timer=timer, + payload_exception=ClientPayloadError, + response_with_body=not skip_payload, + read_until_eof=read_until_eof, + auto_decompress=auto_decompress, + ) + + if self._tail: + data, self._tail = self._tail, b"" + self.data_received(data) + + def _drop_timeout(self) -> None: + if self._read_timeout_handle is not None: + self._read_timeout_handle.cancel() + self._read_timeout_handle = None + + def _reschedule_timeout(self) -> None: + timeout = self._read_timeout + if self._read_timeout_handle is not None: + self._read_timeout_handle.cancel() + + if timeout: + self._read_timeout_handle = self._loop.call_later( + timeout, self._on_read_timeout + ) + else: + self._read_timeout_handle = None + + def _on_read_timeout(self) -> None: + exc = ServerTimeoutError("Timeout on reading data from socket") + self.set_exception(exc) + if self._payload is not None: + self._payload.set_exception(exc) + + def data_received(self, data: bytes) -> None: + self._reschedule_timeout() + + if not data: + return + + # custom payload parser + if self._payload_parser is not None: + eof, tail = self._payload_parser.feed_data(data) + if eof: + self._payload = None + self._payload_parser = None + + if tail: + self.data_received(tail) + return + else: + if self._upgraded or self._parser is None: + # i.e. websocket connection, websocket parser is not set yet + self._tail += data + else: + # parse http messages + try: + messages, upgraded, tail = self._parser.feed_data(data) + except BaseException as exc: + if self.transport is not None: + # connection.release() could be called BEFORE + # data_received(), the transport is already + # closed in this case + self.transport.close() + # should_close is True after the call + self.set_exception(exc) + return + + self._upgraded = upgraded + + payload = None + for message, payload in messages: + if message.should_close: + self._should_close = True + + self._payload = payload + + if self._skip_payload or message.code in (204, 304): + self.feed_data((message, EMPTY_PAYLOAD), 0) # type: ignore + else: + self.feed_data((message, payload), 0) + if payload is not None: + # new message(s) was processed + # register timeout handler unsubscribing + # either on end-of-stream or immediately for + # EMPTY_PAYLOAD + if payload is not EMPTY_PAYLOAD: + payload.on_eof(self._drop_timeout) + else: + self._drop_timeout() + + if tail: + if upgraded: + self.data_received(tail) + else: + self._tail = tail diff --git a/dist/ba_data/python-site-packages/aiohttp/client_reqrep.py b/dist/ba_data/python-site-packages/aiohttp/client_reqrep.py new file mode 100644 index 0000000..d826bfe --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/client_reqrep.py @@ -0,0 +1,1127 @@ +import asyncio +import codecs +import functools +import io +import re +import sys +import traceback +import warnings +from hashlib import md5, sha1, sha256 +from http.cookies import CookieError, Morsel, SimpleCookie +from types import MappingProxyType, TracebackType +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Iterable, + List, + Mapping, + Optional, + Tuple, + Type, + Union, + cast, +) + +import attr +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy +from yarl import URL + +from . import hdrs, helpers, http, multipart, payload +from .abc import AbstractStreamWriter +from .client_exceptions import ( + ClientConnectionError, + ClientOSError, + ClientResponseError, + ContentTypeError, + InvalidURL, + ServerFingerprintMismatch, +) +from .formdata import FormData +from .helpers import ( + PY_36, + BaseTimerContext, + BasicAuth, + HeadersMixin, + TimerNoop, + noop, + reify, + set_result, +) +from .http import SERVER_SOFTWARE, HttpVersion10, HttpVersion11, StreamWriter +from .log import client_logger +from .streams import StreamReader +from .typedefs import ( + DEFAULT_JSON_DECODER, + JSONDecoder, + LooseCookies, + LooseHeaders, + RawHeaders, +) + +try: + import ssl + from ssl import SSLContext +except ImportError: # pragma: no cover + ssl = None # type: ignore + SSLContext = object # type: ignore + +try: + import cchardet as chardet +except ImportError: # pragma: no cover + import chardet # type: ignore + + +__all__ = ("ClientRequest", "ClientResponse", "RequestInfo", "Fingerprint") + + +if TYPE_CHECKING: # pragma: no cover + from .client import ClientSession + from .connector import Connection + from .tracing import Trace + + +json_re = re.compile(r"^application/(?:[\w.+-]+?\+)?json") + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class ContentDisposition: + type: Optional[str] + parameters: "MappingProxyType[str, str]" + filename: Optional[str] + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class RequestInfo: + url: URL + method: str + headers: "CIMultiDictProxy[str]" + real_url: URL = attr.ib() + + @real_url.default + def real_url_default(self) -> URL: + return self.url + + +class Fingerprint: + HASHFUNC_BY_DIGESTLEN = { + 16: md5, + 20: sha1, + 32: sha256, + } + + def __init__(self, fingerprint: bytes) -> None: + digestlen = len(fingerprint) + hashfunc = self.HASHFUNC_BY_DIGESTLEN.get(digestlen) + if not hashfunc: + raise ValueError("fingerprint has invalid length") + elif hashfunc is md5 or hashfunc is sha1: + raise ValueError( + "md5 and sha1 are insecure and " "not supported. Use sha256." + ) + self._hashfunc = hashfunc + self._fingerprint = fingerprint + + @property + def fingerprint(self) -> bytes: + return self._fingerprint + + def check(self, transport: asyncio.Transport) -> None: + if not transport.get_extra_info("sslcontext"): + return + sslobj = transport.get_extra_info("ssl_object") + cert = sslobj.getpeercert(binary_form=True) + got = self._hashfunc(cert).digest() + if got != self._fingerprint: + host, port, *_ = transport.get_extra_info("peername") + raise ServerFingerprintMismatch(self._fingerprint, got, host, port) + + +if ssl is not None: + SSL_ALLOWED_TYPES = (ssl.SSLContext, bool, Fingerprint, type(None)) +else: # pragma: no cover + SSL_ALLOWED_TYPES = type(None) + + +def _merge_ssl_params( + ssl: Union["SSLContext", bool, Fingerprint, None], + verify_ssl: Optional[bool], + ssl_context: Optional["SSLContext"], + fingerprint: Optional[bytes], +) -> Union["SSLContext", bool, Fingerprint, None]: + if verify_ssl is not None and not verify_ssl: + warnings.warn( + "verify_ssl is deprecated, use ssl=False instead", + DeprecationWarning, + stacklevel=3, + ) + if ssl is not None: + raise ValueError( + "verify_ssl, ssl_context, fingerprint and ssl " + "parameters are mutually exclusive" + ) + else: + ssl = False + if ssl_context is not None: + warnings.warn( + "ssl_context is deprecated, use ssl=context instead", + DeprecationWarning, + stacklevel=3, + ) + if ssl is not None: + raise ValueError( + "verify_ssl, ssl_context, fingerprint and ssl " + "parameters are mutually exclusive" + ) + else: + ssl = ssl_context + if fingerprint is not None: + warnings.warn( + "fingerprint is deprecated, " "use ssl=Fingerprint(fingerprint) instead", + DeprecationWarning, + stacklevel=3, + ) + if ssl is not None: + raise ValueError( + "verify_ssl, ssl_context, fingerprint and ssl " + "parameters are mutually exclusive" + ) + else: + ssl = Fingerprint(fingerprint) + if not isinstance(ssl, SSL_ALLOWED_TYPES): + raise TypeError( + "ssl should be SSLContext, bool, Fingerprint or None, " + "got {!r} instead.".format(ssl) + ) + return ssl + + +@attr.s(auto_attribs=True, slots=True, frozen=True) +class ConnectionKey: + # the key should contain an information about used proxy / TLS + # to prevent reusing wrong connections from a pool + host: str + port: Optional[int] + is_ssl: bool + ssl: Union[SSLContext, None, bool, Fingerprint] + proxy: Optional[URL] + proxy_auth: Optional[BasicAuth] + proxy_headers_hash: Optional[int] # hash(CIMultiDict) + + +def _is_expected_content_type( + response_content_type: str, expected_content_type: str +) -> bool: + if expected_content_type == "application/json": + return json_re.match(response_content_type) is not None + return expected_content_type in response_content_type + + +class ClientRequest: + GET_METHODS = { + hdrs.METH_GET, + hdrs.METH_HEAD, + hdrs.METH_OPTIONS, + hdrs.METH_TRACE, + } + POST_METHODS = {hdrs.METH_PATCH, hdrs.METH_POST, hdrs.METH_PUT} + ALL_METHODS = GET_METHODS.union(POST_METHODS).union({hdrs.METH_DELETE}) + + DEFAULT_HEADERS = { + hdrs.ACCEPT: "*/*", + hdrs.ACCEPT_ENCODING: "gzip, deflate", + } + + body = b"" + auth = None + response = None + + _writer = None # async task for streaming data + _continue = None # waiter future for '100 Continue' response + + # N.B. + # Adding __del__ method with self._writer closing doesn't make sense + # because _writer is instance method, thus it keeps a reference to self. + # Until writer has finished finalizer will not be called. + + def __init__( + self, + method: str, + url: URL, + *, + params: Optional[Mapping[str, str]] = None, + headers: Optional[LooseHeaders] = None, + skip_auto_headers: Iterable[str] = frozenset(), + data: Any = None, + cookies: Optional[LooseCookies] = None, + auth: Optional[BasicAuth] = None, + version: http.HttpVersion = http.HttpVersion11, + compress: Optional[str] = None, + chunked: Optional[bool] = None, + expect100: bool = False, + loop: Optional[asyncio.AbstractEventLoop] = None, + response_class: Optional[Type["ClientResponse"]] = None, + proxy: Optional[URL] = None, + proxy_auth: Optional[BasicAuth] = None, + timer: Optional[BaseTimerContext] = None, + session: Optional["ClientSession"] = None, + ssl: Union[SSLContext, bool, Fingerprint, None] = None, + proxy_headers: Optional[LooseHeaders] = None, + traces: Optional[List["Trace"]] = None, + ): + + if loop is None: + loop = asyncio.get_event_loop() + + assert isinstance(url, URL), url + assert isinstance(proxy, (URL, type(None))), proxy + # FIXME: session is None in tests only, need to fix tests + # assert session is not None + self._session = cast("ClientSession", session) + if params: + q = MultiDict(url.query) + url2 = url.with_query(params) + q.extend(url2.query) + url = url.with_query(q) + self.original_url = url + self.url = url.with_fragment(None) + self.method = method.upper() + self.chunked = chunked + self.compress = compress + self.loop = loop + self.length = None + if response_class is None: + real_response_class = ClientResponse + else: + real_response_class = response_class + self.response_class = real_response_class # type: Type[ClientResponse] + self._timer = timer if timer is not None else TimerNoop() + self._ssl = ssl + + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + self.update_version(version) + self.update_host(url) + self.update_headers(headers) + self.update_auto_headers(skip_auto_headers) + self.update_cookies(cookies) + self.update_content_encoding(data) + self.update_auth(auth) + self.update_proxy(proxy, proxy_auth, proxy_headers) + + self.update_body_from_data(data) + if data or self.method not in self.GET_METHODS: + self.update_transfer_encoding() + self.update_expect_continue(expect100) + if traces is None: + traces = [] + self._traces = traces + + def is_ssl(self) -> bool: + return self.url.scheme in ("https", "wss") + + @property + def ssl(self) -> Union["SSLContext", None, bool, Fingerprint]: + return self._ssl + + @property + def connection_key(self) -> ConnectionKey: + proxy_headers = self.proxy_headers + if proxy_headers: + h = hash( + tuple((k, v) for k, v in proxy_headers.items()) + ) # type: Optional[int] + else: + h = None + return ConnectionKey( + self.host, + self.port, + self.is_ssl(), + self.ssl, + self.proxy, + self.proxy_auth, + h, + ) + + @property + def host(self) -> str: + ret = self.url.raw_host + assert ret is not None + return ret + + @property + def port(self) -> Optional[int]: + return self.url.port + + @property + def request_info(self) -> RequestInfo: + headers = CIMultiDictProxy(self.headers) # type: CIMultiDictProxy[str] + return RequestInfo(self.url, self.method, headers, self.original_url) + + def update_host(self, url: URL) -> None: + """Update destination host, port and connection type (ssl).""" + # get host/port + if not url.raw_host: + raise InvalidURL(url) + + # basic auth info + username, password = url.user, url.password + if username: + self.auth = helpers.BasicAuth(username, password or "") + + def update_version(self, version: Union[http.HttpVersion, str]) -> None: + """Convert request version to two elements tuple. + + parser HTTP version '1.1' => (1, 1) + """ + if isinstance(version, str): + v = [part.strip() for part in version.split(".", 1)] + try: + version = http.HttpVersion(int(v[0]), int(v[1])) + except ValueError: + raise ValueError( + f"Can not parse http version number: {version}" + ) from None + self.version = version + + def update_headers(self, headers: Optional[LooseHeaders]) -> None: + """Update request headers.""" + self.headers = CIMultiDict() # type: CIMultiDict[str] + + # add host + netloc = cast(str, self.url.raw_host) + if helpers.is_ipv6_address(netloc): + netloc = f"[{netloc}]" + if self.url.port is not None and not self.url.is_default_port(): + netloc += ":" + str(self.url.port) + self.headers[hdrs.HOST] = netloc + + if headers: + if isinstance(headers, (dict, MultiDictProxy, MultiDict)): + headers = headers.items() # type: ignore + + for key, value in headers: # type: ignore + # A special case for Host header + if key.lower() == "host": + self.headers[key] = value + else: + self.headers.add(key, value) + + def update_auto_headers(self, skip_auto_headers: Iterable[str]) -> None: + self.skip_auto_headers = CIMultiDict( + (hdr, None) for hdr in sorted(skip_auto_headers) + ) + used_headers = self.headers.copy() + used_headers.extend(self.skip_auto_headers) # type: ignore + + for hdr, val in self.DEFAULT_HEADERS.items(): + if hdr not in used_headers: + self.headers.add(hdr, val) + + if hdrs.USER_AGENT not in used_headers: + self.headers[hdrs.USER_AGENT] = SERVER_SOFTWARE + + def update_cookies(self, cookies: Optional[LooseCookies]) -> None: + """Update request cookies header.""" + if not cookies: + return + + c = SimpleCookie() # type: SimpleCookie[str] + if hdrs.COOKIE in self.headers: + c.load(self.headers.get(hdrs.COOKIE, "")) + del self.headers[hdrs.COOKIE] + + if isinstance(cookies, Mapping): + iter_cookies = cookies.items() + else: + iter_cookies = cookies # type: ignore + for name, value in iter_cookies: + if isinstance(value, Morsel): + # Preserve coded_value + mrsl_val = value.get(value.key, Morsel()) + mrsl_val.set(value.key, value.value, value.coded_value) + c[name] = mrsl_val + else: + c[name] = value # type: ignore + + self.headers[hdrs.COOKIE] = c.output(header="", sep=";").strip() + + def update_content_encoding(self, data: Any) -> None: + """Set request content encoding.""" + if not data: + return + + enc = self.headers.get(hdrs.CONTENT_ENCODING, "").lower() + if enc: + if self.compress: + raise ValueError( + "compress can not be set " "if Content-Encoding header is set" + ) + elif self.compress: + if not isinstance(self.compress, str): + self.compress = "deflate" + self.headers[hdrs.CONTENT_ENCODING] = self.compress + self.chunked = True # enable chunked, no need to deal with length + + def update_transfer_encoding(self) -> None: + """Analyze transfer-encoding header.""" + te = self.headers.get(hdrs.TRANSFER_ENCODING, "").lower() + + if "chunked" in te: + if self.chunked: + raise ValueError( + "chunked can not be set " + 'if "Transfer-Encoding: chunked" header is set' + ) + + elif self.chunked: + if hdrs.CONTENT_LENGTH in self.headers: + raise ValueError( + "chunked can not be set " "if Content-Length header is set" + ) + + self.headers[hdrs.TRANSFER_ENCODING] = "chunked" + else: + if hdrs.CONTENT_LENGTH not in self.headers: + self.headers[hdrs.CONTENT_LENGTH] = str(len(self.body)) + + def update_auth(self, auth: Optional[BasicAuth]) -> None: + """Set basic auth.""" + if auth is None: + auth = self.auth + if auth is None: + return + + if not isinstance(auth, helpers.BasicAuth): + raise TypeError("BasicAuth() tuple is required instead") + + self.headers[hdrs.AUTHORIZATION] = auth.encode() + + def update_body_from_data(self, body: Any) -> None: + if not body: + return + + # FormData + if isinstance(body, FormData): + body = body() + + try: + body = payload.PAYLOAD_REGISTRY.get(body, disposition=None) + except payload.LookupError: + body = FormData(body)() + + self.body = body + + # enable chunked encoding if needed + if not self.chunked: + if hdrs.CONTENT_LENGTH not in self.headers: + size = body.size + if size is None: + self.chunked = True + else: + if hdrs.CONTENT_LENGTH not in self.headers: + self.headers[hdrs.CONTENT_LENGTH] = str(size) + + # copy payload headers + assert body.headers + for (key, value) in body.headers.items(): + if key in self.headers: + continue + if key in self.skip_auto_headers: + continue + self.headers[key] = value + + def update_expect_continue(self, expect: bool = False) -> None: + if expect: + self.headers[hdrs.EXPECT] = "100-continue" + elif self.headers.get(hdrs.EXPECT, "").lower() == "100-continue": + expect = True + + if expect: + self._continue = self.loop.create_future() + + def update_proxy( + self, + proxy: Optional[URL], + proxy_auth: Optional[BasicAuth], + proxy_headers: Optional[LooseHeaders], + ) -> None: + if proxy and not proxy.scheme == "http": + raise ValueError("Only http proxies are supported") + if proxy_auth and not isinstance(proxy_auth, helpers.BasicAuth): + raise ValueError("proxy_auth must be None or BasicAuth() tuple") + self.proxy = proxy + self.proxy_auth = proxy_auth + self.proxy_headers = proxy_headers + + def keep_alive(self) -> bool: + if self.version < HttpVersion10: + # keep alive not supported at all + return False + if self.version == HttpVersion10: + if self.headers.get(hdrs.CONNECTION) == "keep-alive": + return True + else: # no headers means we close for Http 1.0 + return False + elif self.headers.get(hdrs.CONNECTION) == "close": + return False + + return True + + async def write_bytes( + self, writer: AbstractStreamWriter, conn: "Connection" + ) -> None: + """Support coroutines that yields bytes objects.""" + # 100 response + if self._continue is not None: + await writer.drain() + await self._continue + + protocol = conn.protocol + assert protocol is not None + try: + if isinstance(self.body, payload.Payload): + await self.body.write(writer) + else: + if isinstance(self.body, (bytes, bytearray)): + self.body = (self.body,) # type: ignore + + for chunk in self.body: + await writer.write(chunk) # type: ignore + + await writer.write_eof() + except OSError as exc: + new_exc = ClientOSError( + exc.errno, "Can not write request body for %s" % self.url + ) + new_exc.__context__ = exc + new_exc.__cause__ = exc + protocol.set_exception(new_exc) + except asyncio.CancelledError as exc: + if not conn.closed: + protocol.set_exception(exc) + except Exception as exc: + protocol.set_exception(exc) + finally: + self._writer = None + + async def send(self, conn: "Connection") -> "ClientResponse": + # Specify request target: + # - CONNECT request must send authority form URI + # - not CONNECT proxy must send absolute form URI + # - most common is origin form URI + if self.method == hdrs.METH_CONNECT: + connect_host = self.url.raw_host + assert connect_host is not None + if helpers.is_ipv6_address(connect_host): + connect_host = f"[{connect_host}]" + path = f"{connect_host}:{self.url.port}" + elif self.proxy and not self.is_ssl(): + path = str(self.url) + else: + path = self.url.raw_path + if self.url.raw_query_string: + path += "?" + self.url.raw_query_string + + protocol = conn.protocol + assert protocol is not None + writer = StreamWriter( + protocol, + self.loop, + on_chunk_sent=functools.partial( + self._on_chunk_request_sent, self.method, self.url + ), + ) + + if self.compress: + writer.enable_compression(self.compress) + + if self.chunked is not None: + writer.enable_chunking() + + # set default content-type + if ( + self.method in self.POST_METHODS + and hdrs.CONTENT_TYPE not in self.skip_auto_headers + and hdrs.CONTENT_TYPE not in self.headers + ): + self.headers[hdrs.CONTENT_TYPE] = "application/octet-stream" + + # set the connection header + connection = self.headers.get(hdrs.CONNECTION) + if not connection: + if self.keep_alive(): + if self.version == HttpVersion10: + connection = "keep-alive" + else: + if self.version == HttpVersion11: + connection = "close" + + if connection is not None: + self.headers[hdrs.CONNECTION] = connection + + # status + headers + status_line = "{0} {1} HTTP/{2[0]}.{2[1]}".format( + self.method, path, self.version + ) + await writer.write_headers(status_line, self.headers) + + self._writer = self.loop.create_task(self.write_bytes(writer, conn)) + + response_class = self.response_class + assert response_class is not None + self.response = response_class( + self.method, + self.original_url, + writer=self._writer, + continue100=self._continue, + timer=self._timer, + request_info=self.request_info, + traces=self._traces, + loop=self.loop, + session=self._session, + ) + return self.response + + async def close(self) -> None: + if self._writer is not None: + try: + await self._writer + finally: + self._writer = None + + def terminate(self) -> None: + if self._writer is not None: + if not self.loop.is_closed(): + self._writer.cancel() + self._writer = None + + async def _on_chunk_request_sent(self, method: str, url: URL, chunk: bytes) -> None: + for trace in self._traces: + await trace.send_request_chunk_sent(method, url, chunk) + + +class ClientResponse(HeadersMixin): + + # from the Status-Line of the response + version = None # HTTP-Version + status = None # type: int # Status-Code + reason = None # Reason-Phrase + + content = None # type: StreamReader # Payload stream + _headers = None # type: CIMultiDictProxy[str] # Response headers + _raw_headers = None # type: RawHeaders # Response raw headers + + _connection = None # current connection + _source_traceback = None + # setted up by ClientRequest after ClientResponse object creation + # post-init stage allows to not change ctor signature + _closed = True # to allow __del__ for non-initialized properly response + _released = False + + def __init__( + self, + method: str, + url: URL, + *, + writer: "asyncio.Task[None]", + continue100: Optional["asyncio.Future[bool]"], + timer: BaseTimerContext, + request_info: RequestInfo, + traces: List["Trace"], + loop: asyncio.AbstractEventLoop, + session: "ClientSession", + ) -> None: + assert isinstance(url, URL) + + self.method = method + self.cookies = SimpleCookie() # type: SimpleCookie[str] + + self._real_url = url + self._url = url.with_fragment(None) + self._body = None # type: Any + self._writer = writer # type: Optional[asyncio.Task[None]] + self._continue = continue100 # None by default + self._closed = True + self._history = () # type: Tuple[ClientResponse, ...] + self._request_info = request_info + self._timer = timer if timer is not None else TimerNoop() + self._cache = {} # type: Dict[str, Any] + self._traces = traces + self._loop = loop + # store a reference to session #1985 + self._session = session # type: Optional[ClientSession] + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + @reify + def url(self) -> URL: + return self._url + + @reify + def url_obj(self) -> URL: + warnings.warn("Deprecated, use .url #1654", DeprecationWarning, stacklevel=2) + return self._url + + @reify + def real_url(self) -> URL: + return self._real_url + + @reify + def host(self) -> str: + assert self._url.host is not None + return self._url.host + + @reify + def headers(self) -> "CIMultiDictProxy[str]": + return self._headers + + @reify + def raw_headers(self) -> RawHeaders: + return self._raw_headers + + @reify + def request_info(self) -> RequestInfo: + return self._request_info + + @reify + def content_disposition(self) -> Optional[ContentDisposition]: + raw = self._headers.get(hdrs.CONTENT_DISPOSITION) + if raw is None: + return None + disposition_type, params_dct = multipart.parse_content_disposition(raw) + params = MappingProxyType(params_dct) + filename = multipart.content_disposition_filename(params) + return ContentDisposition(disposition_type, params, filename) + + def __del__(self, _warnings: Any = warnings) -> None: + if self._closed: + return + + if self._connection is not None: + self._connection.release() + self._cleanup_writer() + + if self._loop.get_debug(): + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + _warnings.warn(f"Unclosed response {self!r}", ResourceWarning, **kwargs) + context = {"client_response": self, "message": "Unclosed response"} + if self._source_traceback: + context["source_traceback"] = self._source_traceback + self._loop.call_exception_handler(context) + + def __repr__(self) -> str: + out = io.StringIO() + ascii_encodable_url = str(self.url) + if self.reason: + ascii_encodable_reason = self.reason.encode( + "ascii", "backslashreplace" + ).decode("ascii") + else: + ascii_encodable_reason = self.reason + print( + "".format( + ascii_encodable_url, self.status, ascii_encodable_reason + ), + file=out, + ) + print(self.headers, file=out) + return out.getvalue() + + @property + def connection(self) -> Optional["Connection"]: + return self._connection + + @reify + def history(self) -> Tuple["ClientResponse", ...]: + """A sequence of of responses, if redirects occurred.""" + return self._history + + @reify + def links(self) -> "MultiDictProxy[MultiDictProxy[Union[str, URL]]]": + links_str = ", ".join(self.headers.getall("link", [])) + + if not links_str: + return MultiDictProxy(MultiDict()) + + links = MultiDict() # type: MultiDict[MultiDictProxy[Union[str, URL]]] + + for val in re.split(r",(?=\s*<)", links_str): + match = re.match(r"\s*<(.*)>(.*)", val) + if match is None: # pragma: no cover + # the check exists to suppress mypy error + continue + url, params_str = match.groups() + params = params_str.split(";")[1:] + + link = MultiDict() # type: MultiDict[Union[str, URL]] + + for param in params: + match = re.match(r"^\s*(\S*)\s*=\s*(['\"]?)(.*?)(\2)\s*$", param, re.M) + if match is None: # pragma: no cover + # the check exists to suppress mypy error + continue + key, _, value, _ = match.groups() + + link.add(key, value) + + key = link.get("rel", url) # type: ignore + + link.add("url", self.url.join(URL(url))) + + links.add(key, MultiDictProxy(link)) + + return MultiDictProxy(links) + + async def start(self, connection: "Connection") -> "ClientResponse": + """Start response processing.""" + self._closed = False + self._protocol = connection.protocol + self._connection = connection + + with self._timer: + while True: + # read response + try: + message, payload = await self._protocol.read() # type: ignore + except http.HttpProcessingError as exc: + raise ClientResponseError( + self.request_info, + self.history, + status=exc.code, + message=exc.message, + headers=exc.headers, + ) from exc + + if message.code < 100 or message.code > 199 or message.code == 101: + break + + if self._continue is not None: + set_result(self._continue, True) + self._continue = None + + # payload eof handler + payload.on_eof(self._response_eof) + + # response status + self.version = message.version + self.status = message.code + self.reason = message.reason + + # headers + self._headers = message.headers # type is CIMultiDictProxy + self._raw_headers = message.raw_headers # type is Tuple[bytes, bytes] + + # payload + self.content = payload + + # cookies + for hdr in self.headers.getall(hdrs.SET_COOKIE, ()): + try: + self.cookies.load(hdr) + except CookieError as exc: + client_logger.warning("Can not load response cookies: %s", exc) + return self + + def _response_eof(self) -> None: + if self._closed: + return + + if self._connection is not None: + # websocket, protocol could be None because + # connection could be detached + if ( + self._connection.protocol is not None + and self._connection.protocol.upgraded + ): + return + + self._connection.release() + self._connection = None + + self._closed = True + self._cleanup_writer() + + @property + def closed(self) -> bool: + return self._closed + + def close(self) -> None: + if not self._released: + self._notify_content() + if self._closed: + return + + self._closed = True + if self._loop is None or self._loop.is_closed(): + return + + if self._connection is not None: + self._connection.close() + self._connection = None + self._cleanup_writer() + + def release(self) -> Any: + if not self._released: + self._notify_content() + if self._closed: + return noop() + + self._closed = True + if self._connection is not None: + self._connection.release() + self._connection = None + + self._cleanup_writer() + return noop() + + @property + def ok(self) -> bool: + """Returns ``True`` if ``status`` is less than ``400``, ``False`` if not. + + This is **not** a check for ``200 OK`` but a check that the response + status is under 400. + """ + try: + self.raise_for_status() + except ClientResponseError: + return False + return True + + def raise_for_status(self) -> None: + if 400 <= self.status: + # reason should always be not None for a started response + assert self.reason is not None + self.release() + raise ClientResponseError( + self.request_info, + self.history, + status=self.status, + message=self.reason, + headers=self.headers, + ) + + def _cleanup_writer(self) -> None: + if self._writer is not None: + self._writer.cancel() + self._writer = None + self._session = None + + def _notify_content(self) -> None: + content = self.content + if content and content.exception() is None: + content.set_exception(ClientConnectionError("Connection closed")) + self._released = True + + async def wait_for_close(self) -> None: + if self._writer is not None: + try: + await self._writer + finally: + self._writer = None + self.release() + + async def read(self) -> bytes: + """Read response payload.""" + if self._body is None: + try: + self._body = await self.content.read() + for trace in self._traces: + await trace.send_response_chunk_received( + self.method, self.url, self._body + ) + except BaseException: + self.close() + raise + elif self._released: + raise ClientConnectionError("Connection closed") + + return self._body + + def get_encoding(self) -> str: + ctype = self.headers.get(hdrs.CONTENT_TYPE, "").lower() + mimetype = helpers.parse_mimetype(ctype) + + encoding = mimetype.parameters.get("charset") + if encoding: + try: + codecs.lookup(encoding) + except LookupError: + encoding = None + if not encoding: + if mimetype.type == "application" and ( + mimetype.subtype == "json" or mimetype.subtype == "rdap" + ): + # RFC 7159 states that the default encoding is UTF-8. + # RFC 7483 defines application/rdap+json + encoding = "utf-8" + elif self._body is None: + raise RuntimeError( + "Cannot guess the encoding of " "a not yet read body" + ) + else: + encoding = chardet.detect(self._body)["encoding"] + if not encoding: + encoding = "utf-8" + + return encoding + + async def text(self, encoding: Optional[str] = None, errors: str = "strict") -> str: + """Read response payload and decode.""" + if self._body is None: + await self.read() + + if encoding is None: + encoding = self.get_encoding() + + return self._body.decode(encoding, errors=errors) # type: ignore + + async def json( + self, + *, + encoding: Optional[str] = None, + loads: JSONDecoder = DEFAULT_JSON_DECODER, + content_type: Optional[str] = "application/json", + ) -> Any: + """Read and decodes JSON response.""" + if self._body is None: + await self.read() + + if content_type: + ctype = self.headers.get(hdrs.CONTENT_TYPE, "").lower() + if not _is_expected_content_type(ctype, content_type): + raise ContentTypeError( + self.request_info, + self.history, + message=( + "Attempt to decode JSON with " "unexpected mimetype: %s" % ctype + ), + headers=self.headers, + ) + + stripped = self._body.strip() # type: ignore + if not stripped: + return None + + if encoding is None: + encoding = self.get_encoding() + + return loads(stripped.decode(encoding)) + + async def __aenter__(self) -> "ClientResponse": + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + # similar to _RequestContextManager, we do not need to check + # for exceptions, response object can close connection + # if state is broken + self.release() diff --git a/dist/ba_data/python-site-packages/aiohttp/client_ws.py b/dist/ba_data/python-site-packages/aiohttp/client_ws.py new file mode 100644 index 0000000..28fa371 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/client_ws.py @@ -0,0 +1,301 @@ +"""WebSocket client for asyncio.""" + +import asyncio +from typing import Any, Optional + +import async_timeout + +from .client_exceptions import ClientError +from .client_reqrep import ClientResponse +from .helpers import call_later, set_result +from .http import ( + WS_CLOSED_MESSAGE, + WS_CLOSING_MESSAGE, + WebSocketError, + WSMessage, + WSMsgType, +) +from .http_websocket import WebSocketWriter # WSMessage +from .streams import EofStream, FlowControlDataQueue +from .typedefs import ( + DEFAULT_JSON_DECODER, + DEFAULT_JSON_ENCODER, + JSONDecoder, + JSONEncoder, +) + + +class ClientWebSocketResponse: + def __init__( + self, + reader: "FlowControlDataQueue[WSMessage]", + writer: WebSocketWriter, + protocol: Optional[str], + response: ClientResponse, + timeout: float, + autoclose: bool, + autoping: bool, + loop: asyncio.AbstractEventLoop, + *, + receive_timeout: Optional[float] = None, + heartbeat: Optional[float] = None, + compress: int = 0, + client_notakeover: bool = False, + ) -> None: + self._response = response + self._conn = response.connection + + self._writer = writer + self._reader = reader + self._protocol = protocol + self._closed = False + self._closing = False + self._close_code = None # type: Optional[int] + self._timeout = timeout + self._receive_timeout = receive_timeout + self._autoclose = autoclose + self._autoping = autoping + self._heartbeat = heartbeat + self._heartbeat_cb = None + if heartbeat is not None: + self._pong_heartbeat = heartbeat / 2.0 + self._pong_response_cb = None + self._loop = loop + self._waiting = None # type: Optional[asyncio.Future[bool]] + self._exception = None # type: Optional[BaseException] + self._compress = compress + self._client_notakeover = client_notakeover + + self._reset_heartbeat() + + def _cancel_heartbeat(self) -> None: + if self._pong_response_cb is not None: + self._pong_response_cb.cancel() + self._pong_response_cb = None + + if self._heartbeat_cb is not None: + self._heartbeat_cb.cancel() + self._heartbeat_cb = None + + def _reset_heartbeat(self) -> None: + self._cancel_heartbeat() + + if self._heartbeat is not None: + self._heartbeat_cb = call_later( + self._send_heartbeat, self._heartbeat, self._loop + ) + + def _send_heartbeat(self) -> None: + if self._heartbeat is not None and not self._closed: + # fire-and-forget a task is not perfect but maybe ok for + # sending ping. Otherwise we need a long-living heartbeat + # task in the class. + self._loop.create_task(self._writer.ping()) + + if self._pong_response_cb is not None: + self._pong_response_cb.cancel() + self._pong_response_cb = call_later( + self._pong_not_received, self._pong_heartbeat, self._loop + ) + + def _pong_not_received(self) -> None: + if not self._closed: + self._closed = True + self._close_code = 1006 + self._exception = asyncio.TimeoutError() + self._response.close() + + @property + def closed(self) -> bool: + return self._closed + + @property + def close_code(self) -> Optional[int]: + return self._close_code + + @property + def protocol(self) -> Optional[str]: + return self._protocol + + @property + def compress(self) -> int: + return self._compress + + @property + def client_notakeover(self) -> bool: + return self._client_notakeover + + def get_extra_info(self, name: str, default: Any = None) -> Any: + """extra info from connection transport""" + conn = self._response.connection + if conn is None: + return default + transport = conn.transport + if transport is None: + return default + return transport.get_extra_info(name, default) + + def exception(self) -> Optional[BaseException]: + return self._exception + + async def ping(self, message: bytes = b"") -> None: + await self._writer.ping(message) + + async def pong(self, message: bytes = b"") -> None: + await self._writer.pong(message) + + async def send_str(self, data: str, compress: Optional[int] = None) -> None: + if not isinstance(data, str): + raise TypeError("data argument must be str (%r)" % type(data)) + await self._writer.send(data, binary=False, compress=compress) + + async def send_bytes(self, data: bytes, compress: Optional[int] = None) -> None: + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError("data argument must be byte-ish (%r)" % type(data)) + await self._writer.send(data, binary=True, compress=compress) + + async def send_json( + self, + data: Any, + compress: Optional[int] = None, + *, + dumps: JSONEncoder = DEFAULT_JSON_ENCODER, + ) -> None: + await self.send_str(dumps(data), compress=compress) + + async def close(self, *, code: int = 1000, message: bytes = b"") -> bool: + # we need to break `receive()` cycle first, + # `close()` may be called from different task + if self._waiting is not None and not self._closed: + self._reader.feed_data(WS_CLOSING_MESSAGE, 0) + await self._waiting + + if not self._closed: + self._cancel_heartbeat() + self._closed = True + try: + await self._writer.close(code, message) + except asyncio.CancelledError: + self._close_code = 1006 + self._response.close() + raise + except Exception as exc: + self._close_code = 1006 + self._exception = exc + self._response.close() + return True + + if self._closing: + self._response.close() + return True + + while True: + try: + with async_timeout.timeout(self._timeout, loop=self._loop): + msg = await self._reader.read() + except asyncio.CancelledError: + self._close_code = 1006 + self._response.close() + raise + except Exception as exc: + self._close_code = 1006 + self._exception = exc + self._response.close() + return True + + if msg.type == WSMsgType.CLOSE: + self._close_code = msg.data + self._response.close() + return True + else: + return False + + async def receive(self, timeout: Optional[float] = None) -> WSMessage: + while True: + if self._waiting is not None: + raise RuntimeError("Concurrent call to receive() is not allowed") + + if self._closed: + return WS_CLOSED_MESSAGE + elif self._closing: + await self.close() + return WS_CLOSED_MESSAGE + + try: + self._waiting = self._loop.create_future() + try: + with async_timeout.timeout( + timeout or self._receive_timeout, loop=self._loop + ): + msg = await self._reader.read() + self._reset_heartbeat() + finally: + waiter = self._waiting + self._waiting = None + set_result(waiter, True) + except (asyncio.CancelledError, asyncio.TimeoutError): + self._close_code = 1006 + raise + except EofStream: + self._close_code = 1000 + await self.close() + return WSMessage(WSMsgType.CLOSED, None, None) + except ClientError: + self._closed = True + self._close_code = 1006 + return WS_CLOSED_MESSAGE + except WebSocketError as exc: + self._close_code = exc.code + await self.close(code=exc.code) + return WSMessage(WSMsgType.ERROR, exc, None) + except Exception as exc: + self._exception = exc + self._closing = True + self._close_code = 1006 + await self.close() + return WSMessage(WSMsgType.ERROR, exc, None) + + if msg.type == WSMsgType.CLOSE: + self._closing = True + self._close_code = msg.data + if not self._closed and self._autoclose: + await self.close() + elif msg.type == WSMsgType.CLOSING: + self._closing = True + elif msg.type == WSMsgType.PING and self._autoping: + await self.pong(msg.data) + continue + elif msg.type == WSMsgType.PONG and self._autoping: + continue + + return msg + + async def receive_str(self, *, timeout: Optional[float] = None) -> str: + msg = await self.receive(timeout) + if msg.type != WSMsgType.TEXT: + raise TypeError(f"Received message {msg.type}:{msg.data!r} is not str") + return msg.data + + async def receive_bytes(self, *, timeout: Optional[float] = None) -> bytes: + msg = await self.receive(timeout) + if msg.type != WSMsgType.BINARY: + raise TypeError(f"Received message {msg.type}:{msg.data!r} is not bytes") + return msg.data + + async def receive_json( + self, + *, + loads: JSONDecoder = DEFAULT_JSON_DECODER, + timeout: Optional[float] = None, + ) -> Any: + data = await self.receive_str(timeout=timeout) + return loads(data) + + def __aiter__(self) -> "ClientWebSocketResponse": + return self + + async def __anext__(self) -> WSMessage: + msg = await self.receive() + if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING, WSMsgType.CLOSED): + raise StopAsyncIteration + return msg diff --git a/dist/ba_data/python-site-packages/aiohttp/connector.py b/dist/ba_data/python-site-packages/aiohttp/connector.py new file mode 100644 index 0000000..748b22a --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/connector.py @@ -0,0 +1,1262 @@ +import asyncio +import functools +import random +import sys +import traceback +import warnings +from collections import defaultdict, deque +from contextlib import suppress +from http.cookies import SimpleCookie +from itertools import cycle, islice +from time import monotonic +from types import TracebackType +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + DefaultDict, + Dict, + Iterator, + List, + Optional, + Set, + Tuple, + Type, + Union, + cast, +) + +import attr + +from . import hdrs, helpers +from .abc import AbstractResolver +from .client_exceptions import ( + ClientConnectionError, + ClientConnectorCertificateError, + ClientConnectorError, + ClientConnectorSSLError, + ClientHttpProxyError, + ClientProxyConnectionError, + ServerFingerprintMismatch, + cert_errors, + ssl_errors, +) +from .client_proto import ResponseHandler +from .client_reqrep import ClientRequest, Fingerprint, _merge_ssl_params +from .helpers import PY_36, CeilTimeout, get_running_loop, is_ip_address, noop, sentinel +from .http import RESPONSES +from .locks import EventResultOrError +from .resolver import DefaultResolver + +try: + import ssl + + SSLContext = ssl.SSLContext +except ImportError: # pragma: no cover + ssl = None # type: ignore + SSLContext = object # type: ignore + + +__all__ = ("BaseConnector", "TCPConnector", "UnixConnector", "NamedPipeConnector") + + +if TYPE_CHECKING: # pragma: no cover + from .client import ClientTimeout + from .client_reqrep import ConnectionKey + from .tracing import Trace + + +class _DeprecationWaiter: + __slots__ = ("_awaitable", "_awaited") + + def __init__(self, awaitable: Awaitable[Any]) -> None: + self._awaitable = awaitable + self._awaited = False + + def __await__(self) -> Any: + self._awaited = True + return self._awaitable.__await__() + + def __del__(self) -> None: + if not self._awaited: + warnings.warn( + "Connector.close() is a coroutine, " + "please use await connector.close()", + DeprecationWarning, + ) + + +class Connection: + + _source_traceback = None + _transport = None + + def __init__( + self, + connector: "BaseConnector", + key: "ConnectionKey", + protocol: ResponseHandler, + loop: asyncio.AbstractEventLoop, + ) -> None: + self._key = key + self._connector = connector + self._loop = loop + self._protocol = protocol # type: Optional[ResponseHandler] + self._callbacks = [] # type: List[Callable[[], None]] + + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + def __repr__(self) -> str: + return f"Connection<{self._key}>" + + def __del__(self, _warnings: Any = warnings) -> None: + if self._protocol is not None: + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + _warnings.warn(f"Unclosed connection {self!r}", ResourceWarning, **kwargs) + if self._loop.is_closed(): + return + + self._connector._release(self._key, self._protocol, should_close=True) + + context = {"client_connection": self, "message": "Unclosed connection"} + if self._source_traceback is not None: + context["source_traceback"] = self._source_traceback + self._loop.call_exception_handler(context) + + @property + def loop(self) -> asyncio.AbstractEventLoop: + warnings.warn( + "connector.loop property is deprecated", DeprecationWarning, stacklevel=2 + ) + return self._loop + + @property + def transport(self) -> Optional[asyncio.Transport]: + if self._protocol is None: + return None + return self._protocol.transport + + @property + def protocol(self) -> Optional[ResponseHandler]: + return self._protocol + + def add_callback(self, callback: Callable[[], None]) -> None: + if callback is not None: + self._callbacks.append(callback) + + def _notify_release(self) -> None: + callbacks, self._callbacks = self._callbacks[:], [] + + for cb in callbacks: + with suppress(Exception): + cb() + + def close(self) -> None: + self._notify_release() + + if self._protocol is not None: + self._connector._release(self._key, self._protocol, should_close=True) + self._protocol = None + + def release(self) -> None: + self._notify_release() + + if self._protocol is not None: + self._connector._release( + self._key, self._protocol, should_close=self._protocol.should_close + ) + self._protocol = None + + @property + def closed(self) -> bool: + return self._protocol is None or not self._protocol.is_connected() + + +class _TransportPlaceholder: + """ placeholder for BaseConnector.connect function """ + + def close(self) -> None: + pass + + +class BaseConnector: + """Base connector class. + + keepalive_timeout - (optional) Keep-alive timeout. + force_close - Set to True to force close and do reconnect + after each request (and between redirects). + limit - The total number of simultaneous connections. + limit_per_host - Number of simultaneous connections to one host. + enable_cleanup_closed - Enables clean-up closed ssl transports. + Disabled by default. + loop - Optional event loop. + """ + + _closed = True # prevent AttributeError in __del__ if ctor was failed + _source_traceback = None + + # abort transport after 2 seconds (cleanup broken connections) + _cleanup_closed_period = 2.0 + + def __init__( + self, + *, + keepalive_timeout: Union[object, None, float] = sentinel, + force_close: bool = False, + limit: int = 100, + limit_per_host: int = 0, + enable_cleanup_closed: bool = False, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> None: + + if force_close: + if keepalive_timeout is not None and keepalive_timeout is not sentinel: + raise ValueError( + "keepalive_timeout cannot " "be set if force_close is True" + ) + else: + if keepalive_timeout is sentinel: + keepalive_timeout = 15.0 + + loop = get_running_loop(loop) + + self._closed = False + if loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + self._conns = ( + {} + ) # type: Dict[ConnectionKey, List[Tuple[ResponseHandler, float]]] + self._limit = limit + self._limit_per_host = limit_per_host + self._acquired = set() # type: Set[ResponseHandler] + self._acquired_per_host = defaultdict( + set + ) # type: DefaultDict[ConnectionKey, Set[ResponseHandler]] + self._keepalive_timeout = cast(float, keepalive_timeout) + self._force_close = force_close + + # {host_key: FIFO list of waiters} + self._waiters = defaultdict(deque) # type: ignore + + self._loop = loop + self._factory = functools.partial(ResponseHandler, loop=loop) + + self.cookies = SimpleCookie() # type: SimpleCookie[str] + + # start keep-alive connection cleanup task + self._cleanup_handle = None + + # start cleanup closed transports task + self._cleanup_closed_handle = None + self._cleanup_closed_disabled = not enable_cleanup_closed + self._cleanup_closed_transports = [] # type: List[Optional[asyncio.Transport]] + self._cleanup_closed() + + def __del__(self, _warnings: Any = warnings) -> None: + if self._closed: + return + if not self._conns: + return + + conns = [repr(c) for c in self._conns.values()] + + self._close() + + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + _warnings.warn(f"Unclosed connector {self!r}", ResourceWarning, **kwargs) + context = { + "connector": self, + "connections": conns, + "message": "Unclosed connector", + } + if self._source_traceback is not None: + context["source_traceback"] = self._source_traceback + self._loop.call_exception_handler(context) + + def __enter__(self) -> "BaseConnector": + warnings.warn( + '"witn Connector():" is deprecated, ' + 'use "async with Connector():" instead', + DeprecationWarning, + ) + return self + + def __exit__(self, *exc: Any) -> None: + self.close() + + async def __aenter__(self) -> "BaseConnector": + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]] = None, + exc_value: Optional[BaseException] = None, + exc_traceback: Optional[TracebackType] = None, + ) -> None: + await self.close() + + @property + def force_close(self) -> bool: + """Ultimately close connection on releasing if True.""" + return self._force_close + + @property + def limit(self) -> int: + """The total number for simultaneous connections. + + If limit is 0 the connector has no limit. + The default limit size is 100. + """ + return self._limit + + @property + def limit_per_host(self) -> int: + """The limit_per_host for simultaneous connections + to the same endpoint. + + Endpoints are the same if they are have equal + (host, port, is_ssl) triple. + + """ + return self._limit_per_host + + def _cleanup(self) -> None: + """Cleanup unused transports.""" + if self._cleanup_handle: + self._cleanup_handle.cancel() + # _cleanup_handle should be unset, otherwise _release() will not + # recreate it ever! + self._cleanup_handle = None + + now = self._loop.time() + timeout = self._keepalive_timeout + + if self._conns: + connections = {} + deadline = now - timeout + for key, conns in self._conns.items(): + alive = [] + for proto, use_time in conns: + if proto.is_connected(): + if use_time - deadline < 0: + transport = proto.transport + proto.close() + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + else: + alive.append((proto, use_time)) + else: + transport = proto.transport + proto.close() + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + + if alive: + connections[key] = alive + + self._conns = connections + + if self._conns: + self._cleanup_handle = helpers.weakref_handle( + self, "_cleanup", timeout, self._loop + ) + + def _drop_acquired_per_host( + self, key: "ConnectionKey", val: ResponseHandler + ) -> None: + acquired_per_host = self._acquired_per_host + if key not in acquired_per_host: + return + conns = acquired_per_host[key] + conns.remove(val) + if not conns: + del self._acquired_per_host[key] + + def _cleanup_closed(self) -> None: + """Double confirmation for transport close. + Some broken ssl servers may leave socket open without proper close. + """ + if self._cleanup_closed_handle: + self._cleanup_closed_handle.cancel() + + for transport in self._cleanup_closed_transports: + if transport is not None: + transport.abort() + + self._cleanup_closed_transports = [] + + if not self._cleanup_closed_disabled: + self._cleanup_closed_handle = helpers.weakref_handle( + self, "_cleanup_closed", self._cleanup_closed_period, self._loop + ) + + def close(self) -> Awaitable[None]: + """Close all opened transports.""" + self._close() + return _DeprecationWaiter(noop()) + + def _close(self) -> None: + if self._closed: + return + + self._closed = True + + try: + if self._loop.is_closed(): + return + + # cancel cleanup task + if self._cleanup_handle: + self._cleanup_handle.cancel() + + # cancel cleanup close task + if self._cleanup_closed_handle: + self._cleanup_closed_handle.cancel() + + for data in self._conns.values(): + for proto, t0 in data: + proto.close() + + for proto in self._acquired: + proto.close() + + for transport in self._cleanup_closed_transports: + if transport is not None: + transport.abort() + + finally: + self._conns.clear() + self._acquired.clear() + self._waiters.clear() + self._cleanup_handle = None + self._cleanup_closed_transports.clear() + self._cleanup_closed_handle = None + + @property + def closed(self) -> bool: + """Is connector closed. + + A readonly property. + """ + return self._closed + + def _available_connections(self, key: "ConnectionKey") -> int: + """ + Return number of available connections taking into account + the limit, limit_per_host and the connection key. + + If it returns less than 1 means that there is no connections + availables. + """ + + if self._limit: + # total calc available connections + available = self._limit - len(self._acquired) + + # check limit per host + if ( + self._limit_per_host + and available > 0 + and key in self._acquired_per_host + ): + acquired = self._acquired_per_host.get(key) + assert acquired is not None + available = self._limit_per_host - len(acquired) + + elif self._limit_per_host and key in self._acquired_per_host: + # check limit per host + acquired = self._acquired_per_host.get(key) + assert acquired is not None + available = self._limit_per_host - len(acquired) + else: + available = 1 + + return available + + async def connect( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> Connection: + """Get from pool or create new connection.""" + key = req.connection_key + available = self._available_connections(key) + + # Wait if there are no available connections or if there are/were + # waiters (i.e. don't steal connection from a waiter about to wake up) + if available <= 0 or key in self._waiters: + fut = self._loop.create_future() + + # This connection will now count towards the limit. + self._waiters[key].append(fut) + + if traces: + for trace in traces: + await trace.send_connection_queued_start() + + try: + await fut + except BaseException as e: + if key in self._waiters: + # remove a waiter even if it was cancelled, normally it's + # removed when it's notified + try: + self._waiters[key].remove(fut) + except ValueError: # fut may no longer be in list + pass + + raise e + finally: + if key in self._waiters and not self._waiters[key]: + del self._waiters[key] + + if traces: + for trace in traces: + await trace.send_connection_queued_end() + + proto = self._get(key) + if proto is None: + placeholder = cast(ResponseHandler, _TransportPlaceholder()) + self._acquired.add(placeholder) + self._acquired_per_host[key].add(placeholder) + + if traces: + for trace in traces: + await trace.send_connection_create_start() + + try: + proto = await self._create_connection(req, traces, timeout) + if self._closed: + proto.close() + raise ClientConnectionError("Connector is closed.") + except BaseException: + if not self._closed: + self._acquired.remove(placeholder) + self._drop_acquired_per_host(key, placeholder) + self._release_waiter() + raise + else: + if not self._closed: + self._acquired.remove(placeholder) + self._drop_acquired_per_host(key, placeholder) + + if traces: + for trace in traces: + await trace.send_connection_create_end() + else: + if traces: + for trace in traces: + await trace.send_connection_reuseconn() + + self._acquired.add(proto) + self._acquired_per_host[key].add(proto) + return Connection(self, key, proto, self._loop) + + def _get(self, key: "ConnectionKey") -> Optional[ResponseHandler]: + try: + conns = self._conns[key] + except KeyError: + return None + + t1 = self._loop.time() + while conns: + proto, t0 = conns.pop() + if proto.is_connected(): + if t1 - t0 > self._keepalive_timeout: + transport = proto.transport + proto.close() + # only for SSL transports + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + else: + if not conns: + # The very last connection was reclaimed: drop the key + del self._conns[key] + return proto + else: + transport = proto.transport + proto.close() + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + + # No more connections: drop the key + del self._conns[key] + return None + + def _release_waiter(self) -> None: + """ + Iterates over all waiters till found one that is not finsihed and + belongs to a host that has available connections. + """ + if not self._waiters: + return + + # Having the dict keys ordered this avoids to iterate + # at the same order at each call. + queues = list(self._waiters.keys()) + random.shuffle(queues) + + for key in queues: + if self._available_connections(key) < 1: + continue + + waiters = self._waiters[key] + while waiters: + waiter = waiters.popleft() + if not waiter.done(): + waiter.set_result(None) + return + + def _release_acquired(self, key: "ConnectionKey", proto: ResponseHandler) -> None: + if self._closed: + # acquired connection is already released on connector closing + return + + try: + self._acquired.remove(proto) + self._drop_acquired_per_host(key, proto) + except KeyError: # pragma: no cover + # this may be result of undetermenistic order of objects + # finalization due garbage collection. + pass + else: + self._release_waiter() + + def _release( + self, + key: "ConnectionKey", + protocol: ResponseHandler, + *, + should_close: bool = False, + ) -> None: + if self._closed: + # acquired connection is already released on connector closing + return + + self._release_acquired(key, protocol) + + if self._force_close: + should_close = True + + if should_close or protocol.should_close: + transport = protocol.transport + protocol.close() + + if key.is_ssl and not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transport) + else: + conns = self._conns.get(key) + if conns is None: + conns = self._conns[key] = [] + conns.append((protocol, self._loop.time())) + + if self._cleanup_handle is None: + self._cleanup_handle = helpers.weakref_handle( + self, "_cleanup", self._keepalive_timeout, self._loop + ) + + async def _create_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> ResponseHandler: + raise NotImplementedError() + + +class _DNSCacheTable: + def __init__(self, ttl: Optional[float] = None) -> None: + self._addrs_rr = ( + {} + ) # type: Dict[Tuple[str, int], Tuple[Iterator[Dict[str, Any]], int]] + self._timestamps = {} # type: Dict[Tuple[str, int], float] + self._ttl = ttl + + def __contains__(self, host: object) -> bool: + return host in self._addrs_rr + + def add(self, key: Tuple[str, int], addrs: List[Dict[str, Any]]) -> None: + self._addrs_rr[key] = (cycle(addrs), len(addrs)) + + if self._ttl: + self._timestamps[key] = monotonic() + + def remove(self, key: Tuple[str, int]) -> None: + self._addrs_rr.pop(key, None) + + if self._ttl: + self._timestamps.pop(key, None) + + def clear(self) -> None: + self._addrs_rr.clear() + self._timestamps.clear() + + def next_addrs(self, key: Tuple[str, int]) -> List[Dict[str, Any]]: + loop, length = self._addrs_rr[key] + addrs = list(islice(loop, length)) + # Consume one more element to shift internal state of `cycle` + next(loop) + return addrs + + def expired(self, key: Tuple[str, int]) -> bool: + if self._ttl is None: + return False + + return self._timestamps[key] + self._ttl < monotonic() + + +class TCPConnector(BaseConnector): + """TCP connector. + + verify_ssl - Set to True to check ssl certifications. + fingerprint - Pass the binary sha256 + digest of the expected certificate in DER format to verify + that the certificate the server presents matches. See also + https://en.wikipedia.org/wiki/Transport_Layer_Security#Certificate_pinning + resolver - Enable DNS lookups and use this + resolver + use_dns_cache - Use memory cache for DNS lookups. + ttl_dns_cache - Max seconds having cached a DNS entry, None forever. + family - socket address family + local_addr - local tuple of (host, port) to bind socket to + + keepalive_timeout - (optional) Keep-alive timeout. + force_close - Set to True to force close and do reconnect + after each request (and between redirects). + limit - The total number of simultaneous connections. + limit_per_host - Number of simultaneous connections to one host. + enable_cleanup_closed - Enables clean-up closed ssl transports. + Disabled by default. + loop - Optional event loop. + """ + + def __init__( + self, + *, + verify_ssl: bool = True, + fingerprint: Optional[bytes] = None, + use_dns_cache: bool = True, + ttl_dns_cache: Optional[int] = 10, + family: int = 0, + ssl_context: Optional[SSLContext] = None, + ssl: Union[None, bool, Fingerprint, SSLContext] = None, + local_addr: Optional[Tuple[str, int]] = None, + resolver: Optional[AbstractResolver] = None, + keepalive_timeout: Union[None, float, object] = sentinel, + force_close: bool = False, + limit: int = 100, + limit_per_host: int = 0, + enable_cleanup_closed: bool = False, + loop: Optional[asyncio.AbstractEventLoop] = None, + ): + super().__init__( + keepalive_timeout=keepalive_timeout, + force_close=force_close, + limit=limit, + limit_per_host=limit_per_host, + enable_cleanup_closed=enable_cleanup_closed, + loop=loop, + ) + + self._ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint) + if resolver is None: + resolver = DefaultResolver(loop=self._loop) + self._resolver = resolver + + self._use_dns_cache = use_dns_cache + self._cached_hosts = _DNSCacheTable(ttl=ttl_dns_cache) + self._throttle_dns_events = ( + {} + ) # type: Dict[Tuple[str, int], EventResultOrError] + self._family = family + self._local_addr = local_addr + + def close(self) -> Awaitable[None]: + """Close all ongoing DNS calls.""" + for ev in self._throttle_dns_events.values(): + ev.cancel() + + return super().close() + + @property + def family(self) -> int: + """Socket family like AF_INET.""" + return self._family + + @property + def use_dns_cache(self) -> bool: + """True if local DNS caching is enabled.""" + return self._use_dns_cache + + def clear_dns_cache( + self, host: Optional[str] = None, port: Optional[int] = None + ) -> None: + """Remove specified host/port or clear all dns local cache.""" + if host is not None and port is not None: + self._cached_hosts.remove((host, port)) + elif host is not None or port is not None: + raise ValueError("either both host and port " "or none of them are allowed") + else: + self._cached_hosts.clear() + + async def _resolve_host( + self, host: str, port: int, traces: Optional[List["Trace"]] = None + ) -> List[Dict[str, Any]]: + if is_ip_address(host): + return [ + { + "hostname": host, + "host": host, + "port": port, + "family": self._family, + "proto": 0, + "flags": 0, + } + ] + + if not self._use_dns_cache: + + if traces: + for trace in traces: + await trace.send_dns_resolvehost_start(host) + + res = await self._resolver.resolve(host, port, family=self._family) + + if traces: + for trace in traces: + await trace.send_dns_resolvehost_end(host) + + return res + + key = (host, port) + + if (key in self._cached_hosts) and (not self._cached_hosts.expired(key)): + # get result early, before any await (#4014) + result = self._cached_hosts.next_addrs(key) + + if traces: + for trace in traces: + await trace.send_dns_cache_hit(host) + return result + + if key in self._throttle_dns_events: + # get event early, before any await (#4014) + event = self._throttle_dns_events[key] + if traces: + for trace in traces: + await trace.send_dns_cache_hit(host) + await event.wait() + else: + # update dict early, before any await (#4014) + self._throttle_dns_events[key] = EventResultOrError(self._loop) + if traces: + for trace in traces: + await trace.send_dns_cache_miss(host) + try: + + if traces: + for trace in traces: + await trace.send_dns_resolvehost_start(host) + + addrs = await self._resolver.resolve(host, port, family=self._family) + if traces: + for trace in traces: + await trace.send_dns_resolvehost_end(host) + + self._cached_hosts.add(key, addrs) + self._throttle_dns_events[key].set() + except BaseException as e: + # any DNS exception, independently of the implementation + # is set for the waiters to raise the same exception. + self._throttle_dns_events[key].set(exc=e) + raise + finally: + self._throttle_dns_events.pop(key) + + return self._cached_hosts.next_addrs(key) + + async def _create_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> ResponseHandler: + """Create connection. + + Has same keyword arguments as BaseEventLoop.create_connection. + """ + if req.proxy: + _, proto = await self._create_proxy_connection(req, traces, timeout) + else: + _, proto = await self._create_direct_connection(req, traces, timeout) + + return proto + + @staticmethod + @functools.lru_cache(None) + def _make_ssl_context(verified: bool) -> SSLContext: + if verified: + return ssl.create_default_context() + else: + sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext.options |= ssl.OP_NO_SSLv2 + sslcontext.options |= ssl.OP_NO_SSLv3 + try: + sslcontext.options |= ssl.OP_NO_COMPRESSION + except AttributeError as attr_err: + warnings.warn( + "{!s}: The Python interpreter is compiled " + "against OpenSSL < 1.0.0. Ref: " + "https://docs.python.org/3/library/ssl.html" + "#ssl.OP_NO_COMPRESSION".format(attr_err), + ) + sslcontext.set_default_verify_paths() + return sslcontext + + def _get_ssl_context(self, req: "ClientRequest") -> Optional[SSLContext]: + """Logic to get the correct SSL context + + 0. if req.ssl is false, return None + + 1. if ssl_context is specified in req, use it + 2. if _ssl_context is specified in self, use it + 3. otherwise: + 1. if verify_ssl is not specified in req, use self.ssl_context + (will generate a default context according to self.verify_ssl) + 2. if verify_ssl is True in req, generate a default SSL context + 3. if verify_ssl is False in req, generate a SSL context that + won't verify + """ + if req.is_ssl(): + if ssl is None: # pragma: no cover + raise RuntimeError("SSL is not supported.") + sslcontext = req.ssl + if isinstance(sslcontext, ssl.SSLContext): + return sslcontext + if sslcontext is not None: + # not verified or fingerprinted + return self._make_ssl_context(False) + sslcontext = self._ssl + if isinstance(sslcontext, ssl.SSLContext): + return sslcontext + if sslcontext is not None: + # not verified or fingerprinted + return self._make_ssl_context(False) + return self._make_ssl_context(True) + else: + return None + + def _get_fingerprint(self, req: "ClientRequest") -> Optional["Fingerprint"]: + ret = req.ssl + if isinstance(ret, Fingerprint): + return ret + ret = self._ssl + if isinstance(ret, Fingerprint): + return ret + return None + + async def _wrap_create_connection( + self, + *args: Any, + req: "ClientRequest", + timeout: "ClientTimeout", + client_error: Type[Exception] = ClientConnectorError, + **kwargs: Any, + ) -> Tuple[asyncio.Transport, ResponseHandler]: + try: + with CeilTimeout(timeout.sock_connect): + return await self._loop.create_connection(*args, **kwargs) # type: ignore # noqa + except cert_errors as exc: + raise ClientConnectorCertificateError(req.connection_key, exc) from exc + except ssl_errors as exc: + raise ClientConnectorSSLError(req.connection_key, exc) from exc + except OSError as exc: + raise client_error(req.connection_key, exc) from exc + + async def _create_direct_connection( + self, + req: "ClientRequest", + traces: List["Trace"], + timeout: "ClientTimeout", + *, + client_error: Type[Exception] = ClientConnectorError, + ) -> Tuple[asyncio.Transport, ResponseHandler]: + sslcontext = self._get_ssl_context(req) + fingerprint = self._get_fingerprint(req) + + host = req.url.raw_host + assert host is not None + port = req.port + assert port is not None + host_resolved = asyncio.ensure_future( + self._resolve_host(host, port, traces=traces), loop=self._loop + ) + try: + # Cancelling this lookup should not cancel the underlying lookup + # or else the cancel event will get broadcast to all the waiters + # across all connections. + hosts = await asyncio.shield(host_resolved) + except asyncio.CancelledError: + + def drop_exception(fut: "asyncio.Future[List[Dict[str, Any]]]") -> None: + with suppress(Exception, asyncio.CancelledError): + fut.result() + + host_resolved.add_done_callback(drop_exception) + raise + except OSError as exc: + # in case of proxy it is not ClientProxyConnectionError + # it is problem of resolving proxy ip itself + raise ClientConnectorError(req.connection_key, exc) from exc + + last_exc = None # type: Optional[Exception] + + for hinfo in hosts: + host = hinfo["host"] + port = hinfo["port"] + + try: + transp, proto = await self._wrap_create_connection( + self._factory, + host, + port, + timeout=timeout, + ssl=sslcontext, + family=hinfo["family"], + proto=hinfo["proto"], + flags=hinfo["flags"], + server_hostname=hinfo["hostname"] if sslcontext else None, + local_addr=self._local_addr, + req=req, + client_error=client_error, + ) + except ClientConnectorError as exc: + last_exc = exc + continue + + if req.is_ssl() and fingerprint: + try: + fingerprint.check(transp) + except ServerFingerprintMismatch as exc: + transp.close() + if not self._cleanup_closed_disabled: + self._cleanup_closed_transports.append(transp) + last_exc = exc + continue + + return transp, proto + else: + assert last_exc is not None + raise last_exc + + async def _create_proxy_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> Tuple[asyncio.Transport, ResponseHandler]: + headers = {} # type: Dict[str, str] + if req.proxy_headers is not None: + headers = req.proxy_headers # type: ignore + headers[hdrs.HOST] = req.headers[hdrs.HOST] + + url = req.proxy + assert url is not None + proxy_req = ClientRequest( + hdrs.METH_GET, + url, + headers=headers, + auth=req.proxy_auth, + loop=self._loop, + ssl=req.ssl, + ) + + # create connection to proxy server + transport, proto = await self._create_direct_connection( + proxy_req, [], timeout, client_error=ClientProxyConnectionError + ) + + # Many HTTP proxies has buggy keepalive support. Let's not + # reuse connection but close it after processing every + # response. + proto.force_close() + + auth = proxy_req.headers.pop(hdrs.AUTHORIZATION, None) + if auth is not None: + if not req.is_ssl(): + req.headers[hdrs.PROXY_AUTHORIZATION] = auth + else: + proxy_req.headers[hdrs.PROXY_AUTHORIZATION] = auth + + if req.is_ssl(): + sslcontext = self._get_ssl_context(req) + # For HTTPS requests over HTTP proxy + # we must notify proxy to tunnel connection + # so we send CONNECT command: + # CONNECT www.python.org:443 HTTP/1.1 + # Host: www.python.org + # + # next we must do TLS handshake and so on + # to do this we must wrap raw socket into secure one + # asyncio handles this perfectly + proxy_req.method = hdrs.METH_CONNECT + proxy_req.url = req.url + key = attr.evolve( + req.connection_key, proxy=None, proxy_auth=None, proxy_headers_hash=None + ) + conn = Connection(self, key, proto, self._loop) + proxy_resp = await proxy_req.send(conn) + try: + protocol = conn._protocol + assert protocol is not None + protocol.set_response_params() + resp = await proxy_resp.start(conn) + except BaseException: + proxy_resp.close() + conn.close() + raise + else: + conn._protocol = None + conn._transport = None + try: + if resp.status != 200: + message = resp.reason + if message is None: + message = RESPONSES[resp.status][0] + raise ClientHttpProxyError( + proxy_resp.request_info, + resp.history, + status=resp.status, + message=message, + headers=resp.headers, + ) + rawsock = transport.get_extra_info("socket", default=None) + if rawsock is None: + raise RuntimeError("Transport does not expose socket instance") + # Duplicate the socket, so now we can close proxy transport + rawsock = rawsock.dup() + finally: + transport.close() + + transport, proto = await self._wrap_create_connection( + self._factory, + timeout=timeout, + ssl=sslcontext, + sock=rawsock, + server_hostname=req.host, + req=req, + ) + finally: + proxy_resp.close() + + return transport, proto + + +class UnixConnector(BaseConnector): + """Unix socket connector. + + path - Unix socket path. + keepalive_timeout - (optional) Keep-alive timeout. + force_close - Set to True to force close and do reconnect + after each request (and between redirects). + limit - The total number of simultaneous connections. + limit_per_host - Number of simultaneous connections to one host. + loop - Optional event loop. + """ + + def __init__( + self, + path: str, + force_close: bool = False, + keepalive_timeout: Union[object, float, None] = sentinel, + limit: int = 100, + limit_per_host: int = 0, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> None: + super().__init__( + force_close=force_close, + keepalive_timeout=keepalive_timeout, + limit=limit, + limit_per_host=limit_per_host, + loop=loop, + ) + self._path = path + + @property + def path(self) -> str: + """Path to unix socket.""" + return self._path + + async def _create_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> ResponseHandler: + try: + with CeilTimeout(timeout.sock_connect): + _, proto = await self._loop.create_unix_connection( + self._factory, self._path + ) + except OSError as exc: + raise ClientConnectorError(req.connection_key, exc) from exc + + return cast(ResponseHandler, proto) + + +class NamedPipeConnector(BaseConnector): + """Named pipe connector. + + Only supported by the proactor event loop. + See also: https://docs.python.org/3.7/library/asyncio-eventloop.html + + path - Windows named pipe path. + keepalive_timeout - (optional) Keep-alive timeout. + force_close - Set to True to force close and do reconnect + after each request (and between redirects). + limit - The total number of simultaneous connections. + limit_per_host - Number of simultaneous connections to one host. + loop - Optional event loop. + """ + + def __init__( + self, + path: str, + force_close: bool = False, + keepalive_timeout: Union[object, float, None] = sentinel, + limit: int = 100, + limit_per_host: int = 0, + loop: Optional[asyncio.AbstractEventLoop] = None, + ) -> None: + super().__init__( + force_close=force_close, + keepalive_timeout=keepalive_timeout, + limit=limit, + limit_per_host=limit_per_host, + loop=loop, + ) + if not isinstance(self._loop, asyncio.ProactorEventLoop): # type: ignore + raise RuntimeError( + "Named Pipes only available in proactor " "loop under windows" + ) + self._path = path + + @property + def path(self) -> str: + """Path to the named pipe.""" + return self._path + + async def _create_connection( + self, req: "ClientRequest", traces: List["Trace"], timeout: "ClientTimeout" + ) -> ResponseHandler: + try: + with CeilTimeout(timeout.sock_connect): + _, proto = await self._loop.create_pipe_connection( # type: ignore + self._factory, self._path + ) + # the drain is required so that the connection_made is called + # and transport is set otherwise it is not set before the + # `assert conn.transport is not None` + # in client.py's _request method + await asyncio.sleep(0) + # other option is to manually set transport like + # `proto.transport = trans` + except OSError as exc: + raise ClientConnectorError(req.connection_key, exc) from exc + + return cast(ResponseHandler, proto) diff --git a/dist/ba_data/python-site-packages/aiohttp/cookiejar.py b/dist/ba_data/python-site-packages/aiohttp/cookiejar.py new file mode 100644 index 0000000..b6b59d6 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/cookiejar.py @@ -0,0 +1,382 @@ +import asyncio +import datetime +import os # noqa +import pathlib +import pickle +import re +from collections import defaultdict +from http.cookies import BaseCookie, Morsel, SimpleCookie +from typing import ( # noqa + DefaultDict, + Dict, + Iterable, + Iterator, + Mapping, + Optional, + Set, + Tuple, + Union, + cast, +) + +from yarl import URL + +from .abc import AbstractCookieJar +from .helpers import is_ip_address, next_whole_second +from .typedefs import LooseCookies, PathLike + +__all__ = ("CookieJar", "DummyCookieJar") + + +CookieItem = Union[str, "Morsel[str]"] + + +class CookieJar(AbstractCookieJar): + """Implements cookie storage adhering to RFC 6265.""" + + DATE_TOKENS_RE = re.compile( + r"[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]*" + r"(?P[\x00-\x08\x0A-\x1F\d:a-zA-Z\x7F-\xFF]+)" + ) + + DATE_HMS_TIME_RE = re.compile(r"(\d{1,2}):(\d{1,2}):(\d{1,2})") + + DATE_DAY_OF_MONTH_RE = re.compile(r"(\d{1,2})") + + DATE_MONTH_RE = re.compile( + "(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|" "(aug)|(sep)|(oct)|(nov)|(dec)", + re.I, + ) + + DATE_YEAR_RE = re.compile(r"(\d{2,4})") + + MAX_TIME = datetime.datetime.max.replace(tzinfo=datetime.timezone.utc) + + MAX_32BIT_TIME = datetime.datetime.utcfromtimestamp(2 ** 31 - 1) + + def __init__( + self, + *, + unsafe: bool = False, + quote_cookie: bool = True, + loop: Optional[asyncio.AbstractEventLoop] = None + ) -> None: + super().__init__(loop=loop) + self._cookies = defaultdict( + SimpleCookie + ) # type: DefaultDict[str, SimpleCookie[str]] + self._host_only_cookies = set() # type: Set[Tuple[str, str]] + self._unsafe = unsafe + self._quote_cookie = quote_cookie + self._next_expiration = next_whole_second() + self._expirations = {} # type: Dict[Tuple[str, str], datetime.datetime] + # #4515: datetime.max may not be representable on 32-bit platforms + self._max_time = self.MAX_TIME + try: + self._max_time.timestamp() + except OverflowError: + self._max_time = self.MAX_32BIT_TIME + + def save(self, file_path: PathLike) -> None: + file_path = pathlib.Path(file_path) + with file_path.open(mode="wb") as f: + pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL) + + def load(self, file_path: PathLike) -> None: + file_path = pathlib.Path(file_path) + with file_path.open(mode="rb") as f: + self._cookies = pickle.load(f) + + def clear(self) -> None: + self._cookies.clear() + self._host_only_cookies.clear() + self._next_expiration = next_whole_second() + self._expirations.clear() + + def __iter__(self) -> "Iterator[Morsel[str]]": + self._do_expiration() + for val in self._cookies.values(): + yield from val.values() + + def __len__(self) -> int: + return sum(1 for i in self) + + def _do_expiration(self) -> None: + now = datetime.datetime.now(datetime.timezone.utc) + if self._next_expiration > now: + return + if not self._expirations: + return + next_expiration = self._max_time + to_del = [] + cookies = self._cookies + expirations = self._expirations + for (domain, name), when in expirations.items(): + if when <= now: + cookies[domain].pop(name, None) + to_del.append((domain, name)) + self._host_only_cookies.discard((domain, name)) + else: + next_expiration = min(next_expiration, when) + for key in to_del: + del expirations[key] + + try: + self._next_expiration = next_expiration.replace( + microsecond=0 + ) + datetime.timedelta(seconds=1) + except OverflowError: + self._next_expiration = self._max_time + + def _expire_cookie(self, when: datetime.datetime, domain: str, name: str) -> None: + self._next_expiration = min(self._next_expiration, when) + self._expirations[(domain, name)] = when + + def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None: + """Update cookies.""" + hostname = response_url.raw_host + + if not self._unsafe and is_ip_address(hostname): + # Don't accept cookies from IPs + return + + if isinstance(cookies, Mapping): + cookies = cookies.items() + + for name, cookie in cookies: + if not isinstance(cookie, Morsel): + tmp = SimpleCookie() # type: SimpleCookie[str] + tmp[name] = cookie # type: ignore + cookie = tmp[name] + + domain = cookie["domain"] + + # ignore domains with trailing dots + if domain.endswith("."): + domain = "" + del cookie["domain"] + + if not domain and hostname is not None: + # Set the cookie's domain to the response hostname + # and set its host-only-flag + self._host_only_cookies.add((hostname, name)) + domain = cookie["domain"] = hostname + + if domain.startswith("."): + # Remove leading dot + domain = domain[1:] + cookie["domain"] = domain + + if hostname and not self._is_domain_match(domain, hostname): + # Setting cookies for different domains is not allowed + continue + + path = cookie["path"] + if not path or not path.startswith("/"): + # Set the cookie's path to the response path + path = response_url.path + if not path.startswith("/"): + path = "/" + else: + # Cut everything from the last slash to the end + path = "/" + path[1 : path.rfind("/")] + cookie["path"] = path + + max_age = cookie["max-age"] + if max_age: + try: + delta_seconds = int(max_age) + try: + max_age_expiration = datetime.datetime.now( + datetime.timezone.utc + ) + datetime.timedelta(seconds=delta_seconds) + except OverflowError: + max_age_expiration = self._max_time + self._expire_cookie(max_age_expiration, domain, name) + except ValueError: + cookie["max-age"] = "" + + else: + expires = cookie["expires"] + if expires: + expire_time = self._parse_date(expires) + if expire_time: + self._expire_cookie(expire_time, domain, name) + else: + cookie["expires"] = "" + + self._cookies[domain][name] = cookie + + self._do_expiration() + + def filter_cookies( + self, request_url: URL = URL() + ) -> Union["BaseCookie[str]", "SimpleCookie[str]"]: + """Returns this jar's cookies filtered by their attributes.""" + self._do_expiration() + request_url = URL(request_url) + filtered: Union["SimpleCookie[str]", "BaseCookie[str]"] = ( + SimpleCookie() if self._quote_cookie else BaseCookie() + ) + hostname = request_url.raw_host or "" + is_not_secure = request_url.scheme not in ("https", "wss") + + for cookie in self: + name = cookie.key + domain = cookie["domain"] + + # Send shared cookies + if not domain: + filtered[name] = cookie.value + continue + + if not self._unsafe and is_ip_address(hostname): + continue + + if (domain, name) in self._host_only_cookies: + if domain != hostname: + continue + elif not self._is_domain_match(domain, hostname): + continue + + if not self._is_path_match(request_url.path, cookie["path"]): + continue + + if is_not_secure and cookie["secure"]: + continue + + # It's critical we use the Morsel so the coded_value + # (based on cookie version) is preserved + mrsl_val = cast("Morsel[str]", cookie.get(cookie.key, Morsel())) + mrsl_val.set(cookie.key, cookie.value, cookie.coded_value) + filtered[name] = mrsl_val + + return filtered + + @staticmethod + def _is_domain_match(domain: str, hostname: str) -> bool: + """Implements domain matching adhering to RFC 6265.""" + if hostname == domain: + return True + + if not hostname.endswith(domain): + return False + + non_matching = hostname[: -len(domain)] + + if not non_matching.endswith("."): + return False + + return not is_ip_address(hostname) + + @staticmethod + def _is_path_match(req_path: str, cookie_path: str) -> bool: + """Implements path matching adhering to RFC 6265.""" + if not req_path.startswith("/"): + req_path = "/" + + if req_path == cookie_path: + return True + + if not req_path.startswith(cookie_path): + return False + + if cookie_path.endswith("/"): + return True + + non_matching = req_path[len(cookie_path) :] + + return non_matching.startswith("/") + + @classmethod + def _parse_date(cls, date_str: str) -> Optional[datetime.datetime]: + """Implements date string parsing adhering to RFC 6265.""" + if not date_str: + return None + + found_time = False + found_day = False + found_month = False + found_year = False + + hour = minute = second = 0 + day = 0 + month = 0 + year = 0 + + for token_match in cls.DATE_TOKENS_RE.finditer(date_str): + + token = token_match.group("token") + + if not found_time: + time_match = cls.DATE_HMS_TIME_RE.match(token) + if time_match: + found_time = True + hour, minute, second = [int(s) for s in time_match.groups()] + continue + + if not found_day: + day_match = cls.DATE_DAY_OF_MONTH_RE.match(token) + if day_match: + found_day = True + day = int(day_match.group()) + continue + + if not found_month: + month_match = cls.DATE_MONTH_RE.match(token) + if month_match: + found_month = True + assert month_match.lastindex is not None + month = month_match.lastindex + continue + + if not found_year: + year_match = cls.DATE_YEAR_RE.match(token) + if year_match: + found_year = True + year = int(year_match.group()) + + if 70 <= year <= 99: + year += 1900 + elif 0 <= year <= 69: + year += 2000 + + if False in (found_day, found_month, found_year, found_time): + return None + + if not 1 <= day <= 31: + return None + + if year < 1601 or hour > 23 or minute > 59 or second > 59: + return None + + return datetime.datetime( + year, month, day, hour, minute, second, tzinfo=datetime.timezone.utc + ) + + +class DummyCookieJar(AbstractCookieJar): + """Implements a dummy cookie storage. + + It can be used with the ClientSession when no cookie processing is needed. + + """ + + def __init__(self, *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: + super().__init__(loop=loop) + + def __iter__(self) -> "Iterator[Morsel[str]]": + while False: + yield None + + def __len__(self) -> int: + return 0 + + def clear(self) -> None: + pass + + def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None: + pass + + def filter_cookies(self, request_url: URL) -> "BaseCookie[str]": + return SimpleCookie() diff --git a/dist/ba_data/python-site-packages/aiohttp/formdata.py b/dist/ba_data/python-site-packages/aiohttp/formdata.py new file mode 100644 index 0000000..900716b --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/formdata.py @@ -0,0 +1,170 @@ +import io +from typing import Any, Iterable, List, Optional +from urllib.parse import urlencode + +from multidict import MultiDict, MultiDictProxy + +from . import hdrs, multipart, payload +from .helpers import guess_filename +from .payload import Payload + +__all__ = ("FormData",) + + +class FormData: + """Helper class for multipart/form-data and + application/x-www-form-urlencoded body generation.""" + + def __init__( + self, + fields: Iterable[Any] = (), + quote_fields: bool = True, + charset: Optional[str] = None, + ) -> None: + self._writer = multipart.MultipartWriter("form-data") + self._fields = [] # type: List[Any] + self._is_multipart = False + self._is_processed = False + self._quote_fields = quote_fields + self._charset = charset + + if isinstance(fields, dict): + fields = list(fields.items()) + elif not isinstance(fields, (list, tuple)): + fields = (fields,) + self.add_fields(*fields) + + @property + def is_multipart(self) -> bool: + return self._is_multipart + + def add_field( + self, + name: str, + value: Any, + *, + content_type: Optional[str] = None, + filename: Optional[str] = None, + content_transfer_encoding: Optional[str] = None + ) -> None: + + if isinstance(value, io.IOBase): + self._is_multipart = True + elif isinstance(value, (bytes, bytearray, memoryview)): + if filename is None and content_transfer_encoding is None: + filename = name + + type_options = MultiDict({"name": name}) # type: MultiDict[str] + if filename is not None and not isinstance(filename, str): + raise TypeError( + "filename must be an instance of str. " "Got: %s" % filename + ) + if filename is None and isinstance(value, io.IOBase): + filename = guess_filename(value, name) + if filename is not None: + type_options["filename"] = filename + self._is_multipart = True + + headers = {} + if content_type is not None: + if not isinstance(content_type, str): + raise TypeError( + "content_type must be an instance of str. " "Got: %s" % content_type + ) + headers[hdrs.CONTENT_TYPE] = content_type + self._is_multipart = True + if content_transfer_encoding is not None: + if not isinstance(content_transfer_encoding, str): + raise TypeError( + "content_transfer_encoding must be an instance" + " of str. Got: %s" % content_transfer_encoding + ) + headers[hdrs.CONTENT_TRANSFER_ENCODING] = content_transfer_encoding + self._is_multipart = True + + self._fields.append((type_options, headers, value)) + + def add_fields(self, *fields: Any) -> None: + to_add = list(fields) + + while to_add: + rec = to_add.pop(0) + + if isinstance(rec, io.IOBase): + k = guess_filename(rec, "unknown") + self.add_field(k, rec) # type: ignore + + elif isinstance(rec, (MultiDictProxy, MultiDict)): + to_add.extend(rec.items()) + + elif isinstance(rec, (list, tuple)) and len(rec) == 2: + k, fp = rec + self.add_field(k, fp) # type: ignore + + else: + raise TypeError( + "Only io.IOBase, multidict and (name, file) " + "pairs allowed, use .add_field() for passing " + "more complex parameters, got {!r}".format(rec) + ) + + def _gen_form_urlencoded(self) -> payload.BytesPayload: + # form data (x-www-form-urlencoded) + data = [] + for type_options, _, value in self._fields: + data.append((type_options["name"], value)) + + charset = self._charset if self._charset is not None else "utf-8" + + if charset == "utf-8": + content_type = "application/x-www-form-urlencoded" + else: + content_type = "application/x-www-form-urlencoded; " "charset=%s" % charset + + return payload.BytesPayload( + urlencode(data, doseq=True, encoding=charset).encode(), + content_type=content_type, + ) + + def _gen_form_data(self) -> multipart.MultipartWriter: + """Encode a list of fields using the multipart/form-data MIME format""" + if self._is_processed: + raise RuntimeError("Form data has been processed already") + for dispparams, headers, value in self._fields: + try: + if hdrs.CONTENT_TYPE in headers: + part = payload.get_payload( + value, + content_type=headers[hdrs.CONTENT_TYPE], + headers=headers, + encoding=self._charset, + ) + else: + part = payload.get_payload( + value, headers=headers, encoding=self._charset + ) + except Exception as exc: + raise TypeError( + "Can not serialize value type: %r\n " + "headers: %r\n value: %r" % (type(value), headers, value) + ) from exc + + if dispparams: + part.set_content_disposition( + "form-data", quote_fields=self._quote_fields, **dispparams + ) + # FIXME cgi.FieldStorage doesn't likes body parts with + # Content-Length which were sent via chunked transfer encoding + assert part.headers is not None + part.headers.popall(hdrs.CONTENT_LENGTH, None) + + self._writer.append_payload(part) + + self._is_processed = True + return self._writer + + def __call__(self) -> Payload: + if self._is_multipart: + return self._gen_form_data() + else: + return self._gen_form_urlencoded() diff --git a/dist/ba_data/python-site-packages/aiohttp/frozenlist.py b/dist/ba_data/python-site-packages/aiohttp/frozenlist.py new file mode 100644 index 0000000..46b2610 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/frozenlist.py @@ -0,0 +1,72 @@ +from collections.abc import MutableSequence +from functools import total_ordering + +from .helpers import NO_EXTENSIONS + + +@total_ordering +class FrozenList(MutableSequence): + + __slots__ = ("_frozen", "_items") + + def __init__(self, items=None): + self._frozen = False + if items is not None: + items = list(items) + else: + items = [] + self._items = items + + @property + def frozen(self): + return self._frozen + + def freeze(self): + self._frozen = True + + def __getitem__(self, index): + return self._items[index] + + def __setitem__(self, index, value): + if self._frozen: + raise RuntimeError("Cannot modify frozen list.") + self._items[index] = value + + def __delitem__(self, index): + if self._frozen: + raise RuntimeError("Cannot modify frozen list.") + del self._items[index] + + def __len__(self): + return self._items.__len__() + + def __iter__(self): + return self._items.__iter__() + + def __reversed__(self): + return self._items.__reversed__() + + def __eq__(self, other): + return list(self) == other + + def __le__(self, other): + return list(self) <= other + + def insert(self, pos, item): + if self._frozen: + raise RuntimeError("Cannot modify frozen list.") + self._items.insert(pos, item) + + def __repr__(self): + return f"" + + +PyFrozenList = FrozenList + +try: + from aiohttp._frozenlist import FrozenList as CFrozenList # type: ignore + + if not NO_EXTENSIONS: + FrozenList = CFrozenList # type: ignore +except ImportError: # pragma: no cover + pass diff --git a/dist/ba_data/python-site-packages/aiohttp/frozenlist.pyi b/dist/ba_data/python-site-packages/aiohttp/frozenlist.pyi new file mode 100644 index 0000000..72ab086 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/frozenlist.pyi @@ -0,0 +1,46 @@ +from typing import ( + Generic, + Iterable, + Iterator, + List, + MutableSequence, + Optional, + TypeVar, + Union, + overload, +) + +_T = TypeVar("_T") +_Arg = Union[List[_T], Iterable[_T]] + +class FrozenList(MutableSequence[_T], Generic[_T]): + def __init__(self, items: Optional[_Arg[_T]] = ...) -> None: ... + @property + def frozen(self) -> bool: ... + def freeze(self) -> None: ... + @overload + def __getitem__(self, i: int) -> _T: ... + @overload + def __getitem__(self, s: slice) -> FrozenList[_T]: ... + @overload + def __setitem__(self, i: int, o: _T) -> None: ... + @overload + def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ... + @overload + def __delitem__(self, i: int) -> None: ... + @overload + def __delitem__(self, i: slice) -> None: ... + def __len__(self) -> int: ... + def __iter__(self) -> Iterator[_T]: ... + def __reversed__(self) -> Iterator[_T]: ... + def __eq__(self, other: object) -> bool: ... + def __le__(self, other: FrozenList[_T]) -> bool: ... + def __ne__(self, other: object) -> bool: ... + def __lt__(self, other: FrozenList[_T]) -> bool: ... + def __ge__(self, other: FrozenList[_T]) -> bool: ... + def __gt__(self, other: FrozenList[_T]) -> bool: ... + def insert(self, pos: int, item: _T) -> None: ... + def __repr__(self) -> str: ... + +# types for C accelerators are the same +CFrozenList = PyFrozenList = FrozenList diff --git a/dist/ba_data/python-site-packages/aiohttp/hdrs.py b/dist/ba_data/python-site-packages/aiohttp/hdrs.py new file mode 100644 index 0000000..f04a545 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/hdrs.py @@ -0,0 +1,108 @@ +"""HTTP Headers constants.""" + +# After changing the file content call ./tools/gen.py +# to regenerate the headers parser + +from multidict import istr + +METH_ANY = "*" +METH_CONNECT = "CONNECT" +METH_HEAD = "HEAD" +METH_GET = "GET" +METH_DELETE = "DELETE" +METH_OPTIONS = "OPTIONS" +METH_PATCH = "PATCH" +METH_POST = "POST" +METH_PUT = "PUT" +METH_TRACE = "TRACE" + +METH_ALL = { + METH_CONNECT, + METH_HEAD, + METH_GET, + METH_DELETE, + METH_OPTIONS, + METH_PATCH, + METH_POST, + METH_PUT, + METH_TRACE, +} + + +ACCEPT = istr("Accept") +ACCEPT_CHARSET = istr("Accept-Charset") +ACCEPT_ENCODING = istr("Accept-Encoding") +ACCEPT_LANGUAGE = istr("Accept-Language") +ACCEPT_RANGES = istr("Accept-Ranges") +ACCESS_CONTROL_MAX_AGE = istr("Access-Control-Max-Age") +ACCESS_CONTROL_ALLOW_CREDENTIALS = istr("Access-Control-Allow-Credentials") +ACCESS_CONTROL_ALLOW_HEADERS = istr("Access-Control-Allow-Headers") +ACCESS_CONTROL_ALLOW_METHODS = istr("Access-Control-Allow-Methods") +ACCESS_CONTROL_ALLOW_ORIGIN = istr("Access-Control-Allow-Origin") +ACCESS_CONTROL_EXPOSE_HEADERS = istr("Access-Control-Expose-Headers") +ACCESS_CONTROL_REQUEST_HEADERS = istr("Access-Control-Request-Headers") +ACCESS_CONTROL_REQUEST_METHOD = istr("Access-Control-Request-Method") +AGE = istr("Age") +ALLOW = istr("Allow") +AUTHORIZATION = istr("Authorization") +CACHE_CONTROL = istr("Cache-Control") +CONNECTION = istr("Connection") +CONTENT_DISPOSITION = istr("Content-Disposition") +CONTENT_ENCODING = istr("Content-Encoding") +CONTENT_LANGUAGE = istr("Content-Language") +CONTENT_LENGTH = istr("Content-Length") +CONTENT_LOCATION = istr("Content-Location") +CONTENT_MD5 = istr("Content-MD5") +CONTENT_RANGE = istr("Content-Range") +CONTENT_TRANSFER_ENCODING = istr("Content-Transfer-Encoding") +CONTENT_TYPE = istr("Content-Type") +COOKIE = istr("Cookie") +DATE = istr("Date") +DESTINATION = istr("Destination") +DIGEST = istr("Digest") +ETAG = istr("Etag") +EXPECT = istr("Expect") +EXPIRES = istr("Expires") +FORWARDED = istr("Forwarded") +FROM = istr("From") +HOST = istr("Host") +IF_MATCH = istr("If-Match") +IF_MODIFIED_SINCE = istr("If-Modified-Since") +IF_NONE_MATCH = istr("If-None-Match") +IF_RANGE = istr("If-Range") +IF_UNMODIFIED_SINCE = istr("If-Unmodified-Since") +KEEP_ALIVE = istr("Keep-Alive") +LAST_EVENT_ID = istr("Last-Event-ID") +LAST_MODIFIED = istr("Last-Modified") +LINK = istr("Link") +LOCATION = istr("Location") +MAX_FORWARDS = istr("Max-Forwards") +ORIGIN = istr("Origin") +PRAGMA = istr("Pragma") +PROXY_AUTHENTICATE = istr("Proxy-Authenticate") +PROXY_AUTHORIZATION = istr("Proxy-Authorization") +RANGE = istr("Range") +REFERER = istr("Referer") +RETRY_AFTER = istr("Retry-After") +SEC_WEBSOCKET_ACCEPT = istr("Sec-WebSocket-Accept") +SEC_WEBSOCKET_VERSION = istr("Sec-WebSocket-Version") +SEC_WEBSOCKET_PROTOCOL = istr("Sec-WebSocket-Protocol") +SEC_WEBSOCKET_EXTENSIONS = istr("Sec-WebSocket-Extensions") +SEC_WEBSOCKET_KEY = istr("Sec-WebSocket-Key") +SEC_WEBSOCKET_KEY1 = istr("Sec-WebSocket-Key1") +SERVER = istr("Server") +SET_COOKIE = istr("Set-Cookie") +TE = istr("TE") +TRAILER = istr("Trailer") +TRANSFER_ENCODING = istr("Transfer-Encoding") +UPGRADE = istr("Upgrade") +URI = istr("URI") +USER_AGENT = istr("User-Agent") +VARY = istr("Vary") +VIA = istr("Via") +WANT_DIGEST = istr("Want-Digest") +WARNING = istr("Warning") +WWW_AUTHENTICATE = istr("WWW-Authenticate") +X_FORWARDED_FOR = istr("X-Forwarded-For") +X_FORWARDED_HOST = istr("X-Forwarded-Host") +X_FORWARDED_PROTO = istr("X-Forwarded-Proto") diff --git a/dist/ba_data/python-site-packages/aiohttp/helpers.py b/dist/ba_data/python-site-packages/aiohttp/helpers.py new file mode 100644 index 0000000..bbf5f12 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/helpers.py @@ -0,0 +1,780 @@ +"""Various helper functions""" + +import asyncio +import base64 +import binascii +import cgi +import datetime +import functools +import inspect +import netrc +import os +import platform +import re +import sys +import time +import warnings +import weakref +from collections import namedtuple +from contextlib import suppress +from math import ceil +from pathlib import Path +from types import TracebackType +from typing import ( + Any, + Callable, + Dict, + Generator, + Generic, + Iterable, + Iterator, + List, + Mapping, + Optional, + Pattern, + Set, + Tuple, + Type, + TypeVar, + Union, + cast, +) +from urllib.parse import quote +from urllib.request import getproxies + +import async_timeout +import attr +from multidict import MultiDict, MultiDictProxy +from typing_extensions import Protocol +from yarl import URL + +from . import hdrs +from .log import client_logger, internal_logger +from .typedefs import PathLike # noqa + +__all__ = ("BasicAuth", "ChainMapProxy") + +PY_36 = sys.version_info >= (3, 6) +PY_37 = sys.version_info >= (3, 7) +PY_38 = sys.version_info >= (3, 8) + +if not PY_37: + import idna_ssl + + idna_ssl.patch_match_hostname() + +try: + from typing import ContextManager +except ImportError: + from typing_extensions import ContextManager + + +def all_tasks( + loop: Optional[asyncio.AbstractEventLoop] = None, +) -> Set["asyncio.Task[Any]"]: + tasks = list(asyncio.Task.all_tasks(loop)) + return {t for t in tasks if not t.done()} + + +if PY_37: + all_tasks = getattr(asyncio, "all_tasks") + + +_T = TypeVar("_T") +_S = TypeVar("_S") + + +sentinel = object() # type: Any +NO_EXTENSIONS = bool(os.environ.get("AIOHTTP_NO_EXTENSIONS")) # type: bool + +# N.B. sys.flags.dev_mode is available on Python 3.7+, use getattr +# for compatibility with older versions +DEBUG = getattr(sys.flags, "dev_mode", False) or ( + not sys.flags.ignore_environment and bool(os.environ.get("PYTHONASYNCIODEBUG")) +) # type: bool + + +CHAR = {chr(i) for i in range(0, 128)} +CTL = {chr(i) for i in range(0, 32)} | { + chr(127), +} +SEPARATORS = { + "(", + ")", + "<", + ">", + "@", + ",", + ";", + ":", + "\\", + '"', + "/", + "[", + "]", + "?", + "=", + "{", + "}", + " ", + chr(9), +} +TOKEN = CHAR ^ CTL ^ SEPARATORS + + +class noop: + def __await__(self) -> Generator[None, None, None]: + yield + + +class BasicAuth(namedtuple("BasicAuth", ["login", "password", "encoding"])): + """Http basic authentication helper.""" + + def __new__( + cls, login: str, password: str = "", encoding: str = "latin1" + ) -> "BasicAuth": + if login is None: + raise ValueError("None is not allowed as login value") + + if password is None: + raise ValueError("None is not allowed as password value") + + if ":" in login: + raise ValueError('A ":" is not allowed in login (RFC 1945#section-11.1)') + + return super().__new__(cls, login, password, encoding) + + @classmethod + def decode(cls, auth_header: str, encoding: str = "latin1") -> "BasicAuth": + """Create a BasicAuth object from an Authorization HTTP header.""" + try: + auth_type, encoded_credentials = auth_header.split(" ", 1) + except ValueError: + raise ValueError("Could not parse authorization header.") + + if auth_type.lower() != "basic": + raise ValueError("Unknown authorization method %s" % auth_type) + + try: + decoded = base64.b64decode( + encoded_credentials.encode("ascii"), validate=True + ).decode(encoding) + except binascii.Error: + raise ValueError("Invalid base64 encoding.") + + try: + # RFC 2617 HTTP Authentication + # https://www.ietf.org/rfc/rfc2617.txt + # the colon must be present, but the username and password may be + # otherwise blank. + username, password = decoded.split(":", 1) + except ValueError: + raise ValueError("Invalid credentials.") + + return cls(username, password, encoding=encoding) + + @classmethod + def from_url(cls, url: URL, *, encoding: str = "latin1") -> Optional["BasicAuth"]: + """Create BasicAuth from url.""" + if not isinstance(url, URL): + raise TypeError("url should be yarl.URL instance") + if url.user is None: + return None + return cls(url.user, url.password or "", encoding=encoding) + + def encode(self) -> str: + """Encode credentials.""" + creds = (f"{self.login}:{self.password}").encode(self.encoding) + return "Basic %s" % base64.b64encode(creds).decode(self.encoding) + + +def strip_auth_from_url(url: URL) -> Tuple[URL, Optional[BasicAuth]]: + auth = BasicAuth.from_url(url) + if auth is None: + return url, None + else: + return url.with_user(None), auth + + +def netrc_from_env() -> Optional[netrc.netrc]: + """Attempt to load the netrc file from the path specified by the env-var + NETRC or in the default location in the user's home directory. + + Returns None if it couldn't be found or fails to parse. + """ + netrc_env = os.environ.get("NETRC") + + if netrc_env is not None: + netrc_path = Path(netrc_env) + else: + try: + home_dir = Path.home() + except RuntimeError as e: # pragma: no cover + # if pathlib can't resolve home, it may raise a RuntimeError + client_logger.debug( + "Could not resolve home directory when " + "trying to look for .netrc file: %s", + e, + ) + return None + + netrc_path = home_dir / ( + "_netrc" if platform.system() == "Windows" else ".netrc" + ) + + try: + return netrc.netrc(str(netrc_path)) + except netrc.NetrcParseError as e: + client_logger.warning("Could not parse .netrc file: %s", e) + except OSError as e: + # we couldn't read the file (doesn't exist, permissions, etc.) + if netrc_env or netrc_path.is_file(): + # only warn if the environment wanted us to load it, + # or it appears like the default file does actually exist + client_logger.warning("Could not read .netrc file: %s", e) + + return None + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class ProxyInfo: + proxy: URL + proxy_auth: Optional[BasicAuth] + + +def proxies_from_env() -> Dict[str, ProxyInfo]: + proxy_urls = {k: URL(v) for k, v in getproxies().items() if k in ("http", "https")} + netrc_obj = netrc_from_env() + stripped = {k: strip_auth_from_url(v) for k, v in proxy_urls.items()} + ret = {} + for proto, val in stripped.items(): + proxy, auth = val + if proxy.scheme == "https": + client_logger.warning("HTTPS proxies %s are not supported, ignoring", proxy) + continue + if netrc_obj and auth is None: + auth_from_netrc = None + if proxy.host is not None: + auth_from_netrc = netrc_obj.authenticators(proxy.host) + if auth_from_netrc is not None: + # auth_from_netrc is a (`user`, `account`, `password`) tuple, + # `user` and `account` both can be username, + # if `user` is None, use `account` + *logins, password = auth_from_netrc + login = logins[0] if logins[0] else logins[-1] + auth = BasicAuth(cast(str, login), cast(str, password)) + ret[proto] = ProxyInfo(proxy, auth) + return ret + + +def current_task( + loop: Optional[asyncio.AbstractEventLoop] = None, +) -> "Optional[asyncio.Task[Any]]": + if PY_37: + return asyncio.current_task(loop=loop) + else: + return asyncio.Task.current_task(loop=loop) + + +def get_running_loop( + loop: Optional[asyncio.AbstractEventLoop] = None, +) -> asyncio.AbstractEventLoop: + if loop is None: + loop = asyncio.get_event_loop() + if not loop.is_running(): + warnings.warn( + "The object should be created within an async function", + DeprecationWarning, + stacklevel=3, + ) + if loop.get_debug(): + internal_logger.warning( + "The object should be created within an async function", stack_info=True + ) + return loop + + +def isasyncgenfunction(obj: Any) -> bool: + func = getattr(inspect, "isasyncgenfunction", None) + if func is not None: + return func(obj) + else: + return False + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class MimeType: + type: str + subtype: str + suffix: str + parameters: "MultiDictProxy[str]" + + +@functools.lru_cache(maxsize=56) +def parse_mimetype(mimetype: str) -> MimeType: + """Parses a MIME type into its components. + + mimetype is a MIME type string. + + Returns a MimeType object. + + Example: + + >>> parse_mimetype('text/html; charset=utf-8') + MimeType(type='text', subtype='html', suffix='', + parameters={'charset': 'utf-8'}) + + """ + if not mimetype: + return MimeType( + type="", subtype="", suffix="", parameters=MultiDictProxy(MultiDict()) + ) + + parts = mimetype.split(";") + params = MultiDict() # type: MultiDict[str] + for item in parts[1:]: + if not item: + continue + key, value = cast( + Tuple[str, str], item.split("=", 1) if "=" in item else (item, "") + ) + params.add(key.lower().strip(), value.strip(' "')) + + fulltype = parts[0].strip().lower() + if fulltype == "*": + fulltype = "*/*" + + mtype, stype = ( + cast(Tuple[str, str], fulltype.split("/", 1)) + if "/" in fulltype + else (fulltype, "") + ) + stype, suffix = ( + cast(Tuple[str, str], stype.split("+", 1)) if "+" in stype else (stype, "") + ) + + return MimeType( + type=mtype, subtype=stype, suffix=suffix, parameters=MultiDictProxy(params) + ) + + +def guess_filename(obj: Any, default: Optional[str] = None) -> Optional[str]: + name = getattr(obj, "name", None) + if name and isinstance(name, str) and name[0] != "<" and name[-1] != ">": + return Path(name).name + return default + + +def content_disposition_header( + disptype: str, quote_fields: bool = True, **params: str +) -> str: + """Sets ``Content-Disposition`` header. + + disptype is a disposition type: inline, attachment, form-data. + Should be valid extension token (see RFC 2183) + + params is a dict with disposition params. + """ + if not disptype or not (TOKEN > set(disptype)): + raise ValueError("bad content disposition type {!r}" "".format(disptype)) + + value = disptype + if params: + lparams = [] + for key, val in params.items(): + if not key or not (TOKEN > set(key)): + raise ValueError( + "bad content disposition parameter" " {!r}={!r}".format(key, val) + ) + qval = quote(val, "") if quote_fields else val + lparams.append((key, '"%s"' % qval)) + if key == "filename": + lparams.append(("filename*", "utf-8''" + qval)) + sparams = "; ".join("=".join(pair) for pair in lparams) + value = "; ".join((value, sparams)) + return value + + +class _TSelf(Protocol): + _cache: Dict[str, Any] + + +class reify(Generic[_T]): + """Use as a class method decorator. It operates almost exactly like + the Python `@property` decorator, but it puts the result of the + method it decorates into the instance dict after the first call, + effectively replacing the function it decorates with an instance + variable. It is, in Python parlance, a data descriptor. + + """ + + def __init__(self, wrapped: Callable[..., _T]) -> None: + self.wrapped = wrapped + self.__doc__ = wrapped.__doc__ + self.name = wrapped.__name__ + + def __get__(self, inst: _TSelf, owner: Optional[Type[Any]] = None) -> _T: + try: + try: + return inst._cache[self.name] + except KeyError: + val = self.wrapped(inst) + inst._cache[self.name] = val + return val + except AttributeError: + if inst is None: + return self + raise + + def __set__(self, inst: _TSelf, value: _T) -> None: + raise AttributeError("reified property is read-only") + + +reify_py = reify + +try: + from ._helpers import reify as reify_c + + if not NO_EXTENSIONS: + reify = reify_c # type: ignore +except ImportError: + pass + +_ipv4_pattern = ( + r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}" + r"(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" +) +_ipv6_pattern = ( + r"^(?:(?:(?:[A-F0-9]{1,4}:){6}|(?=(?:[A-F0-9]{0,4}:){0,6}" + r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}$)(([0-9A-F]{1,4}:){0,5}|:)" + r"((:[0-9A-F]{1,4}){1,5}:|:)|::(?:[A-F0-9]{1,4}:){5})" + r"(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}" + r"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])|(?:[A-F0-9]{1,4}:){7}" + r"[A-F0-9]{1,4}|(?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4}$)" + r"(([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:)|(?:[A-F0-9]{1,4}:){7}" + r":|:(:[A-F0-9]{1,4}){7})$" +) +_ipv4_regex = re.compile(_ipv4_pattern) +_ipv6_regex = re.compile(_ipv6_pattern, flags=re.IGNORECASE) +_ipv4_regexb = re.compile(_ipv4_pattern.encode("ascii")) +_ipv6_regexb = re.compile(_ipv6_pattern.encode("ascii"), flags=re.IGNORECASE) + + +def _is_ip_address( + regex: Pattern[str], regexb: Pattern[bytes], host: Optional[Union[str, bytes]] +) -> bool: + if host is None: + return False + if isinstance(host, str): + return bool(regex.match(host)) + elif isinstance(host, (bytes, bytearray, memoryview)): + return bool(regexb.match(host)) + else: + raise TypeError("{} [{}] is not a str or bytes".format(host, type(host))) + + +is_ipv4_address = functools.partial(_is_ip_address, _ipv4_regex, _ipv4_regexb) +is_ipv6_address = functools.partial(_is_ip_address, _ipv6_regex, _ipv6_regexb) + + +def is_ip_address(host: Optional[Union[str, bytes, bytearray, memoryview]]) -> bool: + return is_ipv4_address(host) or is_ipv6_address(host) + + +def next_whole_second() -> datetime.datetime: + """Return current time rounded up to the next whole second.""" + return datetime.datetime.now(datetime.timezone.utc).replace( + microsecond=0 + ) + datetime.timedelta(seconds=0) + + +_cached_current_datetime = None # type: Optional[int] +_cached_formatted_datetime = "" + + +def rfc822_formatted_time() -> str: + global _cached_current_datetime + global _cached_formatted_datetime + + now = int(time.time()) + if now != _cached_current_datetime: + # Weekday and month names for HTTP date/time formatting; + # always English! + # Tuples are constants stored in codeobject! + _weekdayname = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun") + _monthname = ( + "", # Dummy so we can use 1-based month numbers + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", + ) + + year, month, day, hh, mm, ss, wd, *tail = time.gmtime(now) + _cached_formatted_datetime = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( + _weekdayname[wd], + day, + _monthname[month], + year, + hh, + mm, + ss, + ) + _cached_current_datetime = now + return _cached_formatted_datetime + + +def _weakref_handle(info): # type: ignore + ref, name = info + ob = ref() + if ob is not None: + with suppress(Exception): + getattr(ob, name)() + + +def weakref_handle(ob, name, timeout, loop): # type: ignore + if timeout is not None and timeout > 0: + when = loop.time() + timeout + if timeout >= 5: + when = ceil(when) + + return loop.call_at(when, _weakref_handle, (weakref.ref(ob), name)) + + +def call_later(cb, timeout, loop): # type: ignore + if timeout is not None and timeout > 0: + when = loop.time() + timeout + if timeout > 5: + when = ceil(when) + return loop.call_at(when, cb) + + +class TimeoutHandle: + """ Timeout handle """ + + def __init__( + self, loop: asyncio.AbstractEventLoop, timeout: Optional[float] + ) -> None: + self._timeout = timeout + self._loop = loop + self._callbacks = ( + [] + ) # type: List[Tuple[Callable[..., None], Tuple[Any, ...], Dict[str, Any]]] + + def register( + self, callback: Callable[..., None], *args: Any, **kwargs: Any + ) -> None: + self._callbacks.append((callback, args, kwargs)) + + def close(self) -> None: + self._callbacks.clear() + + def start(self) -> Optional[asyncio.Handle]: + timeout = self._timeout + if timeout is not None and timeout > 0: + when = self._loop.time() + timeout + if timeout >= 5: + when = ceil(when) + return self._loop.call_at(when, self.__call__) + else: + return None + + def timer(self) -> "BaseTimerContext": + if self._timeout is not None and self._timeout > 0: + timer = TimerContext(self._loop) + self.register(timer.timeout) + return timer + else: + return TimerNoop() + + def __call__(self) -> None: + for cb, args, kwargs in self._callbacks: + with suppress(Exception): + cb(*args, **kwargs) + + self._callbacks.clear() + + +class BaseTimerContext(ContextManager["BaseTimerContext"]): + pass + + +class TimerNoop(BaseTimerContext): + def __enter__(self) -> BaseTimerContext: + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + return + + +class TimerContext(BaseTimerContext): + """ Low resolution timeout context manager """ + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + self._loop = loop + self._tasks = [] # type: List[asyncio.Task[Any]] + self._cancelled = False + + def __enter__(self) -> BaseTimerContext: + task = current_task(loop=self._loop) + + if task is None: + raise RuntimeError( + "Timeout context manager should be used " "inside a task" + ) + + if self._cancelled: + task.cancel() + raise asyncio.TimeoutError from None + + self._tasks.append(task) + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> Optional[bool]: + if self._tasks: + self._tasks.pop() + + if exc_type is asyncio.CancelledError and self._cancelled: + raise asyncio.TimeoutError from None + return None + + def timeout(self) -> None: + if not self._cancelled: + for task in set(self._tasks): + task.cancel() + + self._cancelled = True + + +class CeilTimeout(async_timeout.timeout): + def __enter__(self) -> async_timeout.timeout: + if self._timeout is not None: + self._task = current_task(loop=self._loop) + if self._task is None: + raise RuntimeError( + "Timeout context manager should be used inside a task" + ) + now = self._loop.time() + delay = self._timeout + when = now + delay + if delay > 5: + when = ceil(when) + self._cancel_handler = self._loop.call_at(when, self._cancel_task) + return self + + +class HeadersMixin: + + ATTRS = frozenset(["_content_type", "_content_dict", "_stored_content_type"]) + + _content_type = None # type: Optional[str] + _content_dict = None # type: Optional[Dict[str, str]] + _stored_content_type = sentinel + + def _parse_content_type(self, raw: str) -> None: + self._stored_content_type = raw + if raw is None: + # default value according to RFC 2616 + self._content_type = "application/octet-stream" + self._content_dict = {} + else: + self._content_type, self._content_dict = cgi.parse_header(raw) + + @property + def content_type(self) -> str: + """The value of content part for Content-Type HTTP header.""" + raw = self._headers.get(hdrs.CONTENT_TYPE) # type: ignore + if self._stored_content_type != raw: + self._parse_content_type(raw) + return self._content_type # type: ignore + + @property + def charset(self) -> Optional[str]: + """The value of charset part for Content-Type HTTP header.""" + raw = self._headers.get(hdrs.CONTENT_TYPE) # type: ignore + if self._stored_content_type != raw: + self._parse_content_type(raw) + return self._content_dict.get("charset") # type: ignore + + @property + def content_length(self) -> Optional[int]: + """The value of Content-Length HTTP header.""" + content_length = self._headers.get(hdrs.CONTENT_LENGTH) # type: ignore + + if content_length is not None: + return int(content_length) + else: + return None + + +def set_result(fut: "asyncio.Future[_T]", result: _T) -> None: + if not fut.done(): + fut.set_result(result) + + +def set_exception(fut: "asyncio.Future[_T]", exc: BaseException) -> None: + if not fut.done(): + fut.set_exception(exc) + + +class ChainMapProxy(Mapping[str, Any]): + __slots__ = ("_maps",) + + def __init__(self, maps: Iterable[Mapping[str, Any]]) -> None: + self._maps = tuple(maps) + + def __init_subclass__(cls) -> None: + raise TypeError( + "Inheritance class {} from ChainMapProxy " + "is forbidden".format(cls.__name__) + ) + + def __getitem__(self, key: str) -> Any: + for mapping in self._maps: + try: + return mapping[key] + except KeyError: + pass + raise KeyError(key) + + def get(self, key: str, default: Any = None) -> Any: + return self[key] if key in self else default + + def __len__(self) -> int: + # reuses stored hash values if possible + return len(set().union(*self._maps)) # type: ignore + + def __iter__(self) -> Iterator[str]: + d = {} # type: Dict[str, Any] + for mapping in reversed(self._maps): + # reuses stored hash values if possible + d.update(mapping) + return iter(d) + + def __contains__(self, key: object) -> bool: + return any(key in m for m in self._maps) + + def __bool__(self) -> bool: + return any(self._maps) + + def __repr__(self) -> str: + content = ", ".join(map(repr, self._maps)) + return f"ChainMapProxy({content})" diff --git a/dist/ba_data/python-site-packages/aiohttp/http.py b/dist/ba_data/python-site-packages/aiohttp/http.py new file mode 100644 index 0000000..415ffbf --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/http.py @@ -0,0 +1,72 @@ +import http.server +import sys +from typing import Mapping, Tuple + +from . import __version__ +from .http_exceptions import HttpProcessingError as HttpProcessingError +from .http_parser import ( + HeadersParser as HeadersParser, + HttpParser as HttpParser, + HttpRequestParser as HttpRequestParser, + HttpResponseParser as HttpResponseParser, + RawRequestMessage as RawRequestMessage, + RawResponseMessage as RawResponseMessage, +) +from .http_websocket import ( + WS_CLOSED_MESSAGE as WS_CLOSED_MESSAGE, + WS_CLOSING_MESSAGE as WS_CLOSING_MESSAGE, + WS_KEY as WS_KEY, + WebSocketError as WebSocketError, + WebSocketReader as WebSocketReader, + WebSocketWriter as WebSocketWriter, + WSCloseCode as WSCloseCode, + WSMessage as WSMessage, + WSMsgType as WSMsgType, + ws_ext_gen as ws_ext_gen, + ws_ext_parse as ws_ext_parse, +) +from .http_writer import ( + HttpVersion as HttpVersion, + HttpVersion10 as HttpVersion10, + HttpVersion11 as HttpVersion11, + StreamWriter as StreamWriter, +) + +__all__ = ( + "HttpProcessingError", + "RESPONSES", + "SERVER_SOFTWARE", + # .http_writer + "StreamWriter", + "HttpVersion", + "HttpVersion10", + "HttpVersion11", + # .http_parser + "HeadersParser", + "HttpParser", + "HttpRequestParser", + "HttpResponseParser", + "RawRequestMessage", + "RawResponseMessage", + # .http_websocket + "WS_CLOSED_MESSAGE", + "WS_CLOSING_MESSAGE", + "WS_KEY", + "WebSocketReader", + "WebSocketWriter", + "ws_ext_gen", + "ws_ext_parse", + "WSMessage", + "WebSocketError", + "WSMsgType", + "WSCloseCode", +) + + +SERVER_SOFTWARE = "Python/{0[0]}.{0[1]} aiohttp/{1}".format( + sys.version_info, __version__ +) # type: str + +RESPONSES = ( + http.server.BaseHTTPRequestHandler.responses +) # type: Mapping[int, Tuple[str, str]] diff --git a/dist/ba_data/python-site-packages/aiohttp/http_exceptions.py b/dist/ba_data/python-site-packages/aiohttp/http_exceptions.py new file mode 100644 index 0000000..c885f80 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/http_exceptions.py @@ -0,0 +1,105 @@ +"""Low-level http related exceptions.""" + + +from typing import Optional, Union + +from .typedefs import _CIMultiDict + +__all__ = ("HttpProcessingError",) + + +class HttpProcessingError(Exception): + """HTTP error. + + Shortcut for raising HTTP errors with custom code, message and headers. + + code: HTTP Error code. + message: (optional) Error message. + headers: (optional) Headers to be sent in response, a list of pairs + """ + + code = 0 + message = "" + headers = None + + def __init__( + self, + *, + code: Optional[int] = None, + message: str = "", + headers: Optional[_CIMultiDict] = None, + ) -> None: + if code is not None: + self.code = code + self.headers = headers + self.message = message + + def __str__(self) -> str: + return f"{self.code}, message={self.message!r}" + + def __repr__(self) -> str: + return f"<{self.__class__.__name__}: {self}>" + + +class BadHttpMessage(HttpProcessingError): + + code = 400 + message = "Bad Request" + + def __init__(self, message: str, *, headers: Optional[_CIMultiDict] = None) -> None: + super().__init__(message=message, headers=headers) + self.args = (message,) + + +class HttpBadRequest(BadHttpMessage): + + code = 400 + message = "Bad Request" + + +class PayloadEncodingError(BadHttpMessage): + """Base class for payload errors""" + + +class ContentEncodingError(PayloadEncodingError): + """Content encoding error.""" + + +class TransferEncodingError(PayloadEncodingError): + """transfer encoding error.""" + + +class ContentLengthError(PayloadEncodingError): + """Not enough data for satisfy content length header.""" + + +class LineTooLong(BadHttpMessage): + def __init__( + self, line: str, limit: str = "Unknown", actual_size: str = "Unknown" + ) -> None: + super().__init__( + f"Got more than {limit} bytes ({actual_size}) when reading {line}." + ) + self.args = (line, limit, actual_size) + + +class InvalidHeader(BadHttpMessage): + def __init__(self, hdr: Union[bytes, str]) -> None: + if isinstance(hdr, bytes): + hdr = hdr.decode("utf-8", "surrogateescape") + super().__init__(f"Invalid HTTP Header: {hdr}") + self.hdr = hdr + self.args = (hdr,) + + +class BadStatusLine(BadHttpMessage): + def __init__(self, line: str = "") -> None: + if not isinstance(line, str): + line = repr(line) + super().__init__(f"Bad status line {line!r}") + self.args = (line,) + self.line = line + + +class InvalidURLError(BadHttpMessage): + pass diff --git a/dist/ba_data/python-site-packages/aiohttp/http_parser.py b/dist/ba_data/python-site-packages/aiohttp/http_parser.py new file mode 100644 index 0000000..71ba815 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/http_parser.py @@ -0,0 +1,901 @@ +import abc +import asyncio +import collections +import re +import string +import zlib +from enum import IntEnum +from typing import Any, List, Optional, Tuple, Type, Union + +from multidict import CIMultiDict, CIMultiDictProxy, istr +from yarl import URL + +from . import hdrs +from .base_protocol import BaseProtocol +from .helpers import NO_EXTENSIONS, BaseTimerContext +from .http_exceptions import ( + BadStatusLine, + ContentEncodingError, + ContentLengthError, + InvalidHeader, + LineTooLong, + TransferEncodingError, +) +from .http_writer import HttpVersion, HttpVersion10 +from .log import internal_logger +from .streams import EMPTY_PAYLOAD, StreamReader +from .typedefs import RawHeaders + +try: + import brotli + + HAS_BROTLI = True +except ImportError: # pragma: no cover + HAS_BROTLI = False + + +__all__ = ( + "HeadersParser", + "HttpParser", + "HttpRequestParser", + "HttpResponseParser", + "RawRequestMessage", + "RawResponseMessage", +) + +ASCIISET = set(string.printable) + +# See https://tools.ietf.org/html/rfc7230#section-3.1.1 +# and https://tools.ietf.org/html/rfc7230#appendix-B +# +# method = token +# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / +# "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA +# token = 1*tchar +METHRE = re.compile(r"[!#$%&'*+\-.^_`|~0-9A-Za-z]+") +VERSRE = re.compile(r"HTTP/(\d+).(\d+)") +HDRRE = re.compile(rb"[\x00-\x1F\x7F()<>@,;:\[\]={} \t\\\\\"]") + +RawRequestMessage = collections.namedtuple( + "RawRequestMessage", + [ + "method", + "path", + "version", + "headers", + "raw_headers", + "should_close", + "compression", + "upgrade", + "chunked", + "url", + ], +) + +RawResponseMessage = collections.namedtuple( + "RawResponseMessage", + [ + "version", + "code", + "reason", + "headers", + "raw_headers", + "should_close", + "compression", + "upgrade", + "chunked", + ], +) + + +class ParseState(IntEnum): + + PARSE_NONE = 0 + PARSE_LENGTH = 1 + PARSE_CHUNKED = 2 + PARSE_UNTIL_EOF = 3 + + +class ChunkState(IntEnum): + PARSE_CHUNKED_SIZE = 0 + PARSE_CHUNKED_CHUNK = 1 + PARSE_CHUNKED_CHUNK_EOF = 2 + PARSE_MAYBE_TRAILERS = 3 + PARSE_TRAILERS = 4 + + +class HeadersParser: + def __init__( + self, + max_line_size: int = 8190, + max_headers: int = 32768, + max_field_size: int = 8190, + ) -> None: + self.max_line_size = max_line_size + self.max_headers = max_headers + self.max_field_size = max_field_size + + def parse_headers( + self, lines: List[bytes] + ) -> Tuple["CIMultiDictProxy[str]", RawHeaders]: + headers = CIMultiDict() # type: CIMultiDict[str] + raw_headers = [] + + lines_idx = 1 + line = lines[1] + line_count = len(lines) + + while line: + # Parse initial header name : value pair. + try: + bname, bvalue = line.split(b":", 1) + except ValueError: + raise InvalidHeader(line) from None + + bname = bname.strip(b" \t") + bvalue = bvalue.lstrip() + if HDRRE.search(bname): + raise InvalidHeader(bname) + if len(bname) > self.max_field_size: + raise LineTooLong( + "request header name {}".format( + bname.decode("utf8", "xmlcharrefreplace") + ), + str(self.max_field_size), + str(len(bname)), + ) + + header_length = len(bvalue) + + # next line + lines_idx += 1 + line = lines[lines_idx] + + # consume continuation lines + continuation = line and line[0] in (32, 9) # (' ', '\t') + + if continuation: + bvalue_lst = [bvalue] + while continuation: + header_length += len(line) + if header_length > self.max_field_size: + raise LineTooLong( + "request header field {}".format( + bname.decode("utf8", "xmlcharrefreplace") + ), + str(self.max_field_size), + str(header_length), + ) + bvalue_lst.append(line) + + # next line + lines_idx += 1 + if lines_idx < line_count: + line = lines[lines_idx] + if line: + continuation = line[0] in (32, 9) # (' ', '\t') + else: + line = b"" + break + bvalue = b"".join(bvalue_lst) + else: + if header_length > self.max_field_size: + raise LineTooLong( + "request header field {}".format( + bname.decode("utf8", "xmlcharrefreplace") + ), + str(self.max_field_size), + str(header_length), + ) + + bvalue = bvalue.strip() + name = bname.decode("utf-8", "surrogateescape") + value = bvalue.decode("utf-8", "surrogateescape") + + headers.add(name, value) + raw_headers.append((bname, bvalue)) + + return (CIMultiDictProxy(headers), tuple(raw_headers)) + + +class HttpParser(abc.ABC): + def __init__( + self, + protocol: Optional[BaseProtocol] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + limit: int = 2 ** 16, + max_line_size: int = 8190, + max_headers: int = 32768, + max_field_size: int = 8190, + timer: Optional[BaseTimerContext] = None, + code: Optional[int] = None, + method: Optional[str] = None, + readall: bool = False, + payload_exception: Optional[Type[BaseException]] = None, + response_with_body: bool = True, + read_until_eof: bool = False, + auto_decompress: bool = True, + ) -> None: + self.protocol = protocol + self.loop = loop + self.max_line_size = max_line_size + self.max_headers = max_headers + self.max_field_size = max_field_size + self.timer = timer + self.code = code + self.method = method + self.readall = readall + self.payload_exception = payload_exception + self.response_with_body = response_with_body + self.read_until_eof = read_until_eof + + self._lines = [] # type: List[bytes] + self._tail = b"" + self._upgraded = False + self._payload = None + self._payload_parser = None # type: Optional[HttpPayloadParser] + self._auto_decompress = auto_decompress + self._limit = limit + self._headers_parser = HeadersParser(max_line_size, max_headers, max_field_size) + + @abc.abstractmethod + def parse_message(self, lines: List[bytes]) -> Any: + pass + + def feed_eof(self) -> Any: + if self._payload_parser is not None: + self._payload_parser.feed_eof() + self._payload_parser = None + else: + # try to extract partial message + if self._tail: + self._lines.append(self._tail) + + if self._lines: + if self._lines[-1] != "\r\n": + self._lines.append(b"") + try: + return self.parse_message(self._lines) + except Exception: + return None + + def feed_data( + self, + data: bytes, + SEP: bytes = b"\r\n", + EMPTY: bytes = b"", + CONTENT_LENGTH: istr = hdrs.CONTENT_LENGTH, + METH_CONNECT: str = hdrs.METH_CONNECT, + SEC_WEBSOCKET_KEY1: istr = hdrs.SEC_WEBSOCKET_KEY1, + ) -> Tuple[List[Any], bool, bytes]: + + messages = [] + + if self._tail: + data, self._tail = self._tail + data, b"" + + data_len = len(data) + start_pos = 0 + loop = self.loop + + while start_pos < data_len: + + # read HTTP message (request/response line + headers), \r\n\r\n + # and split by lines + if self._payload_parser is None and not self._upgraded: + pos = data.find(SEP, start_pos) + # consume \r\n + if pos == start_pos and not self._lines: + start_pos = pos + 2 + continue + + if pos >= start_pos: + # line found + self._lines.append(data[start_pos:pos]) + start_pos = pos + 2 + + # \r\n\r\n found + if self._lines[-1] == EMPTY: + try: + msg = self.parse_message(self._lines) + finally: + self._lines.clear() + + # payload length + length = msg.headers.get(CONTENT_LENGTH) + if length is not None: + try: + length = int(length) + except ValueError: + raise InvalidHeader(CONTENT_LENGTH) + if length < 0: + raise InvalidHeader(CONTENT_LENGTH) + + # do not support old websocket spec + if SEC_WEBSOCKET_KEY1 in msg.headers: + raise InvalidHeader(SEC_WEBSOCKET_KEY1) + + self._upgraded = msg.upgrade + + method = getattr(msg, "method", self.method) + + assert self.protocol is not None + # calculate payload + if ( + (length is not None and length > 0) + or msg.chunked + and not msg.upgrade + ): + payload = StreamReader( + self.protocol, + timer=self.timer, + loop=loop, + limit=self._limit, + ) + payload_parser = HttpPayloadParser( + payload, + length=length, + chunked=msg.chunked, + method=method, + compression=msg.compression, + code=self.code, + readall=self.readall, + response_with_body=self.response_with_body, + auto_decompress=self._auto_decompress, + ) + if not payload_parser.done: + self._payload_parser = payload_parser + elif method == METH_CONNECT: + payload = StreamReader( + self.protocol, + timer=self.timer, + loop=loop, + limit=self._limit, + ) + self._upgraded = True + self._payload_parser = HttpPayloadParser( + payload, + method=msg.method, + compression=msg.compression, + readall=True, + auto_decompress=self._auto_decompress, + ) + else: + if ( + getattr(msg, "code", 100) >= 199 + and length is None + and self.read_until_eof + ): + payload = StreamReader( + self.protocol, + timer=self.timer, + loop=loop, + limit=self._limit, + ) + payload_parser = HttpPayloadParser( + payload, + length=length, + chunked=msg.chunked, + method=method, + compression=msg.compression, + code=self.code, + readall=True, + response_with_body=self.response_with_body, + auto_decompress=self._auto_decompress, + ) + if not payload_parser.done: + self._payload_parser = payload_parser + else: + payload = EMPTY_PAYLOAD # type: ignore + + messages.append((msg, payload)) + else: + self._tail = data[start_pos:] + data = EMPTY + break + + # no parser, just store + elif self._payload_parser is None and self._upgraded: + assert not self._lines + break + + # feed payload + elif data and start_pos < data_len: + assert not self._lines + assert self._payload_parser is not None + try: + eof, data = self._payload_parser.feed_data(data[start_pos:]) + except BaseException as exc: + if self.payload_exception is not None: + self._payload_parser.payload.set_exception( + self.payload_exception(str(exc)) + ) + else: + self._payload_parser.payload.set_exception(exc) + + eof = True + data = b"" + + if eof: + start_pos = 0 + data_len = len(data) + self._payload_parser = None + continue + else: + break + + if data and start_pos < data_len: + data = data[start_pos:] + else: + data = EMPTY + + return messages, self._upgraded, data + + def parse_headers( + self, lines: List[bytes] + ) -> Tuple[ + "CIMultiDictProxy[str]", RawHeaders, Optional[bool], Optional[str], bool, bool + ]: + """Parses RFC 5322 headers from a stream. + + Line continuations are supported. Returns list of header name + and value pairs. Header name is in upper case. + """ + headers, raw_headers = self._headers_parser.parse_headers(lines) + close_conn = None + encoding = None + upgrade = False + chunked = False + + # keep-alive + conn = headers.get(hdrs.CONNECTION) + if conn: + v = conn.lower() + if v == "close": + close_conn = True + elif v == "keep-alive": + close_conn = False + elif v == "upgrade": + upgrade = True + + # encoding + enc = headers.get(hdrs.CONTENT_ENCODING) + if enc: + enc = enc.lower() + if enc in ("gzip", "deflate", "br"): + encoding = enc + + # chunking + te = headers.get(hdrs.TRANSFER_ENCODING) + if te and "chunked" in te.lower(): + chunked = True + + return (headers, raw_headers, close_conn, encoding, upgrade, chunked) + + def set_upgraded(self, val: bool) -> None: + """Set connection upgraded (to websocket) mode. + :param bool val: new state. + """ + self._upgraded = val + + +class HttpRequestParser(HttpParser): + """Read request status line. Exception .http_exceptions.BadStatusLine + could be raised in case of any errors in status line. + Returns RawRequestMessage. + """ + + def parse_message(self, lines: List[bytes]) -> Any: + # request line + line = lines[0].decode("utf-8", "surrogateescape") + try: + method, path, version = line.split(None, 2) + except ValueError: + raise BadStatusLine(line) from None + + if len(path) > self.max_line_size: + raise LineTooLong( + "Status line is too long", str(self.max_line_size), str(len(path)) + ) + + path_part, _hash_separator, url_fragment = path.partition("#") + path_part, _question_mark_separator, qs_part = path_part.partition("?") + + # method + if not METHRE.match(method): + raise BadStatusLine(method) + + # version + try: + if version.startswith("HTTP/"): + n1, n2 = version[5:].split(".", 1) + version_o = HttpVersion(int(n1), int(n2)) + else: + raise BadStatusLine(version) + except Exception: + raise BadStatusLine(version) + + # read headers + ( + headers, + raw_headers, + close, + compression, + upgrade, + chunked, + ) = self.parse_headers(lines) + + if close is None: # then the headers weren't set in the request + if version_o <= HttpVersion10: # HTTP 1.0 must asks to not close + close = True + else: # HTTP 1.1 must ask to close. + close = False + + return RawRequestMessage( + method, + path, + version_o, + headers, + raw_headers, + close, + compression, + upgrade, + chunked, + # NOTE: `yarl.URL.build()` is used to mimic what the Cython-based + # NOTE: parser does, otherwise it results into the same + # NOTE: HTTP Request-Line input producing different + # NOTE: `yarl.URL()` objects + URL.build( + path=path_part, + query_string=qs_part, + fragment=url_fragment, + encoded=True, + ), + ) + + +class HttpResponseParser(HttpParser): + """Read response status line and headers. + + BadStatusLine could be raised in case of any errors in status line. + Returns RawResponseMessage""" + + def parse_message(self, lines: List[bytes]) -> Any: + line = lines[0].decode("utf-8", "surrogateescape") + try: + version, status = line.split(None, 1) + except ValueError: + raise BadStatusLine(line) from None + + try: + status, reason = status.split(None, 1) + except ValueError: + reason = "" + + if len(reason) > self.max_line_size: + raise LineTooLong( + "Status line is too long", str(self.max_line_size), str(len(reason)) + ) + + # version + match = VERSRE.match(version) + if match is None: + raise BadStatusLine(line) + version_o = HttpVersion(int(match.group(1)), int(match.group(2))) + + # The status code is a three-digit number + try: + status_i = int(status) + except ValueError: + raise BadStatusLine(line) from None + + if status_i > 999: + raise BadStatusLine(line) + + # read headers + ( + headers, + raw_headers, + close, + compression, + upgrade, + chunked, + ) = self.parse_headers(lines) + + if close is None: + close = version_o <= HttpVersion10 + + return RawResponseMessage( + version_o, + status_i, + reason.strip(), + headers, + raw_headers, + close, + compression, + upgrade, + chunked, + ) + + +class HttpPayloadParser: + def __init__( + self, + payload: StreamReader, + length: Optional[int] = None, + chunked: bool = False, + compression: Optional[str] = None, + code: Optional[int] = None, + method: Optional[str] = None, + readall: bool = False, + response_with_body: bool = True, + auto_decompress: bool = True, + ) -> None: + self._length = 0 + self._type = ParseState.PARSE_NONE + self._chunk = ChunkState.PARSE_CHUNKED_SIZE + self._chunk_size = 0 + self._chunk_tail = b"" + self._auto_decompress = auto_decompress + self.done = False + + # payload decompression wrapper + if response_with_body and compression and self._auto_decompress: + real_payload = DeflateBuffer( + payload, compression + ) # type: Union[StreamReader, DeflateBuffer] + else: + real_payload = payload + + # payload parser + if not response_with_body: + # don't parse payload if it's not expected to be received + self._type = ParseState.PARSE_NONE + real_payload.feed_eof() + self.done = True + + elif chunked: + self._type = ParseState.PARSE_CHUNKED + elif length is not None: + self._type = ParseState.PARSE_LENGTH + self._length = length + if self._length == 0: + real_payload.feed_eof() + self.done = True + else: + if readall and code != 204: + self._type = ParseState.PARSE_UNTIL_EOF + elif method in ("PUT", "POST"): + internal_logger.warning( # pragma: no cover + "Content-Length or Transfer-Encoding header is required" + ) + self._type = ParseState.PARSE_NONE + real_payload.feed_eof() + self.done = True + + self.payload = real_payload + + def feed_eof(self) -> None: + if self._type == ParseState.PARSE_UNTIL_EOF: + self.payload.feed_eof() + elif self._type == ParseState.PARSE_LENGTH: + raise ContentLengthError( + "Not enough data for satisfy content length header." + ) + elif self._type == ParseState.PARSE_CHUNKED: + raise TransferEncodingError( + "Not enough data for satisfy transfer length header." + ) + + def feed_data( + self, chunk: bytes, SEP: bytes = b"\r\n", CHUNK_EXT: bytes = b";" + ) -> Tuple[bool, bytes]: + # Read specified amount of bytes + if self._type == ParseState.PARSE_LENGTH: + required = self._length + chunk_len = len(chunk) + + if required >= chunk_len: + self._length = required - chunk_len + self.payload.feed_data(chunk, chunk_len) + if self._length == 0: + self.payload.feed_eof() + return True, b"" + else: + self._length = 0 + self.payload.feed_data(chunk[:required], required) + self.payload.feed_eof() + return True, chunk[required:] + + # Chunked transfer encoding parser + elif self._type == ParseState.PARSE_CHUNKED: + if self._chunk_tail: + chunk = self._chunk_tail + chunk + self._chunk_tail = b"" + + while chunk: + + # read next chunk size + if self._chunk == ChunkState.PARSE_CHUNKED_SIZE: + pos = chunk.find(SEP) + if pos >= 0: + i = chunk.find(CHUNK_EXT, 0, pos) + if i >= 0: + size_b = chunk[:i] # strip chunk-extensions + else: + size_b = chunk[:pos] + + try: + size = int(bytes(size_b), 16) + except ValueError: + exc = TransferEncodingError( + chunk[:pos].decode("ascii", "surrogateescape") + ) + self.payload.set_exception(exc) + raise exc from None + + chunk = chunk[pos + 2 :] + if size == 0: # eof marker + self._chunk = ChunkState.PARSE_MAYBE_TRAILERS + else: + self._chunk = ChunkState.PARSE_CHUNKED_CHUNK + self._chunk_size = size + self.payload.begin_http_chunk_receiving() + else: + self._chunk_tail = chunk + return False, b"" + + # read chunk and feed buffer + if self._chunk == ChunkState.PARSE_CHUNKED_CHUNK: + required = self._chunk_size + chunk_len = len(chunk) + + if required > chunk_len: + self._chunk_size = required - chunk_len + self.payload.feed_data(chunk, chunk_len) + return False, b"" + else: + self._chunk_size = 0 + self.payload.feed_data(chunk[:required], required) + chunk = chunk[required:] + self._chunk = ChunkState.PARSE_CHUNKED_CHUNK_EOF + self.payload.end_http_chunk_receiving() + + # toss the CRLF at the end of the chunk + if self._chunk == ChunkState.PARSE_CHUNKED_CHUNK_EOF: + if chunk[:2] == SEP: + chunk = chunk[2:] + self._chunk = ChunkState.PARSE_CHUNKED_SIZE + else: + self._chunk_tail = chunk + return False, b"" + + # if stream does not contain trailer, after 0\r\n + # we should get another \r\n otherwise + # trailers needs to be skiped until \r\n\r\n + if self._chunk == ChunkState.PARSE_MAYBE_TRAILERS: + head = chunk[:2] + if head == SEP: + # end of stream + self.payload.feed_eof() + return True, chunk[2:] + # Both CR and LF, or only LF may not be received yet. It is + # expected that CRLF or LF will be shown at the very first + # byte next time, otherwise trailers should come. The last + # CRLF which marks the end of response might not be + # contained in the same TCP segment which delivered the + # size indicator. + if not head: + return False, b"" + if head == SEP[:1]: + self._chunk_tail = head + return False, b"" + self._chunk = ChunkState.PARSE_TRAILERS + + # read and discard trailer up to the CRLF terminator + if self._chunk == ChunkState.PARSE_TRAILERS: + pos = chunk.find(SEP) + if pos >= 0: + chunk = chunk[pos + 2 :] + self._chunk = ChunkState.PARSE_MAYBE_TRAILERS + else: + self._chunk_tail = chunk + return False, b"" + + # Read all bytes until eof + elif self._type == ParseState.PARSE_UNTIL_EOF: + self.payload.feed_data(chunk, len(chunk)) + + return False, b"" + + +class DeflateBuffer: + """DeflateStream decompress stream and feed data into specified stream.""" + + def __init__(self, out: StreamReader, encoding: Optional[str]) -> None: + self.out = out + self.size = 0 + self.encoding = encoding + self._started_decoding = False + + if encoding == "br": + if not HAS_BROTLI: # pragma: no cover + raise ContentEncodingError( + "Can not decode content-encoding: brotli (br). " + "Please install `brotlipy`" + ) + self.decompressor = brotli.Decompressor() + else: + zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else zlib.MAX_WBITS + self.decompressor = zlib.decompressobj(wbits=zlib_mode) + + def set_exception(self, exc: BaseException) -> None: + self.out.set_exception(exc) + + def feed_data(self, chunk: bytes, size: int) -> None: + if not size: + return + + self.size += size + + # RFC1950 + # bits 0..3 = CM = 0b1000 = 8 = "deflate" + # bits 4..7 = CINFO = 1..7 = windows size. + if ( + not self._started_decoding + and self.encoding == "deflate" + and chunk[0] & 0xF != 8 + ): + # Change the decoder to decompress incorrectly compressed data + # Actually we should issue a warning about non-RFC-compliant data. + self.decompressor = zlib.decompressobj(wbits=-zlib.MAX_WBITS) + + try: + chunk = self.decompressor.decompress(chunk) + except Exception: + raise ContentEncodingError( + "Can not decode content-encoding: %s" % self.encoding + ) + + self._started_decoding = True + + if chunk: + self.out.feed_data(chunk, len(chunk)) + + def feed_eof(self) -> None: + chunk = self.decompressor.flush() + + if chunk or self.size > 0: + self.out.feed_data(chunk, len(chunk)) + if self.encoding == "deflate" and not self.decompressor.eof: + raise ContentEncodingError("deflate") + + self.out.feed_eof() + + def begin_http_chunk_receiving(self) -> None: + self.out.begin_http_chunk_receiving() + + def end_http_chunk_receiving(self) -> None: + self.out.end_http_chunk_receiving() + + +HttpRequestParserPy = HttpRequestParser +HttpResponseParserPy = HttpResponseParser +RawRequestMessagePy = RawRequestMessage +RawResponseMessagePy = RawResponseMessage + +try: + if not NO_EXTENSIONS: + from ._http_parser import ( # type: ignore + HttpRequestParser, + HttpResponseParser, + RawRequestMessage, + RawResponseMessage, + ) + + HttpRequestParserC = HttpRequestParser + HttpResponseParserC = HttpResponseParser + RawRequestMessageC = RawRequestMessage + RawResponseMessageC = RawResponseMessage +except ImportError: # pragma: no cover + pass diff --git a/dist/ba_data/python-site-packages/aiohttp/http_websocket.py b/dist/ba_data/python-site-packages/aiohttp/http_websocket.py new file mode 100644 index 0000000..5cdaeea --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/http_websocket.py @@ -0,0 +1,698 @@ +"""WebSocket protocol versions 13 and 8.""" + +import asyncio +import collections +import json +import random +import re +import sys +import zlib +from enum import IntEnum +from struct import Struct +from typing import Any, Callable, List, Optional, Tuple, Union + +from .base_protocol import BaseProtocol +from .helpers import NO_EXTENSIONS +from .streams import DataQueue + +__all__ = ( + "WS_CLOSED_MESSAGE", + "WS_CLOSING_MESSAGE", + "WS_KEY", + "WebSocketReader", + "WebSocketWriter", + "WSMessage", + "WebSocketError", + "WSMsgType", + "WSCloseCode", +) + + +class WSCloseCode(IntEnum): + OK = 1000 + GOING_AWAY = 1001 + PROTOCOL_ERROR = 1002 + UNSUPPORTED_DATA = 1003 + INVALID_TEXT = 1007 + POLICY_VIOLATION = 1008 + MESSAGE_TOO_BIG = 1009 + MANDATORY_EXTENSION = 1010 + INTERNAL_ERROR = 1011 + SERVICE_RESTART = 1012 + TRY_AGAIN_LATER = 1013 + + +ALLOWED_CLOSE_CODES = {int(i) for i in WSCloseCode} + + +class WSMsgType(IntEnum): + # websocket spec types + CONTINUATION = 0x0 + TEXT = 0x1 + BINARY = 0x2 + PING = 0x9 + PONG = 0xA + CLOSE = 0x8 + + # aiohttp specific types + CLOSING = 0x100 + CLOSED = 0x101 + ERROR = 0x102 + + text = TEXT + binary = BINARY + ping = PING + pong = PONG + close = CLOSE + closing = CLOSING + closed = CLOSED + error = ERROR + + +WS_KEY = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + + +UNPACK_LEN2 = Struct("!H").unpack_from +UNPACK_LEN3 = Struct("!Q").unpack_from +UNPACK_CLOSE_CODE = Struct("!H").unpack +PACK_LEN1 = Struct("!BB").pack +PACK_LEN2 = Struct("!BBH").pack +PACK_LEN3 = Struct("!BBQ").pack +PACK_CLOSE_CODE = Struct("!H").pack +MSG_SIZE = 2 ** 14 +DEFAULT_LIMIT = 2 ** 16 + + +_WSMessageBase = collections.namedtuple("_WSMessageBase", ["type", "data", "extra"]) + + +class WSMessage(_WSMessageBase): + def json(self, *, loads: Callable[[Any], Any] = json.loads) -> Any: + """Return parsed JSON data. + + .. versionadded:: 0.22 + """ + return loads(self.data) + + +WS_CLOSED_MESSAGE = WSMessage(WSMsgType.CLOSED, None, None) +WS_CLOSING_MESSAGE = WSMessage(WSMsgType.CLOSING, None, None) + + +class WebSocketError(Exception): + """WebSocket protocol parser error.""" + + def __init__(self, code: int, message: str) -> None: + self.code = code + super().__init__(code, message) + + def __str__(self) -> str: + return self.args[1] + + +class WSHandshakeError(Exception): + """WebSocket protocol handshake error.""" + + +native_byteorder = sys.byteorder + + +# Used by _websocket_mask_python +_XOR_TABLE = [bytes(a ^ b for a in range(256)) for b in range(256)] + + +def _websocket_mask_python(mask: bytes, data: bytearray) -> None: + """Websocket masking function. + + `mask` is a `bytes` object of length 4; `data` is a `bytearray` + object of any length. The contents of `data` are masked with `mask`, + as specified in section 5.3 of RFC 6455. + + Note that this function mutates the `data` argument. + + This pure-python implementation may be replaced by an optimized + version when available. + + """ + assert isinstance(data, bytearray), data + assert len(mask) == 4, mask + + if data: + a, b, c, d = (_XOR_TABLE[n] for n in mask) + data[::4] = data[::4].translate(a) + data[1::4] = data[1::4].translate(b) + data[2::4] = data[2::4].translate(c) + data[3::4] = data[3::4].translate(d) + + +if NO_EXTENSIONS: # pragma: no cover + _websocket_mask = _websocket_mask_python +else: + try: + from ._websocket import _websocket_mask_cython # type: ignore + + _websocket_mask = _websocket_mask_cython + except ImportError: # pragma: no cover + _websocket_mask = _websocket_mask_python + +_WS_DEFLATE_TRAILING = bytes([0x00, 0x00, 0xFF, 0xFF]) + + +_WS_EXT_RE = re.compile( + r"^(?:;\s*(?:" + r"(server_no_context_takeover)|" + r"(client_no_context_takeover)|" + r"(server_max_window_bits(?:=(\d+))?)|" + r"(client_max_window_bits(?:=(\d+))?)))*$" +) + +_WS_EXT_RE_SPLIT = re.compile(r"permessage-deflate([^,]+)?") + + +def ws_ext_parse(extstr: Optional[str], isserver: bool = False) -> Tuple[int, bool]: + if not extstr: + return 0, False + + compress = 0 + notakeover = False + for ext in _WS_EXT_RE_SPLIT.finditer(extstr): + defext = ext.group(1) + # Return compress = 15 when get `permessage-deflate` + if not defext: + compress = 15 + break + match = _WS_EXT_RE.match(defext) + if match: + compress = 15 + if isserver: + # Server never fail to detect compress handshake. + # Server does not need to send max wbit to client + if match.group(4): + compress = int(match.group(4)) + # Group3 must match if group4 matches + # Compress wbit 8 does not support in zlib + # If compress level not support, + # CONTINUE to next extension + if compress > 15 or compress < 9: + compress = 0 + continue + if match.group(1): + notakeover = True + # Ignore regex group 5 & 6 for client_max_window_bits + break + else: + if match.group(6): + compress = int(match.group(6)) + # Group5 must match if group6 matches + # Compress wbit 8 does not support in zlib + # If compress level not support, + # FAIL the parse progress + if compress > 15 or compress < 9: + raise WSHandshakeError("Invalid window size") + if match.group(2): + notakeover = True + # Ignore regex group 5 & 6 for client_max_window_bits + break + # Return Fail if client side and not match + elif not isserver: + raise WSHandshakeError("Extension for deflate not supported" + ext.group(1)) + + return compress, notakeover + + +def ws_ext_gen( + compress: int = 15, isserver: bool = False, server_notakeover: bool = False +) -> str: + # client_notakeover=False not used for server + # compress wbit 8 does not support in zlib + if compress < 9 or compress > 15: + raise ValueError( + "Compress wbits must between 9 and 15, " "zlib does not support wbits=8" + ) + enabledext = ["permessage-deflate"] + if not isserver: + enabledext.append("client_max_window_bits") + + if compress < 15: + enabledext.append("server_max_window_bits=" + str(compress)) + if server_notakeover: + enabledext.append("server_no_context_takeover") + # if client_notakeover: + # enabledext.append('client_no_context_takeover') + return "; ".join(enabledext) + + +class WSParserState(IntEnum): + READ_HEADER = 1 + READ_PAYLOAD_LENGTH = 2 + READ_PAYLOAD_MASK = 3 + READ_PAYLOAD = 4 + + +class WebSocketReader: + def __init__( + self, queue: DataQueue[WSMessage], max_msg_size: int, compress: bool = True + ) -> None: + self.queue = queue + self._max_msg_size = max_msg_size + + self._exc = None # type: Optional[BaseException] + self._partial = bytearray() + self._state = WSParserState.READ_HEADER + + self._opcode = None # type: Optional[int] + self._frame_fin = False + self._frame_opcode = None # type: Optional[int] + self._frame_payload = bytearray() + + self._tail = b"" + self._has_mask = False + self._frame_mask = None # type: Optional[bytes] + self._payload_length = 0 + self._payload_length_flag = 0 + self._compressed = None # type: Optional[bool] + self._decompressobj = None # type: Any # zlib.decompressobj actually + self._compress = compress + + def feed_eof(self) -> None: + self.queue.feed_eof() + + def feed_data(self, data: bytes) -> Tuple[bool, bytes]: + if self._exc: + return True, data + + try: + return self._feed_data(data) + except Exception as exc: + self._exc = exc + self.queue.set_exception(exc) + return True, b"" + + def _feed_data(self, data: bytes) -> Tuple[bool, bytes]: + for fin, opcode, payload, compressed in self.parse_frame(data): + if compressed and not self._decompressobj: + self._decompressobj = zlib.decompressobj(wbits=-zlib.MAX_WBITS) + if opcode == WSMsgType.CLOSE: + if len(payload) >= 2: + close_code = UNPACK_CLOSE_CODE(payload[:2])[0] + if close_code < 3000 and close_code not in ALLOWED_CLOSE_CODES: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + f"Invalid close code: {close_code}", + ) + try: + close_message = payload[2:].decode("utf-8") + except UnicodeDecodeError as exc: + raise WebSocketError( + WSCloseCode.INVALID_TEXT, "Invalid UTF-8 text message" + ) from exc + msg = WSMessage(WSMsgType.CLOSE, close_code, close_message) + elif payload: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + f"Invalid close frame: {fin} {opcode} {payload!r}", + ) + else: + msg = WSMessage(WSMsgType.CLOSE, 0, "") + + self.queue.feed_data(msg, 0) + + elif opcode == WSMsgType.PING: + self.queue.feed_data( + WSMessage(WSMsgType.PING, payload, ""), len(payload) + ) + + elif opcode == WSMsgType.PONG: + self.queue.feed_data( + WSMessage(WSMsgType.PONG, payload, ""), len(payload) + ) + + elif ( + opcode not in (WSMsgType.TEXT, WSMsgType.BINARY) + and self._opcode is None + ): + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, f"Unexpected opcode={opcode!r}" + ) + else: + # load text/binary + if not fin: + # got partial frame payload + if opcode != WSMsgType.CONTINUATION: + self._opcode = opcode + self._partial.extend(payload) + if self._max_msg_size and len(self._partial) >= self._max_msg_size: + raise WebSocketError( + WSCloseCode.MESSAGE_TOO_BIG, + "Message size {} exceeds limit {}".format( + len(self._partial), self._max_msg_size + ), + ) + else: + # previous frame was non finished + # we should get continuation opcode + if self._partial: + if opcode != WSMsgType.CONTINUATION: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "The opcode in non-fin frame is expected " + "to be zero, got {!r}".format(opcode), + ) + + if opcode == WSMsgType.CONTINUATION: + assert self._opcode is not None + opcode = self._opcode + self._opcode = None + + self._partial.extend(payload) + if self._max_msg_size and len(self._partial) >= self._max_msg_size: + raise WebSocketError( + WSCloseCode.MESSAGE_TOO_BIG, + "Message size {} exceeds limit {}".format( + len(self._partial), self._max_msg_size + ), + ) + + # Decompress process must to be done after all packets + # received. + if compressed: + self._partial.extend(_WS_DEFLATE_TRAILING) + payload_merged = self._decompressobj.decompress( + self._partial, self._max_msg_size + ) + if self._decompressobj.unconsumed_tail: + left = len(self._decompressobj.unconsumed_tail) + raise WebSocketError( + WSCloseCode.MESSAGE_TOO_BIG, + "Decompressed message size {} exceeds limit {}".format( + self._max_msg_size + left, self._max_msg_size + ), + ) + else: + payload_merged = bytes(self._partial) + + self._partial.clear() + + if opcode == WSMsgType.TEXT: + try: + text = payload_merged.decode("utf-8") + self.queue.feed_data( + WSMessage(WSMsgType.TEXT, text, ""), len(text) + ) + except UnicodeDecodeError as exc: + raise WebSocketError( + WSCloseCode.INVALID_TEXT, "Invalid UTF-8 text message" + ) from exc + else: + self.queue.feed_data( + WSMessage(WSMsgType.BINARY, payload_merged, ""), + len(payload_merged), + ) + + return False, b"" + + def parse_frame( + self, buf: bytes + ) -> List[Tuple[bool, Optional[int], bytearray, Optional[bool]]]: + """Return the next frame from the socket.""" + frames = [] + if self._tail: + buf, self._tail = self._tail + buf, b"" + + start_pos = 0 + buf_length = len(buf) + + while True: + # read header + if self._state == WSParserState.READ_HEADER: + if buf_length - start_pos >= 2: + data = buf[start_pos : start_pos + 2] + start_pos += 2 + first_byte, second_byte = data + + fin = (first_byte >> 7) & 1 + rsv1 = (first_byte >> 6) & 1 + rsv2 = (first_byte >> 5) & 1 + rsv3 = (first_byte >> 4) & 1 + opcode = first_byte & 0xF + + # frame-fin = %x0 ; more frames of this message follow + # / %x1 ; final frame of this message + # frame-rsv1 = %x0 ; + # 1 bit, MUST be 0 unless negotiated otherwise + # frame-rsv2 = %x0 ; + # 1 bit, MUST be 0 unless negotiated otherwise + # frame-rsv3 = %x0 ; + # 1 bit, MUST be 0 unless negotiated otherwise + # + # Remove rsv1 from this test for deflate development + if rsv2 or rsv3 or (rsv1 and not self._compress): + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "Received frame with non-zero reserved bits", + ) + + if opcode > 0x7 and fin == 0: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "Received fragmented control frame", + ) + + has_mask = (second_byte >> 7) & 1 + length = second_byte & 0x7F + + # Control frames MUST have a payload + # length of 125 bytes or less + if opcode > 0x7 and length > 125: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "Control frame payload cannot be " "larger than 125 bytes", + ) + + # Set compress status if last package is FIN + # OR set compress status if this is first fragment + # Raise error if not first fragment with rsv1 = 0x1 + if self._frame_fin or self._compressed is None: + self._compressed = True if rsv1 else False + elif rsv1: + raise WebSocketError( + WSCloseCode.PROTOCOL_ERROR, + "Received frame with non-zero reserved bits", + ) + + self._frame_fin = bool(fin) + self._frame_opcode = opcode + self._has_mask = bool(has_mask) + self._payload_length_flag = length + self._state = WSParserState.READ_PAYLOAD_LENGTH + else: + break + + # read payload length + if self._state == WSParserState.READ_PAYLOAD_LENGTH: + length = self._payload_length_flag + if length == 126: + if buf_length - start_pos >= 2: + data = buf[start_pos : start_pos + 2] + start_pos += 2 + length = UNPACK_LEN2(data)[0] + self._payload_length = length + self._state = ( + WSParserState.READ_PAYLOAD_MASK + if self._has_mask + else WSParserState.READ_PAYLOAD + ) + else: + break + elif length > 126: + if buf_length - start_pos >= 8: + data = buf[start_pos : start_pos + 8] + start_pos += 8 + length = UNPACK_LEN3(data)[0] + self._payload_length = length + self._state = ( + WSParserState.READ_PAYLOAD_MASK + if self._has_mask + else WSParserState.READ_PAYLOAD + ) + else: + break + else: + self._payload_length = length + self._state = ( + WSParserState.READ_PAYLOAD_MASK + if self._has_mask + else WSParserState.READ_PAYLOAD + ) + + # read payload mask + if self._state == WSParserState.READ_PAYLOAD_MASK: + if buf_length - start_pos >= 4: + self._frame_mask = buf[start_pos : start_pos + 4] + start_pos += 4 + self._state = WSParserState.READ_PAYLOAD + else: + break + + if self._state == WSParserState.READ_PAYLOAD: + length = self._payload_length + payload = self._frame_payload + + chunk_len = buf_length - start_pos + if length >= chunk_len: + self._payload_length = length - chunk_len + payload.extend(buf[start_pos:]) + start_pos = buf_length + else: + self._payload_length = 0 + payload.extend(buf[start_pos : start_pos + length]) + start_pos = start_pos + length + + if self._payload_length == 0: + if self._has_mask: + assert self._frame_mask is not None + _websocket_mask(self._frame_mask, payload) + + frames.append( + (self._frame_fin, self._frame_opcode, payload, self._compressed) + ) + + self._frame_payload = bytearray() + self._state = WSParserState.READ_HEADER + else: + break + + self._tail = buf[start_pos:] + + return frames + + +class WebSocketWriter: + def __init__( + self, + protocol: BaseProtocol, + transport: asyncio.Transport, + *, + use_mask: bool = False, + limit: int = DEFAULT_LIMIT, + random: Any = random.Random(), + compress: int = 0, + notakeover: bool = False, + ) -> None: + self.protocol = protocol + self.transport = transport + self.use_mask = use_mask + self.randrange = random.randrange + self.compress = compress + self.notakeover = notakeover + self._closing = False + self._limit = limit + self._output_size = 0 + self._compressobj = None # type: Any # actually compressobj + + async def _send_frame( + self, message: bytes, opcode: int, compress: Optional[int] = None + ) -> None: + """Send a frame over the websocket with message as its payload.""" + if self._closing and not (opcode & WSMsgType.CLOSE): + raise ConnectionResetError("Cannot write to closing transport") + + rsv = 0 + + # Only compress larger packets (disabled) + # Does small packet needs to be compressed? + # if self.compress and opcode < 8 and len(message) > 124: + if (compress or self.compress) and opcode < 8: + if compress: + # Do not set self._compress if compressing is for this frame + compressobj = zlib.compressobj(level=zlib.Z_BEST_SPEED, wbits=-compress) + else: # self.compress + if not self._compressobj: + self._compressobj = zlib.compressobj( + level=zlib.Z_BEST_SPEED, wbits=-self.compress + ) + compressobj = self._compressobj + + message = compressobj.compress(message) + message = message + compressobj.flush( + zlib.Z_FULL_FLUSH if self.notakeover else zlib.Z_SYNC_FLUSH + ) + if message.endswith(_WS_DEFLATE_TRAILING): + message = message[:-4] + rsv = rsv | 0x40 + + msg_length = len(message) + + use_mask = self.use_mask + if use_mask: + mask_bit = 0x80 + else: + mask_bit = 0 + + if msg_length < 126: + header = PACK_LEN1(0x80 | rsv | opcode, msg_length | mask_bit) + elif msg_length < (1 << 16): + header = PACK_LEN2(0x80 | rsv | opcode, 126 | mask_bit, msg_length) + else: + header = PACK_LEN3(0x80 | rsv | opcode, 127 | mask_bit, msg_length) + if use_mask: + mask = self.randrange(0, 0xFFFFFFFF) + mask = mask.to_bytes(4, "big") + message = bytearray(message) + _websocket_mask(mask, message) + self._write(header + mask + message) + self._output_size += len(header) + len(mask) + len(message) + else: + if len(message) > MSG_SIZE: + self._write(header) + self._write(message) + else: + self._write(header + message) + + self._output_size += len(header) + len(message) + + if self._output_size > self._limit: + self._output_size = 0 + await self.protocol._drain_helper() + + def _write(self, data: bytes) -> None: + if self.transport is None or self.transport.is_closing(): + raise ConnectionResetError("Cannot write to closing transport") + self.transport.write(data) + + async def pong(self, message: bytes = b"") -> None: + """Send pong message.""" + if isinstance(message, str): + message = message.encode("utf-8") + await self._send_frame(message, WSMsgType.PONG) + + async def ping(self, message: bytes = b"") -> None: + """Send ping message.""" + if isinstance(message, str): + message = message.encode("utf-8") + await self._send_frame(message, WSMsgType.PING) + + async def send( + self, + message: Union[str, bytes], + binary: bool = False, + compress: Optional[int] = None, + ) -> None: + """Send a frame over the websocket with message as its payload.""" + if isinstance(message, str): + message = message.encode("utf-8") + if binary: + await self._send_frame(message, WSMsgType.BINARY, compress) + else: + await self._send_frame(message, WSMsgType.TEXT, compress) + + async def close(self, code: int = 1000, message: bytes = b"") -> None: + """Close the websocket, sending the specified code and message.""" + if isinstance(message, str): + message = message.encode("utf-8") + try: + await self._send_frame( + PACK_CLOSE_CODE(code) + message, opcode=WSMsgType.CLOSE + ) + finally: + self._closing = True diff --git a/dist/ba_data/python-site-packages/aiohttp/http_writer.py b/dist/ba_data/python-site-packages/aiohttp/http_writer.py new file mode 100644 index 0000000..d261fc4 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/http_writer.py @@ -0,0 +1,182 @@ +"""Http related parsers and protocol.""" + +import asyncio +import collections +import zlib +from typing import Any, Awaitable, Callable, Optional, Union # noqa + +from multidict import CIMultiDict + +from .abc import AbstractStreamWriter +from .base_protocol import BaseProtocol +from .helpers import NO_EXTENSIONS + +__all__ = ("StreamWriter", "HttpVersion", "HttpVersion10", "HttpVersion11") + +HttpVersion = collections.namedtuple("HttpVersion", ["major", "minor"]) +HttpVersion10 = HttpVersion(1, 0) +HttpVersion11 = HttpVersion(1, 1) + + +_T_OnChunkSent = Optional[Callable[[bytes], Awaitable[None]]] + + +class StreamWriter(AbstractStreamWriter): + def __init__( + self, + protocol: BaseProtocol, + loop: asyncio.AbstractEventLoop, + on_chunk_sent: _T_OnChunkSent = None, + ) -> None: + self._protocol = protocol + self._transport = protocol.transport + + self.loop = loop + self.length = None + self.chunked = False + self.buffer_size = 0 + self.output_size = 0 + + self._eof = False + self._compress = None # type: Any + self._drain_waiter = None + + self._on_chunk_sent = on_chunk_sent # type: _T_OnChunkSent + + @property + def transport(self) -> Optional[asyncio.Transport]: + return self._transport + + @property + def protocol(self) -> BaseProtocol: + return self._protocol + + def enable_chunking(self) -> None: + self.chunked = True + + def enable_compression(self, encoding: str = "deflate") -> None: + zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else zlib.MAX_WBITS + self._compress = zlib.compressobj(wbits=zlib_mode) + + def _write(self, chunk: bytes) -> None: + size = len(chunk) + self.buffer_size += size + self.output_size += size + + if self._transport is None or self._transport.is_closing(): + raise ConnectionResetError("Cannot write to closing transport") + self._transport.write(chunk) + + async def write( + self, chunk: bytes, *, drain: bool = True, LIMIT: int = 0x10000 + ) -> None: + """Writes chunk of data to a stream. + + write_eof() indicates end of stream. + writer can't be used after write_eof() method being called. + write() return drain future. + """ + if self._on_chunk_sent is not None: + await self._on_chunk_sent(chunk) + + if isinstance(chunk, memoryview): + if chunk.nbytes != len(chunk): + # just reshape it + chunk = chunk.cast("c") + + if self._compress is not None: + chunk = self._compress.compress(chunk) + if not chunk: + return + + if self.length is not None: + chunk_len = len(chunk) + if self.length >= chunk_len: + self.length = self.length - chunk_len + else: + chunk = chunk[: self.length] + self.length = 0 + if not chunk: + return + + if chunk: + if self.chunked: + chunk_len_pre = ("%x\r\n" % len(chunk)).encode("ascii") + chunk = chunk_len_pre + chunk + b"\r\n" + + self._write(chunk) + + if self.buffer_size > LIMIT and drain: + self.buffer_size = 0 + await self.drain() + + async def write_headers( + self, status_line: str, headers: "CIMultiDict[str]" + ) -> None: + """Write request/response status and headers.""" + # status + headers + buf = _serialize_headers(status_line, headers) + self._write(buf) + + async def write_eof(self, chunk: bytes = b"") -> None: + if self._eof: + return + + if chunk and self._on_chunk_sent is not None: + await self._on_chunk_sent(chunk) + + if self._compress: + if chunk: + chunk = self._compress.compress(chunk) + + chunk = chunk + self._compress.flush() + if chunk and self.chunked: + chunk_len = ("%x\r\n" % len(chunk)).encode("ascii") + chunk = chunk_len + chunk + b"\r\n0\r\n\r\n" + else: + if self.chunked: + if chunk: + chunk_len = ("%x\r\n" % len(chunk)).encode("ascii") + chunk = chunk_len + chunk + b"\r\n0\r\n\r\n" + else: + chunk = b"0\r\n\r\n" + + if chunk: + self._write(chunk) + + await self.drain() + + self._eof = True + self._transport = None + + async def drain(self) -> None: + """Flush the write buffer. + + The intended use is to write + + await w.write(data) + await w.drain() + """ + if self._protocol.transport is not None: + await self._protocol._drain_helper() + + +def _py_serialize_headers(status_line: str, headers: "CIMultiDict[str]") -> bytes: + line = ( + status_line + + "\r\n" + + "".join([k + ": " + v + "\r\n" for k, v in headers.items()]) + ) + return line.encode("utf-8") + b"\r\n" + + +_serialize_headers = _py_serialize_headers + +try: + import aiohttp._http_writer as _http_writer # type: ignore + + _c_serialize_headers = _http_writer._serialize_headers + if not NO_EXTENSIONS: + _serialize_headers = _c_serialize_headers +except ImportError: + pass diff --git a/dist/ba_data/python-site-packages/aiohttp/locks.py b/dist/ba_data/python-site-packages/aiohttp/locks.py new file mode 100644 index 0000000..ce5b9c6 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/locks.py @@ -0,0 +1,45 @@ +import asyncio +import collections +from typing import Any, Optional + +try: + from typing import Deque +except ImportError: + from typing_extensions import Deque + + +class EventResultOrError: + """ + This class wrappers the Event asyncio lock allowing either awake the + locked Tasks without any error or raising an exception. + + thanks to @vorpalsmith for the simple design. + """ + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + self._loop = loop + self._exc = None # type: Optional[BaseException] + self._event = asyncio.Event() + self._waiters = collections.deque() # type: Deque[asyncio.Future[Any]] + + def set(self, exc: Optional[BaseException] = None) -> None: + self._exc = exc + self._event.set() + + async def wait(self) -> Any: + waiter = self._loop.create_task(self._event.wait()) + self._waiters.append(waiter) + try: + val = await waiter + finally: + self._waiters.remove(waiter) + + if self._exc is not None: + raise self._exc + + return val + + def cancel(self) -> None: + """ Cancel all waiters """ + for waiter in self._waiters: + waiter.cancel() diff --git a/dist/ba_data/python-site-packages/aiohttp/log.py b/dist/ba_data/python-site-packages/aiohttp/log.py new file mode 100644 index 0000000..3cecea2 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/log.py @@ -0,0 +1,8 @@ +import logging + +access_logger = logging.getLogger("aiohttp.access") +client_logger = logging.getLogger("aiohttp.client") +internal_logger = logging.getLogger("aiohttp.internal") +server_logger = logging.getLogger("aiohttp.server") +web_logger = logging.getLogger("aiohttp.web") +ws_logger = logging.getLogger("aiohttp.websocket") diff --git a/dist/ba_data/python-site-packages/aiohttp/multipart.py b/dist/ba_data/python-site-packages/aiohttp/multipart.py new file mode 100644 index 0000000..9e1ca92 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/multipart.py @@ -0,0 +1,957 @@ +import base64 +import binascii +import json +import re +import uuid +import warnings +import zlib +from collections import deque +from types import TracebackType +from typing import ( + TYPE_CHECKING, + Any, + AsyncIterator, + Dict, + Iterator, + List, + Mapping, + Optional, + Sequence, + Tuple, + Type, + Union, +) +from urllib.parse import parse_qsl, unquote, urlencode + +from multidict import CIMultiDict, CIMultiDictProxy, MultiMapping + +from .hdrs import ( + CONTENT_DISPOSITION, + CONTENT_ENCODING, + CONTENT_LENGTH, + CONTENT_TRANSFER_ENCODING, + CONTENT_TYPE, +) +from .helpers import CHAR, TOKEN, parse_mimetype, reify +from .http import HeadersParser +from .payload import ( + JsonPayload, + LookupError, + Order, + Payload, + StringPayload, + get_payload, + payload_type, +) +from .streams import StreamReader + +__all__ = ( + "MultipartReader", + "MultipartWriter", + "BodyPartReader", + "BadContentDispositionHeader", + "BadContentDispositionParam", + "parse_content_disposition", + "content_disposition_filename", +) + + +if TYPE_CHECKING: # pragma: no cover + from .client_reqrep import ClientResponse + + +class BadContentDispositionHeader(RuntimeWarning): + pass + + +class BadContentDispositionParam(RuntimeWarning): + pass + + +def parse_content_disposition( + header: Optional[str], +) -> Tuple[Optional[str], Dict[str, str]]: + def is_token(string: str) -> bool: + return bool(string) and TOKEN >= set(string) + + def is_quoted(string: str) -> bool: + return string[0] == string[-1] == '"' + + def is_rfc5987(string: str) -> bool: + return is_token(string) and string.count("'") == 2 + + def is_extended_param(string: str) -> bool: + return string.endswith("*") + + def is_continuous_param(string: str) -> bool: + pos = string.find("*") + 1 + if not pos: + return False + substring = string[pos:-1] if string.endswith("*") else string[pos:] + return substring.isdigit() + + def unescape(text: str, *, chars: str = "".join(map(re.escape, CHAR))) -> str: + return re.sub(f"\\\\([{chars}])", "\\1", text) + + if not header: + return None, {} + + disptype, *parts = header.split(";") + if not is_token(disptype): + warnings.warn(BadContentDispositionHeader(header)) + return None, {} + + params = {} # type: Dict[str, str] + while parts: + item = parts.pop(0) + + if "=" not in item: + warnings.warn(BadContentDispositionHeader(header)) + return None, {} + + key, value = item.split("=", 1) + key = key.lower().strip() + value = value.lstrip() + + if key in params: + warnings.warn(BadContentDispositionHeader(header)) + return None, {} + + if not is_token(key): + warnings.warn(BadContentDispositionParam(item)) + continue + + elif is_continuous_param(key): + if is_quoted(value): + value = unescape(value[1:-1]) + elif not is_token(value): + warnings.warn(BadContentDispositionParam(item)) + continue + + elif is_extended_param(key): + if is_rfc5987(value): + encoding, _, value = value.split("'", 2) + encoding = encoding or "utf-8" + else: + warnings.warn(BadContentDispositionParam(item)) + continue + + try: + value = unquote(value, encoding, "strict") + except UnicodeDecodeError: # pragma: nocover + warnings.warn(BadContentDispositionParam(item)) + continue + + else: + failed = True + if is_quoted(value): + failed = False + value = unescape(value[1:-1].lstrip("\\/")) + elif is_token(value): + failed = False + elif parts: + # maybe just ; in filename, in any case this is just + # one case fix, for proper fix we need to redesign parser + _value = "{};{}".format(value, parts[0]) + if is_quoted(_value): + parts.pop(0) + value = unescape(_value[1:-1].lstrip("\\/")) + failed = False + + if failed: + warnings.warn(BadContentDispositionHeader(header)) + return None, {} + + params[key] = value + + return disptype.lower(), params + + +def content_disposition_filename( + params: Mapping[str, str], name: str = "filename" +) -> Optional[str]: + name_suf = "%s*" % name + if not params: + return None + elif name_suf in params: + return params[name_suf] + elif name in params: + return params[name] + else: + parts = [] + fnparams = sorted( + (key, value) for key, value in params.items() if key.startswith(name_suf) + ) + for num, (key, value) in enumerate(fnparams): + _, tail = key.split("*", 1) + if tail.endswith("*"): + tail = tail[:-1] + if tail == str(num): + parts.append(value) + else: + break + if not parts: + return None + value = "".join(parts) + if "'" in value: + encoding, _, value = value.split("'", 2) + encoding = encoding or "utf-8" + return unquote(value, encoding, "strict") + return value + + +class MultipartResponseWrapper: + """Wrapper around the MultipartReader. + + It takes care about + underlying connection and close it when it needs in. + """ + + def __init__( + self, + resp: "ClientResponse", + stream: "MultipartReader", + ) -> None: + self.resp = resp + self.stream = stream + + def __aiter__(self) -> "MultipartResponseWrapper": + return self + + async def __anext__( + self, + ) -> Union["MultipartReader", "BodyPartReader"]: + part = await self.next() + if part is None: + raise StopAsyncIteration + return part + + def at_eof(self) -> bool: + """Returns True when all response data had been read.""" + return self.resp.content.at_eof() + + async def next( + self, + ) -> Optional[Union["MultipartReader", "BodyPartReader"]]: + """Emits next multipart reader object.""" + item = await self.stream.next() + if self.stream.at_eof(): + await self.release() + return item + + async def release(self) -> None: + """Releases the connection gracefully, reading all the content + to the void.""" + await self.resp.release() + + +class BodyPartReader: + """Multipart reader for single body part.""" + + chunk_size = 8192 + + def __init__( + self, boundary: bytes, headers: "CIMultiDictProxy[str]", content: StreamReader + ) -> None: + self.headers = headers + self._boundary = boundary + self._content = content + self._at_eof = False + length = self.headers.get(CONTENT_LENGTH, None) + self._length = int(length) if length is not None else None + self._read_bytes = 0 + # TODO: typeing.Deque is not supported by Python 3.5 + self._unread = deque() # type: Any + self._prev_chunk = None # type: Optional[bytes] + self._content_eof = 0 + self._cache = {} # type: Dict[str, Any] + + def __aiter__(self) -> AsyncIterator["BodyPartReader"]: + return self # type: ignore + + async def __anext__(self) -> bytes: + part = await self.next() + if part is None: + raise StopAsyncIteration + return part + + async def next(self) -> Optional[bytes]: + item = await self.read() + if not item: + return None + return item + + async def read(self, *, decode: bool = False) -> bytes: + """Reads body part data. + + decode: Decodes data following by encoding + method from Content-Encoding header. If it missed + data remains untouched + """ + if self._at_eof: + return b"" + data = bytearray() + while not self._at_eof: + data.extend(await self.read_chunk(self.chunk_size)) + if decode: + return self.decode(data) + return data + + async def read_chunk(self, size: int = chunk_size) -> bytes: + """Reads body part content chunk of the specified size. + + size: chunk size + """ + if self._at_eof: + return b"" + if self._length: + chunk = await self._read_chunk_from_length(size) + else: + chunk = await self._read_chunk_from_stream(size) + + self._read_bytes += len(chunk) + if self._read_bytes == self._length: + self._at_eof = True + if self._at_eof: + clrf = await self._content.readline() + assert ( + b"\r\n" == clrf + ), "reader did not read all the data or it is malformed" + return chunk + + async def _read_chunk_from_length(self, size: int) -> bytes: + # Reads body part content chunk of the specified size. + # The body part must has Content-Length header with proper value. + assert self._length is not None, "Content-Length required for chunked read" + chunk_size = min(size, self._length - self._read_bytes) + chunk = await self._content.read(chunk_size) + return chunk + + async def _read_chunk_from_stream(self, size: int) -> bytes: + # Reads content chunk of body part with unknown length. + # The Content-Length header for body part is not necessary. + assert ( + size >= len(self._boundary) + 2 + ), "Chunk size must be greater or equal than boundary length + 2" + first_chunk = self._prev_chunk is None + if first_chunk: + self._prev_chunk = await self._content.read(size) + + chunk = await self._content.read(size) + self._content_eof += int(self._content.at_eof()) + assert self._content_eof < 3, "Reading after EOF" + assert self._prev_chunk is not None + window = self._prev_chunk + chunk + sub = b"\r\n" + self._boundary + if first_chunk: + idx = window.find(sub) + else: + idx = window.find(sub, max(0, len(self._prev_chunk) - len(sub))) + if idx >= 0: + # pushing boundary back to content + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + self._content.unread_data(window[idx:]) + if size > idx: + self._prev_chunk = self._prev_chunk[:idx] + chunk = window[len(self._prev_chunk) : idx] + if not chunk: + self._at_eof = True + result = self._prev_chunk + self._prev_chunk = chunk + return result + + async def readline(self) -> bytes: + """Reads body part by line by line.""" + if self._at_eof: + return b"" + + if self._unread: + line = self._unread.popleft() + else: + line = await self._content.readline() + + if line.startswith(self._boundary): + # the very last boundary may not come with \r\n, + # so set single rules for everyone + sline = line.rstrip(b"\r\n") + boundary = self._boundary + last_boundary = self._boundary + b"--" + # ensure that we read exactly the boundary, not something alike + if sline == boundary or sline == last_boundary: + self._at_eof = True + self._unread.append(line) + return b"" + else: + next_line = await self._content.readline() + if next_line.startswith(self._boundary): + line = line[:-2] # strip CRLF but only once + self._unread.append(next_line) + + return line + + async def release(self) -> None: + """Like read(), but reads all the data to the void.""" + if self._at_eof: + return + while not self._at_eof: + await self.read_chunk(self.chunk_size) + + async def text(self, *, encoding: Optional[str] = None) -> str: + """Like read(), but assumes that body part contains text data.""" + data = await self.read(decode=True) + # see https://www.w3.org/TR/html5/forms.html#multipart/form-data-encoding-algorithm # NOQA + # and https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-send # NOQA + encoding = encoding or self.get_charset(default="utf-8") + return data.decode(encoding) + + async def json(self, *, encoding: Optional[str] = None) -> Optional[Dict[str, Any]]: + """Like read(), but assumes that body parts contains JSON data.""" + data = await self.read(decode=True) + if not data: + return None + encoding = encoding or self.get_charset(default="utf-8") + return json.loads(data.decode(encoding)) + + async def form(self, *, encoding: Optional[str] = None) -> List[Tuple[str, str]]: + """Like read(), but assumes that body parts contains form + urlencoded data. + """ + data = await self.read(decode=True) + if not data: + return [] + if encoding is not None: + real_encoding = encoding + else: + real_encoding = self.get_charset(default="utf-8") + return parse_qsl( + data.rstrip().decode(real_encoding), + keep_blank_values=True, + encoding=real_encoding, + ) + + def at_eof(self) -> bool: + """Returns True if the boundary was reached or False otherwise.""" + return self._at_eof + + def decode(self, data: bytes) -> bytes: + """Decodes data according the specified Content-Encoding + or Content-Transfer-Encoding headers value. + """ + if CONTENT_TRANSFER_ENCODING in self.headers: + data = self._decode_content_transfer(data) + if CONTENT_ENCODING in self.headers: + return self._decode_content(data) + return data + + def _decode_content(self, data: bytes) -> bytes: + encoding = self.headers.get(CONTENT_ENCODING, "").lower() + + if encoding == "deflate": + return zlib.decompress(data, -zlib.MAX_WBITS) + elif encoding == "gzip": + return zlib.decompress(data, 16 + zlib.MAX_WBITS) + elif encoding == "identity": + return data + else: + raise RuntimeError(f"unknown content encoding: {encoding}") + + def _decode_content_transfer(self, data: bytes) -> bytes: + encoding = self.headers.get(CONTENT_TRANSFER_ENCODING, "").lower() + + if encoding == "base64": + return base64.b64decode(data) + elif encoding == "quoted-printable": + return binascii.a2b_qp(data) + elif encoding in ("binary", "8bit", "7bit"): + return data + else: + raise RuntimeError( + "unknown content transfer encoding: {}" "".format(encoding) + ) + + def get_charset(self, default: str) -> str: + """Returns charset parameter from Content-Type header or default.""" + ctype = self.headers.get(CONTENT_TYPE, "") + mimetype = parse_mimetype(ctype) + return mimetype.parameters.get("charset", default) + + @reify + def name(self) -> Optional[str]: + """Returns name specified in Content-Disposition header or None + if missed or header is malformed. + """ + + _, params = parse_content_disposition(self.headers.get(CONTENT_DISPOSITION)) + return content_disposition_filename(params, "name") + + @reify + def filename(self) -> Optional[str]: + """Returns filename specified in Content-Disposition header or None + if missed or header is malformed. + """ + _, params = parse_content_disposition(self.headers.get(CONTENT_DISPOSITION)) + return content_disposition_filename(params, "filename") + + +@payload_type(BodyPartReader, order=Order.try_first) +class BodyPartReaderPayload(Payload): + def __init__(self, value: BodyPartReader, *args: Any, **kwargs: Any) -> None: + super().__init__(value, *args, **kwargs) + + params = {} # type: Dict[str, str] + if value.name is not None: + params["name"] = value.name + if value.filename is not None: + params["filename"] = value.filename + + if params: + self.set_content_disposition("attachment", True, **params) + + async def write(self, writer: Any) -> None: + field = self._value + chunk = await field.read_chunk(size=2 ** 16) + while chunk: + await writer.write(field.decode(chunk)) + chunk = await field.read_chunk(size=2 ** 16) + + +class MultipartReader: + """Multipart body reader.""" + + #: Response wrapper, used when multipart readers constructs from response. + response_wrapper_cls = MultipartResponseWrapper + #: Multipart reader class, used to handle multipart/* body parts. + #: None points to type(self) + multipart_reader_cls = None + #: Body part reader class for non multipart/* content types. + part_reader_cls = BodyPartReader + + def __init__(self, headers: Mapping[str, str], content: StreamReader) -> None: + self.headers = headers + self._boundary = ("--" + self._get_boundary()).encode() + self._content = content + self._last_part = ( + None + ) # type: Optional[Union['MultipartReader', BodyPartReader]] + self._at_eof = False + self._at_bof = True + self._unread = [] # type: List[bytes] + + def __aiter__( + self, + ) -> AsyncIterator["BodyPartReader"]: + return self # type: ignore + + async def __anext__( + self, + ) -> Optional[Union["MultipartReader", BodyPartReader]]: + part = await self.next() + if part is None: + raise StopAsyncIteration + return part + + @classmethod + def from_response( + cls, + response: "ClientResponse", + ) -> MultipartResponseWrapper: + """Constructs reader instance from HTTP response. + + :param response: :class:`~aiohttp.client.ClientResponse` instance + """ + obj = cls.response_wrapper_cls( + response, cls(response.headers, response.content) + ) + return obj + + def at_eof(self) -> bool: + """Returns True if the final boundary was reached or + False otherwise. + """ + return self._at_eof + + async def next( + self, + ) -> Optional[Union["MultipartReader", BodyPartReader]]: + """Emits the next multipart body part.""" + # So, if we're at BOF, we need to skip till the boundary. + if self._at_eof: + return None + await self._maybe_release_last_part() + if self._at_bof: + await self._read_until_first_boundary() + self._at_bof = False + else: + await self._read_boundary() + if self._at_eof: # we just read the last boundary, nothing to do there + return None + self._last_part = await self.fetch_next_part() + return self._last_part + + async def release(self) -> None: + """Reads all the body parts to the void till the final boundary.""" + while not self._at_eof: + item = await self.next() + if item is None: + break + await item.release() + + async def fetch_next_part( + self, + ) -> Union["MultipartReader", BodyPartReader]: + """Returns the next body part reader.""" + headers = await self._read_headers() + return self._get_part_reader(headers) + + def _get_part_reader( + self, + headers: "CIMultiDictProxy[str]", + ) -> Union["MultipartReader", BodyPartReader]: + """Dispatches the response by the `Content-Type` header, returning + suitable reader instance. + + :param dict headers: Response headers + """ + ctype = headers.get(CONTENT_TYPE, "") + mimetype = parse_mimetype(ctype) + + if mimetype.type == "multipart": + if self.multipart_reader_cls is None: + return type(self)(headers, self._content) + return self.multipart_reader_cls(headers, self._content) + else: + return self.part_reader_cls(self._boundary, headers, self._content) + + def _get_boundary(self) -> str: + mimetype = parse_mimetype(self.headers[CONTENT_TYPE]) + + assert mimetype.type == "multipart", "multipart/* content type expected" + + if "boundary" not in mimetype.parameters: + raise ValueError( + "boundary missed for Content-Type: %s" % self.headers[CONTENT_TYPE] + ) + + boundary = mimetype.parameters["boundary"] + if len(boundary) > 70: + raise ValueError("boundary %r is too long (70 chars max)" % boundary) + + return boundary + + async def _readline(self) -> bytes: + if self._unread: + return self._unread.pop() + return await self._content.readline() + + async def _read_until_first_boundary(self) -> None: + while True: + chunk = await self._readline() + if chunk == b"": + raise ValueError( + "Could not find starting boundary %r" % (self._boundary) + ) + chunk = chunk.rstrip() + if chunk == self._boundary: + return + elif chunk == self._boundary + b"--": + self._at_eof = True + return + + async def _read_boundary(self) -> None: + chunk = (await self._readline()).rstrip() + if chunk == self._boundary: + pass + elif chunk == self._boundary + b"--": + self._at_eof = True + epilogue = await self._readline() + next_line = await self._readline() + + # the epilogue is expected and then either the end of input or the + # parent multipart boundary, if the parent boundary is found then + # it should be marked as unread and handed to the parent for + # processing + if next_line[:2] == b"--": + self._unread.append(next_line) + # otherwise the request is likely missing an epilogue and both + # lines should be passed to the parent for processing + # (this handles the old behavior gracefully) + else: + self._unread.extend([next_line, epilogue]) + else: + raise ValueError(f"Invalid boundary {chunk!r}, expected {self._boundary!r}") + + async def _read_headers(self) -> "CIMultiDictProxy[str]": + lines = [b""] + while True: + chunk = await self._content.readline() + chunk = chunk.strip() + lines.append(chunk) + if not chunk: + break + parser = HeadersParser() + headers, raw_headers = parser.parse_headers(lines) + return headers + + async def _maybe_release_last_part(self) -> None: + """Ensures that the last read body part is read completely.""" + if self._last_part is not None: + if not self._last_part.at_eof(): + await self._last_part.release() + self._unread.extend(self._last_part._unread) + self._last_part = None + + +_Part = Tuple[Payload, str, str] + + +class MultipartWriter(Payload): + """Multipart body writer.""" + + def __init__(self, subtype: str = "mixed", boundary: Optional[str] = None) -> None: + boundary = boundary if boundary is not None else uuid.uuid4().hex + # The underlying Payload API demands a str (utf-8), not bytes, + # so we need to ensure we don't lose anything during conversion. + # As a result, require the boundary to be ASCII only. + # In both situations. + + try: + self._boundary = boundary.encode("ascii") + except UnicodeEncodeError: + raise ValueError("boundary should contain ASCII only chars") from None + ctype = f"multipart/{subtype}; boundary={self._boundary_value}" + + super().__init__(None, content_type=ctype) + + self._parts = [] # type: List[_Part] + + def __enter__(self) -> "MultipartWriter": + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> None: + pass + + def __iter__(self) -> Iterator[_Part]: + return iter(self._parts) + + def __len__(self) -> int: + return len(self._parts) + + def __bool__(self) -> bool: + return True + + _valid_tchar_regex = re.compile(br"\A[!#$%&'*+\-.^_`|~\w]+\Z") + _invalid_qdtext_char_regex = re.compile(br"[\x00-\x08\x0A-\x1F\x7F]") + + @property + def _boundary_value(self) -> str: + """Wrap boundary parameter value in quotes, if necessary. + + Reads self.boundary and returns a unicode sting. + """ + # Refer to RFCs 7231, 7230, 5234. + # + # parameter = token "=" ( token / quoted-string ) + # token = 1*tchar + # quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE + # qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text + # obs-text = %x80-FF + # quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) + # tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" + # / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" + # / DIGIT / ALPHA + # ; any VCHAR, except delimiters + # VCHAR = %x21-7E + value = self._boundary + if re.match(self._valid_tchar_regex, value): + return value.decode("ascii") # cannot fail + + if re.search(self._invalid_qdtext_char_regex, value): + raise ValueError("boundary value contains invalid characters") + + # escape %x5C and %x22 + quoted_value_content = value.replace(b"\\", b"\\\\") + quoted_value_content = quoted_value_content.replace(b'"', b'\\"') + + return '"' + quoted_value_content.decode("ascii") + '"' + + @property + def boundary(self) -> str: + return self._boundary.decode("ascii") + + def append(self, obj: Any, headers: Optional[MultiMapping[str]] = None) -> Payload: + if headers is None: + headers = CIMultiDict() + + if isinstance(obj, Payload): + obj.headers.update(headers) + return self.append_payload(obj) + else: + try: + payload = get_payload(obj, headers=headers) + except LookupError: + raise TypeError("Cannot create payload from %r" % obj) + else: + return self.append_payload(payload) + + def append_payload(self, payload: Payload) -> Payload: + """Adds a new body part to multipart writer.""" + # compression + encoding = payload.headers.get( + CONTENT_ENCODING, + "", + ).lower() # type: Optional[str] + if encoding and encoding not in ("deflate", "gzip", "identity"): + raise RuntimeError(f"unknown content encoding: {encoding}") + if encoding == "identity": + encoding = None + + # te encoding + te_encoding = payload.headers.get( + CONTENT_TRANSFER_ENCODING, + "", + ).lower() # type: Optional[str] + if te_encoding not in ("", "base64", "quoted-printable", "binary"): + raise RuntimeError( + "unknown content transfer encoding: {}" "".format(te_encoding) + ) + if te_encoding == "binary": + te_encoding = None + + # size + size = payload.size + if size is not None and not (encoding or te_encoding): + payload.headers[CONTENT_LENGTH] = str(size) + + self._parts.append((payload, encoding, te_encoding)) # type: ignore + return payload + + def append_json( + self, obj: Any, headers: Optional[MultiMapping[str]] = None + ) -> Payload: + """Helper to append JSON part.""" + if headers is None: + headers = CIMultiDict() + + return self.append_payload(JsonPayload(obj, headers=headers)) + + def append_form( + self, + obj: Union[Sequence[Tuple[str, str]], Mapping[str, str]], + headers: Optional[MultiMapping[str]] = None, + ) -> Payload: + """Helper to append form urlencoded part.""" + assert isinstance(obj, (Sequence, Mapping)) + + if headers is None: + headers = CIMultiDict() + + if isinstance(obj, Mapping): + obj = list(obj.items()) + data = urlencode(obj, doseq=True) + + return self.append_payload( + StringPayload( + data, headers=headers, content_type="application/x-www-form-urlencoded" + ) + ) + + @property + def size(self) -> Optional[int]: + """Size of the payload.""" + total = 0 + for part, encoding, te_encoding in self._parts: + if encoding or te_encoding or part.size is None: + return None + + total += int( + 2 + + len(self._boundary) + + 2 + + part.size # b'--'+self._boundary+b'\r\n' + + len(part._binary_headers) + + 2 # b'\r\n' + ) + + total += 2 + len(self._boundary) + 4 # b'--'+self._boundary+b'--\r\n' + return total + + async def write(self, writer: Any, close_boundary: bool = True) -> None: + """Write body.""" + for part, encoding, te_encoding in self._parts: + await writer.write(b"--" + self._boundary + b"\r\n") + await writer.write(part._binary_headers) + + if encoding or te_encoding: + w = MultipartPayloadWriter(writer) + if encoding: + w.enable_compression(encoding) + if te_encoding: + w.enable_encoding(te_encoding) + await part.write(w) # type: ignore + await w.write_eof() + else: + await part.write(writer) + + await writer.write(b"\r\n") + + if close_boundary: + await writer.write(b"--" + self._boundary + b"--\r\n") + + +class MultipartPayloadWriter: + def __init__(self, writer: Any) -> None: + self._writer = writer + self._encoding = None # type: Optional[str] + self._compress = None # type: Any + self._encoding_buffer = None # type: Optional[bytearray] + + def enable_encoding(self, encoding: str) -> None: + if encoding == "base64": + self._encoding = encoding + self._encoding_buffer = bytearray() + elif encoding == "quoted-printable": + self._encoding = "quoted-printable" + + def enable_compression(self, encoding: str = "deflate") -> None: + zlib_mode = 16 + zlib.MAX_WBITS if encoding == "gzip" else -zlib.MAX_WBITS + self._compress = zlib.compressobj(wbits=zlib_mode) + + async def write_eof(self) -> None: + if self._compress is not None: + chunk = self._compress.flush() + if chunk: + self._compress = None + await self.write(chunk) + + if self._encoding == "base64": + if self._encoding_buffer: + await self._writer.write(base64.b64encode(self._encoding_buffer)) + + async def write(self, chunk: bytes) -> None: + if self._compress is not None: + if chunk: + chunk = self._compress.compress(chunk) + if not chunk: + return + + if self._encoding == "base64": + buf = self._encoding_buffer + assert buf is not None + buf.extend(chunk) + + if buf: + div, mod = divmod(len(buf), 3) + enc_chunk, self._encoding_buffer = (buf[: div * 3], buf[div * 3 :]) + if enc_chunk: + b64chunk = base64.b64encode(enc_chunk) + await self._writer.write(b64chunk) + elif self._encoding == "quoted-printable": + await self._writer.write(binascii.b2a_qp(chunk)) + else: + await self._writer.write(chunk) diff --git a/dist/ba_data/python-site-packages/aiohttp/payload.py b/dist/ba_data/python-site-packages/aiohttp/payload.py new file mode 100644 index 0000000..c63dd22 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/payload.py @@ -0,0 +1,448 @@ +import asyncio +import enum +import io +import json +import mimetypes +import os +import warnings +from abc import ABC, abstractmethod +from itertools import chain +from typing import ( + IO, + TYPE_CHECKING, + Any, + ByteString, + Dict, + Iterable, + Optional, + Text, + TextIO, + Tuple, + Type, + Union, +) + +from multidict import CIMultiDict + +from . import hdrs +from .abc import AbstractStreamWriter +from .helpers import ( + PY_36, + content_disposition_header, + guess_filename, + parse_mimetype, + sentinel, +) +from .streams import StreamReader +from .typedefs import JSONEncoder, _CIMultiDict + +__all__ = ( + "PAYLOAD_REGISTRY", + "get_payload", + "payload_type", + "Payload", + "BytesPayload", + "StringPayload", + "IOBasePayload", + "BytesIOPayload", + "BufferedReaderPayload", + "TextIOPayload", + "StringIOPayload", + "JsonPayload", + "AsyncIterablePayload", +) + +TOO_LARGE_BYTES_BODY = 2 ** 20 # 1 MB + + +if TYPE_CHECKING: # pragma: no cover + from typing import List + + +class LookupError(Exception): + pass + + +class Order(str, enum.Enum): + normal = "normal" + try_first = "try_first" + try_last = "try_last" + + +def get_payload(data: Any, *args: Any, **kwargs: Any) -> "Payload": + return PAYLOAD_REGISTRY.get(data, *args, **kwargs) + + +def register_payload( + factory: Type["Payload"], type: Any, *, order: Order = Order.normal +) -> None: + PAYLOAD_REGISTRY.register(factory, type, order=order) + + +class payload_type: + def __init__(self, type: Any, *, order: Order = Order.normal) -> None: + self.type = type + self.order = order + + def __call__(self, factory: Type["Payload"]) -> Type["Payload"]: + register_payload(factory, self.type, order=self.order) + return factory + + +class PayloadRegistry: + """Payload registry. + + note: we need zope.interface for more efficient adapter search + """ + + def __init__(self) -> None: + self._first = [] # type: List[Tuple[Type[Payload], Any]] + self._normal = [] # type: List[Tuple[Type[Payload], Any]] + self._last = [] # type: List[Tuple[Type[Payload], Any]] + + def get( + self, data: Any, *args: Any, _CHAIN: Any = chain, **kwargs: Any + ) -> "Payload": + if isinstance(data, Payload): + return data + for factory, type in _CHAIN(self._first, self._normal, self._last): + if isinstance(data, type): + return factory(data, *args, **kwargs) + + raise LookupError() + + def register( + self, factory: Type["Payload"], type: Any, *, order: Order = Order.normal + ) -> None: + if order is Order.try_first: + self._first.append((factory, type)) + elif order is Order.normal: + self._normal.append((factory, type)) + elif order is Order.try_last: + self._last.append((factory, type)) + else: + raise ValueError(f"Unsupported order {order!r}") + + +class Payload(ABC): + + _default_content_type = "application/octet-stream" # type: str + _size = None # type: Optional[int] + + def __init__( + self, + value: Any, + headers: Optional[ + Union[_CIMultiDict, Dict[str, str], Iterable[Tuple[str, str]]] + ] = None, + content_type: Optional[str] = sentinel, + filename: Optional[str] = None, + encoding: Optional[str] = None, + **kwargs: Any, + ) -> None: + self._encoding = encoding + self._filename = filename + self._headers = CIMultiDict() # type: _CIMultiDict + self._value = value + if content_type is not sentinel and content_type is not None: + self._headers[hdrs.CONTENT_TYPE] = content_type + elif self._filename is not None: + content_type = mimetypes.guess_type(self._filename)[0] + if content_type is None: + content_type = self._default_content_type + self._headers[hdrs.CONTENT_TYPE] = content_type + else: + self._headers[hdrs.CONTENT_TYPE] = self._default_content_type + self._headers.update(headers or {}) + + @property + def size(self) -> Optional[int]: + """Size of the payload.""" + return self._size + + @property + def filename(self) -> Optional[str]: + """Filename of the payload.""" + return self._filename + + @property + def headers(self) -> _CIMultiDict: + """Custom item headers""" + return self._headers + + @property + def _binary_headers(self) -> bytes: + return ( + "".join([k + ": " + v + "\r\n" for k, v in self.headers.items()]).encode( + "utf-8" + ) + + b"\r\n" + ) + + @property + def encoding(self) -> Optional[str]: + """Payload encoding""" + return self._encoding + + @property + def content_type(self) -> str: + """Content type""" + return self._headers[hdrs.CONTENT_TYPE] + + def set_content_disposition( + self, disptype: str, quote_fields: bool = True, **params: Any + ) -> None: + """Sets ``Content-Disposition`` header.""" + self._headers[hdrs.CONTENT_DISPOSITION] = content_disposition_header( + disptype, quote_fields=quote_fields, **params + ) + + @abstractmethod + async def write(self, writer: AbstractStreamWriter) -> None: + """Write payload. + + writer is an AbstractStreamWriter instance: + """ + + +class BytesPayload(Payload): + def __init__(self, value: ByteString, *args: Any, **kwargs: Any) -> None: + if not isinstance(value, (bytes, bytearray, memoryview)): + raise TypeError( + "value argument must be byte-ish, not {!r}".format(type(value)) + ) + + if "content_type" not in kwargs: + kwargs["content_type"] = "application/octet-stream" + + super().__init__(value, *args, **kwargs) + + if isinstance(value, memoryview): + self._size = value.nbytes + else: + self._size = len(value) + + if self._size > TOO_LARGE_BYTES_BODY: + if PY_36: + kwargs = {"source": self} + else: + kwargs = {} + warnings.warn( + "Sending a large body directly with raw bytes might" + " lock the event loop. You should probably pass an " + "io.BytesIO object instead", + ResourceWarning, + **kwargs, + ) + + async def write(self, writer: AbstractStreamWriter) -> None: + await writer.write(self._value) + + +class StringPayload(BytesPayload): + def __init__( + self, + value: Text, + *args: Any, + encoding: Optional[str] = None, + content_type: Optional[str] = None, + **kwargs: Any, + ) -> None: + + if encoding is None: + if content_type is None: + real_encoding = "utf-8" + content_type = "text/plain; charset=utf-8" + else: + mimetype = parse_mimetype(content_type) + real_encoding = mimetype.parameters.get("charset", "utf-8") + else: + if content_type is None: + content_type = "text/plain; charset=%s" % encoding + real_encoding = encoding + + super().__init__( + value.encode(real_encoding), + encoding=real_encoding, + content_type=content_type, + *args, + **kwargs, + ) + + +class StringIOPayload(StringPayload): + def __init__(self, value: IO[str], *args: Any, **kwargs: Any) -> None: + super().__init__(value.read(), *args, **kwargs) + + +class IOBasePayload(Payload): + def __init__( + self, value: IO[Any], disposition: str = "attachment", *args: Any, **kwargs: Any + ) -> None: + if "filename" not in kwargs: + kwargs["filename"] = guess_filename(value) + + super().__init__(value, *args, **kwargs) + + if self._filename is not None and disposition is not None: + if hdrs.CONTENT_DISPOSITION not in self.headers: + self.set_content_disposition(disposition, filename=self._filename) + + async def write(self, writer: AbstractStreamWriter) -> None: + loop = asyncio.get_event_loop() + try: + chunk = await loop.run_in_executor(None, self._value.read, 2 ** 16) + while chunk: + await writer.write(chunk) + chunk = await loop.run_in_executor(None, self._value.read, 2 ** 16) + finally: + await loop.run_in_executor(None, self._value.close) + + +class TextIOPayload(IOBasePayload): + def __init__( + self, + value: TextIO, + *args: Any, + encoding: Optional[str] = None, + content_type: Optional[str] = None, + **kwargs: Any, + ) -> None: + + if encoding is None: + if content_type is None: + encoding = "utf-8" + content_type = "text/plain; charset=utf-8" + else: + mimetype = parse_mimetype(content_type) + encoding = mimetype.parameters.get("charset", "utf-8") + else: + if content_type is None: + content_type = "text/plain; charset=%s" % encoding + + super().__init__( + value, + content_type=content_type, + encoding=encoding, + *args, + **kwargs, + ) + + @property + def size(self) -> Optional[int]: + try: + return os.fstat(self._value.fileno()).st_size - self._value.tell() + except OSError: + return None + + async def write(self, writer: AbstractStreamWriter) -> None: + loop = asyncio.get_event_loop() + try: + chunk = await loop.run_in_executor(None, self._value.read, 2 ** 16) + while chunk: + await writer.write(chunk.encode(self._encoding)) + chunk = await loop.run_in_executor(None, self._value.read, 2 ** 16) + finally: + await loop.run_in_executor(None, self._value.close) + + +class BytesIOPayload(IOBasePayload): + @property + def size(self) -> int: + position = self._value.tell() + end = self._value.seek(0, os.SEEK_END) + self._value.seek(position) + return end - position + + +class BufferedReaderPayload(IOBasePayload): + @property + def size(self) -> Optional[int]: + try: + return os.fstat(self._value.fileno()).st_size - self._value.tell() + except OSError: + # data.fileno() is not supported, e.g. + # io.BufferedReader(io.BytesIO(b'data')) + return None + + +class JsonPayload(BytesPayload): + def __init__( + self, + value: Any, + encoding: str = "utf-8", + content_type: str = "application/json", + dumps: JSONEncoder = json.dumps, + *args: Any, + **kwargs: Any, + ) -> None: + + super().__init__( + dumps(value).encode(encoding), + content_type=content_type, + encoding=encoding, + *args, + **kwargs, + ) + + +if TYPE_CHECKING: # pragma: no cover + from typing import AsyncIterable, AsyncIterator + + _AsyncIterator = AsyncIterator[bytes] + _AsyncIterable = AsyncIterable[bytes] +else: + from collections.abc import AsyncIterable, AsyncIterator + + _AsyncIterator = AsyncIterator + _AsyncIterable = AsyncIterable + + +class AsyncIterablePayload(Payload): + + _iter = None # type: Optional[_AsyncIterator] + + def __init__(self, value: _AsyncIterable, *args: Any, **kwargs: Any) -> None: + if not isinstance(value, AsyncIterable): + raise TypeError( + "value argument must support " + "collections.abc.AsyncIterablebe interface, " + "got {!r}".format(type(value)) + ) + + if "content_type" not in kwargs: + kwargs["content_type"] = "application/octet-stream" + + super().__init__(value, *args, **kwargs) + + self._iter = value.__aiter__() + + async def write(self, writer: AbstractStreamWriter) -> None: + if self._iter: + try: + # iter is not None check prevents rare cases + # when the case iterable is used twice + while True: + chunk = await self._iter.__anext__() + await writer.write(chunk) + except StopAsyncIteration: + self._iter = None + + +class StreamReaderPayload(AsyncIterablePayload): + def __init__(self, value: StreamReader, *args: Any, **kwargs: Any) -> None: + super().__init__(value.iter_any(), *args, **kwargs) + + +PAYLOAD_REGISTRY = PayloadRegistry() +PAYLOAD_REGISTRY.register(BytesPayload, (bytes, bytearray, memoryview)) +PAYLOAD_REGISTRY.register(StringPayload, str) +PAYLOAD_REGISTRY.register(StringIOPayload, io.StringIO) +PAYLOAD_REGISTRY.register(TextIOPayload, io.TextIOBase) +PAYLOAD_REGISTRY.register(BytesIOPayload, io.BytesIO) +PAYLOAD_REGISTRY.register(BufferedReaderPayload, (io.BufferedReader, io.BufferedRandom)) +PAYLOAD_REGISTRY.register(IOBasePayload, io.IOBase) +PAYLOAD_REGISTRY.register(StreamReaderPayload, StreamReader) +# try_last for giving a chance to more specialized async interables like +# multidict.BodyPartReaderPayload override the default +PAYLOAD_REGISTRY.register(AsyncIterablePayload, AsyncIterable, order=Order.try_last) diff --git a/dist/ba_data/python-site-packages/aiohttp/payload_streamer.py b/dist/ba_data/python-site-packages/aiohttp/payload_streamer.py new file mode 100644 index 0000000..3b2de15 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/payload_streamer.py @@ -0,0 +1,74 @@ +""" Payload implemenation for coroutines as data provider. + +As a simple case, you can upload data from file:: + + @aiohttp.streamer + async def file_sender(writer, file_name=None): + with open(file_name, 'rb') as f: + chunk = f.read(2**16) + while chunk: + await writer.write(chunk) + + chunk = f.read(2**16) + +Then you can use `file_sender` like this: + + async with session.post('http://httpbin.org/post', + data=file_sender(file_name='huge_file')) as resp: + print(await resp.text()) + +..note:: Coroutine must accept `writer` as first argument + +""" + +import types +import warnings +from typing import Any, Awaitable, Callable, Dict, Tuple + +from .abc import AbstractStreamWriter +from .payload import Payload, payload_type + +__all__ = ("streamer",) + + +class _stream_wrapper: + def __init__( + self, + coro: Callable[..., Awaitable[None]], + args: Tuple[Any, ...], + kwargs: Dict[str, Any], + ) -> None: + self.coro = types.coroutine(coro) + self.args = args + self.kwargs = kwargs + + async def __call__(self, writer: AbstractStreamWriter) -> None: + await self.coro(writer, *self.args, **self.kwargs) # type: ignore + + +class streamer: + def __init__(self, coro: Callable[..., Awaitable[None]]) -> None: + warnings.warn( + "@streamer is deprecated, use async generators instead", + DeprecationWarning, + stacklevel=2, + ) + self.coro = coro + + def __call__(self, *args: Any, **kwargs: Any) -> _stream_wrapper: + return _stream_wrapper(self.coro, args, kwargs) + + +@payload_type(_stream_wrapper) +class StreamWrapperPayload(Payload): + async def write(self, writer: AbstractStreamWriter) -> None: + await self._value(writer) + + +@payload_type(streamer) +class StreamPayload(StreamWrapperPayload): + def __init__(self, value: Any, *args: Any, **kwargs: Any) -> None: + super().__init__(value(), *args, **kwargs) + + async def write(self, writer: AbstractStreamWriter) -> None: + await self._value(writer) diff --git a/dist/ba_data/python-site-packages/aiohttp/py.typed b/dist/ba_data/python-site-packages/aiohttp/py.typed new file mode 100644 index 0000000..f5642f7 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/py.typed @@ -0,0 +1 @@ +Marker diff --git a/dist/ba_data/python-site-packages/aiohttp/pytest_plugin.py b/dist/ba_data/python-site-packages/aiohttp/pytest_plugin.py new file mode 100644 index 0000000..5204293 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/pytest_plugin.py @@ -0,0 +1,380 @@ +import asyncio +import contextlib +import warnings +from collections.abc import Callable + +import pytest + +from aiohttp.helpers import PY_37, isasyncgenfunction +from aiohttp.web import Application + +from .test_utils import ( + BaseTestServer, + RawTestServer, + TestClient, + TestServer, + loop_context, + setup_test_loop, + teardown_test_loop, + unused_port as _unused_port, +) + +try: + import uvloop +except ImportError: # pragma: no cover + uvloop = None + +try: + import tokio +except ImportError: # pragma: no cover + tokio = None + + +def pytest_addoption(parser): # type: ignore + parser.addoption( + "--aiohttp-fast", + action="store_true", + default=False, + help="run tests faster by disabling extra checks", + ) + parser.addoption( + "--aiohttp-loop", + action="store", + default="pyloop", + help="run tests with specific loop: pyloop, uvloop, tokio or all", + ) + parser.addoption( + "--aiohttp-enable-loop-debug", + action="store_true", + default=False, + help="enable event loop debug mode", + ) + + +def pytest_fixture_setup(fixturedef): # type: ignore + """ + Allow fixtures to be coroutines. Run coroutine fixtures in an event loop. + """ + func = fixturedef.func + + if isasyncgenfunction(func): + # async generator fixture + is_async_gen = True + elif asyncio.iscoroutinefunction(func): + # regular async fixture + is_async_gen = False + else: + # not an async fixture, nothing to do + return + + strip_request = False + if "request" not in fixturedef.argnames: + fixturedef.argnames += ("request",) + strip_request = True + + def wrapper(*args, **kwargs): # type: ignore + request = kwargs["request"] + if strip_request: + del kwargs["request"] + + # if neither the fixture nor the test use the 'loop' fixture, + # 'getfixturevalue' will fail because the test is not parameterized + # (this can be removed someday if 'loop' is no longer parameterized) + if "loop" not in request.fixturenames: + raise Exception( + "Asynchronous fixtures must depend on the 'loop' fixture or " + "be used in tests depending from it." + ) + + _loop = request.getfixturevalue("loop") + + if is_async_gen: + # for async generators, we need to advance the generator once, + # then advance it again in a finalizer + gen = func(*args, **kwargs) + + def finalizer(): # type: ignore + try: + return _loop.run_until_complete(gen.__anext__()) + except StopAsyncIteration: + pass + + request.addfinalizer(finalizer) + return _loop.run_until_complete(gen.__anext__()) + else: + return _loop.run_until_complete(func(*args, **kwargs)) + + fixturedef.func = wrapper + + +@pytest.fixture +def fast(request): # type: ignore + """--fast config option""" + return request.config.getoption("--aiohttp-fast") + + +@pytest.fixture +def loop_debug(request): # type: ignore + """--enable-loop-debug config option""" + return request.config.getoption("--aiohttp-enable-loop-debug") + + +@contextlib.contextmanager +def _runtime_warning_context(): # type: ignore + """ + Context manager which checks for RuntimeWarnings, specifically to + avoid "coroutine 'X' was never awaited" warnings being missed. + + If RuntimeWarnings occur in the context a RuntimeError is raised. + """ + with warnings.catch_warnings(record=True) as _warnings: + yield + rw = [ + "{w.filename}:{w.lineno}:{w.message}".format(w=w) + for w in _warnings + if w.category == RuntimeWarning + ] + if rw: + raise RuntimeError( + "{} Runtime Warning{},\n{}".format( + len(rw), "" if len(rw) == 1 else "s", "\n".join(rw) + ) + ) + + +@contextlib.contextmanager +def _passthrough_loop_context(loop, fast=False): # type: ignore + """ + setups and tears down a loop unless one is passed in via the loop + argument when it's passed straight through. + """ + if loop: + # loop already exists, pass it straight through + yield loop + else: + # this shadows loop_context's standard behavior + loop = setup_test_loop() + yield loop + teardown_test_loop(loop, fast=fast) + + +def pytest_pycollect_makeitem(collector, name, obj): # type: ignore + """ + Fix pytest collecting for coroutines. + """ + if collector.funcnamefilter(name) and asyncio.iscoroutinefunction(obj): + return list(collector._genfunctions(name, obj)) + + +def pytest_pyfunc_call(pyfuncitem): # type: ignore + """ + Run coroutines in an event loop instead of a normal function call. + """ + fast = pyfuncitem.config.getoption("--aiohttp-fast") + if asyncio.iscoroutinefunction(pyfuncitem.function): + existing_loop = pyfuncitem.funcargs.get( + "proactor_loop" + ) or pyfuncitem.funcargs.get("loop", None) + with _runtime_warning_context(): + with _passthrough_loop_context(existing_loop, fast=fast) as _loop: + testargs = { + arg: pyfuncitem.funcargs[arg] + for arg in pyfuncitem._fixtureinfo.argnames + } + _loop.run_until_complete(pyfuncitem.obj(**testargs)) + + return True + + +def pytest_generate_tests(metafunc): # type: ignore + if "loop_factory" not in metafunc.fixturenames: + return + + loops = metafunc.config.option.aiohttp_loop + avail_factories = {"pyloop": asyncio.DefaultEventLoopPolicy} + + if uvloop is not None: # pragma: no cover + avail_factories["uvloop"] = uvloop.EventLoopPolicy + + if tokio is not None: # pragma: no cover + avail_factories["tokio"] = tokio.EventLoopPolicy + + if loops == "all": + loops = "pyloop,uvloop?,tokio?" + + factories = {} # type: ignore + for name in loops.split(","): + required = not name.endswith("?") + name = name.strip(" ?") + if name not in avail_factories: # pragma: no cover + if required: + raise ValueError( + "Unknown loop '%s', available loops: %s" + % (name, list(factories.keys())) + ) + else: + continue + factories[name] = avail_factories[name] + metafunc.parametrize( + "loop_factory", list(factories.values()), ids=list(factories.keys()) + ) + + +@pytest.fixture +def loop(loop_factory, fast, loop_debug): # type: ignore + """Return an instance of the event loop.""" + policy = loop_factory() + asyncio.set_event_loop_policy(policy) + with loop_context(fast=fast) as _loop: + if loop_debug: + _loop.set_debug(True) # pragma: no cover + asyncio.set_event_loop(_loop) + yield _loop + + +@pytest.fixture +def proactor_loop(): # type: ignore + if not PY_37: + policy = asyncio.get_event_loop_policy() + policy._loop_factory = asyncio.ProactorEventLoop # type: ignore + else: + policy = asyncio.WindowsProactorEventLoopPolicy() # type: ignore + asyncio.set_event_loop_policy(policy) + + with loop_context(policy.new_event_loop) as _loop: + asyncio.set_event_loop(_loop) + yield _loop + + +@pytest.fixture +def unused_port(aiohttp_unused_port): # type: ignore # pragma: no cover + warnings.warn( + "Deprecated, use aiohttp_unused_port fixture instead", + DeprecationWarning, + stacklevel=2, + ) + return aiohttp_unused_port + + +@pytest.fixture +def aiohttp_unused_port(): # type: ignore + """Return a port that is unused on the current host.""" + return _unused_port + + +@pytest.fixture +def aiohttp_server(loop): # type: ignore + """Factory to create a TestServer instance, given an app. + + aiohttp_server(app, **kwargs) + """ + servers = [] + + async def go(app, *, port=None, **kwargs): # type: ignore + server = TestServer(app, port=port) + await server.start_server(loop=loop, **kwargs) + servers.append(server) + return server + + yield go + + async def finalize(): # type: ignore + while servers: + await servers.pop().close() + + loop.run_until_complete(finalize()) + + +@pytest.fixture +def test_server(aiohttp_server): # type: ignore # pragma: no cover + warnings.warn( + "Deprecated, use aiohttp_server fixture instead", + DeprecationWarning, + stacklevel=2, + ) + return aiohttp_server + + +@pytest.fixture +def aiohttp_raw_server(loop): # type: ignore + """Factory to create a RawTestServer instance, given a web handler. + + aiohttp_raw_server(handler, **kwargs) + """ + servers = [] + + async def go(handler, *, port=None, **kwargs): # type: ignore + server = RawTestServer(handler, port=port) + await server.start_server(loop=loop, **kwargs) + servers.append(server) + return server + + yield go + + async def finalize(): # type: ignore + while servers: + await servers.pop().close() + + loop.run_until_complete(finalize()) + + +@pytest.fixture +def raw_test_server(aiohttp_raw_server): # type: ignore # pragma: no cover + warnings.warn( + "Deprecated, use aiohttp_raw_server fixture instead", + DeprecationWarning, + stacklevel=2, + ) + return aiohttp_raw_server + + +@pytest.fixture +def aiohttp_client(loop): # type: ignore + """Factory to create a TestClient instance. + + aiohttp_client(app, **kwargs) + aiohttp_client(server, **kwargs) + aiohttp_client(raw_server, **kwargs) + """ + clients = [] + + async def go(__param, *args, server_kwargs=None, **kwargs): # type: ignore + + if isinstance(__param, Callable) and not isinstance( # type: ignore + __param, (Application, BaseTestServer) + ): + __param = __param(loop, *args, **kwargs) + kwargs = {} + else: + assert not args, "args should be empty" + + if isinstance(__param, Application): + server_kwargs = server_kwargs or {} + server = TestServer(__param, loop=loop, **server_kwargs) + client = TestClient(server, loop=loop, **kwargs) + elif isinstance(__param, BaseTestServer): + client = TestClient(__param, loop=loop, **kwargs) + else: + raise ValueError("Unknown argument type: %r" % type(__param)) + + await client.start_server() + clients.append(client) + return client + + yield go + + async def finalize(): # type: ignore + while clients: + await clients.pop().close() + + loop.run_until_complete(finalize()) + + +@pytest.fixture +def test_client(aiohttp_client): # type: ignore # pragma: no cover + warnings.warn( + "Deprecated, use aiohttp_client fixture instead", + DeprecationWarning, + stacklevel=2, + ) + return aiohttp_client diff --git a/dist/ba_data/python-site-packages/aiohttp/resolver.py b/dist/ba_data/python-site-packages/aiohttp/resolver.py new file mode 100644 index 0000000..2974bca --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/resolver.py @@ -0,0 +1,149 @@ +import asyncio +import socket +from typing import Any, Dict, List, Optional + +from .abc import AbstractResolver +from .helpers import get_running_loop + +__all__ = ("ThreadedResolver", "AsyncResolver", "DefaultResolver") + +try: + import aiodns + + # aiodns_default = hasattr(aiodns.DNSResolver, 'gethostbyname') +except ImportError: # pragma: no cover + aiodns = None + +aiodns_default = False + + +class ThreadedResolver(AbstractResolver): + """Use Executor for synchronous getaddrinfo() calls, which defaults to + concurrent.futures.ThreadPoolExecutor. + """ + + def __init__(self, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: + self._loop = get_running_loop(loop) + + async def resolve( + self, hostname: str, port: int = 0, family: int = socket.AF_INET + ) -> List[Dict[str, Any]]: + infos = await self._loop.getaddrinfo( + hostname, + port, + type=socket.SOCK_STREAM, + family=family, + flags=socket.AI_ADDRCONFIG, + ) + + hosts = [] + for family, _, proto, _, address in infos: + if family == socket.AF_INET6 and address[3]: # type: ignore + # This is essential for link-local IPv6 addresses. + # LL IPv6 is a VERY rare case. Strictly speaking, we should use + # getnameinfo() unconditionally, but performance makes sense. + host, _port = socket.getnameinfo( + address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV + ) + port = int(_port) + else: + host, port = address[:2] + hosts.append( + { + "hostname": hostname, + "host": host, + "port": port, + "family": family, + "proto": proto, + "flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV, + } + ) + + return hosts + + async def close(self) -> None: + pass + + +class AsyncResolver(AbstractResolver): + """Use the `aiodns` package to make asynchronous DNS lookups""" + + def __init__( + self, + loop: Optional[asyncio.AbstractEventLoop] = None, + *args: Any, + **kwargs: Any + ) -> None: + if aiodns is None: + raise RuntimeError("Resolver requires aiodns library") + + self._loop = get_running_loop(loop) + self._resolver = aiodns.DNSResolver(*args, loop=loop, **kwargs) + + if not hasattr(self._resolver, "gethostbyname"): + # aiodns 1.1 is not available, fallback to DNSResolver.query + self.resolve = self._resolve_with_query # type: ignore + + async def resolve( + self, host: str, port: int = 0, family: int = socket.AF_INET + ) -> List[Dict[str, Any]]: + try: + resp = await self._resolver.gethostbyname(host, family) + except aiodns.error.DNSError as exc: + msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed" + raise OSError(msg) from exc + hosts = [] + for address in resp.addresses: + hosts.append( + { + "hostname": host, + "host": address, + "port": port, + "family": family, + "proto": 0, + "flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV, + } + ) + + if not hosts: + raise OSError("DNS lookup failed") + + return hosts + + async def _resolve_with_query( + self, host: str, port: int = 0, family: int = socket.AF_INET + ) -> List[Dict[str, Any]]: + if family == socket.AF_INET6: + qtype = "AAAA" + else: + qtype = "A" + + try: + resp = await self._resolver.query(host, qtype) + except aiodns.error.DNSError as exc: + msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed" + raise OSError(msg) from exc + + hosts = [] + for rr in resp: + hosts.append( + { + "hostname": host, + "host": rr.host, + "port": port, + "family": family, + "proto": 0, + "flags": socket.AI_NUMERICHOST, + } + ) + + if not hosts: + raise OSError("DNS lookup failed") + + return hosts + + async def close(self) -> None: + return self._resolver.cancel() + + +DefaultResolver = AsyncResolver if aiodns_default else ThreadedResolver diff --git a/dist/ba_data/python-site-packages/aiohttp/signals.py b/dist/ba_data/python-site-packages/aiohttp/signals.py new file mode 100644 index 0000000..d406c02 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/signals.py @@ -0,0 +1,34 @@ +from aiohttp.frozenlist import FrozenList + +__all__ = ("Signal",) + + +class Signal(FrozenList): + """Coroutine-based signal implementation. + + To connect a callback to a signal, use any list method. + + Signals are fired using the send() coroutine, which takes named + arguments. + """ + + __slots__ = ("_owner",) + + def __init__(self, owner): + super().__init__() + self._owner = owner + + def __repr__(self): + return "".format( + self._owner, self.frozen, list(self) + ) + + async def send(self, *args, **kwargs): + """ + Sends data to all registered receivers. + """ + if not self.frozen: + raise RuntimeError("Cannot send non-frozen signal.") + + for receiver in self: + await receiver(*args, **kwargs) # type: ignore diff --git a/dist/ba_data/python-site-packages/aiohttp/signals.pyi b/dist/ba_data/python-site-packages/aiohttp/signals.pyi new file mode 100644 index 0000000..455f8e2 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/signals.pyi @@ -0,0 +1,12 @@ +from typing import Any, Generic, TypeVar + +from aiohttp.frozenlist import FrozenList + +__all__ = ("Signal",) + +_T = TypeVar("_T") + +class Signal(FrozenList[_T], Generic[_T]): + def __init__(self, owner: Any) -> None: ... + def __repr__(self) -> str: ... + async def send(self, *args: Any, **kwargs: Any) -> None: ... diff --git a/dist/ba_data/python-site-packages/aiohttp/streams.py b/dist/ba_data/python-site-packages/aiohttp/streams.py new file mode 100644 index 0000000..42970b5 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/streams.py @@ -0,0 +1,647 @@ +import asyncio +import collections +import warnings +from typing import Awaitable, Callable, Generic, List, Optional, Tuple, TypeVar + +from .base_protocol import BaseProtocol +from .helpers import BaseTimerContext, set_exception, set_result +from .log import internal_logger + +try: # pragma: no cover + from typing import Deque +except ImportError: + from typing_extensions import Deque + +__all__ = ( + "EMPTY_PAYLOAD", + "EofStream", + "StreamReader", + "DataQueue", + "FlowControlDataQueue", +) + +_T = TypeVar("_T") + + +class EofStream(Exception): + """eof stream indication.""" + + +class AsyncStreamIterator(Generic[_T]): + def __init__(self, read_func: Callable[[], Awaitable[_T]]) -> None: + self.read_func = read_func + + def __aiter__(self) -> "AsyncStreamIterator[_T]": + return self + + async def __anext__(self) -> _T: + try: + rv = await self.read_func() + except EofStream: + raise StopAsyncIteration + if rv == b"": + raise StopAsyncIteration + return rv + + +class ChunkTupleAsyncStreamIterator: + def __init__(self, stream: "StreamReader") -> None: + self._stream = stream + + def __aiter__(self) -> "ChunkTupleAsyncStreamIterator": + return self + + async def __anext__(self) -> Tuple[bytes, bool]: + rv = await self._stream.readchunk() + if rv == (b"", False): + raise StopAsyncIteration + return rv + + +class AsyncStreamReaderMixin: + def __aiter__(self) -> AsyncStreamIterator[bytes]: + return AsyncStreamIterator(self.readline) # type: ignore + + def iter_chunked(self, n: int) -> AsyncStreamIterator[bytes]: + """Returns an asynchronous iterator that yields chunks of size n. + + Python-3.5 available for Python 3.5+ only + """ + return AsyncStreamIterator(lambda: self.read(n)) # type: ignore + + def iter_any(self) -> AsyncStreamIterator[bytes]: + """Returns an asynchronous iterator that yields all the available + data as soon as it is received + + Python-3.5 available for Python 3.5+ only + """ + return AsyncStreamIterator(self.readany) # type: ignore + + def iter_chunks(self) -> ChunkTupleAsyncStreamIterator: + """Returns an asynchronous iterator that yields chunks of data + as they are received by the server. The yielded objects are tuples + of (bytes, bool) as returned by the StreamReader.readchunk method. + + Python-3.5 available for Python 3.5+ only + """ + return ChunkTupleAsyncStreamIterator(self) # type: ignore + + +class StreamReader(AsyncStreamReaderMixin): + """An enhancement of asyncio.StreamReader. + + Supports asynchronous iteration by line, chunk or as available:: + + async for line in reader: + ... + async for chunk in reader.iter_chunked(1024): + ... + async for slice in reader.iter_any(): + ... + + """ + + total_bytes = 0 + + def __init__( + self, + protocol: BaseProtocol, + limit: int, + *, + timer: Optional[BaseTimerContext] = None, + loop: Optional[asyncio.AbstractEventLoop] = None + ) -> None: + self._protocol = protocol + self._low_water = limit + self._high_water = limit * 2 + if loop is None: + loop = asyncio.get_event_loop() + self._loop = loop + self._size = 0 + self._cursor = 0 + self._http_chunk_splits = None # type: Optional[List[int]] + self._buffer = collections.deque() # type: Deque[bytes] + self._buffer_offset = 0 + self._eof = False + self._waiter = None # type: Optional[asyncio.Future[None]] + self._eof_waiter = None # type: Optional[asyncio.Future[None]] + self._exception = None # type: Optional[BaseException] + self._timer = timer + self._eof_callbacks = [] # type: List[Callable[[], None]] + + def __repr__(self) -> str: + info = [self.__class__.__name__] + if self._size: + info.append("%d bytes" % self._size) + if self._eof: + info.append("eof") + if self._low_water != 2 ** 16: # default limit + info.append("low=%d high=%d" % (self._low_water, self._high_water)) + if self._waiter: + info.append("w=%r" % self._waiter) + if self._exception: + info.append("e=%r" % self._exception) + return "<%s>" % " ".join(info) + + def get_read_buffer_limits(self) -> Tuple[int, int]: + return (self._low_water, self._high_water) + + def exception(self) -> Optional[BaseException]: + return self._exception + + def set_exception(self, exc: BaseException) -> None: + self._exception = exc + self._eof_callbacks.clear() + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_exception(waiter, exc) + + waiter = self._eof_waiter + if waiter is not None: + self._eof_waiter = None + set_exception(waiter, exc) + + def on_eof(self, callback: Callable[[], None]) -> None: + if self._eof: + try: + callback() + except Exception: + internal_logger.exception("Exception in eof callback") + else: + self._eof_callbacks.append(callback) + + def feed_eof(self) -> None: + self._eof = True + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + waiter = self._eof_waiter + if waiter is not None: + self._eof_waiter = None + set_result(waiter, None) + + for cb in self._eof_callbacks: + try: + cb() + except Exception: + internal_logger.exception("Exception in eof callback") + + self._eof_callbacks.clear() + + def is_eof(self) -> bool: + """Return True if 'feed_eof' was called.""" + return self._eof + + def at_eof(self) -> bool: + """Return True if the buffer is empty and 'feed_eof' was called.""" + return self._eof and not self._buffer + + async def wait_eof(self) -> None: + if self._eof: + return + + assert self._eof_waiter is None + self._eof_waiter = self._loop.create_future() + try: + await self._eof_waiter + finally: + self._eof_waiter = None + + def unread_data(self, data: bytes) -> None: + """rollback reading some data from stream, inserting it to buffer head.""" + warnings.warn( + "unread_data() is deprecated " + "and will be removed in future releases (#3260)", + DeprecationWarning, + stacklevel=2, + ) + if not data: + return + + if self._buffer_offset: + self._buffer[0] = self._buffer[0][self._buffer_offset :] + self._buffer_offset = 0 + self._size += len(data) + self._cursor -= len(data) + self._buffer.appendleft(data) + self._eof_counter = 0 + + # TODO: size is ignored, remove the param later + def feed_data(self, data: bytes, size: int = 0) -> None: + assert not self._eof, "feed_data after feed_eof" + + if not data: + return + + self._size += len(data) + self._buffer.append(data) + self.total_bytes += len(data) + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + if self._size > self._high_water and not self._protocol._reading_paused: + self._protocol.pause_reading() + + def begin_http_chunk_receiving(self) -> None: + if self._http_chunk_splits is None: + if self.total_bytes: + raise RuntimeError( + "Called begin_http_chunk_receiving when" "some data was already fed" + ) + self._http_chunk_splits = [] + + def end_http_chunk_receiving(self) -> None: + if self._http_chunk_splits is None: + raise RuntimeError( + "Called end_chunk_receiving without calling " + "begin_chunk_receiving first" + ) + + # self._http_chunk_splits contains logical byte offsets from start of + # the body transfer. Each offset is the offset of the end of a chunk. + # "Logical" means bytes, accessible for a user. + # If no chunks containig logical data were received, current position + # is difinitely zero. + pos = self._http_chunk_splits[-1] if self._http_chunk_splits else 0 + + if self.total_bytes == pos: + # We should not add empty chunks here. So we check for that. + # Note, when chunked + gzip is used, we can receive a chunk + # of compressed data, but that data may not be enough for gzip FSM + # to yield any uncompressed data. That's why current position may + # not change after receiving a chunk. + return + + self._http_chunk_splits.append(self.total_bytes) + + # wake up readchunk when end of http chunk received + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + async def _wait(self, func_name: str) -> None: + # StreamReader uses a future to link the protocol feed_data() method + # to a read coroutine. Running two read coroutines at the same time + # would have an unexpected behaviour. It would not possible to know + # which coroutine would get the next data. + if self._waiter is not None: + raise RuntimeError( + "%s() called while another coroutine is " + "already waiting for incoming data" % func_name + ) + + waiter = self._waiter = self._loop.create_future() + try: + if self._timer: + with self._timer: + await waiter + else: + await waiter + finally: + self._waiter = None + + async def readline(self) -> bytes: + if self._exception is not None: + raise self._exception + + line = [] + line_size = 0 + not_enough = True + + while not_enough: + while self._buffer and not_enough: + offset = self._buffer_offset + ichar = self._buffer[0].find(b"\n", offset) + 1 + # Read from current offset to found b'\n' or to the end. + data = self._read_nowait_chunk(ichar - offset if ichar else -1) + line.append(data) + line_size += len(data) + if ichar: + not_enough = False + + if line_size > self._high_water: + raise ValueError("Line is too long") + + if self._eof: + break + + if not_enough: + await self._wait("readline") + + return b"".join(line) + + async def read(self, n: int = -1) -> bytes: + if self._exception is not None: + raise self._exception + + # migration problem; with DataQueue you have to catch + # EofStream exception, so common way is to run payload.read() inside + # infinite loop. what can cause real infinite loop with StreamReader + # lets keep this code one major release. + if __debug__: + if self._eof and not self._buffer: + self._eof_counter = getattr(self, "_eof_counter", 0) + 1 + if self._eof_counter > 5: + internal_logger.warning( + "Multiple access to StreamReader in eof state, " + "might be infinite loop.", + stack_info=True, + ) + + if not n: + return b"" + + if n < 0: + # This used to just loop creating a new waiter hoping to + # collect everything in self._buffer, but that would + # deadlock if the subprocess sends more than self.limit + # bytes. So just call self.readany() until EOF. + blocks = [] + while True: + block = await self.readany() + if not block: + break + blocks.append(block) + return b"".join(blocks) + + # TODO: should be `if` instead of `while` + # because waiter maybe triggered on chunk end, + # without feeding any data + while not self._buffer and not self._eof: + await self._wait("read") + + return self._read_nowait(n) + + async def readany(self) -> bytes: + if self._exception is not None: + raise self._exception + + # TODO: should be `if` instead of `while` + # because waiter maybe triggered on chunk end, + # without feeding any data + while not self._buffer and not self._eof: + await self._wait("readany") + + return self._read_nowait(-1) + + async def readchunk(self) -> Tuple[bytes, bool]: + """Returns a tuple of (data, end_of_http_chunk). When chunked transfer + encoding is used, end_of_http_chunk is a boolean indicating if the end + of the data corresponds to the end of a HTTP chunk , otherwise it is + always False. + """ + while True: + if self._exception is not None: + raise self._exception + + while self._http_chunk_splits: + pos = self._http_chunk_splits.pop(0) + if pos == self._cursor: + return (b"", True) + if pos > self._cursor: + return (self._read_nowait(pos - self._cursor), True) + internal_logger.warning( + "Skipping HTTP chunk end due to data " + "consumption beyond chunk boundary" + ) + + if self._buffer: + return (self._read_nowait_chunk(-1), False) + # return (self._read_nowait(-1), False) + + if self._eof: + # Special case for signifying EOF. + # (b'', True) is not a final return value actually. + return (b"", False) + + await self._wait("readchunk") + + async def readexactly(self, n: int) -> bytes: + if self._exception is not None: + raise self._exception + + blocks = [] # type: List[bytes] + while n > 0: + block = await self.read(n) + if not block: + partial = b"".join(blocks) + raise asyncio.IncompleteReadError(partial, len(partial) + n) + blocks.append(block) + n -= len(block) + + return b"".join(blocks) + + def read_nowait(self, n: int = -1) -> bytes: + # default was changed to be consistent with .read(-1) + # + # I believe the most users don't know about the method and + # they are not affected. + if self._exception is not None: + raise self._exception + + if self._waiter and not self._waiter.done(): + raise RuntimeError( + "Called while some coroutine is waiting for incoming data." + ) + + return self._read_nowait(n) + + def _read_nowait_chunk(self, n: int) -> bytes: + first_buffer = self._buffer[0] + offset = self._buffer_offset + if n != -1 and len(first_buffer) - offset > n: + data = first_buffer[offset : offset + n] + self._buffer_offset += n + + elif offset: + self._buffer.popleft() + data = first_buffer[offset:] + self._buffer_offset = 0 + + else: + data = self._buffer.popleft() + + self._size -= len(data) + self._cursor += len(data) + + chunk_splits = self._http_chunk_splits + # Prevent memory leak: drop useless chunk splits + while chunk_splits and chunk_splits[0] < self._cursor: + chunk_splits.pop(0) + + if self._size < self._low_water and self._protocol._reading_paused: + self._protocol.resume_reading() + return data + + def _read_nowait(self, n: int) -> bytes: + """ Read not more than n bytes, or whole buffer if n == -1 """ + chunks = [] + + while self._buffer: + chunk = self._read_nowait_chunk(n) + chunks.append(chunk) + if n != -1: + n -= len(chunk) + if n == 0: + break + + return b"".join(chunks) if chunks else b"" + + +class EmptyStreamReader(AsyncStreamReaderMixin): + def exception(self) -> Optional[BaseException]: + return None + + def set_exception(self, exc: BaseException) -> None: + pass + + def on_eof(self, callback: Callable[[], None]) -> None: + try: + callback() + except Exception: + internal_logger.exception("Exception in eof callback") + + def feed_eof(self) -> None: + pass + + def is_eof(self) -> bool: + return True + + def at_eof(self) -> bool: + return True + + async def wait_eof(self) -> None: + return + + def feed_data(self, data: bytes, n: int = 0) -> None: + pass + + async def readline(self) -> bytes: + return b"" + + async def read(self, n: int = -1) -> bytes: + return b"" + + async def readany(self) -> bytes: + return b"" + + async def readchunk(self) -> Tuple[bytes, bool]: + return (b"", True) + + async def readexactly(self, n: int) -> bytes: + raise asyncio.IncompleteReadError(b"", n) + + def read_nowait(self) -> bytes: + return b"" + + +EMPTY_PAYLOAD = EmptyStreamReader() + + +class DataQueue(Generic[_T]): + """DataQueue is a general-purpose blocking queue with one reader.""" + + def __init__(self, loop: asyncio.AbstractEventLoop) -> None: + self._loop = loop + self._eof = False + self._waiter = None # type: Optional[asyncio.Future[None]] + self._exception = None # type: Optional[BaseException] + self._size = 0 + self._buffer = collections.deque() # type: Deque[Tuple[_T, int]] + + def __len__(self) -> int: + return len(self._buffer) + + def is_eof(self) -> bool: + return self._eof + + def at_eof(self) -> bool: + return self._eof and not self._buffer + + def exception(self) -> Optional[BaseException]: + return self._exception + + def set_exception(self, exc: BaseException) -> None: + self._eof = True + self._exception = exc + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_exception(waiter, exc) + + def feed_data(self, data: _T, size: int = 0) -> None: + self._size += size + self._buffer.append((data, size)) + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + def feed_eof(self) -> None: + self._eof = True + + waiter = self._waiter + if waiter is not None: + self._waiter = None + set_result(waiter, None) + + async def read(self) -> _T: + if not self._buffer and not self._eof: + assert not self._waiter + self._waiter = self._loop.create_future() + try: + await self._waiter + except (asyncio.CancelledError, asyncio.TimeoutError): + self._waiter = None + raise + + if self._buffer: + data, size = self._buffer.popleft() + self._size -= size + return data + else: + if self._exception is not None: + raise self._exception + else: + raise EofStream + + def __aiter__(self) -> AsyncStreamIterator[_T]: + return AsyncStreamIterator(self.read) + + +class FlowControlDataQueue(DataQueue[_T]): + """FlowControlDataQueue resumes and pauses an underlying stream. + + It is a destination for parsed data.""" + + def __init__( + self, protocol: BaseProtocol, limit: int, *, loop: asyncio.AbstractEventLoop + ) -> None: + super().__init__(loop=loop) + + self._protocol = protocol + self._limit = limit * 2 + + def feed_data(self, data: _T, size: int = 0) -> None: + super().feed_data(data, size) + + if self._size > self._limit and not self._protocol._reading_paused: + self._protocol.pause_reading() + + async def read(self) -> _T: + try: + return await super().read() + finally: + if self._size < self._limit and self._protocol._reading_paused: + self._protocol.resume_reading() diff --git a/dist/ba_data/python-site-packages/aiohttp/tcp_helpers.py b/dist/ba_data/python-site-packages/aiohttp/tcp_helpers.py new file mode 100644 index 0000000..0e1dbf1 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/tcp_helpers.py @@ -0,0 +1,38 @@ +"""Helper methods to tune a TCP connection""" + +import asyncio +import socket +from contextlib import suppress +from typing import Optional # noqa + +__all__ = ("tcp_keepalive", "tcp_nodelay") + + +if hasattr(socket, "SO_KEEPALIVE"): + + def tcp_keepalive(transport: asyncio.Transport) -> None: + sock = transport.get_extra_info("socket") + if sock is not None: + sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) + + +else: + + def tcp_keepalive(transport: asyncio.Transport) -> None: # pragma: no cover + pass + + +def tcp_nodelay(transport: asyncio.Transport, value: bool) -> None: + sock = transport.get_extra_info("socket") + + if sock is None: + return + + if sock.family not in (socket.AF_INET, socket.AF_INET6): + return + + value = bool(value) + + # socket may be closed already, on windows OSError get raised + with suppress(OSError): + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, value) diff --git a/dist/ba_data/python-site-packages/aiohttp/test_utils.py b/dist/ba_data/python-site-packages/aiohttp/test_utils.py new file mode 100644 index 0000000..7a9ca7d --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/test_utils.py @@ -0,0 +1,676 @@ +"""Utilities shared by tests.""" + +import asyncio +import contextlib +import functools +import gc +import inspect +import os +import socket +import sys +import unittest +from abc import ABC, abstractmethod +from types import TracebackType +from typing import TYPE_CHECKING, Any, Callable, Iterator, List, Optional, Type, Union +from unittest import mock + +from multidict import CIMultiDict, CIMultiDictProxy +from yarl import URL + +import aiohttp +from aiohttp.client import ( + ClientResponse, + _RequestContextManager, + _WSRequestContextManager, +) + +from . import ClientSession, hdrs +from .abc import AbstractCookieJar +from .client_reqrep import ClientResponse +from .client_ws import ClientWebSocketResponse +from .helpers import sentinel +from .http import HttpVersion, RawRequestMessage +from .signals import Signal +from .web import ( + Application, + AppRunner, + BaseRunner, + Request, + Server, + ServerRunner, + SockSite, + UrlMappingMatchInfo, +) +from .web_protocol import _RequestHandler + +if TYPE_CHECKING: # pragma: no cover + from ssl import SSLContext +else: + SSLContext = None + + +REUSE_ADDRESS = os.name == "posix" and sys.platform != "cygwin" + + +def get_unused_port_socket(host: str) -> socket.socket: + return get_port_socket(host, 0) + + +def get_port_socket(host: str, port: int) -> socket.socket: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if REUSE_ADDRESS: + # Windows has different semantics for SO_REUSEADDR, + # so don't set it. Ref: + # https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind((host, port)) + return s + + +def unused_port() -> int: + """Return a port that is unused on the current host.""" + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind(("127.0.0.1", 0)) + return s.getsockname()[1] + + +class BaseTestServer(ABC): + __test__ = False + + def __init__( + self, + *, + scheme: Union[str, object] = sentinel, + loop: Optional[asyncio.AbstractEventLoop] = None, + host: str = "127.0.0.1", + port: Optional[int] = None, + skip_url_asserts: bool = False, + **kwargs: Any, + ) -> None: + self._loop = loop + self.runner = None # type: Optional[BaseRunner] + self._root = None # type: Optional[URL] + self.host = host + self.port = port + self._closed = False + self.scheme = scheme + self.skip_url_asserts = skip_url_asserts + + async def start_server( + self, loop: Optional[asyncio.AbstractEventLoop] = None, **kwargs: Any + ) -> None: + if self.runner: + return + self._loop = loop + self._ssl = kwargs.pop("ssl", None) + self.runner = await self._make_runner(**kwargs) + await self.runner.setup() + if not self.port: + self.port = 0 + _sock = get_port_socket(self.host, self.port) + self.host, self.port = _sock.getsockname()[:2] + site = SockSite(self.runner, sock=_sock, ssl_context=self._ssl) + await site.start() + server = site._server + assert server is not None + sockets = server.sockets + assert sockets is not None + self.port = sockets[0].getsockname()[1] + if self.scheme is sentinel: + if self._ssl: + scheme = "https" + else: + scheme = "http" + self.scheme = scheme + self._root = URL(f"{self.scheme}://{self.host}:{self.port}") + + @abstractmethod # pragma: no cover + async def _make_runner(self, **kwargs: Any) -> BaseRunner: + pass + + def make_url(self, path: str) -> URL: + assert self._root is not None + url = URL(path) + if not self.skip_url_asserts: + assert not url.is_absolute() + return self._root.join(url) + else: + return URL(str(self._root) + path) + + @property + def started(self) -> bool: + return self.runner is not None + + @property + def closed(self) -> bool: + return self._closed + + @property + def handler(self) -> Server: + # for backward compatibility + # web.Server instance + runner = self.runner + assert runner is not None + assert runner.server is not None + return runner.server + + async def close(self) -> None: + """Close all fixtures created by the test client. + + After that point, the TestClient is no longer usable. + + This is an idempotent function: running close multiple times + will not have any additional effects. + + close is also run when the object is garbage collected, and on + exit when used as a context manager. + + """ + if self.started and not self.closed: + assert self.runner is not None + await self.runner.cleanup() + self._root = None + self.port = None + self._closed = True + + def __enter__(self) -> None: + raise TypeError("Use async with instead") + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_value: Optional[BaseException], + traceback: Optional[TracebackType], + ) -> None: + # __exit__ should exist in pair with __enter__ but never executed + pass # pragma: no cover + + async def __aenter__(self) -> "BaseTestServer": + await self.start_server(loop=self._loop) + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_value: Optional[BaseException], + traceback: Optional[TracebackType], + ) -> None: + await self.close() + + +class TestServer(BaseTestServer): + def __init__( + self, + app: Application, + *, + scheme: Union[str, object] = sentinel, + host: str = "127.0.0.1", + port: Optional[int] = None, + **kwargs: Any, + ): + self.app = app + super().__init__(scheme=scheme, host=host, port=port, **kwargs) + + async def _make_runner(self, **kwargs: Any) -> BaseRunner: + return AppRunner(self.app, **kwargs) + + +class RawTestServer(BaseTestServer): + def __init__( + self, + handler: _RequestHandler, + *, + scheme: Union[str, object] = sentinel, + host: str = "127.0.0.1", + port: Optional[int] = None, + **kwargs: Any, + ) -> None: + self._handler = handler + super().__init__(scheme=scheme, host=host, port=port, **kwargs) + + async def _make_runner(self, debug: bool = True, **kwargs: Any) -> ServerRunner: + srv = Server(self._handler, loop=self._loop, debug=debug, **kwargs) + return ServerRunner(srv, debug=debug, **kwargs) + + +class TestClient: + """ + A test client implementation. + + To write functional tests for aiohttp based servers. + + """ + + __test__ = False + + def __init__( + self, + server: BaseTestServer, + *, + cookie_jar: Optional[AbstractCookieJar] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + **kwargs: Any, + ) -> None: + if not isinstance(server, BaseTestServer): + raise TypeError( + "server must be TestServer " "instance, found type: %r" % type(server) + ) + self._server = server + self._loop = loop + if cookie_jar is None: + cookie_jar = aiohttp.CookieJar(unsafe=True, loop=loop) + self._session = ClientSession(loop=loop, cookie_jar=cookie_jar, **kwargs) + self._closed = False + self._responses = [] # type: List[ClientResponse] + self._websockets = [] # type: List[ClientWebSocketResponse] + + async def start_server(self) -> None: + await self._server.start_server(loop=self._loop) + + @property + def host(self) -> str: + return self._server.host + + @property + def port(self) -> Optional[int]: + return self._server.port + + @property + def server(self) -> BaseTestServer: + return self._server + + @property + def app(self) -> Application: + return getattr(self._server, "app", None) + + @property + def session(self) -> ClientSession: + """An internal aiohttp.ClientSession. + + Unlike the methods on the TestClient, client session requests + do not automatically include the host in the url queried, and + will require an absolute path to the resource. + + """ + return self._session + + def make_url(self, path: str) -> URL: + return self._server.make_url(path) + + async def _request(self, method: str, path: str, **kwargs: Any) -> ClientResponse: + resp = await self._session.request(method, self.make_url(path), **kwargs) + # save it to close later + self._responses.append(resp) + return resp + + def request(self, method: str, path: str, **kwargs: Any) -> _RequestContextManager: + """Routes a request to tested http server. + + The interface is identical to aiohttp.ClientSession.request, + except the loop kwarg is overridden by the instance used by the + test server. + + """ + return _RequestContextManager(self._request(method, path, **kwargs)) + + def get(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP GET request.""" + return _RequestContextManager(self._request(hdrs.METH_GET, path, **kwargs)) + + def post(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP POST request.""" + return _RequestContextManager(self._request(hdrs.METH_POST, path, **kwargs)) + + def options(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP OPTIONS request.""" + return _RequestContextManager(self._request(hdrs.METH_OPTIONS, path, **kwargs)) + + def head(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP HEAD request.""" + return _RequestContextManager(self._request(hdrs.METH_HEAD, path, **kwargs)) + + def put(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP PUT request.""" + return _RequestContextManager(self._request(hdrs.METH_PUT, path, **kwargs)) + + def patch(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP PATCH request.""" + return _RequestContextManager(self._request(hdrs.METH_PATCH, path, **kwargs)) + + def delete(self, path: str, **kwargs: Any) -> _RequestContextManager: + """Perform an HTTP PATCH request.""" + return _RequestContextManager(self._request(hdrs.METH_DELETE, path, **kwargs)) + + def ws_connect(self, path: str, **kwargs: Any) -> _WSRequestContextManager: + """Initiate websocket connection. + + The api corresponds to aiohttp.ClientSession.ws_connect. + + """ + return _WSRequestContextManager(self._ws_connect(path, **kwargs)) + + async def _ws_connect(self, path: str, **kwargs: Any) -> ClientWebSocketResponse: + ws = await self._session.ws_connect(self.make_url(path), **kwargs) + self._websockets.append(ws) + return ws + + async def close(self) -> None: + """Close all fixtures created by the test client. + + After that point, the TestClient is no longer usable. + + This is an idempotent function: running close multiple times + will not have any additional effects. + + close is also run on exit when used as a(n) (asynchronous) + context manager. + + """ + if not self._closed: + for resp in self._responses: + resp.close() + for ws in self._websockets: + await ws.close() + await self._session.close() + await self._server.close() + self._closed = True + + def __enter__(self) -> None: + raise TypeError("Use async with instead") + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + # __exit__ should exist in pair with __enter__ but never executed + pass # pragma: no cover + + async def __aenter__(self) -> "TestClient": + await self.start_server() + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc: Optional[BaseException], + tb: Optional[TracebackType], + ) -> None: + await self.close() + + +class AioHTTPTestCase(unittest.TestCase): + """A base class to allow for unittest web applications using + aiohttp. + + Provides the following: + + * self.client (aiohttp.test_utils.TestClient): an aiohttp test client. + * self.loop (asyncio.BaseEventLoop): the event loop in which the + application and server are running. + * self.app (aiohttp.web.Application): the application returned by + self.get_application() + + Note that the TestClient's methods are asynchronous: you have to + execute function on the test client using asynchronous methods. + """ + + async def get_application(self) -> Application: + """ + This method should be overridden + to return the aiohttp.web.Application + object to test. + + """ + return self.get_app() + + def get_app(self) -> Application: + """Obsolete method used to constructing web application. + + Use .get_application() coroutine instead + + """ + raise RuntimeError("Did you forget to define get_application()?") + + def setUp(self) -> None: + self.loop = setup_test_loop() + + self.app = self.loop.run_until_complete(self.get_application()) + self.server = self.loop.run_until_complete(self.get_server(self.app)) + self.client = self.loop.run_until_complete(self.get_client(self.server)) + + self.loop.run_until_complete(self.client.start_server()) + + self.loop.run_until_complete(self.setUpAsync()) + + async def setUpAsync(self) -> None: + pass + + def tearDown(self) -> None: + self.loop.run_until_complete(self.tearDownAsync()) + self.loop.run_until_complete(self.client.close()) + teardown_test_loop(self.loop) + + async def tearDownAsync(self) -> None: + pass + + async def get_server(self, app: Application) -> TestServer: + """Return a TestServer instance.""" + return TestServer(app, loop=self.loop) + + async def get_client(self, server: TestServer) -> TestClient: + """Return a TestClient instance.""" + return TestClient(server, loop=self.loop) + + +def unittest_run_loop(func: Any, *args: Any, **kwargs: Any) -> Any: + """A decorator dedicated to use with asynchronous methods of an + AioHTTPTestCase. + + Handles executing an asynchronous function, using + the self.loop of the AioHTTPTestCase. + """ + + @functools.wraps(func, *args, **kwargs) + def new_func(self: Any, *inner_args: Any, **inner_kwargs: Any) -> Any: + return self.loop.run_until_complete(func(self, *inner_args, **inner_kwargs)) + + return new_func + + +_LOOP_FACTORY = Callable[[], asyncio.AbstractEventLoop] + + +@contextlib.contextmanager +def loop_context( + loop_factory: _LOOP_FACTORY = asyncio.new_event_loop, fast: bool = False +) -> Iterator[asyncio.AbstractEventLoop]: + """A contextmanager that creates an event_loop, for test purposes. + + Handles the creation and cleanup of a test loop. + """ + loop = setup_test_loop(loop_factory) + yield loop + teardown_test_loop(loop, fast=fast) + + +def setup_test_loop( + loop_factory: _LOOP_FACTORY = asyncio.new_event_loop, +) -> asyncio.AbstractEventLoop: + """Create and return an asyncio.BaseEventLoop + instance. + + The caller should also call teardown_test_loop, + once they are done with the loop. + """ + loop = loop_factory() + try: + module = loop.__class__.__module__ + skip_watcher = "uvloop" in module + except AttributeError: # pragma: no cover + # Just in case + skip_watcher = True + asyncio.set_event_loop(loop) + if sys.platform != "win32" and not skip_watcher: + policy = asyncio.get_event_loop_policy() + watcher = asyncio.SafeChildWatcher() + watcher.attach_loop(loop) + with contextlib.suppress(NotImplementedError): + policy.set_child_watcher(watcher) + return loop + + +def teardown_test_loop(loop: asyncio.AbstractEventLoop, fast: bool = False) -> None: + """Teardown and cleanup an event_loop created + by setup_test_loop. + + """ + closed = loop.is_closed() + if not closed: + loop.call_soon(loop.stop) + loop.run_forever() + loop.close() + + if not fast: + gc.collect() + + asyncio.set_event_loop(None) + + +def _create_app_mock() -> mock.MagicMock: + def get_dict(app: Any, key: str) -> Any: + return app.__app_dict[key] + + def set_dict(app: Any, key: str, value: Any) -> None: + app.__app_dict[key] = value + + app = mock.MagicMock() + app.__app_dict = {} + app.__getitem__ = get_dict + app.__setitem__ = set_dict + + app._debug = False + app.on_response_prepare = Signal(app) + app.on_response_prepare.freeze() + return app + + +def _create_transport(sslcontext: Optional[SSLContext] = None) -> mock.Mock: + transport = mock.Mock() + + def get_extra_info(key: str) -> Optional[SSLContext]: + if key == "sslcontext": + return sslcontext + else: + return None + + transport.get_extra_info.side_effect = get_extra_info + return transport + + +def make_mocked_request( + method: str, + path: str, + headers: Any = None, + *, + match_info: Any = sentinel, + version: HttpVersion = HttpVersion(1, 1), + closing: bool = False, + app: Any = None, + writer: Any = sentinel, + protocol: Any = sentinel, + transport: Any = sentinel, + payload: Any = sentinel, + sslcontext: Optional[SSLContext] = None, + client_max_size: int = 1024 ** 2, + loop: Any = ..., +) -> Request: + """Creates mocked web.Request testing purposes. + + Useful in unit tests, when spinning full web server is overkill or + specific conditions and errors are hard to trigger. + + """ + + task = mock.Mock() + if loop is ...: + loop = mock.Mock() + loop.create_future.return_value = () + + if version < HttpVersion(1, 1): + closing = True + + if headers: + headers = CIMultiDictProxy(CIMultiDict(headers)) + raw_hdrs = tuple( + (k.encode("utf-8"), v.encode("utf-8")) for k, v in headers.items() + ) + else: + headers = CIMultiDictProxy(CIMultiDict()) + raw_hdrs = () + + chunked = "chunked" in headers.get(hdrs.TRANSFER_ENCODING, "").lower() + + message = RawRequestMessage( + method, + path, + version, + headers, + raw_hdrs, + closing, + False, + False, + chunked, + URL(path), + ) + if app is None: + app = _create_app_mock() + + if transport is sentinel: + transport = _create_transport(sslcontext) + + if protocol is sentinel: + protocol = mock.Mock() + protocol.transport = transport + + if writer is sentinel: + writer = mock.Mock() + writer.write_headers = make_mocked_coro(None) + writer.write = make_mocked_coro(None) + writer.write_eof = make_mocked_coro(None) + writer.drain = make_mocked_coro(None) + writer.transport = transport + + protocol.transport = transport + protocol.writer = writer + + if payload is sentinel: + payload = mock.Mock() + + req = Request( + message, payload, protocol, writer, task, loop, client_max_size=client_max_size + ) + + match_info = UrlMappingMatchInfo( + {} if match_info is sentinel else match_info, mock.Mock() + ) + match_info.add_app(app) + req._match_info = match_info + + return req + + +def make_mocked_coro( + return_value: Any = sentinel, raise_exception: Any = sentinel +) -> Any: + """Creates a coroutine mock.""" + + async def mock_coro(*args: Any, **kwargs: Any) -> Any: + if raise_exception is not sentinel: + raise raise_exception + if not inspect.isawaitable(return_value): + return return_value + await return_value + + return mock.Mock(wraps=mock_coro) diff --git a/dist/ba_data/python-site-packages/aiohttp/tracing.py b/dist/ba_data/python-site-packages/aiohttp/tracing.py new file mode 100644 index 0000000..7ae7948 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/tracing.py @@ -0,0 +1,442 @@ +from types import SimpleNamespace +from typing import TYPE_CHECKING, Awaitable, Optional, Type, TypeVar + +import attr +from multidict import CIMultiDict +from yarl import URL + +from .client_reqrep import ClientResponse +from .signals import Signal + +if TYPE_CHECKING: # pragma: no cover + from typing_extensions import Protocol + + from .client import ClientSession + + _ParamT_contra = TypeVar("_ParamT_contra", contravariant=True) + + class _SignalCallback(Protocol[_ParamT_contra]): + def __call__( + self, + __client_session: ClientSession, + __trace_config_ctx: SimpleNamespace, + __params: _ParamT_contra, + ) -> Awaitable[None]: + ... + + +__all__ = ( + "TraceConfig", + "TraceRequestStartParams", + "TraceRequestEndParams", + "TraceRequestExceptionParams", + "TraceConnectionQueuedStartParams", + "TraceConnectionQueuedEndParams", + "TraceConnectionCreateStartParams", + "TraceConnectionCreateEndParams", + "TraceConnectionReuseconnParams", + "TraceDnsResolveHostStartParams", + "TraceDnsResolveHostEndParams", + "TraceDnsCacheHitParams", + "TraceDnsCacheMissParams", + "TraceRequestRedirectParams", + "TraceRequestChunkSentParams", + "TraceResponseChunkReceivedParams", +) + + +class TraceConfig: + """First-class used to trace requests launched via ClientSession + objects.""" + + def __init__( + self, trace_config_ctx_factory: Type[SimpleNamespace] = SimpleNamespace + ) -> None: + self._on_request_start = Signal( + self + ) # type: Signal[_SignalCallback[TraceRequestStartParams]] + self._on_request_chunk_sent = Signal( + self + ) # type: Signal[_SignalCallback[TraceRequestChunkSentParams]] + self._on_response_chunk_received = Signal( + self + ) # type: Signal[_SignalCallback[TraceResponseChunkReceivedParams]] + self._on_request_end = Signal( + self + ) # type: Signal[_SignalCallback[TraceRequestEndParams]] + self._on_request_exception = Signal( + self + ) # type: Signal[_SignalCallback[TraceRequestExceptionParams]] + self._on_request_redirect = Signal( + self + ) # type: Signal[_SignalCallback[TraceRequestRedirectParams]] + self._on_connection_queued_start = Signal( + self + ) # type: Signal[_SignalCallback[TraceConnectionQueuedStartParams]] + self._on_connection_queued_end = Signal( + self + ) # type: Signal[_SignalCallback[TraceConnectionQueuedEndParams]] + self._on_connection_create_start = Signal( + self + ) # type: Signal[_SignalCallback[TraceConnectionCreateStartParams]] + self._on_connection_create_end = Signal( + self + ) # type: Signal[_SignalCallback[TraceConnectionCreateEndParams]] + self._on_connection_reuseconn = Signal( + self + ) # type: Signal[_SignalCallback[TraceConnectionReuseconnParams]] + self._on_dns_resolvehost_start = Signal( + self + ) # type: Signal[_SignalCallback[TraceDnsResolveHostStartParams]] + self._on_dns_resolvehost_end = Signal( + self + ) # type: Signal[_SignalCallback[TraceDnsResolveHostEndParams]] + self._on_dns_cache_hit = Signal( + self + ) # type: Signal[_SignalCallback[TraceDnsCacheHitParams]] + self._on_dns_cache_miss = Signal( + self + ) # type: Signal[_SignalCallback[TraceDnsCacheMissParams]] + + self._trace_config_ctx_factory = trace_config_ctx_factory + + def trace_config_ctx( + self, trace_request_ctx: Optional[SimpleNamespace] = None + ) -> SimpleNamespace: + """ Return a new trace_config_ctx instance """ + return self._trace_config_ctx_factory(trace_request_ctx=trace_request_ctx) + + def freeze(self) -> None: + self._on_request_start.freeze() + self._on_request_chunk_sent.freeze() + self._on_response_chunk_received.freeze() + self._on_request_end.freeze() + self._on_request_exception.freeze() + self._on_request_redirect.freeze() + self._on_connection_queued_start.freeze() + self._on_connection_queued_end.freeze() + self._on_connection_create_start.freeze() + self._on_connection_create_end.freeze() + self._on_connection_reuseconn.freeze() + self._on_dns_resolvehost_start.freeze() + self._on_dns_resolvehost_end.freeze() + self._on_dns_cache_hit.freeze() + self._on_dns_cache_miss.freeze() + + @property + def on_request_start(self) -> "Signal[_SignalCallback[TraceRequestStartParams]]": + return self._on_request_start + + @property + def on_request_chunk_sent( + self, + ) -> "Signal[_SignalCallback[TraceRequestChunkSentParams]]": + return self._on_request_chunk_sent + + @property + def on_response_chunk_received( + self, + ) -> "Signal[_SignalCallback[TraceResponseChunkReceivedParams]]": + return self._on_response_chunk_received + + @property + def on_request_end(self) -> "Signal[_SignalCallback[TraceRequestEndParams]]": + return self._on_request_end + + @property + def on_request_exception( + self, + ) -> "Signal[_SignalCallback[TraceRequestExceptionParams]]": + return self._on_request_exception + + @property + def on_request_redirect( + self, + ) -> "Signal[_SignalCallback[TraceRequestRedirectParams]]": + return self._on_request_redirect + + @property + def on_connection_queued_start( + self, + ) -> "Signal[_SignalCallback[TraceConnectionQueuedStartParams]]": + return self._on_connection_queued_start + + @property + def on_connection_queued_end( + self, + ) -> "Signal[_SignalCallback[TraceConnectionQueuedEndParams]]": + return self._on_connection_queued_end + + @property + def on_connection_create_start( + self, + ) -> "Signal[_SignalCallback[TraceConnectionCreateStartParams]]": + return self._on_connection_create_start + + @property + def on_connection_create_end( + self, + ) -> "Signal[_SignalCallback[TraceConnectionCreateEndParams]]": + return self._on_connection_create_end + + @property + def on_connection_reuseconn( + self, + ) -> "Signal[_SignalCallback[TraceConnectionReuseconnParams]]": + return self._on_connection_reuseconn + + @property + def on_dns_resolvehost_start( + self, + ) -> "Signal[_SignalCallback[TraceDnsResolveHostStartParams]]": + return self._on_dns_resolvehost_start + + @property + def on_dns_resolvehost_end( + self, + ) -> "Signal[_SignalCallback[TraceDnsResolveHostEndParams]]": + return self._on_dns_resolvehost_end + + @property + def on_dns_cache_hit(self) -> "Signal[_SignalCallback[TraceDnsCacheHitParams]]": + return self._on_dns_cache_hit + + @property + def on_dns_cache_miss(self) -> "Signal[_SignalCallback[TraceDnsCacheMissParams]]": + return self._on_dns_cache_miss + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestStartParams: + """ Parameters sent by the `on_request_start` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestChunkSentParams: + """ Parameters sent by the `on_request_chunk_sent` signal""" + + method: str + url: URL + chunk: bytes + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceResponseChunkReceivedParams: + """ Parameters sent by the `on_response_chunk_received` signal""" + + method: str + url: URL + chunk: bytes + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestEndParams: + """ Parameters sent by the `on_request_end` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + response: ClientResponse + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestExceptionParams: + """ Parameters sent by the `on_request_exception` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + exception: BaseException + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceRequestRedirectParams: + """ Parameters sent by the `on_request_redirect` signal""" + + method: str + url: URL + headers: "CIMultiDict[str]" + response: ClientResponse + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionQueuedStartParams: + """ Parameters sent by the `on_connection_queued_start` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionQueuedEndParams: + """ Parameters sent by the `on_connection_queued_end` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionCreateStartParams: + """ Parameters sent by the `on_connection_create_start` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionCreateEndParams: + """ Parameters sent by the `on_connection_create_end` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceConnectionReuseconnParams: + """ Parameters sent by the `on_connection_reuseconn` signal""" + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceDnsResolveHostStartParams: + """ Parameters sent by the `on_dns_resolvehost_start` signal""" + + host: str + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceDnsResolveHostEndParams: + """ Parameters sent by the `on_dns_resolvehost_end` signal""" + + host: str + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceDnsCacheHitParams: + """ Parameters sent by the `on_dns_cache_hit` signal""" + + host: str + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class TraceDnsCacheMissParams: + """ Parameters sent by the `on_dns_cache_miss` signal""" + + host: str + + +class Trace: + """Internal class used to keep together the main dependencies used + at the moment of send a signal.""" + + def __init__( + self, + session: "ClientSession", + trace_config: TraceConfig, + trace_config_ctx: SimpleNamespace, + ) -> None: + self._trace_config = trace_config + self._trace_config_ctx = trace_config_ctx + self._session = session + + async def send_request_start( + self, method: str, url: URL, headers: "CIMultiDict[str]" + ) -> None: + return await self._trace_config.on_request_start.send( + self._session, + self._trace_config_ctx, + TraceRequestStartParams(method, url, headers), + ) + + async def send_request_chunk_sent( + self, method: str, url: URL, chunk: bytes + ) -> None: + return await self._trace_config.on_request_chunk_sent.send( + self._session, + self._trace_config_ctx, + TraceRequestChunkSentParams(method, url, chunk), + ) + + async def send_response_chunk_received( + self, method: str, url: URL, chunk: bytes + ) -> None: + return await self._trace_config.on_response_chunk_received.send( + self._session, + self._trace_config_ctx, + TraceResponseChunkReceivedParams(method, url, chunk), + ) + + async def send_request_end( + self, + method: str, + url: URL, + headers: "CIMultiDict[str]", + response: ClientResponse, + ) -> None: + return await self._trace_config.on_request_end.send( + self._session, + self._trace_config_ctx, + TraceRequestEndParams(method, url, headers, response), + ) + + async def send_request_exception( + self, + method: str, + url: URL, + headers: "CIMultiDict[str]", + exception: BaseException, + ) -> None: + return await self._trace_config.on_request_exception.send( + self._session, + self._trace_config_ctx, + TraceRequestExceptionParams(method, url, headers, exception), + ) + + async def send_request_redirect( + self, + method: str, + url: URL, + headers: "CIMultiDict[str]", + response: ClientResponse, + ) -> None: + return await self._trace_config._on_request_redirect.send( + self._session, + self._trace_config_ctx, + TraceRequestRedirectParams(method, url, headers, response), + ) + + async def send_connection_queued_start(self) -> None: + return await self._trace_config.on_connection_queued_start.send( + self._session, self._trace_config_ctx, TraceConnectionQueuedStartParams() + ) + + async def send_connection_queued_end(self) -> None: + return await self._trace_config.on_connection_queued_end.send( + self._session, self._trace_config_ctx, TraceConnectionQueuedEndParams() + ) + + async def send_connection_create_start(self) -> None: + return await self._trace_config.on_connection_create_start.send( + self._session, self._trace_config_ctx, TraceConnectionCreateStartParams() + ) + + async def send_connection_create_end(self) -> None: + return await self._trace_config.on_connection_create_end.send( + self._session, self._trace_config_ctx, TraceConnectionCreateEndParams() + ) + + async def send_connection_reuseconn(self) -> None: + return await self._trace_config.on_connection_reuseconn.send( + self._session, self._trace_config_ctx, TraceConnectionReuseconnParams() + ) + + async def send_dns_resolvehost_start(self, host: str) -> None: + return await self._trace_config.on_dns_resolvehost_start.send( + self._session, self._trace_config_ctx, TraceDnsResolveHostStartParams(host) + ) + + async def send_dns_resolvehost_end(self, host: str) -> None: + return await self._trace_config.on_dns_resolvehost_end.send( + self._session, self._trace_config_ctx, TraceDnsResolveHostEndParams(host) + ) + + async def send_dns_cache_hit(self, host: str) -> None: + return await self._trace_config.on_dns_cache_hit.send( + self._session, self._trace_config_ctx, TraceDnsCacheHitParams(host) + ) + + async def send_dns_cache_miss(self, host: str) -> None: + return await self._trace_config.on_dns_cache_miss.send( + self._session, self._trace_config_ctx, TraceDnsCacheMissParams(host) + ) diff --git a/dist/ba_data/python-site-packages/aiohttp/typedefs.py b/dist/ba_data/python-site-packages/aiohttp/typedefs.py new file mode 100644 index 0000000..1b68a24 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/typedefs.py @@ -0,0 +1,46 @@ +import json +import os +import pathlib +import sys +from typing import TYPE_CHECKING, Any, Callable, Iterable, Mapping, Tuple, Union + +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy, istr +from yarl import URL + +DEFAULT_JSON_ENCODER = json.dumps +DEFAULT_JSON_DECODER = json.loads + +if TYPE_CHECKING: # pragma: no cover + _CIMultiDict = CIMultiDict[str] + _CIMultiDictProxy = CIMultiDictProxy[str] + _MultiDict = MultiDict[str] + _MultiDictProxy = MultiDictProxy[str] + from http.cookies import BaseCookie, Morsel +else: + _CIMultiDict = CIMultiDict + _CIMultiDictProxy = CIMultiDictProxy + _MultiDict = MultiDict + _MultiDictProxy = MultiDictProxy + +Byteish = Union[bytes, bytearray, memoryview] +JSONEncoder = Callable[[Any], str] +JSONDecoder = Callable[[str], Any] +LooseHeaders = Union[Mapping[Union[str, istr], str], _CIMultiDict, _CIMultiDictProxy] +RawHeaders = Tuple[Tuple[bytes, bytes], ...] +StrOrURL = Union[str, URL] + +LooseCookiesMappings = Mapping[str, Union[str, "BaseCookie[str]", "Morsel[Any]"]] +LooseCookiesIterables = Iterable[ + Tuple[str, Union[str, "BaseCookie[str]", "Morsel[Any]"]] +] +LooseCookies = Union[ + LooseCookiesMappings, + LooseCookiesIterables, + "BaseCookie[str]", +] + + +if sys.version_info >= (3, 6): + PathLike = Union[str, "os.PathLike[str]"] +else: + PathLike = Union[str, pathlib.PurePath] diff --git a/dist/ba_data/python-site-packages/aiohttp/web.py b/dist/ba_data/python-site-packages/aiohttp/web.py new file mode 100644 index 0000000..557e3c3 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web.py @@ -0,0 +1,581 @@ +import asyncio +import logging +import socket +import sys +from argparse import ArgumentParser +from collections.abc import Iterable +from importlib import import_module +from typing import ( + Any as Any, + Awaitable as Awaitable, + Callable as Callable, + Iterable as TypingIterable, + List as List, + Optional as Optional, + Set as Set, + Type as Type, + Union as Union, + cast as cast, +) + +from .abc import AbstractAccessLogger +from .helpers import all_tasks +from .log import access_logger +from .web_app import Application as Application, CleanupError as CleanupError +from .web_exceptions import ( + HTTPAccepted as HTTPAccepted, + HTTPBadGateway as HTTPBadGateway, + HTTPBadRequest as HTTPBadRequest, + HTTPClientError as HTTPClientError, + HTTPConflict as HTTPConflict, + HTTPCreated as HTTPCreated, + HTTPError as HTTPError, + HTTPException as HTTPException, + HTTPExpectationFailed as HTTPExpectationFailed, + HTTPFailedDependency as HTTPFailedDependency, + HTTPForbidden as HTTPForbidden, + HTTPFound as HTTPFound, + HTTPGatewayTimeout as HTTPGatewayTimeout, + HTTPGone as HTTPGone, + HTTPInsufficientStorage as HTTPInsufficientStorage, + HTTPInternalServerError as HTTPInternalServerError, + HTTPLengthRequired as HTTPLengthRequired, + HTTPMethodNotAllowed as HTTPMethodNotAllowed, + HTTPMisdirectedRequest as HTTPMisdirectedRequest, + HTTPMovedPermanently as HTTPMovedPermanently, + HTTPMultipleChoices as HTTPMultipleChoices, + HTTPNetworkAuthenticationRequired as HTTPNetworkAuthenticationRequired, + HTTPNoContent as HTTPNoContent, + HTTPNonAuthoritativeInformation as HTTPNonAuthoritativeInformation, + HTTPNotAcceptable as HTTPNotAcceptable, + HTTPNotExtended as HTTPNotExtended, + HTTPNotFound as HTTPNotFound, + HTTPNotImplemented as HTTPNotImplemented, + HTTPNotModified as HTTPNotModified, + HTTPOk as HTTPOk, + HTTPPartialContent as HTTPPartialContent, + HTTPPaymentRequired as HTTPPaymentRequired, + HTTPPermanentRedirect as HTTPPermanentRedirect, + HTTPPreconditionFailed as HTTPPreconditionFailed, + HTTPPreconditionRequired as HTTPPreconditionRequired, + HTTPProxyAuthenticationRequired as HTTPProxyAuthenticationRequired, + HTTPRedirection as HTTPRedirection, + HTTPRequestEntityTooLarge as HTTPRequestEntityTooLarge, + HTTPRequestHeaderFieldsTooLarge as HTTPRequestHeaderFieldsTooLarge, + HTTPRequestRangeNotSatisfiable as HTTPRequestRangeNotSatisfiable, + HTTPRequestTimeout as HTTPRequestTimeout, + HTTPRequestURITooLong as HTTPRequestURITooLong, + HTTPResetContent as HTTPResetContent, + HTTPSeeOther as HTTPSeeOther, + HTTPServerError as HTTPServerError, + HTTPServiceUnavailable as HTTPServiceUnavailable, + HTTPSuccessful as HTTPSuccessful, + HTTPTemporaryRedirect as HTTPTemporaryRedirect, + HTTPTooManyRequests as HTTPTooManyRequests, + HTTPUnauthorized as HTTPUnauthorized, + HTTPUnavailableForLegalReasons as HTTPUnavailableForLegalReasons, + HTTPUnprocessableEntity as HTTPUnprocessableEntity, + HTTPUnsupportedMediaType as HTTPUnsupportedMediaType, + HTTPUpgradeRequired as HTTPUpgradeRequired, + HTTPUseProxy as HTTPUseProxy, + HTTPVariantAlsoNegotiates as HTTPVariantAlsoNegotiates, + HTTPVersionNotSupported as HTTPVersionNotSupported, +) +from .web_fileresponse import FileResponse as FileResponse +from .web_log import AccessLogger +from .web_middlewares import ( + middleware as middleware, + normalize_path_middleware as normalize_path_middleware, +) +from .web_protocol import ( + PayloadAccessError as PayloadAccessError, + RequestHandler as RequestHandler, + RequestPayloadError as RequestPayloadError, +) +from .web_request import ( + BaseRequest as BaseRequest, + FileField as FileField, + Request as Request, +) +from .web_response import ( + ContentCoding as ContentCoding, + Response as Response, + StreamResponse as StreamResponse, + json_response as json_response, +) +from .web_routedef import ( + AbstractRouteDef as AbstractRouteDef, + RouteDef as RouteDef, + RouteTableDef as RouteTableDef, + StaticDef as StaticDef, + delete as delete, + get as get, + head as head, + options as options, + patch as patch, + post as post, + put as put, + route as route, + static as static, + view as view, +) +from .web_runner import ( + AppRunner as AppRunner, + BaseRunner as BaseRunner, + BaseSite as BaseSite, + GracefulExit as GracefulExit, + NamedPipeSite as NamedPipeSite, + ServerRunner as ServerRunner, + SockSite as SockSite, + TCPSite as TCPSite, + UnixSite as UnixSite, +) +from .web_server import Server as Server +from .web_urldispatcher import ( + AbstractResource as AbstractResource, + AbstractRoute as AbstractRoute, + DynamicResource as DynamicResource, + PlainResource as PlainResource, + Resource as Resource, + ResourceRoute as ResourceRoute, + StaticResource as StaticResource, + UrlDispatcher as UrlDispatcher, + UrlMappingMatchInfo as UrlMappingMatchInfo, + View as View, +) +from .web_ws import ( + WebSocketReady as WebSocketReady, + WebSocketResponse as WebSocketResponse, + WSMsgType as WSMsgType, +) + +__all__ = ( + # web_app + "Application", + "CleanupError", + # web_exceptions + "HTTPAccepted", + "HTTPBadGateway", + "HTTPBadRequest", + "HTTPClientError", + "HTTPConflict", + "HTTPCreated", + "HTTPError", + "HTTPException", + "HTTPExpectationFailed", + "HTTPFailedDependency", + "HTTPForbidden", + "HTTPFound", + "HTTPGatewayTimeout", + "HTTPGone", + "HTTPInsufficientStorage", + "HTTPInternalServerError", + "HTTPLengthRequired", + "HTTPMethodNotAllowed", + "HTTPMisdirectedRequest", + "HTTPMovedPermanently", + "HTTPMultipleChoices", + "HTTPNetworkAuthenticationRequired", + "HTTPNoContent", + "HTTPNonAuthoritativeInformation", + "HTTPNotAcceptable", + "HTTPNotExtended", + "HTTPNotFound", + "HTTPNotImplemented", + "HTTPNotModified", + "HTTPOk", + "HTTPPartialContent", + "HTTPPaymentRequired", + "HTTPPermanentRedirect", + "HTTPPreconditionFailed", + "HTTPPreconditionRequired", + "HTTPProxyAuthenticationRequired", + "HTTPRedirection", + "HTTPRequestEntityTooLarge", + "HTTPRequestHeaderFieldsTooLarge", + "HTTPRequestRangeNotSatisfiable", + "HTTPRequestTimeout", + "HTTPRequestURITooLong", + "HTTPResetContent", + "HTTPSeeOther", + "HTTPServerError", + "HTTPServiceUnavailable", + "HTTPSuccessful", + "HTTPTemporaryRedirect", + "HTTPTooManyRequests", + "HTTPUnauthorized", + "HTTPUnavailableForLegalReasons", + "HTTPUnprocessableEntity", + "HTTPUnsupportedMediaType", + "HTTPUpgradeRequired", + "HTTPUseProxy", + "HTTPVariantAlsoNegotiates", + "HTTPVersionNotSupported", + # web_fileresponse + "FileResponse", + # web_middlewares + "middleware", + "normalize_path_middleware", + # web_protocol + "PayloadAccessError", + "RequestHandler", + "RequestPayloadError", + # web_request + "BaseRequest", + "FileField", + "Request", + # web_response + "ContentCoding", + "Response", + "StreamResponse", + "json_response", + # web_routedef + "AbstractRouteDef", + "RouteDef", + "RouteTableDef", + "StaticDef", + "delete", + "get", + "head", + "options", + "patch", + "post", + "put", + "route", + "static", + "view", + # web_runner + "AppRunner", + "BaseRunner", + "BaseSite", + "GracefulExit", + "ServerRunner", + "SockSite", + "TCPSite", + "UnixSite", + "NamedPipeSite", + # web_server + "Server", + # web_urldispatcher + "AbstractResource", + "AbstractRoute", + "DynamicResource", + "PlainResource", + "Resource", + "ResourceRoute", + "StaticResource", + "UrlDispatcher", + "UrlMappingMatchInfo", + "View", + # web_ws + "WebSocketReady", + "WebSocketResponse", + "WSMsgType", + # web + "run_app", +) + + +try: + from ssl import SSLContext +except ImportError: # pragma: no cover + SSLContext = Any # type: ignore + +HostSequence = TypingIterable[str] + + +async def _run_app( + app: Union[Application, Awaitable[Application]], + *, + host: Optional[Union[str, HostSequence]] = None, + port: Optional[int] = None, + path: Optional[str] = None, + sock: Optional[socket.socket] = None, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + print: Callable[..., None] = print, + backlog: int = 128, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + access_log_format: str = AccessLogger.LOG_FORMAT, + access_log: Optional[logging.Logger] = access_logger, + handle_signals: bool = True, + reuse_address: Optional[bool] = None, + reuse_port: Optional[bool] = None, +) -> None: + # A internal functio to actually do all dirty job for application running + if asyncio.iscoroutine(app): + app = await app # type: ignore + + app = cast(Application, app) + + runner = AppRunner( + app, + handle_signals=handle_signals, + access_log_class=access_log_class, + access_log_format=access_log_format, + access_log=access_log, + ) + + await runner.setup() + + sites = [] # type: List[BaseSite] + + try: + if host is not None: + if isinstance(host, (str, bytes, bytearray, memoryview)): + sites.append( + TCPSite( + runner, + host, + port, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + reuse_address=reuse_address, + reuse_port=reuse_port, + ) + ) + else: + for h in host: + sites.append( + TCPSite( + runner, + h, + port, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + reuse_address=reuse_address, + reuse_port=reuse_port, + ) + ) + elif path is None and sock is None or port is not None: + sites.append( + TCPSite( + runner, + port=port, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + reuse_address=reuse_address, + reuse_port=reuse_port, + ) + ) + + if path is not None: + if isinstance(path, (str, bytes, bytearray, memoryview)): + sites.append( + UnixSite( + runner, + path, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + ) + else: + for p in path: + sites.append( + UnixSite( + runner, + p, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + ) + + if sock is not None: + if not isinstance(sock, Iterable): + sites.append( + SockSite( + runner, + sock, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + ) + else: + for s in sock: + sites.append( + SockSite( + runner, + s, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + ) + for site in sites: + await site.start() + + if print: # pragma: no branch + names = sorted(str(s.name) for s in runner.sites) + print( + "======== Running on {} ========\n" + "(Press CTRL+C to quit)".format(", ".join(names)) + ) + + # sleep forever by 1 hour intervals, + # on Windows before Python 3.8 wake up every 1 second to handle + # Ctrl+C smoothly + if sys.platform == "win32" and sys.version_info < (3, 8): + delay = 1 + else: + delay = 3600 + + while True: + await asyncio.sleep(delay) + finally: + await runner.cleanup() + + +def _cancel_tasks( + to_cancel: Set["asyncio.Task[Any]"], loop: asyncio.AbstractEventLoop +) -> None: + if not to_cancel: + return + + for task in to_cancel: + task.cancel() + + loop.run_until_complete( + asyncio.gather(*to_cancel, loop=loop, return_exceptions=True) + ) + + for task in to_cancel: + if task.cancelled(): + continue + if task.exception() is not None: + loop.call_exception_handler( + { + "message": "unhandled exception during asyncio.run() shutdown", + "exception": task.exception(), + "task": task, + } + ) + + +def run_app( + app: Union[Application, Awaitable[Application]], + *, + host: Optional[Union[str, HostSequence]] = None, + port: Optional[int] = None, + path: Optional[str] = None, + sock: Optional[socket.socket] = None, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + print: Callable[..., None] = print, + backlog: int = 128, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + access_log_format: str = AccessLogger.LOG_FORMAT, + access_log: Optional[logging.Logger] = access_logger, + handle_signals: bool = True, + reuse_address: Optional[bool] = None, + reuse_port: Optional[bool] = None, +) -> None: + """Run an app locally""" + loop = asyncio.get_event_loop() + + # Configure if and only if in debugging mode and using the default logger + if loop.get_debug() and access_log and access_log.name == "aiohttp.access": + if access_log.level == logging.NOTSET: + access_log.setLevel(logging.DEBUG) + if not access_log.hasHandlers(): + access_log.addHandler(logging.StreamHandler()) + + try: + main_task = loop.create_task( + _run_app( + app, + host=host, + port=port, + path=path, + sock=sock, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + print=print, + backlog=backlog, + access_log_class=access_log_class, + access_log_format=access_log_format, + access_log=access_log, + handle_signals=handle_signals, + reuse_address=reuse_address, + reuse_port=reuse_port, + ) + ) + loop.run_until_complete(main_task) + except (GracefulExit, KeyboardInterrupt): # pragma: no cover + pass + finally: + _cancel_tasks({main_task}, loop) + _cancel_tasks(all_tasks(loop), loop) + if sys.version_info >= (3, 6): # don't use PY_36 to pass mypy + loop.run_until_complete(loop.shutdown_asyncgens()) + loop.close() + + +def main(argv: List[str]) -> None: + arg_parser = ArgumentParser( + description="aiohttp.web Application server", prog="aiohttp.web" + ) + arg_parser.add_argument( + "entry_func", + help=( + "Callable returning the `aiohttp.web.Application` instance to " + "run. Should be specified in the 'module:function' syntax." + ), + metavar="entry-func", + ) + arg_parser.add_argument( + "-H", + "--hostname", + help="TCP/IP hostname to serve on (default: %(default)r)", + default="localhost", + ) + arg_parser.add_argument( + "-P", + "--port", + help="TCP/IP port to serve on (default: %(default)r)", + type=int, + default="8080", + ) + arg_parser.add_argument( + "-U", + "--path", + help="Unix file system path to serve on. Specifying a path will cause " + "hostname and port arguments to be ignored.", + ) + args, extra_argv = arg_parser.parse_known_args(argv) + + # Import logic + mod_str, _, func_str = args.entry_func.partition(":") + if not func_str or not mod_str: + arg_parser.error("'entry-func' not in 'module:function' syntax") + if mod_str.startswith("."): + arg_parser.error("relative module names not supported") + try: + module = import_module(mod_str) + except ImportError as ex: + arg_parser.error(f"unable to import {mod_str}: {ex}") + try: + func = getattr(module, func_str) + except AttributeError: + arg_parser.error(f"module {mod_str!r} has no attribute {func_str!r}") + + # Compatibility logic + if args.path is not None and not hasattr(socket, "AF_UNIX"): + arg_parser.error( + "file system paths not supported by your operating" " environment" + ) + + logging.basicConfig(level=logging.DEBUG) + + app = func(extra_argv) + run_app(app, host=args.hostname, port=args.port, path=args.path) + arg_parser.exit(message="Stopped\n") + + +if __name__ == "__main__": # pragma: no branch + main(sys.argv[1:]) # pragma: no cover diff --git a/dist/ba_data/python-site-packages/aiohttp/web_app.py b/dist/ba_data/python-site-packages/aiohttp/web_app.py new file mode 100644 index 0000000..14f2937 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_app.py @@ -0,0 +1,552 @@ +import asyncio +import logging +import warnings +from functools import partial, update_wrapper +from typing import ( + TYPE_CHECKING, + Any, + AsyncIterator, + Awaitable, + Callable, + Dict, + Iterable, + Iterator, + List, + Mapping, + MutableMapping, + Optional, + Sequence, + Tuple, + Type, + Union, + cast, +) + +from . import hdrs +from .abc import ( + AbstractAccessLogger, + AbstractMatchInfo, + AbstractRouter, + AbstractStreamWriter, +) +from .frozenlist import FrozenList +from .helpers import DEBUG +from .http_parser import RawRequestMessage +from .log import web_logger +from .signals import Signal +from .streams import StreamReader +from .web_log import AccessLogger +from .web_middlewares import _fix_request_current_app +from .web_protocol import RequestHandler +from .web_request import Request +from .web_response import StreamResponse +from .web_routedef import AbstractRouteDef +from .web_server import Server +from .web_urldispatcher import ( + AbstractResource, + AbstractRoute, + Domain, + MaskDomain, + MatchedSubAppResource, + PrefixedSubAppResource, + UrlDispatcher, +) + +__all__ = ("Application", "CleanupError") + + +if TYPE_CHECKING: # pragma: no cover + _AppSignal = Signal[Callable[["Application"], Awaitable[None]]] + _RespPrepareSignal = Signal[Callable[[Request, StreamResponse], Awaitable[None]]] + _Handler = Callable[[Request], Awaitable[StreamResponse]] + _Middleware = Union[ + Callable[[Request, _Handler], Awaitable[StreamResponse]], + Callable[["Application", _Handler], Awaitable[_Handler]], # old-style + ] + _Middlewares = FrozenList[_Middleware] + _MiddlewaresHandlers = Optional[Sequence[Tuple[_Middleware, bool]]] + _Subapps = List["Application"] +else: + # No type checker mode, skip types + _AppSignal = Signal + _RespPrepareSignal = Signal + _Handler = Callable + _Middleware = Callable + _Middlewares = FrozenList + _MiddlewaresHandlers = Optional[Sequence] + _Subapps = List + + +class Application(MutableMapping[str, Any]): + ATTRS = frozenset( + [ + "logger", + "_debug", + "_router", + "_loop", + "_handler_args", + "_middlewares", + "_middlewares_handlers", + "_run_middlewares", + "_state", + "_frozen", + "_pre_frozen", + "_subapps", + "_on_response_prepare", + "_on_startup", + "_on_shutdown", + "_on_cleanup", + "_client_max_size", + "_cleanup_ctx", + ] + ) + + def __init__( + self, + *, + logger: logging.Logger = web_logger, + router: Optional[UrlDispatcher] = None, + middlewares: Iterable[_Middleware] = (), + handler_args: Optional[Mapping[str, Any]] = None, + client_max_size: int = 1024 ** 2, + loop: Optional[asyncio.AbstractEventLoop] = None, + debug: Any = ..., # mypy doesn't support ellipsis + ) -> None: + if router is None: + router = UrlDispatcher() + else: + warnings.warn( + "router argument is deprecated", DeprecationWarning, stacklevel=2 + ) + assert isinstance(router, AbstractRouter), router + + if loop is not None: + warnings.warn( + "loop argument is deprecated", DeprecationWarning, stacklevel=2 + ) + + if debug is not ...: + warnings.warn( + "debug argument is deprecated", DeprecationWarning, stacklevel=2 + ) + self._debug = debug + self._router = router # type: UrlDispatcher + self._loop = loop + self._handler_args = handler_args + self.logger = logger + + self._middlewares = FrozenList(middlewares) # type: _Middlewares + + # initialized on freezing + self._middlewares_handlers = None # type: _MiddlewaresHandlers + # initialized on freezing + self._run_middlewares = None # type: Optional[bool] + + self._state = {} # type: Dict[str, Any] + self._frozen = False + self._pre_frozen = False + self._subapps = [] # type: _Subapps + + self._on_response_prepare = Signal(self) # type: _RespPrepareSignal + self._on_startup = Signal(self) # type: _AppSignal + self._on_shutdown = Signal(self) # type: _AppSignal + self._on_cleanup = Signal(self) # type: _AppSignal + self._cleanup_ctx = CleanupContext() + self._on_startup.append(self._cleanup_ctx._on_startup) + self._on_cleanup.append(self._cleanup_ctx._on_cleanup) + self._client_max_size = client_max_size + + def __init_subclass__(cls: Type["Application"]) -> None: + warnings.warn( + "Inheritance class {} from web.Application " + "is discouraged".format(cls.__name__), + DeprecationWarning, + stacklevel=2, + ) + + if DEBUG: # pragma: no cover + + def __setattr__(self, name: str, val: Any) -> None: + if name not in self.ATTRS: + warnings.warn( + "Setting custom web.Application.{} attribute " + "is discouraged".format(name), + DeprecationWarning, + stacklevel=2, + ) + super().__setattr__(name, val) + + # MutableMapping API + + def __eq__(self, other: object) -> bool: + return self is other + + def __getitem__(self, key: str) -> Any: + return self._state[key] + + def _check_frozen(self) -> None: + if self._frozen: + warnings.warn( + "Changing state of started or joined " "application is deprecated", + DeprecationWarning, + stacklevel=3, + ) + + def __setitem__(self, key: str, value: Any) -> None: + self._check_frozen() + self._state[key] = value + + def __delitem__(self, key: str) -> None: + self._check_frozen() + del self._state[key] + + def __len__(self) -> int: + return len(self._state) + + def __iter__(self) -> Iterator[str]: + return iter(self._state) + + ######## + @property + def loop(self) -> asyncio.AbstractEventLoop: + # Technically the loop can be None + # but we mask it by explicit type cast + # to provide more convinient type annotation + warnings.warn("loop property is deprecated", DeprecationWarning, stacklevel=2) + return cast(asyncio.AbstractEventLoop, self._loop) + + def _set_loop(self, loop: Optional[asyncio.AbstractEventLoop]) -> None: + if loop is None: + loop = asyncio.get_event_loop() + if self._loop is not None and self._loop is not loop: + raise RuntimeError( + "web.Application instance initialized with different loop" + ) + + self._loop = loop + + # set loop debug + if self._debug is ...: + self._debug = loop.get_debug() + + # set loop to sub applications + for subapp in self._subapps: + subapp._set_loop(loop) + + @property + def pre_frozen(self) -> bool: + return self._pre_frozen + + def pre_freeze(self) -> None: + if self._pre_frozen: + return + + self._pre_frozen = True + self._middlewares.freeze() + self._router.freeze() + self._on_response_prepare.freeze() + self._cleanup_ctx.freeze() + self._on_startup.freeze() + self._on_shutdown.freeze() + self._on_cleanup.freeze() + self._middlewares_handlers = tuple(self._prepare_middleware()) + + # If current app and any subapp do not have middlewares avoid run all + # of the code footprint that it implies, which have a middleware + # hardcoded per app that sets up the current_app attribute. If no + # middlewares are configured the handler will receive the proper + # current_app without needing all of this code. + self._run_middlewares = True if self.middlewares else False + + for subapp in self._subapps: + subapp.pre_freeze() + self._run_middlewares = self._run_middlewares or subapp._run_middlewares + + @property + def frozen(self) -> bool: + return self._frozen + + def freeze(self) -> None: + if self._frozen: + return + + self.pre_freeze() + self._frozen = True + for subapp in self._subapps: + subapp.freeze() + + @property + def debug(self) -> bool: + warnings.warn("debug property is deprecated", DeprecationWarning, stacklevel=2) + return self._debug + + def _reg_subapp_signals(self, subapp: "Application") -> None: + def reg_handler(signame: str) -> None: + subsig = getattr(subapp, signame) + + async def handler(app: "Application") -> None: + await subsig.send(subapp) + + appsig = getattr(self, signame) + appsig.append(handler) + + reg_handler("on_startup") + reg_handler("on_shutdown") + reg_handler("on_cleanup") + + def add_subapp(self, prefix: str, subapp: "Application") -> AbstractResource: + if not isinstance(prefix, str): + raise TypeError("Prefix must be str") + prefix = prefix.rstrip("/") + if not prefix: + raise ValueError("Prefix cannot be empty") + factory = partial(PrefixedSubAppResource, prefix, subapp) + return self._add_subapp(factory, subapp) + + def _add_subapp( + self, resource_factory: Callable[[], AbstractResource], subapp: "Application" + ) -> AbstractResource: + if self.frozen: + raise RuntimeError("Cannot add sub application to frozen application") + if subapp.frozen: + raise RuntimeError("Cannot add frozen application") + resource = resource_factory() + self.router.register_resource(resource) + self._reg_subapp_signals(subapp) + self._subapps.append(subapp) + subapp.pre_freeze() + if self._loop is not None: + subapp._set_loop(self._loop) + return resource + + def add_domain(self, domain: str, subapp: "Application") -> AbstractResource: + if not isinstance(domain, str): + raise TypeError("Domain must be str") + elif "*" in domain: + rule = MaskDomain(domain) # type: Domain + else: + rule = Domain(domain) + factory = partial(MatchedSubAppResource, rule, subapp) + return self._add_subapp(factory, subapp) + + def add_routes(self, routes: Iterable[AbstractRouteDef]) -> List[AbstractRoute]: + return self.router.add_routes(routes) + + @property + def on_response_prepare(self) -> _RespPrepareSignal: + return self._on_response_prepare + + @property + def on_startup(self) -> _AppSignal: + return self._on_startup + + @property + def on_shutdown(self) -> _AppSignal: + return self._on_shutdown + + @property + def on_cleanup(self) -> _AppSignal: + return self._on_cleanup + + @property + def cleanup_ctx(self) -> "CleanupContext": + return self._cleanup_ctx + + @property + def router(self) -> UrlDispatcher: + return self._router + + @property + def middlewares(self) -> _Middlewares: + return self._middlewares + + def _make_handler( + self, + *, + loop: Optional[asyncio.AbstractEventLoop] = None, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + **kwargs: Any, + ) -> Server: + + if not issubclass(access_log_class, AbstractAccessLogger): + raise TypeError( + "access_log_class must be subclass of " + "aiohttp.abc.AbstractAccessLogger, got {}".format(access_log_class) + ) + + self._set_loop(loop) + self.freeze() + + kwargs["debug"] = self._debug + kwargs["access_log_class"] = access_log_class + if self._handler_args: + for k, v in self._handler_args.items(): + kwargs[k] = v + + return Server( + self._handle, # type: ignore + request_factory=self._make_request, + loop=self._loop, + **kwargs, + ) + + def make_handler( + self, + *, + loop: Optional[asyncio.AbstractEventLoop] = None, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + **kwargs: Any, + ) -> Server: + + warnings.warn( + "Application.make_handler(...) is deprecated, " "use AppRunner API instead", + DeprecationWarning, + stacklevel=2, + ) + + return self._make_handler( + loop=loop, access_log_class=access_log_class, **kwargs + ) + + async def startup(self) -> None: + """Causes on_startup signal + + Should be called in the event loop along with the request handler. + """ + await self.on_startup.send(self) + + async def shutdown(self) -> None: + """Causes on_shutdown signal + + Should be called before cleanup() + """ + await self.on_shutdown.send(self) + + async def cleanup(self) -> None: + """Causes on_cleanup signal + + Should be called after shutdown() + """ + await self.on_cleanup.send(self) + + def _make_request( + self, + message: RawRequestMessage, + payload: StreamReader, + protocol: RequestHandler, + writer: AbstractStreamWriter, + task: "asyncio.Task[None]", + _cls: Type[Request] = Request, + ) -> Request: + return _cls( + message, + payload, + protocol, + writer, + task, + self._loop, + client_max_size=self._client_max_size, + ) + + def _prepare_middleware(self) -> Iterator[Tuple[_Middleware, bool]]: + for m in reversed(self._middlewares): + if getattr(m, "__middleware_version__", None) == 1: + yield m, True + else: + warnings.warn( + 'old-style middleware "{!r}" deprecated, ' "see #2252".format(m), + DeprecationWarning, + stacklevel=2, + ) + yield m, False + + yield _fix_request_current_app(self), True + + async def _handle(self, request: Request) -> StreamResponse: + loop = asyncio.get_event_loop() + debug = loop.get_debug() + match_info = await self._router.resolve(request) + if debug: # pragma: no cover + if not isinstance(match_info, AbstractMatchInfo): + raise TypeError( + "match_info should be AbstractMatchInfo " + "instance, not {!r}".format(match_info) + ) + match_info.add_app(self) + + match_info.freeze() + + resp = None + request._match_info = match_info # type: ignore + expect = request.headers.get(hdrs.EXPECT) + if expect: + resp = await match_info.expect_handler(request) + await request.writer.drain() + + if resp is None: + handler = match_info.handler + + if self._run_middlewares: + for app in match_info.apps[::-1]: + for m, new_style in app._middlewares_handlers: # type: ignore + if new_style: + handler = update_wrapper( + partial(m, handler=handler), handler + ) + else: + handler = await m(app, handler) # type: ignore + + resp = await handler(request) + + return resp + + def __call__(self) -> "Application": + """gunicorn compatibility""" + return self + + def __repr__(self) -> str: + return "".format(id(self)) + + def __bool__(self) -> bool: + return True + + +class CleanupError(RuntimeError): + @property + def exceptions(self) -> List[BaseException]: + return self.args[1] + + +if TYPE_CHECKING: # pragma: no cover + _CleanupContextBase = FrozenList[Callable[[Application], AsyncIterator[None]]] +else: + _CleanupContextBase = FrozenList + + +class CleanupContext(_CleanupContextBase): + def __init__(self) -> None: + super().__init__() + self._exits = [] # type: List[AsyncIterator[None]] + + async def _on_startup(self, app: Application) -> None: + for cb in self: + it = cb(app).__aiter__() + await it.__anext__() + self._exits.append(it) + + async def _on_cleanup(self, app: Application) -> None: + errors = [] + for it in reversed(self._exits): + try: + await it.__anext__() + except StopAsyncIteration: + pass + except Exception as exc: + errors.append(exc) + else: + errors.append(RuntimeError(f"{it!r} has more than one 'yield'")) + if errors: + if len(errors) == 1: + raise errors[0] + else: + raise CleanupError("Multiple errors on cleanup stage", errors) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_exceptions.py b/dist/ba_data/python-site-packages/aiohttp/web_exceptions.py new file mode 100644 index 0000000..2eadca0 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_exceptions.py @@ -0,0 +1,441 @@ +import warnings +from typing import Any, Dict, Iterable, List, Optional, Set # noqa + +from yarl import URL + +from .typedefs import LooseHeaders, StrOrURL +from .web_response import Response + +__all__ = ( + "HTTPException", + "HTTPError", + "HTTPRedirection", + "HTTPSuccessful", + "HTTPOk", + "HTTPCreated", + "HTTPAccepted", + "HTTPNonAuthoritativeInformation", + "HTTPNoContent", + "HTTPResetContent", + "HTTPPartialContent", + "HTTPMultipleChoices", + "HTTPMovedPermanently", + "HTTPFound", + "HTTPSeeOther", + "HTTPNotModified", + "HTTPUseProxy", + "HTTPTemporaryRedirect", + "HTTPPermanentRedirect", + "HTTPClientError", + "HTTPBadRequest", + "HTTPUnauthorized", + "HTTPPaymentRequired", + "HTTPForbidden", + "HTTPNotFound", + "HTTPMethodNotAllowed", + "HTTPNotAcceptable", + "HTTPProxyAuthenticationRequired", + "HTTPRequestTimeout", + "HTTPConflict", + "HTTPGone", + "HTTPLengthRequired", + "HTTPPreconditionFailed", + "HTTPRequestEntityTooLarge", + "HTTPRequestURITooLong", + "HTTPUnsupportedMediaType", + "HTTPRequestRangeNotSatisfiable", + "HTTPExpectationFailed", + "HTTPMisdirectedRequest", + "HTTPUnprocessableEntity", + "HTTPFailedDependency", + "HTTPUpgradeRequired", + "HTTPPreconditionRequired", + "HTTPTooManyRequests", + "HTTPRequestHeaderFieldsTooLarge", + "HTTPUnavailableForLegalReasons", + "HTTPServerError", + "HTTPInternalServerError", + "HTTPNotImplemented", + "HTTPBadGateway", + "HTTPServiceUnavailable", + "HTTPGatewayTimeout", + "HTTPVersionNotSupported", + "HTTPVariantAlsoNegotiates", + "HTTPInsufficientStorage", + "HTTPNotExtended", + "HTTPNetworkAuthenticationRequired", +) + + +############################################################ +# HTTP Exceptions +############################################################ + + +class HTTPException(Response, Exception): + + # You should set in subclasses: + # status = 200 + + status_code = -1 + empty_body = False + + __http_exception__ = True + + def __init__( + self, + *, + headers: Optional[LooseHeaders] = None, + reason: Optional[str] = None, + body: Any = None, + text: Optional[str] = None, + content_type: Optional[str] = None, + ) -> None: + if body is not None: + warnings.warn( + "body argument is deprecated for http web exceptions", + DeprecationWarning, + ) + Response.__init__( + self, + status=self.status_code, + headers=headers, + reason=reason, + body=body, + text=text, + content_type=content_type, + ) + Exception.__init__(self, self.reason) + if self.body is None and not self.empty_body: + self.text = f"{self.status}: {self.reason}" + + def __bool__(self) -> bool: + return True + + +class HTTPError(HTTPException): + """Base class for exceptions with status codes in the 400s and 500s.""" + + +class HTTPRedirection(HTTPException): + """Base class for exceptions with status codes in the 300s.""" + + +class HTTPSuccessful(HTTPException): + """Base class for exceptions with status codes in the 200s.""" + + +class HTTPOk(HTTPSuccessful): + status_code = 200 + + +class HTTPCreated(HTTPSuccessful): + status_code = 201 + + +class HTTPAccepted(HTTPSuccessful): + status_code = 202 + + +class HTTPNonAuthoritativeInformation(HTTPSuccessful): + status_code = 203 + + +class HTTPNoContent(HTTPSuccessful): + status_code = 204 + empty_body = True + + +class HTTPResetContent(HTTPSuccessful): + status_code = 205 + empty_body = True + + +class HTTPPartialContent(HTTPSuccessful): + status_code = 206 + + +############################################################ +# 3xx redirection +############################################################ + + +class _HTTPMove(HTTPRedirection): + def __init__( + self, + location: StrOrURL, + *, + headers: Optional[LooseHeaders] = None, + reason: Optional[str] = None, + body: Any = None, + text: Optional[str] = None, + content_type: Optional[str] = None, + ) -> None: + if not location: + raise ValueError("HTTP redirects need a location to redirect to.") + super().__init__( + headers=headers, + reason=reason, + body=body, + text=text, + content_type=content_type, + ) + self.headers["Location"] = str(URL(location)) + self.location = location + + +class HTTPMultipleChoices(_HTTPMove): + status_code = 300 + + +class HTTPMovedPermanently(_HTTPMove): + status_code = 301 + + +class HTTPFound(_HTTPMove): + status_code = 302 + + +# This one is safe after a POST (the redirected location will be +# retrieved with GET): +class HTTPSeeOther(_HTTPMove): + status_code = 303 + + +class HTTPNotModified(HTTPRedirection): + # FIXME: this should include a date or etag header + status_code = 304 + empty_body = True + + +class HTTPUseProxy(_HTTPMove): + # Not a move, but looks a little like one + status_code = 305 + + +class HTTPTemporaryRedirect(_HTTPMove): + status_code = 307 + + +class HTTPPermanentRedirect(_HTTPMove): + status_code = 308 + + +############################################################ +# 4xx client error +############################################################ + + +class HTTPClientError(HTTPError): + pass + + +class HTTPBadRequest(HTTPClientError): + status_code = 400 + + +class HTTPUnauthorized(HTTPClientError): + status_code = 401 + + +class HTTPPaymentRequired(HTTPClientError): + status_code = 402 + + +class HTTPForbidden(HTTPClientError): + status_code = 403 + + +class HTTPNotFound(HTTPClientError): + status_code = 404 + + +class HTTPMethodNotAllowed(HTTPClientError): + status_code = 405 + + def __init__( + self, + method: str, + allowed_methods: Iterable[str], + *, + headers: Optional[LooseHeaders] = None, + reason: Optional[str] = None, + body: Any = None, + text: Optional[str] = None, + content_type: Optional[str] = None, + ) -> None: + allow = ",".join(sorted(allowed_methods)) + super().__init__( + headers=headers, + reason=reason, + body=body, + text=text, + content_type=content_type, + ) + self.headers["Allow"] = allow + self.allowed_methods = set(allowed_methods) # type: Set[str] + self.method = method.upper() + + +class HTTPNotAcceptable(HTTPClientError): + status_code = 406 + + +class HTTPProxyAuthenticationRequired(HTTPClientError): + status_code = 407 + + +class HTTPRequestTimeout(HTTPClientError): + status_code = 408 + + +class HTTPConflict(HTTPClientError): + status_code = 409 + + +class HTTPGone(HTTPClientError): + status_code = 410 + + +class HTTPLengthRequired(HTTPClientError): + status_code = 411 + + +class HTTPPreconditionFailed(HTTPClientError): + status_code = 412 + + +class HTTPRequestEntityTooLarge(HTTPClientError): + status_code = 413 + + def __init__(self, max_size: float, actual_size: float, **kwargs: Any) -> None: + kwargs.setdefault( + "text", + "Maximum request body size {} exceeded, " + "actual body size {}".format(max_size, actual_size), + ) + super().__init__(**kwargs) + + +class HTTPRequestURITooLong(HTTPClientError): + status_code = 414 + + +class HTTPUnsupportedMediaType(HTTPClientError): + status_code = 415 + + +class HTTPRequestRangeNotSatisfiable(HTTPClientError): + status_code = 416 + + +class HTTPExpectationFailed(HTTPClientError): + status_code = 417 + + +class HTTPMisdirectedRequest(HTTPClientError): + status_code = 421 + + +class HTTPUnprocessableEntity(HTTPClientError): + status_code = 422 + + +class HTTPFailedDependency(HTTPClientError): + status_code = 424 + + +class HTTPUpgradeRequired(HTTPClientError): + status_code = 426 + + +class HTTPPreconditionRequired(HTTPClientError): + status_code = 428 + + +class HTTPTooManyRequests(HTTPClientError): + status_code = 429 + + +class HTTPRequestHeaderFieldsTooLarge(HTTPClientError): + status_code = 431 + + +class HTTPUnavailableForLegalReasons(HTTPClientError): + status_code = 451 + + def __init__( + self, + link: str, + *, + headers: Optional[LooseHeaders] = None, + reason: Optional[str] = None, + body: Any = None, + text: Optional[str] = None, + content_type: Optional[str] = None, + ) -> None: + super().__init__( + headers=headers, + reason=reason, + body=body, + text=text, + content_type=content_type, + ) + self.headers["Link"] = '<%s>; rel="blocked-by"' % link + self.link = link + + +############################################################ +# 5xx Server Error +############################################################ +# Response status codes beginning with the digit "5" indicate cases in +# which the server is aware that it has erred or is incapable of +# performing the request. Except when responding to a HEAD request, the +# server SHOULD include an entity containing an explanation of the error +# situation, and whether it is a temporary or permanent condition. User +# agents SHOULD display any included entity to the user. These response +# codes are applicable to any request method. + + +class HTTPServerError(HTTPError): + pass + + +class HTTPInternalServerError(HTTPServerError): + status_code = 500 + + +class HTTPNotImplemented(HTTPServerError): + status_code = 501 + + +class HTTPBadGateway(HTTPServerError): + status_code = 502 + + +class HTTPServiceUnavailable(HTTPServerError): + status_code = 503 + + +class HTTPGatewayTimeout(HTTPServerError): + status_code = 504 + + +class HTTPVersionNotSupported(HTTPServerError): + status_code = 505 + + +class HTTPVariantAlsoNegotiates(HTTPServerError): + status_code = 506 + + +class HTTPInsufficientStorage(HTTPServerError): + status_code = 507 + + +class HTTPNotExtended(HTTPServerError): + status_code = 510 + + +class HTTPNetworkAuthenticationRequired(HTTPServerError): + status_code = 511 diff --git a/dist/ba_data/python-site-packages/aiohttp/web_fileresponse.py b/dist/ba_data/python-site-packages/aiohttp/web_fileresponse.py new file mode 100644 index 0000000..0737c4f --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_fileresponse.py @@ -0,0 +1,243 @@ +import asyncio +import mimetypes +import os +import pathlib +import sys +from typing import ( # noqa + IO, + TYPE_CHECKING, + Any, + Awaitable, + Callable, + List, + Optional, + Union, + cast, +) + +from . import hdrs +from .abc import AbstractStreamWriter +from .typedefs import LooseHeaders +from .web_exceptions import ( + HTTPNotModified, + HTTPPartialContent, + HTTPPreconditionFailed, + HTTPRequestRangeNotSatisfiable, +) +from .web_response import StreamResponse + +__all__ = ("FileResponse",) + +if TYPE_CHECKING: # pragma: no cover + from .web_request import BaseRequest + + +_T_OnChunkSent = Optional[Callable[[bytes], Awaitable[None]]] + + +NOSENDFILE = bool(os.environ.get("AIOHTTP_NOSENDFILE")) + + +class FileResponse(StreamResponse): + """A response object can be used to send files.""" + + def __init__( + self, + path: Union[str, pathlib.Path], + chunk_size: int = 256 * 1024, + status: int = 200, + reason: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + ) -> None: + super().__init__(status=status, reason=reason, headers=headers) + + if isinstance(path, str): + path = pathlib.Path(path) + + self._path = path + self._chunk_size = chunk_size + + async def _sendfile_fallback( + self, writer: AbstractStreamWriter, fobj: IO[Any], offset: int, count: int + ) -> AbstractStreamWriter: + # To keep memory usage low,fobj is transferred in chunks + # controlled by the constructor's chunk_size argument. + + chunk_size = self._chunk_size + loop = asyncio.get_event_loop() + + await loop.run_in_executor(None, fobj.seek, offset) + + chunk = await loop.run_in_executor(None, fobj.read, chunk_size) + while chunk: + await writer.write(chunk) + count = count - chunk_size + if count <= 0: + break + chunk = await loop.run_in_executor(None, fobj.read, min(chunk_size, count)) + + await writer.drain() + return writer + + async def _sendfile( + self, request: "BaseRequest", fobj: IO[Any], offset: int, count: int + ) -> AbstractStreamWriter: + writer = await super().prepare(request) + assert writer is not None + + if NOSENDFILE or sys.version_info < (3, 7) or self.compression: + return await self._sendfile_fallback(writer, fobj, offset, count) + + loop = request._loop + transport = request.transport + assert transport is not None + + try: + await loop.sendfile(transport, fobj, offset, count) + except NotImplementedError: + return await self._sendfile_fallback(writer, fobj, offset, count) + + await super().write_eof() + return writer + + async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter]: + filepath = self._path + + gzip = False + if "gzip" in request.headers.get(hdrs.ACCEPT_ENCODING, ""): + gzip_path = filepath.with_name(filepath.name + ".gz") + + if gzip_path.is_file(): + filepath = gzip_path + gzip = True + + loop = asyncio.get_event_loop() + st = await loop.run_in_executor(None, filepath.stat) + + modsince = request.if_modified_since + if modsince is not None and st.st_mtime <= modsince.timestamp(): + self.set_status(HTTPNotModified.status_code) + self._length_check = False + # Delete any Content-Length headers provided by user. HTTP 304 + # should always have empty response body + return await super().prepare(request) + + unmodsince = request.if_unmodified_since + if unmodsince is not None and st.st_mtime > unmodsince.timestamp(): + self.set_status(HTTPPreconditionFailed.status_code) + return await super().prepare(request) + + if hdrs.CONTENT_TYPE not in self.headers: + ct, encoding = mimetypes.guess_type(str(filepath)) + if not ct: + ct = "application/octet-stream" + should_set_ct = True + else: + encoding = "gzip" if gzip else None + should_set_ct = False + + status = self._status + file_size = st.st_size + count = file_size + + start = None + + ifrange = request.if_range + if ifrange is None or st.st_mtime <= ifrange.timestamp(): + # If-Range header check: + # condition = cached date >= last modification date + # return 206 if True else 200. + # if False: + # Range header would not be processed, return 200 + # if True but Range header missing + # return 200 + try: + rng = request.http_range + start = rng.start + end = rng.stop + except ValueError: + # https://tools.ietf.org/html/rfc7233: + # A server generating a 416 (Range Not Satisfiable) response to + # a byte-range request SHOULD send a Content-Range header field + # with an unsatisfied-range value. + # The complete-length in a 416 response indicates the current + # length of the selected representation. + # + # Will do the same below. Many servers ignore this and do not + # send a Content-Range header with HTTP 416 + self.headers[hdrs.CONTENT_RANGE] = f"bytes */{file_size}" + self.set_status(HTTPRequestRangeNotSatisfiable.status_code) + return await super().prepare(request) + + # If a range request has been made, convert start, end slice + # notation into file pointer offset and count + if start is not None or end is not None: + if start < 0 and end is None: # return tail of file + start += file_size + if start < 0: + # if Range:bytes=-1000 in request header but file size + # is only 200, there would be trouble without this + start = 0 + count = file_size - start + else: + # rfc7233:If the last-byte-pos value is + # absent, or if the value is greater than or equal to + # the current length of the representation data, + # the byte range is interpreted as the remainder + # of the representation (i.e., the server replaces the + # value of last-byte-pos with a value that is one less than + # the current length of the selected representation). + count = ( + min(end if end is not None else file_size, file_size) - start + ) + + if start >= file_size: + # HTTP 416 should be returned in this case. + # + # According to https://tools.ietf.org/html/rfc7233: + # If a valid byte-range-set includes at least one + # byte-range-spec with a first-byte-pos that is less than + # the current length of the representation, or at least one + # suffix-byte-range-spec with a non-zero suffix-length, + # then the byte-range-set is satisfiable. Otherwise, the + # byte-range-set is unsatisfiable. + self.headers[hdrs.CONTENT_RANGE] = f"bytes */{file_size}" + self.set_status(HTTPRequestRangeNotSatisfiable.status_code) + return await super().prepare(request) + + status = HTTPPartialContent.status_code + # Even though you are sending the whole file, you should still + # return a HTTP 206 for a Range request. + self.set_status(status) + + if should_set_ct: + self.content_type = ct # type: ignore + if encoding: + self.headers[hdrs.CONTENT_ENCODING] = encoding + if gzip: + self.headers[hdrs.VARY] = hdrs.ACCEPT_ENCODING + self.last_modified = st.st_mtime # type: ignore + self.content_length = count + + self.headers[hdrs.ACCEPT_RANGES] = "bytes" + + real_start = cast(int, start) + + if status == HTTPPartialContent.status_code: + self.headers[hdrs.CONTENT_RANGE] = "bytes {}-{}/{}".format( + real_start, real_start + count - 1, file_size + ) + + if request.method == hdrs.METH_HEAD or self.status in [204, 304]: + return await super().prepare(request) + + fobj = await loop.run_in_executor(None, filepath.open, "rb") + if start: # be aware that start could be None or int=0 here. + offset = start + else: + offset = 0 + + try: + return await self._sendfile(request, fobj, offset, count) + finally: + await loop.run_in_executor(None, fobj.close) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_log.py b/dist/ba_data/python-site-packages/aiohttp/web_log.py new file mode 100644 index 0000000..4cfa579 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_log.py @@ -0,0 +1,208 @@ +import datetime +import functools +import logging +import os +import re +from collections import namedtuple +from typing import Any, Callable, Dict, Iterable, List, Tuple # noqa + +from .abc import AbstractAccessLogger +from .web_request import BaseRequest +from .web_response import StreamResponse + +KeyMethod = namedtuple("KeyMethod", "key method") + + +class AccessLogger(AbstractAccessLogger): + """Helper object to log access. + + Usage: + log = logging.getLogger("spam") + log_format = "%a %{User-Agent}i" + access_logger = AccessLogger(log, log_format) + access_logger.log(request, response, time) + + Format: + %% The percent sign + %a Remote IP-address (IP-address of proxy if using reverse proxy) + %t Time when the request was started to process + %P The process ID of the child that serviced the request + %r First line of request + %s Response status code + %b Size of response in bytes, including HTTP headers + %T Time taken to serve the request, in seconds + %Tf Time taken to serve the request, in seconds with floating fraction + in .06f format + %D Time taken to serve the request, in microseconds + %{FOO}i request.headers['FOO'] + %{FOO}o response.headers['FOO'] + %{FOO}e os.environ['FOO'] + + """ + + LOG_FORMAT_MAP = { + "a": "remote_address", + "t": "request_start_time", + "P": "process_id", + "r": "first_request_line", + "s": "response_status", + "b": "response_size", + "T": "request_time", + "Tf": "request_time_frac", + "D": "request_time_micro", + "i": "request_header", + "o": "response_header", + } + + LOG_FORMAT = '%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"' + FORMAT_RE = re.compile(r"%(\{([A-Za-z0-9\-_]+)\}([ioe])|[atPrsbOD]|Tf?)") + CLEANUP_RE = re.compile(r"(%[^s])") + _FORMAT_CACHE = {} # type: Dict[str, Tuple[str, List[KeyMethod]]] + + def __init__(self, logger: logging.Logger, log_format: str = LOG_FORMAT) -> None: + """Initialise the logger. + + logger is a logger object to be used for logging. + log_format is a string with apache compatible log format description. + + """ + super().__init__(logger, log_format=log_format) + + _compiled_format = AccessLogger._FORMAT_CACHE.get(log_format) + if not _compiled_format: + _compiled_format = self.compile_format(log_format) + AccessLogger._FORMAT_CACHE[log_format] = _compiled_format + + self._log_format, self._methods = _compiled_format + + def compile_format(self, log_format: str) -> Tuple[str, List[KeyMethod]]: + """Translate log_format into form usable by modulo formatting + + All known atoms will be replaced with %s + Also methods for formatting of those atoms will be added to + _methods in appropriate order + + For example we have log_format = "%a %t" + This format will be translated to "%s %s" + Also contents of _methods will be + [self._format_a, self._format_t] + These method will be called and results will be passed + to translated string format. + + Each _format_* method receive 'args' which is list of arguments + given to self.log + + Exceptions are _format_e, _format_i and _format_o methods which + also receive key name (by functools.partial) + + """ + # list of (key, method) tuples, we don't use an OrderedDict as users + # can repeat the same key more than once + methods = list() + + for atom in self.FORMAT_RE.findall(log_format): + if atom[1] == "": + format_key1 = self.LOG_FORMAT_MAP[atom[0]] + m = getattr(AccessLogger, "_format_%s" % atom[0]) + key_method = KeyMethod(format_key1, m) + else: + format_key2 = (self.LOG_FORMAT_MAP[atom[2]], atom[1]) + m = getattr(AccessLogger, "_format_%s" % atom[2]) + key_method = KeyMethod(format_key2, functools.partial(m, atom[1])) + + methods.append(key_method) + + log_format = self.FORMAT_RE.sub(r"%s", log_format) + log_format = self.CLEANUP_RE.sub(r"%\1", log_format) + return log_format, methods + + @staticmethod + def _format_i( + key: str, request: BaseRequest, response: StreamResponse, time: float + ) -> str: + if request is None: + return "(no headers)" + + # suboptimal, make istr(key) once + return request.headers.get(key, "-") + + @staticmethod + def _format_o( + key: str, request: BaseRequest, response: StreamResponse, time: float + ) -> str: + # suboptimal, make istr(key) once + return response.headers.get(key, "-") + + @staticmethod + def _format_a(request: BaseRequest, response: StreamResponse, time: float) -> str: + if request is None: + return "-" + ip = request.remote + return ip if ip is not None else "-" + + @staticmethod + def _format_t(request: BaseRequest, response: StreamResponse, time: float) -> str: + now = datetime.datetime.utcnow() + start_time = now - datetime.timedelta(seconds=time) + return start_time.strftime("[%d/%b/%Y:%H:%M:%S +0000]") + + @staticmethod + def _format_P(request: BaseRequest, response: StreamResponse, time: float) -> str: + return "<%s>" % os.getpid() + + @staticmethod + def _format_r(request: BaseRequest, response: StreamResponse, time: float) -> str: + if request is None: + return "-" + return "{} {} HTTP/{}.{}".format( + request.method, + request.path_qs, + request.version.major, + request.version.minor, + ) + + @staticmethod + def _format_s(request: BaseRequest, response: StreamResponse, time: float) -> int: + return response.status + + @staticmethod + def _format_b(request: BaseRequest, response: StreamResponse, time: float) -> int: + return response.body_length + + @staticmethod + def _format_T(request: BaseRequest, response: StreamResponse, time: float) -> str: + return str(round(time)) + + @staticmethod + def _format_Tf(request: BaseRequest, response: StreamResponse, time: float) -> str: + return "%06f" % time + + @staticmethod + def _format_D(request: BaseRequest, response: StreamResponse, time: float) -> str: + return str(round(time * 1000000)) + + def _format_line( + self, request: BaseRequest, response: StreamResponse, time: float + ) -> Iterable[Tuple[str, Callable[[BaseRequest, StreamResponse, float], str]]]: + return [(key, method(request, response, time)) for key, method in self._methods] + + def log(self, request: BaseRequest, response: StreamResponse, time: float) -> None: + try: + fmt_info = self._format_line(request, response, time) + + values = list() + extra = dict() + for key, value in fmt_info: + values.append(value) + + if key.__class__ is str: + extra[key] = value + else: + k1, k2 = key # type: ignore + dct = extra.get(k1, {}) # type: ignore + dct[k2] = value # type: ignore + extra[k1] = dct # type: ignore + + self.logger.info(self._log_format % tuple(values), extra=extra) + except Exception: + self.logger.exception("Error in logging") diff --git a/dist/ba_data/python-site-packages/aiohttp/web_middlewares.py b/dist/ba_data/python-site-packages/aiohttp/web_middlewares.py new file mode 100644 index 0000000..8a8967e --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_middlewares.py @@ -0,0 +1,121 @@ +import re +from typing import TYPE_CHECKING, Awaitable, Callable, Tuple, Type, TypeVar + +from .web_exceptions import HTTPPermanentRedirect, _HTTPMove +from .web_request import Request +from .web_response import StreamResponse +from .web_urldispatcher import SystemRoute + +__all__ = ( + "middleware", + "normalize_path_middleware", +) + +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application + +_Func = TypeVar("_Func") + + +async def _check_request_resolves(request: Request, path: str) -> Tuple[bool, Request]: + alt_request = request.clone(rel_url=path) + + match_info = await request.app.router.resolve(alt_request) + alt_request._match_info = match_info # type: ignore + + if match_info.http_exception is None: + return True, alt_request + + return False, request + + +def middleware(f: _Func) -> _Func: + f.__middleware_version__ = 1 # type: ignore + return f + + +_Handler = Callable[[Request], Awaitable[StreamResponse]] +_Middleware = Callable[[Request, _Handler], Awaitable[StreamResponse]] + + +def normalize_path_middleware( + *, + append_slash: bool = True, + remove_slash: bool = False, + merge_slashes: bool = True, + redirect_class: Type[_HTTPMove] = HTTPPermanentRedirect +) -> _Middleware: + """ + Middleware factory which produces a middleware that normalizes + the path of a request. By normalizing it means: + + - Add or remove a trailing slash to the path. + - Double slashes are replaced by one. + + The middleware returns as soon as it finds a path that resolves + correctly. The order if both merge and append/remove are enabled is + 1) merge slashes + 2) append/remove slash + 3) both merge slashes and append/remove slash. + If the path resolves with at least one of those conditions, it will + redirect to the new path. + + Only one of `append_slash` and `remove_slash` can be enabled. If both + are `True` the factory will raise an assertion error + + If `append_slash` is `True` the middleware will append a slash when + needed. If a resource is defined with trailing slash and the request + comes without it, it will append it automatically. + + If `remove_slash` is `True`, `append_slash` must be `False`. When enabled + the middleware will remove trailing slashes and redirect if the resource + is defined + + If merge_slashes is True, merge multiple consecutive slashes in the + path into one. + """ + + correct_configuration = not (append_slash and remove_slash) + assert correct_configuration, "Cannot both remove and append slash" + + @middleware + async def impl(request: Request, handler: _Handler) -> StreamResponse: + if isinstance(request.match_info.route, SystemRoute): + paths_to_check = [] + if "?" in request.raw_path: + path, query = request.raw_path.split("?", 1) + query = "?" + query + else: + query = "" + path = request.raw_path + + if merge_slashes: + paths_to_check.append(re.sub("//+", "/", path)) + if append_slash and not request.path.endswith("/"): + paths_to_check.append(path + "/") + if remove_slash and request.path.endswith("/"): + paths_to_check.append(path[:-1]) + if merge_slashes and append_slash: + paths_to_check.append(re.sub("//+", "/", path + "/")) + if merge_slashes and remove_slash: + merged_slashes = re.sub("//+", "/", path) + paths_to_check.append(merged_slashes[:-1]) + + for path in paths_to_check: + path = re.sub("^//+", "/", path) # SECURITY: GHSA-v6wp-4m6f-gcjg + resolves, request = await _check_request_resolves(request, path) + if resolves: + raise redirect_class(request.raw_path + query) + + return await handler(request) + + return impl + + +def _fix_request_current_app(app: "Application") -> _Middleware: + @middleware + async def impl(request: Request, handler: _Handler) -> StreamResponse: + with request.match_info.set_current_app(app): + return await handler(request) + + return impl diff --git a/dist/ba_data/python-site-packages/aiohttp/web_protocol.py b/dist/ba_data/python-site-packages/aiohttp/web_protocol.py new file mode 100644 index 0000000..8e02bc4 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_protocol.py @@ -0,0 +1,667 @@ +import asyncio +import asyncio.streams +import traceback +import warnings +from collections import deque +from contextlib import suppress +from html import escape as html_escape +from http import HTTPStatus +from logging import Logger +from typing import TYPE_CHECKING, Any, Awaitable, Callable, Optional, Tuple, Type, cast + +import yarl + +from .abc import AbstractAccessLogger, AbstractStreamWriter +from .base_protocol import BaseProtocol +from .helpers import CeilTimeout, current_task +from .http import ( + HttpProcessingError, + HttpRequestParser, + HttpVersion10, + RawRequestMessage, + StreamWriter, +) +from .log import access_logger, server_logger +from .streams import EMPTY_PAYLOAD, StreamReader +from .tcp_helpers import tcp_keepalive +from .web_exceptions import HTTPException +from .web_log import AccessLogger +from .web_request import BaseRequest +from .web_response import Response, StreamResponse + +__all__ = ("RequestHandler", "RequestPayloadError", "PayloadAccessError") + +if TYPE_CHECKING: # pragma: no cover + from .web_server import Server + + +_RequestFactory = Callable[ + [ + RawRequestMessage, + StreamReader, + "RequestHandler", + AbstractStreamWriter, + "asyncio.Task[None]", + ], + BaseRequest, +] + +_RequestHandler = Callable[[BaseRequest], Awaitable[StreamResponse]] + + +ERROR = RawRequestMessage( + "UNKNOWN", "/", HttpVersion10, {}, {}, True, False, False, False, yarl.URL("/") +) + + +class RequestPayloadError(Exception): + """Payload parsing error.""" + + +class PayloadAccessError(Exception): + """Payload was accessed after response was sent.""" + + +class RequestHandler(BaseProtocol): + """HTTP protocol implementation. + + RequestHandler handles incoming HTTP request. It reads request line, + request headers and request payload and calls handle_request() method. + By default it always returns with 404 response. + + RequestHandler handles errors in incoming request, like bad + status line, bad headers or incomplete payload. If any error occurs, + connection gets closed. + + :param keepalive_timeout: number of seconds before closing + keep-alive connection + :type keepalive_timeout: int or None + + :param bool tcp_keepalive: TCP keep-alive is on, default is on + + :param bool debug: enable debug mode + + :param logger: custom logger object + :type logger: aiohttp.log.server_logger + + :param access_log_class: custom class for access_logger + :type access_log_class: aiohttp.abc.AbstractAccessLogger + + :param access_log: custom logging object + :type access_log: aiohttp.log.server_logger + + :param str access_log_format: access log format string + + :param loop: Optional event loop + + :param int max_line_size: Optional maximum header line size + + :param int max_field_size: Optional maximum header field size + + :param int max_headers: Optional maximum header size + + """ + + KEEPALIVE_RESCHEDULE_DELAY = 1 + + __slots__ = ( + "_request_count", + "_keepalive", + "_manager", + "_request_handler", + "_request_factory", + "_tcp_keepalive", + "_keepalive_time", + "_keepalive_handle", + "_keepalive_timeout", + "_lingering_time", + "_messages", + "_message_tail", + "_waiter", + "_error_handler", + "_task_handler", + "_upgrade", + "_payload_parser", + "_request_parser", + "_reading_paused", + "logger", + "debug", + "access_log", + "access_logger", + "_close", + "_force_close", + "_current_request", + ) + + def __init__( + self, + manager: "Server", + *, + loop: asyncio.AbstractEventLoop, + keepalive_timeout: float = 75.0, # NGINX default is 75 secs + tcp_keepalive: bool = True, + logger: Logger = server_logger, + access_log_class: Type[AbstractAccessLogger] = AccessLogger, + access_log: Logger = access_logger, + access_log_format: str = AccessLogger.LOG_FORMAT, + debug: bool = False, + max_line_size: int = 8190, + max_headers: int = 32768, + max_field_size: int = 8190, + lingering_time: float = 10.0, + read_bufsize: int = 2 ** 16, + ): + + super().__init__(loop) + + self._request_count = 0 + self._keepalive = False + self._current_request = None # type: Optional[BaseRequest] + self._manager = manager # type: Optional[Server] + self._request_handler = ( + manager.request_handler + ) # type: Optional[_RequestHandler] + self._request_factory = ( + manager.request_factory + ) # type: Optional[_RequestFactory] + + self._tcp_keepalive = tcp_keepalive + # placeholder to be replaced on keepalive timeout setup + self._keepalive_time = 0.0 + self._keepalive_handle = None # type: Optional[asyncio.Handle] + self._keepalive_timeout = keepalive_timeout + self._lingering_time = float(lingering_time) + + self._messages = deque() # type: Any # Python 3.5 has no typing.Deque + self._message_tail = b"" + + self._waiter = None # type: Optional[asyncio.Future[None]] + self._error_handler = None # type: Optional[asyncio.Task[None]] + self._task_handler = None # type: Optional[asyncio.Task[None]] + + self._upgrade = False + self._payload_parser = None # type: Any + self._request_parser = HttpRequestParser( + self, + loop, + read_bufsize, + max_line_size=max_line_size, + max_field_size=max_field_size, + max_headers=max_headers, + payload_exception=RequestPayloadError, + ) # type: Optional[HttpRequestParser] + + self.logger = logger + self.debug = debug + self.access_log = access_log + if access_log: + self.access_logger = access_log_class( + access_log, access_log_format + ) # type: Optional[AbstractAccessLogger] + else: + self.access_logger = None + + self._close = False + self._force_close = False + + def __repr__(self) -> str: + return "<{} {}>".format( + self.__class__.__name__, + "connected" if self.transport is not None else "disconnected", + ) + + @property + def keepalive_timeout(self) -> float: + return self._keepalive_timeout + + async def shutdown(self, timeout: Optional[float] = 15.0) -> None: + """Worker process is about to exit, we need cleanup everything and + stop accepting requests. It is especially important for keep-alive + connections.""" + self._force_close = True + + if self._keepalive_handle is not None: + self._keepalive_handle.cancel() + + if self._waiter: + self._waiter.cancel() + + # wait for handlers + with suppress(asyncio.CancelledError, asyncio.TimeoutError): + with CeilTimeout(timeout, loop=self._loop): + if self._error_handler is not None and not self._error_handler.done(): + await self._error_handler + + if self._current_request is not None: + self._current_request._cancel(asyncio.CancelledError()) + + if self._task_handler is not None and not self._task_handler.done(): + await self._task_handler + + # force-close non-idle handler + if self._task_handler is not None: + self._task_handler.cancel() + + if self.transport is not None: + self.transport.close() + self.transport = None + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + super().connection_made(transport) + + real_transport = cast(asyncio.Transport, transport) + if self._tcp_keepalive: + tcp_keepalive(real_transport) + + self._task_handler = self._loop.create_task(self.start()) + assert self._manager is not None + self._manager.connection_made(self, real_transport) + + def connection_lost(self, exc: Optional[BaseException]) -> None: + if self._manager is None: + return + self._manager.connection_lost(self, exc) + + super().connection_lost(exc) + + self._manager = None + self._force_close = True + self._request_factory = None + self._request_handler = None + self._request_parser = None + + if self._keepalive_handle is not None: + self._keepalive_handle.cancel() + + if self._current_request is not None: + if exc is None: + exc = ConnectionResetError("Connection lost") + self._current_request._cancel(exc) + + if self._error_handler is not None: + self._error_handler.cancel() + if self._task_handler is not None: + self._task_handler.cancel() + if self._waiter is not None: + self._waiter.cancel() + + self._task_handler = None + + if self._payload_parser is not None: + self._payload_parser.feed_eof() + self._payload_parser = None + + def set_parser(self, parser: Any) -> None: + # Actual type is WebReader + assert self._payload_parser is None + + self._payload_parser = parser + + if self._message_tail: + self._payload_parser.feed_data(self._message_tail) + self._message_tail = b"" + + def eof_received(self) -> None: + pass + + def data_received(self, data: bytes) -> None: + if self._force_close or self._close: + return + # parse http messages + if self._payload_parser is None and not self._upgrade: + assert self._request_parser is not None + try: + messages, upgraded, tail = self._request_parser.feed_data(data) + except HttpProcessingError as exc: + # something happened during parsing + self._error_handler = self._loop.create_task( + self.handle_parse_error( + StreamWriter(self, self._loop), 400, exc, exc.message + ) + ) + self.close() + except Exception as exc: + # 500: internal error + self._error_handler = self._loop.create_task( + self.handle_parse_error(StreamWriter(self, self._loop), 500, exc) + ) + self.close() + else: + if messages: + # sometimes the parser returns no messages + for (msg, payload) in messages: + self._request_count += 1 + self._messages.append((msg, payload)) + + waiter = self._waiter + if waiter is not None: + if not waiter.done(): + # don't set result twice + waiter.set_result(None) + + self._upgrade = upgraded + if upgraded and tail: + self._message_tail = tail + + # no parser, just store + elif self._payload_parser is None and self._upgrade and data: + self._message_tail += data + + # feed payload + elif data: + eof, tail = self._payload_parser.feed_data(data) + if eof: + self.close() + + def keep_alive(self, val: bool) -> None: + """Set keep-alive connection mode. + + :param bool val: new state. + """ + self._keepalive = val + if self._keepalive_handle: + self._keepalive_handle.cancel() + self._keepalive_handle = None + + def close(self) -> None: + """Stop accepting new pipelinig messages and close + connection when handlers done processing messages""" + self._close = True + if self._waiter: + self._waiter.cancel() + + def force_close(self) -> None: + """Force close connection""" + self._force_close = True + if self._waiter: + self._waiter.cancel() + if self.transport is not None: + self.transport.close() + self.transport = None + + def log_access( + self, request: BaseRequest, response: StreamResponse, time: float + ) -> None: + if self.access_logger is not None: + self.access_logger.log(request, response, self._loop.time() - time) + + def log_debug(self, *args: Any, **kw: Any) -> None: + if self.debug: + self.logger.debug(*args, **kw) + + def log_exception(self, *args: Any, **kw: Any) -> None: + self.logger.exception(*args, **kw) + + def _process_keepalive(self) -> None: + if self._force_close or not self._keepalive: + return + + next = self._keepalive_time + self._keepalive_timeout + + # handler in idle state + if self._waiter: + if self._loop.time() > next: + self.force_close() + return + + # not all request handlers are done, + # reschedule itself to next second + self._keepalive_handle = self._loop.call_later( + self.KEEPALIVE_RESCHEDULE_DELAY, self._process_keepalive + ) + + async def _handle_request( + self, + request: BaseRequest, + start_time: float, + ) -> Tuple[StreamResponse, bool]: + assert self._request_handler is not None + try: + try: + self._current_request = request + resp = await self._request_handler(request) + finally: + self._current_request = None + except HTTPException as exc: + resp = Response( + status=exc.status, reason=exc.reason, text=exc.text, headers=exc.headers + ) + reset = await self.finish_response(request, resp, start_time) + except asyncio.CancelledError: + raise + except asyncio.TimeoutError as exc: + self.log_debug("Request handler timed out.", exc_info=exc) + resp = self.handle_error(request, 504) + reset = await self.finish_response(request, resp, start_time) + except Exception as exc: + resp = self.handle_error(request, 500, exc) + reset = await self.finish_response(request, resp, start_time) + else: + reset = await self.finish_response(request, resp, start_time) + + return resp, reset + + async def start(self) -> None: + """Process incoming request. + + It reads request line, request headers and request payload, then + calls handle_request() method. Subclass has to override + handle_request(). start() handles various exceptions in request + or response handling. Connection is being closed always unless + keep_alive(True) specified. + """ + loop = self._loop + handler = self._task_handler + assert handler is not None + manager = self._manager + assert manager is not None + keepalive_timeout = self._keepalive_timeout + resp = None + assert self._request_factory is not None + assert self._request_handler is not None + + while not self._force_close: + if not self._messages: + try: + # wait for next request + self._waiter = loop.create_future() + await self._waiter + except asyncio.CancelledError: + break + finally: + self._waiter = None + + message, payload = self._messages.popleft() + + start = loop.time() + + manager.requests_count += 1 + writer = StreamWriter(self, loop) + request = self._request_factory(message, payload, self, writer, handler) + try: + # a new task is used for copy context vars (#3406) + task = self._loop.create_task(self._handle_request(request, start)) + try: + resp, reset = await task + except (asyncio.CancelledError, ConnectionError): + self.log_debug("Ignored premature client disconnection") + break + # Deprecation warning (See #2415) + if getattr(resp, "__http_exception__", False): + warnings.warn( + "returning HTTPException object is deprecated " + "(#2415) and will be removed, " + "please raise the exception instead", + DeprecationWarning, + ) + + # Drop the processed task from asyncio.Task.all_tasks() early + del task + if reset: + self.log_debug("Ignored premature client disconnection 2") + break + + # notify server about keep-alive + self._keepalive = bool(resp.keep_alive) + + # check payload + if not payload.is_eof(): + lingering_time = self._lingering_time + if not self._force_close and lingering_time: + self.log_debug( + "Start lingering close timer for %s sec.", lingering_time + ) + + now = loop.time() + end_t = now + lingering_time + + with suppress(asyncio.TimeoutError, asyncio.CancelledError): + while not payload.is_eof() and now < end_t: + with CeilTimeout(end_t - now, loop=loop): + # read and ignore + await payload.readany() + now = loop.time() + + # if payload still uncompleted + if not payload.is_eof() and not self._force_close: + self.log_debug("Uncompleted request.") + self.close() + + payload.set_exception(PayloadAccessError()) + + except asyncio.CancelledError: + self.log_debug("Ignored premature client disconnection ") + break + except RuntimeError as exc: + if self.debug: + self.log_exception("Unhandled runtime exception", exc_info=exc) + self.force_close() + except Exception as exc: + self.log_exception("Unhandled exception", exc_info=exc) + self.force_close() + finally: + if self.transport is None and resp is not None: + self.log_debug("Ignored premature client disconnection.") + elif not self._force_close: + if self._keepalive and not self._close: + # start keep-alive timer + if keepalive_timeout is not None: + now = self._loop.time() + self._keepalive_time = now + if self._keepalive_handle is None: + self._keepalive_handle = loop.call_at( + now + keepalive_timeout, self._process_keepalive + ) + else: + break + + # remove handler, close transport if no handlers left + if not self._force_close: + self._task_handler = None + if self.transport is not None and self._error_handler is None: + self.transport.close() + + async def finish_response( + self, request: BaseRequest, resp: StreamResponse, start_time: float + ) -> bool: + """ + Prepare the response and write_eof, then log access. This has to + be called within the context of any exception so the access logger + can get exception information. Returns True if the client disconnects + prematurely. + """ + if self._request_parser is not None: + self._request_parser.set_upgraded(False) + self._upgrade = False + if self._message_tail: + self._request_parser.feed_data(self._message_tail) + self._message_tail = b"" + try: + prepare_meth = resp.prepare + except AttributeError: + if resp is None: + raise RuntimeError("Missing return " "statement on request handler") + else: + raise RuntimeError( + "Web-handler should return " + "a response instance, " + "got {!r}".format(resp) + ) + try: + await prepare_meth(request) + await resp.write_eof() + except ConnectionError: + self.log_access(request, resp, start_time) + return True + else: + self.log_access(request, resp, start_time) + return False + + def handle_error( + self, + request: BaseRequest, + status: int = 500, + exc: Optional[BaseException] = None, + message: Optional[str] = None, + ) -> StreamResponse: + """Handle errors. + + Returns HTTP response with specific status code. Logs additional + information. It always closes current connection.""" + self.log_exception("Error handling request", exc_info=exc) + + ct = "text/plain" + if status == HTTPStatus.INTERNAL_SERVER_ERROR: + title = "{0.value} {0.phrase}".format(HTTPStatus.INTERNAL_SERVER_ERROR) + msg = HTTPStatus.INTERNAL_SERVER_ERROR.description + tb = None + if self.debug: + with suppress(Exception): + tb = traceback.format_exc() + + if "text/html" in request.headers.get("Accept", ""): + if tb: + tb = html_escape(tb) + msg = f"

Traceback:

\n
{tb}
" + message = ( + "" + "{title}" + "\n

{title}

" + "\n{msg}\n\n" + ).format(title=title, msg=msg) + ct = "text/html" + else: + if tb: + msg = tb + message = title + "\n\n" + msg + + resp = Response(status=status, text=message, content_type=ct) + resp.force_close() + + # some data already got sent, connection is broken + if request.writer.output_size > 0 or self.transport is None: + self.force_close() + + return resp + + async def handle_parse_error( + self, + writer: AbstractStreamWriter, + status: int, + exc: Optional[BaseException] = None, + message: Optional[str] = None, + ) -> None: + task = current_task() + assert task is not None + request = BaseRequest( + ERROR, EMPTY_PAYLOAD, self, writer, task, self._loop # type: ignore + ) + + resp = self.handle_error(request, status, exc, message) + await resp.prepare(request) + await resp.write_eof() + + if self.transport is not None: + self.transport.close() + + self._error_handler = None diff --git a/dist/ba_data/python-site-packages/aiohttp/web_request.py b/dist/ba_data/python-site-packages/aiohttp/web_request.py new file mode 100644 index 0000000..f11e7be --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_request.py @@ -0,0 +1,824 @@ +import asyncio +import datetime +import io +import re +import socket +import string +import tempfile +import types +import warnings +from email.utils import parsedate +from http.cookies import SimpleCookie +from types import MappingProxyType +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Iterator, + Mapping, + MutableMapping, + Optional, + Tuple, + Union, + cast, +) +from urllib.parse import parse_qsl + +import attr +from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy +from yarl import URL + +from . import hdrs +from .abc import AbstractStreamWriter +from .helpers import DEBUG, ChainMapProxy, HeadersMixin, reify, sentinel +from .http_parser import RawRequestMessage +from .http_writer import HttpVersion +from .multipart import BodyPartReader, MultipartReader +from .streams import EmptyStreamReader, StreamReader +from .typedefs import ( + DEFAULT_JSON_DECODER, + JSONDecoder, + LooseHeaders, + RawHeaders, + StrOrURL, +) +from .web_exceptions import HTTPRequestEntityTooLarge +from .web_response import StreamResponse + +__all__ = ("BaseRequest", "FileField", "Request") + + +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application + from .web_protocol import RequestHandler + from .web_urldispatcher import UrlMappingMatchInfo + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class FileField: + name: str + filename: str + file: io.BufferedReader + content_type: str + headers: "CIMultiDictProxy[str]" + + +_TCHAR = string.digits + string.ascii_letters + r"!#$%&'*+.^_`|~-" +# '-' at the end to prevent interpretation as range in a char class + +_TOKEN = fr"[{_TCHAR}]+" + +_QDTEXT = r"[{}]".format( + r"".join(chr(c) for c in (0x09, 0x20, 0x21) + tuple(range(0x23, 0x7F))) +) +# qdtext includes 0x5C to escape 0x5D ('\]') +# qdtext excludes obs-text (because obsoleted, and encoding not specified) + +_QUOTED_PAIR = r"\\[\t !-~]" + +_QUOTED_STRING = r'"(?:{quoted_pair}|{qdtext})*"'.format( + qdtext=_QDTEXT, quoted_pair=_QUOTED_PAIR +) + +_FORWARDED_PAIR = r"({token})=({token}|{quoted_string})(:\d{{1,4}})?".format( + token=_TOKEN, quoted_string=_QUOTED_STRING +) + +_QUOTED_PAIR_REPLACE_RE = re.compile(r"\\([\t !-~])") +# same pattern as _QUOTED_PAIR but contains a capture group + +_FORWARDED_PAIR_RE = re.compile(_FORWARDED_PAIR) + +############################################################ +# HTTP Request +############################################################ + + +class BaseRequest(MutableMapping[str, Any], HeadersMixin): + + POST_METHODS = { + hdrs.METH_PATCH, + hdrs.METH_POST, + hdrs.METH_PUT, + hdrs.METH_TRACE, + hdrs.METH_DELETE, + } + + ATTRS = HeadersMixin.ATTRS | frozenset( + [ + "_message", + "_protocol", + "_payload_writer", + "_payload", + "_headers", + "_method", + "_version", + "_rel_url", + "_post", + "_read_bytes", + "_state", + "_cache", + "_task", + "_client_max_size", + "_loop", + "_transport_sslcontext", + "_transport_peername", + ] + ) + + def __init__( + self, + message: RawRequestMessage, + payload: StreamReader, + protocol: "RequestHandler", + payload_writer: AbstractStreamWriter, + task: "asyncio.Task[None]", + loop: asyncio.AbstractEventLoop, + *, + client_max_size: int = 1024 ** 2, + state: Optional[Dict[str, Any]] = None, + scheme: Optional[str] = None, + host: Optional[str] = None, + remote: Optional[str] = None, + ) -> None: + if state is None: + state = {} + self._message = message + self._protocol = protocol + self._payload_writer = payload_writer + + self._payload = payload + self._headers = message.headers + self._method = message.method + self._version = message.version + self._rel_url = message.url + self._post = ( + None + ) # type: Optional[MultiDictProxy[Union[str, bytes, FileField]]] + self._read_bytes = None # type: Optional[bytes] + + self._state = state + self._cache = {} # type: Dict[str, Any] + self._task = task + self._client_max_size = client_max_size + self._loop = loop + + transport = self._protocol.transport + assert transport is not None + self._transport_sslcontext = transport.get_extra_info("sslcontext") + self._transport_peername = transport.get_extra_info("peername") + + if scheme is not None: + self._cache["scheme"] = scheme + if host is not None: + self._cache["host"] = host + if remote is not None: + self._cache["remote"] = remote + + def clone( + self, + *, + method: str = sentinel, + rel_url: StrOrURL = sentinel, + headers: LooseHeaders = sentinel, + scheme: str = sentinel, + host: str = sentinel, + remote: str = sentinel, + ) -> "BaseRequest": + """Clone itself with replacement some attributes. + + Creates and returns a new instance of Request object. If no parameters + are given, an exact copy is returned. If a parameter is not passed, it + will reuse the one from the current request object. + + """ + + if self._read_bytes: + raise RuntimeError("Cannot clone request " "after reading its content") + + dct = {} # type: Dict[str, Any] + if method is not sentinel: + dct["method"] = method + if rel_url is not sentinel: + new_url = URL(rel_url) + dct["url"] = new_url + dct["path"] = str(new_url) + if headers is not sentinel: + # a copy semantic + dct["headers"] = CIMultiDictProxy(CIMultiDict(headers)) + dct["raw_headers"] = tuple( + (k.encode("utf-8"), v.encode("utf-8")) for k, v in headers.items() + ) + + message = self._message._replace(**dct) + + kwargs = {} + if scheme is not sentinel: + kwargs["scheme"] = scheme + if host is not sentinel: + kwargs["host"] = host + if remote is not sentinel: + kwargs["remote"] = remote + + return self.__class__( + message, + self._payload, + self._protocol, + self._payload_writer, + self._task, + self._loop, + client_max_size=self._client_max_size, + state=self._state.copy(), + **kwargs, + ) + + @property + def task(self) -> "asyncio.Task[None]": + return self._task + + @property + def protocol(self) -> "RequestHandler": + return self._protocol + + @property + def transport(self) -> Optional[asyncio.Transport]: + if self._protocol is None: + return None + return self._protocol.transport + + @property + def writer(self) -> AbstractStreamWriter: + return self._payload_writer + + @reify + def message(self) -> RawRequestMessage: + warnings.warn("Request.message is deprecated", DeprecationWarning, stacklevel=3) + return self._message + + @reify + def rel_url(self) -> URL: + return self._rel_url + + @reify + def loop(self) -> asyncio.AbstractEventLoop: + warnings.warn( + "request.loop property is deprecated", DeprecationWarning, stacklevel=2 + ) + return self._loop + + # MutableMapping API + + def __getitem__(self, key: str) -> Any: + return self._state[key] + + def __setitem__(self, key: str, value: Any) -> None: + self._state[key] = value + + def __delitem__(self, key: str) -> None: + del self._state[key] + + def __len__(self) -> int: + return len(self._state) + + def __iter__(self) -> Iterator[str]: + return iter(self._state) + + ######## + + @reify + def secure(self) -> bool: + """A bool indicating if the request is handled with SSL.""" + return self.scheme == "https" + + @reify + def forwarded(self) -> Tuple[Mapping[str, str], ...]: + """A tuple containing all parsed Forwarded header(s). + + Makes an effort to parse Forwarded headers as specified by RFC 7239: + + - It adds one (immutable) dictionary per Forwarded 'field-value', ie + per proxy. The element corresponds to the data in the Forwarded + field-value added by the first proxy encountered by the client. Each + subsequent item corresponds to those added by later proxies. + - It checks that every value has valid syntax in general as specified + in section 4: either a 'token' or a 'quoted-string'. + - It un-escapes found escape sequences. + - It does NOT validate 'by' and 'for' contents as specified in section + 6. + - It does NOT validate 'host' contents (Host ABNF). + - It does NOT validate 'proto' contents for valid URI scheme names. + + Returns a tuple containing one or more immutable dicts + """ + elems = [] + for field_value in self._message.headers.getall(hdrs.FORWARDED, ()): + length = len(field_value) + pos = 0 + need_separator = False + elem = {} # type: Dict[str, str] + elems.append(types.MappingProxyType(elem)) + while 0 <= pos < length: + match = _FORWARDED_PAIR_RE.match(field_value, pos) + if match is not None: # got a valid forwarded-pair + if need_separator: + # bad syntax here, skip to next comma + pos = field_value.find(",", pos) + else: + name, value, port = match.groups() + if value[0] == '"': + # quoted string: remove quotes and unescape + value = _QUOTED_PAIR_REPLACE_RE.sub(r"\1", value[1:-1]) + if port: + value += port + elem[name.lower()] = value + pos += len(match.group(0)) + need_separator = True + elif field_value[pos] == ",": # next forwarded-element + need_separator = False + elem = {} + elems.append(types.MappingProxyType(elem)) + pos += 1 + elif field_value[pos] == ";": # next forwarded-pair + need_separator = False + pos += 1 + elif field_value[pos] in " \t": + # Allow whitespace even between forwarded-pairs, though + # RFC 7239 doesn't. This simplifies code and is in line + # with Postel's law. + pos += 1 + else: + # bad syntax here, skip to next comma + pos = field_value.find(",", pos) + return tuple(elems) + + @reify + def scheme(self) -> str: + """A string representing the scheme of the request. + + Hostname is resolved in this order: + + - overridden value by .clone(scheme=new_scheme) call. + - type of connection to peer: HTTPS if socket is SSL, HTTP otherwise. + + 'http' or 'https'. + """ + if self._transport_sslcontext: + return "https" + else: + return "http" + + @reify + def method(self) -> str: + """Read only property for getting HTTP method. + + The value is upper-cased str like 'GET', 'POST', 'PUT' etc. + """ + return self._method + + @reify + def version(self) -> HttpVersion: + """Read only property for getting HTTP version of request. + + Returns aiohttp.protocol.HttpVersion instance. + """ + return self._version + + @reify + def host(self) -> str: + """Hostname of the request. + + Hostname is resolved in this order: + + - overridden value by .clone(host=new_host) call. + - HOST HTTP header + - socket.getfqdn() value + """ + host = self._message.headers.get(hdrs.HOST) + if host is not None: + return host + else: + return socket.getfqdn() + + @reify + def remote(self) -> Optional[str]: + """Remote IP of client initiated HTTP request. + + The IP is resolved in this order: + + - overridden value by .clone(remote=new_remote) call. + - peername of opened socket + """ + if isinstance(self._transport_peername, (list, tuple)): + return self._transport_peername[0] + else: + return self._transport_peername + + @reify + def url(self) -> URL: + url = URL.build(scheme=self.scheme, host=self.host) + return url.join(self._rel_url) + + @reify + def path(self) -> str: + """The URL including *PATH INFO* without the host or scheme. + + E.g., ``/app/blog`` + """ + return self._rel_url.path + + @reify + def path_qs(self) -> str: + """The URL including PATH_INFO and the query string. + + E.g, /app/blog?id=10 + """ + return str(self._rel_url) + + @reify + def raw_path(self) -> str: + """The URL including raw *PATH INFO* without the host or scheme. + Warning, the path is unquoted and may contains non valid URL characters + + E.g., ``/my%2Fpath%7Cwith%21some%25strange%24characters`` + """ + return self._message.path + + @reify + def query(self) -> "MultiDictProxy[str]": + """A multidict with all the variables in the query string.""" + return self._rel_url.query + + @reify + def query_string(self) -> str: + """The query string in the URL. + + E.g., id=10 + """ + return self._rel_url.query_string + + @reify + def headers(self) -> "CIMultiDictProxy[str]": + """A case-insensitive multidict proxy with all headers.""" + return self._headers + + @reify + def raw_headers(self) -> RawHeaders: + """A sequence of pairs for all headers.""" + return self._message.raw_headers + + @staticmethod + def _http_date(_date_str: Optional[str]) -> Optional[datetime.datetime]: + """Process a date string, return a datetime object""" + if _date_str is not None: + timetuple = parsedate(_date_str) + if timetuple is not None: + return datetime.datetime(*timetuple[:6], tzinfo=datetime.timezone.utc) + return None + + @reify + def if_modified_since(self) -> Optional[datetime.datetime]: + """The value of If-Modified-Since HTTP header, or None. + + This header is represented as a `datetime` object. + """ + return self._http_date(self.headers.get(hdrs.IF_MODIFIED_SINCE)) + + @reify + def if_unmodified_since(self) -> Optional[datetime.datetime]: + """The value of If-Unmodified-Since HTTP header, or None. + + This header is represented as a `datetime` object. + """ + return self._http_date(self.headers.get(hdrs.IF_UNMODIFIED_SINCE)) + + @reify + def if_range(self) -> Optional[datetime.datetime]: + """The value of If-Range HTTP header, or None. + + This header is represented as a `datetime` object. + """ + return self._http_date(self.headers.get(hdrs.IF_RANGE)) + + @reify + def keep_alive(self) -> bool: + """Is keepalive enabled by client?""" + return not self._message.should_close + + @reify + def cookies(self) -> Mapping[str, str]: + """Return request cookies. + + A read-only dictionary-like object. + """ + raw = self.headers.get(hdrs.COOKIE, "") + parsed = SimpleCookie(raw) # type: SimpleCookie[str] + return MappingProxyType({key: val.value for key, val in parsed.items()}) + + @reify + def http_range(self) -> slice: + """The content of Range HTTP header. + + Return a slice instance. + + """ + rng = self._headers.get(hdrs.RANGE) + start, end = None, None + if rng is not None: + try: + pattern = r"^bytes=(\d*)-(\d*)$" + start, end = re.findall(pattern, rng)[0] + except IndexError: # pattern was not found in header + raise ValueError("range not in acceptable format") + + end = int(end) if end else None + start = int(start) if start else None + + if start is None and end is not None: + # end with no start is to return tail of content + start = -end + end = None + + if start is not None and end is not None: + # end is inclusive in range header, exclusive for slice + end += 1 + + if start >= end: + raise ValueError("start cannot be after end") + + if start is end is None: # No valid range supplied + raise ValueError("No start or end of range specified") + + return slice(start, end, 1) + + @reify + def content(self) -> StreamReader: + """Return raw payload stream.""" + return self._payload + + @property + def has_body(self) -> bool: + """Return True if request's HTTP BODY can be read, False otherwise.""" + warnings.warn( + "Deprecated, use .can_read_body #2005", DeprecationWarning, stacklevel=2 + ) + return not self._payload.at_eof() + + @property + def can_read_body(self) -> bool: + """Return True if request's HTTP BODY can be read, False otherwise.""" + return not self._payload.at_eof() + + @reify + def body_exists(self) -> bool: + """Return True if request has HTTP BODY, False otherwise.""" + return type(self._payload) is not EmptyStreamReader + + async def release(self) -> None: + """Release request. + + Eat unread part of HTTP BODY if present. + """ + while not self._payload.at_eof(): + await self._payload.readany() + + async def read(self) -> bytes: + """Read request body if present. + + Returns bytes object with full request content. + """ + if self._read_bytes is None: + body = bytearray() + while True: + chunk = await self._payload.readany() + body.extend(chunk) + if self._client_max_size: + body_size = len(body) + if body_size >= self._client_max_size: + raise HTTPRequestEntityTooLarge( + max_size=self._client_max_size, actual_size=body_size + ) + if not chunk: + break + self._read_bytes = bytes(body) + return self._read_bytes + + async def text(self) -> str: + """Return BODY as text using encoding from .charset.""" + bytes_body = await self.read() + encoding = self.charset or "utf-8" + return bytes_body.decode(encoding) + + async def json(self, *, loads: JSONDecoder = DEFAULT_JSON_DECODER) -> Any: + """Return BODY as JSON.""" + body = await self.text() + return loads(body) + + async def multipart(self) -> MultipartReader: + """Return async iterator to process BODY as multipart.""" + return MultipartReader(self._headers, self._payload) + + async def post(self) -> "MultiDictProxy[Union[str, bytes, FileField]]": + """Return POST parameters.""" + if self._post is not None: + return self._post + if self._method not in self.POST_METHODS: + self._post = MultiDictProxy(MultiDict()) + return self._post + + content_type = self.content_type + if content_type not in ( + "", + "application/x-www-form-urlencoded", + "multipart/form-data", + ): + self._post = MultiDictProxy(MultiDict()) + return self._post + + out = MultiDict() # type: MultiDict[Union[str, bytes, FileField]] + + if content_type == "multipart/form-data": + multipart = await self.multipart() + max_size = self._client_max_size + + field = await multipart.next() + while field is not None: + size = 0 + field_ct = field.headers.get(hdrs.CONTENT_TYPE) + + if isinstance(field, BodyPartReader): + assert field.name is not None + + # Note that according to RFC 7578, the Content-Type header + # is optional, even for files, so we can't assume it's + # present. + # https://tools.ietf.org/html/rfc7578#section-4.4 + if field.filename: + # store file in temp file + tmp = tempfile.TemporaryFile() + chunk = await field.read_chunk(size=2 ** 16) + while chunk: + chunk = field.decode(chunk) + tmp.write(chunk) + size += len(chunk) + if 0 < max_size < size: + raise HTTPRequestEntityTooLarge( + max_size=max_size, actual_size=size + ) + chunk = await field.read_chunk(size=2 ** 16) + tmp.seek(0) + + if field_ct is None: + field_ct = "application/octet-stream" + + ff = FileField( + field.name, + field.filename, + cast(io.BufferedReader, tmp), + field_ct, + field.headers, + ) + out.add(field.name, ff) + else: + # deal with ordinary data + value = await field.read(decode=True) + if field_ct is None or field_ct.startswith("text/"): + charset = field.get_charset(default="utf-8") + out.add(field.name, value.decode(charset)) + else: + out.add(field.name, value) + size += len(value) + if 0 < max_size < size: + raise HTTPRequestEntityTooLarge( + max_size=max_size, actual_size=size + ) + else: + raise ValueError( + "To decode nested multipart you need " "to use custom reader", + ) + + field = await multipart.next() + else: + data = await self.read() + if data: + charset = self.charset or "utf-8" + out.extend( + parse_qsl( + data.rstrip().decode(charset), + keep_blank_values=True, + encoding=charset, + ) + ) + + self._post = MultiDictProxy(out) + return self._post + + def get_extra_info(self, name: str, default: Any = None) -> Any: + """Extra info from protocol transport""" + protocol = self._protocol + if protocol is None: + return default + + transport = protocol.transport + if transport is None: + return default + + return transport.get_extra_info(name, default) + + def __repr__(self) -> str: + ascii_encodable_path = self.path.encode("ascii", "backslashreplace").decode( + "ascii" + ) + return "<{} {} {} >".format( + self.__class__.__name__, self._method, ascii_encodable_path + ) + + def __eq__(self, other: object) -> bool: + return id(self) == id(other) + + def __bool__(self) -> bool: + return True + + async def _prepare_hook(self, response: StreamResponse) -> None: + return + + def _cancel(self, exc: BaseException) -> None: + self._payload.set_exception(exc) + + +class Request(BaseRequest): + + ATTRS = BaseRequest.ATTRS | frozenset(["_match_info"]) + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + # matchdict, route_name, handler + # or information about traversal lookup + + # initialized after route resolving + self._match_info = None # type: Optional[UrlMappingMatchInfo] + + if DEBUG: + + def __setattr__(self, name: str, val: Any) -> None: + if name not in self.ATTRS: + warnings.warn( + "Setting custom {}.{} attribute " + "is discouraged".format(self.__class__.__name__, name), + DeprecationWarning, + stacklevel=2, + ) + super().__setattr__(name, val) + + def clone( + self, + *, + method: str = sentinel, + rel_url: StrOrURL = sentinel, + headers: LooseHeaders = sentinel, + scheme: str = sentinel, + host: str = sentinel, + remote: str = sentinel, + ) -> "Request": + ret = super().clone( + method=method, + rel_url=rel_url, + headers=headers, + scheme=scheme, + host=host, + remote=remote, + ) + new_ret = cast(Request, ret) + new_ret._match_info = self._match_info + return new_ret + + @reify + def match_info(self) -> "UrlMappingMatchInfo": + """Result of route resolving.""" + match_info = self._match_info + assert match_info is not None + return match_info + + @property + def app(self) -> "Application": + """Application instance.""" + match_info = self._match_info + assert match_info is not None + return match_info.current_app + + @property + def config_dict(self) -> ChainMapProxy: + match_info = self._match_info + assert match_info is not None + lst = match_info.apps + app = self.app + idx = lst.index(app) + sublist = list(reversed(lst[: idx + 1])) + return ChainMapProxy(sublist) + + async def _prepare_hook(self, response: StreamResponse) -> None: + match_info = self._match_info + if match_info is None: + return + for app in match_info._apps: + await app.on_response_prepare.send(self, response) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_response.py b/dist/ba_data/python-site-packages/aiohttp/web_response.py new file mode 100644 index 0000000..f34b00e --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_response.py @@ -0,0 +1,781 @@ +import asyncio +import collections.abc +import datetime +import enum +import json +import math +import time +import warnings +import zlib +from concurrent.futures import Executor +from email.utils import parsedate +from http.cookies import Morsel, SimpleCookie +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Iterator, + Mapping, + MutableMapping, + Optional, + Tuple, + Union, + cast, +) + +from multidict import CIMultiDict, istr + +from . import hdrs, payload +from .abc import AbstractStreamWriter +from .helpers import PY_38, HeadersMixin, rfc822_formatted_time, sentinel +from .http import RESPONSES, SERVER_SOFTWARE, HttpVersion10, HttpVersion11 +from .payload import Payload +from .typedefs import JSONEncoder, LooseHeaders + +__all__ = ("ContentCoding", "StreamResponse", "Response", "json_response") + + +if TYPE_CHECKING: # pragma: no cover + from .web_request import BaseRequest + + BaseClass = MutableMapping[str, Any] +else: + BaseClass = collections.abc.MutableMapping + + +if not PY_38: + # allow samesite to be used in python < 3.8 + # already permitted in python 3.8, see https://bugs.python.org/issue29613 + Morsel._reserved["samesite"] = "SameSite" # type: ignore + + +class ContentCoding(enum.Enum): + # The content codings that we have support for. + # + # Additional registered codings are listed at: + # https://www.iana.org/assignments/http-parameters/http-parameters.xhtml#content-coding + deflate = "deflate" + gzip = "gzip" + identity = "identity" + + +############################################################ +# HTTP Response classes +############################################################ + + +class StreamResponse(BaseClass, HeadersMixin): + + _length_check = True + + def __init__( + self, + *, + status: int = 200, + reason: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + ) -> None: + self._body = None + self._keep_alive = None # type: Optional[bool] + self._chunked = False + self._compression = False + self._compression_force = None # type: Optional[ContentCoding] + self._cookies = SimpleCookie() # type: SimpleCookie[str] + + self._req = None # type: Optional[BaseRequest] + self._payload_writer = None # type: Optional[AbstractStreamWriter] + self._eof_sent = False + self._body_length = 0 + self._state = {} # type: Dict[str, Any] + + if headers is not None: + self._headers = CIMultiDict(headers) # type: CIMultiDict[str] + else: + self._headers = CIMultiDict() + + self.set_status(status, reason) + + @property + def prepared(self) -> bool: + return self._payload_writer is not None + + @property + def task(self) -> "asyncio.Task[None]": + return getattr(self._req, "task", None) + + @property + def status(self) -> int: + return self._status + + @property + def chunked(self) -> bool: + return self._chunked + + @property + def compression(self) -> bool: + return self._compression + + @property + def reason(self) -> str: + return self._reason + + def set_status( + self, + status: int, + reason: Optional[str] = None, + _RESPONSES: Mapping[int, Tuple[str, str]] = RESPONSES, + ) -> None: + assert not self.prepared, ( + "Cannot change the response status code after " "the headers have been sent" + ) + self._status = int(status) + if reason is None: + try: + reason = _RESPONSES[self._status][0] + except Exception: + reason = "" + self._reason = reason + + @property + def keep_alive(self) -> Optional[bool]: + return self._keep_alive + + def force_close(self) -> None: + self._keep_alive = False + + @property + def body_length(self) -> int: + return self._body_length + + @property + def output_length(self) -> int: + warnings.warn("output_length is deprecated", DeprecationWarning) + assert self._payload_writer + return self._payload_writer.buffer_size + + def enable_chunked_encoding(self, chunk_size: Optional[int] = None) -> None: + """Enables automatic chunked transfer encoding.""" + self._chunked = True + + if hdrs.CONTENT_LENGTH in self._headers: + raise RuntimeError( + "You can't enable chunked encoding when " "a content length is set" + ) + if chunk_size is not None: + warnings.warn("Chunk size is deprecated #1615", DeprecationWarning) + + def enable_compression( + self, force: Optional[Union[bool, ContentCoding]] = None + ) -> None: + """Enables response compression encoding.""" + # Backwards compatibility for when force was a bool <0.17. + if type(force) == bool: + force = ContentCoding.deflate if force else ContentCoding.identity + warnings.warn( + "Using boolean for force is deprecated #3318", DeprecationWarning + ) + elif force is not None: + assert isinstance(force, ContentCoding), ( + "force should one of " "None, bool or " "ContentEncoding" + ) + + self._compression = True + self._compression_force = force + + @property + def headers(self) -> "CIMultiDict[str]": + return self._headers + + @property + def cookies(self) -> "SimpleCookie[str]": + return self._cookies + + def set_cookie( + self, + name: str, + value: str, + *, + expires: Optional[str] = None, + domain: Optional[str] = None, + max_age: Optional[Union[int, str]] = None, + path: str = "/", + secure: Optional[bool] = None, + httponly: Optional[bool] = None, + version: Optional[str] = None, + samesite: Optional[str] = None, + ) -> None: + """Set or update response cookie. + + Sets new cookie or updates existent with new value. + Also updates only those params which are not None. + """ + + old = self._cookies.get(name) + if old is not None and old.coded_value == "": + # deleted cookie + self._cookies.pop(name, None) + + self._cookies[name] = value + c = self._cookies[name] + + if expires is not None: + c["expires"] = expires + elif c.get("expires") == "Thu, 01 Jan 1970 00:00:00 GMT": + del c["expires"] + + if domain is not None: + c["domain"] = domain + + if max_age is not None: + c["max-age"] = str(max_age) + elif "max-age" in c: + del c["max-age"] + + c["path"] = path + + if secure is not None: + c["secure"] = secure + if httponly is not None: + c["httponly"] = httponly + if version is not None: + c["version"] = version + if samesite is not None: + c["samesite"] = samesite + + def del_cookie( + self, name: str, *, domain: Optional[str] = None, path: str = "/" + ) -> None: + """Delete cookie. + + Creates new empty expired cookie. + """ + # TODO: do we need domain/path here? + self._cookies.pop(name, None) + self.set_cookie( + name, + "", + max_age=0, + expires="Thu, 01 Jan 1970 00:00:00 GMT", + domain=domain, + path=path, + ) + + @property + def content_length(self) -> Optional[int]: + # Just a placeholder for adding setter + return super().content_length + + @content_length.setter + def content_length(self, value: Optional[int]) -> None: + if value is not None: + value = int(value) + if self._chunked: + raise RuntimeError( + "You can't set content length when " "chunked encoding is enable" + ) + self._headers[hdrs.CONTENT_LENGTH] = str(value) + else: + self._headers.pop(hdrs.CONTENT_LENGTH, None) + + @property + def content_type(self) -> str: + # Just a placeholder for adding setter + return super().content_type + + @content_type.setter + def content_type(self, value: str) -> None: + self.content_type # read header values if needed + self._content_type = str(value) + self._generate_content_type_header() + + @property + def charset(self) -> Optional[str]: + # Just a placeholder for adding setter + return super().charset + + @charset.setter + def charset(self, value: Optional[str]) -> None: + ctype = self.content_type # read header values if needed + if ctype == "application/octet-stream": + raise RuntimeError( + "Setting charset for application/octet-stream " + "doesn't make sense, setup content_type first" + ) + assert self._content_dict is not None + if value is None: + self._content_dict.pop("charset", None) + else: + self._content_dict["charset"] = str(value).lower() + self._generate_content_type_header() + + @property + def last_modified(self) -> Optional[datetime.datetime]: + """The value of Last-Modified HTTP header, or None. + + This header is represented as a `datetime` object. + """ + httpdate = self._headers.get(hdrs.LAST_MODIFIED) + if httpdate is not None: + timetuple = parsedate(httpdate) + if timetuple is not None: + return datetime.datetime(*timetuple[:6], tzinfo=datetime.timezone.utc) + return None + + @last_modified.setter + def last_modified( + self, value: Optional[Union[int, float, datetime.datetime, str]] + ) -> None: + if value is None: + self._headers.pop(hdrs.LAST_MODIFIED, None) + elif isinstance(value, (int, float)): + self._headers[hdrs.LAST_MODIFIED] = time.strftime( + "%a, %d %b %Y %H:%M:%S GMT", time.gmtime(math.ceil(value)) + ) + elif isinstance(value, datetime.datetime): + self._headers[hdrs.LAST_MODIFIED] = time.strftime( + "%a, %d %b %Y %H:%M:%S GMT", value.utctimetuple() + ) + elif isinstance(value, str): + self._headers[hdrs.LAST_MODIFIED] = value + + def _generate_content_type_header( + self, CONTENT_TYPE: istr = hdrs.CONTENT_TYPE + ) -> None: + assert self._content_dict is not None + assert self._content_type is not None + params = "; ".join(f"{k}={v}" for k, v in self._content_dict.items()) + if params: + ctype = self._content_type + "; " + params + else: + ctype = self._content_type + self._headers[CONTENT_TYPE] = ctype + + async def _do_start_compression(self, coding: ContentCoding) -> None: + if coding != ContentCoding.identity: + assert self._payload_writer is not None + self._headers[hdrs.CONTENT_ENCODING] = coding.value + self._payload_writer.enable_compression(coding.value) + # Compressed payload may have different content length, + # remove the header + self._headers.popall(hdrs.CONTENT_LENGTH, None) + + async def _start_compression(self, request: "BaseRequest") -> None: + if self._compression_force: + await self._do_start_compression(self._compression_force) + else: + accept_encoding = request.headers.get(hdrs.ACCEPT_ENCODING, "").lower() + for coding in ContentCoding: + if coding.value in accept_encoding: + await self._do_start_compression(coding) + return + + async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter]: + if self._eof_sent: + return None + if self._payload_writer is not None: + return self._payload_writer + + return await self._start(request) + + async def _start(self, request: "BaseRequest") -> AbstractStreamWriter: + self._req = request + writer = self._payload_writer = request._payload_writer + + await self._prepare_headers() + await request._prepare_hook(self) + await self._write_headers() + + return writer + + async def _prepare_headers(self) -> None: + request = self._req + assert request is not None + writer = self._payload_writer + assert writer is not None + keep_alive = self._keep_alive + if keep_alive is None: + keep_alive = request.keep_alive + self._keep_alive = keep_alive + + version = request.version + + headers = self._headers + for cookie in self._cookies.values(): + value = cookie.output(header="")[1:] + headers.add(hdrs.SET_COOKIE, value) + + if self._compression: + await self._start_compression(request) + + if self._chunked: + if version != HttpVersion11: + raise RuntimeError( + "Using chunked encoding is forbidden " + "for HTTP/{0.major}.{0.minor}".format(request.version) + ) + writer.enable_chunking() + headers[hdrs.TRANSFER_ENCODING] = "chunked" + if hdrs.CONTENT_LENGTH in headers: + del headers[hdrs.CONTENT_LENGTH] + elif self._length_check: + writer.length = self.content_length + if writer.length is None: + if version >= HttpVersion11: + writer.enable_chunking() + headers[hdrs.TRANSFER_ENCODING] = "chunked" + if hdrs.CONTENT_LENGTH in headers: + del headers[hdrs.CONTENT_LENGTH] + else: + keep_alive = False + # HTTP 1.1: https://tools.ietf.org/html/rfc7230#section-3.3.2 + # HTTP 1.0: https://tools.ietf.org/html/rfc1945#section-10.4 + elif version >= HttpVersion11 and self.status in (100, 101, 102, 103, 204): + del headers[hdrs.CONTENT_LENGTH] + + headers.setdefault(hdrs.CONTENT_TYPE, "application/octet-stream") + headers.setdefault(hdrs.DATE, rfc822_formatted_time()) + headers.setdefault(hdrs.SERVER, SERVER_SOFTWARE) + + # connection header + if hdrs.CONNECTION not in headers: + if keep_alive: + if version == HttpVersion10: + headers[hdrs.CONNECTION] = "keep-alive" + else: + if version == HttpVersion11: + headers[hdrs.CONNECTION] = "close" + + async def _write_headers(self) -> None: + request = self._req + assert request is not None + writer = self._payload_writer + assert writer is not None + # status line + version = request.version + status_line = "HTTP/{}.{} {} {}".format( + version[0], version[1], self._status, self._reason + ) + await writer.write_headers(status_line, self._headers) + + async def write(self, data: bytes) -> None: + assert isinstance( + data, (bytes, bytearray, memoryview) + ), "data argument must be byte-ish (%r)" % type(data) + + if self._eof_sent: + raise RuntimeError("Cannot call write() after write_eof()") + if self._payload_writer is None: + raise RuntimeError("Cannot call write() before prepare()") + + await self._payload_writer.write(data) + + async def drain(self) -> None: + assert not self._eof_sent, "EOF has already been sent" + assert self._payload_writer is not None, "Response has not been started" + warnings.warn( + "drain method is deprecated, use await resp.write()", + DeprecationWarning, + stacklevel=2, + ) + await self._payload_writer.drain() + + async def write_eof(self, data: bytes = b"") -> None: + assert isinstance( + data, (bytes, bytearray, memoryview) + ), "data argument must be byte-ish (%r)" % type(data) + + if self._eof_sent: + return + + assert self._payload_writer is not None, "Response has not been started" + + await self._payload_writer.write_eof(data) + self._eof_sent = True + self._req = None + self._body_length = self._payload_writer.output_size + self._payload_writer = None + + def __repr__(self) -> str: + if self._eof_sent: + info = "eof" + elif self.prepared: + assert self._req is not None + info = f"{self._req.method} {self._req.path} " + else: + info = "not prepared" + return f"<{self.__class__.__name__} {self.reason} {info}>" + + def __getitem__(self, key: str) -> Any: + return self._state[key] + + def __setitem__(self, key: str, value: Any) -> None: + self._state[key] = value + + def __delitem__(self, key: str) -> None: + del self._state[key] + + def __len__(self) -> int: + return len(self._state) + + def __iter__(self) -> Iterator[str]: + return iter(self._state) + + def __hash__(self) -> int: + return hash(id(self)) + + def __eq__(self, other: object) -> bool: + return self is other + + +class Response(StreamResponse): + def __init__( + self, + *, + body: Any = None, + status: int = 200, + reason: Optional[str] = None, + text: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + content_type: Optional[str] = None, + charset: Optional[str] = None, + zlib_executor_size: Optional[int] = None, + zlib_executor: Optional[Executor] = None, + ) -> None: + if body is not None and text is not None: + raise ValueError("body and text are not allowed together") + + if headers is None: + real_headers = CIMultiDict() # type: CIMultiDict[str] + elif not isinstance(headers, CIMultiDict): + real_headers = CIMultiDict(headers) + else: + real_headers = headers # = cast('CIMultiDict[str]', headers) + + if content_type is not None and "charset" in content_type: + raise ValueError("charset must not be in content_type " "argument") + + if text is not None: + if hdrs.CONTENT_TYPE in real_headers: + if content_type or charset: + raise ValueError( + "passing both Content-Type header and " + "content_type or charset params " + "is forbidden" + ) + else: + # fast path for filling headers + if not isinstance(text, str): + raise TypeError("text argument must be str (%r)" % type(text)) + if content_type is None: + content_type = "text/plain" + if charset is None: + charset = "utf-8" + real_headers[hdrs.CONTENT_TYPE] = content_type + "; charset=" + charset + body = text.encode(charset) + text = None + else: + if hdrs.CONTENT_TYPE in real_headers: + if content_type is not None or charset is not None: + raise ValueError( + "passing both Content-Type header and " + "content_type or charset params " + "is forbidden" + ) + else: + if content_type is not None: + if charset is not None: + content_type += "; charset=" + charset + real_headers[hdrs.CONTENT_TYPE] = content_type + + super().__init__(status=status, reason=reason, headers=real_headers) + + if text is not None: + self.text = text + else: + self.body = body + + self._compressed_body = None # type: Optional[bytes] + self._zlib_executor_size = zlib_executor_size + self._zlib_executor = zlib_executor + + @property + def body(self) -> Optional[Union[bytes, Payload]]: + return self._body + + @body.setter + def body( + self, + body: bytes, + CONTENT_TYPE: istr = hdrs.CONTENT_TYPE, + CONTENT_LENGTH: istr = hdrs.CONTENT_LENGTH, + ) -> None: + if body is None: + self._body = None # type: Optional[bytes] + self._body_payload = False # type: bool + elif isinstance(body, (bytes, bytearray)): + self._body = body + self._body_payload = False + else: + try: + self._body = body = payload.PAYLOAD_REGISTRY.get(body) + except payload.LookupError: + raise ValueError("Unsupported body type %r" % type(body)) + + self._body_payload = True + + headers = self._headers + + # set content-length header if needed + if not self._chunked and CONTENT_LENGTH not in headers: + size = body.size + if size is not None: + headers[CONTENT_LENGTH] = str(size) + + # set content-type + if CONTENT_TYPE not in headers: + headers[CONTENT_TYPE] = body.content_type + + # copy payload headers + if body.headers: + for (key, value) in body.headers.items(): + if key not in headers: + headers[key] = value + + self._compressed_body = None + + @property + def text(self) -> Optional[str]: + if self._body is None: + return None + return self._body.decode(self.charset or "utf-8") + + @text.setter + def text(self, text: str) -> None: + assert text is None or isinstance( + text, str + ), "text argument must be str (%r)" % type(text) + + if self.content_type == "application/octet-stream": + self.content_type = "text/plain" + if self.charset is None: + self.charset = "utf-8" + + self._body = text.encode(self.charset) + self._body_payload = False + self._compressed_body = None + + @property + def content_length(self) -> Optional[int]: + if self._chunked: + return None + + if hdrs.CONTENT_LENGTH in self._headers: + return super().content_length + + if self._compressed_body is not None: + # Return length of the compressed body + return len(self._compressed_body) + elif self._body_payload: + # A payload without content length, or a compressed payload + return None + elif self._body is not None: + return len(self._body) + else: + return 0 + + @content_length.setter + def content_length(self, value: Optional[int]) -> None: + raise RuntimeError("Content length is set automatically") + + async def write_eof(self, data: bytes = b"") -> None: + if self._eof_sent: + return + if self._compressed_body is None: + body = self._body # type: Optional[Union[bytes, Payload]] + else: + body = self._compressed_body + assert not data, f"data arg is not supported, got {data!r}" + assert self._req is not None + assert self._payload_writer is not None + if body is not None: + if self._req._method == hdrs.METH_HEAD or self._status in [204, 304]: + await super().write_eof() + elif self._body_payload: + payload = cast(Payload, body) + await payload.write(self._payload_writer) + await super().write_eof() + else: + await super().write_eof(cast(bytes, body)) + else: + await super().write_eof() + + async def _start(self, request: "BaseRequest") -> AbstractStreamWriter: + if not self._chunked and hdrs.CONTENT_LENGTH not in self._headers: + if not self._body_payload: + if self._body is not None: + self._headers[hdrs.CONTENT_LENGTH] = str(len(self._body)) + else: + self._headers[hdrs.CONTENT_LENGTH] = "0" + + return await super()._start(request) + + def _compress_body(self, zlib_mode: int) -> None: + assert zlib_mode > 0 + compressobj = zlib.compressobj(wbits=zlib_mode) + body_in = self._body + assert body_in is not None + self._compressed_body = compressobj.compress(body_in) + compressobj.flush() + + async def _do_start_compression(self, coding: ContentCoding) -> None: + if self._body_payload or self._chunked: + return await super()._do_start_compression(coding) + + if coding != ContentCoding.identity: + # Instead of using _payload_writer.enable_compression, + # compress the whole body + zlib_mode = ( + 16 + zlib.MAX_WBITS if coding == ContentCoding.gzip else zlib.MAX_WBITS + ) + body_in = self._body + assert body_in is not None + if ( + self._zlib_executor_size is not None + and len(body_in) > self._zlib_executor_size + ): + await asyncio.get_event_loop().run_in_executor( + self._zlib_executor, self._compress_body, zlib_mode + ) + else: + self._compress_body(zlib_mode) + + body_out = self._compressed_body + assert body_out is not None + + self._headers[hdrs.CONTENT_ENCODING] = coding.value + self._headers[hdrs.CONTENT_LENGTH] = str(len(body_out)) + + +def json_response( + data: Any = sentinel, + *, + text: Optional[str] = None, + body: Optional[bytes] = None, + status: int = 200, + reason: Optional[str] = None, + headers: Optional[LooseHeaders] = None, + content_type: str = "application/json", + dumps: JSONEncoder = json.dumps, +) -> Response: + if data is not sentinel: + if text or body: + raise ValueError("only one of data, text, or body should be specified") + else: + text = dumps(data) + return Response( + text=text, + body=body, + status=status, + reason=reason, + headers=headers, + content_type=content_type, + ) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_routedef.py b/dist/ba_data/python-site-packages/aiohttp/web_routedef.py new file mode 100644 index 0000000..1885251 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_routedef.py @@ -0,0 +1,215 @@ +import abc +import os # noqa +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Dict, + Iterator, + List, + Optional, + Sequence, + Type, + Union, + overload, +) + +import attr + +from . import hdrs +from .abc import AbstractView +from .typedefs import PathLike + +if TYPE_CHECKING: # pragma: no cover + from .web_request import Request + from .web_response import StreamResponse + from .web_urldispatcher import AbstractRoute, UrlDispatcher +else: + Request = StreamResponse = UrlDispatcher = AbstractRoute = None + + +__all__ = ( + "AbstractRouteDef", + "RouteDef", + "StaticDef", + "RouteTableDef", + "head", + "options", + "get", + "post", + "patch", + "put", + "delete", + "route", + "view", + "static", +) + + +class AbstractRouteDef(abc.ABC): + @abc.abstractmethod + def register(self, router: UrlDispatcher) -> List[AbstractRoute]: + pass # pragma: no cover + + +_SimpleHandler = Callable[[Request], Awaitable[StreamResponse]] +_HandlerType = Union[Type[AbstractView], _SimpleHandler] + + +@attr.s(auto_attribs=True, frozen=True, repr=False, slots=True) +class RouteDef(AbstractRouteDef): + method: str + path: str + handler: _HandlerType + kwargs: Dict[str, Any] + + def __repr__(self) -> str: + info = [] + for name, value in sorted(self.kwargs.items()): + info.append(f", {name}={value!r}") + return " {handler.__name__!r}" "{info}>".format( + method=self.method, path=self.path, handler=self.handler, info="".join(info) + ) + + def register(self, router: UrlDispatcher) -> List[AbstractRoute]: + if self.method in hdrs.METH_ALL: + reg = getattr(router, "add_" + self.method.lower()) + return [reg(self.path, self.handler, **self.kwargs)] + else: + return [ + router.add_route(self.method, self.path, self.handler, **self.kwargs) + ] + + +@attr.s(auto_attribs=True, frozen=True, repr=False, slots=True) +class StaticDef(AbstractRouteDef): + prefix: str + path: PathLike + kwargs: Dict[str, Any] + + def __repr__(self) -> str: + info = [] + for name, value in sorted(self.kwargs.items()): + info.append(f", {name}={value!r}") + return " {path}" "{info}>".format( + prefix=self.prefix, path=self.path, info="".join(info) + ) + + def register(self, router: UrlDispatcher) -> List[AbstractRoute]: + resource = router.add_static(self.prefix, self.path, **self.kwargs) + routes = resource.get_info().get("routes", {}) + return list(routes.values()) + + +def route(method: str, path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return RouteDef(method, path, handler, kwargs) + + +def head(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_HEAD, path, handler, **kwargs) + + +def options(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_OPTIONS, path, handler, **kwargs) + + +def get( + path: str, + handler: _HandlerType, + *, + name: Optional[str] = None, + allow_head: bool = True, + **kwargs: Any, +) -> RouteDef: + return route( + hdrs.METH_GET, path, handler, name=name, allow_head=allow_head, **kwargs + ) + + +def post(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_POST, path, handler, **kwargs) + + +def put(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_PUT, path, handler, **kwargs) + + +def patch(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_PATCH, path, handler, **kwargs) + + +def delete(path: str, handler: _HandlerType, **kwargs: Any) -> RouteDef: + return route(hdrs.METH_DELETE, path, handler, **kwargs) + + +def view(path: str, handler: Type[AbstractView], **kwargs: Any) -> RouteDef: + return route(hdrs.METH_ANY, path, handler, **kwargs) + + +def static(prefix: str, path: PathLike, **kwargs: Any) -> StaticDef: + return StaticDef(prefix, path, kwargs) + + +_Deco = Callable[[_HandlerType], _HandlerType] + + +class RouteTableDef(Sequence[AbstractRouteDef]): + """Route definition table""" + + def __init__(self) -> None: + self._items = [] # type: List[AbstractRouteDef] + + def __repr__(self) -> str: + return "".format(len(self._items)) + + @overload + def __getitem__(self, index: int) -> AbstractRouteDef: + ... + + @overload + def __getitem__(self, index: slice) -> List[AbstractRouteDef]: + ... + + def __getitem__(self, index): # type: ignore + return self._items[index] + + def __iter__(self) -> Iterator[AbstractRouteDef]: + return iter(self._items) + + def __len__(self) -> int: + return len(self._items) + + def __contains__(self, item: object) -> bool: + return item in self._items + + def route(self, method: str, path: str, **kwargs: Any) -> _Deco: + def inner(handler: _HandlerType) -> _HandlerType: + self._items.append(RouteDef(method, path, handler, kwargs)) + return handler + + return inner + + def head(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_HEAD, path, **kwargs) + + def get(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_GET, path, **kwargs) + + def post(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_POST, path, **kwargs) + + def put(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_PUT, path, **kwargs) + + def patch(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_PATCH, path, **kwargs) + + def delete(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_DELETE, path, **kwargs) + + def view(self, path: str, **kwargs: Any) -> _Deco: + return self.route(hdrs.METH_ANY, path, **kwargs) + + def static(self, prefix: str, path: PathLike, **kwargs: Any) -> None: + self._items.append(StaticDef(prefix, path, kwargs)) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_runner.py b/dist/ba_data/python-site-packages/aiohttp/web_runner.py new file mode 100644 index 0000000..25ac28a --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_runner.py @@ -0,0 +1,381 @@ +import asyncio +import signal +import socket +from abc import ABC, abstractmethod +from typing import Any, List, Optional, Set + +from yarl import URL + +from .web_app import Application +from .web_server import Server + +try: + from ssl import SSLContext +except ImportError: + SSLContext = object # type: ignore + + +__all__ = ( + "BaseSite", + "TCPSite", + "UnixSite", + "NamedPipeSite", + "SockSite", + "BaseRunner", + "AppRunner", + "ServerRunner", + "GracefulExit", +) + + +class GracefulExit(SystemExit): + code = 1 + + +def _raise_graceful_exit() -> None: + raise GracefulExit() + + +class BaseSite(ABC): + __slots__ = ("_runner", "_shutdown_timeout", "_ssl_context", "_backlog", "_server") + + def __init__( + self, + runner: "BaseRunner", + *, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + backlog: int = 128, + ) -> None: + if runner.server is None: + raise RuntimeError("Call runner.setup() before making a site") + self._runner = runner + self._shutdown_timeout = shutdown_timeout + self._ssl_context = ssl_context + self._backlog = backlog + self._server = None # type: Optional[asyncio.AbstractServer] + + @property + @abstractmethod + def name(self) -> str: + pass # pragma: no cover + + @abstractmethod + async def start(self) -> None: + self._runner._reg_site(self) + + async def stop(self) -> None: + self._runner._check_site(self) + if self._server is None: + self._runner._unreg_site(self) + return # not started yet + self._server.close() + # named pipes do not have wait_closed property + if hasattr(self._server, "wait_closed"): + await self._server.wait_closed() + await self._runner.shutdown() + assert self._runner.server + await self._runner.server.shutdown(self._shutdown_timeout) + self._runner._unreg_site(self) + + +class TCPSite(BaseSite): + __slots__ = ("_host", "_port", "_reuse_address", "_reuse_port") + + def __init__( + self, + runner: "BaseRunner", + host: Optional[str] = None, + port: Optional[int] = None, + *, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + backlog: int = 128, + reuse_address: Optional[bool] = None, + reuse_port: Optional[bool] = None, + ) -> None: + super().__init__( + runner, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + self._host = host + if port is None: + port = 8443 if self._ssl_context else 8080 + self._port = port + self._reuse_address = reuse_address + self._reuse_port = reuse_port + + @property + def name(self) -> str: + scheme = "https" if self._ssl_context else "http" + host = "0.0.0.0" if self._host is None else self._host + return str(URL.build(scheme=scheme, host=host, port=self._port)) + + async def start(self) -> None: + await super().start() + loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None + self._server = await loop.create_server( + server, + self._host, + self._port, + ssl=self._ssl_context, + backlog=self._backlog, + reuse_address=self._reuse_address, + reuse_port=self._reuse_port, + ) + + +class UnixSite(BaseSite): + __slots__ = ("_path",) + + def __init__( + self, + runner: "BaseRunner", + path: str, + *, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + backlog: int = 128, + ) -> None: + super().__init__( + runner, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + self._path = path + + @property + def name(self) -> str: + scheme = "https" if self._ssl_context else "http" + return f"{scheme}://unix:{self._path}:" + + async def start(self) -> None: + await super().start() + loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None + self._server = await loop.create_unix_server( + server, self._path, ssl=self._ssl_context, backlog=self._backlog + ) + + +class NamedPipeSite(BaseSite): + __slots__ = ("_path",) + + def __init__( + self, runner: "BaseRunner", path: str, *, shutdown_timeout: float = 60.0 + ) -> None: + loop = asyncio.get_event_loop() + if not isinstance(loop, asyncio.ProactorEventLoop): # type: ignore + raise RuntimeError( + "Named Pipes only available in proactor" "loop under windows" + ) + super().__init__(runner, shutdown_timeout=shutdown_timeout) + self._path = path + + @property + def name(self) -> str: + return self._path + + async def start(self) -> None: + await super().start() + loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None + _server = await loop.start_serving_pipe(server, self._path) # type: ignore + self._server = _server[0] + + +class SockSite(BaseSite): + __slots__ = ("_sock", "_name") + + def __init__( + self, + runner: "BaseRunner", + sock: socket.socket, + *, + shutdown_timeout: float = 60.0, + ssl_context: Optional[SSLContext] = None, + backlog: int = 128, + ) -> None: + super().__init__( + runner, + shutdown_timeout=shutdown_timeout, + ssl_context=ssl_context, + backlog=backlog, + ) + self._sock = sock + scheme = "https" if self._ssl_context else "http" + if hasattr(socket, "AF_UNIX") and sock.family == socket.AF_UNIX: + name = f"{scheme}://unix:{sock.getsockname()}:" + else: + host, port = sock.getsockname()[:2] + name = str(URL.build(scheme=scheme, host=host, port=port)) + self._name = name + + @property + def name(self) -> str: + return self._name + + async def start(self) -> None: + await super().start() + loop = asyncio.get_event_loop() + server = self._runner.server + assert server is not None + self._server = await loop.create_server( + server, sock=self._sock, ssl=self._ssl_context, backlog=self._backlog + ) + + +class BaseRunner(ABC): + __slots__ = ("_handle_signals", "_kwargs", "_server", "_sites") + + def __init__(self, *, handle_signals: bool = False, **kwargs: Any) -> None: + self._handle_signals = handle_signals + self._kwargs = kwargs + self._server = None # type: Optional[Server] + self._sites = [] # type: List[BaseSite] + + @property + def server(self) -> Optional[Server]: + return self._server + + @property + def addresses(self) -> List[Any]: + ret = [] # type: List[Any] + for site in self._sites: + server = site._server + if server is not None: + sockets = server.sockets + if sockets is not None: + for sock in sockets: + ret.append(sock.getsockname()) + return ret + + @property + def sites(self) -> Set[BaseSite]: + return set(self._sites) + + async def setup(self) -> None: + loop = asyncio.get_event_loop() + + if self._handle_signals: + try: + loop.add_signal_handler(signal.SIGINT, _raise_graceful_exit) + loop.add_signal_handler(signal.SIGTERM, _raise_graceful_exit) + except NotImplementedError: # pragma: no cover + # add_signal_handler is not implemented on Windows + pass + + self._server = await self._make_server() + + @abstractmethod + async def shutdown(self) -> None: + pass # pragma: no cover + + async def cleanup(self) -> None: + loop = asyncio.get_event_loop() + + if self._server is None: + # no started yet, do nothing + return + + # The loop over sites is intentional, an exception on gather() + # leaves self._sites in unpredictable state. + # The loop guaranties that a site is either deleted on success or + # still present on failure + for site in list(self._sites): + await site.stop() + await self._cleanup_server() + self._server = None + if self._handle_signals: + try: + loop.remove_signal_handler(signal.SIGINT) + loop.remove_signal_handler(signal.SIGTERM) + except NotImplementedError: # pragma: no cover + # remove_signal_handler is not implemented on Windows + pass + + @abstractmethod + async def _make_server(self) -> Server: + pass # pragma: no cover + + @abstractmethod + async def _cleanup_server(self) -> None: + pass # pragma: no cover + + def _reg_site(self, site: BaseSite) -> None: + if site in self._sites: + raise RuntimeError(f"Site {site} is already registered in runner {self}") + self._sites.append(site) + + def _check_site(self, site: BaseSite) -> None: + if site not in self._sites: + raise RuntimeError(f"Site {site} is not registered in runner {self}") + + def _unreg_site(self, site: BaseSite) -> None: + if site not in self._sites: + raise RuntimeError(f"Site {site} is not registered in runner {self}") + self._sites.remove(site) + + +class ServerRunner(BaseRunner): + """Low-level web server runner""" + + __slots__ = ("_web_server",) + + def __init__( + self, web_server: Server, *, handle_signals: bool = False, **kwargs: Any + ) -> None: + super().__init__(handle_signals=handle_signals, **kwargs) + self._web_server = web_server + + async def shutdown(self) -> None: + pass + + async def _make_server(self) -> Server: + return self._web_server + + async def _cleanup_server(self) -> None: + pass + + +class AppRunner(BaseRunner): + """Web Application runner""" + + __slots__ = ("_app",) + + def __init__( + self, app: Application, *, handle_signals: bool = False, **kwargs: Any + ) -> None: + super().__init__(handle_signals=handle_signals, **kwargs) + if not isinstance(app, Application): + raise TypeError( + "The first argument should be web.Application " + "instance, got {!r}".format(app) + ) + self._app = app + + @property + def app(self) -> Application: + return self._app + + async def shutdown(self) -> None: + await self._app.shutdown() + + async def _make_server(self) -> Server: + loop = asyncio.get_event_loop() + self._app._set_loop(loop) + self._app.on_startup.freeze() + await self._app.startup() + self._app.freeze() + + return self._app._make_handler(loop=loop, **self._kwargs) + + async def _cleanup_server(self) -> None: + await self._app.cleanup() diff --git a/dist/ba_data/python-site-packages/aiohttp/web_server.py b/dist/ba_data/python-site-packages/aiohttp/web_server.py new file mode 100644 index 0000000..5657ed9 --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_server.py @@ -0,0 +1,62 @@ +"""Low level HTTP server.""" +import asyncio +from typing import Any, Awaitable, Callable, Dict, List, Optional # noqa + +from .abc import AbstractStreamWriter +from .helpers import get_running_loop +from .http_parser import RawRequestMessage +from .streams import StreamReader +from .web_protocol import RequestHandler, _RequestFactory, _RequestHandler +from .web_request import BaseRequest + +__all__ = ("Server",) + + +class Server: + def __init__( + self, + handler: _RequestHandler, + *, + request_factory: Optional[_RequestFactory] = None, + loop: Optional[asyncio.AbstractEventLoop] = None, + **kwargs: Any + ) -> None: + self._loop = get_running_loop(loop) + self._connections = {} # type: Dict[RequestHandler, asyncio.Transport] + self._kwargs = kwargs + self.requests_count = 0 + self.request_handler = handler + self.request_factory = request_factory or self._make_request + + @property + def connections(self) -> List[RequestHandler]: + return list(self._connections.keys()) + + def connection_made( + self, handler: RequestHandler, transport: asyncio.Transport + ) -> None: + self._connections[handler] = transport + + def connection_lost( + self, handler: RequestHandler, exc: Optional[BaseException] = None + ) -> None: + if handler in self._connections: + del self._connections[handler] + + def _make_request( + self, + message: RawRequestMessage, + payload: StreamReader, + protocol: RequestHandler, + writer: AbstractStreamWriter, + task: "asyncio.Task[None]", + ) -> BaseRequest: + return BaseRequest(message, payload, protocol, writer, task, self._loop) + + async def shutdown(self, timeout: Optional[float] = None) -> None: + coros = [conn.shutdown(timeout) for conn in self._connections] + await asyncio.gather(*coros) + self._connections.clear() + + def __call__(self) -> RequestHandler: + return RequestHandler(self, loop=self._loop, **self._kwargs) diff --git a/dist/ba_data/python-site-packages/aiohttp/web_urldispatcher.py b/dist/ba_data/python-site-packages/aiohttp/web_urldispatcher.py new file mode 100644 index 0000000..2afd72f --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_urldispatcher.py @@ -0,0 +1,1233 @@ +import abc +import asyncio +import base64 +import hashlib +import inspect +import keyword +import os +import re +import warnings +from contextlib import contextmanager +from functools import wraps +from pathlib import Path +from types import MappingProxyType +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Container, + Dict, + Generator, + Iterable, + Iterator, + List, + Mapping, + Optional, + Pattern, + Set, + Sized, + Tuple, + Type, + Union, + cast, +) + +from typing_extensions import TypedDict +from yarl import URL, __version__ as yarl_version # type: ignore + +from . import hdrs +from .abc import AbstractMatchInfo, AbstractRouter, AbstractView +from .helpers import DEBUG +from .http import HttpVersion11 +from .typedefs import PathLike +from .web_exceptions import ( + HTTPException, + HTTPExpectationFailed, + HTTPForbidden, + HTTPMethodNotAllowed, + HTTPNotFound, +) +from .web_fileresponse import FileResponse +from .web_request import Request +from .web_response import Response, StreamResponse +from .web_routedef import AbstractRouteDef + +__all__ = ( + "UrlDispatcher", + "UrlMappingMatchInfo", + "AbstractResource", + "Resource", + "PlainResource", + "DynamicResource", + "AbstractRoute", + "ResourceRoute", + "StaticResource", + "View", +) + + +if TYPE_CHECKING: # pragma: no cover + from .web_app import Application + + BaseDict = Dict[str, str] +else: + BaseDict = dict + +YARL_VERSION = tuple(map(int, yarl_version.split(".")[:2])) + +HTTP_METHOD_RE = re.compile(r"^[0-9A-Za-z!#\$%&'\*\+\-\.\^_`\|~]+$") +ROUTE_RE = re.compile(r"(\{[_a-zA-Z][^{}]*(?:\{[^{}]*\}[^{}]*)*\})") +PATH_SEP = re.escape("/") + + +_WebHandler = Callable[[Request], Awaitable[StreamResponse]] +_ExpectHandler = Callable[[Request], Awaitable[None]] +_Resolve = Tuple[Optional[AbstractMatchInfo], Set[str]] + + +class _InfoDict(TypedDict, total=False): + path: str + + formatter: str + pattern: Pattern[str] + + directory: Path + prefix: str + routes: Mapping[str, "AbstractRoute"] + + app: "Application" + + domain: str + + rule: "AbstractRuleMatching" + + http_exception: HTTPException + + +class AbstractResource(Sized, Iterable["AbstractRoute"]): + def __init__(self, *, name: Optional[str] = None) -> None: + self._name = name + + @property + def name(self) -> Optional[str]: + return self._name + + @property + @abc.abstractmethod + def canonical(self) -> str: + """Exposes the resource's canonical path. + + For example '/foo/bar/{name}' + + """ + + @abc.abstractmethod # pragma: no branch + def url_for(self, **kwargs: str) -> URL: + """Construct url for resource with additional params.""" + + @abc.abstractmethod # pragma: no branch + async def resolve(self, request: Request) -> _Resolve: + """Resolve resource + + Return (UrlMappingMatchInfo, allowed_methods) pair.""" + + @abc.abstractmethod + def add_prefix(self, prefix: str) -> None: + """Add a prefix to processed URLs. + + Required for subapplications support. + + """ + + @abc.abstractmethod + def get_info(self) -> _InfoDict: + """Return a dict with additional info useful for introspection""" + + def freeze(self) -> None: + pass + + @abc.abstractmethod + def raw_match(self, path: str) -> bool: + """Perform a raw match against path""" + + +class AbstractRoute(abc.ABC): + def __init__( + self, + method: str, + handler: Union[_WebHandler, Type[AbstractView]], + *, + expect_handler: Optional[_ExpectHandler] = None, + resource: Optional[AbstractResource] = None, + ) -> None: + + if expect_handler is None: + expect_handler = _default_expect_handler + + assert asyncio.iscoroutinefunction( + expect_handler + ), f"Coroutine is expected, got {expect_handler!r}" + + method = method.upper() + if not HTTP_METHOD_RE.match(method): + raise ValueError(f"{method} is not allowed HTTP method") + + assert callable(handler), handler + if asyncio.iscoroutinefunction(handler): + pass + elif inspect.isgeneratorfunction(handler): + warnings.warn( + "Bare generators are deprecated, " "use @coroutine wrapper", + DeprecationWarning, + ) + elif isinstance(handler, type) and issubclass(handler, AbstractView): + pass + else: + warnings.warn( + "Bare functions are deprecated, " "use async ones", DeprecationWarning + ) + + @wraps(handler) + async def handler_wrapper(request: Request) -> StreamResponse: + result = old_handler(request) + if asyncio.iscoroutine(result): + return await result + return result # type: ignore + + old_handler = handler + handler = handler_wrapper + + self._method = method + self._handler = handler + self._expect_handler = expect_handler + self._resource = resource + + @property + def method(self) -> str: + return self._method + + @property + def handler(self) -> _WebHandler: + return self._handler + + @property + @abc.abstractmethod + def name(self) -> Optional[str]: + """Optional route's name, always equals to resource's name.""" + + @property + def resource(self) -> Optional[AbstractResource]: + return self._resource + + @abc.abstractmethod + def get_info(self) -> _InfoDict: + """Return a dict with additional info useful for introspection""" + + @abc.abstractmethod # pragma: no branch + def url_for(self, *args: str, **kwargs: str) -> URL: + """Construct url for route with additional params.""" + + async def handle_expect_header(self, request: Request) -> None: + await self._expect_handler(request) + + +class UrlMappingMatchInfo(BaseDict, AbstractMatchInfo): + def __init__(self, match_dict: Dict[str, str], route: AbstractRoute): + super().__init__(match_dict) + self._route = route + self._apps = [] # type: List[Application] + self._current_app = None # type: Optional[Application] + self._frozen = False + + @property + def handler(self) -> _WebHandler: + return self._route.handler + + @property + def route(self) -> AbstractRoute: + return self._route + + @property + def expect_handler(self) -> _ExpectHandler: + return self._route.handle_expect_header + + @property + def http_exception(self) -> Optional[HTTPException]: + return None + + def get_info(self) -> _InfoDict: # type: ignore + return self._route.get_info() + + @property + def apps(self) -> Tuple["Application", ...]: + return tuple(self._apps) + + def add_app(self, app: "Application") -> None: + if self._frozen: + raise RuntimeError("Cannot change apps stack after .freeze() call") + if self._current_app is None: + self._current_app = app + self._apps.insert(0, app) + + @property + def current_app(self) -> "Application": + app = self._current_app + assert app is not None + return app + + @contextmanager + def set_current_app(self, app: "Application") -> Generator[None, None, None]: + if DEBUG: # pragma: no cover + if app not in self._apps: + raise RuntimeError( + "Expected one of the following apps {!r}, got {!r}".format( + self._apps, app + ) + ) + prev = self._current_app + self._current_app = app + try: + yield + finally: + self._current_app = prev + + def freeze(self) -> None: + self._frozen = True + + def __repr__(self) -> str: + return f"" + + +class MatchInfoError(UrlMappingMatchInfo): + def __init__(self, http_exception: HTTPException) -> None: + self._exception = http_exception + super().__init__({}, SystemRoute(self._exception)) + + @property + def http_exception(self) -> HTTPException: + return self._exception + + def __repr__(self) -> str: + return "".format( + self._exception.status, self._exception.reason + ) + + +async def _default_expect_handler(request: Request) -> None: + """Default handler for Expect header. + + Just send "100 Continue" to client. + raise HTTPExpectationFailed if value of header is not "100-continue" + """ + expect = request.headers.get(hdrs.EXPECT, "") + if request.version == HttpVersion11: + if expect.lower() == "100-continue": + await request.writer.write(b"HTTP/1.1 100 Continue\r\n\r\n") + else: + raise HTTPExpectationFailed(text="Unknown Expect: %s" % expect) + + +class Resource(AbstractResource): + def __init__(self, *, name: Optional[str] = None) -> None: + super().__init__(name=name) + self._routes = [] # type: List[ResourceRoute] + + def add_route( + self, + method: str, + handler: Union[Type[AbstractView], _WebHandler], + *, + expect_handler: Optional[_ExpectHandler] = None, + ) -> "ResourceRoute": + + for route_obj in self._routes: + if route_obj.method == method or route_obj.method == hdrs.METH_ANY: + raise RuntimeError( + "Added route will never be executed, " + "method {route.method} is already " + "registered".format(route=route_obj) + ) + + route_obj = ResourceRoute(method, handler, self, expect_handler=expect_handler) + self.register_route(route_obj) + return route_obj + + def register_route(self, route: "ResourceRoute") -> None: + assert isinstance( + route, ResourceRoute + ), f"Instance of Route class is required, got {route!r}" + self._routes.append(route) + + async def resolve(self, request: Request) -> _Resolve: + allowed_methods = set() # type: Set[str] + + match_dict = self._match(request.rel_url.raw_path) + if match_dict is None: + return None, allowed_methods + + for route_obj in self._routes: + route_method = route_obj.method + allowed_methods.add(route_method) + + if route_method == request.method or route_method == hdrs.METH_ANY: + return (UrlMappingMatchInfo(match_dict, route_obj), allowed_methods) + else: + return None, allowed_methods + + @abc.abstractmethod + def _match(self, path: str) -> Optional[Dict[str, str]]: + pass # pragma: no cover + + def __len__(self) -> int: + return len(self._routes) + + def __iter__(self) -> Iterator[AbstractRoute]: + return iter(self._routes) + + # TODO: implement all abstract methods + + +class PlainResource(Resource): + def __init__(self, path: str, *, name: Optional[str] = None) -> None: + super().__init__(name=name) + assert not path or path.startswith("/") + self._path = path + + @property + def canonical(self) -> str: + return self._path + + def freeze(self) -> None: + if not self._path: + self._path = "/" + + def add_prefix(self, prefix: str) -> None: + assert prefix.startswith("/") + assert not prefix.endswith("/") + assert len(prefix) > 1 + self._path = prefix + self._path + + def _match(self, path: str) -> Optional[Dict[str, str]]: + # string comparison is about 10 times faster than regexp matching + if self._path == path: + return {} + else: + return None + + def raw_match(self, path: str) -> bool: + return self._path == path + + def get_info(self) -> _InfoDict: + return {"path": self._path} + + def url_for(self) -> URL: # type: ignore + return URL.build(path=self._path, encoded=True) + + def __repr__(self) -> str: + name = "'" + self.name + "' " if self.name is not None else "" + return f"" + + +class DynamicResource(Resource): + + DYN = re.compile(r"\{(?P[_a-zA-Z][_a-zA-Z0-9]*)\}") + DYN_WITH_RE = re.compile(r"\{(?P[_a-zA-Z][_a-zA-Z0-9]*):(?P.+)\}") + GOOD = r"[^{}/]+" + + def __init__(self, path: str, *, name: Optional[str] = None) -> None: + super().__init__(name=name) + pattern = "" + formatter = "" + for part in ROUTE_RE.split(path): + match = self.DYN.fullmatch(part) + if match: + pattern += "(?P<{}>{})".format(match.group("var"), self.GOOD) + formatter += "{" + match.group("var") + "}" + continue + + match = self.DYN_WITH_RE.fullmatch(part) + if match: + pattern += "(?P<{var}>{re})".format(**match.groupdict()) + formatter += "{" + match.group("var") + "}" + continue + + if "{" in part or "}" in part: + raise ValueError(f"Invalid path '{path}'['{part}']") + + part = _requote_path(part) + formatter += part + pattern += re.escape(part) + + try: + compiled = re.compile(pattern) + except re.error as exc: + raise ValueError(f"Bad pattern '{pattern}': {exc}") from None + assert compiled.pattern.startswith(PATH_SEP) + assert formatter.startswith("/") + self._pattern = compiled + self._formatter = formatter + + @property + def canonical(self) -> str: + return self._formatter + + def add_prefix(self, prefix: str) -> None: + assert prefix.startswith("/") + assert not prefix.endswith("/") + assert len(prefix) > 1 + self._pattern = re.compile(re.escape(prefix) + self._pattern.pattern) + self._formatter = prefix + self._formatter + + def _match(self, path: str) -> Optional[Dict[str, str]]: + match = self._pattern.fullmatch(path) + if match is None: + return None + else: + return { + key: _unquote_path(value) for key, value in match.groupdict().items() + } + + def raw_match(self, path: str) -> bool: + return self._formatter == path + + def get_info(self) -> _InfoDict: + return {"formatter": self._formatter, "pattern": self._pattern} + + def url_for(self, **parts: str) -> URL: + url = self._formatter.format_map({k: _quote_path(v) for k, v in parts.items()}) + return URL.build(path=url, encoded=True) + + def __repr__(self) -> str: + name = "'" + self.name + "' " if self.name is not None else "" + return "".format( + name=name, formatter=self._formatter + ) + + +class PrefixResource(AbstractResource): + def __init__(self, prefix: str, *, name: Optional[str] = None) -> None: + assert not prefix or prefix.startswith("/"), prefix + assert prefix in ("", "/") or not prefix.endswith("/"), prefix + super().__init__(name=name) + self._prefix = _requote_path(prefix) + + @property + def canonical(self) -> str: + return self._prefix + + def add_prefix(self, prefix: str) -> None: + assert prefix.startswith("/") + assert not prefix.endswith("/") + assert len(prefix) > 1 + self._prefix = prefix + self._prefix + + def raw_match(self, prefix: str) -> bool: + return False + + # TODO: impl missing abstract methods + + +class StaticResource(PrefixResource): + VERSION_KEY = "v" + + def __init__( + self, + prefix: str, + directory: PathLike, + *, + name: Optional[str] = None, + expect_handler: Optional[_ExpectHandler] = None, + chunk_size: int = 256 * 1024, + show_index: bool = False, + follow_symlinks: bool = False, + append_version: bool = False, + ) -> None: + super().__init__(prefix, name=name) + try: + directory = Path(directory) + if str(directory).startswith("~"): + directory = Path(os.path.expanduser(str(directory))) + directory = directory.resolve() + if not directory.is_dir(): + raise ValueError("Not a directory") + except (FileNotFoundError, ValueError) as error: + raise ValueError(f"No directory exists at '{directory}'") from error + self._directory = directory + self._show_index = show_index + self._chunk_size = chunk_size + self._follow_symlinks = follow_symlinks + self._expect_handler = expect_handler + self._append_version = append_version + + self._routes = { + "GET": ResourceRoute( + "GET", self._handle, self, expect_handler=expect_handler + ), + "HEAD": ResourceRoute( + "HEAD", self._handle, self, expect_handler=expect_handler + ), + } + + def url_for( # type: ignore + self, + *, + filename: Union[str, Path], + append_version: Optional[bool] = None, + ) -> URL: + if append_version is None: + append_version = self._append_version + if isinstance(filename, Path): + filename = str(filename) + filename = filename.lstrip("/") + + url = URL.build(path=self._prefix, encoded=True) + # filename is not encoded + if YARL_VERSION < (1, 6): + url = url / filename.replace("%", "%25") + else: + url = url / filename + + if append_version: + try: + filepath = self._directory.joinpath(filename).resolve() + if not self._follow_symlinks: + filepath.relative_to(self._directory) + except (ValueError, FileNotFoundError): + # ValueError for case when path point to symlink + # with follow_symlinks is False + return url # relatively safe + if filepath.is_file(): + # TODO cache file content + # with file watcher for cache invalidation + with filepath.open("rb") as f: + file_bytes = f.read() + h = self._get_file_hash(file_bytes) + url = url.with_query({self.VERSION_KEY: h}) + return url + return url + + @staticmethod + def _get_file_hash(byte_array: bytes) -> str: + m = hashlib.sha256() # todo sha256 can be configurable param + m.update(byte_array) + b64 = base64.urlsafe_b64encode(m.digest()) + return b64.decode("ascii") + + def get_info(self) -> _InfoDict: + return { + "directory": self._directory, + "prefix": self._prefix, + "routes": self._routes, + } + + def set_options_route(self, handler: _WebHandler) -> None: + if "OPTIONS" in self._routes: + raise RuntimeError("OPTIONS route was set already") + self._routes["OPTIONS"] = ResourceRoute( + "OPTIONS", handler, self, expect_handler=self._expect_handler + ) + + async def resolve(self, request: Request) -> _Resolve: + path = request.rel_url.raw_path + method = request.method + allowed_methods = set(self._routes) + if not path.startswith(self._prefix): + return None, set() + + if method not in allowed_methods: + return None, allowed_methods + + match_dict = {"filename": _unquote_path(path[len(self._prefix) + 1 :])} + return (UrlMappingMatchInfo(match_dict, self._routes[method]), allowed_methods) + + def __len__(self) -> int: + return len(self._routes) + + def __iter__(self) -> Iterator[AbstractRoute]: + return iter(self._routes.values()) + + async def _handle(self, request: Request) -> StreamResponse: + rel_url = request.match_info["filename"] + try: + filename = Path(rel_url) + if filename.anchor: + # rel_url is an absolute name like + # /static/\\machine_name\c$ or /static/D:\path + # where the static dir is totally different + raise HTTPForbidden() + filepath = self._directory.joinpath(filename).resolve() + if not self._follow_symlinks: + filepath.relative_to(self._directory) + except (ValueError, FileNotFoundError) as error: + # relatively safe + raise HTTPNotFound() from error + except HTTPForbidden: + raise + except Exception as error: + # perm error or other kind! + request.app.logger.exception(error) + raise HTTPNotFound() from error + + # on opening a dir, load its contents if allowed + if filepath.is_dir(): + if self._show_index: + try: + return Response( + text=self._directory_as_html(filepath), content_type="text/html" + ) + except PermissionError: + raise HTTPForbidden() + else: + raise HTTPForbidden() + elif filepath.is_file(): + return FileResponse(filepath, chunk_size=self._chunk_size) + else: + raise HTTPNotFound + + def _directory_as_html(self, filepath: Path) -> str: + # returns directory's index as html + + # sanity check + assert filepath.is_dir() + + relative_path_to_dir = filepath.relative_to(self._directory).as_posix() + index_of = f"Index of /{relative_path_to_dir}" + h1 = f"

{index_of}

" + + index_list = [] + dir_index = filepath.iterdir() + for _file in sorted(dir_index): + # show file url as relative to static path + rel_path = _file.relative_to(self._directory).as_posix() + file_url = self._prefix + "/" + rel_path + + # if file is a directory, add '/' to the end of the name + if _file.is_dir(): + file_name = f"{_file.name}/" + else: + file_name = _file.name + + index_list.append( + '
  • {name}
  • '.format( + url=file_url, name=file_name + ) + ) + ul = "
      \n{}\n
    ".format("\n".join(index_list)) + body = f"\n{h1}\n{ul}\n" + + head_str = f"\n{index_of}\n" + html = f"\n{head_str}\n{body}\n" + + return html + + def __repr__(self) -> str: + name = "'" + self.name + "'" if self.name is not None else "" + return " {directory!r}>".format( + name=name, path=self._prefix, directory=self._directory + ) + + +class PrefixedSubAppResource(PrefixResource): + def __init__(self, prefix: str, app: "Application") -> None: + super().__init__(prefix) + self._app = app + for resource in app.router.resources(): + resource.add_prefix(prefix) + + def add_prefix(self, prefix: str) -> None: + super().add_prefix(prefix) + for resource in self._app.router.resources(): + resource.add_prefix(prefix) + + def url_for(self, *args: str, **kwargs: str) -> URL: + raise RuntimeError(".url_for() is not supported " "by sub-application root") + + def get_info(self) -> _InfoDict: + return {"app": self._app, "prefix": self._prefix} + + async def resolve(self, request: Request) -> _Resolve: + if ( + not request.url.raw_path.startswith(self._prefix + "/") + and request.url.raw_path != self._prefix + ): + return None, set() + match_info = await self._app.router.resolve(request) + match_info.add_app(self._app) + if isinstance(match_info.http_exception, HTTPMethodNotAllowed): + methods = match_info.http_exception.allowed_methods + else: + methods = set() + return match_info, methods + + def __len__(self) -> int: + return len(self._app.router.routes()) + + def __iter__(self) -> Iterator[AbstractRoute]: + return iter(self._app.router.routes()) + + def __repr__(self) -> str: + return " {app!r}>".format( + prefix=self._prefix, app=self._app + ) + + +class AbstractRuleMatching(abc.ABC): + @abc.abstractmethod # pragma: no branch + async def match(self, request: Request) -> bool: + """Return bool if the request satisfies the criteria""" + + @abc.abstractmethod # pragma: no branch + def get_info(self) -> _InfoDict: + """Return a dict with additional info useful for introspection""" + + @property + @abc.abstractmethod # pragma: no branch + def canonical(self) -> str: + """Return a str""" + + +class Domain(AbstractRuleMatching): + re_part = re.compile(r"(?!-)[a-z\d-]{1,63}(? None: + super().__init__() + self._domain = self.validation(domain) + + @property + def canonical(self) -> str: + return self._domain + + def validation(self, domain: str) -> str: + if not isinstance(domain, str): + raise TypeError("Domain must be str") + domain = domain.rstrip(".").lower() + if not domain: + raise ValueError("Domain cannot be empty") + elif "://" in domain: + raise ValueError("Scheme not supported") + url = URL("http://" + domain) + assert url.raw_host is not None + if not all(self.re_part.fullmatch(x) for x in url.raw_host.split(".")): + raise ValueError("Domain not valid") + if url.port == 80: + return url.raw_host + return f"{url.raw_host}:{url.port}" + + async def match(self, request: Request) -> bool: + host = request.headers.get(hdrs.HOST) + if not host: + return False + return self.match_domain(host) + + def match_domain(self, host: str) -> bool: + return host.lower() == self._domain + + def get_info(self) -> _InfoDict: + return {"domain": self._domain} + + +class MaskDomain(Domain): + re_part = re.compile(r"(?!-)[a-z\d\*-]{1,63}(? None: + super().__init__(domain) + mask = self._domain.replace(".", r"\.").replace("*", ".*") + self._mask = re.compile(mask) + + @property + def canonical(self) -> str: + return self._mask.pattern + + def match_domain(self, host: str) -> bool: + return self._mask.fullmatch(host) is not None + + +class MatchedSubAppResource(PrefixedSubAppResource): + def __init__(self, rule: AbstractRuleMatching, app: "Application") -> None: + AbstractResource.__init__(self) + self._prefix = "" + self._app = app + self._rule = rule + + @property + def canonical(self) -> str: + return self._rule.canonical + + def get_info(self) -> _InfoDict: + return {"app": self._app, "rule": self._rule} + + async def resolve(self, request: Request) -> _Resolve: + if not await self._rule.match(request): + return None, set() + match_info = await self._app.router.resolve(request) + match_info.add_app(self._app) + if isinstance(match_info.http_exception, HTTPMethodNotAllowed): + methods = match_info.http_exception.allowed_methods + else: + methods = set() + return match_info, methods + + def __repr__(self) -> str: + return " {app!r}>" "".format(app=self._app) + + +class ResourceRoute(AbstractRoute): + """A route with resource""" + + def __init__( + self, + method: str, + handler: Union[_WebHandler, Type[AbstractView]], + resource: AbstractResource, + *, + expect_handler: Optional[_ExpectHandler] = None, + ) -> None: + super().__init__( + method, handler, expect_handler=expect_handler, resource=resource + ) + + def __repr__(self) -> str: + return " {handler!r}".format( + method=self.method, resource=self._resource, handler=self.handler + ) + + @property + def name(self) -> Optional[str]: + if self._resource is None: + return None + return self._resource.name + + def url_for(self, *args: str, **kwargs: str) -> URL: + """Construct url for route with additional params.""" + assert self._resource is not None + return self._resource.url_for(*args, **kwargs) + + def get_info(self) -> _InfoDict: + assert self._resource is not None + return self._resource.get_info() + + +class SystemRoute(AbstractRoute): + def __init__(self, http_exception: HTTPException) -> None: + super().__init__(hdrs.METH_ANY, self._handle) + self._http_exception = http_exception + + def url_for(self, *args: str, **kwargs: str) -> URL: + raise RuntimeError(".url_for() is not allowed for SystemRoute") + + @property + def name(self) -> Optional[str]: + return None + + def get_info(self) -> _InfoDict: + return {"http_exception": self._http_exception} + + async def _handle(self, request: Request) -> StreamResponse: + raise self._http_exception + + @property + def status(self) -> int: + return self._http_exception.status + + @property + def reason(self) -> str: + return self._http_exception.reason + + def __repr__(self) -> str: + return "".format(self=self) + + +class View(AbstractView): + async def _iter(self) -> StreamResponse: + if self.request.method not in hdrs.METH_ALL: + self._raise_allowed_methods() + method = getattr(self, self.request.method.lower(), None) + if method is None: + self._raise_allowed_methods() + resp = await method() + return resp + + def __await__(self) -> Generator[Any, None, StreamResponse]: + return self._iter().__await__() + + def _raise_allowed_methods(self) -> None: + allowed_methods = {m for m in hdrs.METH_ALL if hasattr(self, m.lower())} + raise HTTPMethodNotAllowed(self.request.method, allowed_methods) + + +class ResourcesView(Sized, Iterable[AbstractResource], Container[AbstractResource]): + def __init__(self, resources: List[AbstractResource]) -> None: + self._resources = resources + + def __len__(self) -> int: + return len(self._resources) + + def __iter__(self) -> Iterator[AbstractResource]: + yield from self._resources + + def __contains__(self, resource: object) -> bool: + return resource in self._resources + + +class RoutesView(Sized, Iterable[AbstractRoute], Container[AbstractRoute]): + def __init__(self, resources: List[AbstractResource]): + self._routes = [] # type: List[AbstractRoute] + for resource in resources: + for route in resource: + self._routes.append(route) + + def __len__(self) -> int: + return len(self._routes) + + def __iter__(self) -> Iterator[AbstractRoute]: + yield from self._routes + + def __contains__(self, route: object) -> bool: + return route in self._routes + + +class UrlDispatcher(AbstractRouter, Mapping[str, AbstractResource]): + + NAME_SPLIT_RE = re.compile(r"[.:-]") + + def __init__(self) -> None: + super().__init__() + self._resources = [] # type: List[AbstractResource] + self._named_resources = {} # type: Dict[str, AbstractResource] + + async def resolve(self, request: Request) -> AbstractMatchInfo: + method = request.method + allowed_methods = set() # type: Set[str] + + for resource in self._resources: + match_dict, allowed = await resource.resolve(request) + if match_dict is not None: + return match_dict + else: + allowed_methods |= allowed + else: + if allowed_methods: + return MatchInfoError(HTTPMethodNotAllowed(method, allowed_methods)) + else: + return MatchInfoError(HTTPNotFound()) + + def __iter__(self) -> Iterator[str]: + return iter(self._named_resources) + + def __len__(self) -> int: + return len(self._named_resources) + + def __contains__(self, resource: object) -> bool: + return resource in self._named_resources + + def __getitem__(self, name: str) -> AbstractResource: + return self._named_resources[name] + + def resources(self) -> ResourcesView: + return ResourcesView(self._resources) + + def routes(self) -> RoutesView: + return RoutesView(self._resources) + + def named_resources(self) -> Mapping[str, AbstractResource]: + return MappingProxyType(self._named_resources) + + def register_resource(self, resource: AbstractResource) -> None: + assert isinstance( + resource, AbstractResource + ), f"Instance of AbstractResource class is required, got {resource!r}" + if self.frozen: + raise RuntimeError("Cannot register a resource into frozen router.") + + name = resource.name + + if name is not None: + parts = self.NAME_SPLIT_RE.split(name) + for part in parts: + if keyword.iskeyword(part): + raise ValueError( + f"Incorrect route name {name!r}, " + "python keywords cannot be used " + "for route name" + ) + if not part.isidentifier(): + raise ValueError( + "Incorrect route name {!r}, " + "the name should be a sequence of " + "python identifiers separated " + "by dash, dot or column".format(name) + ) + if name in self._named_resources: + raise ValueError( + "Duplicate {!r}, " + "already handled by {!r}".format(name, self._named_resources[name]) + ) + self._named_resources[name] = resource + self._resources.append(resource) + + def add_resource(self, path: str, *, name: Optional[str] = None) -> Resource: + if path and not path.startswith("/"): + raise ValueError("path should be started with / or be empty") + # Reuse last added resource if path and name are the same + if self._resources: + resource = self._resources[-1] + if resource.name == name and resource.raw_match(path): + return cast(Resource, resource) + if not ("{" in path or "}" in path or ROUTE_RE.search(path)): + resource = PlainResource(_requote_path(path), name=name) + self.register_resource(resource) + return resource + resource = DynamicResource(path, name=name) + self.register_resource(resource) + return resource + + def add_route( + self, + method: str, + path: str, + handler: Union[_WebHandler, Type[AbstractView]], + *, + name: Optional[str] = None, + expect_handler: Optional[_ExpectHandler] = None, + ) -> AbstractRoute: + resource = self.add_resource(path, name=name) + return resource.add_route(method, handler, expect_handler=expect_handler) + + def add_static( + self, + prefix: str, + path: PathLike, + *, + name: Optional[str] = None, + expect_handler: Optional[_ExpectHandler] = None, + chunk_size: int = 256 * 1024, + show_index: bool = False, + follow_symlinks: bool = False, + append_version: bool = False, + ) -> AbstractResource: + """Add static files view. + + prefix - url prefix + path - folder with files + + """ + assert prefix.startswith("/") + if prefix.endswith("/"): + prefix = prefix[:-1] + resource = StaticResource( + prefix, + path, + name=name, + expect_handler=expect_handler, + chunk_size=chunk_size, + show_index=show_index, + follow_symlinks=follow_symlinks, + append_version=append_version, + ) + self.register_resource(resource) + return resource + + def add_head(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute: + """ + Shortcut for add_route with method HEAD + """ + return self.add_route(hdrs.METH_HEAD, path, handler, **kwargs) + + def add_options( + self, path: str, handler: _WebHandler, **kwargs: Any + ) -> AbstractRoute: + """ + Shortcut for add_route with method OPTIONS + """ + return self.add_route(hdrs.METH_OPTIONS, path, handler, **kwargs) + + def add_get( + self, + path: str, + handler: _WebHandler, + *, + name: Optional[str] = None, + allow_head: bool = True, + **kwargs: Any, + ) -> AbstractRoute: + """ + Shortcut for add_route with method GET, if allow_head is true another + route is added allowing head requests to the same endpoint + """ + resource = self.add_resource(path, name=name) + if allow_head: + resource.add_route(hdrs.METH_HEAD, handler, **kwargs) + return resource.add_route(hdrs.METH_GET, handler, **kwargs) + + def add_post(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute: + """ + Shortcut for add_route with method POST + """ + return self.add_route(hdrs.METH_POST, path, handler, **kwargs) + + def add_put(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute: + """ + Shortcut for add_route with method PUT + """ + return self.add_route(hdrs.METH_PUT, path, handler, **kwargs) + + def add_patch( + self, path: str, handler: _WebHandler, **kwargs: Any + ) -> AbstractRoute: + """ + Shortcut for add_route with method PATCH + """ + return self.add_route(hdrs.METH_PATCH, path, handler, **kwargs) + + def add_delete( + self, path: str, handler: _WebHandler, **kwargs: Any + ) -> AbstractRoute: + """ + Shortcut for add_route with method DELETE + """ + return self.add_route(hdrs.METH_DELETE, path, handler, **kwargs) + + def add_view( + self, path: str, handler: Type[AbstractView], **kwargs: Any + ) -> AbstractRoute: + """ + Shortcut for add_route with ANY methods for a class-based view + """ + return self.add_route(hdrs.METH_ANY, path, handler, **kwargs) + + def freeze(self) -> None: + super().freeze() + for resource in self._resources: + resource.freeze() + + def add_routes(self, routes: Iterable[AbstractRouteDef]) -> List[AbstractRoute]: + """Append routes to route table. + + Parameter should be a sequence of RouteDef objects. + + Returns a list of registered AbstractRoute instances. + """ + registered_routes = [] + for route_def in routes: + registered_routes.extend(route_def.register(self)) + return registered_routes + + +def _quote_path(value: str) -> str: + if YARL_VERSION < (1, 6): + value = value.replace("%", "%25") + return URL.build(path=value, encoded=False).raw_path + + +def _unquote_path(value: str) -> str: + return URL.build(path=value, encoded=True).path + + +def _requote_path(value: str) -> str: + # Quote non-ascii characters and other characters which must be quoted, + # but preserve existing %-sequences. + result = _quote_path(value) + if "%" in value: + result = result.replace("%25", "%") + return result diff --git a/dist/ba_data/python-site-packages/aiohttp/web_ws.py b/dist/ba_data/python-site-packages/aiohttp/web_ws.py new file mode 100644 index 0000000..da7ce6d --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/web_ws.py @@ -0,0 +1,481 @@ +import asyncio +import base64 +import binascii +import hashlib +import json +from typing import Any, Iterable, Optional, Tuple + +import async_timeout +import attr +from multidict import CIMultiDict + +from . import hdrs +from .abc import AbstractStreamWriter +from .helpers import call_later, set_result +from .http import ( + WS_CLOSED_MESSAGE, + WS_CLOSING_MESSAGE, + WS_KEY, + WebSocketError, + WebSocketReader, + WebSocketWriter, + WSMessage, + WSMsgType as WSMsgType, + ws_ext_gen, + ws_ext_parse, +) +from .log import ws_logger +from .streams import EofStream, FlowControlDataQueue +from .typedefs import JSONDecoder, JSONEncoder +from .web_exceptions import HTTPBadRequest, HTTPException +from .web_request import BaseRequest +from .web_response import StreamResponse + +__all__ = ( + "WebSocketResponse", + "WebSocketReady", + "WSMsgType", +) + +THRESHOLD_CONNLOST_ACCESS = 5 + + +@attr.s(auto_attribs=True, frozen=True, slots=True) +class WebSocketReady: + ok: bool + protocol: Optional[str] + + def __bool__(self) -> bool: + return self.ok + + +class WebSocketResponse(StreamResponse): + + _length_check = False + + def __init__( + self, + *, + timeout: float = 10.0, + receive_timeout: Optional[float] = None, + autoclose: bool = True, + autoping: bool = True, + heartbeat: Optional[float] = None, + protocols: Iterable[str] = (), + compress: bool = True, + max_msg_size: int = 4 * 1024 * 1024, + ) -> None: + super().__init__(status=101) + self._protocols = protocols + self._ws_protocol = None # type: Optional[str] + self._writer = None # type: Optional[WebSocketWriter] + self._reader = None # type: Optional[FlowControlDataQueue[WSMessage]] + self._closed = False + self._closing = False + self._conn_lost = 0 + self._close_code = None # type: Optional[int] + self._loop = None # type: Optional[asyncio.AbstractEventLoop] + self._waiting = None # type: Optional[asyncio.Future[bool]] + self._exception = None # type: Optional[BaseException] + self._timeout = timeout + self._receive_timeout = receive_timeout + self._autoclose = autoclose + self._autoping = autoping + self._heartbeat = heartbeat + self._heartbeat_cb = None + if heartbeat is not None: + self._pong_heartbeat = heartbeat / 2.0 + self._pong_response_cb = None + self._compress = compress + self._max_msg_size = max_msg_size + + def _cancel_heartbeat(self) -> None: + if self._pong_response_cb is not None: + self._pong_response_cb.cancel() + self._pong_response_cb = None + + if self._heartbeat_cb is not None: + self._heartbeat_cb.cancel() + self._heartbeat_cb = None + + def _reset_heartbeat(self) -> None: + self._cancel_heartbeat() + + if self._heartbeat is not None: + self._heartbeat_cb = call_later( + self._send_heartbeat, self._heartbeat, self._loop + ) + + def _send_heartbeat(self) -> None: + if self._heartbeat is not None and not self._closed: + # fire-and-forget a task is not perfect but maybe ok for + # sending ping. Otherwise we need a long-living heartbeat + # task in the class. + self._loop.create_task(self._writer.ping()) # type: ignore + + if self._pong_response_cb is not None: + self._pong_response_cb.cancel() + self._pong_response_cb = call_later( + self._pong_not_received, self._pong_heartbeat, self._loop + ) + + def _pong_not_received(self) -> None: + if self._req is not None and self._req.transport is not None: + self._closed = True + self._close_code = 1006 + self._exception = asyncio.TimeoutError() + self._req.transport.close() + + async def prepare(self, request: BaseRequest) -> AbstractStreamWriter: + # make pre-check to don't hide it by do_handshake() exceptions + if self._payload_writer is not None: + return self._payload_writer + + protocol, writer = self._pre_start(request) + payload_writer = await super().prepare(request) + assert payload_writer is not None + self._post_start(request, protocol, writer) + await payload_writer.drain() + return payload_writer + + def _handshake( + self, request: BaseRequest + ) -> Tuple["CIMultiDict[str]", str, bool, bool]: + headers = request.headers + if "websocket" != headers.get(hdrs.UPGRADE, "").lower().strip(): + raise HTTPBadRequest( + text=( + "No WebSocket UPGRADE hdr: {}\n Can " + '"Upgrade" only to "WebSocket".' + ).format(headers.get(hdrs.UPGRADE)) + ) + + if "upgrade" not in headers.get(hdrs.CONNECTION, "").lower(): + raise HTTPBadRequest( + text="No CONNECTION upgrade hdr: {}".format( + headers.get(hdrs.CONNECTION) + ) + ) + + # find common sub-protocol between client and server + protocol = None + if hdrs.SEC_WEBSOCKET_PROTOCOL in headers: + req_protocols = [ + str(proto.strip()) + for proto in headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(",") + ] + + for proto in req_protocols: + if proto in self._protocols: + protocol = proto + break + else: + # No overlap found: Return no protocol as per spec + ws_logger.warning( + "Client protocols %r don’t overlap server-known ones %r", + req_protocols, + self._protocols, + ) + + # check supported version + version = headers.get(hdrs.SEC_WEBSOCKET_VERSION, "") + if version not in ("13", "8", "7"): + raise HTTPBadRequest(text=f"Unsupported version: {version}") + + # check client handshake for validity + key = headers.get(hdrs.SEC_WEBSOCKET_KEY) + try: + if not key or len(base64.b64decode(key)) != 16: + raise HTTPBadRequest(text=f"Handshake error: {key!r}") + except binascii.Error: + raise HTTPBadRequest(text=f"Handshake error: {key!r}") from None + + accept_val = base64.b64encode( + hashlib.sha1(key.encode() + WS_KEY).digest() + ).decode() + response_headers = CIMultiDict( # type: ignore + { + hdrs.UPGRADE: "websocket", # type: ignore + hdrs.CONNECTION: "upgrade", + hdrs.SEC_WEBSOCKET_ACCEPT: accept_val, + } + ) + + notakeover = False + compress = 0 + if self._compress: + extensions = headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS) + # Server side always get return with no exception. + # If something happened, just drop compress extension + compress, notakeover = ws_ext_parse(extensions, isserver=True) + if compress: + enabledext = ws_ext_gen( + compress=compress, isserver=True, server_notakeover=notakeover + ) + response_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = enabledext + + if protocol: + response_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = protocol + return (response_headers, protocol, compress, notakeover) # type: ignore + + def _pre_start(self, request: BaseRequest) -> Tuple[str, WebSocketWriter]: + self._loop = request._loop + + headers, protocol, compress, notakeover = self._handshake(request) + + self.set_status(101) + self.headers.update(headers) + self.force_close() + self._compress = compress + transport = request._protocol.transport + assert transport is not None + writer = WebSocketWriter( + request._protocol, transport, compress=compress, notakeover=notakeover + ) + + return protocol, writer + + def _post_start( + self, request: BaseRequest, protocol: str, writer: WebSocketWriter + ) -> None: + self._ws_protocol = protocol + self._writer = writer + + self._reset_heartbeat() + + loop = self._loop + assert loop is not None + self._reader = FlowControlDataQueue(request._protocol, 2 ** 16, loop=loop) + request.protocol.set_parser( + WebSocketReader(self._reader, self._max_msg_size, compress=self._compress) + ) + # disable HTTP keepalive for WebSocket + request.protocol.keep_alive(False) + + def can_prepare(self, request: BaseRequest) -> WebSocketReady: + if self._writer is not None: + raise RuntimeError("Already started") + try: + _, protocol, _, _ = self._handshake(request) + except HTTPException: + return WebSocketReady(False, None) + else: + return WebSocketReady(True, protocol) + + @property + def closed(self) -> bool: + return self._closed + + @property + def close_code(self) -> Optional[int]: + return self._close_code + + @property + def ws_protocol(self) -> Optional[str]: + return self._ws_protocol + + @property + def compress(self) -> bool: + return self._compress + + def exception(self) -> Optional[BaseException]: + return self._exception + + async def ping(self, message: bytes = b"") -> None: + if self._writer is None: + raise RuntimeError("Call .prepare() first") + await self._writer.ping(message) + + async def pong(self, message: bytes = b"") -> None: + # unsolicited pong + if self._writer is None: + raise RuntimeError("Call .prepare() first") + await self._writer.pong(message) + + async def send_str(self, data: str, compress: Optional[bool] = None) -> None: + if self._writer is None: + raise RuntimeError("Call .prepare() first") + if not isinstance(data, str): + raise TypeError("data argument must be str (%r)" % type(data)) + await self._writer.send(data, binary=False, compress=compress) + + async def send_bytes(self, data: bytes, compress: Optional[bool] = None) -> None: + if self._writer is None: + raise RuntimeError("Call .prepare() first") + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError("data argument must be byte-ish (%r)" % type(data)) + await self._writer.send(data, binary=True, compress=compress) + + async def send_json( + self, + data: Any, + compress: Optional[bool] = None, + *, + dumps: JSONEncoder = json.dumps, + ) -> None: + await self.send_str(dumps(data), compress=compress) + + async def write_eof(self) -> None: # type: ignore + if self._eof_sent: + return + if self._payload_writer is None: + raise RuntimeError("Response has not been started") + + await self.close() + self._eof_sent = True + + async def close(self, *, code: int = 1000, message: bytes = b"") -> bool: + if self._writer is None: + raise RuntimeError("Call .prepare() first") + + self._cancel_heartbeat() + reader = self._reader + assert reader is not None + + # we need to break `receive()` cycle first, + # `close()` may be called from different task + if self._waiting is not None and not self._closed: + reader.feed_data(WS_CLOSING_MESSAGE, 0) + await self._waiting + + if not self._closed: + self._closed = True + try: + await self._writer.close(code, message) + writer = self._payload_writer + assert writer is not None + await writer.drain() + except (asyncio.CancelledError, asyncio.TimeoutError): + self._close_code = 1006 + raise + except Exception as exc: + self._close_code = 1006 + self._exception = exc + return True + + if self._closing: + return True + + reader = self._reader + assert reader is not None + try: + with async_timeout.timeout(self._timeout, loop=self._loop): + msg = await reader.read() + except asyncio.CancelledError: + self._close_code = 1006 + raise + except Exception as exc: + self._close_code = 1006 + self._exception = exc + return True + + if msg.type == WSMsgType.CLOSE: + self._close_code = msg.data + return True + + self._close_code = 1006 + self._exception = asyncio.TimeoutError() + return True + else: + return False + + async def receive(self, timeout: Optional[float] = None) -> WSMessage: + if self._reader is None: + raise RuntimeError("Call .prepare() first") + + loop = self._loop + assert loop is not None + while True: + if self._waiting is not None: + raise RuntimeError("Concurrent call to receive() is not allowed") + + if self._closed: + self._conn_lost += 1 + if self._conn_lost >= THRESHOLD_CONNLOST_ACCESS: + raise RuntimeError("WebSocket connection is closed.") + return WS_CLOSED_MESSAGE + elif self._closing: + return WS_CLOSING_MESSAGE + + try: + self._waiting = loop.create_future() + try: + with async_timeout.timeout( + timeout or self._receive_timeout, loop=self._loop + ): + msg = await self._reader.read() + self._reset_heartbeat() + finally: + waiter = self._waiting + set_result(waiter, True) + self._waiting = None + except (asyncio.CancelledError, asyncio.TimeoutError): + self._close_code = 1006 + raise + except EofStream: + self._close_code = 1000 + await self.close() + return WSMessage(WSMsgType.CLOSED, None, None) + except WebSocketError as exc: + self._close_code = exc.code + await self.close(code=exc.code) + return WSMessage(WSMsgType.ERROR, exc, None) + except Exception as exc: + self._exception = exc + self._closing = True + self._close_code = 1006 + await self.close() + return WSMessage(WSMsgType.ERROR, exc, None) + + if msg.type == WSMsgType.CLOSE: + self._closing = True + self._close_code = msg.data + if not self._closed and self._autoclose: + await self.close() + elif msg.type == WSMsgType.CLOSING: + self._closing = True + elif msg.type == WSMsgType.PING and self._autoping: + await self.pong(msg.data) + continue + elif msg.type == WSMsgType.PONG and self._autoping: + continue + + return msg + + async def receive_str(self, *, timeout: Optional[float] = None) -> str: + msg = await self.receive(timeout) + if msg.type != WSMsgType.TEXT: + raise TypeError( + "Received message {}:{!r} is not WSMsgType.TEXT".format( + msg.type, msg.data + ) + ) + return msg.data + + async def receive_bytes(self, *, timeout: Optional[float] = None) -> bytes: + msg = await self.receive(timeout) + if msg.type != WSMsgType.BINARY: + raise TypeError(f"Received message {msg.type}:{msg.data!r} is not bytes") + return msg.data + + async def receive_json( + self, *, loads: JSONDecoder = json.loads, timeout: Optional[float] = None + ) -> Any: + data = await self.receive_str(timeout=timeout) + return loads(data) + + async def write(self, data: bytes) -> None: + raise RuntimeError("Cannot call .write() for websocket") + + def __aiter__(self) -> "WebSocketResponse": + return self + + async def __anext__(self) -> WSMessage: + msg = await self.receive() + if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING, WSMsgType.CLOSED): + raise StopAsyncIteration + return msg + + def _cancel(self, exc: BaseException) -> None: + if self._reader is not None: + self._reader.set_exception(exc) diff --git a/dist/ba_data/python-site-packages/aiohttp/worker.py b/dist/ba_data/python-site-packages/aiohttp/worker.py new file mode 100644 index 0000000..67b244b --- /dev/null +++ b/dist/ba_data/python-site-packages/aiohttp/worker.py @@ -0,0 +1,252 @@ +"""Async gunicorn worker for aiohttp.web""" + +import asyncio +import os +import re +import signal +import sys +from types import FrameType +from typing import Any, Awaitable, Callable, Optional, Union # noqa + +from gunicorn.config import AccessLogFormat as GunicornAccessLogFormat +from gunicorn.workers import base + +from aiohttp import web + +from .helpers import set_result +from .web_app import Application +from .web_log import AccessLogger + +try: + import ssl + + SSLContext = ssl.SSLContext +except ImportError: # pragma: no cover + ssl = None # type: ignore + SSLContext = object # type: ignore + + +__all__ = ("GunicornWebWorker", "GunicornUVLoopWebWorker", "GunicornTokioWebWorker") + + +class GunicornWebWorker(base.Worker): + + DEFAULT_AIOHTTP_LOG_FORMAT = AccessLogger.LOG_FORMAT + DEFAULT_GUNICORN_LOG_FORMAT = GunicornAccessLogFormat.default + + def __init__(self, *args: Any, **kw: Any) -> None: # pragma: no cover + super().__init__(*args, **kw) + + self._task = None # type: Optional[asyncio.Task[None]] + self.exit_code = 0 + self._notify_waiter = None # type: Optional[asyncio.Future[bool]] + + def init_process(self) -> None: + # create new event_loop after fork + asyncio.get_event_loop().close() + + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(self.loop) + + super().init_process() + + def run(self) -> None: + self._task = self.loop.create_task(self._run()) + + try: # ignore all finalization problems + self.loop.run_until_complete(self._task) + except Exception: + self.log.exception("Exception in gunicorn worker") + if sys.version_info >= (3, 6): + self.loop.run_until_complete(self.loop.shutdown_asyncgens()) + self.loop.close() + + sys.exit(self.exit_code) + + async def _run(self) -> None: + if isinstance(self.wsgi, Application): + app = self.wsgi + elif asyncio.iscoroutinefunction(self.wsgi): + app = await self.wsgi() + else: + raise RuntimeError( + "wsgi app should be either Application or " + "async function returning Application, got {}".format(self.wsgi) + ) + access_log = self.log.access_log if self.cfg.accesslog else None + runner = web.AppRunner( + app, + logger=self.log, + keepalive_timeout=self.cfg.keepalive, + access_log=access_log, + access_log_format=self._get_valid_log_format(self.cfg.access_log_format), + ) + await runner.setup() + + ctx = self._create_ssl_context(self.cfg) if self.cfg.is_ssl else None + + runner = runner + assert runner is not None + server = runner.server + assert server is not None + for sock in self.sockets: + site = web.SockSite( + runner, + sock, + ssl_context=ctx, + shutdown_timeout=self.cfg.graceful_timeout / 100 * 95, + ) + await site.start() + + # If our parent changed then we shut down. + pid = os.getpid() + try: + while self.alive: # type: ignore + self.notify() + + cnt = server.requests_count + if self.cfg.max_requests and cnt > self.cfg.max_requests: + self.alive = False + self.log.info("Max requests, shutting down: %s", self) + + elif pid == os.getpid() and self.ppid != os.getppid(): + self.alive = False + self.log.info("Parent changed, shutting down: %s", self) + else: + await self._wait_next_notify() + except BaseException: + pass + + await runner.cleanup() + + def _wait_next_notify(self) -> "asyncio.Future[bool]": + self._notify_waiter_done() + + loop = self.loop + assert loop is not None + self._notify_waiter = waiter = loop.create_future() + self.loop.call_later(1.0, self._notify_waiter_done, waiter) + + return waiter + + def _notify_waiter_done( + self, waiter: Optional["asyncio.Future[bool]"] = None + ) -> None: + if waiter is None: + waiter = self._notify_waiter + if waiter is not None: + set_result(waiter, True) + + if waiter is self._notify_waiter: + self._notify_waiter = None + + def init_signals(self) -> None: + # Set up signals through the event loop API. + + self.loop.add_signal_handler( + signal.SIGQUIT, self.handle_quit, signal.SIGQUIT, None + ) + + self.loop.add_signal_handler( + signal.SIGTERM, self.handle_exit, signal.SIGTERM, None + ) + + self.loop.add_signal_handler( + signal.SIGINT, self.handle_quit, signal.SIGINT, None + ) + + self.loop.add_signal_handler( + signal.SIGWINCH, self.handle_winch, signal.SIGWINCH, None + ) + + self.loop.add_signal_handler( + signal.SIGUSR1, self.handle_usr1, signal.SIGUSR1, None + ) + + self.loop.add_signal_handler( + signal.SIGABRT, self.handle_abort, signal.SIGABRT, None + ) + + # Don't let SIGTERM and SIGUSR1 disturb active requests + # by interrupting system calls + signal.siginterrupt(signal.SIGTERM, False) + signal.siginterrupt(signal.SIGUSR1, False) + + def handle_quit(self, sig: int, frame: FrameType) -> None: + self.alive = False + + # worker_int callback + self.cfg.worker_int(self) + + # wakeup closing process + self._notify_waiter_done() + + def handle_abort(self, sig: int, frame: FrameType) -> None: + self.alive = False + self.exit_code = 1 + self.cfg.worker_abort(self) + sys.exit(1) + + @staticmethod + def _create_ssl_context(cfg: Any) -> "SSLContext": + """Creates SSLContext instance for usage in asyncio.create_server. + + See ssl.SSLSocket.__init__ for more details. + """ + if ssl is None: # pragma: no cover + raise RuntimeError("SSL is not supported.") + + ctx = ssl.SSLContext(cfg.ssl_version) + ctx.load_cert_chain(cfg.certfile, cfg.keyfile) + ctx.verify_mode = cfg.cert_reqs + if cfg.ca_certs: + ctx.load_verify_locations(cfg.ca_certs) + if cfg.ciphers: + ctx.set_ciphers(cfg.ciphers) + return ctx + + def _get_valid_log_format(self, source_format: str) -> str: + if source_format == self.DEFAULT_GUNICORN_LOG_FORMAT: + return self.DEFAULT_AIOHTTP_LOG_FORMAT + elif re.search(r"%\([^\)]+\)", source_format): + raise ValueError( + "Gunicorn's style options in form of `%(name)s` are not " + "supported for the log formatting. Please use aiohttp's " + "format specification to configure access log formatting: " + "http://docs.aiohttp.org/en/stable/logging.html" + "#format-specification" + ) + else: + return source_format + + +class GunicornUVLoopWebWorker(GunicornWebWorker): + def init_process(self) -> None: + import uvloop + + # Close any existing event loop before setting a + # new policy. + asyncio.get_event_loop().close() + + # Setup uvloop policy, so that every + # asyncio.get_event_loop() will create an instance + # of uvloop event loop. + asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) + + super().init_process() + + +class GunicornTokioWebWorker(GunicornWebWorker): + def init_process(self) -> None: # pragma: no cover + import tokio + + # Close any existing event loop before setting a + # new policy. + asyncio.get_event_loop().close() + + # Setup tokio policy, so that every + # asyncio.get_event_loop() will create an instance + # of tokio event loop. + asyncio.set_event_loop_policy(tokio.EventLoopPolicy()) + + super().init_process() diff --git a/dist/ba_data/python-site-packages/async_timeout/__init__.py b/dist/ba_data/python-site-packages/async_timeout/__init__.py new file mode 100644 index 0000000..dcc55f0 --- /dev/null +++ b/dist/ba_data/python-site-packages/async_timeout/__init__.py @@ -0,0 +1,115 @@ +import asyncio +import sys + +from types import TracebackType +from typing import Optional, Type, Any # noqa + + +__version__ = '3.0.1' + +PY_37 = sys.version_info >= (3, 7) + + +class timeout: + """timeout context manager. + + Useful in cases when you want to apply timeout logic around block + of code or in cases when asyncio.wait_for is not suitable. For example: + + >>> with timeout(0.001): + ... async with aiohttp.get('https://github.com') as r: + ... await r.text() + + + timeout - value in seconds or None to disable timeout logic + loop - asyncio compatible event loop + """ + def __init__(self, timeout: Optional[float], + *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: + self._timeout = timeout + if loop is None: + loop = asyncio.get_event_loop() + self._loop = loop + self._task = None # type: Optional[asyncio.Task[Any]] + self._cancelled = False + self._cancel_handler = None # type: Optional[asyncio.Handle] + self._cancel_at = None # type: Optional[float] + + def __enter__(self) -> 'timeout': + return self._do_enter() + + def __exit__(self, + exc_type: Type[BaseException], + exc_val: BaseException, + exc_tb: TracebackType) -> Optional[bool]: + self._do_exit(exc_type) + return None + + async def __aenter__(self) -> 'timeout': + return self._do_enter() + + async def __aexit__(self, + exc_type: Type[BaseException], + exc_val: BaseException, + exc_tb: TracebackType) -> None: + self._do_exit(exc_type) + + @property + def expired(self) -> bool: + return self._cancelled + + @property + def remaining(self) -> Optional[float]: + if self._cancel_at is not None: + return max(self._cancel_at - self._loop.time(), 0.0) + else: + return None + + def _do_enter(self) -> 'timeout': + # Support Tornado 5- without timeout + # Details: https://github.com/python/asyncio/issues/392 + if self._timeout is None: + return self + + self._task = current_task(self._loop) + if self._task is None: + raise RuntimeError('Timeout context manager should be used ' + 'inside a task') + + if self._timeout <= 0: + self._loop.call_soon(self._cancel_task) + return self + + self._cancel_at = self._loop.time() + self._timeout + self._cancel_handler = self._loop.call_at( + self._cancel_at, self._cancel_task) + return self + + def _do_exit(self, exc_type: Type[BaseException]) -> None: + if exc_type is asyncio.CancelledError and self._cancelled: + self._cancel_handler = None + self._task = None + raise asyncio.TimeoutError + if self._timeout is not None and self._cancel_handler is not None: + self._cancel_handler.cancel() + self._cancel_handler = None + self._task = None + return None + + def _cancel_task(self) -> None: + if self._task is not None: + self._task.cancel() + self._cancelled = True + + +def current_task(loop: asyncio.AbstractEventLoop) -> 'asyncio.Task[Any]': + if PY_37: + task = asyncio.current_task(loop=loop) # type: ignore + else: + task = asyncio.Task.current_task(loop=loop) + if task is None: + # this should be removed, tokio must use register_task and family API + if hasattr(loop, 'current_task'): + task = loop.current_task() # type: ignore + + return task diff --git a/dist/ba_data/python-site-packages/async_timeout/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/async_timeout/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d1c9fe4 Binary files /dev/null and b/dist/ba_data/python-site-packages/async_timeout/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/async_timeout/py.typed b/dist/ba_data/python-site-packages/async_timeout/py.typed new file mode 100644 index 0000000..f6e0339 --- /dev/null +++ b/dist/ba_data/python-site-packages/async_timeout/py.typed @@ -0,0 +1 @@ +Placeholder \ No newline at end of file diff --git a/dist/ba_data/python-site-packages/attr/__init__.py b/dist/ba_data/python-site-packages/attr/__init__.py new file mode 100644 index 0000000..b1ce7fe --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/__init__.py @@ -0,0 +1,78 @@ +from __future__ import absolute_import, division, print_function + +import sys + +from functools import partial + +from . import converters, exceptions, filters, setters, validators +from ._cmp import cmp_using +from ._config import get_run_validators, set_run_validators +from ._funcs import asdict, assoc, astuple, evolve, has, resolve_types +from ._make import ( + NOTHING, + Attribute, + Factory, + attrib, + attrs, + fields, + fields_dict, + make_class, + validate, +) +from ._version_info import VersionInfo + + +__version__ = "21.2.0" +__version_info__ = VersionInfo._from_version_string(__version__) + +__title__ = "attrs" +__description__ = "Classes Without Boilerplate" +__url__ = "https://www.attrs.org/" +__uri__ = __url__ +__doc__ = __description__ + " <" + __uri__ + ">" + +__author__ = "Hynek Schlawack" +__email__ = "hs@ox.cx" + +__license__ = "MIT" +__copyright__ = "Copyright (c) 2015 Hynek Schlawack" + + +s = attributes = attrs +ib = attr = attrib +dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) + +__all__ = [ + "Attribute", + "Factory", + "NOTHING", + "asdict", + "assoc", + "astuple", + "attr", + "attrib", + "attributes", + "attrs", + "cmp_using", + "converters", + "evolve", + "exceptions", + "fields", + "fields_dict", + "filters", + "get_run_validators", + "has", + "ib", + "make_class", + "resolve_types", + "s", + "set_run_validators", + "setters", + "validate", + "validators", +] + +if sys.version_info[:2] >= (3, 6): + from ._next_gen import define, field, frozen, mutable + + __all__.extend((define, field, frozen, mutable)) diff --git a/dist/ba_data/python-site-packages/attr/__init__.pyi b/dist/ba_data/python-site-packages/attr/__init__.pyi new file mode 100644 index 0000000..3503b07 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/__init__.pyi @@ -0,0 +1,475 @@ +import sys + +from typing import ( + Any, + Callable, + Dict, + Generic, + List, + Mapping, + Optional, + Sequence, + Tuple, + Type, + TypeVar, + Union, + overload, +) + +# `import X as X` is required to make these public +from . import converters as converters +from . import exceptions as exceptions +from . import filters as filters +from . import setters as setters +from . import validators as validators +from ._version_info import VersionInfo + + +__version__: str +__version_info__: VersionInfo +__title__: str +__description__: str +__url__: str +__uri__: str +__author__: str +__email__: str +__license__: str +__copyright__: str + +_T = TypeVar("_T") +_C = TypeVar("_C", bound=type) + +_EqOrderType = Union[bool, Callable[[Any], Any]] +_ValidatorType = Callable[[Any, Attribute[_T], _T], Any] +_ConverterType = Callable[[Any], Any] +_FilterType = Callable[[Attribute[_T], _T], bool] +_ReprType = Callable[[Any], str] +_ReprArgType = Union[bool, _ReprType] +_OnSetAttrType = Callable[[Any, Attribute[Any], Any], Any] +_OnSetAttrArgType = Union[ + _OnSetAttrType, List[_OnSetAttrType], setters._NoOpType +] +_FieldTransformer = Callable[[type, List[Attribute[Any]]], List[Attribute[Any]]] +# FIXME: in reality, if multiple validators are passed they must be in a list +# or tuple, but those are invariant and so would prevent subtypes of +# _ValidatorType from working when passed in a list or tuple. +_ValidatorArgType = Union[_ValidatorType[_T], Sequence[_ValidatorType[_T]]] + +# _make -- + +NOTHING: object + +# NOTE: Factory lies about its return type to make this possible: +# `x: List[int] # = Factory(list)` +# Work around mypy issue #4554 in the common case by using an overload. +if sys.version_info >= (3, 8): + from typing import Literal + + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Callable[[Any], _T], + takes_self: Literal[True], + ) -> _T: ... + @overload + def Factory( + factory: Callable[[], _T], + takes_self: Literal[False], + ) -> _T: ... +else: + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Union[Callable[[Any], _T], Callable[[], _T]], + takes_self: bool = ..., + ) -> _T: ... + +# Static type inference support via __dataclass_transform__ implemented as per: +# https://github.com/microsoft/pyright/blob/1.1.135/specs/dataclass_transforms.md +# This annotation must be applied to all overloads of "define" and "attrs" +# +# NOTE: This is a typing construct and does not exist at runtime. Extensions +# wrapping attrs decorators should declare a separate __dataclass_transform__ +# signature in the extension module using the specification linked above to +# provide pyright support. +def __dataclass_transform__( + *, + eq_default: bool = True, + order_default: bool = False, + kw_only_default: bool = False, + field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()), +) -> Callable[[_T], _T]: ... + +class Attribute(Generic[_T]): + name: str + default: Optional[_T] + validator: Optional[_ValidatorType[_T]] + repr: _ReprArgType + cmp: _EqOrderType + eq: _EqOrderType + order: _EqOrderType + hash: Optional[bool] + init: bool + converter: Optional[_ConverterType] + metadata: Dict[Any, Any] + type: Optional[Type[_T]] + kw_only: bool + on_setattr: _OnSetAttrType + + def evolve(self, **changes: Any) -> "Attribute[Any]": ... + +# NOTE: We had several choices for the annotation to use for type arg: +# 1) Type[_T] +# - Pros: Handles simple cases correctly +# - Cons: Might produce less informative errors in the case of conflicting +# TypeVars e.g. `attr.ib(default='bad', type=int)` +# 2) Callable[..., _T] +# - Pros: Better error messages than #1 for conflicting TypeVars +# - Cons: Terrible error messages for validator checks. +# e.g. attr.ib(type=int, validator=validate_str) +# -> error: Cannot infer function type argument +# 3) type (and do all of the work in the mypy plugin) +# - Pros: Simple here, and we could customize the plugin with our own errors. +# - Cons: Would need to write mypy plugin code to handle all the cases. +# We chose option #1. + +# `attr` lies about its return type to make the following possible: +# attr() -> Any +# attr(8) -> int +# attr(validator=) -> Whatever the callable expects. +# This makes this type of assignments possible: +# x: int = attr(8) +# +# This form catches explicit None or no default but with no other arguments +# returns Any. +@overload +def attrib( + default: None = ..., + validator: None = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: None = ..., + converter: None = ..., + factory: None = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> Any: ... + +# This form catches an explicit None or no default and infers the type from the +# other arguments. +@overload +def attrib( + default: None = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: Optional[Type[_T]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> _T: ... + +# This form catches an explicit default argument. +@overload +def attrib( + default: _T, + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: Optional[Type[_T]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> _T: ... + +# This form covers type=non-Type: e.g. forward references (str), Any +@overload +def attrib( + default: Optional[_T] = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + type: object = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> Any: ... +@overload +def field( + *, + default: None = ..., + validator: None = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: None = ..., + factory: None = ..., + kw_only: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> Any: ... + +# This form catches an explicit None or no default and infers the type from the +# other arguments. +@overload +def field( + *, + default: None = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> _T: ... + +# This form catches an explicit default argument. +@overload +def field( + *, + default: _T, + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> _T: ... + +# This form covers type=non-Type: e.g. forward references (str), Any +@overload +def field( + *, + default: Optional[_T] = ..., + validator: Optional[_ValidatorArgType[_T]] = ..., + repr: _ReprArgType = ..., + hash: Optional[bool] = ..., + init: bool = ..., + metadata: Optional[Mapping[Any, Any]] = ..., + converter: Optional[_ConverterType] = ..., + factory: Optional[Callable[[], _T]] = ..., + kw_only: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., +) -> Any: ... +@overload +@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) +def attrs( + maybe_cls: _C, + these: Optional[Dict[str, Any]] = ..., + repr_ns: Optional[str] = ..., + repr: bool = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + auto_detect: bool = ..., + collect_by_mro: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., +) -> _C: ... +@overload +@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) +def attrs( + maybe_cls: None = ..., + these: Optional[Dict[str, Any]] = ..., + repr_ns: Optional[str] = ..., + repr: bool = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + auto_detect: bool = ..., + collect_by_mro: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., +) -> Callable[[_C], _C]: ... +@overload +@__dataclass_transform__(field_descriptors=(attrib, field)) +def define( + maybe_cls: _C, + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., +) -> _C: ... +@overload +@__dataclass_transform__(field_descriptors=(attrib, field)) +def define( + maybe_cls: None = ..., + *, + these: Optional[Dict[str, Any]] = ..., + repr: bool = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[bool] = ..., + order: Optional[bool] = ..., + auto_detect: bool = ..., + getstate_setstate: Optional[bool] = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., +) -> Callable[[_C], _C]: ... + +mutable = define +frozen = define # they differ only in their defaults + +# TODO: add support for returning NamedTuple from the mypy plugin +class _Fields(Tuple[Attribute[Any], ...]): + def __getattr__(self, name: str) -> Attribute[Any]: ... + +def fields(cls: type) -> _Fields: ... +def fields_dict(cls: type) -> Dict[str, Attribute[Any]]: ... +def validate(inst: Any) -> None: ... +def resolve_types( + cls: _C, + globalns: Optional[Dict[str, Any]] = ..., + localns: Optional[Dict[str, Any]] = ..., + attribs: Optional[List[Attribute[Any]]] = ..., +) -> _C: ... + +# TODO: add support for returning a proper attrs class from the mypy plugin +# we use Any instead of _CountingAttr so that e.g. `make_class('Foo', +# [attr.ib()])` is valid +def make_class( + name: str, + attrs: Union[List[str], Tuple[str, ...], Dict[str, Any]], + bases: Tuple[type, ...] = ..., + repr_ns: Optional[str] = ..., + repr: bool = ..., + cmp: Optional[_EqOrderType] = ..., + hash: Optional[bool] = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: Optional[_EqOrderType] = ..., + order: Optional[_EqOrderType] = ..., + collect_by_mro: bool = ..., + on_setattr: Optional[_OnSetAttrArgType] = ..., + field_transformer: Optional[_FieldTransformer] = ..., +) -> type: ... + +# _funcs -- + +# TODO: add support for returning TypedDict from the mypy plugin +# FIXME: asdict/astuple do not honor their factory args. Waiting on one of +# these: +# https://github.com/python/mypy/issues/4236 +# https://github.com/python/typing/issues/253 +def asdict( + inst: Any, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + dict_factory: Type[Mapping[Any, Any]] = ..., + retain_collection_types: bool = ..., + value_serializer: Optional[Callable[[type, Attribute[Any], Any], Any]] = ..., +) -> Dict[str, Any]: ... + +# TODO: add support for returning NamedTuple from the mypy plugin +def astuple( + inst: Any, + recurse: bool = ..., + filter: Optional[_FilterType[Any]] = ..., + tuple_factory: Type[Sequence[Any]] = ..., + retain_collection_types: bool = ..., +) -> Tuple[Any, ...]: ... +def has(cls: type) -> bool: ... +def assoc(inst: _T, **changes: Any) -> _T: ... +def evolve(inst: _T, **changes: Any) -> _T: ... + +# _config -- + +def set_run_validators(run: bool) -> None: ... +def get_run_validators() -> bool: ... + +# aliases -- + +s = attributes = attrs +ib = attr = attrib +dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;) diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..7479e3c Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/_cmp.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/_cmp.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9411fe8 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/_cmp.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/_compat.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/_compat.cpython-310.opt-1.pyc new file mode 100644 index 0000000..2e3e6c3 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/_compat.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/_config.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/_config.cpython-310.opt-1.pyc new file mode 100644 index 0000000..06836df Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/_config.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/_funcs.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/_funcs.cpython-310.opt-1.pyc new file mode 100644 index 0000000..5f01e54 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/_funcs.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/_make.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/_make.cpython-310.opt-1.pyc new file mode 100644 index 0000000..a32c506 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/_make.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/_next_gen.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/_next_gen.cpython-310.opt-1.pyc new file mode 100644 index 0000000..b2881d2 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/_next_gen.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/_version_info.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/_version_info.cpython-310.opt-1.pyc new file mode 100644 index 0000000..eb6f226 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/_version_info.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/converters.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/converters.cpython-310.opt-1.pyc new file mode 100644 index 0000000..a7fbd39 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/converters.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/exceptions.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/exceptions.cpython-310.opt-1.pyc new file mode 100644 index 0000000..bfae0c9 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/exceptions.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/filters.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/filters.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9ed61c5 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/filters.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/setters.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/setters.cpython-310.opt-1.pyc new file mode 100644 index 0000000..03fa497 Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/setters.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/__pycache__/validators.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/attr/__pycache__/validators.cpython-310.opt-1.pyc new file mode 100644 index 0000000..e7e793e Binary files /dev/null and b/dist/ba_data/python-site-packages/attr/__pycache__/validators.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/attr/_cmp.py b/dist/ba_data/python-site-packages/attr/_cmp.py new file mode 100644 index 0000000..b747b60 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_cmp.py @@ -0,0 +1,152 @@ +from __future__ import absolute_import, division, print_function + +import functools + +from ._compat import new_class +from ._make import _make_ne + + +_operation_names = {"eq": "==", "lt": "<", "le": "<=", "gt": ">", "ge": ">="} + + +def cmp_using( + eq=None, + lt=None, + le=None, + gt=None, + ge=None, + require_same_type=True, + class_name="Comparable", +): + """ + Create a class that can be passed into `attr.ib`'s ``eq``, ``order``, and + ``cmp`` arguments to customize field comparison. + + The resulting class will have a full set of ordering methods if + at least one of ``{lt, le, gt, ge}`` and ``eq`` are provided. + + :param Optional[callable] eq: `callable` used to evaluate equality + of two objects. + :param Optional[callable] lt: `callable` used to evaluate whether + one object is less than another object. + :param Optional[callable] le: `callable` used to evaluate whether + one object is less than or equal to another object. + :param Optional[callable] gt: `callable` used to evaluate whether + one object is greater than another object. + :param Optional[callable] ge: `callable` used to evaluate whether + one object is greater than or equal to another object. + + :param bool require_same_type: When `True`, equality and ordering methods + will return `NotImplemented` if objects are not of the same type. + + :param Optional[str] class_name: Name of class. Defaults to 'Comparable'. + + See `comparison` for more details. + + .. versionadded:: 21.1.0 + """ + + body = { + "__slots__": ["value"], + "__init__": _make_init(), + "_requirements": [], + "_is_comparable_to": _is_comparable_to, + } + + # Add operations. + num_order_functions = 0 + has_eq_function = False + + if eq is not None: + has_eq_function = True + body["__eq__"] = _make_operator("eq", eq) + body["__ne__"] = _make_ne() + + if lt is not None: + num_order_functions += 1 + body["__lt__"] = _make_operator("lt", lt) + + if le is not None: + num_order_functions += 1 + body["__le__"] = _make_operator("le", le) + + if gt is not None: + num_order_functions += 1 + body["__gt__"] = _make_operator("gt", gt) + + if ge is not None: + num_order_functions += 1 + body["__ge__"] = _make_operator("ge", ge) + + type_ = new_class(class_name, (object,), {}, lambda ns: ns.update(body)) + + # Add same type requirement. + if require_same_type: + type_._requirements.append(_check_same_type) + + # Add total ordering if at least one operation was defined. + if 0 < num_order_functions < 4: + if not has_eq_function: + # functools.total_ordering requires __eq__ to be defined, + # so raise early error here to keep a nice stack. + raise ValueError( + "eq must be define is order to complete ordering from " + "lt, le, gt, ge." + ) + type_ = functools.total_ordering(type_) + + return type_ + + +def _make_init(): + """ + Create __init__ method. + """ + + def __init__(self, value): + """ + Initialize object with *value*. + """ + self.value = value + + return __init__ + + +def _make_operator(name, func): + """ + Create operator method. + """ + + def method(self, other): + if not self._is_comparable_to(other): + return NotImplemented + + result = func(self.value, other.value) + if result is NotImplemented: + return NotImplemented + + return result + + method.__name__ = "__%s__" % (name,) + method.__doc__ = "Return a %s b. Computed by attrs." % ( + _operation_names[name], + ) + + return method + + +def _is_comparable_to(self, other): + """ + Check whether `other` is comparable to `self`. + """ + for func in self._requirements: + if not func(self, other): + return False + return True + + +def _check_same_type(self, other): + """ + Return True if *self* and *other* are of the same type, False otherwise. + """ + return other.value.__class__ is self.value.__class__ diff --git a/dist/ba_data/python-site-packages/attr/_cmp.pyi b/dist/ba_data/python-site-packages/attr/_cmp.pyi new file mode 100644 index 0000000..7093550 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_cmp.pyi @@ -0,0 +1,14 @@ +from typing import Type + +from . import _CompareWithType + + +def cmp_using( + eq: Optional[_CompareWithType], + lt: Optional[_CompareWithType], + le: Optional[_CompareWithType], + gt: Optional[_CompareWithType], + ge: Optional[_CompareWithType], + require_same_type: bool, + class_name: str, +) -> Type: ... diff --git a/dist/ba_data/python-site-packages/attr/_compat.py b/dist/ba_data/python-site-packages/attr/_compat.py new file mode 100644 index 0000000..6939f33 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_compat.py @@ -0,0 +1,242 @@ +from __future__ import absolute_import, division, print_function + +import platform +import sys +import types +import warnings + + +PY2 = sys.version_info[0] == 2 +PYPY = platform.python_implementation() == "PyPy" + + +if PYPY or sys.version_info[:2] >= (3, 6): + ordered_dict = dict +else: + from collections import OrderedDict + + ordered_dict = OrderedDict + + +if PY2: + from collections import Mapping, Sequence + + from UserDict import IterableUserDict + + # We 'bundle' isclass instead of using inspect as importing inspect is + # fairly expensive (order of 10-15 ms for a modern machine in 2016) + def isclass(klass): + return isinstance(klass, (type, types.ClassType)) + + def new_class(name, bases, kwds, exec_body): + """ + A minimal stub of types.new_class that we need for make_class. + """ + ns = {} + exec_body(ns) + + return type(name, bases, ns) + + # TYPE is used in exceptions, repr(int) is different on Python 2 and 3. + TYPE = "type" + + def iteritems(d): + return d.iteritems() + + # Python 2 is bereft of a read-only dict proxy, so we make one! + class ReadOnlyDict(IterableUserDict): + """ + Best-effort read-only dict wrapper. + """ + + def __setitem__(self, key, val): + # We gently pretend we're a Python 3 mappingproxy. + raise TypeError( + "'mappingproxy' object does not support item assignment" + ) + + def update(self, _): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError( + "'mappingproxy' object has no attribute 'update'" + ) + + def __delitem__(self, _): + # We gently pretend we're a Python 3 mappingproxy. + raise TypeError( + "'mappingproxy' object does not support item deletion" + ) + + def clear(self): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError( + "'mappingproxy' object has no attribute 'clear'" + ) + + def pop(self, key, default=None): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError( + "'mappingproxy' object has no attribute 'pop'" + ) + + def popitem(self): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError( + "'mappingproxy' object has no attribute 'popitem'" + ) + + def setdefault(self, key, default=None): + # We gently pretend we're a Python 3 mappingproxy. + raise AttributeError( + "'mappingproxy' object has no attribute 'setdefault'" + ) + + def __repr__(self): + # Override to be identical to the Python 3 version. + return "mappingproxy(" + repr(self.data) + ")" + + def metadata_proxy(d): + res = ReadOnlyDict() + res.data.update(d) # We blocked update, so we have to do it like this. + return res + + def just_warn(*args, **kw): # pragma: no cover + """ + We only warn on Python 3 because we are not aware of any concrete + consequences of not setting the cell on Python 2. + """ + + +else: # Python 3 and later. + from collections.abc import Mapping, Sequence # noqa + + def just_warn(*args, **kw): + """ + We only warn on Python 3 because we are not aware of any concrete + consequences of not setting the cell on Python 2. + """ + warnings.warn( + "Running interpreter doesn't sufficiently support code object " + "introspection. Some features like bare super() or accessing " + "__class__ will not work with slotted classes.", + RuntimeWarning, + stacklevel=2, + ) + + def isclass(klass): + return isinstance(klass, type) + + TYPE = "class" + + def iteritems(d): + return d.items() + + new_class = types.new_class + + def metadata_proxy(d): + return types.MappingProxyType(dict(d)) + + +def make_set_closure_cell(): + """Return a function of two arguments (cell, value) which sets + the value stored in the closure cell `cell` to `value`. + """ + # pypy makes this easy. (It also supports the logic below, but + # why not do the easy/fast thing?) + if PYPY: + + def set_closure_cell(cell, value): + cell.__setstate__((value,)) + + return set_closure_cell + + # Otherwise gotta do it the hard way. + + # Create a function that will set its first cellvar to `value`. + def set_first_cellvar_to(value): + x = value + return + + # This function will be eliminated as dead code, but + # not before its reference to `x` forces `x` to be + # represented as a closure cell rather than a local. + def force_x_to_be_a_cell(): # pragma: no cover + return x + + try: + # Extract the code object and make sure our assumptions about + # the closure behavior are correct. + if PY2: + co = set_first_cellvar_to.func_code + else: + co = set_first_cellvar_to.__code__ + if co.co_cellvars != ("x",) or co.co_freevars != (): + raise AssertionError # pragma: no cover + + # Convert this code object to a code object that sets the + # function's first _freevar_ (not cellvar) to the argument. + if sys.version_info >= (3, 8): + # CPython 3.8+ has an incompatible CodeType signature + # (added a posonlyargcount argument) but also added + # CodeType.replace() to do this without counting parameters. + set_first_freevar_code = co.replace( + co_cellvars=co.co_freevars, co_freevars=co.co_cellvars + ) + else: + args = [co.co_argcount] + if not PY2: + args.append(co.co_kwonlyargcount) + args.extend( + [ + co.co_nlocals, + co.co_stacksize, + co.co_flags, + co.co_code, + co.co_consts, + co.co_names, + co.co_varnames, + co.co_filename, + co.co_name, + co.co_firstlineno, + co.co_lnotab, + # These two arguments are reversed: + co.co_cellvars, + co.co_freevars, + ] + ) + set_first_freevar_code = types.CodeType(*args) + + def set_closure_cell(cell, value): + # Create a function using the set_first_freevar_code, + # whose first closure cell is `cell`. Calling it will + # change the value of that cell. + setter = types.FunctionType( + set_first_freevar_code, {}, "setter", (), (cell,) + ) + # And call it to set the cell. + setter(value) + + # Make sure it works on this interpreter: + def make_func_with_cell(): + x = None + + def func(): + return x # pragma: no cover + + return func + + if PY2: + cell = make_func_with_cell().func_closure[0] + else: + cell = make_func_with_cell().__closure__[0] + set_closure_cell(cell, 100) + if cell.cell_contents != 100: + raise AssertionError # pragma: no cover + + except Exception: + return just_warn + else: + return set_closure_cell + + +set_closure_cell = make_set_closure_cell() diff --git a/dist/ba_data/python-site-packages/attr/_config.py b/dist/ba_data/python-site-packages/attr/_config.py new file mode 100644 index 0000000..8ec9209 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_config.py @@ -0,0 +1,23 @@ +from __future__ import absolute_import, division, print_function + + +__all__ = ["set_run_validators", "get_run_validators"] + +_run_validators = True + + +def set_run_validators(run): + """ + Set whether or not validators are run. By default, they are run. + """ + if not isinstance(run, bool): + raise TypeError("'run' must be bool.") + global _run_validators + _run_validators = run + + +def get_run_validators(): + """ + Return whether or not validators are run. + """ + return _run_validators diff --git a/dist/ba_data/python-site-packages/attr/_funcs.py b/dist/ba_data/python-site-packages/attr/_funcs.py new file mode 100644 index 0000000..fda508c --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_funcs.py @@ -0,0 +1,395 @@ +from __future__ import absolute_import, division, print_function + +import copy + +from ._compat import iteritems +from ._make import NOTHING, _obj_setattr, fields +from .exceptions import AttrsAttributeNotFoundError + + +def asdict( + inst, + recurse=True, + filter=None, + dict_factory=dict, + retain_collection_types=False, + value_serializer=None, +): + """ + Return the ``attrs`` attribute values of *inst* as a dict. + + Optionally recurse into other ``attrs``-decorated classes. + + :param inst: Instance of an ``attrs``-decorated class. + :param bool recurse: Recurse into classes that are also + ``attrs``-decorated. + :param callable filter: A callable whose return code determines whether an + attribute or element is included (``True``) or dropped (``False``). Is + called with the `attr.Attribute` as the first argument and the + value as the second argument. + :param callable dict_factory: A callable to produce dictionaries from. For + example, to produce ordered dictionaries instead of normal Python + dictionaries, pass in ``collections.OrderedDict``. + :param bool retain_collection_types: Do not convert to ``list`` when + encountering an attribute whose type is ``tuple`` or ``set``. Only + meaningful if ``recurse`` is ``True``. + :param Optional[callable] value_serializer: A hook that is called for every + attribute or dict key/value. It receives the current instance, field + and value and must return the (updated) value. The hook is run *after* + the optional *filter* has been applied. + + :rtype: return type of *dict_factory* + + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. versionadded:: 16.0.0 *dict_factory* + .. versionadded:: 16.1.0 *retain_collection_types* + .. versionadded:: 20.3.0 *value_serializer* + """ + attrs = fields(inst.__class__) + rv = dict_factory() + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + + if value_serializer is not None: + v = value_serializer(inst, a, v) + + if recurse is True: + if has(v.__class__): + rv[a.name] = asdict( + v, + True, + filter, + dict_factory, + retain_collection_types, + value_serializer, + ) + elif isinstance(v, (tuple, list, set, frozenset)): + cf = v.__class__ if retain_collection_types is True else list + rv[a.name] = cf( + [ + _asdict_anything( + i, + filter, + dict_factory, + retain_collection_types, + value_serializer, + ) + for i in v + ] + ) + elif isinstance(v, dict): + df = dict_factory + rv[a.name] = df( + ( + _asdict_anything( + kk, + filter, + df, + retain_collection_types, + value_serializer, + ), + _asdict_anything( + vv, + filter, + df, + retain_collection_types, + value_serializer, + ), + ) + for kk, vv in iteritems(v) + ) + else: + rv[a.name] = v + else: + rv[a.name] = v + return rv + + +def _asdict_anything( + val, + filter, + dict_factory, + retain_collection_types, + value_serializer, +): + """ + ``asdict`` only works on attrs instances, this works on anything. + """ + if getattr(val.__class__, "__attrs_attrs__", None) is not None: + # Attrs class. + rv = asdict( + val, + True, + filter, + dict_factory, + retain_collection_types, + value_serializer, + ) + elif isinstance(val, (tuple, list, set, frozenset)): + cf = val.__class__ if retain_collection_types is True else list + rv = cf( + [ + _asdict_anything( + i, + filter, + dict_factory, + retain_collection_types, + value_serializer, + ) + for i in val + ] + ) + elif isinstance(val, dict): + df = dict_factory + rv = df( + ( + _asdict_anything( + kk, filter, df, retain_collection_types, value_serializer + ), + _asdict_anything( + vv, filter, df, retain_collection_types, value_serializer + ), + ) + for kk, vv in iteritems(val) + ) + else: + rv = val + if value_serializer is not None: + rv = value_serializer(None, None, rv) + + return rv + + +def astuple( + inst, + recurse=True, + filter=None, + tuple_factory=tuple, + retain_collection_types=False, +): + """ + Return the ``attrs`` attribute values of *inst* as a tuple. + + Optionally recurse into other ``attrs``-decorated classes. + + :param inst: Instance of an ``attrs``-decorated class. + :param bool recurse: Recurse into classes that are also + ``attrs``-decorated. + :param callable filter: A callable whose return code determines whether an + attribute or element is included (``True``) or dropped (``False``). Is + called with the `attr.Attribute` as the first argument and the + value as the second argument. + :param callable tuple_factory: A callable to produce tuples from. For + example, to produce lists instead of tuples. + :param bool retain_collection_types: Do not convert to ``list`` + or ``dict`` when encountering an attribute which type is + ``tuple``, ``dict`` or ``set``. Only meaningful if ``recurse`` is + ``True``. + + :rtype: return type of *tuple_factory* + + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. versionadded:: 16.2.0 + """ + attrs = fields(inst.__class__) + rv = [] + retain = retain_collection_types # Very long. :/ + for a in attrs: + v = getattr(inst, a.name) + if filter is not None and not filter(a, v): + continue + if recurse is True: + if has(v.__class__): + rv.append( + astuple( + v, + recurse=True, + filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + ) + elif isinstance(v, (tuple, list, set, frozenset)): + cf = v.__class__ if retain is True else list + rv.append( + cf( + [ + astuple( + j, + recurse=True, + filter=filter, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(j.__class__) + else j + for j in v + ] + ) + ) + elif isinstance(v, dict): + df = v.__class__ if retain is True else dict + rv.append( + df( + ( + astuple( + kk, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(kk.__class__) + else kk, + astuple( + vv, + tuple_factory=tuple_factory, + retain_collection_types=retain, + ) + if has(vv.__class__) + else vv, + ) + for kk, vv in iteritems(v) + ) + ) + else: + rv.append(v) + else: + rv.append(v) + + return rv if tuple_factory is list else tuple_factory(rv) + + +def has(cls): + """ + Check whether *cls* is a class with ``attrs`` attributes. + + :param type cls: Class to introspect. + :raise TypeError: If *cls* is not a class. + + :rtype: bool + """ + return getattr(cls, "__attrs_attrs__", None) is not None + + +def assoc(inst, **changes): + """ + Copy *inst* and apply *changes*. + + :param inst: Instance of a class with ``attrs`` attributes. + :param changes: Keyword changes in the new copy. + + :return: A copy of inst with *changes* incorporated. + + :raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't + be found on *cls*. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. deprecated:: 17.1.0 + Use `evolve` instead. + """ + import warnings + + warnings.warn( + "assoc is deprecated and will be removed after 2018/01.", + DeprecationWarning, + stacklevel=2, + ) + new = copy.copy(inst) + attrs = fields(inst.__class__) + for k, v in iteritems(changes): + a = getattr(attrs, k, NOTHING) + if a is NOTHING: + raise AttrsAttributeNotFoundError( + "{k} is not an attrs attribute on {cl}.".format( + k=k, cl=new.__class__ + ) + ) + _obj_setattr(new, k, v) + return new + + +def evolve(inst, **changes): + """ + Create a new instance, based on *inst* with *changes* applied. + + :param inst: Instance of a class with ``attrs`` attributes. + :param changes: Keyword changes in the new copy. + + :return: A copy of inst with *changes* incorporated. + + :raise TypeError: If *attr_name* couldn't be found in the class + ``__init__``. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + .. versionadded:: 17.1.0 + """ + cls = inst.__class__ + attrs = fields(cls) + for a in attrs: + if not a.init: + continue + attr_name = a.name # To deal with private attributes. + init_name = attr_name if attr_name[0] != "_" else attr_name[1:] + if init_name not in changes: + changes[init_name] = getattr(inst, attr_name) + + return cls(**changes) + + +def resolve_types(cls, globalns=None, localns=None, attribs=None): + """ + Resolve any strings and forward annotations in type annotations. + + This is only required if you need concrete types in `Attribute`'s *type* + field. In other words, you don't need to resolve your types if you only + use them for static type checking. + + With no arguments, names will be looked up in the module in which the class + was created. If this is not what you want, e.g. if the name only exists + inside a method, you may pass *globalns* or *localns* to specify other + dictionaries in which to look up these names. See the docs of + `typing.get_type_hints` for more details. + + :param type cls: Class to resolve. + :param Optional[dict] globalns: Dictionary containing global variables. + :param Optional[dict] localns: Dictionary containing local variables. + :param Optional[list] attribs: List of attribs for the given class. + This is necessary when calling from inside a ``field_transformer`` + since *cls* is not an ``attrs`` class yet. + + :raise TypeError: If *cls* is not a class. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class and you didn't pass any attribs. + :raise NameError: If types cannot be resolved because of missing variables. + + :returns: *cls* so you can use this function also as a class decorator. + Please note that you have to apply it **after** `attr.s`. That means + the decorator has to come in the line **before** `attr.s`. + + .. versionadded:: 20.1.0 + .. versionadded:: 21.1.0 *attribs* + + """ + try: + # Since calling get_type_hints is expensive we cache whether we've + # done it already. + cls.__attrs_types_resolved__ + except AttributeError: + import typing + + hints = typing.get_type_hints(cls, globalns=globalns, localns=localns) + for field in fields(cls) if attribs is None else attribs: + if field.name in hints: + # Since fields have been frozen we must work around it. + _obj_setattr(field, "type", hints[field.name]) + cls.__attrs_types_resolved__ = True + + # Return the class so you can use it as a decorator too. + return cls diff --git a/dist/ba_data/python-site-packages/attr/_make.py b/dist/ba_data/python-site-packages/attr/_make.py new file mode 100644 index 0000000..a1912b1 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_make.py @@ -0,0 +1,3052 @@ +from __future__ import absolute_import, division, print_function + +import copy +import inspect +import linecache +import sys +import threading +import uuid +import warnings + +from operator import itemgetter + +from . import _config, setters +from ._compat import ( + PY2, + PYPY, + isclass, + iteritems, + metadata_proxy, + new_class, + ordered_dict, + set_closure_cell, +) +from .exceptions import ( + DefaultAlreadySetError, + FrozenInstanceError, + NotAnAttrsClassError, + PythonTooOldError, + UnannotatedAttributeError, +) + + +if not PY2: + import typing + + +# This is used at least twice, so cache it here. +_obj_setattr = object.__setattr__ +_init_converter_pat = "__attr_converter_%s" +_init_factory_pat = "__attr_factory_{}" +_tuple_property_pat = ( + " {attr_name} = _attrs_property(_attrs_itemgetter({index}))" +) +_classvar_prefixes = ( + "typing.ClassVar", + "t.ClassVar", + "ClassVar", + "typing_extensions.ClassVar", +) +# we don't use a double-underscore prefix because that triggers +# name mangling when trying to create a slot for the field +# (when slots=True) +_hash_cache_field = "_attrs_cached_hash" + +_empty_metadata_singleton = metadata_proxy({}) + +# Unique object for unequivocal getattr() defaults. +_sentinel = object() + + +class _Nothing(object): + """ + Sentinel class to indicate the lack of a value when ``None`` is ambiguous. + + ``_Nothing`` is a singleton. There is only ever one of it. + + .. versionchanged:: 21.1.0 ``bool(NOTHING)`` is now False. + """ + + _singleton = None + + def __new__(cls): + if _Nothing._singleton is None: + _Nothing._singleton = super(_Nothing, cls).__new__(cls) + return _Nothing._singleton + + def __repr__(self): + return "NOTHING" + + def __bool__(self): + return False + + def __len__(self): + return 0 # __bool__ for Python 2 + + +NOTHING = _Nothing() +""" +Sentinel to indicate the lack of a value when ``None`` is ambiguous. +""" + + +class _CacheHashWrapper(int): + """ + An integer subclass that pickles / copies as None + + This is used for non-slots classes with ``cache_hash=True``, to avoid + serializing a potentially (even likely) invalid hash value. Since ``None`` + is the default value for uncalculated hashes, whenever this is copied, + the copy's value for the hash should automatically reset. + + See GH #613 for more details. + """ + + if PY2: + # For some reason `type(None)` isn't callable in Python 2, but we don't + # actually need a constructor for None objects, we just need any + # available function that returns None. + def __reduce__(self, _none_constructor=getattr, _args=(0, "", None)): + return _none_constructor, _args + + else: + + def __reduce__(self, _none_constructor=type(None), _args=()): + return _none_constructor, _args + + +def attrib( + default=NOTHING, + validator=None, + repr=True, + cmp=None, + hash=None, + init=True, + metadata=None, + type=None, + converter=None, + factory=None, + kw_only=False, + eq=None, + order=None, + on_setattr=None, +): + """ + Create a new attribute on a class. + + .. warning:: + + Does *not* do anything unless the class is also decorated with + `attr.s`! + + :param default: A value that is used if an ``attrs``-generated ``__init__`` + is used and no value is passed while instantiating or the attribute is + excluded using ``init=False``. + + If the value is an instance of `Factory`, its callable will be + used to construct a new value (useful for mutable data types like lists + or dicts). + + If a default is not set (or set manually to `attr.NOTHING`), a value + *must* be supplied when instantiating; otherwise a `TypeError` + will be raised. + + The default can also be set using decorator notation as shown below. + + :type default: Any value + + :param callable factory: Syntactic sugar for + ``default=attr.Factory(factory)``. + + :param validator: `callable` that is called by ``attrs``-generated + ``__init__`` methods after the instance has been initialized. They + receive the initialized instance, the `Attribute`, and the + passed value. + + The return value is *not* inspected so the validator has to throw an + exception itself. + + If a `list` is passed, its items are treated as validators and must + all pass. + + Validators can be globally disabled and re-enabled using + `get_run_validators`. + + The validator can also be set using decorator notation as shown below. + + :type validator: `callable` or a `list` of `callable`\\ s. + + :param repr: Include this attribute in the generated ``__repr__`` + method. If ``True``, include the attribute; if ``False``, omit it. By + default, the built-in ``repr()`` function is used. To override how the + attribute value is formatted, pass a ``callable`` that takes a single + value and returns a string. Note that the resulting string is used + as-is, i.e. it will be used directly *instead* of calling ``repr()`` + (the default). + :type repr: a `bool` or a `callable` to use a custom function. + + :param eq: If ``True`` (default), include this attribute in the + generated ``__eq__`` and ``__ne__`` methods that check two instances + for equality. To override how the attribute value is compared, + pass a ``callable`` that takes a single value and returns the value + to be compared. + :type eq: a `bool` or a `callable`. + + :param order: If ``True`` (default), include this attributes in the + generated ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. + To override how the attribute value is ordered, + pass a ``callable`` that takes a single value and returns the value + to be ordered. + :type order: a `bool` or a `callable`. + + :param cmp: Setting *cmp* is equivalent to setting *eq* and *order* to the + same value. Must not be mixed with *eq* or *order*. + :type cmp: a `bool` or a `callable`. + + :param Optional[bool] hash: Include this attribute in the generated + ``__hash__`` method. If ``None`` (default), mirror *eq*'s value. This + is the correct behavior according the Python spec. Setting this value + to anything else than ``None`` is *discouraged*. + :param bool init: Include this attribute in the generated ``__init__`` + method. It is possible to set this to ``False`` and set a default + value. In that case this attributed is unconditionally initialized + with the specified default value or factory. + :param callable converter: `callable` that is called by + ``attrs``-generated ``__init__`` methods to convert attribute's value + to the desired format. It is given the passed-in value, and the + returned value will be used as the new value of the attribute. The + value is converted before being passed to the validator, if any. + :param metadata: An arbitrary mapping, to be used by third-party + components. See `extending_metadata`. + :param type: The type of the attribute. In Python 3.6 or greater, the + preferred method to specify the type is using a variable annotation + (see `PEP 526 `_). + This argument is provided for backward compatibility. + Regardless of the approach used, the type will be stored on + ``Attribute.type``. + + Please note that ``attrs`` doesn't do anything with this metadata by + itself. You can use it as part of your own code or for + `static type checking `. + :param kw_only: Make this attribute keyword-only (Python 3+) + in the generated ``__init__`` (if ``init`` is ``False``, this + parameter is ignored). + :param on_setattr: Allows to overwrite the *on_setattr* setting from + `attr.s`. If left `None`, the *on_setattr* value from `attr.s` is used. + Set to `attr.setters.NO_OP` to run **no** `setattr` hooks for this + attribute -- regardless of the setting in `attr.s`. + :type on_setattr: `callable`, or a list of callables, or `None`, or + `attr.setters.NO_OP` + + .. versionadded:: 15.2.0 *convert* + .. versionadded:: 16.3.0 *metadata* + .. versionchanged:: 17.1.0 *validator* can be a ``list`` now. + .. versionchanged:: 17.1.0 + *hash* is ``None`` and therefore mirrors *eq* by default. + .. versionadded:: 17.3.0 *type* + .. deprecated:: 17.4.0 *convert* + .. versionadded:: 17.4.0 *converter* as a replacement for the deprecated + *convert* to achieve consistency with other noun-based arguments. + .. versionadded:: 18.1.0 + ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``. + .. versionadded:: 18.2.0 *kw_only* + .. versionchanged:: 19.2.0 *convert* keyword argument removed. + .. versionchanged:: 19.2.0 *repr* also accepts a custom callable. + .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. + .. versionadded:: 19.2.0 *eq* and *order* + .. versionadded:: 20.1.0 *on_setattr* + .. versionchanged:: 20.3.0 *kw_only* backported to Python 2 + .. versionchanged:: 21.1.0 + *eq*, *order*, and *cmp* also accept a custom callable + .. versionchanged:: 21.1.0 *cmp* undeprecated + """ + eq, eq_key, order, order_key = _determine_attrib_eq_order( + cmp, eq, order, True + ) + + if hash is not None and hash is not True and hash is not False: + raise TypeError( + "Invalid value for hash. Must be True, False, or None." + ) + + if factory is not None: + if default is not NOTHING: + raise ValueError( + "The `default` and `factory` arguments are mutually " + "exclusive." + ) + if not callable(factory): + raise ValueError("The `factory` argument must be a callable.") + default = Factory(factory) + + if metadata is None: + metadata = {} + + # Apply syntactic sugar by auto-wrapping. + if isinstance(on_setattr, (list, tuple)): + on_setattr = setters.pipe(*on_setattr) + + if validator and isinstance(validator, (list, tuple)): + validator = and_(*validator) + + if converter and isinstance(converter, (list, tuple)): + converter = pipe(*converter) + + return _CountingAttr( + default=default, + validator=validator, + repr=repr, + cmp=None, + hash=hash, + init=init, + converter=converter, + metadata=metadata, + type=type, + kw_only=kw_only, + eq=eq, + eq_key=eq_key, + order=order, + order_key=order_key, + on_setattr=on_setattr, + ) + + +def _compile_and_eval(script, globs, locs=None, filename=""): + """ + "Exec" the script with the given global (globs) and local (locs) variables. + """ + bytecode = compile(script, filename, "exec") + eval(bytecode, globs, locs) + + +def _make_method(name, script, filename, globs=None): + """ + Create the method with the script given and return the method object. + """ + locs = {} + if globs is None: + globs = {} + + _compile_and_eval(script, globs, locs, filename) + + # In order of debuggers like PDB being able to step through the code, + # we add a fake linecache entry. + linecache.cache[filename] = ( + len(script), + None, + script.splitlines(True), + filename, + ) + + return locs[name] + + +def _make_attr_tuple_class(cls_name, attr_names): + """ + Create a tuple subclass to hold `Attribute`s for an `attrs` class. + + The subclass is a bare tuple with properties for names. + + class MyClassAttributes(tuple): + __slots__ = () + x = property(itemgetter(0)) + """ + attr_class_name = "{}Attributes".format(cls_name) + attr_class_template = [ + "class {}(tuple):".format(attr_class_name), + " __slots__ = ()", + ] + if attr_names: + for i, attr_name in enumerate(attr_names): + attr_class_template.append( + _tuple_property_pat.format(index=i, attr_name=attr_name) + ) + else: + attr_class_template.append(" pass") + globs = {"_attrs_itemgetter": itemgetter, "_attrs_property": property} + _compile_and_eval("\n".join(attr_class_template), globs) + return globs[attr_class_name] + + +# Tuple class for extracted attributes from a class definition. +# `base_attrs` is a subset of `attrs`. +_Attributes = _make_attr_tuple_class( + "_Attributes", + [ + # all attributes to build dunder methods for + "attrs", + # attributes that have been inherited + "base_attrs", + # map inherited attributes to their originating classes + "base_attrs_map", + ], +) + + +def _is_class_var(annot): + """ + Check whether *annot* is a typing.ClassVar. + + The string comparison hack is used to avoid evaluating all string + annotations which would put attrs-based classes at a performance + disadvantage compared to plain old classes. + """ + annot = str(annot) + + # Annotation can be quoted. + if annot.startswith(("'", '"')) and annot.endswith(("'", '"')): + annot = annot[1:-1] + + return annot.startswith(_classvar_prefixes) + + +def _has_own_attribute(cls, attrib_name): + """ + Check whether *cls* defines *attrib_name* (and doesn't just inherit it). + + Requires Python 3. + """ + attr = getattr(cls, attrib_name, _sentinel) + if attr is _sentinel: + return False + + for base_cls in cls.__mro__[1:]: + a = getattr(base_cls, attrib_name, None) + if attr is a: + return False + + return True + + +def _get_annotations(cls): + """ + Get annotations for *cls*. + """ + if _has_own_attribute(cls, "__annotations__"): + return cls.__annotations__ + + return {} + + +def _counter_getter(e): + """ + Key function for sorting to avoid re-creating a lambda for every class. + """ + return e[1].counter + + +def _collect_base_attrs(cls, taken_attr_names): + """ + Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. + """ + base_attrs = [] + base_attr_map = {} # A dictionary of base attrs to their classes. + + # Traverse the MRO and collect attributes. + for base_cls in reversed(cls.__mro__[1:-1]): + for a in getattr(base_cls, "__attrs_attrs__", []): + if a.inherited or a.name in taken_attr_names: + continue + + a = a.evolve(inherited=True) + base_attrs.append(a) + base_attr_map[a.name] = base_cls + + # For each name, only keep the freshest definition i.e. the furthest at the + # back. base_attr_map is fine because it gets overwritten with every new + # instance. + filtered = [] + seen = set() + for a in reversed(base_attrs): + if a.name in seen: + continue + filtered.insert(0, a) + seen.add(a.name) + + return filtered, base_attr_map + + +def _collect_base_attrs_broken(cls, taken_attr_names): + """ + Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. + + N.B. *taken_attr_names* will be mutated. + + Adhere to the old incorrect behavior. + + Notably it collects from the front and considers inherited attributes which + leads to the buggy behavior reported in #428. + """ + base_attrs = [] + base_attr_map = {} # A dictionary of base attrs to their classes. + + # Traverse the MRO and collect attributes. + for base_cls in cls.__mro__[1:-1]: + for a in getattr(base_cls, "__attrs_attrs__", []): + if a.name in taken_attr_names: + continue + + a = a.evolve(inherited=True) + taken_attr_names.add(a.name) + base_attrs.append(a) + base_attr_map[a.name] = base_cls + + return base_attrs, base_attr_map + + +def _transform_attrs( + cls, these, auto_attribs, kw_only, collect_by_mro, field_transformer +): + """ + Transform all `_CountingAttr`s on a class into `Attribute`s. + + If *these* is passed, use that and don't look for them on the class. + + *collect_by_mro* is True, collect them in the correct MRO order, otherwise + use the old -- incorrect -- order. See #428. + + Return an `_Attributes`. + """ + cd = cls.__dict__ + anns = _get_annotations(cls) + + if these is not None: + ca_list = [(name, ca) for name, ca in iteritems(these)] + + if not isinstance(these, ordered_dict): + ca_list.sort(key=_counter_getter) + elif auto_attribs is True: + ca_names = { + name + for name, attr in cd.items() + if isinstance(attr, _CountingAttr) + } + ca_list = [] + annot_names = set() + for attr_name, type in anns.items(): + if _is_class_var(type): + continue + annot_names.add(attr_name) + a = cd.get(attr_name, NOTHING) + + if not isinstance(a, _CountingAttr): + if a is NOTHING: + a = attrib() + else: + a = attrib(default=a) + ca_list.append((attr_name, a)) + + unannotated = ca_names - annot_names + if len(unannotated) > 0: + raise UnannotatedAttributeError( + "The following `attr.ib`s lack a type annotation: " + + ", ".join( + sorted(unannotated, key=lambda n: cd.get(n).counter) + ) + + "." + ) + else: + ca_list = sorted( + ( + (name, attr) + for name, attr in cd.items() + if isinstance(attr, _CountingAttr) + ), + key=lambda e: e[1].counter, + ) + + own_attrs = [ + Attribute.from_counting_attr( + name=attr_name, ca=ca, type=anns.get(attr_name) + ) + for attr_name, ca in ca_list + ] + + if collect_by_mro: + base_attrs, base_attr_map = _collect_base_attrs( + cls, {a.name for a in own_attrs} + ) + else: + base_attrs, base_attr_map = _collect_base_attrs_broken( + cls, {a.name for a in own_attrs} + ) + + attr_names = [a.name for a in base_attrs + own_attrs] + + AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names) + + if kw_only: + own_attrs = [a.evolve(kw_only=True) for a in own_attrs] + base_attrs = [a.evolve(kw_only=True) for a in base_attrs] + + attrs = AttrsClass(base_attrs + own_attrs) + + # Mandatory vs non-mandatory attr order only matters when they are part of + # the __init__ signature and when they aren't kw_only (which are moved to + # the end and can be mandatory or non-mandatory in any order, as they will + # be specified as keyword args anyway). Check the order of those attrs: + had_default = False + for a in (a for a in attrs if a.init is not False and a.kw_only is False): + if had_default is True and a.default is NOTHING: + raise ValueError( + "No mandatory attributes allowed after an attribute with a " + "default value or factory. Attribute in question: %r" % (a,) + ) + + if had_default is False and a.default is not NOTHING: + had_default = True + + if field_transformer is not None: + attrs = field_transformer(cls, attrs) + return _Attributes((attrs, base_attrs, base_attr_map)) + + +if PYPY: + + def _frozen_setattrs(self, name, value): + """ + Attached to frozen classes as __setattr__. + """ + if isinstance(self, BaseException) and name in ( + "__cause__", + "__context__", + ): + BaseException.__setattr__(self, name, value) + return + + raise FrozenInstanceError() + + +else: + + def _frozen_setattrs(self, name, value): + """ + Attached to frozen classes as __setattr__. + """ + raise FrozenInstanceError() + + +def _frozen_delattrs(self, name): + """ + Attached to frozen classes as __delattr__. + """ + raise FrozenInstanceError() + + +class _ClassBuilder(object): + """ + Iteratively build *one* class. + """ + + __slots__ = ( + "_attr_names", + "_attrs", + "_base_attr_map", + "_base_names", + "_cache_hash", + "_cls", + "_cls_dict", + "_delete_attribs", + "_frozen", + "_has_pre_init", + "_has_post_init", + "_is_exc", + "_on_setattr", + "_slots", + "_weakref_slot", + "_has_own_setattr", + "_has_custom_setattr", + ) + + def __init__( + self, + cls, + these, + slots, + frozen, + weakref_slot, + getstate_setstate, + auto_attribs, + kw_only, + cache_hash, + is_exc, + collect_by_mro, + on_setattr, + has_custom_setattr, + field_transformer, + ): + attrs, base_attrs, base_map = _transform_attrs( + cls, + these, + auto_attribs, + kw_only, + collect_by_mro, + field_transformer, + ) + + self._cls = cls + self._cls_dict = dict(cls.__dict__) if slots else {} + self._attrs = attrs + self._base_names = set(a.name for a in base_attrs) + self._base_attr_map = base_map + self._attr_names = tuple(a.name for a in attrs) + self._slots = slots + self._frozen = frozen + self._weakref_slot = weakref_slot + self._cache_hash = cache_hash + self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False)) + self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False)) + self._delete_attribs = not bool(these) + self._is_exc = is_exc + self._on_setattr = on_setattr + + self._has_custom_setattr = has_custom_setattr + self._has_own_setattr = False + + self._cls_dict["__attrs_attrs__"] = self._attrs + + if frozen: + self._cls_dict["__setattr__"] = _frozen_setattrs + self._cls_dict["__delattr__"] = _frozen_delattrs + + self._has_own_setattr = True + + if getstate_setstate: + ( + self._cls_dict["__getstate__"], + self._cls_dict["__setstate__"], + ) = self._make_getstate_setstate() + + def __repr__(self): + return "<_ClassBuilder(cls={cls})>".format(cls=self._cls.__name__) + + def build_class(self): + """ + Finalize class based on the accumulated configuration. + + Builder cannot be used after calling this method. + """ + if self._slots is True: + return self._create_slots_class() + else: + return self._patch_original_class() + + def _patch_original_class(self): + """ + Apply accumulated methods and return the class. + """ + cls = self._cls + base_names = self._base_names + + # Clean class of attribute definitions (`attr.ib()`s). + if self._delete_attribs: + for name in self._attr_names: + if ( + name not in base_names + and getattr(cls, name, _sentinel) is not _sentinel + ): + try: + delattr(cls, name) + except AttributeError: + # This can happen if a base class defines a class + # variable and we want to set an attribute with the + # same name by using only a type annotation. + pass + + # Attach our dunder methods. + for name, value in self._cls_dict.items(): + setattr(cls, name, value) + + # If we've inherited an attrs __setattr__ and don't write our own, + # reset it to object's. + if not self._has_own_setattr and getattr( + cls, "__attrs_own_setattr__", False + ): + cls.__attrs_own_setattr__ = False + + if not self._has_custom_setattr: + cls.__setattr__ = object.__setattr__ + + return cls + + def _create_slots_class(self): + """ + Build and return a new class with a `__slots__` attribute. + """ + cd = { + k: v + for k, v in iteritems(self._cls_dict) + if k not in tuple(self._attr_names) + ("__dict__", "__weakref__") + } + + # If our class doesn't have its own implementation of __setattr__ + # (either from the user or by us), check the bases, if one of them has + # an attrs-made __setattr__, that needs to be reset. We don't walk the + # MRO because we only care about our immediate base classes. + # XXX: This can be confused by subclassing a slotted attrs class with + # XXX: a non-attrs class and subclass the resulting class with an attrs + # XXX: class. See `test_slotted_confused` for details. For now that's + # XXX: OK with us. + if not self._has_own_setattr: + cd["__attrs_own_setattr__"] = False + + if not self._has_custom_setattr: + for base_cls in self._cls.__bases__: + if base_cls.__dict__.get("__attrs_own_setattr__", False): + cd["__setattr__"] = object.__setattr__ + break + + # Traverse the MRO to collect existing slots + # and check for an existing __weakref__. + existing_slots = dict() + weakref_inherited = False + for base_cls in self._cls.__mro__[1:-1]: + if base_cls.__dict__.get("__weakref__", None) is not None: + weakref_inherited = True + existing_slots.update( + { + name: getattr(base_cls, name) + for name in getattr(base_cls, "__slots__", []) + } + ) + + base_names = set(self._base_names) + + names = self._attr_names + if ( + self._weakref_slot + and "__weakref__" not in getattr(self._cls, "__slots__", ()) + and "__weakref__" not in names + and not weakref_inherited + ): + names += ("__weakref__",) + + # We only add the names of attributes that aren't inherited. + # Setting __slots__ to inherited attributes wastes memory. + slot_names = [name for name in names if name not in base_names] + # There are slots for attributes from current class + # that are defined in parent classes. + # As their descriptors may be overriden by a child class, + # we collect them here and update the class dict + reused_slots = { + slot: slot_descriptor + for slot, slot_descriptor in iteritems(existing_slots) + if slot in slot_names + } + slot_names = [name for name in slot_names if name not in reused_slots] + cd.update(reused_slots) + if self._cache_hash: + slot_names.append(_hash_cache_field) + cd["__slots__"] = tuple(slot_names) + + qualname = getattr(self._cls, "__qualname__", None) + if qualname is not None: + cd["__qualname__"] = qualname + + # Create new class based on old class and our methods. + cls = type(self._cls)(self._cls.__name__, self._cls.__bases__, cd) + + # The following is a fix for + # https://github.com/python-attrs/attrs/issues/102. On Python 3, + # if a method mentions `__class__` or uses the no-arg super(), the + # compiler will bake a reference to the class in the method itself + # as `method.__closure__`. Since we replace the class with a + # clone, we rewrite these references so it keeps working. + for item in cls.__dict__.values(): + if isinstance(item, (classmethod, staticmethod)): + # Class- and staticmethods hide their functions inside. + # These might need to be rewritten as well. + closure_cells = getattr(item.__func__, "__closure__", None) + elif isinstance(item, property): + # Workaround for property `super()` shortcut (PY3-only). + # There is no universal way for other descriptors. + closure_cells = getattr(item.fget, "__closure__", None) + else: + closure_cells = getattr(item, "__closure__", None) + + if not closure_cells: # Catch None or the empty list. + continue + for cell in closure_cells: + try: + match = cell.cell_contents is self._cls + except ValueError: # ValueError: Cell is empty + pass + else: + if match: + set_closure_cell(cell, cls) + + return cls + + def add_repr(self, ns): + self._cls_dict["__repr__"] = self._add_method_dunders( + _make_repr(self._attrs, ns=ns) + ) + return self + + def add_str(self): + repr = self._cls_dict.get("__repr__") + if repr is None: + raise ValueError( + "__str__ can only be generated if a __repr__ exists." + ) + + def __str__(self): + return self.__repr__() + + self._cls_dict["__str__"] = self._add_method_dunders(__str__) + return self + + def _make_getstate_setstate(self): + """ + Create custom __setstate__ and __getstate__ methods. + """ + # __weakref__ is not writable. + state_attr_names = tuple( + an for an in self._attr_names if an != "__weakref__" + ) + + def slots_getstate(self): + """ + Automatically created by attrs. + """ + return tuple(getattr(self, name) for name in state_attr_names) + + hash_caching_enabled = self._cache_hash + + def slots_setstate(self, state): + """ + Automatically created by attrs. + """ + __bound_setattr = _obj_setattr.__get__(self, Attribute) + for name, value in zip(state_attr_names, state): + __bound_setattr(name, value) + + # The hash code cache is not included when the object is + # serialized, but it still needs to be initialized to None to + # indicate that the first call to __hash__ should be a cache + # miss. + if hash_caching_enabled: + __bound_setattr(_hash_cache_field, None) + + return slots_getstate, slots_setstate + + def make_unhashable(self): + self._cls_dict["__hash__"] = None + return self + + def add_hash(self): + self._cls_dict["__hash__"] = self._add_method_dunders( + _make_hash( + self._cls, + self._attrs, + frozen=self._frozen, + cache_hash=self._cache_hash, + ) + ) + + return self + + def add_init(self): + self._cls_dict["__init__"] = self._add_method_dunders( + _make_init( + self._cls, + self._attrs, + self._has_pre_init, + self._has_post_init, + self._frozen, + self._slots, + self._cache_hash, + self._base_attr_map, + self._is_exc, + self._on_setattr is not None + and self._on_setattr is not setters.NO_OP, + attrs_init=False, + ) + ) + + return self + + def add_attrs_init(self): + self._cls_dict["__attrs_init__"] = self._add_method_dunders( + _make_init( + self._cls, + self._attrs, + self._has_pre_init, + self._has_post_init, + self._frozen, + self._slots, + self._cache_hash, + self._base_attr_map, + self._is_exc, + self._on_setattr is not None + and self._on_setattr is not setters.NO_OP, + attrs_init=True, + ) + ) + + return self + + def add_eq(self): + cd = self._cls_dict + + cd["__eq__"] = self._add_method_dunders( + _make_eq(self._cls, self._attrs) + ) + cd["__ne__"] = self._add_method_dunders(_make_ne()) + + return self + + def add_order(self): + cd = self._cls_dict + + cd["__lt__"], cd["__le__"], cd["__gt__"], cd["__ge__"] = ( + self._add_method_dunders(meth) + for meth in _make_order(self._cls, self._attrs) + ) + + return self + + def add_setattr(self): + if self._frozen: + return self + + sa_attrs = {} + for a in self._attrs: + on_setattr = a.on_setattr or self._on_setattr + if on_setattr and on_setattr is not setters.NO_OP: + sa_attrs[a.name] = a, on_setattr + + if not sa_attrs: + return self + + if self._has_custom_setattr: + # We need to write a __setattr__ but there already is one! + raise ValueError( + "Can't combine custom __setattr__ with on_setattr hooks." + ) + + # docstring comes from _add_method_dunders + def __setattr__(self, name, val): + try: + a, hook = sa_attrs[name] + except KeyError: + nval = val + else: + nval = hook(self, a, val) + + _obj_setattr(self, name, nval) + + self._cls_dict["__attrs_own_setattr__"] = True + self._cls_dict["__setattr__"] = self._add_method_dunders(__setattr__) + self._has_own_setattr = True + + return self + + def _add_method_dunders(self, method): + """ + Add __module__ and __qualname__ to a *method* if possible. + """ + try: + method.__module__ = self._cls.__module__ + except AttributeError: + pass + + try: + method.__qualname__ = ".".join( + (self._cls.__qualname__, method.__name__) + ) + except AttributeError: + pass + + try: + method.__doc__ = "Method generated by attrs for class %s." % ( + self._cls.__qualname__, + ) + except AttributeError: + pass + + return method + + +_CMP_DEPRECATION = ( + "The usage of `cmp` is deprecated and will be removed on or after " + "2021-06-01. Please use `eq` and `order` instead." +) + + +def _determine_attrs_eq_order(cmp, eq, order, default_eq): + """ + Validate the combination of *cmp*, *eq*, and *order*. Derive the effective + values of eq and order. If *eq* is None, set it to *default_eq*. + """ + if cmp is not None and any((eq is not None, order is not None)): + raise ValueError("Don't mix `cmp` with `eq' and `order`.") + + # cmp takes precedence due to bw-compatibility. + if cmp is not None: + return cmp, cmp + + # If left None, equality is set to the specified default and ordering + # mirrors equality. + if eq is None: + eq = default_eq + + if order is None: + order = eq + + if eq is False and order is True: + raise ValueError("`order` can only be True if `eq` is True too.") + + return eq, order + + +def _determine_attrib_eq_order(cmp, eq, order, default_eq): + """ + Validate the combination of *cmp*, *eq*, and *order*. Derive the effective + values of eq and order. If *eq* is None, set it to *default_eq*. + """ + if cmp is not None and any((eq is not None, order is not None)): + raise ValueError("Don't mix `cmp` with `eq' and `order`.") + + def decide_callable_or_boolean(value): + """ + Decide whether a key function is used. + """ + if callable(value): + value, key = True, value + else: + key = None + return value, key + + # cmp takes precedence due to bw-compatibility. + if cmp is not None: + cmp, cmp_key = decide_callable_or_boolean(cmp) + return cmp, cmp_key, cmp, cmp_key + + # If left None, equality is set to the specified default and ordering + # mirrors equality. + if eq is None: + eq, eq_key = default_eq, None + else: + eq, eq_key = decide_callable_or_boolean(eq) + + if order is None: + order, order_key = eq, eq_key + else: + order, order_key = decide_callable_or_boolean(order) + + if eq is False and order is True: + raise ValueError("`order` can only be True if `eq` is True too.") + + return eq, eq_key, order, order_key + + +def _determine_whether_to_implement( + cls, flag, auto_detect, dunders, default=True +): + """ + Check whether we should implement a set of methods for *cls*. + + *flag* is the argument passed into @attr.s like 'init', *auto_detect* the + same as passed into @attr.s and *dunders* is a tuple of attribute names + whose presence signal that the user has implemented it themselves. + + Return *default* if no reason for either for or against is found. + + auto_detect must be False on Python 2. + """ + if flag is True or flag is False: + return flag + + if flag is None and auto_detect is False: + return default + + # Logically, flag is None and auto_detect is True here. + for dunder in dunders: + if _has_own_attribute(cls, dunder): + return False + + return default + + +def attrs( + maybe_cls=None, + these=None, + repr_ns=None, + repr=None, + cmp=None, + hash=None, + init=None, + slots=False, + frozen=False, + weakref_slot=True, + str=False, + auto_attribs=False, + kw_only=False, + cache_hash=False, + auto_exc=False, + eq=None, + order=None, + auto_detect=False, + collect_by_mro=False, + getstate_setstate=None, + on_setattr=None, + field_transformer=None, +): + r""" + A class decorator that adds `dunder + `_\ -methods according to the + specified attributes using `attr.ib` or the *these* argument. + + :param these: A dictionary of name to `attr.ib` mappings. This is + useful to avoid the definition of your attributes within the class body + because you can't (e.g. if you want to add ``__repr__`` methods to + Django models) or don't want to. + + If *these* is not ``None``, ``attrs`` will *not* search the class body + for attributes and will *not* remove any attributes from it. + + If *these* is an ordered dict (`dict` on Python 3.6+, + `collections.OrderedDict` otherwise), the order is deduced from + the order of the attributes inside *these*. Otherwise the order + of the definition of the attributes is used. + + :type these: `dict` of `str` to `attr.ib` + + :param str repr_ns: When using nested classes, there's no way in Python 2 + to automatically detect that. Therefore it's possible to set the + namespace explicitly for a more meaningful ``repr`` output. + :param bool auto_detect: Instead of setting the *init*, *repr*, *eq*, + *order*, and *hash* arguments explicitly, assume they are set to + ``True`` **unless any** of the involved methods for one of the + arguments is implemented in the *current* class (i.e. it is *not* + inherited from some base class). + + So for example by implementing ``__eq__`` on a class yourself, + ``attrs`` will deduce ``eq=False`` and will create *neither* + ``__eq__`` *nor* ``__ne__`` (but Python classes come with a sensible + ``__ne__`` by default, so it *should* be enough to only implement + ``__eq__`` in most cases). + + .. warning:: + + If you prevent ``attrs`` from creating the ordering methods for you + (``order=False``, e.g. by implementing ``__le__``), it becomes + *your* responsibility to make sure its ordering is sound. The best + way is to use the `functools.total_ordering` decorator. + + + Passing ``True`` or ``False`` to *init*, *repr*, *eq*, *order*, + *cmp*, or *hash* overrides whatever *auto_detect* would determine. + + *auto_detect* requires Python 3. Setting it ``True`` on Python 2 raises + a `PythonTooOldError`. + + :param bool repr: Create a ``__repr__`` method with a human readable + representation of ``attrs`` attributes.. + :param bool str: Create a ``__str__`` method that is identical to + ``__repr__``. This is usually not necessary except for + `Exception`\ s. + :param Optional[bool] eq: If ``True`` or ``None`` (default), add ``__eq__`` + and ``__ne__`` methods that check two instances for equality. + + They compare the instances as if they were tuples of their ``attrs`` + attributes if and only if the types of both classes are *identical*! + :param Optional[bool] order: If ``True``, add ``__lt__``, ``__le__``, + ``__gt__``, and ``__ge__`` methods that behave like *eq* above and + allow instances to be ordered. If ``None`` (default) mirror value of + *eq*. + :param Optional[bool] cmp: Setting *cmp* is equivalent to setting *eq* + and *order* to the same value. Must not be mixed with *eq* or *order*. + :param Optional[bool] hash: If ``None`` (default), the ``__hash__`` method + is generated according how *eq* and *frozen* are set. + + 1. If *both* are True, ``attrs`` will generate a ``__hash__`` for you. + 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set to + None, marking it unhashable (which it is). + 3. If *eq* is False, ``__hash__`` will be left untouched meaning the + ``__hash__`` method of the base class will be used (if base class is + ``object``, this means it will fall back to id-based hashing.). + + Although not recommended, you can decide for yourself and force + ``attrs`` to create one (e.g. if the class is immutable even though you + didn't freeze it programmatically) by passing ``True`` or not. Both of + these cases are rather special and should be used carefully. + + See our documentation on `hashing`, Python's documentation on + `object.__hash__`, and the `GitHub issue that led to the default \ + behavior `_ for more + details. + :param bool init: Create a ``__init__`` method that initializes the + ``attrs`` attributes. Leading underscores are stripped for the argument + name. If a ``__attrs_pre_init__`` method exists on the class, it will + be called before the class is initialized. If a ``__attrs_post_init__`` + method exists on the class, it will be called after the class is fully + initialized. + + If ``init`` is ``False``, an ``__attrs_init__`` method will be + injected instead. This allows you to define a custom ``__init__`` + method that can do pre-init work such as ``super().__init__()``, + and then call ``__attrs_init__()`` and ``__attrs_post_init__()``. + :param bool slots: Create a `slotted class ` that's more + memory-efficient. Slotted classes are generally superior to the default + dict classes, but have some gotchas you should know about, so we + encourage you to read the `glossary entry `. + :param bool frozen: Make instances immutable after initialization. If + someone attempts to modify a frozen instance, + `attr.exceptions.FrozenInstanceError` is raised. + + .. note:: + + 1. This is achieved by installing a custom ``__setattr__`` method + on your class, so you can't implement your own. + + 2. True immutability is impossible in Python. + + 3. This *does* have a minor a runtime performance `impact + ` when initializing new instances. In other words: + ``__init__`` is slightly slower with ``frozen=True``. + + 4. If a class is frozen, you cannot modify ``self`` in + ``__attrs_post_init__`` or a self-written ``__init__``. You can + circumvent that limitation by using + ``object.__setattr__(self, "attribute_name", value)``. + + 5. Subclasses of a frozen class are frozen too. + + :param bool weakref_slot: Make instances weak-referenceable. This has no + effect unless ``slots`` is also enabled. + :param bool auto_attribs: If ``True``, collect `PEP 526`_-annotated + attributes (Python 3.6 and later only) from the class body. + + In this case, you **must** annotate every field. If ``attrs`` + encounters a field that is set to an `attr.ib` but lacks a type + annotation, an `attr.exceptions.UnannotatedAttributeError` is + raised. Use ``field_name: typing.Any = attr.ib(...)`` if you don't + want to set a type. + + If you assign a value to those attributes (e.g. ``x: int = 42``), that + value becomes the default value like if it were passed using + ``attr.ib(default=42)``. Passing an instance of `Factory` also + works as expected in most cases (see warning below). + + Attributes annotated as `typing.ClassVar`, and attributes that are + neither annotated nor set to an `attr.ib` are **ignored**. + + .. warning:: + For features that use the attribute name to create decorators (e.g. + `validators `), you still *must* assign `attr.ib` to + them. Otherwise Python will either not find the name or try to use + the default value to call e.g. ``validator`` on it. + + These errors can be quite confusing and probably the most common bug + report on our bug tracker. + + .. _`PEP 526`: https://www.python.org/dev/peps/pep-0526/ + :param bool kw_only: Make all attributes keyword-only (Python 3+) + in the generated ``__init__`` (if ``init`` is ``False``, this + parameter is ignored). + :param bool cache_hash: Ensure that the object's hash code is computed + only once and stored on the object. If this is set to ``True``, + hashing must be either explicitly or implicitly enabled for this + class. If the hash code is cached, avoid any reassignments of + fields involved in hash code computation or mutations of the objects + those fields point to after object creation. If such changes occur, + the behavior of the object's hash code is undefined. + :param bool auto_exc: If the class subclasses `BaseException` + (which implicitly includes any subclass of any exception), the + following happens to behave like a well-behaved Python exceptions + class: + + - the values for *eq*, *order*, and *hash* are ignored and the + instances compare and hash by the instance's ids (N.B. ``attrs`` will + *not* remove existing implementations of ``__hash__`` or the equality + methods. It just won't add own ones.), + - all attributes that are either passed into ``__init__`` or have a + default value are additionally available as a tuple in the ``args`` + attribute, + - the value of *str* is ignored leaving ``__str__`` to base classes. + :param bool collect_by_mro: Setting this to `True` fixes the way ``attrs`` + collects attributes from base classes. The default behavior is + incorrect in certain cases of multiple inheritance. It should be on by + default but is kept off for backward-compatability. + + See issue `#428 `_ for + more details. + + :param Optional[bool] getstate_setstate: + .. note:: + This is usually only interesting for slotted classes and you should + probably just set *auto_detect* to `True`. + + If `True`, ``__getstate__`` and + ``__setstate__`` are generated and attached to the class. This is + necessary for slotted classes to be pickleable. If left `None`, it's + `True` by default for slotted classes and ``False`` for dict classes. + + If *auto_detect* is `True`, and *getstate_setstate* is left `None`, + and **either** ``__getstate__`` or ``__setstate__`` is detected directly + on the class (i.e. not inherited), it is set to `False` (this is usually + what you want). + + :param on_setattr: A callable that is run whenever the user attempts to set + an attribute (either by assignment like ``i.x = 42`` or by using + `setattr` like ``setattr(i, "x", 42)``). It receives the same arguments + as validators: the instance, the attribute that is being modified, and + the new value. + + If no exception is raised, the attribute is set to the return value of + the callable. + + If a list of callables is passed, they're automatically wrapped in an + `attr.setters.pipe`. + + :param Optional[callable] field_transformer: + A function that is called with the original class object and all + fields right before ``attrs`` finalizes the class. You can use + this, e.g., to automatically add converters or validators to + fields based on their types. See `transform-fields` for more details. + + .. versionadded:: 16.0.0 *slots* + .. versionadded:: 16.1.0 *frozen* + .. versionadded:: 16.3.0 *str* + .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``. + .. versionchanged:: 17.1.0 + *hash* supports ``None`` as value which is also the default now. + .. versionadded:: 17.3.0 *auto_attribs* + .. versionchanged:: 18.1.0 + If *these* is passed, no attributes are deleted from the class body. + .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained. + .. versionadded:: 18.2.0 *weakref_slot* + .. deprecated:: 18.2.0 + ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now raise a + `DeprecationWarning` if the classes compared are subclasses of + each other. ``__eq`` and ``__ne__`` never tried to compared subclasses + to each other. + .. versionchanged:: 19.2.0 + ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now do not consider + subclasses comparable anymore. + .. versionadded:: 18.2.0 *kw_only* + .. versionadded:: 18.2.0 *cache_hash* + .. versionadded:: 19.1.0 *auto_exc* + .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. + .. versionadded:: 19.2.0 *eq* and *order* + .. versionadded:: 20.1.0 *auto_detect* + .. versionadded:: 20.1.0 *collect_by_mro* + .. versionadded:: 20.1.0 *getstate_setstate* + .. versionadded:: 20.1.0 *on_setattr* + .. versionadded:: 20.3.0 *field_transformer* + .. versionchanged:: 21.1.0 + ``init=False`` injects ``__attrs_init__`` + .. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__`` + .. versionchanged:: 21.1.0 *cmp* undeprecated + """ + if auto_detect and PY2: + raise PythonTooOldError( + "auto_detect only works on Python 3 and later." + ) + + eq_, order_ = _determine_attrs_eq_order(cmp, eq, order, None) + hash_ = hash # work around the lack of nonlocal + + if isinstance(on_setattr, (list, tuple)): + on_setattr = setters.pipe(*on_setattr) + + def wrap(cls): + + if getattr(cls, "__class__", None) is None: + raise TypeError("attrs only works with new-style classes.") + + is_frozen = frozen or _has_frozen_base_class(cls) + is_exc = auto_exc is True and issubclass(cls, BaseException) + has_own_setattr = auto_detect and _has_own_attribute( + cls, "__setattr__" + ) + + if has_own_setattr and is_frozen: + raise ValueError("Can't freeze a class with a custom __setattr__.") + + builder = _ClassBuilder( + cls, + these, + slots, + is_frozen, + weakref_slot, + _determine_whether_to_implement( + cls, + getstate_setstate, + auto_detect, + ("__getstate__", "__setstate__"), + default=slots, + ), + auto_attribs, + kw_only, + cache_hash, + is_exc, + collect_by_mro, + on_setattr, + has_own_setattr, + field_transformer, + ) + if _determine_whether_to_implement( + cls, repr, auto_detect, ("__repr__",) + ): + builder.add_repr(repr_ns) + if str is True: + builder.add_str() + + eq = _determine_whether_to_implement( + cls, eq_, auto_detect, ("__eq__", "__ne__") + ) + if not is_exc and eq is True: + builder.add_eq() + if not is_exc and _determine_whether_to_implement( + cls, order_, auto_detect, ("__lt__", "__le__", "__gt__", "__ge__") + ): + builder.add_order() + + builder.add_setattr() + + if ( + hash_ is None + and auto_detect is True + and _has_own_attribute(cls, "__hash__") + ): + hash = False + else: + hash = hash_ + if hash is not True and hash is not False and hash is not None: + # Can't use `hash in` because 1 == True for example. + raise TypeError( + "Invalid value for hash. Must be True, False, or None." + ) + elif hash is False or (hash is None and eq is False) or is_exc: + # Don't do anything. Should fall back to __object__'s __hash__ + # which is by id. + if cache_hash: + raise TypeError( + "Invalid value for cache_hash. To use hash caching," + " hashing must be either explicitly or implicitly " + "enabled." + ) + elif hash is True or ( + hash is None and eq is True and is_frozen is True + ): + # Build a __hash__ if told so, or if it's safe. + builder.add_hash() + else: + # Raise TypeError on attempts to hash. + if cache_hash: + raise TypeError( + "Invalid value for cache_hash. To use hash caching," + " hashing must be either explicitly or implicitly " + "enabled." + ) + builder.make_unhashable() + + if _determine_whether_to_implement( + cls, init, auto_detect, ("__init__",) + ): + builder.add_init() + else: + builder.add_attrs_init() + if cache_hash: + raise TypeError( + "Invalid value for cache_hash. To use hash caching," + " init must be True." + ) + + return builder.build_class() + + # maybe_cls's type depends on the usage of the decorator. It's a class + # if it's used as `@attrs` but ``None`` if used as `@attrs()`. + if maybe_cls is None: + return wrap + else: + return wrap(maybe_cls) + + +_attrs = attrs +""" +Internal alias so we can use it in functions that take an argument called +*attrs*. +""" + + +if PY2: + + def _has_frozen_base_class(cls): + """ + Check whether *cls* has a frozen ancestor by looking at its + __setattr__. + """ + return ( + getattr(cls.__setattr__, "__module__", None) + == _frozen_setattrs.__module__ + and cls.__setattr__.__name__ == _frozen_setattrs.__name__ + ) + + +else: + + def _has_frozen_base_class(cls): + """ + Check whether *cls* has a frozen ancestor by looking at its + __setattr__. + """ + return cls.__setattr__ == _frozen_setattrs + + +def _generate_unique_filename(cls, func_name): + """ + Create a "filename" suitable for a function being generated. + """ + unique_id = uuid.uuid4() + extra = "" + count = 1 + + while True: + unique_filename = "".format( + func_name, + cls.__module__, + getattr(cls, "__qualname__", cls.__name__), + extra, + ) + # To handle concurrency we essentially "reserve" our spot in + # the linecache with a dummy line. The caller can then + # set this value correctly. + cache_line = (1, None, (str(unique_id),), unique_filename) + if ( + linecache.cache.setdefault(unique_filename, cache_line) + == cache_line + ): + return unique_filename + + # Looks like this spot is taken. Try again. + count += 1 + extra = "-{0}".format(count) + + +def _make_hash(cls, attrs, frozen, cache_hash): + attrs = tuple( + a for a in attrs if a.hash is True or (a.hash is None and a.eq is True) + ) + + tab = " " + + unique_filename = _generate_unique_filename(cls, "hash") + type_hash = hash(unique_filename) + + hash_def = "def __hash__(self" + hash_func = "hash((" + closing_braces = "))" + if not cache_hash: + hash_def += "):" + else: + if not PY2: + hash_def += ", *" + + hash_def += ( + ", _cache_wrapper=" + + "__import__('attr._make')._make._CacheHashWrapper):" + ) + hash_func = "_cache_wrapper(" + hash_func + closing_braces += ")" + + method_lines = [hash_def] + + def append_hash_computation_lines(prefix, indent): + """ + Generate the code for actually computing the hash code. + Below this will either be returned directly or used to compute + a value which is then cached, depending on the value of cache_hash + """ + + method_lines.extend( + [ + indent + prefix + hash_func, + indent + " %d," % (type_hash,), + ] + ) + + for a in attrs: + method_lines.append(indent + " self.%s," % a.name) + + method_lines.append(indent + " " + closing_braces) + + if cache_hash: + method_lines.append(tab + "if self.%s is None:" % _hash_cache_field) + if frozen: + append_hash_computation_lines( + "object.__setattr__(self, '%s', " % _hash_cache_field, tab * 2 + ) + method_lines.append(tab * 2 + ")") # close __setattr__ + else: + append_hash_computation_lines( + "self.%s = " % _hash_cache_field, tab * 2 + ) + method_lines.append(tab + "return self.%s" % _hash_cache_field) + else: + append_hash_computation_lines("return ", tab) + + script = "\n".join(method_lines) + return _make_method("__hash__", script, unique_filename) + + +def _add_hash(cls, attrs): + """ + Add a hash method to *cls*. + """ + cls.__hash__ = _make_hash(cls, attrs, frozen=False, cache_hash=False) + return cls + + +def _make_ne(): + """ + Create __ne__ method. + """ + + def __ne__(self, other): + """ + Check equality and either forward a NotImplemented or + return the result negated. + """ + result = self.__eq__(other) + if result is NotImplemented: + return NotImplemented + + return not result + + return __ne__ + + +def _make_eq(cls, attrs): + """ + Create __eq__ method for *cls* with *attrs*. + """ + attrs = [a for a in attrs if a.eq] + + unique_filename = _generate_unique_filename(cls, "eq") + lines = [ + "def __eq__(self, other):", + " if other.__class__ is not self.__class__:", + " return NotImplemented", + ] + + # We can't just do a big self.x = other.x and... clause due to + # irregularities like nan == nan is false but (nan,) == (nan,) is true. + globs = {} + if attrs: + lines.append(" return (") + others = [" ) == ("] + for a in attrs: + if a.eq_key: + cmp_name = "_%s_key" % (a.name,) + # Add the key function to the global namespace + # of the evaluated function. + globs[cmp_name] = a.eq_key + lines.append( + " %s(self.%s)," + % ( + cmp_name, + a.name, + ) + ) + others.append( + " %s(other.%s)," + % ( + cmp_name, + a.name, + ) + ) + else: + lines.append(" self.%s," % (a.name,)) + others.append(" other.%s," % (a.name,)) + + lines += others + [" )"] + else: + lines.append(" return True") + + script = "\n".join(lines) + + return _make_method("__eq__", script, unique_filename, globs) + + +def _make_order(cls, attrs): + """ + Create ordering methods for *cls* with *attrs*. + """ + attrs = [a for a in attrs if a.order] + + def attrs_to_tuple(obj): + """ + Save us some typing. + """ + return tuple( + key(value) if key else value + for value, key in ( + (getattr(obj, a.name), a.order_key) for a in attrs + ) + ) + + def __lt__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) < attrs_to_tuple(other) + + return NotImplemented + + def __le__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) <= attrs_to_tuple(other) + + return NotImplemented + + def __gt__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) > attrs_to_tuple(other) + + return NotImplemented + + def __ge__(self, other): + """ + Automatically created by attrs. + """ + if other.__class__ is self.__class__: + return attrs_to_tuple(self) >= attrs_to_tuple(other) + + return NotImplemented + + return __lt__, __le__, __gt__, __ge__ + + +def _add_eq(cls, attrs=None): + """ + Add equality methods to *cls* with *attrs*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__eq__ = _make_eq(cls, attrs) + cls.__ne__ = _make_ne() + + return cls + + +_already_repring = threading.local() + + +def _make_repr(attrs, ns): + """ + Make a repr method that includes relevant *attrs*, adding *ns* to the full + name. + """ + + # Figure out which attributes to include, and which function to use to + # format them. The a.repr value can be either bool or a custom callable. + attr_names_with_reprs = tuple( + (a.name, repr if a.repr is True else a.repr) + for a in attrs + if a.repr is not False + ) + + def __repr__(self): + """ + Automatically created by attrs. + """ + try: + working_set = _already_repring.working_set + except AttributeError: + working_set = set() + _already_repring.working_set = working_set + + if id(self) in working_set: + return "..." + real_cls = self.__class__ + if ns is None: + qualname = getattr(real_cls, "__qualname__", None) + if qualname is not None: + class_name = qualname.rsplit(">.", 1)[-1] + else: + class_name = real_cls.__name__ + else: + class_name = ns + "." + real_cls.__name__ + + # Since 'self' remains on the stack (i.e.: strongly referenced) for the + # duration of this call, it's safe to depend on id(...) stability, and + # not need to track the instance and therefore worry about properties + # like weakref- or hash-ability. + working_set.add(id(self)) + try: + result = [class_name, "("] + first = True + for name, attr_repr in attr_names_with_reprs: + if first: + first = False + else: + result.append(", ") + result.extend( + (name, "=", attr_repr(getattr(self, name, NOTHING))) + ) + return "".join(result) + ")" + finally: + working_set.remove(id(self)) + + return __repr__ + + +def _add_repr(cls, ns=None, attrs=None): + """ + Add a repr method to *cls*. + """ + if attrs is None: + attrs = cls.__attrs_attrs__ + + cls.__repr__ = _make_repr(attrs, ns) + return cls + + +def fields(cls): + """ + Return the tuple of ``attrs`` attributes for a class. + + The tuple also allows accessing the fields by their names (see below for + examples). + + :param type cls: Class to introspect. + + :raise TypeError: If *cls* is not a class. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + :rtype: tuple (with name accessors) of `attr.Attribute` + + .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields + by name. + """ + if not isclass(cls): + raise TypeError("Passed object must be a class.") + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is None: + raise NotAnAttrsClassError( + "{cls!r} is not an attrs-decorated class.".format(cls=cls) + ) + return attrs + + +def fields_dict(cls): + """ + Return an ordered dictionary of ``attrs`` attributes for a class, whose + keys are the attribute names. + + :param type cls: Class to introspect. + + :raise TypeError: If *cls* is not a class. + :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` + class. + + :rtype: an ordered dict where keys are attribute names and values are + `attr.Attribute`\\ s. This will be a `dict` if it's + naturally ordered like on Python 3.6+ or an + :class:`~collections.OrderedDict` otherwise. + + .. versionadded:: 18.1.0 + """ + if not isclass(cls): + raise TypeError("Passed object must be a class.") + attrs = getattr(cls, "__attrs_attrs__", None) + if attrs is None: + raise NotAnAttrsClassError( + "{cls!r} is not an attrs-decorated class.".format(cls=cls) + ) + return ordered_dict(((a.name, a) for a in attrs)) + + +def validate(inst): + """ + Validate all attributes on *inst* that have a validator. + + Leaves all exceptions through. + + :param inst: Instance of a class with ``attrs`` attributes. + """ + if _config._run_validators is False: + return + + for a in fields(inst.__class__): + v = a.validator + if v is not None: + v(inst, a, getattr(inst, a.name)) + + +def _is_slot_cls(cls): + return "__slots__" in cls.__dict__ + + +def _is_slot_attr(a_name, base_attr_map): + """ + Check if the attribute name comes from a slot class. + """ + return a_name in base_attr_map and _is_slot_cls(base_attr_map[a_name]) + + +def _make_init( + cls, + attrs, + pre_init, + post_init, + frozen, + slots, + cache_hash, + base_attr_map, + is_exc, + has_global_on_setattr, + attrs_init, +): + if frozen and has_global_on_setattr: + raise ValueError("Frozen classes can't use on_setattr.") + + needs_cached_setattr = cache_hash or frozen + filtered_attrs = [] + attr_dict = {} + for a in attrs: + if not a.init and a.default is NOTHING: + continue + + filtered_attrs.append(a) + attr_dict[a.name] = a + + if a.on_setattr is not None: + if frozen is True: + raise ValueError("Frozen classes can't use on_setattr.") + + needs_cached_setattr = True + elif ( + has_global_on_setattr and a.on_setattr is not setters.NO_OP + ) or _is_slot_attr(a.name, base_attr_map): + needs_cached_setattr = True + + unique_filename = _generate_unique_filename(cls, "init") + + script, globs, annotations = _attrs_to_init_script( + filtered_attrs, + frozen, + slots, + pre_init, + post_init, + cache_hash, + base_attr_map, + is_exc, + needs_cached_setattr, + has_global_on_setattr, + attrs_init, + ) + if cls.__module__ in sys.modules: + # This makes typing.get_type_hints(CLS.__init__) resolve string types. + globs.update(sys.modules[cls.__module__].__dict__) + + globs.update({"NOTHING": NOTHING, "attr_dict": attr_dict}) + + if needs_cached_setattr: + # Save the lookup overhead in __init__ if we need to circumvent + # setattr hooks. + globs["_cached_setattr"] = _obj_setattr + + init = _make_method( + "__attrs_init__" if attrs_init else "__init__", + script, + unique_filename, + globs, + ) + init.__annotations__ = annotations + + return init + + +def _setattr(attr_name, value_var, has_on_setattr): + """ + Use the cached object.setattr to set *attr_name* to *value_var*. + """ + return "_setattr('%s', %s)" % (attr_name, value_var) + + +def _setattr_with_converter(attr_name, value_var, has_on_setattr): + """ + Use the cached object.setattr to set *attr_name* to *value_var*, but run + its converter first. + """ + return "_setattr('%s', %s(%s))" % ( + attr_name, + _init_converter_pat % (attr_name,), + value_var, + ) + + +def _assign(attr_name, value, has_on_setattr): + """ + Unless *attr_name* has an on_setattr hook, use normal assignment. Otherwise + relegate to _setattr. + """ + if has_on_setattr: + return _setattr(attr_name, value, True) + + return "self.%s = %s" % (attr_name, value) + + +def _assign_with_converter(attr_name, value_var, has_on_setattr): + """ + Unless *attr_name* has an on_setattr hook, use normal assignment after + conversion. Otherwise relegate to _setattr_with_converter. + """ + if has_on_setattr: + return _setattr_with_converter(attr_name, value_var, True) + + return "self.%s = %s(%s)" % ( + attr_name, + _init_converter_pat % (attr_name,), + value_var, + ) + + +if PY2: + + def _unpack_kw_only_py2(attr_name, default=None): + """ + Unpack *attr_name* from _kw_only dict. + """ + if default is not None: + arg_default = ", %s" % default + else: + arg_default = "" + return "%s = _kw_only.pop('%s'%s)" % ( + attr_name, + attr_name, + arg_default, + ) + + def _unpack_kw_only_lines_py2(kw_only_args): + """ + Unpack all *kw_only_args* from _kw_only dict and handle errors. + + Given a list of strings "{attr_name}" and "{attr_name}={default}" + generates list of lines of code that pop attrs from _kw_only dict and + raise TypeError similar to builtin if required attr is missing or + extra key is passed. + + >>> print("\n".join(_unpack_kw_only_lines_py2(["a", "b=42"]))) + try: + a = _kw_only.pop('a') + b = _kw_only.pop('b', 42) + except KeyError as _key_error: + raise TypeError( + ... + if _kw_only: + raise TypeError( + ... + """ + lines = ["try:"] + lines.extend( + " " + _unpack_kw_only_py2(*arg.split("=")) + for arg in kw_only_args + ) + lines += """\ +except KeyError as _key_error: + raise TypeError( + '__init__() missing required keyword-only argument: %s' % _key_error + ) +if _kw_only: + raise TypeError( + '__init__() got an unexpected keyword argument %r' + % next(iter(_kw_only)) + ) +""".split( + "\n" + ) + return lines + + +def _attrs_to_init_script( + attrs, + frozen, + slots, + pre_init, + post_init, + cache_hash, + base_attr_map, + is_exc, + needs_cached_setattr, + has_global_on_setattr, + attrs_init, +): + """ + Return a script of an initializer for *attrs* and a dict of globals. + + The globals are expected by the generated script. + + If *frozen* is True, we cannot set the attributes directly so we use + a cached ``object.__setattr__``. + """ + lines = [] + if pre_init: + lines.append("self.__attrs_pre_init__()") + + if needs_cached_setattr: + lines.append( + # Circumvent the __setattr__ descriptor to save one lookup per + # assignment. + # Note _setattr will be used again below if cache_hash is True + "_setattr = _cached_setattr.__get__(self, self.__class__)" + ) + + if frozen is True: + if slots is True: + fmt_setter = _setattr + fmt_setter_with_converter = _setattr_with_converter + else: + # Dict frozen classes assign directly to __dict__. + # But only if the attribute doesn't come from an ancestor slot + # class. + # Note _inst_dict will be used again below if cache_hash is True + lines.append("_inst_dict = self.__dict__") + + def fmt_setter(attr_name, value_var, has_on_setattr): + if _is_slot_attr(attr_name, base_attr_map): + return _setattr(attr_name, value_var, has_on_setattr) + + return "_inst_dict['%s'] = %s" % (attr_name, value_var) + + def fmt_setter_with_converter( + attr_name, value_var, has_on_setattr + ): + if has_on_setattr or _is_slot_attr(attr_name, base_attr_map): + return _setattr_with_converter( + attr_name, value_var, has_on_setattr + ) + + return "_inst_dict['%s'] = %s(%s)" % ( + attr_name, + _init_converter_pat % (attr_name,), + value_var, + ) + + else: + # Not frozen. + fmt_setter = _assign + fmt_setter_with_converter = _assign_with_converter + + args = [] + kw_only_args = [] + attrs_to_validate = [] + + # This is a dictionary of names to validator and converter callables. + # Injecting this into __init__ globals lets us avoid lookups. + names_for_globals = {} + annotations = {"return": None} + + for a in attrs: + if a.validator: + attrs_to_validate.append(a) + + attr_name = a.name + has_on_setattr = a.on_setattr is not None or ( + a.on_setattr is not setters.NO_OP and has_global_on_setattr + ) + arg_name = a.name.lstrip("_") + + has_factory = isinstance(a.default, Factory) + if has_factory and a.default.takes_self: + maybe_self = "self" + else: + maybe_self = "" + + if a.init is False: + if has_factory: + init_factory_name = _init_factory_pat.format(a.name) + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, + init_factory_name + "(%s)" % (maybe_self,), + has_on_setattr, + ) + ) + conv_name = _init_converter_pat % (a.name,) + names_for_globals[conv_name] = a.converter + else: + lines.append( + fmt_setter( + attr_name, + init_factory_name + "(%s)" % (maybe_self,), + has_on_setattr, + ) + ) + names_for_globals[init_factory_name] = a.default.factory + else: + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, + "attr_dict['%s'].default" % (attr_name,), + has_on_setattr, + ) + ) + conv_name = _init_converter_pat % (a.name,) + names_for_globals[conv_name] = a.converter + else: + lines.append( + fmt_setter( + attr_name, + "attr_dict['%s'].default" % (attr_name,), + has_on_setattr, + ) + ) + elif a.default is not NOTHING and not has_factory: + arg = "%s=attr_dict['%s'].default" % (arg_name, attr_name) + if a.kw_only: + kw_only_args.append(arg) + else: + args.append(arg) + + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr + ) + ) + names_for_globals[ + _init_converter_pat % (a.name,) + ] = a.converter + else: + lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) + + elif has_factory: + arg = "%s=NOTHING" % (arg_name,) + if a.kw_only: + kw_only_args.append(arg) + else: + args.append(arg) + lines.append("if %s is not NOTHING:" % (arg_name,)) + + init_factory_name = _init_factory_pat.format(a.name) + if a.converter is not None: + lines.append( + " " + + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr + ) + ) + lines.append("else:") + lines.append( + " " + + fmt_setter_with_converter( + attr_name, + init_factory_name + "(" + maybe_self + ")", + has_on_setattr, + ) + ) + names_for_globals[ + _init_converter_pat % (a.name,) + ] = a.converter + else: + lines.append( + " " + fmt_setter(attr_name, arg_name, has_on_setattr) + ) + lines.append("else:") + lines.append( + " " + + fmt_setter( + attr_name, + init_factory_name + "(" + maybe_self + ")", + has_on_setattr, + ) + ) + names_for_globals[init_factory_name] = a.default.factory + else: + if a.kw_only: + kw_only_args.append(arg_name) + else: + args.append(arg_name) + + if a.converter is not None: + lines.append( + fmt_setter_with_converter( + attr_name, arg_name, has_on_setattr + ) + ) + names_for_globals[ + _init_converter_pat % (a.name,) + ] = a.converter + else: + lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) + + if a.init is True: + if a.type is not None and a.converter is None: + annotations[arg_name] = a.type + elif a.converter is not None and not PY2: + # Try to get the type from the converter. + sig = None + try: + sig = inspect.signature(a.converter) + except (ValueError, TypeError): # inspect failed + pass + if sig: + sig_params = list(sig.parameters.values()) + if ( + sig_params + and sig_params[0].annotation + is not inspect.Parameter.empty + ): + annotations[arg_name] = sig_params[0].annotation + + if attrs_to_validate: # we can skip this if there are no validators. + names_for_globals["_config"] = _config + lines.append("if _config._run_validators is True:") + for a in attrs_to_validate: + val_name = "__attr_validator_" + a.name + attr_name = "__attr_" + a.name + lines.append( + " %s(self, %s, self.%s)" % (val_name, attr_name, a.name) + ) + names_for_globals[val_name] = a.validator + names_for_globals[attr_name] = a + + if post_init: + lines.append("self.__attrs_post_init__()") + + # because this is set only after __attrs_post_init is called, a crash + # will result if post-init tries to access the hash code. This seemed + # preferable to setting this beforehand, in which case alteration to + # field values during post-init combined with post-init accessing the + # hash code would result in silent bugs. + if cache_hash: + if frozen: + if slots: + # if frozen and slots, then _setattr defined above + init_hash_cache = "_setattr('%s', %s)" + else: + # if frozen and not slots, then _inst_dict defined above + init_hash_cache = "_inst_dict['%s'] = %s" + else: + init_hash_cache = "self.%s = %s" + lines.append(init_hash_cache % (_hash_cache_field, "None")) + + # For exceptions we rely on BaseException.__init__ for proper + # initialization. + if is_exc: + vals = ",".join("self." + a.name for a in attrs if a.init) + + lines.append("BaseException.__init__(self, %s)" % (vals,)) + + args = ", ".join(args) + if kw_only_args: + if PY2: + lines = _unpack_kw_only_lines_py2(kw_only_args) + lines + + args += "%s**_kw_only" % (", " if args else "",) # leading comma + else: + args += "%s*, %s" % ( + ", " if args else "", # leading comma + ", ".join(kw_only_args), # kw_only args + ) + return ( + """\ +def {init_name}(self, {args}): + {lines} +""".format( + init_name=("__attrs_init__" if attrs_init else "__init__"), + args=args, + lines="\n ".join(lines) if lines else "pass", + ), + names_for_globals, + annotations, + ) + + +class Attribute(object): + """ + *Read-only* representation of an attribute. + + Instances of this class are frequently used for introspection purposes + like: + + - `fields` returns a tuple of them. + - Validators get them passed as the first argument. + - The *field transformer* hook receives a list of them. + + :attribute name: The name of the attribute. + :attribute inherited: Whether or not that attribute has been inherited from + a base class. + + Plus *all* arguments of `attr.ib` (except for ``factory`` + which is only syntactic sugar for ``default=Factory(...)``. + + .. versionadded:: 20.1.0 *inherited* + .. versionadded:: 20.1.0 *on_setattr* + .. versionchanged:: 20.2.0 *inherited* is not taken into account for + equality checks and hashing anymore. + .. versionadded:: 21.1.0 *eq_key* and *order_key* + + For the full version history of the fields, see `attr.ib`. + """ + + __slots__ = ( + "name", + "default", + "validator", + "repr", + "eq", + "eq_key", + "order", + "order_key", + "hash", + "init", + "metadata", + "type", + "converter", + "kw_only", + "inherited", + "on_setattr", + ) + + def __init__( + self, + name, + default, + validator, + repr, + cmp, # XXX: unused, remove along with other cmp code. + hash, + init, + inherited, + metadata=None, + type=None, + converter=None, + kw_only=False, + eq=None, + eq_key=None, + order=None, + order_key=None, + on_setattr=None, + ): + eq, eq_key, order, order_key = _determine_attrib_eq_order( + cmp, eq_key or eq, order_key or order, True + ) + + # Cache this descriptor here to speed things up later. + bound_setattr = _obj_setattr.__get__(self, Attribute) + + # Despite the big red warning, people *do* instantiate `Attribute` + # themselves. + bound_setattr("name", name) + bound_setattr("default", default) + bound_setattr("validator", validator) + bound_setattr("repr", repr) + bound_setattr("eq", eq) + bound_setattr("eq_key", eq_key) + bound_setattr("order", order) + bound_setattr("order_key", order_key) + bound_setattr("hash", hash) + bound_setattr("init", init) + bound_setattr("converter", converter) + bound_setattr( + "metadata", + ( + metadata_proxy(metadata) + if metadata + else _empty_metadata_singleton + ), + ) + bound_setattr("type", type) + bound_setattr("kw_only", kw_only) + bound_setattr("inherited", inherited) + bound_setattr("on_setattr", on_setattr) + + def __setattr__(self, name, value): + raise FrozenInstanceError() + + @classmethod + def from_counting_attr(cls, name, ca, type=None): + # type holds the annotated value. deal with conflicts: + if type is None: + type = ca.type + elif ca.type is not None: + raise ValueError( + "Type annotation and type argument cannot both be present" + ) + inst_dict = { + k: getattr(ca, k) + for k in Attribute.__slots__ + if k + not in ( + "name", + "validator", + "default", + "type", + "inherited", + ) # exclude methods and deprecated alias + } + return cls( + name=name, + validator=ca._validator, + default=ca._default, + type=type, + cmp=None, + inherited=False, + **inst_dict + ) + + @property + def cmp(self): + """ + Simulate the presence of a cmp attribute and warn. + """ + warnings.warn(_CMP_DEPRECATION, DeprecationWarning, stacklevel=2) + + return self.eq and self.order + + # Don't use attr.evolve since fields(Attribute) doesn't work + def evolve(self, **changes): + """ + Copy *self* and apply *changes*. + + This works similarly to `attr.evolve` but that function does not work + with ``Attribute``. + + It is mainly meant to be used for `transform-fields`. + + .. versionadded:: 20.3.0 + """ + new = copy.copy(self) + + new._setattrs(changes.items()) + + return new + + # Don't use _add_pickle since fields(Attribute) doesn't work + def __getstate__(self): + """ + Play nice with pickle. + """ + return tuple( + getattr(self, name) if name != "metadata" else dict(self.metadata) + for name in self.__slots__ + ) + + def __setstate__(self, state): + """ + Play nice with pickle. + """ + self._setattrs(zip(self.__slots__, state)) + + def _setattrs(self, name_values_pairs): + bound_setattr = _obj_setattr.__get__(self, Attribute) + for name, value in name_values_pairs: + if name != "metadata": + bound_setattr(name, value) + else: + bound_setattr( + name, + metadata_proxy(value) + if value + else _empty_metadata_singleton, + ) + + +_a = [ + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + eq=True, + order=False, + hash=(name != "metadata"), + init=True, + inherited=False, + ) + for name in Attribute.__slots__ +] + +Attribute = _add_hash( + _add_eq( + _add_repr(Attribute, attrs=_a), + attrs=[a for a in _a if a.name != "inherited"], + ), + attrs=[a for a in _a if a.hash and a.name != "inherited"], +) + + +class _CountingAttr(object): + """ + Intermediate representation of attributes that uses a counter to preserve + the order in which the attributes have been defined. + + *Internal* data structure of the attrs library. Running into is most + likely the result of a bug like a forgotten `@attr.s` decorator. + """ + + __slots__ = ( + "counter", + "_default", + "repr", + "eq", + "eq_key", + "order", + "order_key", + "hash", + "init", + "metadata", + "_validator", + "converter", + "type", + "kw_only", + "on_setattr", + ) + __attrs_attrs__ = tuple( + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + hash=True, + init=True, + kw_only=False, + eq=True, + eq_key=None, + order=False, + order_key=None, + inherited=False, + on_setattr=None, + ) + for name in ( + "counter", + "_default", + "repr", + "eq", + "order", + "hash", + "init", + "on_setattr", + ) + ) + ( + Attribute( + name="metadata", + default=None, + validator=None, + repr=True, + cmp=None, + hash=False, + init=True, + kw_only=False, + eq=True, + eq_key=None, + order=False, + order_key=None, + inherited=False, + on_setattr=None, + ), + ) + cls_counter = 0 + + def __init__( + self, + default, + validator, + repr, + cmp, + hash, + init, + converter, + metadata, + type, + kw_only, + eq, + eq_key, + order, + order_key, + on_setattr, + ): + _CountingAttr.cls_counter += 1 + self.counter = _CountingAttr.cls_counter + self._default = default + self._validator = validator + self.converter = converter + self.repr = repr + self.eq = eq + self.eq_key = eq_key + self.order = order + self.order_key = order_key + self.hash = hash + self.init = init + self.metadata = metadata + self.type = type + self.kw_only = kw_only + self.on_setattr = on_setattr + + def validator(self, meth): + """ + Decorator that adds *meth* to the list of validators. + + Returns *meth* unchanged. + + .. versionadded:: 17.1.0 + """ + if self._validator is None: + self._validator = meth + else: + self._validator = and_(self._validator, meth) + return meth + + def default(self, meth): + """ + Decorator that allows to set the default for an attribute. + + Returns *meth* unchanged. + + :raises DefaultAlreadySetError: If default has been set before. + + .. versionadded:: 17.1.0 + """ + if self._default is not NOTHING: + raise DefaultAlreadySetError() + + self._default = Factory(meth, takes_self=True) + + return meth + + +_CountingAttr = _add_eq(_add_repr(_CountingAttr)) + + +class Factory(object): + """ + Stores a factory callable. + + If passed as the default value to `attr.ib`, the factory is used to + generate a new value. + + :param callable factory: A callable that takes either none or exactly one + mandatory positional argument depending on *takes_self*. + :param bool takes_self: Pass the partially initialized instance that is + being initialized as a positional argument. + + .. versionadded:: 17.1.0 *takes_self* + """ + + __slots__ = ("factory", "takes_self") + + def __init__(self, factory, takes_self=False): + """ + `Factory` is part of the default machinery so if we want a default + value here, we have to implement it ourselves. + """ + self.factory = factory + self.takes_self = takes_self + + def __getstate__(self): + """ + Play nice with pickle. + """ + return tuple(getattr(self, name) for name in self.__slots__) + + def __setstate__(self, state): + """ + Play nice with pickle. + """ + for name, value in zip(self.__slots__, state): + setattr(self, name, value) + + +_f = [ + Attribute( + name=name, + default=NOTHING, + validator=None, + repr=True, + cmp=None, + eq=True, + order=False, + hash=True, + init=True, + inherited=False, + ) + for name in Factory.__slots__ +] + +Factory = _add_hash(_add_eq(_add_repr(Factory, attrs=_f), attrs=_f), attrs=_f) + + +def make_class(name, attrs, bases=(object,), **attributes_arguments): + """ + A quick way to create a new class called *name* with *attrs*. + + :param str name: The name for the new class. + + :param attrs: A list of names or a dictionary of mappings of names to + attributes. + + If *attrs* is a list or an ordered dict (`dict` on Python 3.6+, + `collections.OrderedDict` otherwise), the order is deduced from + the order of the names or attributes inside *attrs*. Otherwise the + order of the definition of the attributes is used. + :type attrs: `list` or `dict` + + :param tuple bases: Classes that the new class will subclass. + + :param attributes_arguments: Passed unmodified to `attr.s`. + + :return: A new class with *attrs*. + :rtype: type + + .. versionadded:: 17.1.0 *bases* + .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained. + """ + if isinstance(attrs, dict): + cls_dict = attrs + elif isinstance(attrs, (list, tuple)): + cls_dict = dict((a, attrib()) for a in attrs) + else: + raise TypeError("attrs argument must be a dict or a list.") + + pre_init = cls_dict.pop("__attrs_pre_init__", None) + post_init = cls_dict.pop("__attrs_post_init__", None) + user_init = cls_dict.pop("__init__", None) + + body = {} + if pre_init is not None: + body["__attrs_pre_init__"] = pre_init + if post_init is not None: + body["__attrs_post_init__"] = post_init + if user_init is not None: + body["__init__"] = user_init + + type_ = new_class(name, bases, {}, lambda ns: ns.update(body)) + + # For pickling to work, the __module__ variable needs to be set to the + # frame where the class is created. Bypass this step in environments where + # sys._getframe is not defined (Jython for example) or sys._getframe is not + # defined for arguments greater than 0 (IronPython). + try: + type_.__module__ = sys._getframe(1).f_globals.get( + "__name__", "__main__" + ) + except (AttributeError, ValueError): + pass + + # We do it here for proper warnings with meaningful stacklevel. + cmp = attributes_arguments.pop("cmp", None) + ( + attributes_arguments["eq"], + attributes_arguments["order"], + ) = _determine_attrs_eq_order( + cmp, + attributes_arguments.get("eq"), + attributes_arguments.get("order"), + True, + ) + + return _attrs(these=cls_dict, **attributes_arguments)(type_) + + +# These are required by within this module so we define them here and merely +# import into .validators / .converters. + + +@attrs(slots=True, hash=True) +class _AndValidator(object): + """ + Compose many validators to a single one. + """ + + _validators = attrib() + + def __call__(self, inst, attr, value): + for v in self._validators: + v(inst, attr, value) + + +def and_(*validators): + """ + A validator that composes multiple validators into one. + + When called on a value, it runs all wrapped validators. + + :param callables validators: Arbitrary number of validators. + + .. versionadded:: 17.1.0 + """ + vals = [] + for validator in validators: + vals.extend( + validator._validators + if isinstance(validator, _AndValidator) + else [validator] + ) + + return _AndValidator(tuple(vals)) + + +def pipe(*converters): + """ + A converter that composes multiple converters into one. + + When called on a value, it runs all wrapped converters, returning the + *last* value. + + Type annotations will be inferred from the wrapped converters', if + they have any. + + :param callables converters: Arbitrary number of converters. + + .. versionadded:: 20.1.0 + """ + + def pipe_converter(val): + for converter in converters: + val = converter(val) + + return val + + if not PY2: + if not converters: + # If the converter list is empty, pipe_converter is the identity. + A = typing.TypeVar("A") + pipe_converter.__annotations__ = {"val": A, "return": A} + else: + # Get parameter type. + sig = None + try: + sig = inspect.signature(converters[0]) + except (ValueError, TypeError): # inspect failed + pass + if sig: + params = list(sig.parameters.values()) + if ( + params + and params[0].annotation is not inspect.Parameter.empty + ): + pipe_converter.__annotations__["val"] = params[ + 0 + ].annotation + # Get return type. + sig = None + try: + sig = inspect.signature(converters[-1]) + except (ValueError, TypeError): # inspect failed + pass + if sig and sig.return_annotation is not inspect.Signature().empty: + pipe_converter.__annotations__[ + "return" + ] = sig.return_annotation + + return pipe_converter diff --git a/dist/ba_data/python-site-packages/attr/_next_gen.py b/dist/ba_data/python-site-packages/attr/_next_gen.py new file mode 100644 index 0000000..fab0af9 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_next_gen.py @@ -0,0 +1,158 @@ +""" +These are Python 3.6+-only and keyword-only APIs that call `attr.s` and +`attr.ib` with different default values. +""" + +from functools import partial + +from attr.exceptions import UnannotatedAttributeError + +from . import setters +from ._make import NOTHING, _frozen_setattrs, attrib, attrs + + +def define( + maybe_cls=None, + *, + these=None, + repr=None, + hash=None, + init=None, + slots=True, + frozen=False, + weakref_slot=True, + str=False, + auto_attribs=None, + kw_only=False, + cache_hash=False, + auto_exc=True, + eq=None, + order=False, + auto_detect=True, + getstate_setstate=None, + on_setattr=None, + field_transformer=None, +): + r""" + The only behavioral differences are the handling of the *auto_attribs* + option: + + :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves + exactly like `attr.s`. If left `None`, `attr.s` will try to guess: + + 1. If any attributes are annotated and no unannotated `attr.ib`\ s + are found, it assumes *auto_attribs=True*. + 2. Otherwise it assumes *auto_attribs=False* and tries to collect + `attr.ib`\ s. + + and that mutable classes (``frozen=False``) validate on ``__setattr__``. + + .. versionadded:: 20.1.0 + """ + + def do_it(cls, auto_attribs): + return attrs( + maybe_cls=cls, + these=these, + repr=repr, + hash=hash, + init=init, + slots=slots, + frozen=frozen, + weakref_slot=weakref_slot, + str=str, + auto_attribs=auto_attribs, + kw_only=kw_only, + cache_hash=cache_hash, + auto_exc=auto_exc, + eq=eq, + order=order, + auto_detect=auto_detect, + collect_by_mro=True, + getstate_setstate=getstate_setstate, + on_setattr=on_setattr, + field_transformer=field_transformer, + ) + + def wrap(cls): + """ + Making this a wrapper ensures this code runs during class creation. + + We also ensure that frozen-ness of classes is inherited. + """ + nonlocal frozen, on_setattr + + had_on_setattr = on_setattr not in (None, setters.NO_OP) + + # By default, mutable classes validate on setattr. + if frozen is False and on_setattr is None: + on_setattr = setters.validate + + # However, if we subclass a frozen class, we inherit the immutability + # and disable on_setattr. + for base_cls in cls.__bases__: + if base_cls.__setattr__ is _frozen_setattrs: + if had_on_setattr: + raise ValueError( + "Frozen classes can't use on_setattr " + "(frozen-ness was inherited)." + ) + + on_setattr = setters.NO_OP + break + + if auto_attribs is not None: + return do_it(cls, auto_attribs) + + try: + return do_it(cls, True) + except UnannotatedAttributeError: + return do_it(cls, False) + + # maybe_cls's type depends on the usage of the decorator. It's a class + # if it's used as `@attrs` but ``None`` if used as `@attrs()`. + if maybe_cls is None: + return wrap + else: + return wrap(maybe_cls) + + +mutable = define +frozen = partial(define, frozen=True, on_setattr=None) + + +def field( + *, + default=NOTHING, + validator=None, + repr=True, + hash=None, + init=True, + metadata=None, + converter=None, + factory=None, + kw_only=False, + eq=None, + order=None, + on_setattr=None, +): + """ + Identical to `attr.ib`, except keyword-only and with some arguments + removed. + + .. versionadded:: 20.1.0 + """ + return attrib( + default=default, + validator=validator, + repr=repr, + hash=hash, + init=init, + metadata=metadata, + converter=converter, + factory=factory, + kw_only=kw_only, + eq=eq, + order=order, + on_setattr=on_setattr, + ) diff --git a/dist/ba_data/python-site-packages/attr/_version_info.py b/dist/ba_data/python-site-packages/attr/_version_info.py new file mode 100644 index 0000000..014e78a --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_version_info.py @@ -0,0 +1,85 @@ +from __future__ import absolute_import, division, print_function + +from functools import total_ordering + +from ._funcs import astuple +from ._make import attrib, attrs + + +@total_ordering +@attrs(eq=False, order=False, slots=True, frozen=True) +class VersionInfo(object): + """ + A version object that can be compared to tuple of length 1--4: + + >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2) + True + >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1) + True + >>> vi = attr.VersionInfo(19, 2, 0, "final") + >>> vi < (19, 1, 1) + False + >>> vi < (19,) + False + >>> vi == (19, 2,) + True + >>> vi == (19, 2, 1) + False + + .. versionadded:: 19.2 + """ + + year = attrib(type=int) + minor = attrib(type=int) + micro = attrib(type=int) + releaselevel = attrib(type=str) + + @classmethod + def _from_version_string(cls, s): + """ + Parse *s* and return a _VersionInfo. + """ + v = s.split(".") + if len(v) == 3: + v.append("final") + + return cls( + year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3] + ) + + def _ensure_tuple(self, other): + """ + Ensure *other* is a tuple of a valid length. + + Returns a possibly transformed *other* and ourselves as a tuple of + the same length as *other*. + """ + + if self.__class__ is other.__class__: + other = astuple(other) + + if not isinstance(other, tuple): + raise NotImplementedError + + if not (1 <= len(other) <= 4): + raise NotImplementedError + + return astuple(self)[: len(other)], other + + def __eq__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + return us == them + + def __lt__(self, other): + try: + us, them = self._ensure_tuple(other) + except NotImplementedError: + return NotImplemented + + # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't + # have to do anything special with releaselevel for now. + return us < them diff --git a/dist/ba_data/python-site-packages/attr/_version_info.pyi b/dist/ba_data/python-site-packages/attr/_version_info.pyi new file mode 100644 index 0000000..45ced08 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/_version_info.pyi @@ -0,0 +1,9 @@ +class VersionInfo: + @property + def year(self) -> int: ... + @property + def minor(self) -> int: ... + @property + def micro(self) -> int: ... + @property + def releaselevel(self) -> str: ... diff --git a/dist/ba_data/python-site-packages/attr/converters.py b/dist/ba_data/python-site-packages/attr/converters.py new file mode 100644 index 0000000..2777db6 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/converters.py @@ -0,0 +1,111 @@ +""" +Commonly useful converters. +""" + +from __future__ import absolute_import, division, print_function + +from ._compat import PY2 +from ._make import NOTHING, Factory, pipe + + +if not PY2: + import inspect + import typing + + +__all__ = [ + "pipe", + "optional", + "default_if_none", +] + + +def optional(converter): + """ + A converter that allows an attribute to be optional. An optional attribute + is one which can be set to ``None``. + + Type annotations will be inferred from the wrapped converter's, if it + has any. + + :param callable converter: the converter that is used for non-``None`` + values. + + .. versionadded:: 17.1.0 + """ + + def optional_converter(val): + if val is None: + return None + return converter(val) + + if not PY2: + sig = None + try: + sig = inspect.signature(converter) + except (ValueError, TypeError): # inspect failed + pass + if sig: + params = list(sig.parameters.values()) + if params and params[0].annotation is not inspect.Parameter.empty: + optional_converter.__annotations__["val"] = typing.Optional[ + params[0].annotation + ] + if sig.return_annotation is not inspect.Signature.empty: + optional_converter.__annotations__["return"] = typing.Optional[ + sig.return_annotation + ] + + return optional_converter + + +def default_if_none(default=NOTHING, factory=None): + """ + A converter that allows to replace ``None`` values by *default* or the + result of *factory*. + + :param default: Value to be used if ``None`` is passed. Passing an instance + of `attr.Factory` is supported, however the ``takes_self`` option + is *not*. + :param callable factory: A callable that takes no parameters whose result + is used if ``None`` is passed. + + :raises TypeError: If **neither** *default* or *factory* is passed. + :raises TypeError: If **both** *default* and *factory* are passed. + :raises ValueError: If an instance of `attr.Factory` is passed with + ``takes_self=True``. + + .. versionadded:: 18.2.0 + """ + if default is NOTHING and factory is None: + raise TypeError("Must pass either `default` or `factory`.") + + if default is not NOTHING and factory is not None: + raise TypeError( + "Must pass either `default` or `factory` but not both." + ) + + if factory is not None: + default = Factory(factory) + + if isinstance(default, Factory): + if default.takes_self: + raise ValueError( + "`takes_self` is not supported by default_if_none." + ) + + def default_if_none_converter(val): + if val is not None: + return val + + return default.factory() + + else: + + def default_if_none_converter(val): + if val is not None: + return val + + return default + + return default_if_none_converter diff --git a/dist/ba_data/python-site-packages/attr/converters.pyi b/dist/ba_data/python-site-packages/attr/converters.pyi new file mode 100644 index 0000000..84a5759 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/converters.pyi @@ -0,0 +1,13 @@ +from typing import Callable, Optional, TypeVar, overload + +from . import _ConverterType + + +_T = TypeVar("_T") + +def pipe(*validators: _ConverterType) -> _ConverterType: ... +def optional(converter: _ConverterType) -> _ConverterType: ... +@overload +def default_if_none(default: _T) -> _ConverterType: ... +@overload +def default_if_none(*, factory: Callable[[], _T]) -> _ConverterType: ... diff --git a/dist/ba_data/python-site-packages/attr/exceptions.py b/dist/ba_data/python-site-packages/attr/exceptions.py new file mode 100644 index 0000000..f6f9861 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/exceptions.py @@ -0,0 +1,92 @@ +from __future__ import absolute_import, division, print_function + + +class FrozenError(AttributeError): + """ + A frozen/immutable instance or attribute have been attempted to be + modified. + + It mirrors the behavior of ``namedtuples`` by using the same error message + and subclassing `AttributeError`. + + .. versionadded:: 20.1.0 + """ + + msg = "can't set attribute" + args = [msg] + + +class FrozenInstanceError(FrozenError): + """ + A frozen instance has been attempted to be modified. + + .. versionadded:: 16.1.0 + """ + + +class FrozenAttributeError(FrozenError): + """ + A frozen attribute has been attempted to be modified. + + .. versionadded:: 20.1.0 + """ + + +class AttrsAttributeNotFoundError(ValueError): + """ + An ``attrs`` function couldn't find an attribute that the user asked for. + + .. versionadded:: 16.2.0 + """ + + +class NotAnAttrsClassError(ValueError): + """ + A non-``attrs`` class has been passed into an ``attrs`` function. + + .. versionadded:: 16.2.0 + """ + + +class DefaultAlreadySetError(RuntimeError): + """ + A default has been set using ``attr.ib()`` and is attempted to be reset + using the decorator. + + .. versionadded:: 17.1.0 + """ + + +class UnannotatedAttributeError(RuntimeError): + """ + A class with ``auto_attribs=True`` has an ``attr.ib()`` without a type + annotation. + + .. versionadded:: 17.3.0 + """ + + +class PythonTooOldError(RuntimeError): + """ + It was attempted to use an ``attrs`` feature that requires a newer Python + version. + + .. versionadded:: 18.2.0 + """ + + +class NotCallableError(TypeError): + """ + A ``attr.ib()`` requiring a callable has been set with a value + that is not callable. + + .. versionadded:: 19.2.0 + """ + + def __init__(self, msg, value): + super(TypeError, self).__init__(msg, value) + self.msg = msg + self.value = value + + def __str__(self): + return str(self.msg) diff --git a/dist/ba_data/python-site-packages/attr/exceptions.pyi b/dist/ba_data/python-site-packages/attr/exceptions.pyi new file mode 100644 index 0000000..a800fb2 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/exceptions.pyi @@ -0,0 +1,18 @@ +from typing import Any + + +class FrozenError(AttributeError): + msg: str = ... + +class FrozenInstanceError(FrozenError): ... +class FrozenAttributeError(FrozenError): ... +class AttrsAttributeNotFoundError(ValueError): ... +class NotAnAttrsClassError(ValueError): ... +class DefaultAlreadySetError(RuntimeError): ... +class UnannotatedAttributeError(RuntimeError): ... +class PythonTooOldError(RuntimeError): ... + +class NotCallableError(TypeError): + msg: str = ... + value: Any = ... + def __init__(self, msg: str, value: Any) -> None: ... diff --git a/dist/ba_data/python-site-packages/attr/filters.py b/dist/ba_data/python-site-packages/attr/filters.py new file mode 100644 index 0000000..dc47e8f --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/filters.py @@ -0,0 +1,52 @@ +""" +Commonly useful filters for `attr.asdict`. +""" + +from __future__ import absolute_import, division, print_function + +from ._compat import isclass +from ._make import Attribute + + +def _split_what(what): + """ + Returns a tuple of `frozenset`s of classes and attributes. + """ + return ( + frozenset(cls for cls in what if isclass(cls)), + frozenset(cls for cls in what if isinstance(cls, Attribute)), + ) + + +def include(*what): + """ + Whitelist *what*. + + :param what: What to whitelist. + :type what: `list` of `type` or `attr.Attribute`\\ s + + :rtype: `callable` + """ + cls, attrs = _split_what(what) + + def include_(attribute, value): + return value.__class__ in cls or attribute in attrs + + return include_ + + +def exclude(*what): + """ + Blacklist *what*. + + :param what: What to blacklist. + :type what: `list` of classes or `attr.Attribute`\\ s. + + :rtype: `callable` + """ + cls, attrs = _split_what(what) + + def exclude_(attribute, value): + return value.__class__ not in cls and attribute not in attrs + + return exclude_ diff --git a/dist/ba_data/python-site-packages/attr/filters.pyi b/dist/ba_data/python-site-packages/attr/filters.pyi new file mode 100644 index 0000000..f7b63f1 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/filters.pyi @@ -0,0 +1,7 @@ +from typing import Any, Union + +from . import Attribute, _FilterType + + +def include(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ... +def exclude(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ... diff --git a/dist/ba_data/python-site-packages/attr/py.typed b/dist/ba_data/python-site-packages/attr/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/dist/ba_data/python-site-packages/attr/setters.py b/dist/ba_data/python-site-packages/attr/setters.py new file mode 100644 index 0000000..240014b --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/setters.py @@ -0,0 +1,77 @@ +""" +Commonly used hooks for on_setattr. +""" + +from __future__ import absolute_import, division, print_function + +from . import _config +from .exceptions import FrozenAttributeError + + +def pipe(*setters): + """ + Run all *setters* and return the return value of the last one. + + .. versionadded:: 20.1.0 + """ + + def wrapped_pipe(instance, attrib, new_value): + rv = new_value + + for setter in setters: + rv = setter(instance, attrib, rv) + + return rv + + return wrapped_pipe + + +def frozen(_, __, ___): + """ + Prevent an attribute to be modified. + + .. versionadded:: 20.1.0 + """ + raise FrozenAttributeError() + + +def validate(instance, attrib, new_value): + """ + Run *attrib*'s validator on *new_value* if it has one. + + .. versionadded:: 20.1.0 + """ + if _config._run_validators is False: + return new_value + + v = attrib.validator + if not v: + return new_value + + v(instance, attrib, new_value) + + return new_value + + +def convert(instance, attrib, new_value): + """ + Run *attrib*'s converter -- if it has one -- on *new_value* and return the + result. + + .. versionadded:: 20.1.0 + """ + c = attrib.converter + if c: + return c(new_value) + + return new_value + + +NO_OP = object() +""" +Sentinel for disabling class-wide *on_setattr* hooks for certain attributes. + +Does not work in `pipe` or within lists. + +.. versionadded:: 20.1.0 +""" diff --git a/dist/ba_data/python-site-packages/attr/setters.pyi b/dist/ba_data/python-site-packages/attr/setters.pyi new file mode 100644 index 0000000..a921e07 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/setters.pyi @@ -0,0 +1,20 @@ +from typing import Any, NewType, NoReturn, TypeVar, cast + +from . import Attribute, _OnSetAttrType + + +_T = TypeVar("_T") + +def frozen( + instance: Any, attribute: Attribute[Any], new_value: Any +) -> NoReturn: ... +def pipe(*setters: _OnSetAttrType) -> _OnSetAttrType: ... +def validate(instance: Any, attribute: Attribute[_T], new_value: _T) -> _T: ... + +# convert is allowed to return Any, because they can be chained using pipe. +def convert( + instance: Any, attribute: Attribute[Any], new_value: Any +) -> Any: ... + +_NoOpType = NewType("_NoOpType", object) +NO_OP: _NoOpType diff --git a/dist/ba_data/python-site-packages/attr/validators.py b/dist/ba_data/python-site-packages/attr/validators.py new file mode 100644 index 0000000..b9a7305 --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/validators.py @@ -0,0 +1,379 @@ +""" +Commonly useful validators. +""" + +from __future__ import absolute_import, division, print_function + +import re + +from ._make import _AndValidator, and_, attrib, attrs +from .exceptions import NotCallableError + + +__all__ = [ + "and_", + "deep_iterable", + "deep_mapping", + "in_", + "instance_of", + "is_callable", + "matches_re", + "optional", + "provides", +] + + +@attrs(repr=False, slots=True, hash=True) +class _InstanceOfValidator(object): + type = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not isinstance(value, self.type): + raise TypeError( + "'{name}' must be {type!r} (got {value!r} that is a " + "{actual!r}).".format( + name=attr.name, + type=self.type, + actual=value.__class__, + value=value, + ), + attr, + self.type, + value, + ) + + def __repr__(self): + return "".format( + type=self.type + ) + + +def instance_of(type): + """ + A validator that raises a `TypeError` if the initializer is called + with a wrong type for this particular attribute (checks are performed using + `isinstance` therefore it's also valid to pass a tuple of types). + + :param type: The type to check for. + :type type: type or tuple of types + + :raises TypeError: With a human readable error message, the attribute + (of type `attr.Attribute`), the expected type, and the value it + got. + """ + return _InstanceOfValidator(type) + + +@attrs(repr=False, frozen=True, slots=True) +class _MatchesReValidator(object): + regex = attrib() + flags = attrib() + match_func = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.match_func(value): + raise ValueError( + "'{name}' must match regex {regex!r}" + " ({value!r} doesn't)".format( + name=attr.name, regex=self.regex.pattern, value=value + ), + attr, + self.regex, + value, + ) + + def __repr__(self): + return "".format( + regex=self.regex + ) + + +def matches_re(regex, flags=0, func=None): + r""" + A validator that raises `ValueError` if the initializer is called + with a string that doesn't match *regex*. + + :param str regex: a regex string to match against + :param int flags: flags that will be passed to the underlying re function + (default 0) + :param callable func: which underlying `re` function to call (options + are `re.fullmatch`, `re.search`, `re.match`, default + is ``None`` which means either `re.fullmatch` or an emulation of + it on Python 2). For performance reasons, they won't be used directly + but on a pre-`re.compile`\ ed pattern. + + .. versionadded:: 19.2.0 + """ + fullmatch = getattr(re, "fullmatch", None) + valid_funcs = (fullmatch, None, re.search, re.match) + if func not in valid_funcs: + raise ValueError( + "'func' must be one of %s." + % ( + ", ".join( + sorted( + e and e.__name__ or "None" for e in set(valid_funcs) + ) + ), + ) + ) + + pattern = re.compile(regex, flags) + if func is re.match: + match_func = pattern.match + elif func is re.search: + match_func = pattern.search + else: + if fullmatch: + match_func = pattern.fullmatch + else: + pattern = re.compile(r"(?:{})\Z".format(regex), flags) + match_func = pattern.match + + return _MatchesReValidator(pattern, flags, match_func) + + +@attrs(repr=False, slots=True, hash=True) +class _ProvidesValidator(object): + interface = attrib() + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not self.interface.providedBy(value): + raise TypeError( + "'{name}' must provide {interface!r} which {value!r} " + "doesn't.".format( + name=attr.name, interface=self.interface, value=value + ), + attr, + self.interface, + value, + ) + + def __repr__(self): + return "".format( + interface=self.interface + ) + + +def provides(interface): + """ + A validator that raises a `TypeError` if the initializer is called + with an object that does not provide the requested *interface* (checks are + performed using ``interface.providedBy(value)`` (see `zope.interface + `_). + + :param interface: The interface to check for. + :type interface: ``zope.interface.Interface`` + + :raises TypeError: With a human readable error message, the attribute + (of type `attr.Attribute`), the expected interface, and the + value it got. + """ + return _ProvidesValidator(interface) + + +@attrs(repr=False, slots=True, hash=True) +class _OptionalValidator(object): + validator = attrib() + + def __call__(self, inst, attr, value): + if value is None: + return + + self.validator(inst, attr, value) + + def __repr__(self): + return "".format( + what=repr(self.validator) + ) + + +def optional(validator): + """ + A validator that makes an attribute optional. An optional attribute is one + which can be set to ``None`` in addition to satisfying the requirements of + the sub-validator. + + :param validator: A validator (or a list of validators) that is used for + non-``None`` values. + :type validator: callable or `list` of callables. + + .. versionadded:: 15.1.0 + .. versionchanged:: 17.1.0 *validator* can be a list of validators. + """ + if isinstance(validator, list): + return _OptionalValidator(_AndValidator(validator)) + return _OptionalValidator(validator) + + +@attrs(repr=False, slots=True, hash=True) +class _InValidator(object): + options = attrib() + + def __call__(self, inst, attr, value): + try: + in_options = value in self.options + except TypeError: # e.g. `1 in "abc"` + in_options = False + + if not in_options: + raise ValueError( + "'{name}' must be in {options!r} (got {value!r})".format( + name=attr.name, options=self.options, value=value + ) + ) + + def __repr__(self): + return "".format( + options=self.options + ) + + +def in_(options): + """ + A validator that raises a `ValueError` if the initializer is called + with a value that does not belong in the options provided. The check is + performed using ``value in options``. + + :param options: Allowed options. + :type options: list, tuple, `enum.Enum`, ... + + :raises ValueError: With a human readable error message, the attribute (of + type `attr.Attribute`), the expected options, and the value it + got. + + .. versionadded:: 17.1.0 + """ + return _InValidator(options) + + +@attrs(repr=False, slots=False, hash=True) +class _IsCallableValidator(object): + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if not callable(value): + message = ( + "'{name}' must be callable " + "(got {value!r} that is a {actual!r})." + ) + raise NotCallableError( + msg=message.format( + name=attr.name, value=value, actual=value.__class__ + ), + value=value, + ) + + def __repr__(self): + return "" + + +def is_callable(): + """ + A validator that raises a `attr.exceptions.NotCallableError` if the + initializer is called with a value for this particular attribute + that is not callable. + + .. versionadded:: 19.1.0 + + :raises `attr.exceptions.NotCallableError`: With a human readable error + message containing the attribute (`attr.Attribute`) name, + and the value it got. + """ + return _IsCallableValidator() + + +@attrs(repr=False, slots=True, hash=True) +class _DeepIterable(object): + member_validator = attrib(validator=is_callable()) + iterable_validator = attrib( + default=None, validator=optional(is_callable()) + ) + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if self.iterable_validator is not None: + self.iterable_validator(inst, attr, value) + + for member in value: + self.member_validator(inst, attr, member) + + def __repr__(self): + iterable_identifier = ( + "" + if self.iterable_validator is None + else " {iterable!r}".format(iterable=self.iterable_validator) + ) + return ( + "" + ).format( + iterable_identifier=iterable_identifier, + member=self.member_validator, + ) + + +def deep_iterable(member_validator, iterable_validator=None): + """ + A validator that performs deep validation of an iterable. + + :param member_validator: Validator to apply to iterable members + :param iterable_validator: Validator to apply to iterable itself + (optional) + + .. versionadded:: 19.1.0 + + :raises TypeError: if any sub-validators fail + """ + return _DeepIterable(member_validator, iterable_validator) + + +@attrs(repr=False, slots=True, hash=True) +class _DeepMapping(object): + key_validator = attrib(validator=is_callable()) + value_validator = attrib(validator=is_callable()) + mapping_validator = attrib(default=None, validator=optional(is_callable())) + + def __call__(self, inst, attr, value): + """ + We use a callable class to be able to change the ``__repr__``. + """ + if self.mapping_validator is not None: + self.mapping_validator(inst, attr, value) + + for key in value: + self.key_validator(inst, attr, key) + self.value_validator(inst, attr, value[key]) + + def __repr__(self): + return ( + "" + ).format(key=self.key_validator, value=self.value_validator) + + +def deep_mapping(key_validator, value_validator, mapping_validator=None): + """ + A validator that performs deep validation of a dictionary. + + :param key_validator: Validator to apply to dictionary keys + :param value_validator: Validator to apply to dictionary values + :param mapping_validator: Validator to apply to top-level mapping + attribute (optional) + + .. versionadded:: 19.1.0 + + :raises TypeError: if any sub-validators fail + """ + return _DeepMapping(key_validator, value_validator, mapping_validator) diff --git a/dist/ba_data/python-site-packages/attr/validators.pyi b/dist/ba_data/python-site-packages/attr/validators.pyi new file mode 100644 index 0000000..fe92aac --- /dev/null +++ b/dist/ba_data/python-site-packages/attr/validators.pyi @@ -0,0 +1,68 @@ +from typing import ( + Any, + AnyStr, + Callable, + Container, + Iterable, + List, + Mapping, + Match, + Optional, + Tuple, + Type, + TypeVar, + Union, + overload, +) + +from . import _ValidatorType + + +_T = TypeVar("_T") +_T1 = TypeVar("_T1") +_T2 = TypeVar("_T2") +_T3 = TypeVar("_T3") +_I = TypeVar("_I", bound=Iterable) +_K = TypeVar("_K") +_V = TypeVar("_V") +_M = TypeVar("_M", bound=Mapping) + +# To be more precise on instance_of use some overloads. +# If there are more than 3 items in the tuple then we fall back to Any +@overload +def instance_of(type: Type[_T]) -> _ValidatorType[_T]: ... +@overload +def instance_of(type: Tuple[Type[_T]]) -> _ValidatorType[_T]: ... +@overload +def instance_of( + type: Tuple[Type[_T1], Type[_T2]] +) -> _ValidatorType[Union[_T1, _T2]]: ... +@overload +def instance_of( + type: Tuple[Type[_T1], Type[_T2], Type[_T3]] +) -> _ValidatorType[Union[_T1, _T2, _T3]]: ... +@overload +def instance_of(type: Tuple[type, ...]) -> _ValidatorType[Any]: ... +def provides(interface: Any) -> _ValidatorType[Any]: ... +def optional( + validator: Union[_ValidatorType[_T], List[_ValidatorType[_T]]] +) -> _ValidatorType[Optional[_T]]: ... +def in_(options: Container[_T]) -> _ValidatorType[_T]: ... +def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... +def matches_re( + regex: AnyStr, + flags: int = ..., + func: Optional[ + Callable[[AnyStr, AnyStr, int], Optional[Match[AnyStr]]] + ] = ..., +) -> _ValidatorType[AnyStr]: ... +def deep_iterable( + member_validator: _ValidatorType[_T], + iterable_validator: Optional[_ValidatorType[_I]] = ..., +) -> _ValidatorType[_I]: ... +def deep_mapping( + key_validator: _ValidatorType[_K], + value_validator: _ValidatorType[_V], + mapping_validator: Optional[_ValidatorType[_M]] = ..., +) -> _ValidatorType[_M]: ... +def is_callable() -> _ValidatorType[_T]: ... diff --git a/dist/ba_data/python-site-packages/certifi/__init__.py b/dist/ba_data/python-site-packages/certifi/__init__.py new file mode 100644 index 0000000..a3546f1 --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi/__init__.py @@ -0,0 +1,4 @@ +from .core import contents, where + +__all__ = ["contents", "where"] +__version__ = "2022.12.07" diff --git a/dist/ba_data/python-site-packages/certifi/__main__.py b/dist/ba_data/python-site-packages/certifi/__main__.py new file mode 100644 index 0000000..8945b5d --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi/__main__.py @@ -0,0 +1,12 @@ +import argparse + +from certifi import contents, where + +parser = argparse.ArgumentParser() +parser.add_argument("-c", "--contents", action="store_true") +args = parser.parse_args() + +if args.contents: + print(contents()) +else: + print(where()) diff --git a/dist/ba_data/python-site-packages/certifi/cacert.pem b/dist/ba_data/python-site-packages/certifi/cacert.pem new file mode 100644 index 0000000..df9e4e3 --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi/cacert.pem @@ -0,0 +1,4527 @@ + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Premium 2048 Secure Server CA" +# Serial: 946069240 +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Label: "Entrust Root Certification Authority" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 +# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 +# Label: "Security Communication Root CA" +# Serial: 0 +# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a +# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 +# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- + +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Label: "XRamp Global CA Root" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Label: "Hongkong Post Root CA 1" +# Serial: 1000 +# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca +# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 +# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 6047274297262753887 +# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 +# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa +# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Label: "TeliaSonera Root CA v1" +# Serial: 199041966741090107964904287217786801558 +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Label: "E-Tugra Certification Authority" +# Serial: 7667447206703254355 +# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 +# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 +# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Label: "GlobalSign Root CA - R6" +# Serial: 1417766617973444989252670301619537 +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign ECC Root CA - G3" +# Serial: 287880440101571086945156 +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Label: "emSign Root CA - C1" +# Serial: 825510296613316004955058 +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Label: "emSign ECC Root CA - C3" +# Serial: 582948710642506000014504 +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL +BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ +SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n +a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 +NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT +CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u +Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO +dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI +VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV +9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY +2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY +vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt +bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb +x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ +l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK +TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj +Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw +DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG +7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk +MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr +gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk +GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS +3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm +Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ +l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c +JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP +L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa +LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG +mpv0 +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G4" +# Serial: 289383649854506086828220374796556676440 +# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 +# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 +# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft ECC Root Certificate Authority 2017" +# Serial: 136839042543790627607696632466672567020 +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft RSA Root Certificate Authority 2017" +# Serial: 40975477897264996090493496164228220339 +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Label: "e-Szigno Root CA 2017" +# Serial: 411379200276854331539784714 +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- + +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Label: "certSIGN Root CA G2" +# Serial: 313609486401300475190 +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global Certification Authority" +# Serial: 1846098327275375458322922162 +# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e +# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5 +# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8 +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK +yeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P256 Certification Authority" +# Serial: 4151900041497450638097112925 +# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54 +# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf +# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4 +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P384 Certification Authority" +# Serial: 2704997926503831671788816187 +# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6 +# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2 +# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97 +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu +Sw== +-----END CERTIFICATE----- + +# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Label: "NAVER Global Root Certification Authority" +# Serial: 9013692873798656336226253319739695165984492813 +# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b +# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 +# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- + +# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" +# Serial: 131542671362353147877283741781055151509 +# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb +# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a +# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw +CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw +FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S +Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 +MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL +DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS +QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH +sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK +Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu +SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC +MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy +v+c= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Label: "GlobalSign Root R46" +# Serial: 1552617688466950547958867513931858518042577 +# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef +# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 +# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA +MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD +VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy +MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt +c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ +OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG +vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud +316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo +0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE +y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF +zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE ++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN +I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs +x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa +ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC +4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 +7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti +2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk +pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF +FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt +rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk +ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 +u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP +4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 +N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 +vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Label: "GlobalSign Root E46" +# Serial: 1552617690338932563915843282459653771421763 +# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f +# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 +# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx +CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD +ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw +MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex +HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq +R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd +yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ +7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 ++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +# Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH +# Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH +# Label: "GLOBALTRUST 2020" +# Serial: 109160994242082918454945253 +# MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8 +# SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2 +# SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a +-----BEGIN CERTIFICATE----- +MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG +A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw +FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx +MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u +aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b +RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z +YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3 +QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw +yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+ +BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ +SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH +r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0 +4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me +dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw +q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2 +nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu +H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA +VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC +XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd +6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf ++I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi +kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7 +wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB +TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C +MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn +4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I +aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy +qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== +-----END CERTIFICATE----- + +# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Label: "ANF Secure Server Root CA" +# Serial: 996390341000653745 +# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 +# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 +# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 +-----BEGIN CERTIFICATE----- +MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV +BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk +YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV +BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN +MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF +UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD +VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v +dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj +cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q +yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH +2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX +H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL +zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR +p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz +W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/ +SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn +LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3 +n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B +u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj +o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L +9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej +rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK +pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0 +vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq +OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ +/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9 +2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI ++PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2 +MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo +tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= +-----END CERTIFICATE----- + +# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum EC-384 CA" +# Serial: 160250656287871593594747141429395092468 +# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 +# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed +# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw +CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw +JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT +EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 +WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT +LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX +BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE +KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm +Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 +EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J +UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn +nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Root CA" +# Serial: 40870380103424195783807378461123655149 +# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 +# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 +# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd +-----BEGIN CERTIFICATE----- +MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6 +MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu +MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV +BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw +MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg +U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ +n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q +p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq +NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF +8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3 +HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa +mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi +7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF +ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P +qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ +v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6 +Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 +vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD +ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4 +WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo +zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR +5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ +GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf +5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq +0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D +P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM +qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP +0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf +E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb +-----END CERTIFICATE----- + +# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Label: "TunTrust Root CA" +# Serial: 108534058042236574382096126452369648152337120275 +# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 +# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb +# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL +BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg +Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv +b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG +EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u +IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ +n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd +2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF +VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ +GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF +li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU +r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 +eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb +MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg +jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB +7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW +5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE +ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z +xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu +QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 +FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH +22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP +xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn +dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 +Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b +nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ +CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH +u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj +d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS RSA Root CA 2021" +# Serial: 76817823531813593706434026085292783742 +# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 +# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d +# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg +Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL +MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l +mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE +4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv +a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M +pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw +Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b +LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY +AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB +AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq +E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr +W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ +CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU +X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 +f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja +H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP +JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P +zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt +jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 +/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT +BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 +aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW +xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU +63ZTGI0RmLo= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS ECC Root CA 2021" +# Serial: 137515985548005187474074462014555733966 +# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 +# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 +# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw +CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh +cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v +dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG +A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 +KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y +STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD +AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw +SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN +nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 1977337328857672817 +# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 +# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe +# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus ECC Root CA" +# Serial: 630369271402956006249506845124680065938238527194 +# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 +# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 +# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw +RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY +BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz +MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u +LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 +v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd +e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw +V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA +AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG +GJTO +-----END CERTIFICATE----- + +# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus Root CA" +# Serial: 387574501246983434957692974888460947164905180485 +# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc +# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 +# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL +BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x +FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx +MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s +THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc +IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU +AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ +GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 +8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH +flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt +J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim +0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN +pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ +UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW +OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB +AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet +8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j +bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM +Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv +TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS +S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr +I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 +b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB +UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P +Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven +sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X2 O=Internet Security Research Group +# Subject: CN=ISRG Root X2 O=Internet Security Research Group +# Label: "ISRG Root X2" +# Serial: 87493402998870891108772069816698636114 +# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 +# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af +# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 +/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Label: "HiPKI Root CA - G1" +# Serial: 60966262342023497858655262305426234976 +# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 +# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 +# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa +Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 +YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw +qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv +Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 +lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz +Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ +KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK +FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj +HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr +y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ +/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM +a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 +fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG +SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc +SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza +ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc +XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg +iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho +L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF +Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr +kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ +vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU +YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 159662223612894884239637590694 +# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc +# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 +# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD +VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw +MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g +UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx +uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV +HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ ++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 +bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 159662320309726417404178440727 +# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 +# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a +# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 159662449406622349769042896298 +# MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc +# SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94 +# SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8 +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt +nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY +6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu +MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k +RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg +f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV ++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo +dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW +Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa +G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq +gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H +vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC +B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u +NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg +yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev +HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6 +xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR +TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg +JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV +7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl +6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 159662495401136852707857743206 +# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 +# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 +# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 159662532700760215368942768210 +# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 +# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 +# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj +# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj +# Label: "Telia Root CA v2" +# Serial: 7288924052977061235122729490515358 +# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 +# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd +# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA +rBPuUBQemMc= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 1 2020" +# Serial: 165870826978392376648679885835942448534 +# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed +# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 +# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 +NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS +zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 +QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ +VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW +wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV +dWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 1 2020" +# Serial: 126288379621884218666039612629459926992 +# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e +# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 +# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 +NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC +/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD +wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 +OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA +y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb +gfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS ECC P384 Root G5" +# Serial: 13129116028163249804115411775095713523 +# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed +# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee +# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS RSA4096 Root G5" +# Serial: 11930366277458970227240571539258396554 +# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 +# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 +# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root R1 O=Certainly +# Subject: CN=Certainly Root R1 O=Certainly +# Label: "Certainly Root R1" +# Serial: 188833316161142517227353805653483829216 +# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 +# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af +# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 +OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root E1 O=Certainly +# Subject: CN=Certainly Root E1 O=Certainly +# Label: "Certainly Root E1" +# Serial: 8168531406727139161245376702891150584 +# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 +# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b +# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Subject: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Label: "E-Tugra Global Root CA RSA v3" +# Serial: 75951268308633135324246244059508261641472512052 +# MD5 Fingerprint: 22:be:10:f6:c2:f8:03:88:73:5f:33:29:47:28:47:a4 +# SHA1 Fingerprint: e9:a8:5d:22:14:52:1c:5b:aa:0a:b4:be:24:6a:23:8a:c9:ba:e2:a9 +# SHA256 Fingerprint: ef:66:b0:b1:0a:3c:db:9f:2e:36:48:c7:6b:d2:af:18:ea:d2:bf:e6:f1:17:65:5e:28:c4:06:0d:a1:a3:f4:c2 +-----BEGIN CERTIFICATE----- +MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQEL +BQAwgYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUt +VHVncmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYw +JAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIFJTQSB2MzAeFw0yMDAzMTgw +OTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMG +QW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 +Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBD +QSBSU0EgdjMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J7 +7gnJY9LTQ91ew6aEOErxjYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscx +uj7X/iWpKo429NEvx7epXTPcMHD4QGxLsqYxYdE0PD0xesevxKenhOGXpOhL9hd8 +7jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF/YP9f4RtNGx/ardLAQO/ +rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8qQedmCeFL +l+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bG +wzrwbMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4 +znKS4iicvObpCdg604nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBO +M/J+JjKsBY04pOZ2PJ8QaQ5tndLBeSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK +5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiMbIedBi3x7+PmBvrFZhNb/FAH +nnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbgh3cXTJ2w2Amo +DVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSy +tK7mLfcm1ap1LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEL +BQADggIBAImocn+M684uGMQQgC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ +6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN438o2Fi+CiJ+8EUdPdk3ILY7r3y18 +Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/qln0F7psTpURs+APQ +3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3sSdPk +vmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn9 +9t2HVhjYsCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQ +mhty3QUBjYZgv6Rn7rWlDdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YA +VSgU7NbHEqIbZULpkejLPoeJVF3Zr52XnGnnCv8PWniLYypMfUeUP95L6VPQMPHF +9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFHIK+WEj5jlB0E5y67hscM +moi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiXYY60MGo8 +bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Subject: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center +# Label: "E-Tugra Global Root CA ECC v3" +# Serial: 218504919822255052842371958738296604628416471745 +# MD5 Fingerprint: 46:bc:81:bb:f1:b5:1e:f7:4b:96:bc:14:e2:e7:27:64 +# SHA1 Fingerprint: 8a:2f:af:57:53:b1:b0:e6:a1:04:ec:5b:6a:69:71:6d:f6:1c:e2:84 +# SHA256 Fingerprint: 87:3f:46:85:fa:7f:56:36:25:25:2e:6d:36:bc:d7:f1:6f:c2:49:51:f2:64:e4:7e:1b:95:4f:49:08:cd:ca:13 +-----BEGIN CERTIFICATE----- +MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMw +gYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVn +cmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYD +VQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2 +NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5r +YXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1Z3Jh +IFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBF +Q0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQ +KczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK +fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMB +Af8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+C +MXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNp +ADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/6 +7W4WAie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFx +vmjkI6TZraE3 +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication RootCA3" +# Serial: 16247922307909811815 +# MD5 Fingerprint: 1c:9a:16:ff:9e:5c:e0:4d:8a:14:01:f4:35:5d:29:26 +# SHA1 Fingerprint: c3:03:c8:22:74:92:e5:61:a2:9c:5f:79:91:2b:1e:44:13:91:30:3a +# SHA256 Fingerprint: 24:a5:5c:2a:b0:51:44:2d:06:17:76:65:41:23:9a:4a:d0:32:d7:c5:51:75:aa:34:ff:de:2f:bc:4f:5c:52:94 +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNV +BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw +JQYDVQQDEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2 +MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UEAxMeU2VjdXJpdHkg +Q29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4r +CmDvu20rhvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzA +lrenfna84xtSGc4RHwsENPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MG +TfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF7 +9+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGmnpjKIG58u4iFW/vAEGK7 +8vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtYXLVqAvO4 +g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3we +GVPKp7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst ++3A7caoreyYn8xrC3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M +0V9hvqG8OmpI6iZVIhZdXw3/JzOfGAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQ +T9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0VcwCBEF/VfR2ccCAwEAAaNCMEAw +HQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PA +FNr0Y/Dq9HHuTofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd +9XbXv8S2gVj/yP9kaWJ5rW4OH3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQI +UYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASxYfQAW0q3nHE3GYV5v4GwxxMOdnE+ +OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZXSEIx2C/pHF7uNke +gr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml+LLf +iAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUV +nuiZIesnKwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD +2NCcnWXL0CsnMQMeNuE9dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI// +1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm6Vwdp6POXiUyK+OVrCoHzrQoeIY8Laad +TdJ0MN1kURXbg4NR16/9M51NZg== +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication ECC RootCA1" +# Serial: 15446673492073852651 +# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86 +# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41 +# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11 +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT +AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD +VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx +NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT +HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 +IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl +dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK +ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu +9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O +be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= +-----END CERTIFICATE----- diff --git a/dist/ba_data/python-site-packages/certifi/core.py b/dist/ba_data/python-site-packages/certifi/core.py new file mode 100644 index 0000000..de02898 --- /dev/null +++ b/dist/ba_data/python-site-packages/certifi/core.py @@ -0,0 +1,108 @@ +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem or its contents. +""" +import sys + + +if sys.version_info >= (3, 11): + + from importlib.resources import as_file, files + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the file + # in cases where we're inside of a zipimport situation until someone + # actually calls where(), but we don't want to re-extract the file + # on every call of where(), so we'll do it once then store it in a + # global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you to + # manage the cleanup of this file, so it doesn't actually return a + # path, it returns a context manager that will give you the path + # when you enter it and will do any cleanup when you leave it. In + # the common case of not needing a temporary file, it will just + # return the file system location and the __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem")) + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + def contents() -> str: + return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii") + +elif sys.version_info >= (3, 7): + + from importlib.resources import path as get_path, read_text + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the + # file in cases where we're inside of a zipimport situation until + # someone actually calls where(), but we don't want to re-extract + # the file on every call of where(), so we'll do it once then store + # it in a global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you + # to manage the cleanup of this file, so it doesn't actually + # return a path, it returns a context manager that will give + # you the path when you enter it and will do any cleanup when + # you leave it. In the common case of not needing a temporary + # file, it will just return the file system location and the + # __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = get_path("certifi", "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") + +else: + import os + import types + from typing import Union + + Package = Union[types.ModuleType, str] + Resource = Union[str, "os.PathLike"] + + # This fallback will work for Python versions prior to 3.7 that lack the + # importlib.resources module but relies on the existing `where` function + # so won't address issues with environments like PyOxidizer that don't set + # __file__ on modules. + def read_text( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict' + ) -> str: + with open(where(), encoding=encoding) as data: + return data.read() + + # If we don't have importlib.resources, then we will just do the old logic + # of assuming we're on the filesystem and munge the path directly. + def where() -> str: + f = os.path.dirname(__file__) + + return os.path.join(f, "cacert.pem") + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/dist/ba_data/python-site-packages/cffi.libs/libffi-2a6f5b63.so.8.1.0 b/dist/ba_data/python-site-packages/cffi.libs/libffi-2a6f5b63.so.8.1.0 new file mode 100644 index 0000000..81b2c13 Binary files /dev/null and b/dist/ba_data/python-site-packages/cffi.libs/libffi-2a6f5b63.so.8.1.0 differ diff --git a/dist/ba_data/python-site-packages/cffi/__init__.py b/dist/ba_data/python-site-packages/cffi/__init__.py new file mode 100644 index 0000000..90e2e65 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/__init__.py @@ -0,0 +1,14 @@ +__all__ = ['FFI', 'VerificationError', 'VerificationMissing', 'CDefError', + 'FFIError'] + +from .api import FFI +from .error import CDefError, FFIError, VerificationError, VerificationMissing +from .error import PkgConfigError + +__version__ = "1.15.1" +__version_info__ = (1, 15, 1) + +# The verifier module file names are based on the CRC32 of a string that +# contains the following version number. It may be older than __version__ +# if nothing is clearly incompatible. +__version_verifier_modules__ = "0.8.6" diff --git a/dist/ba_data/python-site-packages/cffi/_cffi_errors.h b/dist/ba_data/python-site-packages/cffi/_cffi_errors.h new file mode 100644 index 0000000..158e059 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/_cffi_errors.h @@ -0,0 +1,149 @@ +#ifndef CFFI_MESSAGEBOX +# ifdef _MSC_VER +# define CFFI_MESSAGEBOX 1 +# else +# define CFFI_MESSAGEBOX 0 +# endif +#endif + + +#if CFFI_MESSAGEBOX +/* Windows only: logic to take the Python-CFFI embedding logic + initialization errors and display them in a background thread + with MessageBox. The idea is that if the whole program closes + as a result of this problem, then likely it is already a console + program and you can read the stderr output in the console too. + If it is not a console program, then it will likely show its own + dialog to complain, or generally not abruptly close, and for this + case the background thread should stay alive. +*/ +static void *volatile _cffi_bootstrap_text; + +static PyObject *_cffi_start_error_capture(void) +{ + PyObject *result = NULL; + PyObject *x, *m, *bi; + + if (InterlockedCompareExchangePointer(&_cffi_bootstrap_text, + (void *)1, NULL) != NULL) + return (PyObject *)1; + + m = PyImport_AddModule("_cffi_error_capture"); + if (m == NULL) + goto error; + + result = PyModule_GetDict(m); + if (result == NULL) + goto error; + +#if PY_MAJOR_VERSION >= 3 + bi = PyImport_ImportModule("builtins"); +#else + bi = PyImport_ImportModule("__builtin__"); +#endif + if (bi == NULL) + goto error; + PyDict_SetItemString(result, "__builtins__", bi); + Py_DECREF(bi); + + x = PyRun_String( + "import sys\n" + "class FileLike:\n" + " def write(self, x):\n" + " try:\n" + " of.write(x)\n" + " except: pass\n" + " self.buf += x\n" + " def flush(self):\n" + " pass\n" + "fl = FileLike()\n" + "fl.buf = ''\n" + "of = sys.stderr\n" + "sys.stderr = fl\n" + "def done():\n" + " sys.stderr = of\n" + " return fl.buf\n", /* make sure the returned value stays alive */ + Py_file_input, + result, result); + Py_XDECREF(x); + + error: + if (PyErr_Occurred()) + { + PyErr_WriteUnraisable(Py_None); + PyErr_Clear(); + } + return result; +} + +#pragma comment(lib, "user32.lib") + +static DWORD WINAPI _cffi_bootstrap_dialog(LPVOID ignored) +{ + Sleep(666); /* may be interrupted if the whole process is closing */ +#if PY_MAJOR_VERSION >= 3 + MessageBoxW(NULL, (wchar_t *)_cffi_bootstrap_text, + L"Python-CFFI error", + MB_OK | MB_ICONERROR); +#else + MessageBoxA(NULL, (char *)_cffi_bootstrap_text, + "Python-CFFI error", + MB_OK | MB_ICONERROR); +#endif + _cffi_bootstrap_text = NULL; + return 0; +} + +static void _cffi_stop_error_capture(PyObject *ecap) +{ + PyObject *s; + void *text; + + if (ecap == (PyObject *)1) + return; + + if (ecap == NULL) + goto error; + + s = PyRun_String("done()", Py_eval_input, ecap, ecap); + if (s == NULL) + goto error; + + /* Show a dialog box, but in a background thread, and + never show multiple dialog boxes at once. */ +#if PY_MAJOR_VERSION >= 3 + text = PyUnicode_AsWideCharString(s, NULL); +#else + text = PyString_AsString(s); +#endif + + _cffi_bootstrap_text = text; + + if (text != NULL) + { + HANDLE h; + h = CreateThread(NULL, 0, _cffi_bootstrap_dialog, + NULL, 0, NULL); + if (h != NULL) + CloseHandle(h); + } + /* decref the string, but it should stay alive as 'fl.buf' + in the small module above. It will really be freed only if + we later get another similar error. So it's a leak of at + most one copy of the small module. That's fine for this + situation which is usually a "fatal error" anyway. */ + Py_DECREF(s); + PyErr_Clear(); + return; + + error: + _cffi_bootstrap_text = NULL; + PyErr_Clear(); +} + +#else + +static PyObject *_cffi_start_error_capture(void) { return NULL; } +static void _cffi_stop_error_capture(PyObject *ecap) { } + +#endif diff --git a/dist/ba_data/python-site-packages/cffi/_cffi_include.h b/dist/ba_data/python-site-packages/cffi/_cffi_include.h new file mode 100644 index 0000000..e4c0a67 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/_cffi_include.h @@ -0,0 +1,385 @@ +#define _CFFI_ + +/* We try to define Py_LIMITED_API before including Python.h. + + Mess: we can only define it if Py_DEBUG, Py_TRACE_REFS and + Py_REF_DEBUG are not defined. This is a best-effort approximation: + we can learn about Py_DEBUG from pyconfig.h, but it is unclear if + the same works for the other two macros. Py_DEBUG implies them, + but not the other way around. + + The implementation is messy (issue #350): on Windows, with _MSC_VER, + we have to define Py_LIMITED_API even before including pyconfig.h. + In that case, we guess what pyconfig.h will do to the macros above, + and check our guess after the #include. + + Note that on Windows, with CPython 3.x, you need >= 3.5 and virtualenv + version >= 16.0.0. With older versions of either, you don't get a + copy of PYTHON3.DLL in the virtualenv. We can't check the version of + CPython *before* we even include pyconfig.h. ffi.set_source() puts + a ``#define _CFFI_NO_LIMITED_API'' at the start of this file if it is + running on Windows < 3.5, as an attempt at fixing it, but that's + arguably wrong because it may not be the target version of Python. + Still better than nothing I guess. As another workaround, you can + remove the definition of Py_LIMITED_API here. + + See also 'py_limited_api' in cffi/setuptools_ext.py. +*/ +#if !defined(_CFFI_USE_EMBEDDING) && !defined(Py_LIMITED_API) +# ifdef _MSC_VER +# if !defined(_DEBUG) && !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) && !defined(_CFFI_NO_LIMITED_API) +# define Py_LIMITED_API +# endif +# include + /* sanity-check: Py_LIMITED_API will cause crashes if any of these + are also defined. Normally, the Python file PC/pyconfig.h does not + cause any of these to be defined, with the exception that _DEBUG + causes Py_DEBUG. Double-check that. */ +# ifdef Py_LIMITED_API +# if defined(Py_DEBUG) +# error "pyconfig.h unexpectedly defines Py_DEBUG, but Py_LIMITED_API is set" +# endif +# if defined(Py_TRACE_REFS) +# error "pyconfig.h unexpectedly defines Py_TRACE_REFS, but Py_LIMITED_API is set" +# endif +# if defined(Py_REF_DEBUG) +# error "pyconfig.h unexpectedly defines Py_REF_DEBUG, but Py_LIMITED_API is set" +# endif +# endif +# else +# include +# if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) && !defined(_CFFI_NO_LIMITED_API) +# define Py_LIMITED_API +# endif +# endif +#endif + +#include +#ifdef __cplusplus +extern "C" { +#endif +#include +#include "parse_c_type.h" + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif + +#ifdef __GNUC__ +# define _CFFI_UNUSED_FN __attribute__((unused)) +#else +# define _CFFI_UNUSED_FN /* nothing */ +#endif + +#ifdef __cplusplus +# ifndef _Bool + typedef bool _Bool; /* semi-hackish: C++ has no _Bool; bool is builtin */ +# endif +#endif + +/********** CPython-specific section **********/ +#ifndef PYPY_VERSION + + +#if PY_MAJOR_VERSION >= 3 +# define PyInt_FromLong PyLong_FromLong +#endif + +#define _cffi_from_c_double PyFloat_FromDouble +#define _cffi_from_c_float PyFloat_FromDouble +#define _cffi_from_c_long PyInt_FromLong +#define _cffi_from_c_ulong PyLong_FromUnsignedLong +#define _cffi_from_c_longlong PyLong_FromLongLong +#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong +#define _cffi_from_c__Bool PyBool_FromLong + +#define _cffi_to_c_double PyFloat_AsDouble +#define _cffi_to_c_float PyFloat_AsDouble + +#define _cffi_from_c_int(x, type) \ + (((type)-1) > 0 ? /* unsigned */ \ + (sizeof(type) < sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + sizeof(type) == sizeof(long) ? \ + PyLong_FromUnsignedLong((unsigned long)x) : \ + PyLong_FromUnsignedLongLong((unsigned long long)x)) : \ + (sizeof(type) <= sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + PyLong_FromLongLong((long long)x))) + +#define _cffi_to_c_int(o, type) \ + ((type)( \ + sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \ + : (type)_cffi_to_c_i8(o)) : \ + sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o) \ + : (type)_cffi_to_c_i16(o)) : \ + sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o) \ + : (type)_cffi_to_c_i32(o)) : \ + sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \ + : (type)_cffi_to_c_i64(o)) : \ + (Py_FatalError("unsupported size for type " #type), (type)0))) + +#define _cffi_to_c_i8 \ + ((int(*)(PyObject *))_cffi_exports[1]) +#define _cffi_to_c_u8 \ + ((int(*)(PyObject *))_cffi_exports[2]) +#define _cffi_to_c_i16 \ + ((int(*)(PyObject *))_cffi_exports[3]) +#define _cffi_to_c_u16 \ + ((int(*)(PyObject *))_cffi_exports[4]) +#define _cffi_to_c_i32 \ + ((int(*)(PyObject *))_cffi_exports[5]) +#define _cffi_to_c_u32 \ + ((unsigned int(*)(PyObject *))_cffi_exports[6]) +#define _cffi_to_c_i64 \ + ((long long(*)(PyObject *))_cffi_exports[7]) +#define _cffi_to_c_u64 \ + ((unsigned long long(*)(PyObject *))_cffi_exports[8]) +#define _cffi_to_c_char \ + ((int(*)(PyObject *))_cffi_exports[9]) +#define _cffi_from_c_pointer \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[10]) +#define _cffi_to_c_pointer \ + ((char *(*)(PyObject *, struct _cffi_ctypedescr *))_cffi_exports[11]) +#define _cffi_get_struct_layout \ + not used any more +#define _cffi_restore_errno \ + ((void(*)(void))_cffi_exports[13]) +#define _cffi_save_errno \ + ((void(*)(void))_cffi_exports[14]) +#define _cffi_from_c_char \ + ((PyObject *(*)(char))_cffi_exports[15]) +#define _cffi_from_c_deref \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[16]) +#define _cffi_to_c \ + ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[17]) +#define _cffi_from_c_struct \ + ((PyObject *(*)(char *, struct _cffi_ctypedescr *))_cffi_exports[18]) +#define _cffi_to_c_wchar_t \ + ((_cffi_wchar_t(*)(PyObject *))_cffi_exports[19]) +#define _cffi_from_c_wchar_t \ + ((PyObject *(*)(_cffi_wchar_t))_cffi_exports[20]) +#define _cffi_to_c_long_double \ + ((long double(*)(PyObject *))_cffi_exports[21]) +#define _cffi_to_c__Bool \ + ((_Bool(*)(PyObject *))_cffi_exports[22]) +#define _cffi_prepare_pointer_call_argument \ + ((Py_ssize_t(*)(struct _cffi_ctypedescr *, \ + PyObject *, char **))_cffi_exports[23]) +#define _cffi_convert_array_from_object \ + ((int(*)(char *, struct _cffi_ctypedescr *, PyObject *))_cffi_exports[24]) +#define _CFFI_CPIDX 25 +#define _cffi_call_python \ + ((void(*)(struct _cffi_externpy_s *, char *))_cffi_exports[_CFFI_CPIDX]) +#define _cffi_to_c_wchar3216_t \ + ((int(*)(PyObject *))_cffi_exports[26]) +#define _cffi_from_c_wchar3216_t \ + ((PyObject *(*)(int))_cffi_exports[27]) +#define _CFFI_NUM_EXPORTS 28 + +struct _cffi_ctypedescr; + +static void *_cffi_exports[_CFFI_NUM_EXPORTS]; + +#define _cffi_type(index) ( \ + assert((((uintptr_t)_cffi_types[index]) & 1) == 0), \ + (struct _cffi_ctypedescr *)_cffi_types[index]) + +static PyObject *_cffi_init(const char *module_name, Py_ssize_t version, + const struct _cffi_type_context_s *ctx) +{ + PyObject *module, *o_arg, *new_module; + void *raw[] = { + (void *)module_name, + (void *)version, + (void *)_cffi_exports, + (void *)ctx, + }; + + module = PyImport_ImportModule("_cffi_backend"); + if (module == NULL) + goto failure; + + o_arg = PyLong_FromVoidPtr((void *)raw); + if (o_arg == NULL) + goto failure; + + new_module = PyObject_CallMethod( + module, (char *)"_init_cffi_1_0_external_module", (char *)"O", o_arg); + + Py_DECREF(o_arg); + Py_DECREF(module); + return new_module; + + failure: + Py_XDECREF(module); + return NULL; +} + + +#ifdef HAVE_WCHAR_H +typedef wchar_t _cffi_wchar_t; +#else +typedef uint16_t _cffi_wchar_t; /* same random pick as _cffi_backend.c */ +#endif + +_CFFI_UNUSED_FN static uint16_t _cffi_to_c_char16_t(PyObject *o) +{ + if (sizeof(_cffi_wchar_t) == 2) + return (uint16_t)_cffi_to_c_wchar_t(o); + else + return (uint16_t)_cffi_to_c_wchar3216_t(o); +} + +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char16_t(uint16_t x) +{ + if (sizeof(_cffi_wchar_t) == 2) + return _cffi_from_c_wchar_t((_cffi_wchar_t)x); + else + return _cffi_from_c_wchar3216_t((int)x); +} + +_CFFI_UNUSED_FN static int _cffi_to_c_char32_t(PyObject *o) +{ + if (sizeof(_cffi_wchar_t) == 4) + return (int)_cffi_to_c_wchar_t(o); + else + return (int)_cffi_to_c_wchar3216_t(o); +} + +_CFFI_UNUSED_FN static PyObject *_cffi_from_c_char32_t(unsigned int x) +{ + if (sizeof(_cffi_wchar_t) == 4) + return _cffi_from_c_wchar_t((_cffi_wchar_t)x); + else + return _cffi_from_c_wchar3216_t((int)x); +} + +union _cffi_union_alignment_u { + unsigned char m_char; + unsigned short m_short; + unsigned int m_int; + unsigned long m_long; + unsigned long long m_longlong; + float m_float; + double m_double; + long double m_longdouble; +}; + +struct _cffi_freeme_s { + struct _cffi_freeme_s *next; + union _cffi_union_alignment_u alignment; +}; + +_CFFI_UNUSED_FN static int +_cffi_convert_array_argument(struct _cffi_ctypedescr *ctptr, PyObject *arg, + char **output_data, Py_ssize_t datasize, + struct _cffi_freeme_s **freeme) +{ + char *p; + if (datasize < 0) + return -1; + + p = *output_data; + if (p == NULL) { + struct _cffi_freeme_s *fp = (struct _cffi_freeme_s *)PyObject_Malloc( + offsetof(struct _cffi_freeme_s, alignment) + (size_t)datasize); + if (fp == NULL) + return -1; + fp->next = *freeme; + *freeme = fp; + p = *output_data = (char *)&fp->alignment; + } + memset((void *)p, 0, (size_t)datasize); + return _cffi_convert_array_from_object(p, ctptr, arg); +} + +_CFFI_UNUSED_FN static void +_cffi_free_array_arguments(struct _cffi_freeme_s *freeme) +{ + do { + void *p = (void *)freeme; + freeme = freeme->next; + PyObject_Free(p); + } while (freeme != NULL); +} + +/********** end CPython-specific section **********/ +#else +_CFFI_UNUSED_FN +static void (*_cffi_call_python_org)(struct _cffi_externpy_s *, char *); +# define _cffi_call_python _cffi_call_python_org +#endif + + +#define _cffi_array_len(array) (sizeof(array) / sizeof((array)[0])) + +#define _cffi_prim_int(size, sign) \ + ((size) == 1 ? ((sign) ? _CFFI_PRIM_INT8 : _CFFI_PRIM_UINT8) : \ + (size) == 2 ? ((sign) ? _CFFI_PRIM_INT16 : _CFFI_PRIM_UINT16) : \ + (size) == 4 ? ((sign) ? _CFFI_PRIM_INT32 : _CFFI_PRIM_UINT32) : \ + (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) : \ + _CFFI__UNKNOWN_PRIM) + +#define _cffi_prim_float(size) \ + ((size) == sizeof(float) ? _CFFI_PRIM_FLOAT : \ + (size) == sizeof(double) ? _CFFI_PRIM_DOUBLE : \ + (size) == sizeof(long double) ? _CFFI__UNKNOWN_LONG_DOUBLE : \ + _CFFI__UNKNOWN_FLOAT_PRIM) + +#define _cffi_check_int(got, got_nonpos, expected) \ + ((got_nonpos) == (expected <= 0) && \ + (got) == (unsigned long long)expected) + +#ifdef MS_WIN32 +# define _cffi_stdcall __stdcall +#else +# define _cffi_stdcall /* nothing */ +#endif + +#ifdef __cplusplus +} +#endif diff --git a/dist/ba_data/python-site-packages/cffi/_embedding.h b/dist/ba_data/python-site-packages/cffi/_embedding.h new file mode 100644 index 0000000..8e8df88 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/_embedding.h @@ -0,0 +1,528 @@ + +/***** Support code for embedding *****/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#if defined(_WIN32) +# define CFFI_DLLEXPORT __declspec(dllexport) +#elif defined(__GNUC__) +# define CFFI_DLLEXPORT __attribute__((visibility("default"))) +#else +# define CFFI_DLLEXPORT /* nothing */ +#endif + + +/* There are two global variables of type _cffi_call_python_fnptr: + + * _cffi_call_python, which we declare just below, is the one called + by ``extern "Python"`` implementations. + + * _cffi_call_python_org, which on CPython is actually part of the + _cffi_exports[] array, is the function pointer copied from + _cffi_backend. If _cffi_start_python() fails, then this is set + to NULL; otherwise, it should never be NULL. + + After initialization is complete, both are equal. However, the + first one remains equal to &_cffi_start_and_call_python until the + very end of initialization, when we are (or should be) sure that + concurrent threads also see a completely initialized world, and + only then is it changed. +*/ +#undef _cffi_call_python +typedef void (*_cffi_call_python_fnptr)(struct _cffi_externpy_s *, char *); +static void _cffi_start_and_call_python(struct _cffi_externpy_s *, char *); +static _cffi_call_python_fnptr _cffi_call_python = &_cffi_start_and_call_python; + + +#ifndef _MSC_VER + /* --- Assuming a GCC not infinitely old --- */ +# define cffi_compare_and_swap(l,o,n) __sync_bool_compare_and_swap(l,o,n) +# define cffi_write_barrier() __sync_synchronize() +# if !defined(__amd64__) && !defined(__x86_64__) && \ + !defined(__i386__) && !defined(__i386) +# define cffi_read_barrier() __sync_synchronize() +# else +# define cffi_read_barrier() (void)0 +# endif +#else + /* --- Windows threads version --- */ +# include +# define cffi_compare_and_swap(l,o,n) \ + (InterlockedCompareExchangePointer(l,n,o) == (o)) +# define cffi_write_barrier() InterlockedCompareExchange(&_cffi_dummy,0,0) +# define cffi_read_barrier() (void)0 +static volatile LONG _cffi_dummy; +#endif + +#ifdef WITH_THREAD +# ifndef _MSC_VER +# include + static pthread_mutex_t _cffi_embed_startup_lock; +# else + static CRITICAL_SECTION _cffi_embed_startup_lock; +# endif + static char _cffi_embed_startup_lock_ready = 0; +#endif + +static void _cffi_acquire_reentrant_mutex(void) +{ + static void *volatile lock = NULL; + + while (!cffi_compare_and_swap(&lock, NULL, (void *)1)) { + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: pthread_mutex_init() should be very fast, and + this is only run at start-up anyway. */ + } + +#ifdef WITH_THREAD + if (!_cffi_embed_startup_lock_ready) { +# ifndef _MSC_VER + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&_cffi_embed_startup_lock, &attr); +# else + InitializeCriticalSection(&_cffi_embed_startup_lock); +# endif + _cffi_embed_startup_lock_ready = 1; + } +#endif + + while (!cffi_compare_and_swap(&lock, (void *)1, NULL)) + ; + +#ifndef _MSC_VER + pthread_mutex_lock(&_cffi_embed_startup_lock); +#else + EnterCriticalSection(&_cffi_embed_startup_lock); +#endif +} + +static void _cffi_release_reentrant_mutex(void) +{ +#ifndef _MSC_VER + pthread_mutex_unlock(&_cffi_embed_startup_lock); +#else + LeaveCriticalSection(&_cffi_embed_startup_lock); +#endif +} + + +/********** CPython-specific section **********/ +#ifndef PYPY_VERSION + +#include "_cffi_errors.h" + + +#define _cffi_call_python_org _cffi_exports[_CFFI_CPIDX] + +PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(void); /* forward */ + +static void _cffi_py_initialize(void) +{ + /* XXX use initsigs=0, which "skips initialization registration of + signal handlers, which might be useful when Python is + embedded" according to the Python docs. But review and think + if it should be a user-controllable setting. + + XXX we should also give a way to write errors to a buffer + instead of to stderr. + + XXX if importing 'site' fails, CPython (any version) calls + exit(). Should we try to work around this behavior here? + */ + Py_InitializeEx(0); +} + +static int _cffi_initialize_python(void) +{ + /* This initializes Python, imports _cffi_backend, and then the + present .dll/.so is set up as a CPython C extension module. + */ + int result; + PyGILState_STATE state; + PyObject *pycode=NULL, *global_dict=NULL, *x; + PyObject *builtins; + + state = PyGILState_Ensure(); + + /* Call the initxxx() function from the present module. It will + create and initialize us as a CPython extension module, instead + of letting the startup Python code do it---it might reimport + the same .dll/.so and get maybe confused on some platforms. + It might also have troubles locating the .dll/.so again for all + I know. + */ + (void)_CFFI_PYTHON_STARTUP_FUNC(); + if (PyErr_Occurred()) + goto error; + + /* Now run the Python code provided to ffi.embedding_init_code(). + */ + pycode = Py_CompileString(_CFFI_PYTHON_STARTUP_CODE, + "", + Py_file_input); + if (pycode == NULL) + goto error; + global_dict = PyDict_New(); + if (global_dict == NULL) + goto error; + builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + if (PyDict_SetItemString(global_dict, "__builtins__", builtins) < 0) + goto error; + x = PyEval_EvalCode( +#if PY_MAJOR_VERSION < 3 + (PyCodeObject *) +#endif + pycode, global_dict, global_dict); + if (x == NULL) + goto error; + Py_DECREF(x); + + /* Done! Now if we've been called from + _cffi_start_and_call_python() in an ``extern "Python"``, we can + only hope that the Python code did correctly set up the + corresponding @ffi.def_extern() function. Otherwise, the + general logic of ``extern "Python"`` functions (inside the + _cffi_backend module) will find that the reference is still + missing and print an error. + */ + result = 0; + done: + Py_XDECREF(pycode); + Py_XDECREF(global_dict); + PyGILState_Release(state); + return result; + + error:; + { + /* Print as much information as potentially useful. + Debugging load-time failures with embedding is not fun + */ + PyObject *ecap; + PyObject *exception, *v, *tb, *f, *modules, *mod; + PyErr_Fetch(&exception, &v, &tb); + ecap = _cffi_start_error_capture(); + f = PySys_GetObject((char *)"stderr"); + if (f != NULL && f != Py_None) { + PyFile_WriteString( + "Failed to initialize the Python-CFFI embedding logic:\n\n", f); + } + + if (exception != NULL) { + PyErr_NormalizeException(&exception, &v, &tb); + PyErr_Display(exception, v, tb); + } + Py_XDECREF(exception); + Py_XDECREF(v); + Py_XDECREF(tb); + + if (f != NULL && f != Py_None) { + PyFile_WriteString("\nFrom: " _CFFI_MODULE_NAME + "\ncompiled with cffi version: 1.15.1" + "\n_cffi_backend module: ", f); + modules = PyImport_GetModuleDict(); + mod = PyDict_GetItemString(modules, "_cffi_backend"); + if (mod == NULL) { + PyFile_WriteString("not loaded", f); + } + else { + v = PyObject_GetAttrString(mod, "__file__"); + PyFile_WriteObject(v, f, 0); + Py_XDECREF(v); + } + PyFile_WriteString("\nsys.path: ", f); + PyFile_WriteObject(PySys_GetObject((char *)"path"), f, 0); + PyFile_WriteString("\n\n", f); + } + _cffi_stop_error_capture(ecap); + } + result = -1; + goto done; +} + +#if PY_VERSION_HEX < 0x03080000 +PyAPI_DATA(char *) _PyParser_TokenNames[]; /* from CPython */ +#endif + +static int _cffi_carefully_make_gil(void) +{ + /* This does the basic initialization of Python. It can be called + completely concurrently from unrelated threads. It assumes + that we don't hold the GIL before (if it exists), and we don't + hold it afterwards. + + (What it really does used to be completely different in Python 2 + and Python 3, with the Python 2 solution avoiding the spin-lock + around the Py_InitializeEx() call. However, after recent changes + to CPython 2.7 (issue #358) it no longer works. So we use the + Python 3 solution everywhere.) + + This initializes Python by calling Py_InitializeEx(). + Important: this must not be called concurrently at all. + So we use a global variable as a simple spin lock. This global + variable must be from 'libpythonX.Y.so', not from this + cffi-based extension module, because it must be shared from + different cffi-based extension modules. + + In Python < 3.8, we choose + _PyParser_TokenNames[0] as a completely arbitrary pointer value + that is never written to. The default is to point to the + string "ENDMARKER". We change it temporarily to point to the + next character in that string. (Yes, I know it's REALLY + obscure.) + + In Python >= 3.8, this string array is no longer writable, so + instead we pick PyCapsuleType.tp_version_tag. We can't change + Python < 3.8 because someone might use a mixture of cffi + embedded modules, some of which were compiled before this file + changed. + */ + +#ifdef WITH_THREAD +# if PY_VERSION_HEX < 0x03080000 + char *volatile *lock = (char *volatile *)_PyParser_TokenNames; + char *old_value, *locked_value; + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = old_value + 1; + if (old_value[0] == 'E') { + assert(old_value[1] == 'N'); + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value[0] == 'N'); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# else + int volatile *lock = (int volatile *)&PyCapsule_Type.tp_version_tag; + int old_value, locked_value; + assert(!(PyCapsule_Type.tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG)); + + while (1) { /* spin loop */ + old_value = *lock; + locked_value = -42; + if (old_value == 0) { + if (cffi_compare_and_swap(lock, old_value, locked_value)) + break; + } + else { + assert(old_value == locked_value); + /* should ideally do a spin loop instruction here, but + hard to do it portably and doesn't really matter I + think: PyEval_InitThreads() should be very fast, and + this is only run at start-up anyway. */ + } + } +# endif +#endif + + /* call Py_InitializeEx() */ + if (!Py_IsInitialized()) { + _cffi_py_initialize(); +#if PY_VERSION_HEX < 0x03070000 + PyEval_InitThreads(); +#endif + PyEval_SaveThread(); /* release the GIL */ + /* the returned tstate must be the one that has been stored into the + autoTLSkey by _PyGILState_Init() called from Py_Initialize(). */ + } + else { +#if PY_VERSION_HEX < 0x03070000 + /* PyEval_InitThreads() is always a no-op from CPython 3.7 */ + PyGILState_STATE state = PyGILState_Ensure(); + PyEval_InitThreads(); + PyGILState_Release(state); +#endif + } + +#ifdef WITH_THREAD + /* release the lock */ + while (!cffi_compare_and_swap(lock, locked_value, old_value)) + ; +#endif + + return 0; +} + +/********** end CPython-specific section **********/ + + +#else + + +/********** PyPy-specific section **********/ + +PyMODINIT_FUNC _CFFI_PYTHON_STARTUP_FUNC(const void *[]); /* forward */ + +static struct _cffi_pypy_init_s { + const char *name; + void *func; /* function pointer */ + const char *code; +} _cffi_pypy_init = { + _CFFI_MODULE_NAME, + _CFFI_PYTHON_STARTUP_FUNC, + _CFFI_PYTHON_STARTUP_CODE, +}; + +extern int pypy_carefully_make_gil(const char *); +extern int pypy_init_embedded_cffi_module(int, struct _cffi_pypy_init_s *); + +static int _cffi_carefully_make_gil(void) +{ + return pypy_carefully_make_gil(_CFFI_MODULE_NAME); +} + +static int _cffi_initialize_python(void) +{ + return pypy_init_embedded_cffi_module(0xB011, &_cffi_pypy_init); +} + +/********** end PyPy-specific section **********/ + + +#endif + + +#ifdef __GNUC__ +__attribute__((noinline)) +#endif +static _cffi_call_python_fnptr _cffi_start_python(void) +{ + /* Delicate logic to initialize Python. This function can be + called multiple times concurrently, e.g. when the process calls + its first ``extern "Python"`` functions in multiple threads at + once. It can also be called recursively, in which case we must + ignore it. We also have to consider what occurs if several + different cffi-based extensions reach this code in parallel + threads---it is a different copy of the code, then, and we + can't have any shared global variable unless it comes from + 'libpythonX.Y.so'. + + Idea: + + * _cffi_carefully_make_gil(): "carefully" call + PyEval_InitThreads() (possibly with Py_InitializeEx() first). + + * then we use a (local) custom lock to make sure that a call to this + cffi-based extension will wait if another call to the *same* + extension is running the initialization in another thread. + It is reentrant, so that a recursive call will not block, but + only one from a different thread. + + * then we grab the GIL and (Python 2) we call Py_InitializeEx(). + At this point, concurrent calls to Py_InitializeEx() are not + possible: we have the GIL. + + * do the rest of the specific initialization, which may + temporarily release the GIL but not the custom lock. + Only release the custom lock when we are done. + */ + static char called = 0; + + if (_cffi_carefully_make_gil() != 0) + return NULL; + + _cffi_acquire_reentrant_mutex(); + + /* Here the GIL exists, but we don't have it. We're only protected + from concurrency by the reentrant mutex. */ + + /* This file only initializes the embedded module once, the first + time this is called, even if there are subinterpreters. */ + if (!called) { + called = 1; /* invoke _cffi_initialize_python() only once, + but don't set '_cffi_call_python' right now, + otherwise concurrent threads won't call + this function at all (we need them to wait) */ + if (_cffi_initialize_python() == 0) { + /* now initialization is finished. Switch to the fast-path. */ + + /* We would like nobody to see the new value of + '_cffi_call_python' without also seeing the rest of the + data initialized. However, this is not possible. But + the new value of '_cffi_call_python' is the function + 'cffi_call_python()' from _cffi_backend. So: */ + cffi_write_barrier(); + /* ^^^ we put a write barrier here, and a corresponding + read barrier at the start of cffi_call_python(). This + ensures that after that read barrier, we see everything + done here before the write barrier. + */ + + assert(_cffi_call_python_org != NULL); + _cffi_call_python = (_cffi_call_python_fnptr)_cffi_call_python_org; + } + else { + /* initialization failed. Reset this to NULL, even if it was + already set to some other value. Future calls to + _cffi_start_python() are still forced to occur, and will + always return NULL from now on. */ + _cffi_call_python_org = NULL; + } + } + + _cffi_release_reentrant_mutex(); + + return (_cffi_call_python_fnptr)_cffi_call_python_org; +} + +static +void _cffi_start_and_call_python(struct _cffi_externpy_s *externpy, char *args) +{ + _cffi_call_python_fnptr fnptr; + int current_err = errno; +#ifdef _MSC_VER + int current_lasterr = GetLastError(); +#endif + fnptr = _cffi_start_python(); + if (fnptr == NULL) { + fprintf(stderr, "function %s() called, but initialization code " + "failed. Returning 0.\n", externpy->name); + memset(args, 0, externpy->size_of_result); + } +#ifdef _MSC_VER + SetLastError(current_lasterr); +#endif + errno = current_err; + + if (fnptr != NULL) + fnptr(externpy, args); +} + + +/* The cffi_start_python() function makes sure Python is initialized + and our cffi module is set up. It can be called manually from the + user C code. The same effect is obtained automatically from any + dll-exported ``extern "Python"`` function. This function returns + -1 if initialization failed, 0 if all is OK. */ +_CFFI_UNUSED_FN +static int cffi_start_python(void) +{ + if (_cffi_call_python == &_cffi_start_and_call_python) { + if (_cffi_start_python() == NULL) + return -1; + } + cffi_read_barrier(); + return 0; +} + +#undef cffi_compare_and_swap +#undef cffi_write_barrier +#undef cffi_read_barrier + +#ifdef __cplusplus +} +#endif diff --git a/dist/ba_data/python-site-packages/cffi/api.py b/dist/ba_data/python-site-packages/cffi/api.py new file mode 100644 index 0000000..999a8ae --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/api.py @@ -0,0 +1,965 @@ +import sys, types +from .lock import allocate_lock +from .error import CDefError +from . import model + +try: + callable +except NameError: + # Python 3.1 + from collections import Callable + callable = lambda x: isinstance(x, Callable) + +try: + basestring +except NameError: + # Python 3.x + basestring = str + +_unspecified = object() + + + +class FFI(object): + r''' + The main top-level class that you instantiate once, or once per module. + + Example usage: + + ffi = FFI() + ffi.cdef(""" + int printf(const char *, ...); + """) + + C = ffi.dlopen(None) # standard library + -or- + C = ffi.verify() # use a C compiler: verify the decl above is right + + C.printf("hello, %s!\n", ffi.new("char[]", "world")) + ''' + + def __init__(self, backend=None): + """Create an FFI instance. The 'backend' argument is used to + select a non-default backend, mostly for tests. + """ + if backend is None: + # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with + # _cffi_backend.so compiled. + import _cffi_backend as backend + from . import __version__ + if backend.__version__ != __version__: + # bad version! Try to be as explicit as possible. + if hasattr(backend, '__file__'): + # CPython + raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. When we import the top-level '_cffi_backend' extension module, we get version %s, located in %r. The two versions should be equal; check your installation." % ( + __version__, __file__, + backend.__version__, backend.__file__)) + else: + # PyPy + raise Exception("Version mismatch: this is the 'cffi' package version %s, located in %r. This interpreter comes with a built-in '_cffi_backend' module, which is version %s. The two versions should be equal; check your installation." % ( + __version__, __file__, backend.__version__)) + # (If you insist you can also try to pass the option + # 'backend=backend_ctypes.CTypesBackend()', but don't + # rely on it! It's probably not going to work well.) + + from . import cparser + self._backend = backend + self._lock = allocate_lock() + self._parser = cparser.Parser() + self._cached_btypes = {} + self._parsed_types = types.ModuleType('parsed_types').__dict__ + self._new_types = types.ModuleType('new_types').__dict__ + self._function_caches = [] + self._libraries = [] + self._cdefsources = [] + self._included_ffis = [] + self._windows_unicode = None + self._init_once_cache = {} + self._cdef_version = None + self._embedding = None + self._typecache = model.get_typecache(backend) + if hasattr(backend, 'set_ffi'): + backend.set_ffi(self) + for name in list(backend.__dict__): + if name.startswith('RTLD_'): + setattr(self, name, getattr(backend, name)) + # + with self._lock: + self.BVoidP = self._get_cached_btype(model.voidp_type) + self.BCharA = self._get_cached_btype(model.char_array_type) + if isinstance(backend, types.ModuleType): + # _cffi_backend: attach these constants to the class + if not hasattr(FFI, 'NULL'): + FFI.NULL = self.cast(self.BVoidP, 0) + FFI.CData, FFI.CType = backend._get_types() + else: + # ctypes backend: attach these constants to the instance + self.NULL = self.cast(self.BVoidP, 0) + self.CData, self.CType = backend._get_types() + self.buffer = backend.buffer + + def cdef(self, csource, override=False, packed=False, pack=None): + """Parse the given C source. This registers all declared functions, + types, and global variables. The functions and global variables can + then be accessed via either 'ffi.dlopen()' or 'ffi.verify()'. + The types can be used in 'ffi.new()' and other functions. + If 'packed' is specified as True, all structs declared inside this + cdef are packed, i.e. laid out without any field alignment at all. + Alternatively, 'pack' can be a small integer, and requests for + alignment greater than that are ignored (pack=1 is equivalent to + packed=True). + """ + self._cdef(csource, override=override, packed=packed, pack=pack) + + def embedding_api(self, csource, packed=False, pack=None): + self._cdef(csource, packed=packed, pack=pack, dllexport=True) + if self._embedding is None: + self._embedding = '' + + def _cdef(self, csource, override=False, **options): + if not isinstance(csource, str): # unicode, on Python 2 + if not isinstance(csource, basestring): + raise TypeError("cdef() argument must be a string") + csource = csource.encode('ascii') + with self._lock: + self._cdef_version = object() + self._parser.parse(csource, override=override, **options) + self._cdefsources.append(csource) + if override: + for cache in self._function_caches: + cache.clear() + finishlist = self._parser._recomplete + if finishlist: + self._parser._recomplete = [] + for tp in finishlist: + tp.finish_backend_type(self, finishlist) + + def dlopen(self, name, flags=0): + """Load and return a dynamic library identified by 'name'. + The standard C library can be loaded by passing None. + Note that functions and types declared by 'ffi.cdef()' are not + linked to a particular library, just like C headers; in the + library we only look for the actual (untyped) symbols. + """ + if not (isinstance(name, basestring) or + name is None or + isinstance(name, self.CData)): + raise TypeError("dlopen(name): name must be a file name, None, " + "or an already-opened 'void *' handle") + with self._lock: + lib, function_cache = _make_ffi_library(self, name, flags) + self._function_caches.append(function_cache) + self._libraries.append(lib) + return lib + + def dlclose(self, lib): + """Close a library obtained with ffi.dlopen(). After this call, + access to functions or variables from the library will fail + (possibly with a segmentation fault). + """ + type(lib).__cffi_close__(lib) + + def _typeof_locked(self, cdecl): + # call me with the lock! + key = cdecl + if key in self._parsed_types: + return self._parsed_types[key] + # + if not isinstance(cdecl, str): # unicode, on Python 2 + cdecl = cdecl.encode('ascii') + # + type = self._parser.parse_type(cdecl) + really_a_function_type = type.is_raw_function + if really_a_function_type: + type = type.as_function_pointer() + btype = self._get_cached_btype(type) + result = btype, really_a_function_type + self._parsed_types[key] = result + return result + + def _typeof(self, cdecl, consider_function_as_funcptr=False): + # string -> ctype object + try: + result = self._parsed_types[cdecl] + except KeyError: + with self._lock: + result = self._typeof_locked(cdecl) + # + btype, really_a_function_type = result + if really_a_function_type and not consider_function_as_funcptr: + raise CDefError("the type %r is a function type, not a " + "pointer-to-function type" % (cdecl,)) + return btype + + def typeof(self, cdecl): + """Parse the C type given as a string and return the + corresponding object. + It can also be used on 'cdata' instance to get its C type. + """ + if isinstance(cdecl, basestring): + return self._typeof(cdecl) + if isinstance(cdecl, self.CData): + return self._backend.typeof(cdecl) + if isinstance(cdecl, types.BuiltinFunctionType): + res = _builtin_function_type(cdecl) + if res is not None: + return res + if (isinstance(cdecl, types.FunctionType) + and hasattr(cdecl, '_cffi_base_type')): + with self._lock: + return self._get_cached_btype(cdecl._cffi_base_type) + raise TypeError(type(cdecl)) + + def sizeof(self, cdecl): + """Return the size in bytes of the argument. It can be a + string naming a C type, or a 'cdata' instance. + """ + if isinstance(cdecl, basestring): + BType = self._typeof(cdecl) + return self._backend.sizeof(BType) + else: + return self._backend.sizeof(cdecl) + + def alignof(self, cdecl): + """Return the natural alignment size in bytes of the C type + given as a string. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.alignof(cdecl) + + def offsetof(self, cdecl, *fields_or_indexes): + """Return the offset of the named field inside the given + structure or array, which must be given as a C type name. + You can give several field names in case of nested structures. + You can also give numeric values which correspond to array + items, in case of an array type. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._typeoffsetof(cdecl, *fields_or_indexes)[1] + + def new(self, cdecl, init=None): + """Allocate an instance according to the specified C type and + return a pointer to it. The specified C type must be either a + pointer or an array: ``new('X *')`` allocates an X and returns + a pointer to it, whereas ``new('X[n]')`` allocates an array of + n X'es and returns an array referencing it (which works + mostly like a pointer, like in C). You can also use + ``new('X[]', n)`` to allocate an array of a non-constant + length n. + + The memory is initialized following the rules of declaring a + global variable in C: by default it is zero-initialized, but + an explicit initializer can be given which can be used to + fill all or part of the memory. + + When the returned object goes out of scope, the memory + is freed. In other words the returned object has + ownership of the value of type 'cdecl' that it points to. This + means that the raw data can be used as long as this object is + kept alive, but must not be used for a longer time. Be careful + about that when copying the pointer to the memory somewhere + else, e.g. into another structure. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.newp(cdecl, init) + + def new_allocator(self, alloc=None, free=None, + should_clear_after_alloc=True): + """Return a new allocator, i.e. a function that behaves like ffi.new() + but uses the provided low-level 'alloc' and 'free' functions. + + 'alloc' is called with the size as argument. If it returns NULL, a + MemoryError is raised. 'free' is called with the result of 'alloc' + as argument. Both can be either Python function or directly C + functions. If 'free' is None, then no free function is called. + If both 'alloc' and 'free' are None, the default is used. + + If 'should_clear_after_alloc' is set to False, then the memory + returned by 'alloc' is assumed to be already cleared (or you are + fine with garbage); otherwise CFFI will clear it. + """ + compiled_ffi = self._backend.FFI() + allocator = compiled_ffi.new_allocator(alloc, free, + should_clear_after_alloc) + def allocate(cdecl, init=None): + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return allocator(cdecl, init) + return allocate + + def cast(self, cdecl, source): + """Similar to a C cast: returns an instance of the named C + type initialized with the given 'source'. The source is + casted between integers or pointers of any type. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.cast(cdecl, source) + + def string(self, cdata, maxlen=-1): + """Return a Python string (or unicode string) from the 'cdata'. + If 'cdata' is a pointer or array of characters or bytes, returns + the null-terminated string. The returned string extends until + the first null character, or at most 'maxlen' characters. If + 'cdata' is an array then 'maxlen' defaults to its length. + + If 'cdata' is a pointer or array of wchar_t, returns a unicode + string following the same rules. + + If 'cdata' is a single character or byte or a wchar_t, returns + it as a string or unicode string. + + If 'cdata' is an enum, returns the value of the enumerator as a + string, or 'NUMBER' if the value is out of range. + """ + return self._backend.string(cdata, maxlen) + + def unpack(self, cdata, length): + """Unpack an array of C data of the given length, + returning a Python string/unicode/list. + + If 'cdata' is a pointer to 'char', returns a byte string. + It does not stop at the first null. This is equivalent to: + ffi.buffer(cdata, length)[:] + + If 'cdata' is a pointer to 'wchar_t', returns a unicode string. + 'length' is measured in wchar_t's; it is not the size in bytes. + + If 'cdata' is a pointer to anything else, returns a list of + 'length' items. This is a faster equivalent to: + [cdata[i] for i in range(length)] + """ + return self._backend.unpack(cdata, length) + + #def buffer(self, cdata, size=-1): + # """Return a read-write buffer object that references the raw C data + # pointed to by the given 'cdata'. The 'cdata' must be a pointer or + # an array. Can be passed to functions expecting a buffer, or directly + # manipulated with: + # + # buf[:] get a copy of it in a regular string, or + # buf[idx] as a single character + # buf[:] = ... + # buf[idx] = ... change the content + # """ + # note that 'buffer' is a type, set on this instance by __init__ + + def from_buffer(self, cdecl, python_buffer=_unspecified, + require_writable=False): + """Return a cdata of the given type pointing to the data of the + given Python object, which must support the buffer interface. + Note that this is not meant to be used on the built-in types + str or unicode (you can build 'char[]' arrays explicitly) + but only on objects containing large quantities of raw data + in some other format, like 'array.array' or numpy arrays. + + The first argument is optional and default to 'char[]'. + """ + if python_buffer is _unspecified: + cdecl, python_buffer = self.BCharA, cdecl + elif isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + return self._backend.from_buffer(cdecl, python_buffer, + require_writable) + + def memmove(self, dest, src, n): + """ffi.memmove(dest, src, n) copies n bytes of memory from src to dest. + + Like the C function memmove(), the memory areas may overlap; + apart from that it behaves like the C function memcpy(). + + 'src' can be any cdata ptr or array, or any Python buffer object. + 'dest' can be any cdata ptr or array, or a writable Python buffer + object. The size to copy, 'n', is always measured in bytes. + + Unlike other methods, this one supports all Python buffer including + byte strings and bytearrays---but it still does not support + non-contiguous buffers. + """ + return self._backend.memmove(dest, src, n) + + def callback(self, cdecl, python_callable=None, error=None, onerror=None): + """Return a callback object or a decorator making such a + callback object. 'cdecl' must name a C function pointer type. + The callback invokes the specified 'python_callable' (which may + be provided either directly or via a decorator). Important: the + callback object must be manually kept alive for as long as the + callback may be invoked from the C level. + """ + def callback_decorator_wrap(python_callable): + if not callable(python_callable): + raise TypeError("the 'python_callable' argument " + "is not callable") + return self._backend.callback(cdecl, python_callable, + error, onerror) + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl, consider_function_as_funcptr=True) + if python_callable is None: + return callback_decorator_wrap # decorator mode + else: + return callback_decorator_wrap(python_callable) # direct mode + + def getctype(self, cdecl, replace_with=''): + """Return a string giving the C type 'cdecl', which may be itself + a string or a object. If 'replace_with' is given, it gives + extra text to append (or insert for more complicated C types), like + a variable name, or '*' to get actually the C type 'pointer-to-cdecl'. + """ + if isinstance(cdecl, basestring): + cdecl = self._typeof(cdecl) + replace_with = replace_with.strip() + if (replace_with.startswith('*') + and '&[' in self._backend.getcname(cdecl, '&')): + replace_with = '(%s)' % replace_with + elif replace_with and not replace_with[0] in '[(': + replace_with = ' ' + replace_with + return self._backend.getcname(cdecl, replace_with) + + def gc(self, cdata, destructor, size=0): + """Return a new cdata object that points to the same + data. Later, when this new cdata object is garbage-collected, + 'destructor(old_cdata_object)' will be called. + + The optional 'size' gives an estimate of the size, used to + trigger the garbage collection more eagerly. So far only used + on PyPy. It tells the GC that the returned object keeps alive + roughly 'size' bytes of external memory. + """ + return self._backend.gcp(cdata, destructor, size) + + def _get_cached_btype(self, type): + assert self._lock.acquire(False) is False + # call me with the lock! + try: + BType = self._cached_btypes[type] + except KeyError: + finishlist = [] + BType = type.get_cached_btype(self, finishlist) + for type in finishlist: + type.finish_backend_type(self, finishlist) + return BType + + def verify(self, source='', tmpdir=None, **kwargs): + """Verify that the current ffi signatures compile on this + machine, and return a dynamic library object. The dynamic + library can be used to call functions and access global + variables declared in this 'ffi'. The library is compiled + by the C compiler: it gives you C-level API compatibility + (including calling macros). This is unlike 'ffi.dlopen()', + which requires binary compatibility in the signatures. + """ + from .verifier import Verifier, _caller_dir_pycache + # + # If set_unicode(True) was called, insert the UNICODE and + # _UNICODE macro declarations + if self._windows_unicode: + self._apply_windows_unicode(kwargs) + # + # Set the tmpdir here, and not in Verifier.__init__: it picks + # up the caller's directory, which we want to be the caller of + # ffi.verify(), as opposed to the caller of Veritier(). + tmpdir = tmpdir or _caller_dir_pycache() + # + # Make a Verifier() and use it to load the library. + self.verifier = Verifier(self, source, tmpdir, **kwargs) + lib = self.verifier.load_library() + # + # Save the loaded library for keep-alive purposes, even + # if the caller doesn't keep it alive itself (it should). + self._libraries.append(lib) + return lib + + def _get_errno(self): + return self._backend.get_errno() + def _set_errno(self, errno): + self._backend.set_errno(errno) + errno = property(_get_errno, _set_errno, None, + "the value of 'errno' from/to the C calls") + + def getwinerror(self, code=-1): + return self._backend.getwinerror(code) + + def _pointer_to(self, ctype): + with self._lock: + return model.pointer_cache(self, ctype) + + def addressof(self, cdata, *fields_or_indexes): + """Return the address of a . + If 'fields_or_indexes' are given, returns the address of that + field or array item in the structure or array, recursively in + case of nested structures. + """ + try: + ctype = self._backend.typeof(cdata) + except TypeError: + if '__addressof__' in type(cdata).__dict__: + return type(cdata).__addressof__(cdata, *fields_or_indexes) + raise + if fields_or_indexes: + ctype, offset = self._typeoffsetof(ctype, *fields_or_indexes) + else: + if ctype.kind == "pointer": + raise TypeError("addressof(pointer)") + offset = 0 + ctypeptr = self._pointer_to(ctype) + return self._backend.rawaddressof(ctypeptr, cdata, offset) + + def _typeoffsetof(self, ctype, field_or_index, *fields_or_indexes): + ctype, offset = self._backend.typeoffsetof(ctype, field_or_index) + for field1 in fields_or_indexes: + ctype, offset1 = self._backend.typeoffsetof(ctype, field1, 1) + offset += offset1 + return ctype, offset + + def include(self, ffi_to_include): + """Includes the typedefs, structs, unions and enums defined + in another FFI instance. Usage is similar to a #include in C, + where a part of the program might include types defined in + another part for its own usage. Note that the include() + method has no effect on functions, constants and global + variables, which must anyway be accessed directly from the + lib object returned by the original FFI instance. + """ + if not isinstance(ffi_to_include, FFI): + raise TypeError("ffi.include() expects an argument that is also of" + " type cffi.FFI, not %r" % ( + type(ffi_to_include).__name__,)) + if ffi_to_include is self: + raise ValueError("self.include(self)") + with ffi_to_include._lock: + with self._lock: + self._parser.include(ffi_to_include._parser) + self._cdefsources.append('[') + self._cdefsources.extend(ffi_to_include._cdefsources) + self._cdefsources.append(']') + self._included_ffis.append(ffi_to_include) + + def new_handle(self, x): + return self._backend.newp_handle(self.BVoidP, x) + + def from_handle(self, x): + return self._backend.from_handle(x) + + def release(self, x): + self._backend.release(x) + + def set_unicode(self, enabled_flag): + """Windows: if 'enabled_flag' is True, enable the UNICODE and + _UNICODE defines in C, and declare the types like TCHAR and LPTCSTR + to be (pointers to) wchar_t. If 'enabled_flag' is False, + declare these types to be (pointers to) plain 8-bit characters. + This is mostly for backward compatibility; you usually want True. + """ + if self._windows_unicode is not None: + raise ValueError("set_unicode() can only be called once") + enabled_flag = bool(enabled_flag) + if enabled_flag: + self.cdef("typedef wchar_t TBYTE;" + "typedef wchar_t TCHAR;" + "typedef const wchar_t *LPCTSTR;" + "typedef const wchar_t *PCTSTR;" + "typedef wchar_t *LPTSTR;" + "typedef wchar_t *PTSTR;" + "typedef TBYTE *PTBYTE;" + "typedef TCHAR *PTCHAR;") + else: + self.cdef("typedef char TBYTE;" + "typedef char TCHAR;" + "typedef const char *LPCTSTR;" + "typedef const char *PCTSTR;" + "typedef char *LPTSTR;" + "typedef char *PTSTR;" + "typedef TBYTE *PTBYTE;" + "typedef TCHAR *PTCHAR;") + self._windows_unicode = enabled_flag + + def _apply_windows_unicode(self, kwds): + defmacros = kwds.get('define_macros', ()) + if not isinstance(defmacros, (list, tuple)): + raise TypeError("'define_macros' must be a list or tuple") + defmacros = list(defmacros) + [('UNICODE', '1'), + ('_UNICODE', '1')] + kwds['define_macros'] = defmacros + + def _apply_embedding_fix(self, kwds): + # must include an argument like "-lpython2.7" for the compiler + def ensure(key, value): + lst = kwds.setdefault(key, []) + if value not in lst: + lst.append(value) + # + if '__pypy__' in sys.builtin_module_names: + import os + if sys.platform == "win32": + # we need 'libpypy-c.lib'. Current distributions of + # pypy (>= 4.1) contain it as 'libs/python27.lib'. + pythonlib = "python{0[0]}{0[1]}".format(sys.version_info) + if hasattr(sys, 'prefix'): + ensure('library_dirs', os.path.join(sys.prefix, 'libs')) + else: + # we need 'libpypy-c.{so,dylib}', which should be by + # default located in 'sys.prefix/bin' for installed + # systems. + if sys.version_info < (3,): + pythonlib = "pypy-c" + else: + pythonlib = "pypy3-c" + if hasattr(sys, 'prefix'): + ensure('library_dirs', os.path.join(sys.prefix, 'bin')) + # On uninstalled pypy's, the libpypy-c is typically found in + # .../pypy/goal/. + if hasattr(sys, 'prefix'): + ensure('library_dirs', os.path.join(sys.prefix, 'pypy', 'goal')) + else: + if sys.platform == "win32": + template = "python%d%d" + if hasattr(sys, 'gettotalrefcount'): + template += '_d' + else: + try: + import sysconfig + except ImportError: # 2.6 + from distutils import sysconfig + template = "python%d.%d" + if sysconfig.get_config_var('DEBUG_EXT'): + template += sysconfig.get_config_var('DEBUG_EXT') + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + if hasattr(sys, 'abiflags'): + pythonlib += sys.abiflags + ensure('libraries', pythonlib) + if sys.platform == "win32": + ensure('extra_link_args', '/MANIFEST') + + def set_source(self, module_name, source, source_extension='.c', **kwds): + import os + if hasattr(self, '_assigned_source'): + raise ValueError("set_source() cannot be called several times " + "per ffi object") + if not isinstance(module_name, basestring): + raise TypeError("'module_name' must be a string") + if os.sep in module_name or (os.altsep and os.altsep in module_name): + raise ValueError("'module_name' must not contain '/': use a dotted " + "name to make a 'package.module' location") + self._assigned_source = (str(module_name), source, + source_extension, kwds) + + def set_source_pkgconfig(self, module_name, pkgconfig_libs, source, + source_extension='.c', **kwds): + from . import pkgconfig + if not isinstance(pkgconfig_libs, list): + raise TypeError("the pkgconfig_libs argument must be a list " + "of package names") + kwds2 = pkgconfig.flags_from_pkgconfig(pkgconfig_libs) + pkgconfig.merge_flags(kwds, kwds2) + self.set_source(module_name, source, source_extension, **kwds) + + def distutils_extension(self, tmpdir='build', verbose=True): + from distutils.dir_util import mkpath + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + if hasattr(self, 'verifier'): # fallback, 'tmpdir' ignored + return self.verifier.get_extension() + raise ValueError("set_source() must be called before" + " distutils_extension()") + module_name, source, source_extension, kwds = self._assigned_source + if source is None: + raise TypeError("distutils_extension() is only for C extension " + "modules, not for dlopen()-style pure Python " + "modules") + mkpath(tmpdir) + ext, updated = recompile(self, module_name, + source, tmpdir=tmpdir, extradir=tmpdir, + source_extension=source_extension, + call_c_compiler=False, **kwds) + if verbose: + if updated: + sys.stderr.write("regenerated: %r\n" % (ext.sources[0],)) + else: + sys.stderr.write("not modified: %r\n" % (ext.sources[0],)) + return ext + + def emit_c_code(self, filename): + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + raise ValueError("set_source() must be called before emit_c_code()") + module_name, source, source_extension, kwds = self._assigned_source + if source is None: + raise TypeError("emit_c_code() is only for C extension modules, " + "not for dlopen()-style pure Python modules") + recompile(self, module_name, source, + c_file=filename, call_c_compiler=False, **kwds) + + def emit_python_code(self, filename): + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + raise ValueError("set_source() must be called before emit_c_code()") + module_name, source, source_extension, kwds = self._assigned_source + if source is not None: + raise TypeError("emit_python_code() is only for dlopen()-style " + "pure Python modules, not for C extension modules") + recompile(self, module_name, source, + c_file=filename, call_c_compiler=False, **kwds) + + def compile(self, tmpdir='.', verbose=0, target=None, debug=None): + """The 'target' argument gives the final file name of the + compiled DLL. Use '*' to force distutils' choice, suitable for + regular CPython C API modules. Use a file name ending in '.*' + to ask for the system's default extension for dynamic libraries + (.so/.dll/.dylib). + + The default is '*' when building a non-embedded C API extension, + and (module_name + '.*') when building an embedded library. + """ + from .recompiler import recompile + # + if not hasattr(self, '_assigned_source'): + raise ValueError("set_source() must be called before compile()") + module_name, source, source_extension, kwds = self._assigned_source + return recompile(self, module_name, source, tmpdir=tmpdir, + target=target, source_extension=source_extension, + compiler_verbose=verbose, debug=debug, **kwds) + + def init_once(self, func, tag): + # Read _init_once_cache[tag], which is either (False, lock) if + # we're calling the function now in some thread, or (True, result). + # Don't call setdefault() in most cases, to avoid allocating and + # immediately freeing a lock; but still use setdefaut() to avoid + # races. + try: + x = self._init_once_cache[tag] + except KeyError: + x = self._init_once_cache.setdefault(tag, (False, allocate_lock())) + # Common case: we got (True, result), so we return the result. + if x[0]: + return x[1] + # Else, it's a lock. Acquire it to serialize the following tests. + with x[1]: + # Read again from _init_once_cache the current status. + x = self._init_once_cache[tag] + if x[0]: + return x[1] + # Call the function and store the result back. + result = func() + self._init_once_cache[tag] = (True, result) + return result + + def embedding_init_code(self, pysource): + if self._embedding: + raise ValueError("embedding_init_code() can only be called once") + # fix 'pysource' before it gets dumped into the C file: + # - remove empty lines at the beginning, so it starts at "line 1" + # - dedent, if all non-empty lines are indented + # - check for SyntaxErrors + import re + match = re.match(r'\s*\n', pysource) + if match: + pysource = pysource[match.end():] + lines = pysource.splitlines() or [''] + prefix = re.match(r'\s*', lines[0]).group() + for i in range(1, len(lines)): + line = lines[i] + if line.rstrip(): + while not line.startswith(prefix): + prefix = prefix[:-1] + i = len(prefix) + lines = [line[i:]+'\n' for line in lines] + pysource = ''.join(lines) + # + compile(pysource, "cffi_init", "exec") + # + self._embedding = pysource + + def def_extern(self, *args, **kwds): + raise ValueError("ffi.def_extern() is only available on API-mode FFI " + "objects") + + def list_types(self): + """Returns the user type names known to this FFI instance. + This returns a tuple containing three lists of names: + (typedef_names, names_of_structs, names_of_unions) + """ + typedefs = [] + structs = [] + unions = [] + for key in self._parser._declarations: + if key.startswith('typedef '): + typedefs.append(key[8:]) + elif key.startswith('struct '): + structs.append(key[7:]) + elif key.startswith('union '): + unions.append(key[6:]) + typedefs.sort() + structs.sort() + unions.sort() + return (typedefs, structs, unions) + + +def _load_backend_lib(backend, name, flags): + import os + if not isinstance(name, basestring): + if sys.platform != "win32" or name is not None: + return backend.load_library(name, flags) + name = "c" # Windows: load_library(None) fails, but this works + # on Python 2 (backward compatibility hack only) + first_error = None + if '.' in name or '/' in name or os.sep in name: + try: + return backend.load_library(name, flags) + except OSError as e: + first_error = e + import ctypes.util + path = ctypes.util.find_library(name) + if path is None: + if name == "c" and sys.platform == "win32" and sys.version_info >= (3,): + raise OSError("dlopen(None) cannot work on Windows for Python 3 " + "(see http://bugs.python.org/issue23606)") + msg = ("ctypes.util.find_library() did not manage " + "to locate a library called %r" % (name,)) + if first_error is not None: + msg = "%s. Additionally, %s" % (first_error, msg) + raise OSError(msg) + return backend.load_library(path, flags) + +def _make_ffi_library(ffi, libname, flags): + backend = ffi._backend + backendlib = _load_backend_lib(backend, libname, flags) + # + def accessor_function(name): + key = 'function ' + name + tp, _ = ffi._parser._declarations[key] + BType = ffi._get_cached_btype(tp) + value = backendlib.load_function(BType, name) + library.__dict__[name] = value + # + def accessor_variable(name): + key = 'variable ' + name + tp, _ = ffi._parser._declarations[key] + BType = ffi._get_cached_btype(tp) + read_variable = backendlib.read_variable + write_variable = backendlib.write_variable + setattr(FFILibrary, name, property( + lambda self: read_variable(BType, name), + lambda self, value: write_variable(BType, name, value))) + # + def addressof_var(name): + try: + return addr_variables[name] + except KeyError: + with ffi._lock: + if name not in addr_variables: + key = 'variable ' + name + tp, _ = ffi._parser._declarations[key] + BType = ffi._get_cached_btype(tp) + if BType.kind != 'array': + BType = model.pointer_cache(ffi, BType) + p = backendlib.load_function(BType, name) + addr_variables[name] = p + return addr_variables[name] + # + def accessor_constant(name): + raise NotImplementedError("non-integer constant '%s' cannot be " + "accessed from a dlopen() library" % (name,)) + # + def accessor_int_constant(name): + library.__dict__[name] = ffi._parser._int_constants[name] + # + accessors = {} + accessors_version = [False] + addr_variables = {} + # + def update_accessors(): + if accessors_version[0] is ffi._cdef_version: + return + # + for key, (tp, _) in ffi._parser._declarations.items(): + if not isinstance(tp, model.EnumType): + tag, name = key.split(' ', 1) + if tag == 'function': + accessors[name] = accessor_function + elif tag == 'variable': + accessors[name] = accessor_variable + elif tag == 'constant': + accessors[name] = accessor_constant + else: + for i, enumname in enumerate(tp.enumerators): + def accessor_enum(name, tp=tp, i=i): + tp.check_not_partial() + library.__dict__[name] = tp.enumvalues[i] + accessors[enumname] = accessor_enum + for name in ffi._parser._int_constants: + accessors.setdefault(name, accessor_int_constant) + accessors_version[0] = ffi._cdef_version + # + def make_accessor(name): + with ffi._lock: + if name in library.__dict__ or name in FFILibrary.__dict__: + return # added by another thread while waiting for the lock + if name not in accessors: + update_accessors() + if name not in accessors: + raise AttributeError(name) + accessors[name](name) + # + class FFILibrary(object): + def __getattr__(self, name): + make_accessor(name) + return getattr(self, name) + def __setattr__(self, name, value): + try: + property = getattr(self.__class__, name) + except AttributeError: + make_accessor(name) + setattr(self, name, value) + else: + property.__set__(self, value) + def __dir__(self): + with ffi._lock: + update_accessors() + return accessors.keys() + def __addressof__(self, name): + if name in library.__dict__: + return library.__dict__[name] + if name in FFILibrary.__dict__: + return addressof_var(name) + make_accessor(name) + if name in library.__dict__: + return library.__dict__[name] + if name in FFILibrary.__dict__: + return addressof_var(name) + raise AttributeError("cffi library has no function or " + "global variable named '%s'" % (name,)) + def __cffi_close__(self): + backendlib.close_lib() + self.__dict__.clear() + # + if isinstance(libname, basestring): + try: + if not isinstance(libname, str): # unicode, on Python 2 + libname = libname.encode('utf-8') + FFILibrary.__name__ = 'FFILibrary_%s' % libname + except UnicodeError: + pass + library = FFILibrary() + return library, library.__dict__ + +def _builtin_function_type(func): + # a hack to make at least ffi.typeof(builtin_function) work, + # if the builtin function was obtained by 'vengine_cpy'. + import sys + try: + module = sys.modules[func.__module__] + ffi = module._cffi_original_ffi + types_of_builtin_funcs = module._cffi_types_of_builtin_funcs + tp = types_of_builtin_funcs[func] + except (KeyError, AttributeError, TypeError): + return None + else: + with ffi._lock: + return ffi._get_cached_btype(tp) diff --git a/dist/ba_data/python-site-packages/cffi/backend_ctypes.py b/dist/ba_data/python-site-packages/cffi/backend_ctypes.py new file mode 100644 index 0000000..e7956a7 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/backend_ctypes.py @@ -0,0 +1,1121 @@ +import ctypes, ctypes.util, operator, sys +from . import model + +if sys.version_info < (3,): + bytechr = chr +else: + unicode = str + long = int + xrange = range + bytechr = lambda num: bytes([num]) + +class CTypesType(type): + pass + +class CTypesData(object): + __metaclass__ = CTypesType + __slots__ = ['__weakref__'] + __name__ = '' + + def __init__(self, *args): + raise TypeError("cannot instantiate %r" % (self.__class__,)) + + @classmethod + def _newp(cls, init): + raise TypeError("expected a pointer or array ctype, got '%s'" + % (cls._get_c_name(),)) + + @staticmethod + def _to_ctypes(value): + raise TypeError + + @classmethod + def _arg_to_ctypes(cls, *value): + try: + ctype = cls._ctype + except AttributeError: + raise TypeError("cannot create an instance of %r" % (cls,)) + if value: + res = cls._to_ctypes(*value) + if not isinstance(res, ctype): + res = cls._ctype(res) + else: + res = cls._ctype() + return res + + @classmethod + def _create_ctype_obj(cls, init): + if init is None: + return cls._arg_to_ctypes() + else: + return cls._arg_to_ctypes(init) + + @staticmethod + def _from_ctypes(ctypes_value): + raise TypeError + + @classmethod + def _get_c_name(cls, replace_with=''): + return cls._reftypename.replace(' &', replace_with) + + @classmethod + def _fix_class(cls): + cls.__name__ = 'CData<%s>' % (cls._get_c_name(),) + cls.__qualname__ = 'CData<%s>' % (cls._get_c_name(),) + cls.__module__ = 'ffi' + + def _get_own_repr(self): + raise NotImplementedError + + def _addr_repr(self, address): + if address == 0: + return 'NULL' + else: + if address < 0: + address += 1 << (8*ctypes.sizeof(ctypes.c_void_p)) + return '0x%x' % address + + def __repr__(self, c_name=None): + own = self._get_own_repr() + return '' % (c_name or self._get_c_name(), own) + + def _convert_to_address(self, BClass): + if BClass is None: + raise TypeError("cannot convert %r to an address" % ( + self._get_c_name(),)) + else: + raise TypeError("cannot convert %r to %r" % ( + self._get_c_name(), BClass._get_c_name())) + + @classmethod + def _get_size(cls): + return ctypes.sizeof(cls._ctype) + + def _get_size_of_instance(self): + return ctypes.sizeof(self._ctype) + + @classmethod + def _cast_from(cls, source): + raise TypeError("cannot cast to %r" % (cls._get_c_name(),)) + + def _cast_to_integer(self): + return self._convert_to_address(None) + + @classmethod + def _alignment(cls): + return ctypes.alignment(cls._ctype) + + def __iter__(self): + raise TypeError("cdata %r does not support iteration" % ( + self._get_c_name()),) + + def _make_cmp(name): + cmpfunc = getattr(operator, name) + def cmp(self, other): + v_is_ptr = not isinstance(self, CTypesGenericPrimitive) + w_is_ptr = (isinstance(other, CTypesData) and + not isinstance(other, CTypesGenericPrimitive)) + if v_is_ptr and w_is_ptr: + return cmpfunc(self._convert_to_address(None), + other._convert_to_address(None)) + elif v_is_ptr or w_is_ptr: + return NotImplemented + else: + if isinstance(self, CTypesGenericPrimitive): + self = self._value + if isinstance(other, CTypesGenericPrimitive): + other = other._value + return cmpfunc(self, other) + cmp.func_name = name + return cmp + + __eq__ = _make_cmp('__eq__') + __ne__ = _make_cmp('__ne__') + __lt__ = _make_cmp('__lt__') + __le__ = _make_cmp('__le__') + __gt__ = _make_cmp('__gt__') + __ge__ = _make_cmp('__ge__') + + def __hash__(self): + return hash(self._convert_to_address(None)) + + def _to_string(self, maxlen): + raise TypeError("string(): %r" % (self,)) + + +class CTypesGenericPrimitive(CTypesData): + __slots__ = [] + + def __hash__(self): + return hash(self._value) + + def _get_own_repr(self): + return repr(self._from_ctypes(self._value)) + + +class CTypesGenericArray(CTypesData): + __slots__ = [] + + @classmethod + def _newp(cls, init): + return cls(init) + + def __iter__(self): + for i in xrange(len(self)): + yield self[i] + + def _get_own_repr(self): + return self._addr_repr(ctypes.addressof(self._blob)) + + +class CTypesGenericPtr(CTypesData): + __slots__ = ['_address', '_as_ctype_ptr'] + _automatic_casts = False + kind = "pointer" + + @classmethod + def _newp(cls, init): + return cls(init) + + @classmethod + def _cast_from(cls, source): + if source is None: + address = 0 + elif isinstance(source, CTypesData): + address = source._cast_to_integer() + elif isinstance(source, (int, long)): + address = source + else: + raise TypeError("bad type for cast to %r: %r" % + (cls, type(source).__name__)) + return cls._new_pointer_at(address) + + @classmethod + def _new_pointer_at(cls, address): + self = cls.__new__(cls) + self._address = address + self._as_ctype_ptr = ctypes.cast(address, cls._ctype) + return self + + def _get_own_repr(self): + try: + return self._addr_repr(self._address) + except AttributeError: + return '???' + + def _cast_to_integer(self): + return self._address + + def __nonzero__(self): + return bool(self._address) + __bool__ = __nonzero__ + + @classmethod + def _to_ctypes(cls, value): + if not isinstance(value, CTypesData): + raise TypeError("unexpected %s object" % type(value).__name__) + address = value._convert_to_address(cls) + return ctypes.cast(address, cls._ctype) + + @classmethod + def _from_ctypes(cls, ctypes_ptr): + address = ctypes.cast(ctypes_ptr, ctypes.c_void_p).value or 0 + return cls._new_pointer_at(address) + + @classmethod + def _initialize(cls, ctypes_ptr, value): + if value: + ctypes_ptr.contents = cls._to_ctypes(value).contents + + def _convert_to_address(self, BClass): + if (BClass in (self.__class__, None) or BClass._automatic_casts + or self._automatic_casts): + return self._address + else: + return CTypesData._convert_to_address(self, BClass) + + +class CTypesBaseStructOrUnion(CTypesData): + __slots__ = ['_blob'] + + @classmethod + def _create_ctype_obj(cls, init): + # may be overridden + raise TypeError("cannot instantiate opaque type %s" % (cls,)) + + def _get_own_repr(self): + return self._addr_repr(ctypes.addressof(self._blob)) + + @classmethod + def _offsetof(cls, fieldname): + return getattr(cls._ctype, fieldname).offset + + def _convert_to_address(self, BClass): + if getattr(BClass, '_BItem', None) is self.__class__: + return ctypes.addressof(self._blob) + else: + return CTypesData._convert_to_address(self, BClass) + + @classmethod + def _from_ctypes(cls, ctypes_struct_or_union): + self = cls.__new__(cls) + self._blob = ctypes_struct_or_union + return self + + @classmethod + def _to_ctypes(cls, value): + return value._blob + + def __repr__(self, c_name=None): + return CTypesData.__repr__(self, c_name or self._get_c_name(' &')) + + +class CTypesBackend(object): + + PRIMITIVE_TYPES = { + 'char': ctypes.c_char, + 'short': ctypes.c_short, + 'int': ctypes.c_int, + 'long': ctypes.c_long, + 'long long': ctypes.c_longlong, + 'signed char': ctypes.c_byte, + 'unsigned char': ctypes.c_ubyte, + 'unsigned short': ctypes.c_ushort, + 'unsigned int': ctypes.c_uint, + 'unsigned long': ctypes.c_ulong, + 'unsigned long long': ctypes.c_ulonglong, + 'float': ctypes.c_float, + 'double': ctypes.c_double, + '_Bool': ctypes.c_bool, + } + + for _name in ['unsigned long long', 'unsigned long', + 'unsigned int', 'unsigned short', 'unsigned char']: + _size = ctypes.sizeof(PRIMITIVE_TYPES[_name]) + PRIMITIVE_TYPES['uint%d_t' % (8*_size)] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_void_p): + PRIMITIVE_TYPES['uintptr_t'] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_size_t): + PRIMITIVE_TYPES['size_t'] = PRIMITIVE_TYPES[_name] + + for _name in ['long long', 'long', 'int', 'short', 'signed char']: + _size = ctypes.sizeof(PRIMITIVE_TYPES[_name]) + PRIMITIVE_TYPES['int%d_t' % (8*_size)] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_void_p): + PRIMITIVE_TYPES['intptr_t'] = PRIMITIVE_TYPES[_name] + PRIMITIVE_TYPES['ptrdiff_t'] = PRIMITIVE_TYPES[_name] + if _size == ctypes.sizeof(ctypes.c_size_t): + PRIMITIVE_TYPES['ssize_t'] = PRIMITIVE_TYPES[_name] + + + def __init__(self): + self.RTLD_LAZY = 0 # not supported anyway by ctypes + self.RTLD_NOW = 0 + self.RTLD_GLOBAL = ctypes.RTLD_GLOBAL + self.RTLD_LOCAL = ctypes.RTLD_LOCAL + + def set_ffi(self, ffi): + self.ffi = ffi + + def _get_types(self): + return CTypesData, CTypesType + + def load_library(self, path, flags=0): + cdll = ctypes.CDLL(path, flags) + return CTypesLibrary(self, cdll) + + def new_void_type(self): + class CTypesVoid(CTypesData): + __slots__ = [] + _reftypename = 'void &' + @staticmethod + def _from_ctypes(novalue): + return None + @staticmethod + def _to_ctypes(novalue): + if novalue is not None: + raise TypeError("None expected, got %s object" % + (type(novalue).__name__,)) + return None + CTypesVoid._fix_class() + return CTypesVoid + + def new_primitive_type(self, name): + if name == 'wchar_t': + raise NotImplementedError(name) + ctype = self.PRIMITIVE_TYPES[name] + if name == 'char': + kind = 'char' + elif name in ('float', 'double'): + kind = 'float' + else: + if name in ('signed char', 'unsigned char'): + kind = 'byte' + elif name == '_Bool': + kind = 'bool' + else: + kind = 'int' + is_signed = (ctype(-1).value == -1) + # + def _cast_source_to_int(source): + if isinstance(source, (int, long, float)): + source = int(source) + elif isinstance(source, CTypesData): + source = source._cast_to_integer() + elif isinstance(source, bytes): + source = ord(source) + elif source is None: + source = 0 + else: + raise TypeError("bad type for cast to %r: %r" % + (CTypesPrimitive, type(source).__name__)) + return source + # + kind1 = kind + class CTypesPrimitive(CTypesGenericPrimitive): + __slots__ = ['_value'] + _ctype = ctype + _reftypename = '%s &' % name + kind = kind1 + + def __init__(self, value): + self._value = value + + @staticmethod + def _create_ctype_obj(init): + if init is None: + return ctype() + return ctype(CTypesPrimitive._to_ctypes(init)) + + if kind == 'int' or kind == 'byte': + @classmethod + def _cast_from(cls, source): + source = _cast_source_to_int(source) + source = ctype(source).value # cast within range + return cls(source) + def __int__(self): + return self._value + + if kind == 'bool': + @classmethod + def _cast_from(cls, source): + if not isinstance(source, (int, long, float)): + source = _cast_source_to_int(source) + return cls(bool(source)) + def __int__(self): + return int(self._value) + + if kind == 'char': + @classmethod + def _cast_from(cls, source): + source = _cast_source_to_int(source) + source = bytechr(source & 0xFF) + return cls(source) + def __int__(self): + return ord(self._value) + + if kind == 'float': + @classmethod + def _cast_from(cls, source): + if isinstance(source, float): + pass + elif isinstance(source, CTypesGenericPrimitive): + if hasattr(source, '__float__'): + source = float(source) + else: + source = int(source) + else: + source = _cast_source_to_int(source) + source = ctype(source).value # fix precision + return cls(source) + def __int__(self): + return int(self._value) + def __float__(self): + return self._value + + _cast_to_integer = __int__ + + if kind == 'int' or kind == 'byte' or kind == 'bool': + @staticmethod + def _to_ctypes(x): + if not isinstance(x, (int, long)): + if isinstance(x, CTypesData): + x = int(x) + else: + raise TypeError("integer expected, got %s" % + type(x).__name__) + if ctype(x).value != x: + if not is_signed and x < 0: + raise OverflowError("%s: negative integer" % name) + else: + raise OverflowError("%s: integer out of bounds" + % name) + return x + + if kind == 'char': + @staticmethod + def _to_ctypes(x): + if isinstance(x, bytes) and len(x) == 1: + return x + if isinstance(x, CTypesPrimitive): # > + return x._value + raise TypeError("character expected, got %s" % + type(x).__name__) + def __nonzero__(self): + return ord(self._value) != 0 + else: + def __nonzero__(self): + return self._value != 0 + __bool__ = __nonzero__ + + if kind == 'float': + @staticmethod + def _to_ctypes(x): + if not isinstance(x, (int, long, float, CTypesData)): + raise TypeError("float expected, got %s" % + type(x).__name__) + return ctype(x).value + + @staticmethod + def _from_ctypes(value): + return getattr(value, 'value', value) + + @staticmethod + def _initialize(blob, init): + blob.value = CTypesPrimitive._to_ctypes(init) + + if kind == 'char': + def _to_string(self, maxlen): + return self._value + if kind == 'byte': + def _to_string(self, maxlen): + return chr(self._value & 0xff) + # + CTypesPrimitive._fix_class() + return CTypesPrimitive + + def new_pointer_type(self, BItem): + getbtype = self.ffi._get_cached_btype + if BItem is getbtype(model.PrimitiveType('char')): + kind = 'charp' + elif BItem in (getbtype(model.PrimitiveType('signed char')), + getbtype(model.PrimitiveType('unsigned char'))): + kind = 'bytep' + elif BItem is getbtype(model.void_type): + kind = 'voidp' + else: + kind = 'generic' + # + class CTypesPtr(CTypesGenericPtr): + __slots__ = ['_own'] + if kind == 'charp': + __slots__ += ['__as_strbuf'] + _BItem = BItem + if hasattr(BItem, '_ctype'): + _ctype = ctypes.POINTER(BItem._ctype) + _bitem_size = ctypes.sizeof(BItem._ctype) + else: + _ctype = ctypes.c_void_p + if issubclass(BItem, CTypesGenericArray): + _reftypename = BItem._get_c_name('(* &)') + else: + _reftypename = BItem._get_c_name(' * &') + + def __init__(self, init): + ctypeobj = BItem._create_ctype_obj(init) + if kind == 'charp': + self.__as_strbuf = ctypes.create_string_buffer( + ctypeobj.value + b'\x00') + self._as_ctype_ptr = ctypes.cast( + self.__as_strbuf, self._ctype) + else: + self._as_ctype_ptr = ctypes.pointer(ctypeobj) + self._address = ctypes.cast(self._as_ctype_ptr, + ctypes.c_void_p).value + self._own = True + + def __add__(self, other): + if isinstance(other, (int, long)): + return self._new_pointer_at(self._address + + other * self._bitem_size) + else: + return NotImplemented + + def __sub__(self, other): + if isinstance(other, (int, long)): + return self._new_pointer_at(self._address - + other * self._bitem_size) + elif type(self) is type(other): + return (self._address - other._address) // self._bitem_size + else: + return NotImplemented + + def __getitem__(self, index): + if getattr(self, '_own', False) and index != 0: + raise IndexError + return BItem._from_ctypes(self._as_ctype_ptr[index]) + + def __setitem__(self, index, value): + self._as_ctype_ptr[index] = BItem._to_ctypes(value) + + if kind == 'charp' or kind == 'voidp': + @classmethod + def _arg_to_ctypes(cls, *value): + if value and isinstance(value[0], bytes): + return ctypes.c_char_p(value[0]) + else: + return super(CTypesPtr, cls)._arg_to_ctypes(*value) + + if kind == 'charp' or kind == 'bytep': + def _to_string(self, maxlen): + if maxlen < 0: + maxlen = sys.maxsize + p = ctypes.cast(self._as_ctype_ptr, + ctypes.POINTER(ctypes.c_char)) + n = 0 + while n < maxlen and p[n] != b'\x00': + n += 1 + return b''.join([p[i] for i in range(n)]) + + def _get_own_repr(self): + if getattr(self, '_own', False): + return 'owning %d bytes' % ( + ctypes.sizeof(self._as_ctype_ptr.contents),) + return super(CTypesPtr, self)._get_own_repr() + # + if (BItem is self.ffi._get_cached_btype(model.void_type) or + BItem is self.ffi._get_cached_btype(model.PrimitiveType('char'))): + CTypesPtr._automatic_casts = True + # + CTypesPtr._fix_class() + return CTypesPtr + + def new_array_type(self, CTypesPtr, length): + if length is None: + brackets = ' &[]' + else: + brackets = ' &[%d]' % length + BItem = CTypesPtr._BItem + getbtype = self.ffi._get_cached_btype + if BItem is getbtype(model.PrimitiveType('char')): + kind = 'char' + elif BItem in (getbtype(model.PrimitiveType('signed char')), + getbtype(model.PrimitiveType('unsigned char'))): + kind = 'byte' + else: + kind = 'generic' + # + class CTypesArray(CTypesGenericArray): + __slots__ = ['_blob', '_own'] + if length is not None: + _ctype = BItem._ctype * length + else: + __slots__.append('_ctype') + _reftypename = BItem._get_c_name(brackets) + _declared_length = length + _CTPtr = CTypesPtr + + def __init__(self, init): + if length is None: + if isinstance(init, (int, long)): + len1 = init + init = None + elif kind == 'char' and isinstance(init, bytes): + len1 = len(init) + 1 # extra null + else: + init = tuple(init) + len1 = len(init) + self._ctype = BItem._ctype * len1 + self._blob = self._ctype() + self._own = True + if init is not None: + self._initialize(self._blob, init) + + @staticmethod + def _initialize(blob, init): + if isinstance(init, bytes): + init = [init[i:i+1] for i in range(len(init))] + else: + if isinstance(init, CTypesGenericArray): + if (len(init) != len(blob) or + not isinstance(init, CTypesArray)): + raise TypeError("length/type mismatch: %s" % (init,)) + init = tuple(init) + if len(init) > len(blob): + raise IndexError("too many initializers") + addr = ctypes.cast(blob, ctypes.c_void_p).value + PTR = ctypes.POINTER(BItem._ctype) + itemsize = ctypes.sizeof(BItem._ctype) + for i, value in enumerate(init): + p = ctypes.cast(addr + i * itemsize, PTR) + BItem._initialize(p.contents, value) + + def __len__(self): + return len(self._blob) + + def __getitem__(self, index): + if not (0 <= index < len(self._blob)): + raise IndexError + return BItem._from_ctypes(self._blob[index]) + + def __setitem__(self, index, value): + if not (0 <= index < len(self._blob)): + raise IndexError + self._blob[index] = BItem._to_ctypes(value) + + if kind == 'char' or kind == 'byte': + def _to_string(self, maxlen): + if maxlen < 0: + maxlen = len(self._blob) + p = ctypes.cast(self._blob, + ctypes.POINTER(ctypes.c_char)) + n = 0 + while n < maxlen and p[n] != b'\x00': + n += 1 + return b''.join([p[i] for i in range(n)]) + + def _get_own_repr(self): + if getattr(self, '_own', False): + return 'owning %d bytes' % (ctypes.sizeof(self._blob),) + return super(CTypesArray, self)._get_own_repr() + + def _convert_to_address(self, BClass): + if BClass in (CTypesPtr, None) or BClass._automatic_casts: + return ctypes.addressof(self._blob) + else: + return CTypesData._convert_to_address(self, BClass) + + @staticmethod + def _from_ctypes(ctypes_array): + self = CTypesArray.__new__(CTypesArray) + self._blob = ctypes_array + return self + + @staticmethod + def _arg_to_ctypes(value): + return CTypesPtr._arg_to_ctypes(value) + + def __add__(self, other): + if isinstance(other, (int, long)): + return CTypesPtr._new_pointer_at( + ctypes.addressof(self._blob) + + other * ctypes.sizeof(BItem._ctype)) + else: + return NotImplemented + + @classmethod + def _cast_from(cls, source): + raise NotImplementedError("casting to %r" % ( + cls._get_c_name(),)) + # + CTypesArray._fix_class() + return CTypesArray + + def _new_struct_or_union(self, kind, name, base_ctypes_class): + # + class struct_or_union(base_ctypes_class): + pass + struct_or_union.__name__ = '%s_%s' % (kind, name) + kind1 = kind + # + class CTypesStructOrUnion(CTypesBaseStructOrUnion): + __slots__ = ['_blob'] + _ctype = struct_or_union + _reftypename = '%s &' % (name,) + _kind = kind = kind1 + # + CTypesStructOrUnion._fix_class() + return CTypesStructOrUnion + + def new_struct_type(self, name): + return self._new_struct_or_union('struct', name, ctypes.Structure) + + def new_union_type(self, name): + return self._new_struct_or_union('union', name, ctypes.Union) + + def complete_struct_or_union(self, CTypesStructOrUnion, fields, tp, + totalsize=-1, totalalignment=-1, sflags=0, + pack=0): + if totalsize >= 0 or totalalignment >= 0: + raise NotImplementedError("the ctypes backend of CFFI does not support " + "structures completed by verify(); please " + "compile and install the _cffi_backend module.") + struct_or_union = CTypesStructOrUnion._ctype + fnames = [fname for (fname, BField, bitsize) in fields] + btypes = [BField for (fname, BField, bitsize) in fields] + bitfields = [bitsize for (fname, BField, bitsize) in fields] + # + bfield_types = {} + cfields = [] + for (fname, BField, bitsize) in fields: + if bitsize < 0: + cfields.append((fname, BField._ctype)) + bfield_types[fname] = BField + else: + cfields.append((fname, BField._ctype, bitsize)) + bfield_types[fname] = Ellipsis + if sflags & 8: + struct_or_union._pack_ = 1 + elif pack: + struct_or_union._pack_ = pack + struct_or_union._fields_ = cfields + CTypesStructOrUnion._bfield_types = bfield_types + # + @staticmethod + def _create_ctype_obj(init): + result = struct_or_union() + if init is not None: + initialize(result, init) + return result + CTypesStructOrUnion._create_ctype_obj = _create_ctype_obj + # + def initialize(blob, init): + if is_union: + if len(init) > 1: + raise ValueError("union initializer: %d items given, but " + "only one supported (use a dict if needed)" + % (len(init),)) + if not isinstance(init, dict): + if isinstance(init, (bytes, unicode)): + raise TypeError("union initializer: got a str") + init = tuple(init) + if len(init) > len(fnames): + raise ValueError("too many values for %s initializer" % + CTypesStructOrUnion._get_c_name()) + init = dict(zip(fnames, init)) + addr = ctypes.addressof(blob) + for fname, value in init.items(): + BField, bitsize = name2fieldtype[fname] + assert bitsize < 0, \ + "not implemented: initializer with bit fields" + offset = CTypesStructOrUnion._offsetof(fname) + PTR = ctypes.POINTER(BField._ctype) + p = ctypes.cast(addr + offset, PTR) + BField._initialize(p.contents, value) + is_union = CTypesStructOrUnion._kind == 'union' + name2fieldtype = dict(zip(fnames, zip(btypes, bitfields))) + # + for fname, BField, bitsize in fields: + if fname == '': + raise NotImplementedError("nested anonymous structs/unions") + if hasattr(CTypesStructOrUnion, fname): + raise ValueError("the field name %r conflicts in " + "the ctypes backend" % fname) + if bitsize < 0: + def getter(self, fname=fname, BField=BField, + offset=CTypesStructOrUnion._offsetof(fname), + PTR=ctypes.POINTER(BField._ctype)): + addr = ctypes.addressof(self._blob) + p = ctypes.cast(addr + offset, PTR) + return BField._from_ctypes(p.contents) + def setter(self, value, fname=fname, BField=BField): + setattr(self._blob, fname, BField._to_ctypes(value)) + # + if issubclass(BField, CTypesGenericArray): + setter = None + if BField._declared_length == 0: + def getter(self, fname=fname, BFieldPtr=BField._CTPtr, + offset=CTypesStructOrUnion._offsetof(fname), + PTR=ctypes.POINTER(BField._ctype)): + addr = ctypes.addressof(self._blob) + p = ctypes.cast(addr + offset, PTR) + return BFieldPtr._from_ctypes(p) + # + else: + def getter(self, fname=fname, BField=BField): + return BField._from_ctypes(getattr(self._blob, fname)) + def setter(self, value, fname=fname, BField=BField): + # xxx obscure workaround + value = BField._to_ctypes(value) + oldvalue = getattr(self._blob, fname) + setattr(self._blob, fname, value) + if value != getattr(self._blob, fname): + setattr(self._blob, fname, oldvalue) + raise OverflowError("value too large for bitfield") + setattr(CTypesStructOrUnion, fname, property(getter, setter)) + # + CTypesPtr = self.ffi._get_cached_btype(model.PointerType(tp)) + for fname in fnames: + if hasattr(CTypesPtr, fname): + raise ValueError("the field name %r conflicts in " + "the ctypes backend" % fname) + def getter(self, fname=fname): + return getattr(self[0], fname) + def setter(self, value, fname=fname): + setattr(self[0], fname, value) + setattr(CTypesPtr, fname, property(getter, setter)) + + def new_function_type(self, BArgs, BResult, has_varargs): + nameargs = [BArg._get_c_name() for BArg in BArgs] + if has_varargs: + nameargs.append('...') + nameargs = ', '.join(nameargs) + # + class CTypesFunctionPtr(CTypesGenericPtr): + __slots__ = ['_own_callback', '_name'] + _ctype = ctypes.CFUNCTYPE(getattr(BResult, '_ctype', None), + *[BArg._ctype for BArg in BArgs], + use_errno=True) + _reftypename = BResult._get_c_name('(* &)(%s)' % (nameargs,)) + + def __init__(self, init, error=None): + # create a callback to the Python callable init() + import traceback + assert not has_varargs, "varargs not supported for callbacks" + if getattr(BResult, '_ctype', None) is not None: + error = BResult._from_ctypes( + BResult._create_ctype_obj(error)) + else: + error = None + def callback(*args): + args2 = [] + for arg, BArg in zip(args, BArgs): + args2.append(BArg._from_ctypes(arg)) + try: + res2 = init(*args2) + res2 = BResult._to_ctypes(res2) + except: + traceback.print_exc() + res2 = error + if issubclass(BResult, CTypesGenericPtr): + if res2: + res2 = ctypes.cast(res2, ctypes.c_void_p).value + # .value: http://bugs.python.org/issue1574593 + else: + res2 = None + #print repr(res2) + return res2 + if issubclass(BResult, CTypesGenericPtr): + # The only pointers callbacks can return are void*s: + # http://bugs.python.org/issue5710 + callback_ctype = ctypes.CFUNCTYPE( + ctypes.c_void_p, + *[BArg._ctype for BArg in BArgs], + use_errno=True) + else: + callback_ctype = CTypesFunctionPtr._ctype + self._as_ctype_ptr = callback_ctype(callback) + self._address = ctypes.cast(self._as_ctype_ptr, + ctypes.c_void_p).value + self._own_callback = init + + @staticmethod + def _initialize(ctypes_ptr, value): + if value: + raise NotImplementedError("ctypes backend: not supported: " + "initializers for function pointers") + + def __repr__(self): + c_name = getattr(self, '_name', None) + if c_name: + i = self._reftypename.index('(* &)') + if self._reftypename[i-1] not in ' )*': + c_name = ' ' + c_name + c_name = self._reftypename.replace('(* &)', c_name) + return CTypesData.__repr__(self, c_name) + + def _get_own_repr(self): + if getattr(self, '_own_callback', None) is not None: + return 'calling %r' % (self._own_callback,) + return super(CTypesFunctionPtr, self)._get_own_repr() + + def __call__(self, *args): + if has_varargs: + assert len(args) >= len(BArgs) + extraargs = args[len(BArgs):] + args = args[:len(BArgs)] + else: + assert len(args) == len(BArgs) + ctypes_args = [] + for arg, BArg in zip(args, BArgs): + ctypes_args.append(BArg._arg_to_ctypes(arg)) + if has_varargs: + for i, arg in enumerate(extraargs): + if arg is None: + ctypes_args.append(ctypes.c_void_p(0)) # NULL + continue + if not isinstance(arg, CTypesData): + raise TypeError( + "argument %d passed in the variadic part " + "needs to be a cdata object (got %s)" % + (1 + len(BArgs) + i, type(arg).__name__)) + ctypes_args.append(arg._arg_to_ctypes(arg)) + result = self._as_ctype_ptr(*ctypes_args) + return BResult._from_ctypes(result) + # + CTypesFunctionPtr._fix_class() + return CTypesFunctionPtr + + def new_enum_type(self, name, enumerators, enumvalues, CTypesInt): + assert isinstance(name, str) + reverse_mapping = dict(zip(reversed(enumvalues), + reversed(enumerators))) + # + class CTypesEnum(CTypesInt): + __slots__ = [] + _reftypename = '%s &' % name + + def _get_own_repr(self): + value = self._value + try: + return '%d: %s' % (value, reverse_mapping[value]) + except KeyError: + return str(value) + + def _to_string(self, maxlen): + value = self._value + try: + return reverse_mapping[value] + except KeyError: + return str(value) + # + CTypesEnum._fix_class() + return CTypesEnum + + def get_errno(self): + return ctypes.get_errno() + + def set_errno(self, value): + ctypes.set_errno(value) + + def string(self, b, maxlen=-1): + return b._to_string(maxlen) + + def buffer(self, bptr, size=-1): + raise NotImplementedError("buffer() with ctypes backend") + + def sizeof(self, cdata_or_BType): + if isinstance(cdata_or_BType, CTypesData): + return cdata_or_BType._get_size_of_instance() + else: + assert issubclass(cdata_or_BType, CTypesData) + return cdata_or_BType._get_size() + + def alignof(self, BType): + assert issubclass(BType, CTypesData) + return BType._alignment() + + def newp(self, BType, source): + if not issubclass(BType, CTypesData): + raise TypeError + return BType._newp(source) + + def cast(self, BType, source): + return BType._cast_from(source) + + def callback(self, BType, source, error, onerror): + assert onerror is None # XXX not implemented + return BType(source, error) + + _weakref_cache_ref = None + + def gcp(self, cdata, destructor, size=0): + if self._weakref_cache_ref is None: + import weakref + class MyRef(weakref.ref): + def __eq__(self, other): + myref = self() + return self is other or ( + myref is not None and myref is other()) + def __ne__(self, other): + return not (self == other) + def __hash__(self): + try: + return self._hash + except AttributeError: + self._hash = hash(self()) + return self._hash + self._weakref_cache_ref = {}, MyRef + weak_cache, MyRef = self._weakref_cache_ref + + if destructor is None: + try: + del weak_cache[MyRef(cdata)] + except KeyError: + raise TypeError("Can remove destructor only on a object " + "previously returned by ffi.gc()") + return None + + def remove(k): + cdata, destructor = weak_cache.pop(k, (None, None)) + if destructor is not None: + destructor(cdata) + + new_cdata = self.cast(self.typeof(cdata), cdata) + assert new_cdata is not cdata + weak_cache[MyRef(new_cdata, remove)] = (cdata, destructor) + return new_cdata + + typeof = type + + def getcname(self, BType, replace_with): + return BType._get_c_name(replace_with) + + def typeoffsetof(self, BType, fieldname, num=0): + if isinstance(fieldname, str): + if num == 0 and issubclass(BType, CTypesGenericPtr): + BType = BType._BItem + if not issubclass(BType, CTypesBaseStructOrUnion): + raise TypeError("expected a struct or union ctype") + BField = BType._bfield_types[fieldname] + if BField is Ellipsis: + raise TypeError("not supported for bitfields") + return (BField, BType._offsetof(fieldname)) + elif isinstance(fieldname, (int, long)): + if issubclass(BType, CTypesGenericArray): + BType = BType._CTPtr + if not issubclass(BType, CTypesGenericPtr): + raise TypeError("expected an array or ptr ctype") + BItem = BType._BItem + offset = BItem._get_size() * fieldname + if offset > sys.maxsize: + raise OverflowError + return (BItem, offset) + else: + raise TypeError(type(fieldname)) + + def rawaddressof(self, BTypePtr, cdata, offset=None): + if isinstance(cdata, CTypesBaseStructOrUnion): + ptr = ctypes.pointer(type(cdata)._to_ctypes(cdata)) + elif isinstance(cdata, CTypesGenericPtr): + if offset is None or not issubclass(type(cdata)._BItem, + CTypesBaseStructOrUnion): + raise TypeError("unexpected cdata type") + ptr = type(cdata)._to_ctypes(cdata) + elif isinstance(cdata, CTypesGenericArray): + ptr = type(cdata)._to_ctypes(cdata) + else: + raise TypeError("expected a ") + if offset: + ptr = ctypes.cast( + ctypes.c_void_p( + ctypes.cast(ptr, ctypes.c_void_p).value + offset), + type(ptr)) + return BTypePtr._from_ctypes(ptr) + + +class CTypesLibrary(object): + + def __init__(self, backend, cdll): + self.backend = backend + self.cdll = cdll + + def load_function(self, BType, name): + c_func = getattr(self.cdll, name) + funcobj = BType._from_ctypes(c_func) + funcobj._name = name + return funcobj + + def read_variable(self, BType, name): + try: + ctypes_obj = BType._ctype.in_dll(self.cdll, name) + except AttributeError as e: + raise NotImplementedError(e) + return BType._from_ctypes(ctypes_obj) + + def write_variable(self, BType, name, value): + new_ctypes_obj = BType._to_ctypes(value) + ctypes_obj = BType._ctype.in_dll(self.cdll, name) + ctypes.memmove(ctypes.addressof(ctypes_obj), + ctypes.addressof(new_ctypes_obj), + ctypes.sizeof(BType._ctype)) diff --git a/dist/ba_data/python-site-packages/cffi/cffi_opcode.py b/dist/ba_data/python-site-packages/cffi/cffi_opcode.py new file mode 100644 index 0000000..a0df98d --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/cffi_opcode.py @@ -0,0 +1,187 @@ +from .error import VerificationError + +class CffiOp(object): + def __init__(self, op, arg): + self.op = op + self.arg = arg + + def as_c_expr(self): + if self.op is None: + assert isinstance(self.arg, str) + return '(_cffi_opcode_t)(%s)' % (self.arg,) + classname = CLASS_NAME[self.op] + return '_CFFI_OP(_CFFI_OP_%s, %s)' % (classname, self.arg) + + def as_python_bytes(self): + if self.op is None and self.arg.isdigit(): + value = int(self.arg) # non-negative: '-' not in self.arg + if value >= 2**31: + raise OverflowError("cannot emit %r: limited to 2**31-1" + % (self.arg,)) + return format_four_bytes(value) + if isinstance(self.arg, str): + raise VerificationError("cannot emit to Python: %r" % (self.arg,)) + return format_four_bytes((self.arg << 8) | self.op) + + def __str__(self): + classname = CLASS_NAME.get(self.op, self.op) + return '(%s %s)' % (classname, self.arg) + +def format_four_bytes(num): + return '\\x%02X\\x%02X\\x%02X\\x%02X' % ( + (num >> 24) & 0xFF, + (num >> 16) & 0xFF, + (num >> 8) & 0xFF, + (num ) & 0xFF) + +OP_PRIMITIVE = 1 +OP_POINTER = 3 +OP_ARRAY = 5 +OP_OPEN_ARRAY = 7 +OP_STRUCT_UNION = 9 +OP_ENUM = 11 +OP_FUNCTION = 13 +OP_FUNCTION_END = 15 +OP_NOOP = 17 +OP_BITFIELD = 19 +OP_TYPENAME = 21 +OP_CPYTHON_BLTN_V = 23 # varargs +OP_CPYTHON_BLTN_N = 25 # noargs +OP_CPYTHON_BLTN_O = 27 # O (i.e. a single arg) +OP_CONSTANT = 29 +OP_CONSTANT_INT = 31 +OP_GLOBAL_VAR = 33 +OP_DLOPEN_FUNC = 35 +OP_DLOPEN_CONST = 37 +OP_GLOBAL_VAR_F = 39 +OP_EXTERN_PYTHON = 41 + +PRIM_VOID = 0 +PRIM_BOOL = 1 +PRIM_CHAR = 2 +PRIM_SCHAR = 3 +PRIM_UCHAR = 4 +PRIM_SHORT = 5 +PRIM_USHORT = 6 +PRIM_INT = 7 +PRIM_UINT = 8 +PRIM_LONG = 9 +PRIM_ULONG = 10 +PRIM_LONGLONG = 11 +PRIM_ULONGLONG = 12 +PRIM_FLOAT = 13 +PRIM_DOUBLE = 14 +PRIM_LONGDOUBLE = 15 + +PRIM_WCHAR = 16 +PRIM_INT8 = 17 +PRIM_UINT8 = 18 +PRIM_INT16 = 19 +PRIM_UINT16 = 20 +PRIM_INT32 = 21 +PRIM_UINT32 = 22 +PRIM_INT64 = 23 +PRIM_UINT64 = 24 +PRIM_INTPTR = 25 +PRIM_UINTPTR = 26 +PRIM_PTRDIFF = 27 +PRIM_SIZE = 28 +PRIM_SSIZE = 29 +PRIM_INT_LEAST8 = 30 +PRIM_UINT_LEAST8 = 31 +PRIM_INT_LEAST16 = 32 +PRIM_UINT_LEAST16 = 33 +PRIM_INT_LEAST32 = 34 +PRIM_UINT_LEAST32 = 35 +PRIM_INT_LEAST64 = 36 +PRIM_UINT_LEAST64 = 37 +PRIM_INT_FAST8 = 38 +PRIM_UINT_FAST8 = 39 +PRIM_INT_FAST16 = 40 +PRIM_UINT_FAST16 = 41 +PRIM_INT_FAST32 = 42 +PRIM_UINT_FAST32 = 43 +PRIM_INT_FAST64 = 44 +PRIM_UINT_FAST64 = 45 +PRIM_INTMAX = 46 +PRIM_UINTMAX = 47 +PRIM_FLOATCOMPLEX = 48 +PRIM_DOUBLECOMPLEX = 49 +PRIM_CHAR16 = 50 +PRIM_CHAR32 = 51 + +_NUM_PRIM = 52 +_UNKNOWN_PRIM = -1 +_UNKNOWN_FLOAT_PRIM = -2 +_UNKNOWN_LONG_DOUBLE = -3 + +_IO_FILE_STRUCT = -1 + +PRIMITIVE_TO_INDEX = { + 'char': PRIM_CHAR, + 'short': PRIM_SHORT, + 'int': PRIM_INT, + 'long': PRIM_LONG, + 'long long': PRIM_LONGLONG, + 'signed char': PRIM_SCHAR, + 'unsigned char': PRIM_UCHAR, + 'unsigned short': PRIM_USHORT, + 'unsigned int': PRIM_UINT, + 'unsigned long': PRIM_ULONG, + 'unsigned long long': PRIM_ULONGLONG, + 'float': PRIM_FLOAT, + 'double': PRIM_DOUBLE, + 'long double': PRIM_LONGDOUBLE, + 'float _Complex': PRIM_FLOATCOMPLEX, + 'double _Complex': PRIM_DOUBLECOMPLEX, + '_Bool': PRIM_BOOL, + 'wchar_t': PRIM_WCHAR, + 'char16_t': PRIM_CHAR16, + 'char32_t': PRIM_CHAR32, + 'int8_t': PRIM_INT8, + 'uint8_t': PRIM_UINT8, + 'int16_t': PRIM_INT16, + 'uint16_t': PRIM_UINT16, + 'int32_t': PRIM_INT32, + 'uint32_t': PRIM_UINT32, + 'int64_t': PRIM_INT64, + 'uint64_t': PRIM_UINT64, + 'intptr_t': PRIM_INTPTR, + 'uintptr_t': PRIM_UINTPTR, + 'ptrdiff_t': PRIM_PTRDIFF, + 'size_t': PRIM_SIZE, + 'ssize_t': PRIM_SSIZE, + 'int_least8_t': PRIM_INT_LEAST8, + 'uint_least8_t': PRIM_UINT_LEAST8, + 'int_least16_t': PRIM_INT_LEAST16, + 'uint_least16_t': PRIM_UINT_LEAST16, + 'int_least32_t': PRIM_INT_LEAST32, + 'uint_least32_t': PRIM_UINT_LEAST32, + 'int_least64_t': PRIM_INT_LEAST64, + 'uint_least64_t': PRIM_UINT_LEAST64, + 'int_fast8_t': PRIM_INT_FAST8, + 'uint_fast8_t': PRIM_UINT_FAST8, + 'int_fast16_t': PRIM_INT_FAST16, + 'uint_fast16_t': PRIM_UINT_FAST16, + 'int_fast32_t': PRIM_INT_FAST32, + 'uint_fast32_t': PRIM_UINT_FAST32, + 'int_fast64_t': PRIM_INT_FAST64, + 'uint_fast64_t': PRIM_UINT_FAST64, + 'intmax_t': PRIM_INTMAX, + 'uintmax_t': PRIM_UINTMAX, + } + +F_UNION = 0x01 +F_CHECK_FIELDS = 0x02 +F_PACKED = 0x04 +F_EXTERNAL = 0x08 +F_OPAQUE = 0x10 + +G_FLAGS = dict([('_CFFI_' + _key, globals()[_key]) + for _key in ['F_UNION', 'F_CHECK_FIELDS', 'F_PACKED', + 'F_EXTERNAL', 'F_OPAQUE']]) + +CLASS_NAME = {} +for _name, _value in list(globals().items()): + if _name.startswith('OP_') and isinstance(_value, int): + CLASS_NAME[_value] = _name[3:] diff --git a/dist/ba_data/python-site-packages/cffi/commontypes.py b/dist/ba_data/python-site-packages/cffi/commontypes.py new file mode 100644 index 0000000..8ec97c7 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/commontypes.py @@ -0,0 +1,80 @@ +import sys +from . import model +from .error import FFIError + + +COMMON_TYPES = {} + +try: + # fetch "bool" and all simple Windows types + from _cffi_backend import _get_common_types + _get_common_types(COMMON_TYPES) +except ImportError: + pass + +COMMON_TYPES['FILE'] = model.unknown_type('FILE', '_IO_FILE') +COMMON_TYPES['bool'] = '_Bool' # in case we got ImportError above + +for _type in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + if _type.endswith('_t'): + COMMON_TYPES[_type] = _type +del _type + +_CACHE = {} + +def resolve_common_type(parser, commontype): + try: + return _CACHE[commontype] + except KeyError: + cdecl = COMMON_TYPES.get(commontype, commontype) + if not isinstance(cdecl, str): + result, quals = cdecl, 0 # cdecl is already a BaseType + elif cdecl in model.PrimitiveType.ALL_PRIMITIVE_TYPES: + result, quals = model.PrimitiveType(cdecl), 0 + elif cdecl == 'set-unicode-needed': + raise FFIError("The Windows type %r is only available after " + "you call ffi.set_unicode()" % (commontype,)) + else: + if commontype == cdecl: + raise FFIError( + "Unsupported type: %r. Please look at " + "http://cffi.readthedocs.io/en/latest/cdef.html#ffi-cdef-limitations " + "and file an issue if you think this type should really " + "be supported." % (commontype,)) + result, quals = parser.parse_type_and_quals(cdecl) # recursive + + assert isinstance(result, model.BaseTypeByIdentity) + _CACHE[commontype] = result, quals + return result, quals + + +# ____________________________________________________________ +# extra types for Windows (most of them are in commontypes.c) + + +def win_common_types(): + return { + "UNICODE_STRING": model.StructType( + "_UNICODE_STRING", + ["Length", + "MaximumLength", + "Buffer"], + [model.PrimitiveType("unsigned short"), + model.PrimitiveType("unsigned short"), + model.PointerType(model.PrimitiveType("wchar_t"))], + [-1, -1, -1]), + "PUNICODE_STRING": "UNICODE_STRING *", + "PCUNICODE_STRING": "const UNICODE_STRING *", + + "TBYTE": "set-unicode-needed", + "TCHAR": "set-unicode-needed", + "LPCTSTR": "set-unicode-needed", + "PCTSTR": "set-unicode-needed", + "LPTSTR": "set-unicode-needed", + "PTSTR": "set-unicode-needed", + "PTBYTE": "set-unicode-needed", + "PTCHAR": "set-unicode-needed", + } + +if sys.platform == 'win32': + COMMON_TYPES.update(win_common_types()) diff --git a/dist/ba_data/python-site-packages/cffi/cparser.py b/dist/ba_data/python-site-packages/cffi/cparser.py new file mode 100644 index 0000000..74830e9 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/cparser.py @@ -0,0 +1,1006 @@ +from . import model +from .commontypes import COMMON_TYPES, resolve_common_type +from .error import FFIError, CDefError +try: + from . import _pycparser as pycparser +except ImportError: + import pycparser +import weakref, re, sys + +try: + if sys.version_info < (3,): + import thread as _thread + else: + import _thread + lock = _thread.allocate_lock() +except ImportError: + lock = None + +def _workaround_for_static_import_finders(): + # Issue #392: packaging tools like cx_Freeze can not find these + # because pycparser uses exec dynamic import. This is an obscure + # workaround. This function is never called. + import pycparser.yacctab + import pycparser.lextab + +CDEF_SOURCE_STRING = "" +_r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$", + re.DOTALL | re.MULTILINE) +_r_define = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)" + r"\b((?:[^\n\\]|\\.)*?)$", + re.DOTALL | re.MULTILINE) +_r_line_directive = re.compile(r"^[ \t]*#[ \t]*(?:line|\d+)\b.*$", re.MULTILINE) +_r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}") +_r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$") +_r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]") +_r_words = re.compile(r"\w+|\S") +_parser_cache = None +_r_int_literal = re.compile(r"-?0?x?[0-9a-f]+[lu]*$", re.IGNORECASE) +_r_stdcall1 = re.compile(r"\b(__stdcall|WINAPI)\b") +_r_stdcall2 = re.compile(r"[(]\s*(__stdcall|WINAPI)\b") +_r_cdecl = re.compile(r"\b__cdecl\b") +_r_extern_python = re.compile(r'\bextern\s*"' + r'(Python|Python\s*\+\s*C|C\s*\+\s*Python)"\s*.') +_r_star_const_space = re.compile( # matches "* const " + r"[*]\s*((const|volatile|restrict)\b\s*)+") +_r_int_dotdotdot = re.compile(r"(\b(int|long|short|signed|unsigned|char)\s*)+" + r"\.\.\.") +_r_float_dotdotdot = re.compile(r"\b(double|float)\s*\.\.\.") + +def _get_parser(): + global _parser_cache + if _parser_cache is None: + _parser_cache = pycparser.CParser() + return _parser_cache + +def _workaround_for_old_pycparser(csource): + # Workaround for a pycparser issue (fixed between pycparser 2.10 and + # 2.14): "char*const***" gives us a wrong syntax tree, the same as + # for "char***(*const)". This means we can't tell the difference + # afterwards. But "char(*const(***))" gives us the right syntax + # tree. The issue only occurs if there are several stars in + # sequence with no parenthesis inbetween, just possibly qualifiers. + # Attempt to fix it by adding some parentheses in the source: each + # time we see "* const" or "* const *", we add an opening + # parenthesis before each star---the hard part is figuring out where + # to close them. + parts = [] + while True: + match = _r_star_const_space.search(csource) + if not match: + break + #print repr(''.join(parts)+csource), '=>', + parts.append(csource[:match.start()]) + parts.append('('); closing = ')' + parts.append(match.group()) # e.g. "* const " + endpos = match.end() + if csource.startswith('*', endpos): + parts.append('('); closing += ')' + level = 0 + i = endpos + while i < len(csource): + c = csource[i] + if c == '(': + level += 1 + elif c == ')': + if level == 0: + break + level -= 1 + elif c in ',;=': + if level == 0: + break + i += 1 + csource = csource[endpos:i] + closing + csource[i:] + #print repr(''.join(parts)+csource) + parts.append(csource) + return ''.join(parts) + +def _preprocess_extern_python(csource): + # input: `extern "Python" int foo(int);` or + # `extern "Python" { int foo(int); }` + # output: + # void __cffi_extern_python_start; + # int foo(int); + # void __cffi_extern_python_stop; + # + # input: `extern "Python+C" int foo(int);` + # output: + # void __cffi_extern_python_plus_c_start; + # int foo(int); + # void __cffi_extern_python_stop; + parts = [] + while True: + match = _r_extern_python.search(csource) + if not match: + break + endpos = match.end() - 1 + #print + #print ''.join(parts)+csource + #print '=>' + parts.append(csource[:match.start()]) + if 'C' in match.group(1): + parts.append('void __cffi_extern_python_plus_c_start; ') + else: + parts.append('void __cffi_extern_python_start; ') + if csource[endpos] == '{': + # grouping variant + closing = csource.find('}', endpos) + if closing < 0: + raise CDefError("'extern \"Python\" {': no '}' found") + if csource.find('{', endpos + 1, closing) >= 0: + raise NotImplementedError("cannot use { } inside a block " + "'extern \"Python\" { ... }'") + parts.append(csource[endpos+1:closing]) + csource = csource[closing+1:] + else: + # non-grouping variant + semicolon = csource.find(';', endpos) + if semicolon < 0: + raise CDefError("'extern \"Python\": no ';' found") + parts.append(csource[endpos:semicolon+1]) + csource = csource[semicolon+1:] + parts.append(' void __cffi_extern_python_stop;') + #print ''.join(parts)+csource + #print + parts.append(csource) + return ''.join(parts) + +def _warn_for_string_literal(csource): + if '"' not in csource: + return + for line in csource.splitlines(): + if '"' in line and not line.lstrip().startswith('#'): + import warnings + warnings.warn("String literal found in cdef() or type source. " + "String literals are ignored here, but you should " + "remove them anyway because some character sequences " + "confuse pre-parsing.") + break + +def _warn_for_non_extern_non_static_global_variable(decl): + if not decl.storage: + import warnings + warnings.warn("Global variable '%s' in cdef(): for consistency " + "with C it should have a storage class specifier " + "(usually 'extern')" % (decl.name,)) + +def _remove_line_directives(csource): + # _r_line_directive matches whole lines, without the final \n, if they + # start with '#line' with some spacing allowed, or '#NUMBER'. This + # function stores them away and replaces them with exactly the string + # '#line@N', where N is the index in the list 'line_directives'. + line_directives = [] + def replace(m): + i = len(line_directives) + line_directives.append(m.group()) + return '#line@%d' % i + csource = _r_line_directive.sub(replace, csource) + return csource, line_directives + +def _put_back_line_directives(csource, line_directives): + def replace(m): + s = m.group() + if not s.startswith('#line@'): + raise AssertionError("unexpected #line directive " + "(should have been processed and removed") + return line_directives[int(s[6:])] + return _r_line_directive.sub(replace, csource) + +def _preprocess(csource): + # First, remove the lines of the form '#line N "filename"' because + # the "filename" part could confuse the rest + csource, line_directives = _remove_line_directives(csource) + # Remove comments. NOTE: this only work because the cdef() section + # should not contain any string literals (except in line directives)! + def replace_keeping_newlines(m): + return ' ' + m.group().count('\n') * '\n' + csource = _r_comment.sub(replace_keeping_newlines, csource) + # Remove the "#define FOO x" lines + macros = {} + for match in _r_define.finditer(csource): + macroname, macrovalue = match.groups() + macrovalue = macrovalue.replace('\\\n', '').strip() + macros[macroname] = macrovalue + csource = _r_define.sub('', csource) + # + if pycparser.__version__ < '2.14': + csource = _workaround_for_old_pycparser(csource) + # + # BIG HACK: replace WINAPI or __stdcall with "volatile const". + # It doesn't make sense for the return type of a function to be + # "volatile volatile const", so we abuse it to detect __stdcall... + # Hack number 2 is that "int(volatile *fptr)();" is not valid C + # syntax, so we place the "volatile" before the opening parenthesis. + csource = _r_stdcall2.sub(' volatile volatile const(', csource) + csource = _r_stdcall1.sub(' volatile volatile const ', csource) + csource = _r_cdecl.sub(' ', csource) + # + # Replace `extern "Python"` with start/end markers + csource = _preprocess_extern_python(csource) + # + # Now there should not be any string literal left; warn if we get one + _warn_for_string_literal(csource) + # + # Replace "[...]" with "[__dotdotdotarray__]" + csource = _r_partial_array.sub('[__dotdotdotarray__]', csource) + # + # Replace "...}" with "__dotdotdotNUM__}". This construction should + # occur only at the end of enums; at the end of structs we have "...;}" + # and at the end of vararg functions "...);". Also replace "=...[,}]" + # with ",__dotdotdotNUM__[,}]": this occurs in the enums too, when + # giving an unknown value. + matches = list(_r_partial_enum.finditer(csource)) + for number, match in enumerate(reversed(matches)): + p = match.start() + if csource[p] == '=': + p2 = csource.find('...', p, match.end()) + assert p2 > p + csource = '%s,__dotdotdot%d__ %s' % (csource[:p], number, + csource[p2+3:]) + else: + assert csource[p:p+3] == '...' + csource = '%s __dotdotdot%d__ %s' % (csource[:p], number, + csource[p+3:]) + # Replace "int ..." or "unsigned long int..." with "__dotdotdotint__" + csource = _r_int_dotdotdot.sub(' __dotdotdotint__ ', csource) + # Replace "float ..." or "double..." with "__dotdotdotfloat__" + csource = _r_float_dotdotdot.sub(' __dotdotdotfloat__ ', csource) + # Replace all remaining "..." with the same name, "__dotdotdot__", + # which is declared with a typedef for the purpose of C parsing. + csource = csource.replace('...', ' __dotdotdot__ ') + # Finally, put back the line directives + csource = _put_back_line_directives(csource, line_directives) + return csource, macros + +def _common_type_names(csource): + # Look in the source for what looks like usages of types from the + # list of common types. A "usage" is approximated here as the + # appearance of the word, minus a "definition" of the type, which + # is the last word in a "typedef" statement. Approximative only + # but should be fine for all the common types. + look_for_words = set(COMMON_TYPES) + look_for_words.add(';') + look_for_words.add(',') + look_for_words.add('(') + look_for_words.add(')') + look_for_words.add('typedef') + words_used = set() + is_typedef = False + paren = 0 + previous_word = '' + for word in _r_words.findall(csource): + if word in look_for_words: + if word == ';': + if is_typedef: + words_used.discard(previous_word) + look_for_words.discard(previous_word) + is_typedef = False + elif word == 'typedef': + is_typedef = True + paren = 0 + elif word == '(': + paren += 1 + elif word == ')': + paren -= 1 + elif word == ',': + if is_typedef and paren == 0: + words_used.discard(previous_word) + look_for_words.discard(previous_word) + else: # word in COMMON_TYPES + words_used.add(word) + previous_word = word + return words_used + + +class Parser(object): + + def __init__(self): + self._declarations = {} + self._included_declarations = set() + self._anonymous_counter = 0 + self._structnode2type = weakref.WeakKeyDictionary() + self._options = {} + self._int_constants = {} + self._recomplete = [] + self._uses_new_feature = None + + def _parse(self, csource): + csource, macros = _preprocess(csource) + # XXX: for more efficiency we would need to poke into the + # internals of CParser... the following registers the + # typedefs, because their presence or absence influences the + # parsing itself (but what they are typedef'ed to plays no role) + ctn = _common_type_names(csource) + typenames = [] + for name in sorted(self._declarations): + if name.startswith('typedef '): + name = name[8:] + typenames.append(name) + ctn.discard(name) + typenames += sorted(ctn) + # + csourcelines = [] + csourcelines.append('# 1 ""') + for typename in typenames: + csourcelines.append('typedef int %s;' % typename) + csourcelines.append('typedef int __dotdotdotint__, __dotdotdotfloat__,' + ' __dotdotdot__;') + # this forces pycparser to consider the following in the file + # called from line 1 + csourcelines.append('# 1 "%s"' % (CDEF_SOURCE_STRING,)) + csourcelines.append(csource) + fullcsource = '\n'.join(csourcelines) + if lock is not None: + lock.acquire() # pycparser is not thread-safe... + try: + ast = _get_parser().parse(fullcsource) + except pycparser.c_parser.ParseError as e: + self.convert_pycparser_error(e, csource) + finally: + if lock is not None: + lock.release() + # csource will be used to find buggy source text + return ast, macros, csource + + def _convert_pycparser_error(self, e, csource): + # xxx look for ":NUM:" at the start of str(e) + # and interpret that as a line number. This will not work if + # the user gives explicit ``# NUM "FILE"`` directives. + line = None + msg = str(e) + match = re.match(r"%s:(\d+):" % (CDEF_SOURCE_STRING,), msg) + if match: + linenum = int(match.group(1), 10) + csourcelines = csource.splitlines() + if 1 <= linenum <= len(csourcelines): + line = csourcelines[linenum-1] + return line + + def convert_pycparser_error(self, e, csource): + line = self._convert_pycparser_error(e, csource) + + msg = str(e) + if line: + msg = 'cannot parse "%s"\n%s' % (line.strip(), msg) + else: + msg = 'parse error\n%s' % (msg,) + raise CDefError(msg) + + def parse(self, csource, override=False, packed=False, pack=None, + dllexport=False): + if packed: + if packed != True: + raise ValueError("'packed' should be False or True; use " + "'pack' to give another value") + if pack: + raise ValueError("cannot give both 'pack' and 'packed'") + pack = 1 + elif pack: + if pack & (pack - 1): + raise ValueError("'pack' must be a power of two, not %r" % + (pack,)) + else: + pack = 0 + prev_options = self._options + try: + self._options = {'override': override, + 'packed': pack, + 'dllexport': dllexport} + self._internal_parse(csource) + finally: + self._options = prev_options + + def _internal_parse(self, csource): + ast, macros, csource = self._parse(csource) + # add the macros + self._process_macros(macros) + # find the first "__dotdotdot__" and use that as a separator + # between the repeated typedefs and the real csource + iterator = iter(ast.ext) + for decl in iterator: + if decl.name == '__dotdotdot__': + break + else: + assert 0 + current_decl = None + # + try: + self._inside_extern_python = '__cffi_extern_python_stop' + for decl in iterator: + current_decl = decl + if isinstance(decl, pycparser.c_ast.Decl): + self._parse_decl(decl) + elif isinstance(decl, pycparser.c_ast.Typedef): + if not decl.name: + raise CDefError("typedef does not declare any name", + decl) + quals = 0 + if (isinstance(decl.type.type, pycparser.c_ast.IdentifierType) and + decl.type.type.names[-1].startswith('__dotdotdot')): + realtype = self._get_unknown_type(decl) + elif (isinstance(decl.type, pycparser.c_ast.PtrDecl) and + isinstance(decl.type.type, pycparser.c_ast.TypeDecl) and + isinstance(decl.type.type.type, + pycparser.c_ast.IdentifierType) and + decl.type.type.type.names[-1].startswith('__dotdotdot')): + realtype = self._get_unknown_ptr_type(decl) + else: + realtype, quals = self._get_type_and_quals( + decl.type, name=decl.name, partial_length_ok=True, + typedef_example="*(%s *)0" % (decl.name,)) + self._declare('typedef ' + decl.name, realtype, quals=quals) + elif decl.__class__.__name__ == 'Pragma': + pass # skip pragma, only in pycparser 2.15 + else: + raise CDefError("unexpected <%s>: this construct is valid " + "C but not valid in cdef()" % + decl.__class__.__name__, decl) + except CDefError as e: + if len(e.args) == 1: + e.args = e.args + (current_decl,) + raise + except FFIError as e: + msg = self._convert_pycparser_error(e, csource) + if msg: + e.args = (e.args[0] + "\n *** Err: %s" % msg,) + raise + + def _add_constants(self, key, val): + if key in self._int_constants: + if self._int_constants[key] == val: + return # ignore identical double declarations + raise FFIError( + "multiple declarations of constant: %s" % (key,)) + self._int_constants[key] = val + + def _add_integer_constant(self, name, int_str): + int_str = int_str.lower().rstrip("ul") + neg = int_str.startswith('-') + if neg: + int_str = int_str[1:] + # "010" is not valid oct in py3 + if (int_str.startswith("0") and int_str != '0' + and not int_str.startswith("0x")): + int_str = "0o" + int_str[1:] + pyvalue = int(int_str, 0) + if neg: + pyvalue = -pyvalue + self._add_constants(name, pyvalue) + self._declare('macro ' + name, pyvalue) + + def _process_macros(self, macros): + for key, value in macros.items(): + value = value.strip() + if _r_int_literal.match(value): + self._add_integer_constant(key, value) + elif value == '...': + self._declare('macro ' + key, value) + else: + raise CDefError( + 'only supports one of the following syntax:\n' + ' #define %s ... (literally dot-dot-dot)\n' + ' #define %s NUMBER (with NUMBER an integer' + ' constant, decimal/hex/octal)\n' + 'got:\n' + ' #define %s %s' + % (key, key, key, value)) + + def _declare_function(self, tp, quals, decl): + tp = self._get_type_pointer(tp, quals) + if self._options.get('dllexport'): + tag = 'dllexport_python ' + elif self._inside_extern_python == '__cffi_extern_python_start': + tag = 'extern_python ' + elif self._inside_extern_python == '__cffi_extern_python_plus_c_start': + tag = 'extern_python_plus_c ' + else: + tag = 'function ' + self._declare(tag + decl.name, tp) + + def _parse_decl(self, decl): + node = decl.type + if isinstance(node, pycparser.c_ast.FuncDecl): + tp, quals = self._get_type_and_quals(node, name=decl.name) + assert isinstance(tp, model.RawFunctionType) + self._declare_function(tp, quals, decl) + else: + if isinstance(node, pycparser.c_ast.Struct): + self._get_struct_union_enum_type('struct', node) + elif isinstance(node, pycparser.c_ast.Union): + self._get_struct_union_enum_type('union', node) + elif isinstance(node, pycparser.c_ast.Enum): + self._get_struct_union_enum_type('enum', node) + elif not decl.name: + raise CDefError("construct does not declare any variable", + decl) + # + if decl.name: + tp, quals = self._get_type_and_quals(node, + partial_length_ok=True) + if tp.is_raw_function: + self._declare_function(tp, quals, decl) + elif (tp.is_integer_type() and + hasattr(decl, 'init') and + hasattr(decl.init, 'value') and + _r_int_literal.match(decl.init.value)): + self._add_integer_constant(decl.name, decl.init.value) + elif (tp.is_integer_type() and + isinstance(decl.init, pycparser.c_ast.UnaryOp) and + decl.init.op == '-' and + hasattr(decl.init.expr, 'value') and + _r_int_literal.match(decl.init.expr.value)): + self._add_integer_constant(decl.name, + '-' + decl.init.expr.value) + elif (tp is model.void_type and + decl.name.startswith('__cffi_extern_python_')): + # hack: `extern "Python"` in the C source is replaced + # with "void __cffi_extern_python_start;" and + # "void __cffi_extern_python_stop;" + self._inside_extern_python = decl.name + else: + if self._inside_extern_python !='__cffi_extern_python_stop': + raise CDefError( + "cannot declare constants or " + "variables with 'extern \"Python\"'") + if (quals & model.Q_CONST) and not tp.is_array_type: + self._declare('constant ' + decl.name, tp, quals=quals) + else: + _warn_for_non_extern_non_static_global_variable(decl) + self._declare('variable ' + decl.name, tp, quals=quals) + + def parse_type(self, cdecl): + return self.parse_type_and_quals(cdecl)[0] + + def parse_type_and_quals(self, cdecl): + ast, macros = self._parse('void __dummy(\n%s\n);' % cdecl)[:2] + assert not macros + exprnode = ast.ext[-1].type.args.params[0] + if isinstance(exprnode, pycparser.c_ast.ID): + raise CDefError("unknown identifier '%s'" % (exprnode.name,)) + return self._get_type_and_quals(exprnode.type) + + def _declare(self, name, obj, included=False, quals=0): + if name in self._declarations: + prevobj, prevquals = self._declarations[name] + if prevobj is obj and prevquals == quals: + return + if not self._options.get('override'): + raise FFIError( + "multiple declarations of %s (for interactive usage, " + "try cdef(xx, override=True))" % (name,)) + assert '__dotdotdot__' not in name.split() + self._declarations[name] = (obj, quals) + if included: + self._included_declarations.add(obj) + + def _extract_quals(self, type): + quals = 0 + if isinstance(type, (pycparser.c_ast.TypeDecl, + pycparser.c_ast.PtrDecl)): + if 'const' in type.quals: + quals |= model.Q_CONST + if 'volatile' in type.quals: + quals |= model.Q_VOLATILE + if 'restrict' in type.quals: + quals |= model.Q_RESTRICT + return quals + + def _get_type_pointer(self, type, quals, declname=None): + if isinstance(type, model.RawFunctionType): + return type.as_function_pointer() + if (isinstance(type, model.StructOrUnionOrEnum) and + type.name.startswith('$') and type.name[1:].isdigit() and + type.forcename is None and declname is not None): + return model.NamedPointerType(type, declname, quals) + return model.PointerType(type, quals) + + def _get_type_and_quals(self, typenode, name=None, partial_length_ok=False, + typedef_example=None): + # first, dereference typedefs, if we have it already parsed, we're good + if (isinstance(typenode, pycparser.c_ast.TypeDecl) and + isinstance(typenode.type, pycparser.c_ast.IdentifierType) and + len(typenode.type.names) == 1 and + ('typedef ' + typenode.type.names[0]) in self._declarations): + tp, quals = self._declarations['typedef ' + typenode.type.names[0]] + quals |= self._extract_quals(typenode) + return tp, quals + # + if isinstance(typenode, pycparser.c_ast.ArrayDecl): + # array type + if typenode.dim is None: + length = None + else: + length = self._parse_constant( + typenode.dim, partial_length_ok=partial_length_ok) + # a hack: in 'typedef int foo_t[...][...];', don't use '...' as + # the length but use directly the C expression that would be + # generated by recompiler.py. This lets the typedef be used in + # many more places within recompiler.py + if typedef_example is not None: + if length == '...': + length = '_cffi_array_len(%s)' % (typedef_example,) + typedef_example = "*" + typedef_example + # + tp, quals = self._get_type_and_quals(typenode.type, + partial_length_ok=partial_length_ok, + typedef_example=typedef_example) + return model.ArrayType(tp, length), quals + # + if isinstance(typenode, pycparser.c_ast.PtrDecl): + # pointer type + itemtype, itemquals = self._get_type_and_quals(typenode.type) + tp = self._get_type_pointer(itemtype, itemquals, declname=name) + quals = self._extract_quals(typenode) + return tp, quals + # + if isinstance(typenode, pycparser.c_ast.TypeDecl): + quals = self._extract_quals(typenode) + type = typenode.type + if isinstance(type, pycparser.c_ast.IdentifierType): + # assume a primitive type. get it from .names, but reduce + # synonyms to a single chosen combination + names = list(type.names) + if names != ['signed', 'char']: # keep this unmodified + prefixes = {} + while names: + name = names[0] + if name in ('short', 'long', 'signed', 'unsigned'): + prefixes[name] = prefixes.get(name, 0) + 1 + del names[0] + else: + break + # ignore the 'signed' prefix below, and reorder the others + newnames = [] + for prefix in ('unsigned', 'short', 'long'): + for i in range(prefixes.get(prefix, 0)): + newnames.append(prefix) + if not names: + names = ['int'] # implicitly + if names == ['int']: # but kill it if 'short' or 'long' + if 'short' in prefixes or 'long' in prefixes: + names = [] + names = newnames + names + ident = ' '.join(names) + if ident == 'void': + return model.void_type, quals + if ident == '__dotdotdot__': + raise FFIError(':%d: bad usage of "..."' % + typenode.coord.line) + tp0, quals0 = resolve_common_type(self, ident) + return tp0, (quals | quals0) + # + if isinstance(type, pycparser.c_ast.Struct): + # 'struct foobar' + tp = self._get_struct_union_enum_type('struct', type, name) + return tp, quals + # + if isinstance(type, pycparser.c_ast.Union): + # 'union foobar' + tp = self._get_struct_union_enum_type('union', type, name) + return tp, quals + # + if isinstance(type, pycparser.c_ast.Enum): + # 'enum foobar' + tp = self._get_struct_union_enum_type('enum', type, name) + return tp, quals + # + if isinstance(typenode, pycparser.c_ast.FuncDecl): + # a function type + return self._parse_function_type(typenode, name), 0 + # + # nested anonymous structs or unions end up here + if isinstance(typenode, pycparser.c_ast.Struct): + return self._get_struct_union_enum_type('struct', typenode, name, + nested=True), 0 + if isinstance(typenode, pycparser.c_ast.Union): + return self._get_struct_union_enum_type('union', typenode, name, + nested=True), 0 + # + raise FFIError(":%d: bad or unsupported type declaration" % + typenode.coord.line) + + def _parse_function_type(self, typenode, funcname=None): + params = list(getattr(typenode.args, 'params', [])) + for i, arg in enumerate(params): + if not hasattr(arg, 'type'): + raise CDefError("%s arg %d: unknown type '%s'" + " (if you meant to use the old C syntax of giving" + " untyped arguments, it is not supported)" + % (funcname or 'in expression', i + 1, + getattr(arg, 'name', '?'))) + ellipsis = ( + len(params) > 0 and + isinstance(params[-1].type, pycparser.c_ast.TypeDecl) and + isinstance(params[-1].type.type, + pycparser.c_ast.IdentifierType) and + params[-1].type.type.names == ['__dotdotdot__']) + if ellipsis: + params.pop() + if not params: + raise CDefError( + "%s: a function with only '(...)' as argument" + " is not correct C" % (funcname or 'in expression')) + args = [self._as_func_arg(*self._get_type_and_quals(argdeclnode.type)) + for argdeclnode in params] + if not ellipsis and args == [model.void_type]: + args = [] + result, quals = self._get_type_and_quals(typenode.type) + # the 'quals' on the result type are ignored. HACK: we absure them + # to detect __stdcall functions: we textually replace "__stdcall" + # with "volatile volatile const" above. + abi = None + if hasattr(typenode.type, 'quals'): # else, probable syntax error anyway + if typenode.type.quals[-3:] == ['volatile', 'volatile', 'const']: + abi = '__stdcall' + return model.RawFunctionType(tuple(args), result, ellipsis, abi) + + def _as_func_arg(self, type, quals): + if isinstance(type, model.ArrayType): + return model.PointerType(type.item, quals) + elif isinstance(type, model.RawFunctionType): + return type.as_function_pointer() + else: + return type + + def _get_struct_union_enum_type(self, kind, type, name=None, nested=False): + # First, a level of caching on the exact 'type' node of the AST. + # This is obscure, but needed because pycparser "unrolls" declarations + # such as "typedef struct { } foo_t, *foo_p" and we end up with + # an AST that is not a tree, but a DAG, with the "type" node of the + # two branches foo_t and foo_p of the trees being the same node. + # It's a bit silly but detecting "DAG-ness" in the AST tree seems + # to be the only way to distinguish this case from two independent + # structs. See test_struct_with_two_usages. + try: + return self._structnode2type[type] + except KeyError: + pass + # + # Note that this must handle parsing "struct foo" any number of + # times and always return the same StructType object. Additionally, + # one of these times (not necessarily the first), the fields of + # the struct can be specified with "struct foo { ...fields... }". + # If no name is given, then we have to create a new anonymous struct + # with no caching; in this case, the fields are either specified + # right now or never. + # + force_name = name + name = type.name + # + # get the type or create it if needed + if name is None: + # 'force_name' is used to guess a more readable name for + # anonymous structs, for the common case "typedef struct { } foo". + if force_name is not None: + explicit_name = '$%s' % force_name + else: + self._anonymous_counter += 1 + explicit_name = '$%d' % self._anonymous_counter + tp = None + else: + explicit_name = name + key = '%s %s' % (kind, name) + tp, _ = self._declarations.get(key, (None, None)) + # + if tp is None: + if kind == 'struct': + tp = model.StructType(explicit_name, None, None, None) + elif kind == 'union': + tp = model.UnionType(explicit_name, None, None, None) + elif kind == 'enum': + if explicit_name == '__dotdotdot__': + raise CDefError("Enums cannot be declared with ...") + tp = self._build_enum_type(explicit_name, type.values) + else: + raise AssertionError("kind = %r" % (kind,)) + if name is not None: + self._declare(key, tp) + else: + if kind == 'enum' and type.values is not None: + raise NotImplementedError( + "enum %s: the '{}' declaration should appear on the first " + "time the enum is mentioned, not later" % explicit_name) + if not tp.forcename: + tp.force_the_name(force_name) + if tp.forcename and '$' in tp.name: + self._declare('anonymous %s' % tp.forcename, tp) + # + self._structnode2type[type] = tp + # + # enums: done here + if kind == 'enum': + return tp + # + # is there a 'type.decls'? If yes, then this is the place in the + # C sources that declare the fields. If no, then just return the + # existing type, possibly still incomplete. + if type.decls is None: + return tp + # + if tp.fldnames is not None: + raise CDefError("duplicate declaration of struct %s" % name) + fldnames = [] + fldtypes = [] + fldbitsize = [] + fldquals = [] + for decl in type.decls: + if (isinstance(decl.type, pycparser.c_ast.IdentifierType) and + ''.join(decl.type.names) == '__dotdotdot__'): + # XXX pycparser is inconsistent: 'names' should be a list + # of strings, but is sometimes just one string. Use + # str.join() as a way to cope with both. + self._make_partial(tp, nested) + continue + if decl.bitsize is None: + bitsize = -1 + else: + bitsize = self._parse_constant(decl.bitsize) + self._partial_length = False + type, fqual = self._get_type_and_quals(decl.type, + partial_length_ok=True) + if self._partial_length: + self._make_partial(tp, nested) + if isinstance(type, model.StructType) and type.partial: + self._make_partial(tp, nested) + fldnames.append(decl.name or '') + fldtypes.append(type) + fldbitsize.append(bitsize) + fldquals.append(fqual) + tp.fldnames = tuple(fldnames) + tp.fldtypes = tuple(fldtypes) + tp.fldbitsize = tuple(fldbitsize) + tp.fldquals = tuple(fldquals) + if fldbitsize != [-1] * len(fldbitsize): + if isinstance(tp, model.StructType) and tp.partial: + raise NotImplementedError("%s: using both bitfields and '...;'" + % (tp,)) + tp.packed = self._options.get('packed') + if tp.completed: # must be re-completed: it is not opaque any more + tp.completed = 0 + self._recomplete.append(tp) + return tp + + def _make_partial(self, tp, nested): + if not isinstance(tp, model.StructOrUnion): + raise CDefError("%s cannot be partial" % (tp,)) + if not tp.has_c_name() and not nested: + raise NotImplementedError("%s is partial but has no C name" %(tp,)) + tp.partial = True + + def _parse_constant(self, exprnode, partial_length_ok=False): + # for now, limited to expressions that are an immediate number + # or positive/negative number + if isinstance(exprnode, pycparser.c_ast.Constant): + s = exprnode.value + if '0' <= s[0] <= '9': + s = s.rstrip('uUlL') + try: + if s.startswith('0'): + return int(s, 8) + else: + return int(s, 10) + except ValueError: + if len(s) > 1: + if s.lower()[0:2] == '0x': + return int(s, 16) + elif s.lower()[0:2] == '0b': + return int(s, 2) + raise CDefError("invalid constant %r" % (s,)) + elif s[0] == "'" and s[-1] == "'" and ( + len(s) == 3 or (len(s) == 4 and s[1] == "\\")): + return ord(s[-2]) + else: + raise CDefError("invalid constant %r" % (s,)) + # + if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and + exprnode.op == '+'): + return self._parse_constant(exprnode.expr) + # + if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and + exprnode.op == '-'): + return -self._parse_constant(exprnode.expr) + # load previously defined int constant + if (isinstance(exprnode, pycparser.c_ast.ID) and + exprnode.name in self._int_constants): + return self._int_constants[exprnode.name] + # + if (isinstance(exprnode, pycparser.c_ast.ID) and + exprnode.name == '__dotdotdotarray__'): + if partial_length_ok: + self._partial_length = True + return '...' + raise FFIError(":%d: unsupported '[...]' here, cannot derive " + "the actual array length in this context" + % exprnode.coord.line) + # + if isinstance(exprnode, pycparser.c_ast.BinaryOp): + left = self._parse_constant(exprnode.left) + right = self._parse_constant(exprnode.right) + if exprnode.op == '+': + return left + right + elif exprnode.op == '-': + return left - right + elif exprnode.op == '*': + return left * right + elif exprnode.op == '/': + return self._c_div(left, right) + elif exprnode.op == '%': + return left - self._c_div(left, right) * right + elif exprnode.op == '<<': + return left << right + elif exprnode.op == '>>': + return left >> right + elif exprnode.op == '&': + return left & right + elif exprnode.op == '|': + return left | right + elif exprnode.op == '^': + return left ^ right + # + raise FFIError(":%d: unsupported expression: expected a " + "simple numeric constant" % exprnode.coord.line) + + def _c_div(self, a, b): + result = a // b + if ((a < 0) ^ (b < 0)) and (a % b) != 0: + result += 1 + return result + + def _build_enum_type(self, explicit_name, decls): + if decls is not None: + partial = False + enumerators = [] + enumvalues = [] + nextenumvalue = 0 + for enum in decls.enumerators: + if _r_enum_dotdotdot.match(enum.name): + partial = True + continue + if enum.value is not None: + nextenumvalue = self._parse_constant(enum.value) + enumerators.append(enum.name) + enumvalues.append(nextenumvalue) + self._add_constants(enum.name, nextenumvalue) + nextenumvalue += 1 + enumerators = tuple(enumerators) + enumvalues = tuple(enumvalues) + tp = model.EnumType(explicit_name, enumerators, enumvalues) + tp.partial = partial + else: # opaque enum + tp = model.EnumType(explicit_name, (), ()) + return tp + + def include(self, other): + for name, (tp, quals) in other._declarations.items(): + if name.startswith('anonymous $enum_$'): + continue # fix for test_anonymous_enum_include + kind = name.split(' ', 1)[0] + if kind in ('struct', 'union', 'enum', 'anonymous', 'typedef'): + self._declare(name, tp, included=True, quals=quals) + for k, v in other._int_constants.items(): + self._add_constants(k, v) + + def _get_unknown_type(self, decl): + typenames = decl.type.type.names + if typenames == ['__dotdotdot__']: + return model.unknown_type(decl.name) + + if typenames == ['__dotdotdotint__']: + if self._uses_new_feature is None: + self._uses_new_feature = "'typedef int... %s'" % decl.name + return model.UnknownIntegerType(decl.name) + + if typenames == ['__dotdotdotfloat__']: + # note: not for 'long double' so far + if self._uses_new_feature is None: + self._uses_new_feature = "'typedef float... %s'" % decl.name + return model.UnknownFloatType(decl.name) + + raise FFIError(':%d: unsupported usage of "..." in typedef' + % decl.coord.line) + + def _get_unknown_ptr_type(self, decl): + if decl.type.type.type.names == ['__dotdotdot__']: + return model.unknown_ptr_type(decl.name) + raise FFIError(':%d: unsupported usage of "..." in typedef' + % decl.coord.line) diff --git a/dist/ba_data/python-site-packages/cffi/error.py b/dist/ba_data/python-site-packages/cffi/error.py new file mode 100644 index 0000000..0a27247 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/error.py @@ -0,0 +1,31 @@ + +class FFIError(Exception): + __module__ = 'cffi' + +class CDefError(Exception): + __module__ = 'cffi' + def __str__(self): + try: + current_decl = self.args[1] + filename = current_decl.coord.file + linenum = current_decl.coord.line + prefix = '%s:%d: ' % (filename, linenum) + except (AttributeError, TypeError, IndexError): + prefix = '' + return '%s%s' % (prefix, self.args[0]) + +class VerificationError(Exception): + """ An error raised when verification fails + """ + __module__ = 'cffi' + +class VerificationMissing(Exception): + """ An error raised when incomplete structures are passed into + cdef, but no verification has been done + """ + __module__ = 'cffi' + +class PkgConfigError(Exception): + """ An error raised for missing modules in pkg-config + """ + __module__ = 'cffi' diff --git a/dist/ba_data/python-site-packages/cffi/ffiplatform.py b/dist/ba_data/python-site-packages/cffi/ffiplatform.py new file mode 100644 index 0000000..8531346 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/ffiplatform.py @@ -0,0 +1,127 @@ +import sys, os +from .error import VerificationError + + +LIST_OF_FILE_NAMES = ['sources', 'include_dirs', 'library_dirs', + 'extra_objects', 'depends'] + +def get_extension(srcfilename, modname, sources=(), **kwds): + _hack_at_distutils() + from distutils.core import Extension + allsources = [srcfilename] + for src in sources: + allsources.append(os.path.normpath(src)) + return Extension(name=modname, sources=allsources, **kwds) + +def compile(tmpdir, ext, compiler_verbose=0, debug=None): + """Compile a C extension module using distutils.""" + + _hack_at_distutils() + saved_environ = os.environ.copy() + try: + outputfilename = _build(tmpdir, ext, compiler_verbose, debug) + outputfilename = os.path.abspath(outputfilename) + finally: + # workaround for a distutils bugs where some env vars can + # become longer and longer every time it is used + for key, value in saved_environ.items(): + if os.environ.get(key) != value: + os.environ[key] = value + return outputfilename + +def _build(tmpdir, ext, compiler_verbose=0, debug=None): + # XXX compact but horrible :-( + from distutils.core import Distribution + import distutils.errors, distutils.log + # + dist = Distribution({'ext_modules': [ext]}) + dist.parse_config_files() + options = dist.get_option_dict('build_ext') + if debug is None: + debug = sys.flags.debug + options['debug'] = ('ffiplatform', debug) + options['force'] = ('ffiplatform', True) + options['build_lib'] = ('ffiplatform', tmpdir) + options['build_temp'] = ('ffiplatform', tmpdir) + # + try: + old_level = distutils.log.set_threshold(0) or 0 + try: + distutils.log.set_verbosity(compiler_verbose) + dist.run_command('build_ext') + cmd_obj = dist.get_command_obj('build_ext') + [soname] = cmd_obj.get_outputs() + finally: + distutils.log.set_threshold(old_level) + except (distutils.errors.CompileError, + distutils.errors.LinkError) as e: + raise VerificationError('%s: %s' % (e.__class__.__name__, e)) + # + return soname + +try: + from os.path import samefile +except ImportError: + def samefile(f1, f2): + return os.path.abspath(f1) == os.path.abspath(f2) + +def maybe_relative_path(path): + if not os.path.isabs(path): + return path # already relative + dir = path + names = [] + while True: + prevdir = dir + dir, name = os.path.split(prevdir) + if dir == prevdir or not dir: + return path # failed to make it relative + names.append(name) + try: + if samefile(dir, os.curdir): + names.reverse() + return os.path.join(*names) + except OSError: + pass + +# ____________________________________________________________ + +try: + int_or_long = (int, long) + import cStringIO +except NameError: + int_or_long = int # Python 3 + import io as cStringIO + +def _flatten(x, f): + if isinstance(x, str): + f.write('%ds%s' % (len(x), x)) + elif isinstance(x, dict): + keys = sorted(x.keys()) + f.write('%dd' % len(keys)) + for key in keys: + _flatten(key, f) + _flatten(x[key], f) + elif isinstance(x, (list, tuple)): + f.write('%dl' % len(x)) + for value in x: + _flatten(value, f) + elif isinstance(x, int_or_long): + f.write('%di' % (x,)) + else: + raise TypeError( + "the keywords to verify() contains unsupported object %r" % (x,)) + +def flatten(x): + f = cStringIO.StringIO() + _flatten(x, f) + return f.getvalue() + +def _hack_at_distutils(): + # Windows-only workaround for some configurations: see + # https://bugs.python.org/issue23246 (Python 2.7 with + # a specific MS compiler suite download) + if sys.platform == "win32": + try: + import setuptools # for side-effects, patches distutils + except ImportError: + pass diff --git a/dist/ba_data/python-site-packages/cffi/lock.py b/dist/ba_data/python-site-packages/cffi/lock.py new file mode 100644 index 0000000..db91b71 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/lock.py @@ -0,0 +1,30 @@ +import sys + +if sys.version_info < (3,): + try: + from thread import allocate_lock + except ImportError: + from dummy_thread import allocate_lock +else: + try: + from _thread import allocate_lock + except ImportError: + from _dummy_thread import allocate_lock + + +##import sys +##l1 = allocate_lock + +##class allocate_lock(object): +## def __init__(self): +## self._real = l1() +## def __enter__(self): +## for i in range(4, 0, -1): +## print sys._getframe(i).f_code +## print +## return self._real.__enter__() +## def __exit__(self, *args): +## return self._real.__exit__(*args) +## def acquire(self, f): +## assert f is False +## return self._real.acquire(f) diff --git a/dist/ba_data/python-site-packages/cffi/model.py b/dist/ba_data/python-site-packages/cffi/model.py new file mode 100644 index 0000000..ad1c176 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/model.py @@ -0,0 +1,617 @@ +import types +import weakref + +from .lock import allocate_lock +from .error import CDefError, VerificationError, VerificationMissing + +# type qualifiers +Q_CONST = 0x01 +Q_RESTRICT = 0x02 +Q_VOLATILE = 0x04 + +def qualify(quals, replace_with): + if quals & Q_CONST: + replace_with = ' const ' + replace_with.lstrip() + if quals & Q_VOLATILE: + replace_with = ' volatile ' + replace_with.lstrip() + if quals & Q_RESTRICT: + # It seems that __restrict is supported by gcc and msvc. + # If you hit some different compiler, add a #define in + # _cffi_include.h for it (and in its copies, documented there) + replace_with = ' __restrict ' + replace_with.lstrip() + return replace_with + + +class BaseTypeByIdentity(object): + is_array_type = False + is_raw_function = False + + def get_c_name(self, replace_with='', context='a C file', quals=0): + result = self.c_name_with_marker + assert result.count('&') == 1 + # some logic duplication with ffi.getctype()... :-( + replace_with = replace_with.strip() + if replace_with: + if replace_with.startswith('*') and '&[' in result: + replace_with = '(%s)' % replace_with + elif not replace_with[0] in '[(': + replace_with = ' ' + replace_with + replace_with = qualify(quals, replace_with) + result = result.replace('&', replace_with) + if '$' in result: + raise VerificationError( + "cannot generate '%s' in %s: unknown type name" + % (self._get_c_name(), context)) + return result + + def _get_c_name(self): + return self.c_name_with_marker.replace('&', '') + + def has_c_name(self): + return '$' not in self._get_c_name() + + def is_integer_type(self): + return False + + def get_cached_btype(self, ffi, finishlist, can_delay=False): + try: + BType = ffi._cached_btypes[self] + except KeyError: + BType = self.build_backend_type(ffi, finishlist) + BType2 = ffi._cached_btypes.setdefault(self, BType) + assert BType2 is BType + return BType + + def __repr__(self): + return '<%s>' % (self._get_c_name(),) + + def _get_items(self): + return [(name, getattr(self, name)) for name in self._attrs_] + + +class BaseType(BaseTypeByIdentity): + + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self._get_items() == other._get_items()) + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.__class__, tuple(self._get_items()))) + + +class VoidType(BaseType): + _attrs_ = () + + def __init__(self): + self.c_name_with_marker = 'void&' + + def build_backend_type(self, ffi, finishlist): + return global_cache(self, ffi, 'new_void_type') + +void_type = VoidType() + + +class BasePrimitiveType(BaseType): + def is_complex_type(self): + return False + + +class PrimitiveType(BasePrimitiveType): + _attrs_ = ('name',) + + ALL_PRIMITIVE_TYPES = { + 'char': 'c', + 'short': 'i', + 'int': 'i', + 'long': 'i', + 'long long': 'i', + 'signed char': 'i', + 'unsigned char': 'i', + 'unsigned short': 'i', + 'unsigned int': 'i', + 'unsigned long': 'i', + 'unsigned long long': 'i', + 'float': 'f', + 'double': 'f', + 'long double': 'f', + 'float _Complex': 'j', + 'double _Complex': 'j', + '_Bool': 'i', + # the following types are not primitive in the C sense + 'wchar_t': 'c', + 'char16_t': 'c', + 'char32_t': 'c', + 'int8_t': 'i', + 'uint8_t': 'i', + 'int16_t': 'i', + 'uint16_t': 'i', + 'int32_t': 'i', + 'uint32_t': 'i', + 'int64_t': 'i', + 'uint64_t': 'i', + 'int_least8_t': 'i', + 'uint_least8_t': 'i', + 'int_least16_t': 'i', + 'uint_least16_t': 'i', + 'int_least32_t': 'i', + 'uint_least32_t': 'i', + 'int_least64_t': 'i', + 'uint_least64_t': 'i', + 'int_fast8_t': 'i', + 'uint_fast8_t': 'i', + 'int_fast16_t': 'i', + 'uint_fast16_t': 'i', + 'int_fast32_t': 'i', + 'uint_fast32_t': 'i', + 'int_fast64_t': 'i', + 'uint_fast64_t': 'i', + 'intptr_t': 'i', + 'uintptr_t': 'i', + 'intmax_t': 'i', + 'uintmax_t': 'i', + 'ptrdiff_t': 'i', + 'size_t': 'i', + 'ssize_t': 'i', + } + + def __init__(self, name): + assert name in self.ALL_PRIMITIVE_TYPES + self.name = name + self.c_name_with_marker = name + '&' + + def is_char_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'c' + def is_integer_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'i' + def is_float_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'f' + def is_complex_type(self): + return self.ALL_PRIMITIVE_TYPES[self.name] == 'j' + + def build_backend_type(self, ffi, finishlist): + return global_cache(self, ffi, 'new_primitive_type', self.name) + + +class UnknownIntegerType(BasePrimitiveType): + _attrs_ = ('name',) + + def __init__(self, name): + self.name = name + self.c_name_with_marker = name + '&' + + def is_integer_type(self): + return True + + def build_backend_type(self, ffi, finishlist): + raise NotImplementedError("integer type '%s' can only be used after " + "compilation" % self.name) + +class UnknownFloatType(BasePrimitiveType): + _attrs_ = ('name', ) + + def __init__(self, name): + self.name = name + self.c_name_with_marker = name + '&' + + def build_backend_type(self, ffi, finishlist): + raise NotImplementedError("float type '%s' can only be used after " + "compilation" % self.name) + + +class BaseFunctionType(BaseType): + _attrs_ = ('args', 'result', 'ellipsis', 'abi') + + def __init__(self, args, result, ellipsis, abi=None): + self.args = args + self.result = result + self.ellipsis = ellipsis + self.abi = abi + # + reprargs = [arg._get_c_name() for arg in self.args] + if self.ellipsis: + reprargs.append('...') + reprargs = reprargs or ['void'] + replace_with = self._base_pattern % (', '.join(reprargs),) + if abi is not None: + replace_with = replace_with[:1] + abi + ' ' + replace_with[1:] + self.c_name_with_marker = ( + self.result.c_name_with_marker.replace('&', replace_with)) + + +class RawFunctionType(BaseFunctionType): + # Corresponds to a C type like 'int(int)', which is the C type of + # a function, but not a pointer-to-function. The backend has no + # notion of such a type; it's used temporarily by parsing. + _base_pattern = '(&)(%s)' + is_raw_function = True + + def build_backend_type(self, ffi, finishlist): + raise CDefError("cannot render the type %r: it is a function " + "type, not a pointer-to-function type" % (self,)) + + def as_function_pointer(self): + return FunctionPtrType(self.args, self.result, self.ellipsis, self.abi) + + +class FunctionPtrType(BaseFunctionType): + _base_pattern = '(*&)(%s)' + + def build_backend_type(self, ffi, finishlist): + result = self.result.get_cached_btype(ffi, finishlist) + args = [] + for tp in self.args: + args.append(tp.get_cached_btype(ffi, finishlist)) + abi_args = () + if self.abi == "__stdcall": + if not self.ellipsis: # __stdcall ignored for variadic funcs + try: + abi_args = (ffi._backend.FFI_STDCALL,) + except AttributeError: + pass + return global_cache(self, ffi, 'new_function_type', + tuple(args), result, self.ellipsis, *abi_args) + + def as_raw_function(self): + return RawFunctionType(self.args, self.result, self.ellipsis, self.abi) + + +class PointerType(BaseType): + _attrs_ = ('totype', 'quals') + + def __init__(self, totype, quals=0): + self.totype = totype + self.quals = quals + extra = qualify(quals, " *&") + if totype.is_array_type: + extra = "(%s)" % (extra.lstrip(),) + self.c_name_with_marker = totype.c_name_with_marker.replace('&', extra) + + def build_backend_type(self, ffi, finishlist): + BItem = self.totype.get_cached_btype(ffi, finishlist, can_delay=True) + return global_cache(self, ffi, 'new_pointer_type', BItem) + +voidp_type = PointerType(void_type) + +def ConstPointerType(totype): + return PointerType(totype, Q_CONST) + +const_voidp_type = ConstPointerType(void_type) + + +class NamedPointerType(PointerType): + _attrs_ = ('totype', 'name') + + def __init__(self, totype, name, quals=0): + PointerType.__init__(self, totype, quals) + self.name = name + self.c_name_with_marker = name + '&' + + +class ArrayType(BaseType): + _attrs_ = ('item', 'length') + is_array_type = True + + def __init__(self, item, length): + self.item = item + self.length = length + # + if length is None: + brackets = '&[]' + elif length == '...': + brackets = '&[/*...*/]' + else: + brackets = '&[%s]' % length + self.c_name_with_marker = ( + self.item.c_name_with_marker.replace('&', brackets)) + + def length_is_unknown(self): + return isinstance(self.length, str) + + def resolve_length(self, newlength): + return ArrayType(self.item, newlength) + + def build_backend_type(self, ffi, finishlist): + if self.length_is_unknown(): + raise CDefError("cannot render the type %r: unknown length" % + (self,)) + self.item.get_cached_btype(ffi, finishlist) # force the item BType + BPtrItem = PointerType(self.item).get_cached_btype(ffi, finishlist) + return global_cache(self, ffi, 'new_array_type', BPtrItem, self.length) + +char_array_type = ArrayType(PrimitiveType('char'), None) + + +class StructOrUnionOrEnum(BaseTypeByIdentity): + _attrs_ = ('name',) + forcename = None + + def build_c_name_with_marker(self): + name = self.forcename or '%s %s' % (self.kind, self.name) + self.c_name_with_marker = name + '&' + + def force_the_name(self, forcename): + self.forcename = forcename + self.build_c_name_with_marker() + + def get_official_name(self): + assert self.c_name_with_marker.endswith('&') + return self.c_name_with_marker[:-1] + + +class StructOrUnion(StructOrUnionOrEnum): + fixedlayout = None + completed = 0 + partial = False + packed = 0 + + def __init__(self, name, fldnames, fldtypes, fldbitsize, fldquals=None): + self.name = name + self.fldnames = fldnames + self.fldtypes = fldtypes + self.fldbitsize = fldbitsize + self.fldquals = fldquals + self.build_c_name_with_marker() + + def anonymous_struct_fields(self): + if self.fldtypes is not None: + for name, type in zip(self.fldnames, self.fldtypes): + if name == '' and isinstance(type, StructOrUnion): + yield type + + def enumfields(self, expand_anonymous_struct_union=True): + fldquals = self.fldquals + if fldquals is None: + fldquals = (0,) * len(self.fldnames) + for name, type, bitsize, quals in zip(self.fldnames, self.fldtypes, + self.fldbitsize, fldquals): + if (name == '' and isinstance(type, StructOrUnion) + and expand_anonymous_struct_union): + # nested anonymous struct/union + for result in type.enumfields(): + yield result + else: + yield (name, type, bitsize, quals) + + def force_flatten(self): + # force the struct or union to have a declaration that lists + # directly all fields returned by enumfields(), flattening + # nested anonymous structs/unions. + names = [] + types = [] + bitsizes = [] + fldquals = [] + for name, type, bitsize, quals in self.enumfields(): + names.append(name) + types.append(type) + bitsizes.append(bitsize) + fldquals.append(quals) + self.fldnames = tuple(names) + self.fldtypes = tuple(types) + self.fldbitsize = tuple(bitsizes) + self.fldquals = tuple(fldquals) + + def get_cached_btype(self, ffi, finishlist, can_delay=False): + BType = StructOrUnionOrEnum.get_cached_btype(self, ffi, finishlist, + can_delay) + if not can_delay: + self.finish_backend_type(ffi, finishlist) + return BType + + def finish_backend_type(self, ffi, finishlist): + if self.completed: + if self.completed != 2: + raise NotImplementedError("recursive structure declaration " + "for '%s'" % (self.name,)) + return + BType = ffi._cached_btypes[self] + # + self.completed = 1 + # + if self.fldtypes is None: + pass # not completing it: it's an opaque struct + # + elif self.fixedlayout is None: + fldtypes = [tp.get_cached_btype(ffi, finishlist) + for tp in self.fldtypes] + lst = list(zip(self.fldnames, fldtypes, self.fldbitsize)) + extra_flags = () + if self.packed: + if self.packed == 1: + extra_flags = (8,) # SF_PACKED + else: + extra_flags = (0, self.packed) + ffi._backend.complete_struct_or_union(BType, lst, self, + -1, -1, *extra_flags) + # + else: + fldtypes = [] + fieldofs, fieldsize, totalsize, totalalignment = self.fixedlayout + for i in range(len(self.fldnames)): + fsize = fieldsize[i] + ftype = self.fldtypes[i] + # + if isinstance(ftype, ArrayType) and ftype.length_is_unknown(): + # fix the length to match the total size + BItemType = ftype.item.get_cached_btype(ffi, finishlist) + nlen, nrest = divmod(fsize, ffi.sizeof(BItemType)) + if nrest != 0: + self._verification_error( + "field '%s.%s' has a bogus size?" % ( + self.name, self.fldnames[i] or '{}')) + ftype = ftype.resolve_length(nlen) + self.fldtypes = (self.fldtypes[:i] + (ftype,) + + self.fldtypes[i+1:]) + # + BFieldType = ftype.get_cached_btype(ffi, finishlist) + if isinstance(ftype, ArrayType) and ftype.length is None: + assert fsize == 0 + else: + bitemsize = ffi.sizeof(BFieldType) + if bitemsize != fsize: + self._verification_error( + "field '%s.%s' is declared as %d bytes, but is " + "really %d bytes" % (self.name, + self.fldnames[i] or '{}', + bitemsize, fsize)) + fldtypes.append(BFieldType) + # + lst = list(zip(self.fldnames, fldtypes, self.fldbitsize, fieldofs)) + ffi._backend.complete_struct_or_union(BType, lst, self, + totalsize, totalalignment) + self.completed = 2 + + def _verification_error(self, msg): + raise VerificationError(msg) + + def check_not_partial(self): + if self.partial and self.fixedlayout is None: + raise VerificationMissing(self._get_c_name()) + + def build_backend_type(self, ffi, finishlist): + self.check_not_partial() + finishlist.append(self) + # + return global_cache(self, ffi, 'new_%s_type' % self.kind, + self.get_official_name(), key=self) + + +class StructType(StructOrUnion): + kind = 'struct' + + +class UnionType(StructOrUnion): + kind = 'union' + + +class EnumType(StructOrUnionOrEnum): + kind = 'enum' + partial = False + partial_resolved = False + + def __init__(self, name, enumerators, enumvalues, baseinttype=None): + self.name = name + self.enumerators = enumerators + self.enumvalues = enumvalues + self.baseinttype = baseinttype + self.build_c_name_with_marker() + + def force_the_name(self, forcename): + StructOrUnionOrEnum.force_the_name(self, forcename) + if self.forcename is None: + name = self.get_official_name() + self.forcename = '$' + name.replace(' ', '_') + + def check_not_partial(self): + if self.partial and not self.partial_resolved: + raise VerificationMissing(self._get_c_name()) + + def build_backend_type(self, ffi, finishlist): + self.check_not_partial() + base_btype = self.build_baseinttype(ffi, finishlist) + return global_cache(self, ffi, 'new_enum_type', + self.get_official_name(), + self.enumerators, self.enumvalues, + base_btype, key=self) + + def build_baseinttype(self, ffi, finishlist): + if self.baseinttype is not None: + return self.baseinttype.get_cached_btype(ffi, finishlist) + # + if self.enumvalues: + smallest_value = min(self.enumvalues) + largest_value = max(self.enumvalues) + else: + import warnings + try: + # XXX! The goal is to ensure that the warnings.warn() + # will not suppress the warning. We want to get it + # several times if we reach this point several times. + __warningregistry__.clear() + except NameError: + pass + warnings.warn("%r has no values explicitly defined; " + "guessing that it is equivalent to 'unsigned int'" + % self._get_c_name()) + smallest_value = largest_value = 0 + if smallest_value < 0: # needs a signed type + sign = 1 + candidate1 = PrimitiveType("int") + candidate2 = PrimitiveType("long") + else: + sign = 0 + candidate1 = PrimitiveType("unsigned int") + candidate2 = PrimitiveType("unsigned long") + btype1 = candidate1.get_cached_btype(ffi, finishlist) + btype2 = candidate2.get_cached_btype(ffi, finishlist) + size1 = ffi.sizeof(btype1) + size2 = ffi.sizeof(btype2) + if (smallest_value >= ((-1) << (8*size1-1)) and + largest_value < (1 << (8*size1-sign))): + return btype1 + if (smallest_value >= ((-1) << (8*size2-1)) and + largest_value < (1 << (8*size2-sign))): + return btype2 + raise CDefError("%s values don't all fit into either 'long' " + "or 'unsigned long'" % self._get_c_name()) + +def unknown_type(name, structname=None): + if structname is None: + structname = '$%s' % name + tp = StructType(structname, None, None, None) + tp.force_the_name(name) + tp.origin = "unknown_type" + return tp + +def unknown_ptr_type(name, structname=None): + if structname is None: + structname = '$$%s' % name + tp = StructType(structname, None, None, None) + return NamedPointerType(tp, name) + + +global_lock = allocate_lock() +_typecache_cffi_backend = weakref.WeakValueDictionary() + +def get_typecache(backend): + # returns _typecache_cffi_backend if backend is the _cffi_backend + # module, or type(backend).__typecache if backend is an instance of + # CTypesBackend (or some FakeBackend class during tests) + if isinstance(backend, types.ModuleType): + return _typecache_cffi_backend + with global_lock: + if not hasattr(type(backend), '__typecache'): + type(backend).__typecache = weakref.WeakValueDictionary() + return type(backend).__typecache + +def global_cache(srctype, ffi, funcname, *args, **kwds): + key = kwds.pop('key', (funcname, args)) + assert not kwds + try: + return ffi._typecache[key] + except KeyError: + pass + try: + res = getattr(ffi._backend, funcname)(*args) + except NotImplementedError as e: + raise NotImplementedError("%s: %r: %s" % (funcname, srctype, e)) + # note that setdefault() on WeakValueDictionary is not atomic + # and contains a rare bug (http://bugs.python.org/issue19542); + # we have to use a lock and do it ourselves + cache = ffi._typecache + with global_lock: + res1 = cache.get(key) + if res1 is None: + cache[key] = res + return res + else: + return res1 + +def pointer_cache(ffi, BType): + return global_cache('?', ffi, 'new_pointer_type', BType) + +def attach_exception_info(e, name): + if e.args and type(e.args[0]) is str: + e.args = ('%s: %s' % (name, e.args[0]),) + e.args[1:] diff --git a/dist/ba_data/python-site-packages/cffi/parse_c_type.h b/dist/ba_data/python-site-packages/cffi/parse_c_type.h new file mode 100644 index 0000000..84e4ef8 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/parse_c_type.h @@ -0,0 +1,181 @@ + +/* This part is from file 'cffi/parse_c_type.h'. It is copied at the + beginning of C sources generated by CFFI's ffi.set_source(). */ + +typedef void *_cffi_opcode_t; + +#define _CFFI_OP(opcode, arg) (_cffi_opcode_t)(opcode | (((uintptr_t)(arg)) << 8)) +#define _CFFI_GETOP(cffi_opcode) ((unsigned char)(uintptr_t)cffi_opcode) +#define _CFFI_GETARG(cffi_opcode) (((intptr_t)cffi_opcode) >> 8) + +#define _CFFI_OP_PRIMITIVE 1 +#define _CFFI_OP_POINTER 3 +#define _CFFI_OP_ARRAY 5 +#define _CFFI_OP_OPEN_ARRAY 7 +#define _CFFI_OP_STRUCT_UNION 9 +#define _CFFI_OP_ENUM 11 +#define _CFFI_OP_FUNCTION 13 +#define _CFFI_OP_FUNCTION_END 15 +#define _CFFI_OP_NOOP 17 +#define _CFFI_OP_BITFIELD 19 +#define _CFFI_OP_TYPENAME 21 +#define _CFFI_OP_CPYTHON_BLTN_V 23 // varargs +#define _CFFI_OP_CPYTHON_BLTN_N 25 // noargs +#define _CFFI_OP_CPYTHON_BLTN_O 27 // O (i.e. a single arg) +#define _CFFI_OP_CONSTANT 29 +#define _CFFI_OP_CONSTANT_INT 31 +#define _CFFI_OP_GLOBAL_VAR 33 +#define _CFFI_OP_DLOPEN_FUNC 35 +#define _CFFI_OP_DLOPEN_CONST 37 +#define _CFFI_OP_GLOBAL_VAR_F 39 +#define _CFFI_OP_EXTERN_PYTHON 41 + +#define _CFFI_PRIM_VOID 0 +#define _CFFI_PRIM_BOOL 1 +#define _CFFI_PRIM_CHAR 2 +#define _CFFI_PRIM_SCHAR 3 +#define _CFFI_PRIM_UCHAR 4 +#define _CFFI_PRIM_SHORT 5 +#define _CFFI_PRIM_USHORT 6 +#define _CFFI_PRIM_INT 7 +#define _CFFI_PRIM_UINT 8 +#define _CFFI_PRIM_LONG 9 +#define _CFFI_PRIM_ULONG 10 +#define _CFFI_PRIM_LONGLONG 11 +#define _CFFI_PRIM_ULONGLONG 12 +#define _CFFI_PRIM_FLOAT 13 +#define _CFFI_PRIM_DOUBLE 14 +#define _CFFI_PRIM_LONGDOUBLE 15 + +#define _CFFI_PRIM_WCHAR 16 +#define _CFFI_PRIM_INT8 17 +#define _CFFI_PRIM_UINT8 18 +#define _CFFI_PRIM_INT16 19 +#define _CFFI_PRIM_UINT16 20 +#define _CFFI_PRIM_INT32 21 +#define _CFFI_PRIM_UINT32 22 +#define _CFFI_PRIM_INT64 23 +#define _CFFI_PRIM_UINT64 24 +#define _CFFI_PRIM_INTPTR 25 +#define _CFFI_PRIM_UINTPTR 26 +#define _CFFI_PRIM_PTRDIFF 27 +#define _CFFI_PRIM_SIZE 28 +#define _CFFI_PRIM_SSIZE 29 +#define _CFFI_PRIM_INT_LEAST8 30 +#define _CFFI_PRIM_UINT_LEAST8 31 +#define _CFFI_PRIM_INT_LEAST16 32 +#define _CFFI_PRIM_UINT_LEAST16 33 +#define _CFFI_PRIM_INT_LEAST32 34 +#define _CFFI_PRIM_UINT_LEAST32 35 +#define _CFFI_PRIM_INT_LEAST64 36 +#define _CFFI_PRIM_UINT_LEAST64 37 +#define _CFFI_PRIM_INT_FAST8 38 +#define _CFFI_PRIM_UINT_FAST8 39 +#define _CFFI_PRIM_INT_FAST16 40 +#define _CFFI_PRIM_UINT_FAST16 41 +#define _CFFI_PRIM_INT_FAST32 42 +#define _CFFI_PRIM_UINT_FAST32 43 +#define _CFFI_PRIM_INT_FAST64 44 +#define _CFFI_PRIM_UINT_FAST64 45 +#define _CFFI_PRIM_INTMAX 46 +#define _CFFI_PRIM_UINTMAX 47 +#define _CFFI_PRIM_FLOATCOMPLEX 48 +#define _CFFI_PRIM_DOUBLECOMPLEX 49 +#define _CFFI_PRIM_CHAR16 50 +#define _CFFI_PRIM_CHAR32 51 + +#define _CFFI__NUM_PRIM 52 +#define _CFFI__UNKNOWN_PRIM (-1) +#define _CFFI__UNKNOWN_FLOAT_PRIM (-2) +#define _CFFI__UNKNOWN_LONG_DOUBLE (-3) + +#define _CFFI__IO_FILE_STRUCT (-1) + + +struct _cffi_global_s { + const char *name; + void *address; + _cffi_opcode_t type_op; + void *size_or_direct_fn; // OP_GLOBAL_VAR: size, or 0 if unknown + // OP_CPYTHON_BLTN_*: addr of direct function +}; + +struct _cffi_getconst_s { + unsigned long long value; + const struct _cffi_type_context_s *ctx; + int gindex; +}; + +struct _cffi_struct_union_s { + const char *name; + int type_index; // -> _cffi_types, on a OP_STRUCT_UNION + int flags; // _CFFI_F_* flags below + size_t size; + int alignment; + int first_field_index; // -> _cffi_fields array + int num_fields; +}; +#define _CFFI_F_UNION 0x01 // is a union, not a struct +#define _CFFI_F_CHECK_FIELDS 0x02 // complain if fields are not in the + // "standard layout" or if some are missing +#define _CFFI_F_PACKED 0x04 // for CHECK_FIELDS, assume a packed struct +#define _CFFI_F_EXTERNAL 0x08 // in some other ffi.include() +#define _CFFI_F_OPAQUE 0x10 // opaque + +struct _cffi_field_s { + const char *name; + size_t field_offset; + size_t field_size; + _cffi_opcode_t field_type_op; +}; + +struct _cffi_enum_s { + const char *name; + int type_index; // -> _cffi_types, on a OP_ENUM + int type_prim; // _CFFI_PRIM_xxx + const char *enumerators; // comma-delimited string +}; + +struct _cffi_typename_s { + const char *name; + int type_index; /* if opaque, points to a possibly artificial + OP_STRUCT which is itself opaque */ +}; + +struct _cffi_type_context_s { + _cffi_opcode_t *types; + const struct _cffi_global_s *globals; + const struct _cffi_field_s *fields; + const struct _cffi_struct_union_s *struct_unions; + const struct _cffi_enum_s *enums; + const struct _cffi_typename_s *typenames; + int num_globals; + int num_struct_unions; + int num_enums; + int num_typenames; + const char *const *includes; + int num_types; + int flags; /* future extension */ +}; + +struct _cffi_parse_info_s { + const struct _cffi_type_context_s *ctx; + _cffi_opcode_t *output; + unsigned int output_size; + size_t error_location; + const char *error_message; +}; + +struct _cffi_externpy_s { + const char *name; + size_t size_of_result; + void *reserved1, *reserved2; +}; + +#ifdef _CFFI_INTERNAL +static int parse_c_type(struct _cffi_parse_info_s *info, const char *input); +static int search_in_globals(const struct _cffi_type_context_s *ctx, + const char *search, size_t search_len); +static int search_in_struct_unions(const struct _cffi_type_context_s *ctx, + const char *search, size_t search_len); +#endif diff --git a/dist/ba_data/python-site-packages/cffi/pkgconfig.py b/dist/ba_data/python-site-packages/cffi/pkgconfig.py new file mode 100644 index 0000000..5c93f15 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/pkgconfig.py @@ -0,0 +1,121 @@ +# pkg-config, https://www.freedesktop.org/wiki/Software/pkg-config/ integration for cffi +import sys, os, subprocess + +from .error import PkgConfigError + + +def merge_flags(cfg1, cfg2): + """Merge values from cffi config flags cfg2 to cf1 + + Example: + merge_flags({"libraries": ["one"]}, {"libraries": ["two"]}) + {"libraries": ["one", "two"]} + """ + for key, value in cfg2.items(): + if key not in cfg1: + cfg1[key] = value + else: + if not isinstance(cfg1[key], list): + raise TypeError("cfg1[%r] should be a list of strings" % (key,)) + if not isinstance(value, list): + raise TypeError("cfg2[%r] should be a list of strings" % (key,)) + cfg1[key].extend(value) + return cfg1 + + +def call(libname, flag, encoding=sys.getfilesystemencoding()): + """Calls pkg-config and returns the output if found + """ + a = ["pkg-config", "--print-errors"] + a.append(flag) + a.append(libname) + try: + pc = subprocess.Popen(a, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except EnvironmentError as e: + raise PkgConfigError("cannot run pkg-config: %s" % (str(e).strip(),)) + + bout, berr = pc.communicate() + if pc.returncode != 0: + try: + berr = berr.decode(encoding) + except Exception: + pass + raise PkgConfigError(berr.strip()) + + if sys.version_info >= (3,) and not isinstance(bout, str): # Python 3.x + try: + bout = bout.decode(encoding) + except UnicodeDecodeError: + raise PkgConfigError("pkg-config %s %s returned bytes that cannot " + "be decoded with encoding %r:\n%r" % + (flag, libname, encoding, bout)) + + if os.altsep != '\\' and '\\' in bout: + raise PkgConfigError("pkg-config %s %s returned an unsupported " + "backslash-escaped output:\n%r" % + (flag, libname, bout)) + return bout + + +def flags_from_pkgconfig(libs): + r"""Return compiler line flags for FFI.set_source based on pkg-config output + + Usage + ... + ffibuilder.set_source("_foo", pkgconfig = ["libfoo", "libbar >= 1.8.3"]) + + If pkg-config is installed on build machine, then arguments include_dirs, + library_dirs, libraries, define_macros, extra_compile_args and + extra_link_args are extended with an output of pkg-config for libfoo and + libbar. + + Raises PkgConfigError in case the pkg-config call fails. + """ + + def get_include_dirs(string): + return [x[2:] for x in string.split() if x.startswith("-I")] + + def get_library_dirs(string): + return [x[2:] for x in string.split() if x.startswith("-L")] + + def get_libraries(string): + return [x[2:] for x in string.split() if x.startswith("-l")] + + # convert -Dfoo=bar to list of tuples [("foo", "bar")] expected by distutils + def get_macros(string): + def _macro(x): + x = x[2:] # drop "-D" + if '=' in x: + return tuple(x.split("=", 1)) # "-Dfoo=bar" => ("foo", "bar") + else: + return (x, None) # "-Dfoo" => ("foo", None) + return [_macro(x) for x in string.split() if x.startswith("-D")] + + def get_other_cflags(string): + return [x for x in string.split() if not x.startswith("-I") and + not x.startswith("-D")] + + def get_other_libs(string): + return [x for x in string.split() if not x.startswith("-L") and + not x.startswith("-l")] + + # return kwargs for given libname + def kwargs(libname): + fse = sys.getfilesystemencoding() + all_cflags = call(libname, "--cflags") + all_libs = call(libname, "--libs") + return { + "include_dirs": get_include_dirs(all_cflags), + "library_dirs": get_library_dirs(all_libs), + "libraries": get_libraries(all_libs), + "define_macros": get_macros(all_cflags), + "extra_compile_args": get_other_cflags(all_cflags), + "extra_link_args": get_other_libs(all_libs), + } + + # merge all arguments together + ret = {} + for libname in libs: + lib_flags = kwargs(libname) + merge_flags(ret, lib_flags) + return ret diff --git a/dist/ba_data/python-site-packages/cffi/recompiler.py b/dist/ba_data/python-site-packages/cffi/recompiler.py new file mode 100644 index 0000000..5d9d32d --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/recompiler.py @@ -0,0 +1,1581 @@ +import os, sys, io +from . import ffiplatform, model +from .error import VerificationError +from .cffi_opcode import * + +VERSION_BASE = 0x2601 +VERSION_EMBEDDED = 0x2701 +VERSION_CHAR16CHAR32 = 0x2801 + +USE_LIMITED_API = (sys.platform != 'win32' or sys.version_info < (3, 0) or + sys.version_info >= (3, 5)) + + +class GlobalExpr: + def __init__(self, name, address, type_op, size=0, check_value=0): + self.name = name + self.address = address + self.type_op = type_op + self.size = size + self.check_value = check_value + + def as_c_expr(self): + return ' { "%s", (void *)%s, %s, (void *)%s },' % ( + self.name, self.address, self.type_op.as_c_expr(), self.size) + + def as_python_expr(self): + return "b'%s%s',%d" % (self.type_op.as_python_bytes(), self.name, + self.check_value) + +class FieldExpr: + def __init__(self, name, field_offset, field_size, fbitsize, field_type_op): + self.name = name + self.field_offset = field_offset + self.field_size = field_size + self.fbitsize = fbitsize + self.field_type_op = field_type_op + + def as_c_expr(self): + spaces = " " * len(self.name) + return (' { "%s", %s,\n' % (self.name, self.field_offset) + + ' %s %s,\n' % (spaces, self.field_size) + + ' %s %s },' % (spaces, self.field_type_op.as_c_expr())) + + def as_python_expr(self): + raise NotImplementedError + + def as_field_python_expr(self): + if self.field_type_op.op == OP_NOOP: + size_expr = '' + elif self.field_type_op.op == OP_BITFIELD: + size_expr = format_four_bytes(self.fbitsize) + else: + raise NotImplementedError + return "b'%s%s%s'" % (self.field_type_op.as_python_bytes(), + size_expr, + self.name) + +class StructUnionExpr: + def __init__(self, name, type_index, flags, size, alignment, comment, + first_field_index, c_fields): + self.name = name + self.type_index = type_index + self.flags = flags + self.size = size + self.alignment = alignment + self.comment = comment + self.first_field_index = first_field_index + self.c_fields = c_fields + + def as_c_expr(self): + return (' { "%s", %d, %s,' % (self.name, self.type_index, self.flags) + + '\n %s, %s, ' % (self.size, self.alignment) + + '%d, %d ' % (self.first_field_index, len(self.c_fields)) + + ('/* %s */ ' % self.comment if self.comment else '') + + '},') + + def as_python_expr(self): + flags = eval(self.flags, G_FLAGS) + fields_expr = [c_field.as_field_python_expr() + for c_field in self.c_fields] + return "(b'%s%s%s',%s)" % ( + format_four_bytes(self.type_index), + format_four_bytes(flags), + self.name, + ','.join(fields_expr)) + +class EnumExpr: + def __init__(self, name, type_index, size, signed, allenums): + self.name = name + self.type_index = type_index + self.size = size + self.signed = signed + self.allenums = allenums + + def as_c_expr(self): + return (' { "%s", %d, _cffi_prim_int(%s, %s),\n' + ' "%s" },' % (self.name, self.type_index, + self.size, self.signed, self.allenums)) + + def as_python_expr(self): + prim_index = { + (1, 0): PRIM_UINT8, (1, 1): PRIM_INT8, + (2, 0): PRIM_UINT16, (2, 1): PRIM_INT16, + (4, 0): PRIM_UINT32, (4, 1): PRIM_INT32, + (8, 0): PRIM_UINT64, (8, 1): PRIM_INT64, + }[self.size, self.signed] + return "b'%s%s%s\\x00%s'" % (format_four_bytes(self.type_index), + format_four_bytes(prim_index), + self.name, self.allenums) + +class TypenameExpr: + def __init__(self, name, type_index): + self.name = name + self.type_index = type_index + + def as_c_expr(self): + return ' { "%s", %d },' % (self.name, self.type_index) + + def as_python_expr(self): + return "b'%s%s'" % (format_four_bytes(self.type_index), self.name) + + +# ____________________________________________________________ + + +class Recompiler: + _num_externpy = 0 + + def __init__(self, ffi, module_name, target_is_python=False): + self.ffi = ffi + self.module_name = module_name + self.target_is_python = target_is_python + self._version = VERSION_BASE + + def needs_version(self, ver): + self._version = max(self._version, ver) + + def collect_type_table(self): + self._typesdict = {} + self._generate("collecttype") + # + all_decls = sorted(self._typesdict, key=str) + # + # prepare all FUNCTION bytecode sequences first + self.cffi_types = [] + for tp in all_decls: + if tp.is_raw_function: + assert self._typesdict[tp] is None + self._typesdict[tp] = len(self.cffi_types) + self.cffi_types.append(tp) # placeholder + for tp1 in tp.args: + assert isinstance(tp1, (model.VoidType, + model.BasePrimitiveType, + model.PointerType, + model.StructOrUnionOrEnum, + model.FunctionPtrType)) + if self._typesdict[tp1] is None: + self._typesdict[tp1] = len(self.cffi_types) + self.cffi_types.append(tp1) # placeholder + self.cffi_types.append('END') # placeholder + # + # prepare all OTHER bytecode sequences + for tp in all_decls: + if not tp.is_raw_function and self._typesdict[tp] is None: + self._typesdict[tp] = len(self.cffi_types) + self.cffi_types.append(tp) # placeholder + if tp.is_array_type and tp.length is not None: + self.cffi_types.append('LEN') # placeholder + assert None not in self._typesdict.values() + # + # collect all structs and unions and enums + self._struct_unions = {} + self._enums = {} + for tp in all_decls: + if isinstance(tp, model.StructOrUnion): + self._struct_unions[tp] = None + elif isinstance(tp, model.EnumType): + self._enums[tp] = None + for i, tp in enumerate(sorted(self._struct_unions, + key=lambda tp: tp.name)): + self._struct_unions[tp] = i + for i, tp in enumerate(sorted(self._enums, + key=lambda tp: tp.name)): + self._enums[tp] = i + # + # emit all bytecode sequences now + for tp in all_decls: + method = getattr(self, '_emit_bytecode_' + tp.__class__.__name__) + method(tp, self._typesdict[tp]) + # + # consistency check + for op in self.cffi_types: + assert isinstance(op, CffiOp) + self.cffi_types = tuple(self.cffi_types) # don't change any more + + def _enum_fields(self, tp): + # When producing C, expand all anonymous struct/union fields. + # That's necessary to have C code checking the offsets of the + # individual fields contained in them. When producing Python, + # don't do it and instead write it like it is, with the + # corresponding fields having an empty name. Empty names are + # recognized at runtime when we import the generated Python + # file. + expand_anonymous_struct_union = not self.target_is_python + return tp.enumfields(expand_anonymous_struct_union) + + def _do_collect_type(self, tp): + if not isinstance(tp, model.BaseTypeByIdentity): + if isinstance(tp, tuple): + for x in tp: + self._do_collect_type(x) + return + if tp not in self._typesdict: + self._typesdict[tp] = None + if isinstance(tp, model.FunctionPtrType): + self._do_collect_type(tp.as_raw_function()) + elif isinstance(tp, model.StructOrUnion): + if tp.fldtypes is not None and ( + tp not in self.ffi._parser._included_declarations): + for name1, tp1, _, _ in self._enum_fields(tp): + self._do_collect_type(self._field_type(tp, name1, tp1)) + else: + for _, x in tp._get_items(): + self._do_collect_type(x) + + def _generate(self, step_name): + lst = self.ffi._parser._declarations.items() + for name, (tp, quals) in sorted(lst): + kind, realname = name.split(' ', 1) + try: + method = getattr(self, '_generate_cpy_%s_%s' % (kind, + step_name)) + except AttributeError: + raise VerificationError( + "not implemented in recompile(): %r" % name) + try: + self._current_quals = quals + method(tp, realname) + except Exception as e: + model.attach_exception_info(e, name) + raise + + # ---------- + + ALL_STEPS = ["global", "field", "struct_union", "enum", "typename"] + + def collect_step_tables(self): + # collect the declarations for '_cffi_globals', '_cffi_typenames', etc. + self._lsts = {} + for step_name in self.ALL_STEPS: + self._lsts[step_name] = [] + self._seen_struct_unions = set() + self._generate("ctx") + self._add_missing_struct_unions() + # + for step_name in self.ALL_STEPS: + lst = self._lsts[step_name] + if step_name != "field": + lst.sort(key=lambda entry: entry.name) + self._lsts[step_name] = tuple(lst) # don't change any more + # + # check for a possible internal inconsistency: _cffi_struct_unions + # should have been generated with exactly self._struct_unions + lst = self._lsts["struct_union"] + for tp, i in self._struct_unions.items(): + assert i < len(lst) + assert lst[i].name == tp.name + assert len(lst) == len(self._struct_unions) + # same with enums + lst = self._lsts["enum"] + for tp, i in self._enums.items(): + assert i < len(lst) + assert lst[i].name == tp.name + assert len(lst) == len(self._enums) + + # ---------- + + def _prnt(self, what=''): + self._f.write(what + '\n') + + def write_source_to_f(self, f, preamble): + if self.target_is_python: + assert preamble is None + self.write_py_source_to_f(f) + else: + assert preamble is not None + self.write_c_source_to_f(f, preamble) + + def _rel_readlines(self, filename): + g = open(os.path.join(os.path.dirname(__file__), filename), 'r') + lines = g.readlines() + g.close() + return lines + + def write_c_source_to_f(self, f, preamble): + self._f = f + prnt = self._prnt + if self.ffi._embedding is not None: + prnt('#define _CFFI_USE_EMBEDDING') + if not USE_LIMITED_API: + prnt('#define _CFFI_NO_LIMITED_API') + # + # first the '#include' (actually done by inlining the file's content) + lines = self._rel_readlines('_cffi_include.h') + i = lines.index('#include "parse_c_type.h"\n') + lines[i:i+1] = self._rel_readlines('parse_c_type.h') + prnt(''.join(lines)) + # + # if we have ffi._embedding != None, we give it here as a macro + # and include an extra file + base_module_name = self.module_name.split('.')[-1] + if self.ffi._embedding is not None: + prnt('#define _CFFI_MODULE_NAME "%s"' % (self.module_name,)) + prnt('static const char _CFFI_PYTHON_STARTUP_CODE[] = {') + self._print_string_literal_in_array(self.ffi._embedding) + prnt('0 };') + prnt('#ifdef PYPY_VERSION') + prnt('# define _CFFI_PYTHON_STARTUP_FUNC _cffi_pypyinit_%s' % ( + base_module_name,)) + prnt('#elif PY_MAJOR_VERSION >= 3') + prnt('# define _CFFI_PYTHON_STARTUP_FUNC PyInit_%s' % ( + base_module_name,)) + prnt('#else') + prnt('# define _CFFI_PYTHON_STARTUP_FUNC init%s' % ( + base_module_name,)) + prnt('#endif') + lines = self._rel_readlines('_embedding.h') + i = lines.index('#include "_cffi_errors.h"\n') + lines[i:i+1] = self._rel_readlines('_cffi_errors.h') + prnt(''.join(lines)) + self.needs_version(VERSION_EMBEDDED) + # + # then paste the C source given by the user, verbatim. + prnt('/************************************************************/') + prnt() + prnt(preamble) + prnt() + prnt('/************************************************************/') + prnt() + # + # the declaration of '_cffi_types' + prnt('static void *_cffi_types[] = {') + typeindex2type = dict([(i, tp) for (tp, i) in self._typesdict.items()]) + for i, op in enumerate(self.cffi_types): + comment = '' + if i in typeindex2type: + comment = ' // ' + typeindex2type[i]._get_c_name() + prnt('/* %2d */ %s,%s' % (i, op.as_c_expr(), comment)) + if not self.cffi_types: + prnt(' 0') + prnt('};') + prnt() + # + # call generate_cpy_xxx_decl(), for every xxx found from + # ffi._parser._declarations. This generates all the functions. + self._seen_constants = set() + self._generate("decl") + # + # the declaration of '_cffi_globals' and '_cffi_typenames' + nums = {} + for step_name in self.ALL_STEPS: + lst = self._lsts[step_name] + nums[step_name] = len(lst) + if nums[step_name] > 0: + prnt('static const struct _cffi_%s_s _cffi_%ss[] = {' % ( + step_name, step_name)) + for entry in lst: + prnt(entry.as_c_expr()) + prnt('};') + prnt() + # + # the declaration of '_cffi_includes' + if self.ffi._included_ffis: + prnt('static const char * const _cffi_includes[] = {') + for ffi_to_include in self.ffi._included_ffis: + try: + included_module_name, included_source = ( + ffi_to_include._assigned_source[:2]) + except AttributeError: + raise VerificationError( + "ffi object %r includes %r, but the latter has not " + "been prepared with set_source()" % ( + self.ffi, ffi_to_include,)) + if included_source is None: + raise VerificationError( + "not implemented yet: ffi.include() of a Python-based " + "ffi inside a C-based ffi") + prnt(' "%s",' % (included_module_name,)) + prnt(' NULL') + prnt('};') + prnt() + # + # the declaration of '_cffi_type_context' + prnt('static const struct _cffi_type_context_s _cffi_type_context = {') + prnt(' _cffi_types,') + for step_name in self.ALL_STEPS: + if nums[step_name] > 0: + prnt(' _cffi_%ss,' % step_name) + else: + prnt(' NULL, /* no %ss */' % step_name) + for step_name in self.ALL_STEPS: + if step_name != "field": + prnt(' %d, /* num_%ss */' % (nums[step_name], step_name)) + if self.ffi._included_ffis: + prnt(' _cffi_includes,') + else: + prnt(' NULL, /* no includes */') + prnt(' %d, /* num_types */' % (len(self.cffi_types),)) + flags = 0 + if self._num_externpy > 0 or self.ffi._embedding is not None: + flags |= 1 # set to mean that we use extern "Python" + prnt(' %d, /* flags */' % flags) + prnt('};') + prnt() + # + # the init function + prnt('#ifdef __GNUC__') + prnt('# pragma GCC visibility push(default) /* for -fvisibility= */') + prnt('#endif') + prnt() + prnt('#ifdef PYPY_VERSION') + prnt('PyMODINIT_FUNC') + prnt('_cffi_pypyinit_%s(const void *p[])' % (base_module_name,)) + prnt('{') + if flags & 1: + prnt(' if (((intptr_t)p[0]) >= 0x0A03) {') + prnt(' _cffi_call_python_org = ' + '(void(*)(struct _cffi_externpy_s *, char *))p[1];') + prnt(' }') + prnt(' p[0] = (const void *)0x%x;' % self._version) + prnt(' p[1] = &_cffi_type_context;') + prnt('#if PY_MAJOR_VERSION >= 3') + prnt(' return NULL;') + prnt('#endif') + prnt('}') + # on Windows, distutils insists on putting init_cffi_xyz in + # 'export_symbols', so instead of fighting it, just give up and + # give it one + prnt('# ifdef _MSC_VER') + prnt(' PyMODINIT_FUNC') + prnt('# if PY_MAJOR_VERSION >= 3') + prnt(' PyInit_%s(void) { return NULL; }' % (base_module_name,)) + prnt('# else') + prnt(' init%s(void) { }' % (base_module_name,)) + prnt('# endif') + prnt('# endif') + prnt('#elif PY_MAJOR_VERSION >= 3') + prnt('PyMODINIT_FUNC') + prnt('PyInit_%s(void)' % (base_module_name,)) + prnt('{') + prnt(' return _cffi_init("%s", 0x%x, &_cffi_type_context);' % ( + self.module_name, self._version)) + prnt('}') + prnt('#else') + prnt('PyMODINIT_FUNC') + prnt('init%s(void)' % (base_module_name,)) + prnt('{') + prnt(' _cffi_init("%s", 0x%x, &_cffi_type_context);' % ( + self.module_name, self._version)) + prnt('}') + prnt('#endif') + prnt() + prnt('#ifdef __GNUC__') + prnt('# pragma GCC visibility pop') + prnt('#endif') + self._version = None + + def _to_py(self, x): + if isinstance(x, str): + return "b'%s'" % (x,) + if isinstance(x, (list, tuple)): + rep = [self._to_py(item) for item in x] + if len(rep) == 1: + rep.append('') + return "(%s)" % (','.join(rep),) + return x.as_python_expr() # Py2: unicode unexpected; Py3: bytes unexp. + + def write_py_source_to_f(self, f): + self._f = f + prnt = self._prnt + # + # header + prnt("# auto-generated file") + prnt("import _cffi_backend") + # + # the 'import' of the included ffis + num_includes = len(self.ffi._included_ffis or ()) + for i in range(num_includes): + ffi_to_include = self.ffi._included_ffis[i] + try: + included_module_name, included_source = ( + ffi_to_include._assigned_source[:2]) + except AttributeError: + raise VerificationError( + "ffi object %r includes %r, but the latter has not " + "been prepared with set_source()" % ( + self.ffi, ffi_to_include,)) + if included_source is not None: + raise VerificationError( + "not implemented yet: ffi.include() of a C-based " + "ffi inside a Python-based ffi") + prnt('from %s import ffi as _ffi%d' % (included_module_name, i)) + prnt() + prnt("ffi = _cffi_backend.FFI('%s'," % (self.module_name,)) + prnt(" _version = 0x%x," % (self._version,)) + self._version = None + # + # the '_types' keyword argument + self.cffi_types = tuple(self.cffi_types) # don't change any more + types_lst = [op.as_python_bytes() for op in self.cffi_types] + prnt(' _types = %s,' % (self._to_py(''.join(types_lst)),)) + typeindex2type = dict([(i, tp) for (tp, i) in self._typesdict.items()]) + # + # the keyword arguments from ALL_STEPS + for step_name in self.ALL_STEPS: + lst = self._lsts[step_name] + if len(lst) > 0 and step_name != "field": + prnt(' _%ss = %s,' % (step_name, self._to_py(lst))) + # + # the '_includes' keyword argument + if num_includes > 0: + prnt(' _includes = (%s,),' % ( + ', '.join(['_ffi%d' % i for i in range(num_includes)]),)) + # + # the footer + prnt(')') + + # ---------- + + def _gettypenum(self, type): + # a KeyError here is a bug. please report it! :-) + return self._typesdict[type] + + def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode): + extraarg = '' + if isinstance(tp, model.BasePrimitiveType) and not tp.is_complex_type(): + if tp.is_integer_type() and tp.name != '_Bool': + converter = '_cffi_to_c_int' + extraarg = ', %s' % tp.name + elif isinstance(tp, model.UnknownFloatType): + # don't check with is_float_type(): it may be a 'long + # double' here, and _cffi_to_c_double would loose precision + converter = '(%s)_cffi_to_c_double' % (tp.get_c_name(''),) + else: + cname = tp.get_c_name('') + converter = '(%s)_cffi_to_c_%s' % (cname, + tp.name.replace(' ', '_')) + if cname in ('char16_t', 'char32_t'): + self.needs_version(VERSION_CHAR16CHAR32) + errvalue = '-1' + # + elif isinstance(tp, model.PointerType): + self._convert_funcarg_to_c_ptr_or_array(tp, fromvar, + tovar, errcode) + return + # + elif (isinstance(tp, model.StructOrUnionOrEnum) or + isinstance(tp, model.BasePrimitiveType)): + # a struct (not a struct pointer) as a function argument; + # or, a complex (the same code works) + self._prnt(' if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)' + % (tovar, self._gettypenum(tp), fromvar)) + self._prnt(' %s;' % errcode) + return + # + elif isinstance(tp, model.FunctionPtrType): + converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('') + extraarg = ', _cffi_type(%d)' % self._gettypenum(tp) + errvalue = 'NULL' + # + else: + raise NotImplementedError(tp) + # + self._prnt(' %s = %s(%s%s);' % (tovar, converter, fromvar, extraarg)) + self._prnt(' if (%s == (%s)%s && PyErr_Occurred())' % ( + tovar, tp.get_c_name(''), errvalue)) + self._prnt(' %s;' % errcode) + + def _extra_local_variables(self, tp, localvars, freelines): + if isinstance(tp, model.PointerType): + localvars.add('Py_ssize_t datasize') + localvars.add('struct _cffi_freeme_s *large_args_free = NULL') + freelines.add('if (large_args_free != NULL)' + ' _cffi_free_array_arguments(large_args_free);') + + def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode): + self._prnt(' datasize = _cffi_prepare_pointer_call_argument(') + self._prnt(' _cffi_type(%d), %s, (char **)&%s);' % ( + self._gettypenum(tp), fromvar, tovar)) + self._prnt(' if (datasize != 0) {') + self._prnt(' %s = ((size_t)datasize) <= 640 ? ' + '(%s)alloca((size_t)datasize) : NULL;' % ( + tovar, tp.get_c_name(''))) + self._prnt(' if (_cffi_convert_array_argument(_cffi_type(%d), %s, ' + '(char **)&%s,' % (self._gettypenum(tp), fromvar, tovar)) + self._prnt(' datasize, &large_args_free) < 0)') + self._prnt(' %s;' % errcode) + self._prnt(' }') + + def _convert_expr_from_c(self, tp, var, context): + if isinstance(tp, model.BasePrimitiveType): + if tp.is_integer_type() and tp.name != '_Bool': + return '_cffi_from_c_int(%s, %s)' % (var, tp.name) + elif isinstance(tp, model.UnknownFloatType): + return '_cffi_from_c_double(%s)' % (var,) + elif tp.name != 'long double' and not tp.is_complex_type(): + cname = tp.name.replace(' ', '_') + if cname in ('char16_t', 'char32_t'): + self.needs_version(VERSION_CHAR16CHAR32) + return '_cffi_from_c_%s(%s)' % (cname, var) + else: + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, (model.PointerType, model.FunctionPtrType)): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.ArrayType): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(model.PointerType(tp.item))) + elif isinstance(tp, model.StructOrUnion): + if tp.fldnames is None: + raise TypeError("'%s' is used as %s, but is opaque" % ( + tp._get_c_name(), context)) + return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.EnumType): + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + else: + raise NotImplementedError(tp) + + # ---------- + # typedefs + + def _typedef_type(self, tp, name): + return self._global_type(tp, "(*(%s *)0)" % (name,)) + + def _generate_cpy_typedef_collecttype(self, tp, name): + self._do_collect_type(self._typedef_type(tp, name)) + + def _generate_cpy_typedef_decl(self, tp, name): + pass + + def _typedef_ctx(self, tp, name): + type_index = self._typesdict[tp] + self._lsts["typename"].append(TypenameExpr(name, type_index)) + + def _generate_cpy_typedef_ctx(self, tp, name): + tp = self._typedef_type(tp, name) + self._typedef_ctx(tp, name) + if getattr(tp, "origin", None) == "unknown_type": + self._struct_ctx(tp, tp.name, approxname=None) + elif isinstance(tp, model.NamedPointerType): + self._struct_ctx(tp.totype, tp.totype.name, approxname=tp.name, + named_ptr=tp) + + # ---------- + # function declarations + + def _generate_cpy_function_collecttype(self, tp, name): + self._do_collect_type(tp.as_raw_function()) + if tp.ellipsis and not self.target_is_python: + self._do_collect_type(tp) + + def _generate_cpy_function_decl(self, tp, name): + assert not self.target_is_python + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + # cannot support vararg functions better than this: check for its + # exact type (including the fixed arguments), and build it as a + # constant function pointer (no CPython wrapper) + self._generate_cpy_constant_decl(tp, name) + return + prnt = self._prnt + numargs = len(tp.args) + if numargs == 0: + argname = 'noarg' + elif numargs == 1: + argname = 'arg0' + else: + argname = 'args' + # + # ------------------------------ + # the 'd' version of the function, only for addressof(lib, 'func') + arguments = [] + call_arguments = [] + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + arguments.append(type.get_c_name(' x%d' % i, context)) + call_arguments.append('x%d' % i) + repr_arguments = ', '.join(arguments) + repr_arguments = repr_arguments or 'void' + if tp.abi: + abi = tp.abi + ' ' + else: + abi = '' + name_and_arguments = '%s_cffi_d_%s(%s)' % (abi, name, repr_arguments) + prnt('static %s' % (tp.result.get_c_name(name_and_arguments),)) + prnt('{') + call_arguments = ', '.join(call_arguments) + result_code = 'return ' + if isinstance(tp.result, model.VoidType): + result_code = '' + prnt(' %s%s(%s);' % (result_code, name, call_arguments)) + prnt('}') + # + prnt('#ifndef PYPY_VERSION') # ------------------------------ + # + prnt('static PyObject *') + prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname)) + prnt('{') + # + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + arg = type.get_c_name(' x%d' % i, context) + prnt(' %s;' % arg) + # + localvars = set() + freelines = set() + for type in tp.args: + self._extra_local_variables(type, localvars, freelines) + for decl in sorted(localvars): + prnt(' %s;' % (decl,)) + # + if not isinstance(tp.result, model.VoidType): + result_code = 'result = ' + context = 'result of %s' % name + result_decl = ' %s;' % tp.result.get_c_name(' result', context) + prnt(result_decl) + prnt(' PyObject *pyresult;') + else: + result_decl = None + result_code = '' + # + if len(tp.args) > 1: + rng = range(len(tp.args)) + for i in rng: + prnt(' PyObject *arg%d;' % i) + prnt() + prnt(' if (!PyArg_UnpackTuple(args, "%s", %d, %d, %s))' % ( + name, len(rng), len(rng), + ', '.join(['&arg%d' % i for i in rng]))) + prnt(' return NULL;') + prnt() + # + for i, type in enumerate(tp.args): + self._convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i, + 'return NULL') + prnt() + # + prnt(' Py_BEGIN_ALLOW_THREADS') + prnt(' _cffi_restore_errno();') + call_arguments = ['x%d' % i for i in range(len(tp.args))] + call_arguments = ', '.join(call_arguments) + prnt(' { %s%s(%s); }' % (result_code, name, call_arguments)) + prnt(' _cffi_save_errno();') + prnt(' Py_END_ALLOW_THREADS') + prnt() + # + prnt(' (void)self; /* unused */') + if numargs == 0: + prnt(' (void)noarg; /* unused */') + if result_code: + prnt(' pyresult = %s;' % + self._convert_expr_from_c(tp.result, 'result', 'result type')) + for freeline in freelines: + prnt(' ' + freeline) + prnt(' return pyresult;') + else: + for freeline in freelines: + prnt(' ' + freeline) + prnt(' Py_INCREF(Py_None);') + prnt(' return Py_None;') + prnt('}') + # + prnt('#else') # ------------------------------ + # + # the PyPy version: need to replace struct/union arguments with + # pointers, and if the result is a struct/union, insert a first + # arg that is a pointer to the result. We also do that for + # complex args and return type. + def need_indirection(type): + return (isinstance(type, model.StructOrUnion) or + (isinstance(type, model.PrimitiveType) and + type.is_complex_type())) + difference = False + arguments = [] + call_arguments = [] + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + indirection = '' + if need_indirection(type): + indirection = '*' + difference = True + arg = type.get_c_name(' %sx%d' % (indirection, i), context) + arguments.append(arg) + call_arguments.append('%sx%d' % (indirection, i)) + tp_result = tp.result + if need_indirection(tp_result): + context = 'result of %s' % name + arg = tp_result.get_c_name(' *result', context) + arguments.insert(0, arg) + tp_result = model.void_type + result_decl = None + result_code = '*result = ' + difference = True + if difference: + repr_arguments = ', '.join(arguments) + repr_arguments = repr_arguments or 'void' + name_and_arguments = '%s_cffi_f_%s(%s)' % (abi, name, + repr_arguments) + prnt('static %s' % (tp_result.get_c_name(name_and_arguments),)) + prnt('{') + if result_decl: + prnt(result_decl) + call_arguments = ', '.join(call_arguments) + prnt(' { %s%s(%s); }' % (result_code, name, call_arguments)) + if result_decl: + prnt(' return result;') + prnt('}') + else: + prnt('# define _cffi_f_%s _cffi_d_%s' % (name, name)) + # + prnt('#endif') # ------------------------------ + prnt() + + def _generate_cpy_function_ctx(self, tp, name): + if tp.ellipsis and not self.target_is_python: + self._generate_cpy_constant_ctx(tp, name) + return + type_index = self._typesdict[tp.as_raw_function()] + numargs = len(tp.args) + if self.target_is_python: + meth_kind = OP_DLOPEN_FUNC + elif numargs == 0: + meth_kind = OP_CPYTHON_BLTN_N # 'METH_NOARGS' + elif numargs == 1: + meth_kind = OP_CPYTHON_BLTN_O # 'METH_O' + else: + meth_kind = OP_CPYTHON_BLTN_V # 'METH_VARARGS' + self._lsts["global"].append( + GlobalExpr(name, '_cffi_f_%s' % name, + CffiOp(meth_kind, type_index), + size='_cffi_d_%s' % name)) + + # ---------- + # named structs or unions + + def _field_type(self, tp_struct, field_name, tp_field): + if isinstance(tp_field, model.ArrayType): + actual_length = tp_field.length + if actual_length == '...': + ptr_struct_name = tp_struct.get_c_name('*') + actual_length = '_cffi_array_len(((%s)0)->%s)' % ( + ptr_struct_name, field_name) + tp_item = self._field_type(tp_struct, '%s[0]' % field_name, + tp_field.item) + tp_field = model.ArrayType(tp_item, actual_length) + return tp_field + + def _struct_collecttype(self, tp): + self._do_collect_type(tp) + if self.target_is_python: + # also requires nested anon struct/unions in ABI mode, recursively + for fldtype in tp.anonymous_struct_fields(): + self._struct_collecttype(fldtype) + + def _struct_decl(self, tp, cname, approxname): + if tp.fldtypes is None: + return + prnt = self._prnt + checkfuncname = '_cffi_checkfld_%s' % (approxname,) + prnt('_CFFI_UNUSED_FN') + prnt('static void %s(%s *p)' % (checkfuncname, cname)) + prnt('{') + prnt(' /* only to generate compile-time warnings or errors */') + prnt(' (void)p;') + for fname, ftype, fbitsize, fqual in self._enum_fields(tp): + try: + if ftype.is_integer_type() or fbitsize >= 0: + # accept all integers, but complain on float or double + if fname != '': + prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " + "an integer */" % (fname, cname, fname)) + continue + # only accept exactly the type declared, except that '[]' + # is interpreted as a '*' and so will match any array length. + # (It would also match '*', but that's harder to detect...) + while (isinstance(ftype, model.ArrayType) + and (ftype.length is None or ftype.length == '...')): + ftype = ftype.item + fname = fname + '[0]' + prnt(' { %s = &p->%s; (void)tmp; }' % ( + ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), + fname)) + except VerificationError as e: + prnt(' /* %s */' % str(e)) # cannot verify it, ignore + prnt('}') + prnt('struct _cffi_align_%s { char x; %s y; };' % (approxname, cname)) + prnt() + + def _struct_ctx(self, tp, cname, approxname, named_ptr=None): + type_index = self._typesdict[tp] + reason_for_not_expanding = None + flags = [] + if isinstance(tp, model.UnionType): + flags.append("_CFFI_F_UNION") + if tp.fldtypes is None: + flags.append("_CFFI_F_OPAQUE") + reason_for_not_expanding = "opaque" + if (tp not in self.ffi._parser._included_declarations and + (named_ptr is None or + named_ptr not in self.ffi._parser._included_declarations)): + if tp.fldtypes is None: + pass # opaque + elif tp.partial or any(tp.anonymous_struct_fields()): + pass # field layout obtained silently from the C compiler + else: + flags.append("_CFFI_F_CHECK_FIELDS") + if tp.packed: + if tp.packed > 1: + raise NotImplementedError( + "%r is declared with 'pack=%r'; only 0 or 1 are " + "supported in API mode (try to use \"...;\", which " + "does not require a 'pack' declaration)" % + (tp, tp.packed)) + flags.append("_CFFI_F_PACKED") + else: + flags.append("_CFFI_F_EXTERNAL") + reason_for_not_expanding = "external" + flags = '|'.join(flags) or '0' + c_fields = [] + if reason_for_not_expanding is None: + enumfields = list(self._enum_fields(tp)) + for fldname, fldtype, fbitsize, fqual in enumfields: + fldtype = self._field_type(tp, fldname, fldtype) + self._check_not_opaque(fldtype, + "field '%s.%s'" % (tp.name, fldname)) + # cname is None for _add_missing_struct_unions() only + op = OP_NOOP + if fbitsize >= 0: + op = OP_BITFIELD + size = '%d /* bits */' % fbitsize + elif cname is None or ( + isinstance(fldtype, model.ArrayType) and + fldtype.length is None): + size = '(size_t)-1' + else: + size = 'sizeof(((%s)0)->%s)' % ( + tp.get_c_name('*') if named_ptr is None + else named_ptr.name, + fldname) + if cname is None or fbitsize >= 0: + offset = '(size_t)-1' + elif named_ptr is not None: + offset = '((char *)&((%s)0)->%s) - (char *)0' % ( + named_ptr.name, fldname) + else: + offset = 'offsetof(%s, %s)' % (tp.get_c_name(''), fldname) + c_fields.append( + FieldExpr(fldname, offset, size, fbitsize, + CffiOp(op, self._typesdict[fldtype]))) + first_field_index = len(self._lsts["field"]) + self._lsts["field"].extend(c_fields) + # + if cname is None: # unknown name, for _add_missing_struct_unions + size = '(size_t)-2' + align = -2 + comment = "unnamed" + else: + if named_ptr is not None: + size = 'sizeof(*(%s)0)' % (named_ptr.name,) + align = '-1 /* unknown alignment */' + else: + size = 'sizeof(%s)' % (cname,) + align = 'offsetof(struct _cffi_align_%s, y)' % (approxname,) + comment = None + else: + size = '(size_t)-1' + align = -1 + first_field_index = -1 + comment = reason_for_not_expanding + self._lsts["struct_union"].append( + StructUnionExpr(tp.name, type_index, flags, size, align, comment, + first_field_index, c_fields)) + self._seen_struct_unions.add(tp) + + def _check_not_opaque(self, tp, location): + while isinstance(tp, model.ArrayType): + tp = tp.item + if isinstance(tp, model.StructOrUnion) and tp.fldtypes is None: + raise TypeError( + "%s is of an opaque type (not declared in cdef())" % location) + + def _add_missing_struct_unions(self): + # not very nice, but some struct declarations might be missing + # because they don't have any known C name. Check that they are + # not partial (we can't complete or verify them!) and emit them + # anonymously. + lst = list(self._struct_unions.items()) + lst.sort(key=lambda tp_order: tp_order[1]) + for tp, order in lst: + if tp not in self._seen_struct_unions: + if tp.partial: + raise NotImplementedError("internal inconsistency: %r is " + "partial but was not seen at " + "this point" % (tp,)) + if tp.name.startswith('$') and tp.name[1:].isdigit(): + approxname = tp.name[1:] + elif tp.name == '_IO_FILE' and tp.forcename == 'FILE': + approxname = 'FILE' + self._typedef_ctx(tp, 'FILE') + else: + raise NotImplementedError("internal inconsistency: %r" % + (tp,)) + self._struct_ctx(tp, None, approxname) + + def _generate_cpy_struct_collecttype(self, tp, name): + self._struct_collecttype(tp) + _generate_cpy_union_collecttype = _generate_cpy_struct_collecttype + + def _struct_names(self, tp): + cname = tp.get_c_name('') + if ' ' in cname: + return cname, cname.replace(' ', '_') + else: + return cname, '_' + cname + + def _generate_cpy_struct_decl(self, tp, name): + self._struct_decl(tp, *self._struct_names(tp)) + _generate_cpy_union_decl = _generate_cpy_struct_decl + + def _generate_cpy_struct_ctx(self, tp, name): + self._struct_ctx(tp, *self._struct_names(tp)) + _generate_cpy_union_ctx = _generate_cpy_struct_ctx + + # ---------- + # 'anonymous' declarations. These are produced for anonymous structs + # or unions; the 'name' is obtained by a typedef. + + def _generate_cpy_anonymous_collecttype(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_cpy_enum_collecttype(tp, name) + else: + self._struct_collecttype(tp) + + def _generate_cpy_anonymous_decl(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_cpy_enum_decl(tp) + else: + self._struct_decl(tp, name, 'typedef_' + name) + + def _generate_cpy_anonymous_ctx(self, tp, name): + if isinstance(tp, model.EnumType): + self._enum_ctx(tp, name) + else: + self._struct_ctx(tp, name, 'typedef_' + name) + + # ---------- + # constants, declared with "static const ..." + + def _generate_cpy_const(self, is_int, name, tp=None, category='const', + check_value=None): + if (category, name) in self._seen_constants: + raise VerificationError( + "duplicate declaration of %s '%s'" % (category, name)) + self._seen_constants.add((category, name)) + # + prnt = self._prnt + funcname = '_cffi_%s_%s' % (category, name) + if is_int: + prnt('static int %s(unsigned long long *o)' % funcname) + prnt('{') + prnt(' int n = (%s) <= 0;' % (name,)) + prnt(' *o = (unsigned long long)((%s) | 0);' + ' /* check that %s is an integer */' % (name, name)) + if check_value is not None: + if check_value > 0: + check_value = '%dU' % (check_value,) + prnt(' if (!_cffi_check_int(*o, n, %s))' % (check_value,)) + prnt(' n |= 2;') + prnt(' return n;') + prnt('}') + else: + assert check_value is None + prnt('static void %s(char *o)' % funcname) + prnt('{') + prnt(' *(%s)o = %s;' % (tp.get_c_name('*'), name)) + prnt('}') + prnt() + + def _generate_cpy_constant_collecttype(self, tp, name): + is_int = tp.is_integer_type() + if not is_int or self.target_is_python: + self._do_collect_type(tp) + + def _generate_cpy_constant_decl(self, tp, name): + is_int = tp.is_integer_type() + self._generate_cpy_const(is_int, name, tp) + + def _generate_cpy_constant_ctx(self, tp, name): + if not self.target_is_python and tp.is_integer_type(): + type_op = CffiOp(OP_CONSTANT_INT, -1) + else: + if self.target_is_python: + const_kind = OP_DLOPEN_CONST + else: + const_kind = OP_CONSTANT + type_index = self._typesdict[tp] + type_op = CffiOp(const_kind, type_index) + self._lsts["global"].append( + GlobalExpr(name, '_cffi_const_%s' % name, type_op)) + + # ---------- + # enums + + def _generate_cpy_enum_collecttype(self, tp, name): + self._do_collect_type(tp) + + def _generate_cpy_enum_decl(self, tp, name=None): + for enumerator in tp.enumerators: + self._generate_cpy_const(True, enumerator) + + def _enum_ctx(self, tp, cname): + type_index = self._typesdict[tp] + type_op = CffiOp(OP_ENUM, -1) + if self.target_is_python: + tp.check_not_partial() + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + self._lsts["global"].append( + GlobalExpr(enumerator, '_cffi_const_%s' % enumerator, type_op, + check_value=enumvalue)) + # + if cname is not None and '$' not in cname and not self.target_is_python: + size = "sizeof(%s)" % cname + signed = "((%s)-1) <= 0" % cname + else: + basetp = tp.build_baseinttype(self.ffi, []) + size = self.ffi.sizeof(basetp) + signed = int(int(self.ffi.cast(basetp, -1)) < 0) + allenums = ",".join(tp.enumerators) + self._lsts["enum"].append( + EnumExpr(tp.name, type_index, size, signed, allenums)) + + def _generate_cpy_enum_ctx(self, tp, name): + self._enum_ctx(tp, tp._get_c_name()) + + # ---------- + # macros: for now only for integers + + def _generate_cpy_macro_collecttype(self, tp, name): + pass + + def _generate_cpy_macro_decl(self, tp, name): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + self._generate_cpy_const(True, name, check_value=check_value) + + def _generate_cpy_macro_ctx(self, tp, name): + if tp == '...': + if self.target_is_python: + raise VerificationError( + "cannot use the syntax '...' in '#define %s ...' when " + "using the ABI mode" % (name,)) + check_value = None + else: + check_value = tp # an integer + type_op = CffiOp(OP_CONSTANT_INT, -1) + self._lsts["global"].append( + GlobalExpr(name, '_cffi_const_%s' % name, type_op, + check_value=check_value)) + + # ---------- + # global variables + + def _global_type(self, tp, global_name): + if isinstance(tp, model.ArrayType): + actual_length = tp.length + if actual_length == '...': + actual_length = '_cffi_array_len(%s)' % (global_name,) + tp_item = self._global_type(tp.item, '%s[0]' % global_name) + tp = model.ArrayType(tp_item, actual_length) + return tp + + def _generate_cpy_variable_collecttype(self, tp, name): + self._do_collect_type(self._global_type(tp, name)) + + def _generate_cpy_variable_decl(self, tp, name): + prnt = self._prnt + tp = self._global_type(tp, name) + if isinstance(tp, model.ArrayType) and tp.length is None: + tp = tp.item + ampersand = '' + else: + ampersand = '&' + # This code assumes that casts from "tp *" to "void *" is a + # no-op, i.e. a function that returns a "tp *" can be called + # as if it returned a "void *". This should be generally true + # on any modern machine. The only exception to that rule (on + # uncommon architectures, and as far as I can tell) might be + # if 'tp' were a function type, but that is not possible here. + # (If 'tp' is a function _pointer_ type, then casts from "fn_t + # **" to "void *" are again no-ops, as far as I can tell.) + decl = '*_cffi_var_%s(void)' % (name,) + prnt('static ' + tp.get_c_name(decl, quals=self._current_quals)) + prnt('{') + prnt(' return %s(%s);' % (ampersand, name)) + prnt('}') + prnt() + + def _generate_cpy_variable_ctx(self, tp, name): + tp = self._global_type(tp, name) + type_index = self._typesdict[tp] + if self.target_is_python: + op = OP_GLOBAL_VAR + else: + op = OP_GLOBAL_VAR_F + self._lsts["global"].append( + GlobalExpr(name, '_cffi_var_%s' % name, CffiOp(op, type_index))) + + # ---------- + # extern "Python" + + def _generate_cpy_extern_python_collecttype(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + self._do_collect_type(tp) + _generate_cpy_dllexport_python_collecttype = \ + _generate_cpy_extern_python_plus_c_collecttype = \ + _generate_cpy_extern_python_collecttype + + def _extern_python_decl(self, tp, name, tag_and_space): + prnt = self._prnt + if isinstance(tp.result, model.VoidType): + size_of_result = '0' + else: + context = 'result of %s' % name + size_of_result = '(int)sizeof(%s)' % ( + tp.result.get_c_name('', context),) + prnt('static struct _cffi_externpy_s _cffi_externpy__%s =' % name) + prnt(' { "%s.%s", %s, 0, 0 };' % ( + self.module_name, name, size_of_result)) + prnt() + # + arguments = [] + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + arg = type.get_c_name(' a%d' % i, context) + arguments.append(arg) + # + repr_arguments = ', '.join(arguments) + repr_arguments = repr_arguments or 'void' + name_and_arguments = '%s(%s)' % (name, repr_arguments) + if tp.abi == "__stdcall": + name_and_arguments = '_cffi_stdcall ' + name_and_arguments + # + def may_need_128_bits(tp): + return (isinstance(tp, model.PrimitiveType) and + tp.name == 'long double') + # + size_of_a = max(len(tp.args)*8, 8) + if may_need_128_bits(tp.result): + size_of_a = max(size_of_a, 16) + if isinstance(tp.result, model.StructOrUnion): + size_of_a = 'sizeof(%s) > %d ? sizeof(%s) : %d' % ( + tp.result.get_c_name(''), size_of_a, + tp.result.get_c_name(''), size_of_a) + prnt('%s%s' % (tag_and_space, tp.result.get_c_name(name_and_arguments))) + prnt('{') + prnt(' char a[%s];' % size_of_a) + prnt(' char *p = a;') + for i, type in enumerate(tp.args): + arg = 'a%d' % i + if (isinstance(type, model.StructOrUnion) or + may_need_128_bits(type)): + arg = '&' + arg + type = model.PointerType(type) + prnt(' *(%s)(p + %d) = %s;' % (type.get_c_name('*'), i*8, arg)) + prnt(' _cffi_call_python(&_cffi_externpy__%s, p);' % name) + if not isinstance(tp.result, model.VoidType): + prnt(' return *(%s)p;' % (tp.result.get_c_name('*'),)) + prnt('}') + prnt() + self._num_externpy += 1 + + def _generate_cpy_extern_python_decl(self, tp, name): + self._extern_python_decl(tp, name, 'static ') + + def _generate_cpy_dllexport_python_decl(self, tp, name): + self._extern_python_decl(tp, name, 'CFFI_DLLEXPORT ') + + def _generate_cpy_extern_python_plus_c_decl(self, tp, name): + self._extern_python_decl(tp, name, '') + + def _generate_cpy_extern_python_ctx(self, tp, name): + if self.target_is_python: + raise VerificationError( + "cannot use 'extern \"Python\"' in the ABI mode") + if tp.ellipsis: + raise NotImplementedError("a vararg function is extern \"Python\"") + type_index = self._typesdict[tp] + type_op = CffiOp(OP_EXTERN_PYTHON, type_index) + self._lsts["global"].append( + GlobalExpr(name, '&_cffi_externpy__%s' % name, type_op, name)) + + _generate_cpy_dllexport_python_ctx = \ + _generate_cpy_extern_python_plus_c_ctx = \ + _generate_cpy_extern_python_ctx + + def _print_string_literal_in_array(self, s): + prnt = self._prnt + prnt('// # NB. this is not a string because of a size limit in MSVC') + if not isinstance(s, bytes): # unicode + s = s.encode('utf-8') # -> bytes + else: + s.decode('utf-8') # got bytes, check for valid utf-8 + try: + s.decode('ascii') + except UnicodeDecodeError: + s = b'# -*- encoding: utf8 -*-\n' + s + for line in s.splitlines(True): + comment = line + if type('//') is bytes: # python2 + line = map(ord, line) # make a list of integers + else: # python3 + # type(line) is bytes, which enumerates like a list of integers + comment = ascii(comment)[1:-1] + prnt(('// ' + comment).rstrip()) + printed_line = '' + for c in line: + if len(printed_line) >= 76: + prnt(printed_line) + printed_line = '' + printed_line += '%d,' % (c,) + prnt(printed_line) + + # ---------- + # emitting the opcodes for individual types + + def _emit_bytecode_VoidType(self, tp, index): + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, PRIM_VOID) + + def _emit_bytecode_PrimitiveType(self, tp, index): + prim_index = PRIMITIVE_TO_INDEX[tp.name] + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, prim_index) + + def _emit_bytecode_UnknownIntegerType(self, tp, index): + s = ('_cffi_prim_int(sizeof(%s), (\n' + ' ((%s)-1) | 0 /* check that %s is an integer type */\n' + ' ) <= 0)' % (tp.name, tp.name, tp.name)) + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s) + + def _emit_bytecode_UnknownFloatType(self, tp, index): + s = ('_cffi_prim_float(sizeof(%s) *\n' + ' (((%s)1) / 2) * 2 /* integer => 0, float => 1 */\n' + ' )' % (tp.name, tp.name)) + self.cffi_types[index] = CffiOp(OP_PRIMITIVE, s) + + def _emit_bytecode_RawFunctionType(self, tp, index): + self.cffi_types[index] = CffiOp(OP_FUNCTION, self._typesdict[tp.result]) + index += 1 + for tp1 in tp.args: + realindex = self._typesdict[tp1] + if index != realindex: + if isinstance(tp1, model.PrimitiveType): + self._emit_bytecode_PrimitiveType(tp1, index) + else: + self.cffi_types[index] = CffiOp(OP_NOOP, realindex) + index += 1 + flags = int(tp.ellipsis) + if tp.abi is not None: + if tp.abi == '__stdcall': + flags |= 2 + else: + raise NotImplementedError("abi=%r" % (tp.abi,)) + self.cffi_types[index] = CffiOp(OP_FUNCTION_END, flags) + + def _emit_bytecode_PointerType(self, tp, index): + self.cffi_types[index] = CffiOp(OP_POINTER, self._typesdict[tp.totype]) + + _emit_bytecode_ConstPointerType = _emit_bytecode_PointerType + _emit_bytecode_NamedPointerType = _emit_bytecode_PointerType + + def _emit_bytecode_FunctionPtrType(self, tp, index): + raw = tp.as_raw_function() + self.cffi_types[index] = CffiOp(OP_POINTER, self._typesdict[raw]) + + def _emit_bytecode_ArrayType(self, tp, index): + item_index = self._typesdict[tp.item] + if tp.length is None: + self.cffi_types[index] = CffiOp(OP_OPEN_ARRAY, item_index) + elif tp.length == '...': + raise VerificationError( + "type %s badly placed: the '...' array length can only be " + "used on global arrays or on fields of structures" % ( + str(tp).replace('/*...*/', '...'),)) + else: + assert self.cffi_types[index + 1] == 'LEN' + self.cffi_types[index] = CffiOp(OP_ARRAY, item_index) + self.cffi_types[index + 1] = CffiOp(None, str(tp.length)) + + def _emit_bytecode_StructType(self, tp, index): + struct_index = self._struct_unions[tp] + self.cffi_types[index] = CffiOp(OP_STRUCT_UNION, struct_index) + _emit_bytecode_UnionType = _emit_bytecode_StructType + + def _emit_bytecode_EnumType(self, tp, index): + enum_index = self._enums[tp] + self.cffi_types[index] = CffiOp(OP_ENUM, enum_index) + + +if sys.version_info >= (3,): + NativeIO = io.StringIO +else: + class NativeIO(io.BytesIO): + def write(self, s): + if isinstance(s, unicode): + s = s.encode('ascii') + super(NativeIO, self).write(s) + +def _make_c_or_py_source(ffi, module_name, preamble, target_file, verbose): + if verbose: + print("generating %s" % (target_file,)) + recompiler = Recompiler(ffi, module_name, + target_is_python=(preamble is None)) + recompiler.collect_type_table() + recompiler.collect_step_tables() + f = NativeIO() + recompiler.write_source_to_f(f, preamble) + output = f.getvalue() + try: + with open(target_file, 'r') as f1: + if f1.read(len(output) + 1) != output: + raise IOError + if verbose: + print("(already up-to-date)") + return False # already up-to-date + except IOError: + tmp_file = '%s.~%d' % (target_file, os.getpid()) + with open(tmp_file, 'w') as f1: + f1.write(output) + try: + os.rename(tmp_file, target_file) + except OSError: + os.unlink(target_file) + os.rename(tmp_file, target_file) + return True + +def make_c_source(ffi, module_name, preamble, target_c_file, verbose=False): + assert preamble is not None + return _make_c_or_py_source(ffi, module_name, preamble, target_c_file, + verbose) + +def make_py_source(ffi, module_name, target_py_file, verbose=False): + return _make_c_or_py_source(ffi, module_name, None, target_py_file, + verbose) + +def _modname_to_file(outputdir, modname, extension): + parts = modname.split('.') + try: + os.makedirs(os.path.join(outputdir, *parts[:-1])) + except OSError: + pass + parts[-1] += extension + return os.path.join(outputdir, *parts), parts + + +# Aaargh. Distutils is not tested at all for the purpose of compiling +# DLLs that are not extension modules. Here are some hacks to work +# around that, in the _patch_for_*() functions... + +def _patch_meth(patchlist, cls, name, new_meth): + old = getattr(cls, name) + patchlist.append((cls, name, old)) + setattr(cls, name, new_meth) + return old + +def _unpatch_meths(patchlist): + for cls, name, old_meth in reversed(patchlist): + setattr(cls, name, old_meth) + +def _patch_for_embedding(patchlist): + if sys.platform == 'win32': + # we must not remove the manifest when building for embedding! + from distutils.msvc9compiler import MSVCCompiler + _patch_meth(patchlist, MSVCCompiler, '_remove_visual_c_ref', + lambda self, manifest_file: manifest_file) + + if sys.platform == 'darwin': + # we must not make a '-bundle', but a '-dynamiclib' instead + from distutils.ccompiler import CCompiler + def my_link_shared_object(self, *args, **kwds): + if '-bundle' in self.linker_so: + self.linker_so = list(self.linker_so) + i = self.linker_so.index('-bundle') + self.linker_so[i] = '-dynamiclib' + return old_link_shared_object(self, *args, **kwds) + old_link_shared_object = _patch_meth(patchlist, CCompiler, + 'link_shared_object', + my_link_shared_object) + +def _patch_for_target(patchlist, target): + from distutils.command.build_ext import build_ext + # if 'target' is different from '*', we need to patch some internal + # method to just return this 'target' value, instead of having it + # built from module_name + if target.endswith('.*'): + target = target[:-2] + if sys.platform == 'win32': + target += '.dll' + elif sys.platform == 'darwin': + target += '.dylib' + else: + target += '.so' + _patch_meth(patchlist, build_ext, 'get_ext_filename', + lambda self, ext_name: target) + + +def recompile(ffi, module_name, preamble, tmpdir='.', call_c_compiler=True, + c_file=None, source_extension='.c', extradir=None, + compiler_verbose=1, target=None, debug=None, **kwds): + if not isinstance(module_name, str): + module_name = module_name.encode('ascii') + if ffi._windows_unicode: + ffi._apply_windows_unicode(kwds) + if preamble is not None: + embedding = (ffi._embedding is not None) + if embedding: + ffi._apply_embedding_fix(kwds) + if c_file is None: + c_file, parts = _modname_to_file(tmpdir, module_name, + source_extension) + if extradir: + parts = [extradir] + parts + ext_c_file = os.path.join(*parts) + else: + ext_c_file = c_file + # + if target is None: + if embedding: + target = '%s.*' % module_name + else: + target = '*' + # + ext = ffiplatform.get_extension(ext_c_file, module_name, **kwds) + updated = make_c_source(ffi, module_name, preamble, c_file, + verbose=compiler_verbose) + if call_c_compiler: + patchlist = [] + cwd = os.getcwd() + try: + if embedding: + _patch_for_embedding(patchlist) + if target != '*': + _patch_for_target(patchlist, target) + if compiler_verbose: + if tmpdir == '.': + msg = 'the current directory is' + else: + msg = 'setting the current directory to' + print('%s %r' % (msg, os.path.abspath(tmpdir))) + os.chdir(tmpdir) + outputfilename = ffiplatform.compile('.', ext, + compiler_verbose, debug) + finally: + os.chdir(cwd) + _unpatch_meths(patchlist) + return outputfilename + else: + return ext, updated + else: + if c_file is None: + c_file, _ = _modname_to_file(tmpdir, module_name, '.py') + updated = make_py_source(ffi, module_name, c_file, + verbose=compiler_verbose) + if call_c_compiler: + return c_file + else: + return None, updated + diff --git a/dist/ba_data/python-site-packages/cffi/setuptools_ext.py b/dist/ba_data/python-site-packages/cffi/setuptools_ext.py new file mode 100644 index 0000000..8fe3614 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/setuptools_ext.py @@ -0,0 +1,219 @@ +import os +import sys + +try: + basestring +except NameError: + # Python 3.x + basestring = str + +def error(msg): + from distutils.errors import DistutilsSetupError + raise DistutilsSetupError(msg) + + +def execfile(filename, glob): + # We use execfile() (here rewritten for Python 3) instead of + # __import__() to load the build script. The problem with + # a normal import is that in some packages, the intermediate + # __init__.py files may already try to import the file that + # we are generating. + with open(filename) as f: + src = f.read() + src += '\n' # Python 2.6 compatibility + code = compile(src, filename, 'exec') + exec(code, glob, glob) + + +def add_cffi_module(dist, mod_spec): + from cffi.api import FFI + + if not isinstance(mod_spec, basestring): + error("argument to 'cffi_modules=...' must be a str or a list of str," + " not %r" % (type(mod_spec).__name__,)) + mod_spec = str(mod_spec) + try: + build_file_name, ffi_var_name = mod_spec.split(':') + except ValueError: + error("%r must be of the form 'path/build.py:ffi_variable'" % + (mod_spec,)) + if not os.path.exists(build_file_name): + ext = '' + rewritten = build_file_name.replace('.', '/') + '.py' + if os.path.exists(rewritten): + ext = ' (rewrite cffi_modules to [%r])' % ( + rewritten + ':' + ffi_var_name,) + error("%r does not name an existing file%s" % (build_file_name, ext)) + + mod_vars = {'__name__': '__cffi__', '__file__': build_file_name} + execfile(build_file_name, mod_vars) + + try: + ffi = mod_vars[ffi_var_name] + except KeyError: + error("%r: object %r not found in module" % (mod_spec, + ffi_var_name)) + if not isinstance(ffi, FFI): + ffi = ffi() # maybe it's a function instead of directly an ffi + if not isinstance(ffi, FFI): + error("%r is not an FFI instance (got %r)" % (mod_spec, + type(ffi).__name__)) + if not hasattr(ffi, '_assigned_source'): + error("%r: the set_source() method was not called" % (mod_spec,)) + module_name, source, source_extension, kwds = ffi._assigned_source + if ffi._windows_unicode: + kwds = kwds.copy() + ffi._apply_windows_unicode(kwds) + + if source is None: + _add_py_module(dist, ffi, module_name) + else: + _add_c_module(dist, ffi, module_name, source, source_extension, kwds) + +def _set_py_limited_api(Extension, kwds): + """ + Add py_limited_api to kwds if setuptools >= 26 is in use. + Do not alter the setting if it already exists. + Setuptools takes care of ignoring the flag on Python 2 and PyPy. + + CPython itself should ignore the flag in a debugging version + (by not listing .abi3.so in the extensions it supports), but + it doesn't so far, creating troubles. That's why we check + for "not hasattr(sys, 'gettotalrefcount')" (the 2.7 compatible equivalent + of 'd' not in sys.abiflags). (http://bugs.python.org/issue28401) + + On Windows, with CPython <= 3.4, it's better not to use py_limited_api + because virtualenv *still* doesn't copy PYTHON3.DLL on these versions. + Recently (2020) we started shipping only >= 3.5 wheels, though. So + we'll give it another try and set py_limited_api on Windows >= 3.5. + """ + from cffi import recompiler + + if ('py_limited_api' not in kwds and not hasattr(sys, 'gettotalrefcount') + and recompiler.USE_LIMITED_API): + import setuptools + try: + setuptools_major_version = int(setuptools.__version__.partition('.')[0]) + if setuptools_major_version >= 26: + kwds['py_limited_api'] = True + except ValueError: # certain development versions of setuptools + # If we don't know the version number of setuptools, we + # try to set 'py_limited_api' anyway. At worst, we get a + # warning. + kwds['py_limited_api'] = True + return kwds + +def _add_c_module(dist, ffi, module_name, source, source_extension, kwds): + from distutils.core import Extension + # We are a setuptools extension. Need this build_ext for py_limited_api. + from setuptools.command.build_ext import build_ext + from distutils.dir_util import mkpath + from distutils import log + from cffi import recompiler + + allsources = ['$PLACEHOLDER'] + allsources.extend(kwds.pop('sources', [])) + kwds = _set_py_limited_api(Extension, kwds) + ext = Extension(name=module_name, sources=allsources, **kwds) + + def make_mod(tmpdir, pre_run=None): + c_file = os.path.join(tmpdir, module_name + source_extension) + log.info("generating cffi module %r" % c_file) + mkpath(tmpdir) + # a setuptools-only, API-only hook: called with the "ext" and "ffi" + # arguments just before we turn the ffi into C code. To use it, + # subclass the 'distutils.command.build_ext.build_ext' class and + # add a method 'def pre_run(self, ext, ffi)'. + if pre_run is not None: + pre_run(ext, ffi) + updated = recompiler.make_c_source(ffi, module_name, source, c_file) + if not updated: + log.info("already up-to-date") + return c_file + + if dist.ext_modules is None: + dist.ext_modules = [] + dist.ext_modules.append(ext) + + base_class = dist.cmdclass.get('build_ext', build_ext) + class build_ext_make_mod(base_class): + def run(self): + if ext.sources[0] == '$PLACEHOLDER': + pre_run = getattr(self, 'pre_run', None) + ext.sources[0] = make_mod(self.build_temp, pre_run) + base_class.run(self) + dist.cmdclass['build_ext'] = build_ext_make_mod + # NB. multiple runs here will create multiple 'build_ext_make_mod' + # classes. Even in this case the 'build_ext' command should be + # run once; but just in case, the logic above does nothing if + # called again. + + +def _add_py_module(dist, ffi, module_name): + from distutils.dir_util import mkpath + from setuptools.command.build_py import build_py + from setuptools.command.build_ext import build_ext + from distutils import log + from cffi import recompiler + + def generate_mod(py_file): + log.info("generating cffi module %r" % py_file) + mkpath(os.path.dirname(py_file)) + updated = recompiler.make_py_source(ffi, module_name, py_file) + if not updated: + log.info("already up-to-date") + + base_class = dist.cmdclass.get('build_py', build_py) + class build_py_make_mod(base_class): + def run(self): + base_class.run(self) + module_path = module_name.split('.') + module_path[-1] += '.py' + generate_mod(os.path.join(self.build_lib, *module_path)) + def get_source_files(self): + # This is called from 'setup.py sdist' only. Exclude + # the generate .py module in this case. + saved_py_modules = self.py_modules + try: + if saved_py_modules: + self.py_modules = [m for m in saved_py_modules + if m != module_name] + return base_class.get_source_files(self) + finally: + self.py_modules = saved_py_modules + dist.cmdclass['build_py'] = build_py_make_mod + + # distutils and setuptools have no notion I could find of a + # generated python module. If we don't add module_name to + # dist.py_modules, then things mostly work but there are some + # combination of options (--root and --record) that will miss + # the module. So we add it here, which gives a few apparently + # harmless warnings about not finding the file outside the + # build directory. + # Then we need to hack more in get_source_files(); see above. + if dist.py_modules is None: + dist.py_modules = [] + dist.py_modules.append(module_name) + + # the following is only for "build_ext -i" + base_class_2 = dist.cmdclass.get('build_ext', build_ext) + class build_ext_make_mod(base_class_2): + def run(self): + base_class_2.run(self) + if self.inplace: + # from get_ext_fullpath() in distutils/command/build_ext.py + module_path = module_name.split('.') + package = '.'.join(module_path[:-1]) + build_py = self.get_finalized_command('build_py') + package_dir = build_py.get_package_dir(package) + file_name = module_path[-1] + '.py' + generate_mod(os.path.join(package_dir, file_name)) + dist.cmdclass['build_ext'] = build_ext_make_mod + +def cffi_modules(dist, attr, value): + assert attr == 'cffi_modules' + if isinstance(value, basestring): + value = [value] + + for cffi_module in value: + add_cffi_module(dist, cffi_module) diff --git a/dist/ba_data/python-site-packages/cffi/vengine_cpy.py b/dist/ba_data/python-site-packages/cffi/vengine_cpy.py new file mode 100644 index 0000000..6de0df0 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/vengine_cpy.py @@ -0,0 +1,1076 @@ +# +# DEPRECATED: implementation for ffi.verify() +# +import sys, imp +from . import model +from .error import VerificationError + + +class VCPythonEngine(object): + _class_key = 'x' + _gen_python_module = True + + def __init__(self, verifier): + self.verifier = verifier + self.ffi = verifier.ffi + self._struct_pending_verification = {} + self._types_of_builtin_functions = {} + + def patch_extension_kwds(self, kwds): + pass + + def find_module(self, module_name, path, so_suffixes): + try: + f, filename, descr = imp.find_module(module_name, path) + except ImportError: + return None + if f is not None: + f.close() + # Note that after a setuptools installation, there are both .py + # and .so files with the same basename. The code here relies on + # imp.find_module() locating the .so in priority. + if descr[0] not in so_suffixes: + return None + return filename + + def collect_types(self): + self._typesdict = {} + self._generate("collecttype") + + def _prnt(self, what=''): + self._f.write(what + '\n') + + def _gettypenum(self, type): + # a KeyError here is a bug. please report it! :-) + return self._typesdict[type] + + def _do_collect_type(self, tp): + if ((not isinstance(tp, model.PrimitiveType) + or tp.name == 'long double') + and tp not in self._typesdict): + num = len(self._typesdict) + self._typesdict[tp] = num + + def write_source_to_f(self): + self.collect_types() + # + # The new module will have a _cffi_setup() function that receives + # objects from the ffi world, and that calls some setup code in + # the module. This setup code is split in several independent + # functions, e.g. one per constant. The functions are "chained" + # by ending in a tail call to each other. + # + # This is further split in two chained lists, depending on if we + # can do it at import-time or if we must wait for _cffi_setup() to + # provide us with the objects. This is needed because we + # need the values of the enum constants in order to build the + # that we may have to pass to _cffi_setup(). + # + # The following two 'chained_list_constants' items contains + # the head of these two chained lists, as a string that gives the + # call to do, if any. + self._chained_list_constants = ['((void)lib,0)', '((void)lib,0)'] + # + prnt = self._prnt + # first paste some standard set of lines that are mostly '#define' + prnt(cffimod_header) + prnt() + # then paste the C source given by the user, verbatim. + prnt(self.verifier.preamble) + prnt() + # + # call generate_cpy_xxx_decl(), for every xxx found from + # ffi._parser._declarations. This generates all the functions. + self._generate("decl") + # + # implement the function _cffi_setup_custom() as calling the + # head of the chained list. + self._generate_setup_custom() + prnt() + # + # produce the method table, including the entries for the + # generated Python->C function wrappers, which are done + # by generate_cpy_function_method(). + prnt('static PyMethodDef _cffi_methods[] = {') + self._generate("method") + prnt(' {"_cffi_setup", _cffi_setup, METH_VARARGS, NULL},') + prnt(' {NULL, NULL, 0, NULL} /* Sentinel */') + prnt('};') + prnt() + # + # standard init. + modname = self.verifier.get_module_name() + constants = self._chained_list_constants[False] + prnt('#if PY_MAJOR_VERSION >= 3') + prnt() + prnt('static struct PyModuleDef _cffi_module_def = {') + prnt(' PyModuleDef_HEAD_INIT,') + prnt(' "%s",' % modname) + prnt(' NULL,') + prnt(' -1,') + prnt(' _cffi_methods,') + prnt(' NULL, NULL, NULL, NULL') + prnt('};') + prnt() + prnt('PyMODINIT_FUNC') + prnt('PyInit_%s(void)' % modname) + prnt('{') + prnt(' PyObject *lib;') + prnt(' lib = PyModule_Create(&_cffi_module_def);') + prnt(' if (lib == NULL)') + prnt(' return NULL;') + prnt(' if (%s < 0 || _cffi_init() < 0) {' % (constants,)) + prnt(' Py_DECREF(lib);') + prnt(' return NULL;') + prnt(' }') + prnt(' return lib;') + prnt('}') + prnt() + prnt('#else') + prnt() + prnt('PyMODINIT_FUNC') + prnt('init%s(void)' % modname) + prnt('{') + prnt(' PyObject *lib;') + prnt(' lib = Py_InitModule("%s", _cffi_methods);' % modname) + prnt(' if (lib == NULL)') + prnt(' return;') + prnt(' if (%s < 0 || _cffi_init() < 0)' % (constants,)) + prnt(' return;') + prnt(' return;') + prnt('}') + prnt() + prnt('#endif') + + def load_library(self, flags=None): + # XXX review all usages of 'self' here! + # import it as a new extension module + imp.acquire_lock() + try: + if hasattr(sys, "getdlopenflags"): + previous_flags = sys.getdlopenflags() + try: + if hasattr(sys, "setdlopenflags") and flags is not None: + sys.setdlopenflags(flags) + module = imp.load_dynamic(self.verifier.get_module_name(), + self.verifier.modulefilename) + except ImportError as e: + error = "importing %r: %s" % (self.verifier.modulefilename, e) + raise VerificationError(error) + finally: + if hasattr(sys, "setdlopenflags"): + sys.setdlopenflags(previous_flags) + finally: + imp.release_lock() + # + # call loading_cpy_struct() to get the struct layout inferred by + # the C compiler + self._load(module, 'loading') + # + # the C code will need the objects. Collect them in + # order in a list. + revmapping = dict([(value, key) + for (key, value) in self._typesdict.items()]) + lst = [revmapping[i] for i in range(len(revmapping))] + lst = list(map(self.ffi._get_cached_btype, lst)) + # + # build the FFILibrary class and instance and call _cffi_setup(). + # this will set up some fields like '_cffi_types', and only then + # it will invoke the chained list of functions that will really + # build (notably) the constant objects, as if they are + # pointers, and store them as attributes on the 'library' object. + class FFILibrary(object): + _cffi_python_module = module + _cffi_ffi = self.ffi + _cffi_dir = [] + def __dir__(self): + return FFILibrary._cffi_dir + list(self.__dict__) + library = FFILibrary() + if module._cffi_setup(lst, VerificationError, library): + import warnings + warnings.warn("reimporting %r might overwrite older definitions" + % (self.verifier.get_module_name())) + # + # finally, call the loaded_cpy_xxx() functions. This will perform + # the final adjustments, like copying the Python->C wrapper + # functions from the module to the 'library' object, and setting + # up the FFILibrary class with properties for the global C variables. + self._load(module, 'loaded', library=library) + module._cffi_original_ffi = self.ffi + module._cffi_types_of_builtin_funcs = self._types_of_builtin_functions + return library + + def _get_declarations(self): + lst = [(key, tp) for (key, (tp, qual)) in + self.ffi._parser._declarations.items()] + lst.sort() + return lst + + def _generate(self, step_name): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + try: + method = getattr(self, '_generate_cpy_%s_%s' % (kind, + step_name)) + except AttributeError: + raise VerificationError( + "not implemented in verify(): %r" % name) + try: + method(tp, realname) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _load(self, module, step_name, **kwds): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + method = getattr(self, '_%s_cpy_%s' % (step_name, kind)) + try: + method(tp, realname, module, **kwds) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _generate_nothing(self, tp, name): + pass + + def _loaded_noop(self, tp, name, module, **kwds): + pass + + # ---------- + + def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode): + extraarg = '' + if isinstance(tp, model.PrimitiveType): + if tp.is_integer_type() and tp.name != '_Bool': + converter = '_cffi_to_c_int' + extraarg = ', %s' % tp.name + else: + converter = '(%s)_cffi_to_c_%s' % (tp.get_c_name(''), + tp.name.replace(' ', '_')) + errvalue = '-1' + # + elif isinstance(tp, model.PointerType): + self._convert_funcarg_to_c_ptr_or_array(tp, fromvar, + tovar, errcode) + return + # + elif isinstance(tp, (model.StructOrUnion, model.EnumType)): + # a struct (not a struct pointer) as a function argument + self._prnt(' if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)' + % (tovar, self._gettypenum(tp), fromvar)) + self._prnt(' %s;' % errcode) + return + # + elif isinstance(tp, model.FunctionPtrType): + converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('') + extraarg = ', _cffi_type(%d)' % self._gettypenum(tp) + errvalue = 'NULL' + # + else: + raise NotImplementedError(tp) + # + self._prnt(' %s = %s(%s%s);' % (tovar, converter, fromvar, extraarg)) + self._prnt(' if (%s == (%s)%s && PyErr_Occurred())' % ( + tovar, tp.get_c_name(''), errvalue)) + self._prnt(' %s;' % errcode) + + def _extra_local_variables(self, tp, localvars, freelines): + if isinstance(tp, model.PointerType): + localvars.add('Py_ssize_t datasize') + localvars.add('struct _cffi_freeme_s *large_args_free = NULL') + freelines.add('if (large_args_free != NULL)' + ' _cffi_free_array_arguments(large_args_free);') + + def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode): + self._prnt(' datasize = _cffi_prepare_pointer_call_argument(') + self._prnt(' _cffi_type(%d), %s, (char **)&%s);' % ( + self._gettypenum(tp), fromvar, tovar)) + self._prnt(' if (datasize != 0) {') + self._prnt(' %s = ((size_t)datasize) <= 640 ? ' + 'alloca((size_t)datasize) : NULL;' % (tovar,)) + self._prnt(' if (_cffi_convert_array_argument(_cffi_type(%d), %s, ' + '(char **)&%s,' % (self._gettypenum(tp), fromvar, tovar)) + self._prnt(' datasize, &large_args_free) < 0)') + self._prnt(' %s;' % errcode) + self._prnt(' }') + + def _convert_expr_from_c(self, tp, var, context): + if isinstance(tp, model.PrimitiveType): + if tp.is_integer_type() and tp.name != '_Bool': + return '_cffi_from_c_int(%s, %s)' % (var, tp.name) + elif tp.name != 'long double': + return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var) + else: + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, (model.PointerType, model.FunctionPtrType)): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.ArrayType): + return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % ( + var, self._gettypenum(model.PointerType(tp.item))) + elif isinstance(tp, model.StructOrUnion): + if tp.fldnames is None: + raise TypeError("'%s' is used as %s, but is opaque" % ( + tp._get_c_name(), context)) + return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + elif isinstance(tp, model.EnumType): + return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % ( + var, self._gettypenum(tp)) + else: + raise NotImplementedError(tp) + + # ---------- + # typedefs: generates no code so far + + _generate_cpy_typedef_collecttype = _generate_nothing + _generate_cpy_typedef_decl = _generate_nothing + _generate_cpy_typedef_method = _generate_nothing + _loading_cpy_typedef = _loaded_noop + _loaded_cpy_typedef = _loaded_noop + + # ---------- + # function declarations + + def _generate_cpy_function_collecttype(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + self._do_collect_type(tp) + else: + # don't call _do_collect_type(tp) in this common case, + # otherwise test_autofilled_struct_as_argument fails + for type in tp.args: + self._do_collect_type(type) + self._do_collect_type(tp.result) + + def _generate_cpy_function_decl(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + # cannot support vararg functions better than this: check for its + # exact type (including the fixed arguments), and build it as a + # constant function pointer (no CPython wrapper) + self._generate_cpy_const(False, name, tp) + return + prnt = self._prnt + numargs = len(tp.args) + if numargs == 0: + argname = 'noarg' + elif numargs == 1: + argname = 'arg0' + else: + argname = 'args' + prnt('static PyObject *') + prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname)) + prnt('{') + # + context = 'argument of %s' % name + for i, type in enumerate(tp.args): + prnt(' %s;' % type.get_c_name(' x%d' % i, context)) + # + localvars = set() + freelines = set() + for type in tp.args: + self._extra_local_variables(type, localvars, freelines) + for decl in sorted(localvars): + prnt(' %s;' % (decl,)) + # + if not isinstance(tp.result, model.VoidType): + result_code = 'result = ' + context = 'result of %s' % name + prnt(' %s;' % tp.result.get_c_name(' result', context)) + prnt(' PyObject *pyresult;') + else: + result_code = '' + # + if len(tp.args) > 1: + rng = range(len(tp.args)) + for i in rng: + prnt(' PyObject *arg%d;' % i) + prnt() + prnt(' if (!PyArg_ParseTuple(args, "%s:%s", %s))' % ( + 'O' * numargs, name, ', '.join(['&arg%d' % i for i in rng]))) + prnt(' return NULL;') + prnt() + # + for i, type in enumerate(tp.args): + self._convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i, + 'return NULL') + prnt() + # + prnt(' Py_BEGIN_ALLOW_THREADS') + prnt(' _cffi_restore_errno();') + prnt(' { %s%s(%s); }' % ( + result_code, name, + ', '.join(['x%d' % i for i in range(len(tp.args))]))) + prnt(' _cffi_save_errno();') + prnt(' Py_END_ALLOW_THREADS') + prnt() + # + prnt(' (void)self; /* unused */') + if numargs == 0: + prnt(' (void)noarg; /* unused */') + if result_code: + prnt(' pyresult = %s;' % + self._convert_expr_from_c(tp.result, 'result', 'result type')) + for freeline in freelines: + prnt(' ' + freeline) + prnt(' return pyresult;') + else: + for freeline in freelines: + prnt(' ' + freeline) + prnt(' Py_INCREF(Py_None);') + prnt(' return Py_None;') + prnt('}') + prnt() + + def _generate_cpy_function_method(self, tp, name): + if tp.ellipsis: + return + numargs = len(tp.args) + if numargs == 0: + meth = 'METH_NOARGS' + elif numargs == 1: + meth = 'METH_O' + else: + meth = 'METH_VARARGS' + self._prnt(' {"%s", _cffi_f_%s, %s, NULL},' % (name, name, meth)) + + _loading_cpy_function = _loaded_noop + + def _loaded_cpy_function(self, tp, name, module, library): + if tp.ellipsis: + return + func = getattr(module, name) + setattr(library, name, func) + self._types_of_builtin_functions[func] = tp + + # ---------- + # named structs + + _generate_cpy_struct_collecttype = _generate_nothing + def _generate_cpy_struct_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'struct', name) + def _generate_cpy_struct_method(self, tp, name): + self._generate_struct_or_union_method(tp, 'struct', name) + def _loading_cpy_struct(self, tp, name, module): + self._loading_struct_or_union(tp, 'struct', name, module) + def _loaded_cpy_struct(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + _generate_cpy_union_collecttype = _generate_nothing + def _generate_cpy_union_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'union', name) + def _generate_cpy_union_method(self, tp, name): + self._generate_struct_or_union_method(tp, 'union', name) + def _loading_cpy_union(self, tp, name, module): + self._loading_struct_or_union(tp, 'union', name, module) + def _loaded_cpy_union(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + def _generate_struct_or_union_decl(self, tp, prefix, name): + if tp.fldnames is None: + return # nothing to do with opaque structs + checkfuncname = '_cffi_check_%s_%s' % (prefix, name) + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + cname = ('%s %s' % (prefix, name)).strip() + # + prnt = self._prnt + prnt('static void %s(%s *p)' % (checkfuncname, cname)) + prnt('{') + prnt(' /* only to generate compile-time warnings or errors */') + prnt(' (void)p;') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if (isinstance(ftype, model.PrimitiveType) + and ftype.is_integer_type()) or fbitsize >= 0: + # accept all integers, but complain on float or double + prnt(' (void)((p->%s) << 1);' % fname) + else: + # only accept exactly the type declared. + try: + prnt(' { %s = &p->%s; (void)tmp; }' % ( + ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), + fname)) + except VerificationError as e: + prnt(' /* %s */' % str(e)) # cannot verify it, ignore + prnt('}') + prnt('static PyObject *') + prnt('%s(PyObject *self, PyObject *noarg)' % (layoutfuncname,)) + prnt('{') + prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname) + prnt(' static Py_ssize_t nums[] = {') + prnt(' sizeof(%s),' % cname) + prnt(' offsetof(struct _cffi_aligncheck, y),') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + prnt(' offsetof(%s, %s),' % (cname, fname)) + if isinstance(ftype, model.ArrayType) and ftype.length is None: + prnt(' 0, /* %s */' % ftype._get_c_name()) + else: + prnt(' sizeof(((%s *)0)->%s),' % (cname, fname)) + prnt(' -1') + prnt(' };') + prnt(' (void)self; /* unused */') + prnt(' (void)noarg; /* unused */') + prnt(' return _cffi_get_struct_layout(nums);') + prnt(' /* the next line is not executed, but compiled */') + prnt(' %s(0);' % (checkfuncname,)) + prnt('}') + prnt() + + def _generate_struct_or_union_method(self, tp, prefix, name): + if tp.fldnames is None: + return # nothing to do with opaque structs + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + self._prnt(' {"%s", %s, METH_NOARGS, NULL},' % (layoutfuncname, + layoutfuncname)) + + def _loading_struct_or_union(self, tp, prefix, name, module): + if tp.fldnames is None: + return # nothing to do with opaque structs + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + # + function = getattr(module, layoutfuncname) + layout = function() + if isinstance(tp, model.StructOrUnion) and tp.partial: + # use the function()'s sizes and offsets to guide the + # layout of the struct + totalsize = layout[0] + totalalignment = layout[1] + fieldofs = layout[2::2] + fieldsize = layout[3::2] + tp.force_flatten() + assert len(fieldofs) == len(fieldsize) == len(tp.fldnames) + tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment + else: + cname = ('%s %s' % (prefix, name)).strip() + self._struct_pending_verification[tp] = layout, cname + + def _loaded_struct_or_union(self, tp): + if tp.fldnames is None: + return # nothing to do with opaque structs + self.ffi._get_cached_btype(tp) # force 'fixedlayout' to be considered + + if tp in self._struct_pending_verification: + # check that the layout sizes and offsets match the real ones + def check(realvalue, expectedvalue, msg): + if realvalue != expectedvalue: + raise VerificationError( + "%s (we have %d, but C compiler says %d)" + % (msg, expectedvalue, realvalue)) + ffi = self.ffi + BStruct = ffi._get_cached_btype(tp) + layout, cname = self._struct_pending_verification.pop(tp) + check(layout[0], ffi.sizeof(BStruct), "wrong total size") + check(layout[1], ffi.alignof(BStruct), "wrong total alignment") + i = 2 + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + check(layout[i], ffi.offsetof(BStruct, fname), + "wrong offset for field %r" % (fname,)) + if layout[i+1] != 0: + BField = ffi._get_cached_btype(ftype) + check(layout[i+1], ffi.sizeof(BField), + "wrong size for field %r" % (fname,)) + i += 2 + assert i == len(layout) + + # ---------- + # 'anonymous' declarations. These are produced for anonymous structs + # or unions; the 'name' is obtained by a typedef. + + _generate_cpy_anonymous_collecttype = _generate_nothing + + def _generate_cpy_anonymous_decl(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_cpy_enum_decl(tp, name, '') + else: + self._generate_struct_or_union_decl(tp, '', name) + + def _generate_cpy_anonymous_method(self, tp, name): + if not isinstance(tp, model.EnumType): + self._generate_struct_or_union_method(tp, '', name) + + def _loading_cpy_anonymous(self, tp, name, module): + if isinstance(tp, model.EnumType): + self._loading_cpy_enum(tp, name, module) + else: + self._loading_struct_or_union(tp, '', name, module) + + def _loaded_cpy_anonymous(self, tp, name, module, **kwds): + if isinstance(tp, model.EnumType): + self._loaded_cpy_enum(tp, name, module, **kwds) + else: + self._loaded_struct_or_union(tp) + + # ---------- + # constants, likely declared with '#define' + + def _generate_cpy_const(self, is_int, name, tp=None, category='const', + vartp=None, delayed=True, size_too=False, + check_value=None): + prnt = self._prnt + funcname = '_cffi_%s_%s' % (category, name) + prnt('static int %s(PyObject *lib)' % funcname) + prnt('{') + prnt(' PyObject *o;') + prnt(' int res;') + if not is_int: + prnt(' %s;' % (vartp or tp).get_c_name(' i', name)) + else: + assert category == 'const' + # + if check_value is not None: + self._check_int_constant_value(name, check_value) + # + if not is_int: + if category == 'var': + realexpr = '&' + name + else: + realexpr = name + prnt(' i = (%s);' % (realexpr,)) + prnt(' o = %s;' % (self._convert_expr_from_c(tp, 'i', + 'variable type'),)) + assert delayed + else: + prnt(' o = _cffi_from_c_int_const(%s);' % name) + prnt(' if (o == NULL)') + prnt(' return -1;') + if size_too: + prnt(' {') + prnt(' PyObject *o1 = o;') + prnt(' o = Py_BuildValue("On", o1, (Py_ssize_t)sizeof(%s));' + % (name,)) + prnt(' Py_DECREF(o1);') + prnt(' if (o == NULL)') + prnt(' return -1;') + prnt(' }') + prnt(' res = PyObject_SetAttrString(lib, "%s", o);' % name) + prnt(' Py_DECREF(o);') + prnt(' if (res < 0)') + prnt(' return -1;') + prnt(' return %s;' % self._chained_list_constants[delayed]) + self._chained_list_constants[delayed] = funcname + '(lib)' + prnt('}') + prnt() + + def _generate_cpy_constant_collecttype(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + if not is_int: + self._do_collect_type(tp) + + def _generate_cpy_constant_decl(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + self._generate_cpy_const(is_int, name, tp) + + _generate_cpy_constant_method = _generate_nothing + _loading_cpy_constant = _loaded_noop + _loaded_cpy_constant = _loaded_noop + + # ---------- + # enums + + def _check_int_constant_value(self, name, value, err_prefix=''): + prnt = self._prnt + if value <= 0: + prnt(' if ((%s) > 0 || (long)(%s) != %dL) {' % ( + name, name, value)) + else: + prnt(' if ((%s) <= 0 || (unsigned long)(%s) != %dUL) {' % ( + name, name, value)) + prnt(' char buf[64];') + prnt(' if ((%s) <= 0)' % name) + prnt(' snprintf(buf, 63, "%%ld", (long)(%s));' % name) + prnt(' else') + prnt(' snprintf(buf, 63, "%%lu", (unsigned long)(%s));' % + name) + prnt(' PyErr_Format(_cffi_VerificationError,') + prnt(' "%s%s has the real value %s, not %s",') + prnt(' "%s", "%s", buf, "%d");' % ( + err_prefix, name, value)) + prnt(' return -1;') + prnt(' }') + + def _enum_funcname(self, prefix, name): + # "$enum_$1" => "___D_enum____D_1" + name = name.replace('$', '___D_') + return '_cffi_e_%s_%s' % (prefix, name) + + def _generate_cpy_enum_decl(self, tp, name, prefix='enum'): + if tp.partial: + for enumerator in tp.enumerators: + self._generate_cpy_const(True, enumerator, delayed=False) + return + # + funcname = self._enum_funcname(prefix, name) + prnt = self._prnt + prnt('static int %s(PyObject *lib)' % funcname) + prnt('{') + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + self._check_int_constant_value(enumerator, enumvalue, + "enum %s: " % name) + prnt(' return %s;' % self._chained_list_constants[True]) + self._chained_list_constants[True] = funcname + '(lib)' + prnt('}') + prnt() + + _generate_cpy_enum_collecttype = _generate_nothing + _generate_cpy_enum_method = _generate_nothing + + def _loading_cpy_enum(self, tp, name, module): + if tp.partial: + enumvalues = [getattr(module, enumerator) + for enumerator in tp.enumerators] + tp.enumvalues = tuple(enumvalues) + tp.partial_resolved = True + + def _loaded_cpy_enum(self, tp, name, module, library): + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + setattr(library, enumerator, enumvalue) + + # ---------- + # macros: for now only for integers + + def _generate_cpy_macro_decl(self, tp, name): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + self._generate_cpy_const(True, name, check_value=check_value) + + _generate_cpy_macro_collecttype = _generate_nothing + _generate_cpy_macro_method = _generate_nothing + _loading_cpy_macro = _loaded_noop + _loaded_cpy_macro = _loaded_noop + + # ---------- + # global variables + + def _generate_cpy_variable_collecttype(self, tp, name): + if isinstance(tp, model.ArrayType): + tp_ptr = model.PointerType(tp.item) + else: + tp_ptr = model.PointerType(tp) + self._do_collect_type(tp_ptr) + + def _generate_cpy_variable_decl(self, tp, name): + if isinstance(tp, model.ArrayType): + tp_ptr = model.PointerType(tp.item) + self._generate_cpy_const(False, name, tp, vartp=tp_ptr, + size_too = tp.length_is_unknown()) + else: + tp_ptr = model.PointerType(tp) + self._generate_cpy_const(False, name, tp_ptr, category='var') + + _generate_cpy_variable_method = _generate_nothing + _loading_cpy_variable = _loaded_noop + + def _loaded_cpy_variable(self, tp, name, module, library): + value = getattr(library, name) + if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the + # sense that "a=..." is forbidden + if tp.length_is_unknown(): + assert isinstance(value, tuple) + (value, size) = value + BItemType = self.ffi._get_cached_btype(tp.item) + length, rest = divmod(size, self.ffi.sizeof(BItemType)) + if rest != 0: + raise VerificationError( + "bad size: %r does not seem to be an array of %s" % + (name, tp.item)) + tp = tp.resolve_length(length) + # 'value' is a which we have to replace with + # a if the N is actually known + if tp.length is not None: + BArray = self.ffi._get_cached_btype(tp) + value = self.ffi.cast(BArray, value) + setattr(library, name, value) + return + # remove ptr= from the library instance, and replace + # it by a property on the class, which reads/writes into ptr[0]. + ptr = value + delattr(library, name) + def getter(library): + return ptr[0] + def setter(library, value): + ptr[0] = value + setattr(type(library), name, property(getter, setter)) + type(library)._cffi_dir.append(name) + + # ---------- + + def _generate_setup_custom(self): + prnt = self._prnt + prnt('static int _cffi_setup_custom(PyObject *lib)') + prnt('{') + prnt(' return %s;' % self._chained_list_constants[True]) + prnt('}') + +cffimod_header = r''' +#include +#include + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif + +#if PY_MAJOR_VERSION < 3 +# undef PyCapsule_CheckExact +# undef PyCapsule_GetPointer +# define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule)) +# define PyCapsule_GetPointer(capsule, name) \ + (PyCObject_AsVoidPtr(capsule)) +#endif + +#if PY_MAJOR_VERSION >= 3 +# define PyInt_FromLong PyLong_FromLong +#endif + +#define _cffi_from_c_double PyFloat_FromDouble +#define _cffi_from_c_float PyFloat_FromDouble +#define _cffi_from_c_long PyInt_FromLong +#define _cffi_from_c_ulong PyLong_FromUnsignedLong +#define _cffi_from_c_longlong PyLong_FromLongLong +#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong +#define _cffi_from_c__Bool PyBool_FromLong + +#define _cffi_to_c_double PyFloat_AsDouble +#define _cffi_to_c_float PyFloat_AsDouble + +#define _cffi_from_c_int_const(x) \ + (((x) > 0) ? \ + ((unsigned long long)(x) <= (unsigned long long)LONG_MAX) ? \ + PyInt_FromLong((long)(x)) : \ + PyLong_FromUnsignedLongLong((unsigned long long)(x)) : \ + ((long long)(x) >= (long long)LONG_MIN) ? \ + PyInt_FromLong((long)(x)) : \ + PyLong_FromLongLong((long long)(x))) + +#define _cffi_from_c_int(x, type) \ + (((type)-1) > 0 ? /* unsigned */ \ + (sizeof(type) < sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + sizeof(type) == sizeof(long) ? \ + PyLong_FromUnsignedLong((unsigned long)x) : \ + PyLong_FromUnsignedLongLong((unsigned long long)x)) : \ + (sizeof(type) <= sizeof(long) ? \ + PyInt_FromLong((long)x) : \ + PyLong_FromLongLong((long long)x))) + +#define _cffi_to_c_int(o, type) \ + ((type)( \ + sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \ + : (type)_cffi_to_c_i8(o)) : \ + sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o) \ + : (type)_cffi_to_c_i16(o)) : \ + sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o) \ + : (type)_cffi_to_c_i32(o)) : \ + sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \ + : (type)_cffi_to_c_i64(o)) : \ + (Py_FatalError("unsupported size for type " #type), (type)0))) + +#define _cffi_to_c_i8 \ + ((int(*)(PyObject *))_cffi_exports[1]) +#define _cffi_to_c_u8 \ + ((int(*)(PyObject *))_cffi_exports[2]) +#define _cffi_to_c_i16 \ + ((int(*)(PyObject *))_cffi_exports[3]) +#define _cffi_to_c_u16 \ + ((int(*)(PyObject *))_cffi_exports[4]) +#define _cffi_to_c_i32 \ + ((int(*)(PyObject *))_cffi_exports[5]) +#define _cffi_to_c_u32 \ + ((unsigned int(*)(PyObject *))_cffi_exports[6]) +#define _cffi_to_c_i64 \ + ((long long(*)(PyObject *))_cffi_exports[7]) +#define _cffi_to_c_u64 \ + ((unsigned long long(*)(PyObject *))_cffi_exports[8]) +#define _cffi_to_c_char \ + ((int(*)(PyObject *))_cffi_exports[9]) +#define _cffi_from_c_pointer \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[10]) +#define _cffi_to_c_pointer \ + ((char *(*)(PyObject *, CTypeDescrObject *))_cffi_exports[11]) +#define _cffi_get_struct_layout \ + ((PyObject *(*)(Py_ssize_t[]))_cffi_exports[12]) +#define _cffi_restore_errno \ + ((void(*)(void))_cffi_exports[13]) +#define _cffi_save_errno \ + ((void(*)(void))_cffi_exports[14]) +#define _cffi_from_c_char \ + ((PyObject *(*)(char))_cffi_exports[15]) +#define _cffi_from_c_deref \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16]) +#define _cffi_to_c \ + ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[17]) +#define _cffi_from_c_struct \ + ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[18]) +#define _cffi_to_c_wchar_t \ + ((wchar_t(*)(PyObject *))_cffi_exports[19]) +#define _cffi_from_c_wchar_t \ + ((PyObject *(*)(wchar_t))_cffi_exports[20]) +#define _cffi_to_c_long_double \ + ((long double(*)(PyObject *))_cffi_exports[21]) +#define _cffi_to_c__Bool \ + ((_Bool(*)(PyObject *))_cffi_exports[22]) +#define _cffi_prepare_pointer_call_argument \ + ((Py_ssize_t(*)(CTypeDescrObject *, PyObject *, char **))_cffi_exports[23]) +#define _cffi_convert_array_from_object \ + ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[24]) +#define _CFFI_NUM_EXPORTS 25 + +typedef struct _ctypedescr CTypeDescrObject; + +static void *_cffi_exports[_CFFI_NUM_EXPORTS]; +static PyObject *_cffi_types, *_cffi_VerificationError; + +static int _cffi_setup_custom(PyObject *lib); /* forward */ + +static PyObject *_cffi_setup(PyObject *self, PyObject *args) +{ + PyObject *library; + int was_alive = (_cffi_types != NULL); + (void)self; /* unused */ + if (!PyArg_ParseTuple(args, "OOO", &_cffi_types, &_cffi_VerificationError, + &library)) + return NULL; + Py_INCREF(_cffi_types); + Py_INCREF(_cffi_VerificationError); + if (_cffi_setup_custom(library) < 0) + return NULL; + return PyBool_FromLong(was_alive); +} + +union _cffi_union_alignment_u { + unsigned char m_char; + unsigned short m_short; + unsigned int m_int; + unsigned long m_long; + unsigned long long m_longlong; + float m_float; + double m_double; + long double m_longdouble; +}; + +struct _cffi_freeme_s { + struct _cffi_freeme_s *next; + union _cffi_union_alignment_u alignment; +}; + +#ifdef __GNUC__ + __attribute__((unused)) +#endif +static int _cffi_convert_array_argument(CTypeDescrObject *ctptr, PyObject *arg, + char **output_data, Py_ssize_t datasize, + struct _cffi_freeme_s **freeme) +{ + char *p; + if (datasize < 0) + return -1; + + p = *output_data; + if (p == NULL) { + struct _cffi_freeme_s *fp = (struct _cffi_freeme_s *)PyObject_Malloc( + offsetof(struct _cffi_freeme_s, alignment) + (size_t)datasize); + if (fp == NULL) + return -1; + fp->next = *freeme; + *freeme = fp; + p = *output_data = (char *)&fp->alignment; + } + memset((void *)p, 0, (size_t)datasize); + return _cffi_convert_array_from_object(p, ctptr, arg); +} + +#ifdef __GNUC__ + __attribute__((unused)) +#endif +static void _cffi_free_array_arguments(struct _cffi_freeme_s *freeme) +{ + do { + void *p = (void *)freeme; + freeme = freeme->next; + PyObject_Free(p); + } while (freeme != NULL); +} + +static int _cffi_init(void) +{ + PyObject *module, *c_api_object = NULL; + + module = PyImport_ImportModule("_cffi_backend"); + if (module == NULL) + goto failure; + + c_api_object = PyObject_GetAttrString(module, "_C_API"); + if (c_api_object == NULL) + goto failure; + if (!PyCapsule_CheckExact(c_api_object)) { + PyErr_SetNone(PyExc_ImportError); + goto failure; + } + memcpy(_cffi_exports, PyCapsule_GetPointer(c_api_object, "cffi"), + _CFFI_NUM_EXPORTS * sizeof(void *)); + + Py_DECREF(module); + Py_DECREF(c_api_object); + return 0; + + failure: + Py_XDECREF(module); + Py_XDECREF(c_api_object); + return -1; +} + +#define _cffi_type(num) ((CTypeDescrObject *)PyList_GET_ITEM(_cffi_types, num)) + +/**********/ +''' diff --git a/dist/ba_data/python-site-packages/cffi/vengine_gen.py b/dist/ba_data/python-site-packages/cffi/vengine_gen.py new file mode 100644 index 0000000..2642152 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/vengine_gen.py @@ -0,0 +1,675 @@ +# +# DEPRECATED: implementation for ffi.verify() +# +import sys, os +import types + +from . import model +from .error import VerificationError + + +class VGenericEngine(object): + _class_key = 'g' + _gen_python_module = False + + def __init__(self, verifier): + self.verifier = verifier + self.ffi = verifier.ffi + self.export_symbols = [] + self._struct_pending_verification = {} + + def patch_extension_kwds(self, kwds): + # add 'export_symbols' to the dictionary. Note that we add the + # list before filling it. When we fill it, it will thus also show + # up in kwds['export_symbols']. + kwds.setdefault('export_symbols', self.export_symbols) + + def find_module(self, module_name, path, so_suffixes): + for so_suffix in so_suffixes: + basename = module_name + so_suffix + if path is None: + path = sys.path + for dirname in path: + filename = os.path.join(dirname, basename) + if os.path.isfile(filename): + return filename + + def collect_types(self): + pass # not needed in the generic engine + + def _prnt(self, what=''): + self._f.write(what + '\n') + + def write_source_to_f(self): + prnt = self._prnt + # first paste some standard set of lines that are mostly '#include' + prnt(cffimod_header) + # then paste the C source given by the user, verbatim. + prnt(self.verifier.preamble) + # + # call generate_gen_xxx_decl(), for every xxx found from + # ffi._parser._declarations. This generates all the functions. + self._generate('decl') + # + # on Windows, distutils insists on putting init_cffi_xyz in + # 'export_symbols', so instead of fighting it, just give up and + # give it one + if sys.platform == 'win32': + if sys.version_info >= (3,): + prefix = 'PyInit_' + else: + prefix = 'init' + modname = self.verifier.get_module_name() + prnt("void %s%s(void) { }\n" % (prefix, modname)) + + def load_library(self, flags=0): + # import it with the CFFI backend + backend = self.ffi._backend + # needs to make a path that contains '/', on Posix + filename = os.path.join(os.curdir, self.verifier.modulefilename) + module = backend.load_library(filename, flags) + # + # call loading_gen_struct() to get the struct layout inferred by + # the C compiler + self._load(module, 'loading') + + # build the FFILibrary class and instance, this is a module subclass + # because modules are expected to have usually-constant-attributes and + # in PyPy this means the JIT is able to treat attributes as constant, + # which we want. + class FFILibrary(types.ModuleType): + _cffi_generic_module = module + _cffi_ffi = self.ffi + _cffi_dir = [] + def __dir__(self): + return FFILibrary._cffi_dir + library = FFILibrary("") + # + # finally, call the loaded_gen_xxx() functions. This will set + # up the 'library' object. + self._load(module, 'loaded', library=library) + return library + + def _get_declarations(self): + lst = [(key, tp) for (key, (tp, qual)) in + self.ffi._parser._declarations.items()] + lst.sort() + return lst + + def _generate(self, step_name): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + try: + method = getattr(self, '_generate_gen_%s_%s' % (kind, + step_name)) + except AttributeError: + raise VerificationError( + "not implemented in verify(): %r" % name) + try: + method(tp, realname) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _load(self, module, step_name, **kwds): + for name, tp in self._get_declarations(): + kind, realname = name.split(' ', 1) + method = getattr(self, '_%s_gen_%s' % (step_name, kind)) + try: + method(tp, realname, module, **kwds) + except Exception as e: + model.attach_exception_info(e, name) + raise + + def _generate_nothing(self, tp, name): + pass + + def _loaded_noop(self, tp, name, module, **kwds): + pass + + # ---------- + # typedefs: generates no code so far + + _generate_gen_typedef_decl = _generate_nothing + _loading_gen_typedef = _loaded_noop + _loaded_gen_typedef = _loaded_noop + + # ---------- + # function declarations + + def _generate_gen_function_decl(self, tp, name): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + # cannot support vararg functions better than this: check for its + # exact type (including the fixed arguments), and build it as a + # constant function pointer (no _cffi_f_%s wrapper) + self._generate_gen_const(False, name, tp) + return + prnt = self._prnt + numargs = len(tp.args) + argnames = [] + for i, type in enumerate(tp.args): + indirection = '' + if isinstance(type, model.StructOrUnion): + indirection = '*' + argnames.append('%sx%d' % (indirection, i)) + context = 'argument of %s' % name + arglist = [type.get_c_name(' %s' % arg, context) + for type, arg in zip(tp.args, argnames)] + tpresult = tp.result + if isinstance(tpresult, model.StructOrUnion): + arglist.insert(0, tpresult.get_c_name(' *r', context)) + tpresult = model.void_type + arglist = ', '.join(arglist) or 'void' + wrappername = '_cffi_f_%s' % name + self.export_symbols.append(wrappername) + if tp.abi: + abi = tp.abi + ' ' + else: + abi = '' + funcdecl = ' %s%s(%s)' % (abi, wrappername, arglist) + context = 'result of %s' % name + prnt(tpresult.get_c_name(funcdecl, context)) + prnt('{') + # + if isinstance(tp.result, model.StructOrUnion): + result_code = '*r = ' + elif not isinstance(tp.result, model.VoidType): + result_code = 'return ' + else: + result_code = '' + prnt(' %s%s(%s);' % (result_code, name, ', '.join(argnames))) + prnt('}') + prnt() + + _loading_gen_function = _loaded_noop + + def _loaded_gen_function(self, tp, name, module, library): + assert isinstance(tp, model.FunctionPtrType) + if tp.ellipsis: + newfunction = self._load_constant(False, tp, name, module) + else: + indirections = [] + base_tp = tp + if (any(isinstance(typ, model.StructOrUnion) for typ in tp.args) + or isinstance(tp.result, model.StructOrUnion)): + indirect_args = [] + for i, typ in enumerate(tp.args): + if isinstance(typ, model.StructOrUnion): + typ = model.PointerType(typ) + indirections.append((i, typ)) + indirect_args.append(typ) + indirect_result = tp.result + if isinstance(indirect_result, model.StructOrUnion): + if indirect_result.fldtypes is None: + raise TypeError("'%s' is used as result type, " + "but is opaque" % ( + indirect_result._get_c_name(),)) + indirect_result = model.PointerType(indirect_result) + indirect_args.insert(0, indirect_result) + indirections.insert(0, ("result", indirect_result)) + indirect_result = model.void_type + tp = model.FunctionPtrType(tuple(indirect_args), + indirect_result, tp.ellipsis) + BFunc = self.ffi._get_cached_btype(tp) + wrappername = '_cffi_f_%s' % name + newfunction = module.load_function(BFunc, wrappername) + for i, typ in indirections: + newfunction = self._make_struct_wrapper(newfunction, i, typ, + base_tp) + setattr(library, name, newfunction) + type(library)._cffi_dir.append(name) + + def _make_struct_wrapper(self, oldfunc, i, tp, base_tp): + backend = self.ffi._backend + BType = self.ffi._get_cached_btype(tp) + if i == "result": + ffi = self.ffi + def newfunc(*args): + res = ffi.new(BType) + oldfunc(res, *args) + return res[0] + else: + def newfunc(*args): + args = args[:i] + (backend.newp(BType, args[i]),) + args[i+1:] + return oldfunc(*args) + newfunc._cffi_base_type = base_tp + return newfunc + + # ---------- + # named structs + + def _generate_gen_struct_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'struct', name) + + def _loading_gen_struct(self, tp, name, module): + self._loading_struct_or_union(tp, 'struct', name, module) + + def _loaded_gen_struct(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + def _generate_gen_union_decl(self, tp, name): + assert name == tp.name + self._generate_struct_or_union_decl(tp, 'union', name) + + def _loading_gen_union(self, tp, name, module): + self._loading_struct_or_union(tp, 'union', name, module) + + def _loaded_gen_union(self, tp, name, module, **kwds): + self._loaded_struct_or_union(tp) + + def _generate_struct_or_union_decl(self, tp, prefix, name): + if tp.fldnames is None: + return # nothing to do with opaque structs + checkfuncname = '_cffi_check_%s_%s' % (prefix, name) + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + cname = ('%s %s' % (prefix, name)).strip() + # + prnt = self._prnt + prnt('static void %s(%s *p)' % (checkfuncname, cname)) + prnt('{') + prnt(' /* only to generate compile-time warnings or errors */') + prnt(' (void)p;') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if (isinstance(ftype, model.PrimitiveType) + and ftype.is_integer_type()) or fbitsize >= 0: + # accept all integers, but complain on float or double + prnt(' (void)((p->%s) << 1);' % fname) + else: + # only accept exactly the type declared. + try: + prnt(' { %s = &p->%s; (void)tmp; }' % ( + ftype.get_c_name('*tmp', 'field %r'%fname, quals=fqual), + fname)) + except VerificationError as e: + prnt(' /* %s */' % str(e)) # cannot verify it, ignore + prnt('}') + self.export_symbols.append(layoutfuncname) + prnt('intptr_t %s(intptr_t i)' % (layoutfuncname,)) + prnt('{') + prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname) + prnt(' static intptr_t nums[] = {') + prnt(' sizeof(%s),' % cname) + prnt(' offsetof(struct _cffi_aligncheck, y),') + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + prnt(' offsetof(%s, %s),' % (cname, fname)) + if isinstance(ftype, model.ArrayType) and ftype.length is None: + prnt(' 0, /* %s */' % ftype._get_c_name()) + else: + prnt(' sizeof(((%s *)0)->%s),' % (cname, fname)) + prnt(' -1') + prnt(' };') + prnt(' return nums[i];') + prnt(' /* the next line is not executed, but compiled */') + prnt(' %s(0);' % (checkfuncname,)) + prnt('}') + prnt() + + def _loading_struct_or_union(self, tp, prefix, name, module): + if tp.fldnames is None: + return # nothing to do with opaque structs + layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name) + # + BFunc = self.ffi._typeof_locked("intptr_t(*)(intptr_t)")[0] + function = module.load_function(BFunc, layoutfuncname) + layout = [] + num = 0 + while True: + x = function(num) + if x < 0: break + layout.append(x) + num += 1 + if isinstance(tp, model.StructOrUnion) and tp.partial: + # use the function()'s sizes and offsets to guide the + # layout of the struct + totalsize = layout[0] + totalalignment = layout[1] + fieldofs = layout[2::2] + fieldsize = layout[3::2] + tp.force_flatten() + assert len(fieldofs) == len(fieldsize) == len(tp.fldnames) + tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment + else: + cname = ('%s %s' % (prefix, name)).strip() + self._struct_pending_verification[tp] = layout, cname + + def _loaded_struct_or_union(self, tp): + if tp.fldnames is None: + return # nothing to do with opaque structs + self.ffi._get_cached_btype(tp) # force 'fixedlayout' to be considered + + if tp in self._struct_pending_verification: + # check that the layout sizes and offsets match the real ones + def check(realvalue, expectedvalue, msg): + if realvalue != expectedvalue: + raise VerificationError( + "%s (we have %d, but C compiler says %d)" + % (msg, expectedvalue, realvalue)) + ffi = self.ffi + BStruct = ffi._get_cached_btype(tp) + layout, cname = self._struct_pending_verification.pop(tp) + check(layout[0], ffi.sizeof(BStruct), "wrong total size") + check(layout[1], ffi.alignof(BStruct), "wrong total alignment") + i = 2 + for fname, ftype, fbitsize, fqual in tp.enumfields(): + if fbitsize >= 0: + continue # xxx ignore fbitsize for now + check(layout[i], ffi.offsetof(BStruct, fname), + "wrong offset for field %r" % (fname,)) + if layout[i+1] != 0: + BField = ffi._get_cached_btype(ftype) + check(layout[i+1], ffi.sizeof(BField), + "wrong size for field %r" % (fname,)) + i += 2 + assert i == len(layout) + + # ---------- + # 'anonymous' declarations. These are produced for anonymous structs + # or unions; the 'name' is obtained by a typedef. + + def _generate_gen_anonymous_decl(self, tp, name): + if isinstance(tp, model.EnumType): + self._generate_gen_enum_decl(tp, name, '') + else: + self._generate_struct_or_union_decl(tp, '', name) + + def _loading_gen_anonymous(self, tp, name, module): + if isinstance(tp, model.EnumType): + self._loading_gen_enum(tp, name, module, '') + else: + self._loading_struct_or_union(tp, '', name, module) + + def _loaded_gen_anonymous(self, tp, name, module, **kwds): + if isinstance(tp, model.EnumType): + self._loaded_gen_enum(tp, name, module, **kwds) + else: + self._loaded_struct_or_union(tp) + + # ---------- + # constants, likely declared with '#define' + + def _generate_gen_const(self, is_int, name, tp=None, category='const', + check_value=None): + prnt = self._prnt + funcname = '_cffi_%s_%s' % (category, name) + self.export_symbols.append(funcname) + if check_value is not None: + assert is_int + assert category == 'const' + prnt('int %s(char *out_error)' % funcname) + prnt('{') + self._check_int_constant_value(name, check_value) + prnt(' return 0;') + prnt('}') + elif is_int: + assert category == 'const' + prnt('int %s(long long *out_value)' % funcname) + prnt('{') + prnt(' *out_value = (long long)(%s);' % (name,)) + prnt(' return (%s) <= 0;' % (name,)) + prnt('}') + else: + assert tp is not None + assert check_value is None + if category == 'var': + ampersand = '&' + else: + ampersand = '' + extra = '' + if category == 'const' and isinstance(tp, model.StructOrUnion): + extra = 'const *' + ampersand = '&' + prnt(tp.get_c_name(' %s%s(void)' % (extra, funcname), name)) + prnt('{') + prnt(' return (%s%s);' % (ampersand, name)) + prnt('}') + prnt() + + def _generate_gen_constant_decl(self, tp, name): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + self._generate_gen_const(is_int, name, tp) + + _loading_gen_constant = _loaded_noop + + def _load_constant(self, is_int, tp, name, module, check_value=None): + funcname = '_cffi_const_%s' % name + if check_value is not None: + assert is_int + self._load_known_int_constant(module, funcname) + value = check_value + elif is_int: + BType = self.ffi._typeof_locked("long long*")[0] + BFunc = self.ffi._typeof_locked("int(*)(long long*)")[0] + function = module.load_function(BFunc, funcname) + p = self.ffi.new(BType) + negative = function(p) + value = int(p[0]) + if value < 0 and not negative: + BLongLong = self.ffi._typeof_locked("long long")[0] + value += (1 << (8*self.ffi.sizeof(BLongLong))) + else: + assert check_value is None + fntypeextra = '(*)(void)' + if isinstance(tp, model.StructOrUnion): + fntypeextra = '*' + fntypeextra + BFunc = self.ffi._typeof_locked(tp.get_c_name(fntypeextra, name))[0] + function = module.load_function(BFunc, funcname) + value = function() + if isinstance(tp, model.StructOrUnion): + value = value[0] + return value + + def _loaded_gen_constant(self, tp, name, module, library): + is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type() + value = self._load_constant(is_int, tp, name, module) + setattr(library, name, value) + type(library)._cffi_dir.append(name) + + # ---------- + # enums + + def _check_int_constant_value(self, name, value): + prnt = self._prnt + if value <= 0: + prnt(' if ((%s) > 0 || (long)(%s) != %dL) {' % ( + name, name, value)) + else: + prnt(' if ((%s) <= 0 || (unsigned long)(%s) != %dUL) {' % ( + name, name, value)) + prnt(' char buf[64];') + prnt(' if ((%s) <= 0)' % name) + prnt(' sprintf(buf, "%%ld", (long)(%s));' % name) + prnt(' else') + prnt(' sprintf(buf, "%%lu", (unsigned long)(%s));' % + name) + prnt(' sprintf(out_error, "%s has the real value %s, not %s",') + prnt(' "%s", buf, "%d");' % (name[:100], value)) + prnt(' return -1;') + prnt(' }') + + def _load_known_int_constant(self, module, funcname): + BType = self.ffi._typeof_locked("char[]")[0] + BFunc = self.ffi._typeof_locked("int(*)(char*)")[0] + function = module.load_function(BFunc, funcname) + p = self.ffi.new(BType, 256) + if function(p) < 0: + error = self.ffi.string(p) + if sys.version_info >= (3,): + error = str(error, 'utf-8') + raise VerificationError(error) + + def _enum_funcname(self, prefix, name): + # "$enum_$1" => "___D_enum____D_1" + name = name.replace('$', '___D_') + return '_cffi_e_%s_%s' % (prefix, name) + + def _generate_gen_enum_decl(self, tp, name, prefix='enum'): + if tp.partial: + for enumerator in tp.enumerators: + self._generate_gen_const(True, enumerator) + return + # + funcname = self._enum_funcname(prefix, name) + self.export_symbols.append(funcname) + prnt = self._prnt + prnt('int %s(char *out_error)' % funcname) + prnt('{') + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + self._check_int_constant_value(enumerator, enumvalue) + prnt(' return 0;') + prnt('}') + prnt() + + def _loading_gen_enum(self, tp, name, module, prefix='enum'): + if tp.partial: + enumvalues = [self._load_constant(True, tp, enumerator, module) + for enumerator in tp.enumerators] + tp.enumvalues = tuple(enumvalues) + tp.partial_resolved = True + else: + funcname = self._enum_funcname(prefix, name) + self._load_known_int_constant(module, funcname) + + def _loaded_gen_enum(self, tp, name, module, library): + for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues): + setattr(library, enumerator, enumvalue) + type(library)._cffi_dir.append(enumerator) + + # ---------- + # macros: for now only for integers + + def _generate_gen_macro_decl(self, tp, name): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + self._generate_gen_const(True, name, check_value=check_value) + + _loading_gen_macro = _loaded_noop + + def _loaded_gen_macro(self, tp, name, module, library): + if tp == '...': + check_value = None + else: + check_value = tp # an integer + value = self._load_constant(True, tp, name, module, + check_value=check_value) + setattr(library, name, value) + type(library)._cffi_dir.append(name) + + # ---------- + # global variables + + def _generate_gen_variable_decl(self, tp, name): + if isinstance(tp, model.ArrayType): + if tp.length_is_unknown(): + prnt = self._prnt + funcname = '_cffi_sizeof_%s' % (name,) + self.export_symbols.append(funcname) + prnt("size_t %s(void)" % funcname) + prnt("{") + prnt(" return sizeof(%s);" % (name,)) + prnt("}") + tp_ptr = model.PointerType(tp.item) + self._generate_gen_const(False, name, tp_ptr) + else: + tp_ptr = model.PointerType(tp) + self._generate_gen_const(False, name, tp_ptr, category='var') + + _loading_gen_variable = _loaded_noop + + def _loaded_gen_variable(self, tp, name, module, library): + if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the + # sense that "a=..." is forbidden + if tp.length_is_unknown(): + funcname = '_cffi_sizeof_%s' % (name,) + BFunc = self.ffi._typeof_locked('size_t(*)(void)')[0] + function = module.load_function(BFunc, funcname) + size = function() + BItemType = self.ffi._get_cached_btype(tp.item) + length, rest = divmod(size, self.ffi.sizeof(BItemType)) + if rest != 0: + raise VerificationError( + "bad size: %r does not seem to be an array of %s" % + (name, tp.item)) + tp = tp.resolve_length(length) + tp_ptr = model.PointerType(tp.item) + value = self._load_constant(False, tp_ptr, name, module) + # 'value' is a which we have to replace with + # a if the N is actually known + if tp.length is not None: + BArray = self.ffi._get_cached_btype(tp) + value = self.ffi.cast(BArray, value) + setattr(library, name, value) + type(library)._cffi_dir.append(name) + return + # remove ptr= from the library instance, and replace + # it by a property on the class, which reads/writes into ptr[0]. + funcname = '_cffi_var_%s' % name + BFunc = self.ffi._typeof_locked(tp.get_c_name('*(*)(void)', name))[0] + function = module.load_function(BFunc, funcname) + ptr = function() + def getter(library): + return ptr[0] + def setter(library, value): + ptr[0] = value + setattr(type(library), name, property(getter, setter)) + type(library)._cffi_dir.append(name) + +cffimod_header = r''' +#include +#include +#include +#include +#include /* XXX for ssize_t on some platforms */ + +/* this block of #ifs should be kept exactly identical between + c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py + and cffi/_cffi_include.h */ +#if defined(_MSC_VER) +# include /* for alloca() */ +# if _MSC_VER < 1600 /* MSVC < 2010 */ + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; + typedef __int8 int_least8_t; + typedef __int16 int_least16_t; + typedef __int32 int_least32_t; + typedef __int64 int_least64_t; + typedef unsigned __int8 uint_least8_t; + typedef unsigned __int16 uint_least16_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int64 uint_least64_t; + typedef __int8 int_fast8_t; + typedef __int16 int_fast16_t; + typedef __int32 int_fast32_t; + typedef __int64 int_fast64_t; + typedef unsigned __int8 uint_fast8_t; + typedef unsigned __int16 uint_fast16_t; + typedef unsigned __int32 uint_fast32_t; + typedef unsigned __int64 uint_fast64_t; + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; +# else +# include +# endif +# if _MSC_VER < 1800 /* MSVC < 2013 */ +# ifndef __cplusplus + typedef unsigned char _Bool; +# endif +# endif +#else +# include +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) +# include +# endif +#endif +''' diff --git a/dist/ba_data/python-site-packages/cffi/verifier.py b/dist/ba_data/python-site-packages/cffi/verifier.py new file mode 100644 index 0000000..a500c78 --- /dev/null +++ b/dist/ba_data/python-site-packages/cffi/verifier.py @@ -0,0 +1,307 @@ +# +# DEPRECATED: implementation for ffi.verify() +# +import sys, os, binascii, shutil, io +from . import __version_verifier_modules__ +from . import ffiplatform +from .error import VerificationError + +if sys.version_info >= (3, 3): + import importlib.machinery + def _extension_suffixes(): + return importlib.machinery.EXTENSION_SUFFIXES[:] +else: + import imp + def _extension_suffixes(): + return [suffix for suffix, _, type in imp.get_suffixes() + if type == imp.C_EXTENSION] + + +if sys.version_info >= (3,): + NativeIO = io.StringIO +else: + class NativeIO(io.BytesIO): + def write(self, s): + if isinstance(s, unicode): + s = s.encode('ascii') + super(NativeIO, self).write(s) + + +class Verifier(object): + + def __init__(self, ffi, preamble, tmpdir=None, modulename=None, + ext_package=None, tag='', force_generic_engine=False, + source_extension='.c', flags=None, relative_to=None, **kwds): + if ffi._parser._uses_new_feature: + raise VerificationError( + "feature not supported with ffi.verify(), but only " + "with ffi.set_source(): %s" % (ffi._parser._uses_new_feature,)) + self.ffi = ffi + self.preamble = preamble + if not modulename: + flattened_kwds = ffiplatform.flatten(kwds) + vengine_class = _locate_engine_class(ffi, force_generic_engine) + self._vengine = vengine_class(self) + self._vengine.patch_extension_kwds(kwds) + self.flags = flags + self.kwds = self.make_relative_to(kwds, relative_to) + # + if modulename: + if tag: + raise TypeError("can't specify both 'modulename' and 'tag'") + else: + key = '\x00'.join(['%d.%d' % sys.version_info[:2], + __version_verifier_modules__, + preamble, flattened_kwds] + + ffi._cdefsources) + if sys.version_info >= (3,): + key = key.encode('utf-8') + k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff) + k1 = k1.lstrip('0x').rstrip('L') + k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff) + k2 = k2.lstrip('0').rstrip('L') + modulename = '_cffi_%s_%s%s%s' % (tag, self._vengine._class_key, + k1, k2) + suffix = _get_so_suffixes()[0] + self.tmpdir = tmpdir or _caller_dir_pycache() + self.sourcefilename = os.path.join(self.tmpdir, modulename + source_extension) + self.modulefilename = os.path.join(self.tmpdir, modulename + suffix) + self.ext_package = ext_package + self._has_source = False + self._has_module = False + + def write_source(self, file=None): + """Write the C source code. It is produced in 'self.sourcefilename', + which can be tweaked beforehand.""" + with self.ffi._lock: + if self._has_source and file is None: + raise VerificationError( + "source code already written") + self._write_source(file) + + def compile_module(self): + """Write the C source code (if not done already) and compile it. + This produces a dynamic link library in 'self.modulefilename'.""" + with self.ffi._lock: + if self._has_module: + raise VerificationError("module already compiled") + if not self._has_source: + self._write_source() + self._compile_module() + + def load_library(self): + """Get a C module from this Verifier instance. + Returns an instance of a FFILibrary class that behaves like the + objects returned by ffi.dlopen(), but that delegates all + operations to the C module. If necessary, the C code is written + and compiled first. + """ + with self.ffi._lock: + if not self._has_module: + self._locate_module() + if not self._has_module: + if not self._has_source: + self._write_source() + self._compile_module() + return self._load_library() + + def get_module_name(self): + basename = os.path.basename(self.modulefilename) + # kill both the .so extension and the other .'s, as introduced + # by Python 3: 'basename.cpython-33m.so' + basename = basename.split('.', 1)[0] + # and the _d added in Python 2 debug builds --- but try to be + # conservative and not kill a legitimate _d + if basename.endswith('_d') and hasattr(sys, 'gettotalrefcount'): + basename = basename[:-2] + return basename + + def get_extension(self): + ffiplatform._hack_at_distutils() # backward compatibility hack + if not self._has_source: + with self.ffi._lock: + if not self._has_source: + self._write_source() + sourcename = ffiplatform.maybe_relative_path(self.sourcefilename) + modname = self.get_module_name() + return ffiplatform.get_extension(sourcename, modname, **self.kwds) + + def generates_python_module(self): + return self._vengine._gen_python_module + + def make_relative_to(self, kwds, relative_to): + if relative_to and os.path.dirname(relative_to): + dirname = os.path.dirname(relative_to) + kwds = kwds.copy() + for key in ffiplatform.LIST_OF_FILE_NAMES: + if key in kwds: + lst = kwds[key] + if not isinstance(lst, (list, tuple)): + raise TypeError("keyword '%s' should be a list or tuple" + % (key,)) + lst = [os.path.join(dirname, fn) for fn in lst] + kwds[key] = lst + return kwds + + # ---------- + + def _locate_module(self): + if not os.path.isfile(self.modulefilename): + if self.ext_package: + try: + pkg = __import__(self.ext_package, None, None, ['__doc__']) + except ImportError: + return # cannot import the package itself, give up + # (e.g. it might be called differently before installation) + path = pkg.__path__ + else: + path = None + filename = self._vengine.find_module(self.get_module_name(), path, + _get_so_suffixes()) + if filename is None: + return + self.modulefilename = filename + self._vengine.collect_types() + self._has_module = True + + def _write_source_to(self, file): + self._vengine._f = file + try: + self._vengine.write_source_to_f() + finally: + del self._vengine._f + + def _write_source(self, file=None): + if file is not None: + self._write_source_to(file) + else: + # Write our source file to an in memory file. + f = NativeIO() + self._write_source_to(f) + source_data = f.getvalue() + + # Determine if this matches the current file + if os.path.exists(self.sourcefilename): + with open(self.sourcefilename, "r") as fp: + needs_written = not (fp.read() == source_data) + else: + needs_written = True + + # Actually write the file out if it doesn't match + if needs_written: + _ensure_dir(self.sourcefilename) + with open(self.sourcefilename, "w") as fp: + fp.write(source_data) + + # Set this flag + self._has_source = True + + def _compile_module(self): + # compile this C source + tmpdir = os.path.dirname(self.sourcefilename) + outputfilename = ffiplatform.compile(tmpdir, self.get_extension()) + try: + same = ffiplatform.samefile(outputfilename, self.modulefilename) + except OSError: + same = False + if not same: + _ensure_dir(self.modulefilename) + shutil.move(outputfilename, self.modulefilename) + self._has_module = True + + def _load_library(self): + assert self._has_module + if self.flags is not None: + return self._vengine.load_library(self.flags) + else: + return self._vengine.load_library() + +# ____________________________________________________________ + +_FORCE_GENERIC_ENGINE = False # for tests + +def _locate_engine_class(ffi, force_generic_engine): + if _FORCE_GENERIC_ENGINE: + force_generic_engine = True + if not force_generic_engine: + if '__pypy__' in sys.builtin_module_names: + force_generic_engine = True + else: + try: + import _cffi_backend + except ImportError: + _cffi_backend = '?' + if ffi._backend is not _cffi_backend: + force_generic_engine = True + if force_generic_engine: + from . import vengine_gen + return vengine_gen.VGenericEngine + else: + from . import vengine_cpy + return vengine_cpy.VCPythonEngine + +# ____________________________________________________________ + +_TMPDIR = None + +def _caller_dir_pycache(): + if _TMPDIR: + return _TMPDIR + result = os.environ.get('CFFI_TMPDIR') + if result: + return result + filename = sys._getframe(2).f_code.co_filename + return os.path.abspath(os.path.join(os.path.dirname(filename), + '__pycache__')) + +def set_tmpdir(dirname): + """Set the temporary directory to use instead of __pycache__.""" + global _TMPDIR + _TMPDIR = dirname + +def cleanup_tmpdir(tmpdir=None, keep_so=False): + """Clean up the temporary directory by removing all files in it + called `_cffi_*.{c,so}` as well as the `build` subdirectory.""" + tmpdir = tmpdir or _caller_dir_pycache() + try: + filelist = os.listdir(tmpdir) + except OSError: + return + if keep_so: + suffix = '.c' # only remove .c files + else: + suffix = _get_so_suffixes()[0].lower() + for fn in filelist: + if fn.lower().startswith('_cffi_') and ( + fn.lower().endswith(suffix) or fn.lower().endswith('.c')): + try: + os.unlink(os.path.join(tmpdir, fn)) + except OSError: + pass + clean_dir = [os.path.join(tmpdir, 'build')] + for dir in clean_dir: + try: + for fn in os.listdir(dir): + fn = os.path.join(dir, fn) + if os.path.isdir(fn): + clean_dir.append(fn) + else: + os.unlink(fn) + except OSError: + pass + +def _get_so_suffixes(): + suffixes = _extension_suffixes() + if not suffixes: + # bah, no C_EXTENSION available. Occurs on pypy without cpyext + if sys.platform == 'win32': + suffixes = [".pyd"] + else: + suffixes = [".so"] + + return suffixes + +def _ensure_dir(filename): + dirname = os.path.dirname(filename) + if dirname and not os.path.isdir(dirname): + os.makedirs(dirname) diff --git a/dist/ba_data/python-site-packages/chardet/__init__.py b/dist/ba_data/python-site-packages/chardet/__init__.py new file mode 100644 index 0000000..80ad254 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/__init__.py @@ -0,0 +1,83 @@ +######################## BEGIN LICENSE BLOCK ######################## +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +from .universaldetector import UniversalDetector +from .enums import InputState +from .version import __version__, VERSION + + +__all__ = ['UniversalDetector', 'detect', 'detect_all', '__version__', 'VERSION'] + + +def detect(byte_str): + """ + Detect the encoding of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + detector = UniversalDetector() + detector.feed(byte_str) + return detector.close() + + +def detect_all(byte_str): + """ + Detect all the possible encodings of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + + detector = UniversalDetector() + detector.feed(byte_str) + detector.close() + + if detector._input_state == InputState.HIGH_BYTE: + results = [] + for prober in detector._charset_probers: + if prober.get_confidence() > detector.MINIMUM_THRESHOLD: + charset_name = prober.charset_name + lower_charset_name = prober.charset_name.lower() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if detector._has_win_bytes: + charset_name = detector.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + results.append({ + 'encoding': charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language, + }) + if len(results) > 0: + return sorted(results, key=lambda result: -result['confidence']) + + return [detector.result] diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d45604c Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/big5freq.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/big5freq.cpython-310.opt-1.pyc new file mode 100644 index 0000000..25fea8c Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/big5freq.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/big5prober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/big5prober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..556327b Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/big5prober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/chardistribution.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/chardistribution.cpython-310.opt-1.pyc new file mode 100644 index 0000000..0e34ae4 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/chardistribution.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/charsetgroupprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/charsetgroupprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..b2feae6 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/charsetgroupprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/charsetprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/charsetprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..826f724 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/charsetprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/codingstatemachine.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/codingstatemachine.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8aade1f Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/codingstatemachine.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/cp949prober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/cp949prober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..80b4bb7 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/cp949prober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/enums.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/enums.cpython-310.opt-1.pyc new file mode 100644 index 0000000..4e6cb03 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/enums.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/escprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/escprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..634d8ef Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/escprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/escsm.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/escsm.cpython-310.opt-1.pyc new file mode 100644 index 0000000..be63cad Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/escsm.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/eucjpprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/eucjpprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..60e55f0 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/eucjpprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/euckrfreq.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/euckrfreq.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9719a58 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/euckrfreq.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/euckrprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/euckrprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..a09545f Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/euckrprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/euctwfreq.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/euctwfreq.cpython-310.opt-1.pyc new file mode 100644 index 0000000..82af186 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/euctwfreq.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/euctwprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/euctwprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..5332160 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/euctwprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/gb2312freq.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/gb2312freq.cpython-310.opt-1.pyc new file mode 100644 index 0000000..82f8d9e Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/gb2312freq.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/gb2312prober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/gb2312prober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..76326cf Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/gb2312prober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/hebrewprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/hebrewprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..db151da Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/hebrewprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/jisfreq.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/jisfreq.cpython-310.opt-1.pyc new file mode 100644 index 0000000..5f09ee5 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/jisfreq.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/jpcntx.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/jpcntx.cpython-310.opt-1.pyc new file mode 100644 index 0000000..564a5d7 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/jpcntx.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/langbulgarianmodel.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/langbulgarianmodel.cpython-310.opt-1.pyc new file mode 100644 index 0000000..642a602 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/langbulgarianmodel.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/langgreekmodel.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/langgreekmodel.cpython-310.opt-1.pyc new file mode 100644 index 0000000..c12268e Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/langgreekmodel.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/langhebrewmodel.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/langhebrewmodel.cpython-310.opt-1.pyc new file mode 100644 index 0000000..03d98a5 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/langhebrewmodel.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/langrussianmodel.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/langrussianmodel.cpython-310.opt-1.pyc new file mode 100644 index 0000000..44506b1 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/langrussianmodel.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/langthaimodel.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/langthaimodel.cpython-310.opt-1.pyc new file mode 100644 index 0000000..bf30a65 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/langthaimodel.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/langturkishmodel.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/langturkishmodel.cpython-310.opt-1.pyc new file mode 100644 index 0000000..3e8e645 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/langturkishmodel.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/latin1prober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/latin1prober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..52be0e0 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/latin1prober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/mbcharsetprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/mbcharsetprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d2a5551 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/mbcharsetprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/mbcsgroupprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/mbcsgroupprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..3cd7a12 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/mbcsgroupprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/mbcssm.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/mbcssm.cpython-310.opt-1.pyc new file mode 100644 index 0000000..2bfbdf9 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/mbcssm.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/sbcharsetprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/sbcharsetprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d02bf4d Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/sbcharsetprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/sbcsgroupprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/sbcsgroupprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..728f207 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/sbcsgroupprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/sjisprober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/sjisprober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..34f98d5 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/sjisprober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/universaldetector.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/universaldetector.cpython-310.opt-1.pyc new file mode 100644 index 0000000..689bcc7 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/universaldetector.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/utf8prober.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/utf8prober.cpython-310.opt-1.pyc new file mode 100644 index 0000000..986af37 Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/utf8prober.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/__pycache__/version.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/chardet/__pycache__/version.cpython-310.opt-1.pyc new file mode 100644 index 0000000..b3b7ecf Binary files /dev/null and b/dist/ba_data/python-site-packages/chardet/__pycache__/version.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/chardet/big5freq.py b/dist/ba_data/python-site-packages/chardet/big5freq.py new file mode 100644 index 0000000..38f3251 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/big5freq.py @@ -0,0 +1,386 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Big5 frequency table +# by Taiwan's Mandarin Promotion Council +# +# +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +#Char to FreqOrder table +BIG5_TABLE_SIZE = 5376 + +BIG5_CHAR_TO_FREQ_ORDER = ( + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 +3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 +1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 +3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 +4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 +5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 +2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 +1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 +3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 +3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 +2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 +3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 +1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 +5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 +5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 +1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 +3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 +3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 +2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 +2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 +3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 +1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 +1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 +1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 +2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 +4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 +1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 +5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 +2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 +5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 +1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 +5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 +1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 +3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 +4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 +3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 +1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 +4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 +3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 +3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 +2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 +5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 +3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 +5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 +1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 +2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 +1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 +1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 +4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 +3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 +2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 +5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 +1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 +2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 +1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 +1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 +5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 +5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 +5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 +3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 +4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 +4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 +2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 +5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 +3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 +5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 +5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 +1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 +2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 +3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 +4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 +5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 +3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 +4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 +1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 +1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 +4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 +1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 +1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 +1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 +3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 +5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 +2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 +1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 +1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 +5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 +4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 +2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 +1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 +1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 +4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 +4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 +1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 +3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 +5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 +5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 +1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 +2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 +1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 +3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 +2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 +3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 +2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 +4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 +4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 +3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 +3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 +3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 +4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 +3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 +1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 +5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 +5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 +1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 +4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 +4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 +2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 +2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 +3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 +1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 +4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 +2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 +1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 +1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 +2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 +3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 +1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 +5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 +1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 +4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 +1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 +1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 +4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 +4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 +2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 +1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 +4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 +5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 +2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 +3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 +4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 +5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 +5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 +1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 +4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 +4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 +2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 +3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 +3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 +2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 +1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 +4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 +3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 +3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 +2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 +4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 +5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 +3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 +2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 +3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 +1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 +2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 +3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 +4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 +2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 +2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 +5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 +1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 +2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 +1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 +3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 +4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 +2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 +3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 +3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 +2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 +4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 +2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 +3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 +4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 +5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 +3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 +1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 +4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 +1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 +4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 +5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 +5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 +5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 +2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 +3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 +2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 +2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 +1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 +4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 +3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 +3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 +2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 +2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 +4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 +1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 +4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 +1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 +3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 +3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 +5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 +5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 +3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 +3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 +1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 +2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 +5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 +1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 +1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 +3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 +1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 +4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 +5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 +2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 +3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 +1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 +2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 +2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 +5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 +5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 +5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 +2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 +2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 +1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 +4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 +3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 +3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 +4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 +4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 +2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 +2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 +5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 +4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 +5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 +4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 +1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 +3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 +4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 +1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 +5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 +2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 +2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 +3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 +5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 +1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 +3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 +5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 +1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 +5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 +2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 +3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 +2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 +3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 +3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 +3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 +4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 +2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 +4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 +3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 +5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 +1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 +5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 +1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 +4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 +1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 +4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 +1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 +3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 +4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 +5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 +3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 +2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 +) + diff --git a/dist/ba_data/python-site-packages/chardet/big5prober.py b/dist/ba_data/python-site-packages/chardet/big5prober.py new file mode 100644 index 0000000..98f9970 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/big5prober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import Big5DistributionAnalysis +from .mbcssm import BIG5_SM_MODEL + + +class Big5Prober(MultiByteCharSetProber): + def __init__(self): + super(Big5Prober, self).__init__() + self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) + self.distribution_analyzer = Big5DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "Big5" + + @property + def language(self): + return "Chinese" diff --git a/dist/ba_data/python-site-packages/chardet/chardistribution.py b/dist/ba_data/python-site-packages/chardet/chardistribution.py new file mode 100644 index 0000000..c0395f4 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/chardistribution.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, + EUCTW_TYPICAL_DISTRIBUTION_RATIO) +from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, + EUCKR_TYPICAL_DISTRIBUTION_RATIO) +from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, + GB2312_TYPICAL_DISTRIBUTION_RATIO) +from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, + BIG5_TYPICAL_DISTRIBUTION_RATIO) +from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, + JIS_TYPICAL_DISTRIBUTION_RATIO) + + +class CharDistributionAnalysis(object): + ENOUGH_DATA_THRESHOLD = 1024 + SURE_YES = 0.99 + SURE_NO = 0.01 + MINIMUM_DATA_THRESHOLD = 3 + + def __init__(self): + # Mapping table to get frequency order from char order (get from + # GetOrder()) + self._char_to_freq_order = None + self._table_size = None # Size of above table + # This is a constant value which varies from language to language, + # used in calculating confidence. See + # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html + # for further detail. + self.typical_distribution_ratio = None + self._done = None + self._total_chars = None + self._freq_chars = None + self.reset() + + def reset(self): + """reset analyser, clear any state""" + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + self._total_chars = 0 # Total characters encountered + # The number of characters whose frequency order is less than 512 + self._freq_chars = 0 + + def feed(self, char, char_len): + """feed a character with known length""" + if char_len == 2: + # we only care about 2-bytes character in our distribution analysis + order = self.get_order(char) + else: + order = -1 + if order >= 0: + self._total_chars += 1 + # order is valid + if order < self._table_size: + if 512 > self._char_to_freq_order[order]: + self._freq_chars += 1 + + def get_confidence(self): + """return confidence based on existing data""" + # if we didn't receive any character in our consideration range, + # return negative answer + if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: + return self.SURE_NO + + if self._total_chars != self._freq_chars: + r = (self._freq_chars / ((self._total_chars - self._freq_chars) + * self.typical_distribution_ratio)) + if r < self.SURE_YES: + return r + + # normalize confidence (we don't want to be 100% sure) + return self.SURE_YES + + def got_enough_data(self): + # It is not necessary to receive all data to draw conclusion. + # For charset detection, certain amount of data is enough + return self._total_chars > self.ENOUGH_DATA_THRESHOLD + + def get_order(self, byte_str): + # We do not handle characters based on the original encoding string, + # but convert this encoding string to a number, here called order. + # This allows multiple encodings of a language to share one frequency + # table. + return -1 + + +class EUCTWDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCTWDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER + self._table_size = EUCTW_TABLE_SIZE + self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-TW encoding, we are interested + # first byte range: 0xc4 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xC4: + return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 + else: + return -1 + + +class EUCKRDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCKRDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER + self._table_size = EUCKR_TABLE_SIZE + self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-KR encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xB0: + return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 + else: + return -1 + + +class GB2312DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(GB2312DistributionAnalysis, self).__init__() + self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER + self._table_size = GB2312_TABLE_SIZE + self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for GB2312 encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0xB0) and (second_char >= 0xA1): + return 94 * (first_char - 0xB0) + second_char - 0xA1 + else: + return -1 + + +class Big5DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(Big5DistributionAnalysis, self).__init__() + self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER + self._table_size = BIG5_TABLE_SIZE + self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for big5 encoding, we are interested + # first byte range: 0xa4 -- 0xfe + # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if first_char >= 0xA4: + if second_char >= 0xA1: + return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 + else: + return 157 * (first_char - 0xA4) + second_char - 0x40 + else: + return -1 + + +class SJISDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(SJISDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for sjis encoding, we are interested + # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0x81) and (first_char <= 0x9F): + order = 188 * (first_char - 0x81) + elif (first_char >= 0xE0) and (first_char <= 0xEF): + order = 188 * (first_char - 0xE0 + 31) + else: + return -1 + order = order + second_char - 0x40 + if second_char > 0x7F: + order = -1 + return order + + +class EUCJPDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCJPDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-JP encoding, we are interested + # first byte range: 0xa0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + char = byte_str[0] + if char >= 0xA0: + return 94 * (char - 0xA1) + byte_str[1] - 0xa1 + else: + return -1 diff --git a/dist/ba_data/python-site-packages/chardet/charsetgroupprober.py b/dist/ba_data/python-site-packages/chardet/charsetgroupprober.py new file mode 100644 index 0000000..5812cef --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/charsetgroupprober.py @@ -0,0 +1,107 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState +from .charsetprober import CharSetProber + + +class CharSetGroupProber(CharSetProber): + def __init__(self, lang_filter=None): + super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) + self._active_num = 0 + self.probers = [] + self._best_guess_prober = None + + def reset(self): + super(CharSetGroupProber, self).reset() + self._active_num = 0 + for prober in self.probers: + if prober: + prober.reset() + prober.active = True + self._active_num += 1 + self._best_guess_prober = None + + @property + def charset_name(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.charset_name + + @property + def language(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.language + + def feed(self, byte_str): + for prober in self.probers: + if not prober: + continue + if not prober.active: + continue + state = prober.feed(byte_str) + if not state: + continue + if state == ProbingState.FOUND_IT: + self._best_guess_prober = prober + self._state = ProbingState.FOUND_IT + return self.state + elif state == ProbingState.NOT_ME: + prober.active = False + self._active_num -= 1 + if self._active_num <= 0: + self._state = ProbingState.NOT_ME + return self.state + return self.state + + def get_confidence(self): + state = self.state + if state == ProbingState.FOUND_IT: + return 0.99 + elif state == ProbingState.NOT_ME: + return 0.01 + best_conf = 0.0 + self._best_guess_prober = None + for prober in self.probers: + if not prober: + continue + if not prober.active: + self.logger.debug('%s not active', prober.charset_name) + continue + conf = prober.get_confidence() + self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) + if best_conf < conf: + best_conf = conf + self._best_guess_prober = prober + if not self._best_guess_prober: + return 0.0 + return best_conf diff --git a/dist/ba_data/python-site-packages/chardet/charsetprober.py b/dist/ba_data/python-site-packages/chardet/charsetprober.py new file mode 100644 index 0000000..eac4e59 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/charsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging +import re + +from .enums import ProbingState + + +class CharSetProber(object): + + SHORTCUT_THRESHOLD = 0.95 + + def __init__(self, lang_filter=None): + self._state = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + + def reset(self): + self._state = ProbingState.DETECTING + + @property + def charset_name(self): + return None + + def feed(self, buf): + pass + + @property + def state(self): + return self._state + + def get_confidence(self): + return 0.0 + + @staticmethod + def filter_high_byte_only(buf): + buf = re.sub(b'([\x00-\x7F])+', b' ', buf) + return buf + + @staticmethod + def filter_international_words(buf): + """ + We define three types of bytes: + alphabet: english alphabets [a-zA-Z] + international: international characters [\x80-\xFF] + marker: everything else [^a-zA-Z\x80-\xFF] + + The input buffer can be thought to contain a series of words delimited + by markers. This function works to filter all words that contain at + least one international character. All contiguous sequences of markers + are replaced by a single space ascii character. + + This filter applies to all scripts which do not use English characters. + """ + filtered = bytearray() + + # This regex expression filters out only words that have at-least one + # international character. The word may include one marker character at + # the end. + words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', + buf) + + for word in words: + filtered.extend(word[:-1]) + + # If the last character in the word is a marker, replace it with a + # space as markers shouldn't affect our analysis (they are used + # similarly across all languages and may thus have similar + # frequencies). + last_char = word[-1:] + if not last_char.isalpha() and last_char < b'\x80': + last_char = b' ' + filtered.extend(last_char) + + return filtered + + @staticmethod + def filter_with_english_letters(buf): + """ + Returns a copy of ``buf`` that retains only the sequences of English + alphabet and high byte characters that are not between <> characters. + Also retains English alphabet and high byte characters immediately + before occurrences of >. + + This filter can be applied to all scripts which contain both English + characters and extended ASCII characters, but is currently only used by + ``Latin1Prober``. + """ + filtered = bytearray() + in_tag = False + prev = 0 + + for curr in range(len(buf)): + # Slice here to get bytes instead of an int with Python 3 + buf_char = buf[curr:curr + 1] + # Check if we're coming out of or entering an HTML tag + if buf_char == b'>': + in_tag = False + elif buf_char == b'<': + in_tag = True + + # If current character is not extended-ASCII and not alphabetic... + if buf_char < b'\x80' and not buf_char.isalpha(): + # ...and we're not in a tag + if curr > prev and not in_tag: + # Keep everything after last non-extended-ASCII, + # non-alphabetic character + filtered.extend(buf[prev:curr]) + # Output a space to delimit stretch we kept + filtered.extend(b' ') + prev = curr + 1 + + # If we're not in a tag... + if not in_tag: + # Keep everything after last non-extended-ASCII, non-alphabetic + # character + filtered.extend(buf[prev:]) + + return filtered diff --git a/dist/ba_data/python-site-packages/chardet/cli/__init__.py b/dist/ba_data/python-site-packages/chardet/cli/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/cli/__init__.py @@ -0,0 +1 @@ + diff --git a/dist/ba_data/python-site-packages/chardet/cli/chardetect.py b/dist/ba_data/python-site-packages/chardet/cli/chardetect.py new file mode 100644 index 0000000..e1d8cd6 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/cli/chardetect.py @@ -0,0 +1,84 @@ +""" +Script which takes one or more file paths and reports on their detected +encodings + +Example:: + + % chardetect somefile someotherfile + somefile: windows-1252 with confidence 0.5 + someotherfile: ascii with confidence 1.0 + +If no paths are provided, it takes its input from stdin. + +""" + +from __future__ import absolute_import, print_function, unicode_literals + +import argparse +import sys + +from chardet import __version__ +from chardet.compat import PY2 +from chardet.universaldetector import UniversalDetector + + +def description_of(lines, name='stdin'): + """ + Return a string describing the probable encoding of a file or + list of strings. + + :param lines: The lines to get the encoding of. + :type lines: Iterable of bytes + :param name: Name of file or collection of lines + :type name: str + """ + u = UniversalDetector() + for line in lines: + line = bytearray(line) + u.feed(line) + # shortcut out of the loop to save reading further - particularly useful if we read a BOM. + if u.done: + break + u.close() + result = u.result + if PY2: + name = name.decode(sys.getfilesystemencoding(), 'ignore') + if result['encoding']: + return '{}: {} with confidence {}'.format(name, result['encoding'], + result['confidence']) + else: + return '{}: no result'.format(name) + + +def main(argv=None): + """ + Handles command line arguments and gets things started. + + :param argv: List of arguments, as if specified on the command-line. + If None, ``sys.argv[1:]`` is used instead. + :type argv: list of str + """ + # Get command line arguments + parser = argparse.ArgumentParser( + description="Takes one or more file paths and reports their detected \ + encodings") + parser.add_argument('input', + help='File whose encoding we would like to determine. \ + (default: stdin)', + type=argparse.FileType('rb'), nargs='*', + default=[sys.stdin if PY2 else sys.stdin.buffer]) + parser.add_argument('--version', action='version', + version='%(prog)s {}'.format(__version__)) + args = parser.parse_args(argv) + + for f in args.input: + if f.isatty(): + print("You are running chardetect interactively. Press " + + "CTRL-D twice at the start of a blank line to signal the " + + "end of your input. If you want help, run chardetect " + + "--help\n", file=sys.stderr) + print(description_of(f, f.name)) + + +if __name__ == '__main__': + main() diff --git a/dist/ba_data/python-site-packages/chardet/codingstatemachine.py b/dist/ba_data/python-site-packages/chardet/codingstatemachine.py new file mode 100644 index 0000000..68fba44 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/codingstatemachine.py @@ -0,0 +1,88 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging + +from .enums import MachineState + + +class CodingStateMachine(object): + """ + A state machine to verify a byte sequence for a particular encoding. For + each byte the detector receives, it will feed that byte to every active + state machine available, one byte at a time. The state machine changes its + state based on its previous state and the byte it receives. There are 3 + states in a state machine that are of interest to an auto-detector: + + START state: This is the state to start with, or a legal byte sequence + (i.e. a valid code point) for character has been identified. + + ME state: This indicates that the state machine identified a byte sequence + that is specific to the charset it is designed for and that + there is no other possible encoding which can contain this byte + sequence. This will to lead to an immediate positive answer for + the detector. + + ERROR state: This indicates the state machine identified an illegal byte + sequence for that encoding. This will lead to an immediate + negative answer for this encoding. Detector will exclude this + encoding from consideration from here on. + """ + def __init__(self, sm): + self._model = sm + self._curr_byte_pos = 0 + self._curr_char_len = 0 + self._curr_state = None + self.logger = logging.getLogger(__name__) + self.reset() + + def reset(self): + self._curr_state = MachineState.START + + def next_state(self, c): + # for each byte we get its class + # if it is first byte, we also get byte length + byte_class = self._model['class_table'][c] + if self._curr_state == MachineState.START: + self._curr_byte_pos = 0 + self._curr_char_len = self._model['char_len_table'][byte_class] + # from byte's class and state_table, we get its next state + curr_state = (self._curr_state * self._model['class_factor'] + + byte_class) + self._curr_state = self._model['state_table'][curr_state] + self._curr_byte_pos += 1 + return self._curr_state + + def get_current_charlen(self): + return self._curr_char_len + + def get_coding_state_machine(self): + return self._model['name'] + + @property + def language(self): + return self._model['language'] diff --git a/dist/ba_data/python-site-packages/chardet/compat.py b/dist/ba_data/python-site-packages/chardet/compat.py new file mode 100644 index 0000000..8941572 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/compat.py @@ -0,0 +1,36 @@ +######################## BEGIN LICENSE BLOCK ######################## +# Contributor(s): +# Dan Blanchard +# Ian Cordasco +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import sys + + +if sys.version_info < (3, 0): + PY2 = True + PY3 = False + string_types = (str, unicode) + text_type = unicode + iteritems = dict.iteritems +else: + PY2 = False + PY3 = True + string_types = (bytes, str) + text_type = str + iteritems = dict.items diff --git a/dist/ba_data/python-site-packages/chardet/cp949prober.py b/dist/ba_data/python-site-packages/chardet/cp949prober.py new file mode 100644 index 0000000..efd793a --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/cp949prober.py @@ -0,0 +1,49 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .chardistribution import EUCKRDistributionAnalysis +from .codingstatemachine import CodingStateMachine +from .mbcharsetprober import MultiByteCharSetProber +from .mbcssm import CP949_SM_MODEL + + +class CP949Prober(MultiByteCharSetProber): + def __init__(self): + super(CP949Prober, self).__init__() + self.coding_sm = CodingStateMachine(CP949_SM_MODEL) + # NOTE: CP949 is a superset of EUC-KR, so the distribution should be + # not different. + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "CP949" + + @property + def language(self): + return "Korean" diff --git a/dist/ba_data/python-site-packages/chardet/enums.py b/dist/ba_data/python-site-packages/chardet/enums.py new file mode 100644 index 0000000..0451207 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/enums.py @@ -0,0 +1,76 @@ +""" +All of the Enums that are used throughout the chardet package. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + + +class InputState(object): + """ + This enum represents the different states a universal detector can be in. + """ + PURE_ASCII = 0 + ESC_ASCII = 1 + HIGH_BYTE = 2 + + +class LanguageFilter(object): + """ + This enum represents the different language filters we can apply to a + ``UniversalDetector``. + """ + CHINESE_SIMPLIFIED = 0x01 + CHINESE_TRADITIONAL = 0x02 + JAPANESE = 0x04 + KOREAN = 0x08 + NON_CJK = 0x10 + ALL = 0x1F + CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL + CJK = CHINESE | JAPANESE | KOREAN + + +class ProbingState(object): + """ + This enum represents the different states a prober can be in. + """ + DETECTING = 0 + FOUND_IT = 1 + NOT_ME = 2 + + +class MachineState(object): + """ + This enum represents the different states a state machine can be in. + """ + START = 0 + ERROR = 1 + ITS_ME = 2 + + +class SequenceLikelihood(object): + """ + This enum represents the likelihood of a character following the previous one. + """ + NEGATIVE = 0 + UNLIKELY = 1 + LIKELY = 2 + POSITIVE = 3 + + @classmethod + def get_num_categories(cls): + """:returns: The number of likelihood categories in the enum.""" + return 4 + + +class CharacterCategory(object): + """ + This enum represents the different categories language models for + ``SingleByteCharsetProber`` put characters into. + + Anything less than CONTROL is considered a letter. + """ + UNDEFINED = 255 + LINE_BREAK = 254 + SYMBOL = 253 + DIGIT = 252 + CONTROL = 251 diff --git a/dist/ba_data/python-site-packages/chardet/escprober.py b/dist/ba_data/python-site-packages/chardet/escprober.py new file mode 100644 index 0000000..c70493f --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/escprober.py @@ -0,0 +1,101 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .codingstatemachine import CodingStateMachine +from .enums import LanguageFilter, ProbingState, MachineState +from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, + ISO2022KR_SM_MODEL) + + +class EscCharSetProber(CharSetProber): + """ + This CharSetProber uses a "code scheme" approach for detecting encodings, + whereby easily recognizable escape or shift sequences are relied on to + identify these encodings. + """ + + def __init__(self, lang_filter=None): + super(EscCharSetProber, self).__init__(lang_filter=lang_filter) + self.coding_sm = [] + if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: + self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) + self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) + if self.lang_filter & LanguageFilter.JAPANESE: + self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) + if self.lang_filter & LanguageFilter.KOREAN: + self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) + self.active_sm_count = None + self._detected_charset = None + self._detected_language = None + self._state = None + self.reset() + + def reset(self): + super(EscCharSetProber, self).reset() + for coding_sm in self.coding_sm: + if not coding_sm: + continue + coding_sm.active = True + coding_sm.reset() + self.active_sm_count = len(self.coding_sm) + self._detected_charset = None + self._detected_language = None + + @property + def charset_name(self): + return self._detected_charset + + @property + def language(self): + return self._detected_language + + def get_confidence(self): + if self._detected_charset: + return 0.99 + else: + return 0.00 + + def feed(self, byte_str): + for c in byte_str: + for coding_sm in self.coding_sm: + if not coding_sm or not coding_sm.active: + continue + coding_state = coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + coding_sm.active = False + self.active_sm_count -= 1 + if self.active_sm_count <= 0: + self._state = ProbingState.NOT_ME + return self.state + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + self._detected_charset = coding_sm.get_coding_state_machine() + self._detected_language = coding_sm.language + return self.state + + return self.state diff --git a/dist/ba_data/python-site-packages/chardet/escsm.py b/dist/ba_data/python-site-packages/chardet/escsm.py new file mode 100644 index 0000000..0069523 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/escsm.py @@ -0,0 +1,246 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +HZ_CLS = ( +1,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,0,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,4,0,5,2,0, # 78 - 7f +1,1,1,1,1,1,1,1, # 80 - 87 +1,1,1,1,1,1,1,1, # 88 - 8f +1,1,1,1,1,1,1,1, # 90 - 97 +1,1,1,1,1,1,1,1, # 98 - 9f +1,1,1,1,1,1,1,1, # a0 - a7 +1,1,1,1,1,1,1,1, # a8 - af +1,1,1,1,1,1,1,1, # b0 - b7 +1,1,1,1,1,1,1,1, # b8 - bf +1,1,1,1,1,1,1,1, # c0 - c7 +1,1,1,1,1,1,1,1, # c8 - cf +1,1,1,1,1,1,1,1, # d0 - d7 +1,1,1,1,1,1,1,1, # d8 - df +1,1,1,1,1,1,1,1, # e0 - e7 +1,1,1,1,1,1,1,1, # e8 - ef +1,1,1,1,1,1,1,1, # f0 - f7 +1,1,1,1,1,1,1,1, # f8 - ff +) + +HZ_ST = ( +MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 + 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f + 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 + 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f +) + +HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +HZ_SM_MODEL = {'class_table': HZ_CLS, + 'class_factor': 6, + 'state_table': HZ_ST, + 'char_len_table': HZ_CHAR_LEN_TABLE, + 'name': "HZ-GB-2312", + 'language': 'Chinese'} + +ISO2022CN_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,3,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,4,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022CN_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 + 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f +) + +ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, + 'class_factor': 9, + 'state_table': ISO2022CN_ST, + 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, + 'name': "ISO-2022-CN", + 'language': 'Chinese'} + +ISO2022JP_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,2,2, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,7,0,0,0, # 20 - 27 +3,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +6,0,4,0,8,0,0,0, # 40 - 47 +0,9,5,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022JP_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 +) + +ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, + 'class_factor': 10, + 'state_table': ISO2022JP_ST, + 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, + 'name': "ISO-2022-JP", + 'language': 'Japanese'} + +ISO2022KR_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,3,0,0,0, # 20 - 27 +0,4,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,5,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022KR_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 +) + +ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, + 'class_factor': 6, + 'state_table': ISO2022KR_ST, + 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, + 'name': "ISO-2022-KR", + 'language': 'Korean'} + + diff --git a/dist/ba_data/python-site-packages/chardet/eucjpprober.py b/dist/ba_data/python-site-packages/chardet/eucjpprober.py new file mode 100644 index 0000000..20ce8f7 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/eucjpprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState, MachineState +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCJPDistributionAnalysis +from .jpcntx import EUCJPContextAnalysis +from .mbcssm import EUCJP_SM_MODEL + + +class EUCJPProber(MultiByteCharSetProber): + def __init__(self): + super(EUCJPProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) + self.distribution_analyzer = EUCJPDistributionAnalysis() + self.context_analyzer = EUCJPContextAnalysis() + self.reset() + + def reset(self): + super(EUCJPProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return "EUC-JP" + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char, char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/dist/ba_data/python-site-packages/chardet/euckrfreq.py b/dist/ba_data/python-site-packages/chardet/euckrfreq.py new file mode 100644 index 0000000..b68078c --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/euckrfreq.py @@ -0,0 +1,195 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology + +# 128 --> 0.79 +# 256 --> 0.92 +# 512 --> 0.986 +# 1024 --> 0.99944 +# 2048 --> 0.99999 +# +# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 +# Random Distribution Ration = 512 / (2350-512) = 0.279. +# +# Typical Distribution Ratio + +EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 + +EUCKR_TABLE_SIZE = 2352 + +# Char to FreqOrder table , +EUCKR_CHAR_TO_FREQ_ORDER = ( + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, +1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, +1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, +1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, +1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, +1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, +1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, +1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, +1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, +1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, +1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, +1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, +1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, +1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, +1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, +1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, +1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, +1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, +1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, +1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, +1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, +1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, +1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, +1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, +1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, +1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, +1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, +1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, +1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, +2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, +2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, +2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, +2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, +2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, +1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, +2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, +1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, +2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, +2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, +1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, +2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, +2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, +2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, +1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, +2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, +2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, +2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, +2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, +2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, +2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, +1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, +2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, +2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, +2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, +2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, +2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, +1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, +1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, +2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, +1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, +2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, +1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, +2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, +2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, +2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, +2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, +2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, +1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, +1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, +2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, +1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, +2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, +2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, +1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, +2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, +1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, +2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, +1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, +2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, +2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, +1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, +1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, +2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, +2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, +2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, +2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, +2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, +2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, +1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, +2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, +2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, +2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, +2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, +2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, +2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, +1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, +2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 +) + diff --git a/dist/ba_data/python-site-packages/chardet/euckrprober.py b/dist/ba_data/python-site-packages/chardet/euckrprober.py new file mode 100644 index 0000000..345a060 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/euckrprober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCKRDistributionAnalysis +from .mbcssm import EUCKR_SM_MODEL + + +class EUCKRProber(MultiByteCharSetProber): + def __init__(self): + super(EUCKRProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-KR" + + @property + def language(self): + return "Korean" diff --git a/dist/ba_data/python-site-packages/chardet/euctwfreq.py b/dist/ba_data/python-site-packages/chardet/euctwfreq.py new file mode 100644 index 0000000..ed7a995 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/euctwfreq.py @@ -0,0 +1,387 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# EUCTW frequency table +# Converted from big5 work +# by Taiwan's Mandarin Promotion Council +# + +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +# Char to FreqOrder table , +EUCTW_TABLE_SIZE = 5376 + +EUCTW_CHAR_TO_FREQ_ORDER = ( + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 +3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 +1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 +3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 +4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 +7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 +2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 +1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 +3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 +3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 +2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 +3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 +1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 +7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 +7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 +1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 +3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 +3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 +2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 +2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 +3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 +1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 +1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 +1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 +2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 +4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 +1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 +7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 +2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 +7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 +1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 +7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 +1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 +3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 +4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 +3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 +1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 +4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 +3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 +3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 +2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 +7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 +3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 +7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 +1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 +2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 +1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 +1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 +4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 +3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 +2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 +7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 +1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 +2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 +1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 +1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 +7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 +7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 +7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 +3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 +4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 +1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 +7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 +2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 +7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 +3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 +3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 +7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 +2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 +7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 +4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 +2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 +7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 +3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 +2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 +2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 +2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 +1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 +1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 +2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 +1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 +7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 +7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 +2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 +4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 +1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 +7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 +4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 +2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 +1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 +1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 +3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 +3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 +1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 +3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 +7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 +7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 +1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 +2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 +1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 +3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 +2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 +3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 +2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 +4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 +4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 +3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 +3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 +3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 +3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 +3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 +1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 +7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 +7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 +1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 +4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 +3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 +2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 +2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 +3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 +1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 +4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 +2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 +1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 +1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 +2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 +3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 +1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 +7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 +1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 +4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 +1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 +1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 +3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 +3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 +2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 +1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 +4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 +7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 +2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 +3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 +4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 +7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 +7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 +1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 +4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 +3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 +2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 +3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 +3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 +2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 +1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 +4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 +3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 +3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 +2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 +4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 +7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 +3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 +2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 +3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 +1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 +2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 +3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 +4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 +2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 +2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 +7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 +1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 +2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 +1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 +3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 +4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 +2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 +3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 +3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 +2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 +4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 +2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 +3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 +4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 +7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 +3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 +1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 +4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 +1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 +4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 +7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 +7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 +2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 +1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 +1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 +3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 +3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 +2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 +7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 +1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 +3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 +7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 +1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 +7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 +4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 +1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 +2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 +2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 +4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 +3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 +3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 +1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 +2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 +7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 +1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 +1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 +3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 +1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 +4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 +7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 +2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 +3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 +1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 +2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 +2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 +7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 +7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 +7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 +2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 +2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 +1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 +4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 +3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 +3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 +4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 +4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 +2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 +2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 +7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 +4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 +7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 +2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 +1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 +3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 +4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 +2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 +2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 +1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 +2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 +2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 +4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 +7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 +1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 +3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 +7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 +1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 +8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 +2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 +8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 +2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 +2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 +8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 +8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 +8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 +8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 +4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 +3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 +8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 +1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 +8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 +1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 +4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 +1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 +4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 +1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 +3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 +4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 +8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 +3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 +2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 +) + diff --git a/dist/ba_data/python-site-packages/chardet/euctwprober.py b/dist/ba_data/python-site-packages/chardet/euctwprober.py new file mode 100644 index 0000000..35669cc --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/euctwprober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCTWDistributionAnalysis +from .mbcssm import EUCTW_SM_MODEL + +class EUCTWProber(MultiByteCharSetProber): + def __init__(self): + super(EUCTWProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) + self.distribution_analyzer = EUCTWDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-TW" + + @property + def language(self): + return "Taiwan" diff --git a/dist/ba_data/python-site-packages/chardet/gb2312freq.py b/dist/ba_data/python-site-packages/chardet/gb2312freq.py new file mode 100644 index 0000000..697837b --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/gb2312freq.py @@ -0,0 +1,283 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# GB2312 most frequently used character table +# +# Char to FreqOrder table , from hz6763 + +# 512 --> 0.79 -- 0.79 +# 1024 --> 0.92 -- 0.13 +# 2048 --> 0.98 -- 0.06 +# 6768 --> 1.00 -- 0.02 +# +# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 +# Random Distribution Ration = 512 / (3755 - 512) = 0.157 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + +GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 + +GB2312_TABLE_SIZE = 3760 + +GB2312_CHAR_TO_FREQ_ORDER = ( +1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, +2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, +2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, +1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, +1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, +1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, +2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, +3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, +1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, +2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, +2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, +1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, +3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, +1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, +2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, +1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, +3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, +1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, +2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, +1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, +3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, +3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, +3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, +1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, +3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, +2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, +1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, +1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, +4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, +3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, +3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, +1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, +2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, +1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, +1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, +3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, +3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, +4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, +3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, +1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, +1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, +4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, +3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, +1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, +1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, +2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, +3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, +4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, +3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, +2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, +2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, +2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, +2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, +3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, +2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, +2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, +1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, +2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, +1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, +1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, +1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, +2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, +3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, +2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, +2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, +2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, +3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, +1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, +1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, +2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, +1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, +3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, +1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, +1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, +3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, +2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, +1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, +4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, +1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, +1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, +3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, +1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, +1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, +1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, +1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, +3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, +4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, +3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, +2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, +2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, +1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, +3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, +2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, +1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, +1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, +2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, +2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, +3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, +4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, +3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, +3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, +2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, +1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, +3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, +4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, +2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, +1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, +1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, +1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, +3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, +1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, +1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, +2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, +2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, +2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, +1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, +1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, +2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, +1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, +1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, +2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, +2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, +3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, +1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, +4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, +3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, +1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, +3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, +1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, +4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, +1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, +2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, +1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, +1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, +3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, +2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, +1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, +1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, +1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, +3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, +2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, +3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, +3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, +3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, +2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, +2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, +1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, +1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, +3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, +3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, +1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, +1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, +3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, +2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, +2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, +1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, +3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, +4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, +1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, +2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, +3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, +3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, +1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, +2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, +1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, +1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, +1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, +1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, +1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, +1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 +) + diff --git a/dist/ba_data/python-site-packages/chardet/gb2312prober.py b/dist/ba_data/python-site-packages/chardet/gb2312prober.py new file mode 100644 index 0000000..8446d2d --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/gb2312prober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import GB2312DistributionAnalysis +from .mbcssm import GB2312_SM_MODEL + +class GB2312Prober(MultiByteCharSetProber): + def __init__(self): + super(GB2312Prober, self).__init__() + self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) + self.distribution_analyzer = GB2312DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "GB2312" + + @property + def language(self): + return "Chinese" diff --git a/dist/ba_data/python-site-packages/chardet/hebrewprober.py b/dist/ba_data/python-site-packages/chardet/hebrewprober.py new file mode 100644 index 0000000..b0e1bf4 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/hebrewprober.py @@ -0,0 +1,292 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Shy Shalom +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +# This prober doesn't actually recognize a language or a charset. +# It is a helper prober for the use of the Hebrew model probers + +### General ideas of the Hebrew charset recognition ### +# +# Four main charsets exist in Hebrew: +# "ISO-8859-8" - Visual Hebrew +# "windows-1255" - Logical Hebrew +# "ISO-8859-8-I" - Logical Hebrew +# "x-mac-hebrew" - ?? Logical Hebrew ?? +# +# Both "ISO" charsets use a completely identical set of code points, whereas +# "windows-1255" and "x-mac-hebrew" are two different proper supersets of +# these code points. windows-1255 defines additional characters in the range +# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific +# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. +# x-mac-hebrew defines similar additional code points but with a different +# mapping. +# +# As far as an average Hebrew text with no diacritics is concerned, all four +# charsets are identical with respect to code points. Meaning that for the +# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters +# (including final letters). +# +# The dominant difference between these charsets is their directionality. +# "Visual" directionality means that the text is ordered as if the renderer is +# not aware of a BIDI rendering algorithm. The renderer sees the text and +# draws it from left to right. The text itself when ordered naturally is read +# backwards. A buffer of Visual Hebrew generally looks like so: +# "[last word of first line spelled backwards] [whole line ordered backwards +# and spelled backwards] [first word of first line spelled backwards] +# [end of line] [last word of second line] ... etc' " +# adding punctuation marks, numbers and English text to visual text is +# naturally also "visual" and from left to right. +# +# "Logical" directionality means the text is ordered "naturally" according to +# the order it is read. It is the responsibility of the renderer to display +# the text from right to left. A BIDI algorithm is used to place general +# punctuation marks, numbers and English text in the text. +# +# Texts in x-mac-hebrew are almost impossible to find on the Internet. From +# what little evidence I could find, it seems that its general directionality +# is Logical. +# +# To sum up all of the above, the Hebrew probing mechanism knows about two +# charsets: +# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are +# backwards while line order is natural. For charset recognition purposes +# the line order is unimportant (In fact, for this implementation, even +# word order is unimportant). +# Logical Hebrew - "windows-1255" - normal, naturally ordered text. +# +# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be +# specifically identified. +# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew +# that contain special punctuation marks or diacritics is displayed with +# some unconverted characters showing as question marks. This problem might +# be corrected using another model prober for x-mac-hebrew. Due to the fact +# that x-mac-hebrew texts are so rare, writing another model prober isn't +# worth the effort and performance hit. +# +#### The Prober #### +# +# The prober is divided between two SBCharSetProbers and a HebrewProber, +# all of which are managed, created, fed data, inquired and deleted by the +# SBCSGroupProber. The two SBCharSetProbers identify that the text is in +# fact some kind of Hebrew, Logical or Visual. The final decision about which +# one is it is made by the HebrewProber by combining final-letter scores +# with the scores of the two SBCharSetProbers to produce a final answer. +# +# The SBCSGroupProber is responsible for stripping the original text of HTML +# tags, English characters, numbers, low-ASCII punctuation characters, spaces +# and new lines. It reduces any sequence of such characters to a single space. +# The buffer fed to each prober in the SBCS group prober is pure text in +# high-ASCII. +# The two SBCharSetProbers (model probers) share the same language model: +# Win1255Model. +# The first SBCharSetProber uses the model normally as any other +# SBCharSetProber does, to recognize windows-1255, upon which this model was +# built. The second SBCharSetProber is told to make the pair-of-letter +# lookup in the language model backwards. This in practice exactly simulates +# a visual Hebrew model using the windows-1255 logical Hebrew model. +# +# The HebrewProber is not using any language model. All it does is look for +# final-letter evidence suggesting the text is either logical Hebrew or visual +# Hebrew. Disjointed from the model probers, the results of the HebrewProber +# alone are meaningless. HebrewProber always returns 0.00 as confidence +# since it never identifies a charset by itself. Instead, the pointer to the +# HebrewProber is passed to the model probers as a helper "Name Prober". +# When the Group prober receives a positive identification from any prober, +# it asks for the name of the charset identified. If the prober queried is a +# Hebrew model prober, the model prober forwards the call to the +# HebrewProber to make the final decision. In the HebrewProber, the +# decision is made according to the final-letters scores maintained and Both +# model probers scores. The answer is returned in the form of the name of the +# charset identified, either "windows-1255" or "ISO-8859-8". + +class HebrewProber(CharSetProber): + # windows-1255 / ISO-8859-8 code points of interest + FINAL_KAF = 0xea + NORMAL_KAF = 0xeb + FINAL_MEM = 0xed + NORMAL_MEM = 0xee + FINAL_NUN = 0xef + NORMAL_NUN = 0xf0 + FINAL_PE = 0xf3 + NORMAL_PE = 0xf4 + FINAL_TSADI = 0xf5 + NORMAL_TSADI = 0xf6 + + # Minimum Visual vs Logical final letter score difference. + # If the difference is below this, don't rely solely on the final letter score + # distance. + MIN_FINAL_CHAR_DISTANCE = 5 + + # Minimum Visual vs Logical model score difference. + # If the difference is below this, don't rely at all on the model score + # distance. + MIN_MODEL_DISTANCE = 0.01 + + VISUAL_HEBREW_NAME = "ISO-8859-8" + LOGICAL_HEBREW_NAME = "windows-1255" + + def __init__(self): + super(HebrewProber, self).__init__() + self._final_char_logical_score = None + self._final_char_visual_score = None + self._prev = None + self._before_prev = None + self._logical_prober = None + self._visual_prober = None + self.reset() + + def reset(self): + self._final_char_logical_score = 0 + self._final_char_visual_score = 0 + # The two last characters seen in the previous buffer, + # mPrev and mBeforePrev are initialized to space in order to simulate + # a word delimiter at the beginning of the data + self._prev = ' ' + self._before_prev = ' ' + # These probers are owned by the group prober. + + def set_model_probers(self, logicalProber, visualProber): + self._logical_prober = logicalProber + self._visual_prober = visualProber + + def is_final(self, c): + return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, + self.FINAL_PE, self.FINAL_TSADI] + + def is_non_final(self, c): + # The normal Tsadi is not a good Non-Final letter due to words like + # 'lechotet' (to chat) containing an apostrophe after the tsadi. This + # apostrophe is converted to a space in FilterWithoutEnglishLetters + # causing the Non-Final tsadi to appear at an end of a word even + # though this is not the case in the original text. + # The letters Pe and Kaf rarely display a related behavior of not being + # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' + # for example legally end with a Non-Final Pe or Kaf. However, the + # benefit of these letters as Non-Final letters outweighs the damage + # since these words are quite rare. + return c in [self.NORMAL_KAF, self.NORMAL_MEM, + self.NORMAL_NUN, self.NORMAL_PE] + + def feed(self, byte_str): + # Final letter analysis for logical-visual decision. + # Look for evidence that the received buffer is either logical Hebrew + # or visual Hebrew. + # The following cases are checked: + # 1) A word longer than 1 letter, ending with a final letter. This is + # an indication that the text is laid out "naturally" since the + # final letter really appears at the end. +1 for logical score. + # 2) A word longer than 1 letter, ending with a Non-Final letter. In + # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, + # should not end with the Non-Final form of that letter. Exceptions + # to this rule are mentioned above in isNonFinal(). This is an + # indication that the text is laid out backwards. +1 for visual + # score + # 3) A word longer than 1 letter, starting with a final letter. Final + # letters should not appear at the beginning of a word. This is an + # indication that the text is laid out backwards. +1 for visual + # score. + # + # The visual score and logical score are accumulated throughout the + # text and are finally checked against each other in GetCharSetName(). + # No checking for final letters in the middle of words is done since + # that case is not an indication for either Logical or Visual text. + # + # We automatically filter out all 7-bit characters (replace them with + # spaces) so the word boundary detection works properly. [MAP] + + if self.state == ProbingState.NOT_ME: + # Both model probers say it's not them. No reason to continue. + return ProbingState.NOT_ME + + byte_str = self.filter_high_byte_only(byte_str) + + for cur in byte_str: + if cur == ' ': + # We stand on a space - a word just ended + if self._before_prev != ' ': + # next-to-last char was not a space so self._prev is not a + # 1 letter word + if self.is_final(self._prev): + # case (1) [-2:not space][-1:final letter][cur:space] + self._final_char_logical_score += 1 + elif self.is_non_final(self._prev): + # case (2) [-2:not space][-1:Non-Final letter][ + # cur:space] + self._final_char_visual_score += 1 + else: + # Not standing on a space + if ((self._before_prev == ' ') and + (self.is_final(self._prev)) and (cur != ' ')): + # case (3) [-2:space][-1:final letter][cur:not space] + self._final_char_visual_score += 1 + self._before_prev = self._prev + self._prev = cur + + # Forever detecting, till the end or until both model probers return + # ProbingState.NOT_ME (handled above) + return ProbingState.DETECTING + + @property + def charset_name(self): + # Make the decision: is it Logical or Visual? + # If the final letter score distance is dominant enough, rely on it. + finalsub = self._final_char_logical_score - self._final_char_visual_score + if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # It's not dominant enough, try to rely on the model scores instead. + modelsub = (self._logical_prober.get_confidence() + - self._visual_prober.get_confidence()) + if modelsub > self.MIN_MODEL_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if modelsub < -self.MIN_MODEL_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # Still no good, back to final letter distance, maybe it'll save the + # day. + if finalsub < 0.0: + return self.VISUAL_HEBREW_NAME + + # (finalsub > 0 - Logical) or (don't know what to do) default to + # Logical. + return self.LOGICAL_HEBREW_NAME + + @property + def language(self): + return 'Hebrew' + + @property + def state(self): + # Remain active as long as any of the model probers are active. + if (self._logical_prober.state == ProbingState.NOT_ME) and \ + (self._visual_prober.state == ProbingState.NOT_ME): + return ProbingState.NOT_ME + return ProbingState.DETECTING diff --git a/dist/ba_data/python-site-packages/chardet/jisfreq.py b/dist/ba_data/python-site-packages/chardet/jisfreq.py new file mode 100644 index 0000000..83fc082 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/jisfreq.py @@ -0,0 +1,325 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology +# +# Japanese frequency table, applied to both S-JIS and EUC-JP +# They are sorted in order. + +# 128 --> 0.77094 +# 256 --> 0.85710 +# 512 --> 0.92635 +# 1024 --> 0.97130 +# 2048 --> 0.99431 +# +# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 +# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 +# +# Typical Distribution Ratio, 25% of IDR + +JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 + +# Char to FreqOrder table , +JIS_TABLE_SIZE = 4368 + +JIS_CHAR_TO_FREQ_ORDER = ( + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 +3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 +1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 +2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 +2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 +5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 +1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 +5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 +5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 +5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 +5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 +5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 +5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 +1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 +1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 +1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 +2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 +3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 +3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 +1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 +5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 +5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 +5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 +5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 +4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 +5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 +5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 +5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 +5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 +5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 +5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 +5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 +5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 +3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 +5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 +5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 +5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 +5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 +5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 +5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 +5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 +5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 +5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 +5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 +5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 +5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 +5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 +5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 +5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 +5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 +5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 +5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 +5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 +5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 +5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 +5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 +5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 +5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 +5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 +5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 +5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 +5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 +5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 +5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 +5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 +5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 +5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 +6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 +6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 +6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 +6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 +6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 +6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 +6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 +6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 +4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 +1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 +1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 +3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 +3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 +3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 +3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 +2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 +3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 +1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 +1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 +2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 +2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 +2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 +2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 +1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 +1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 +1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 +1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 +2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 +1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 +2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 +1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 +1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 +1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 +1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 +1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 +1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 +1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 +2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 +2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 +2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 +3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 +3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 +3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 +1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 +2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 +1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 +3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 +4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 +2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 +1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 +2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 +1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 +1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 +2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 +2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 +2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 +3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 +1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 +2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 +1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 +2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 +1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 +1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 +1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 +1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 +1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 +2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 +2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 +3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 +2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 +1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 +6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 +1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 +2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 +1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 +3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 +3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 +1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 +1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 +1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 +1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 +2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 +3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 +2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 +1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 +2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 +1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 +4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 +2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 +1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 +1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 +2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 +6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 +1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 +1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 +2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 +3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 +3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 +1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 +1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 +3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 +2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 +4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 +2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 +1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 +1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 +1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 +1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 +3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 +1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 +3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 +2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 +1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 +1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 +1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 +1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 +1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 +2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 +4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 +1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 +1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 +3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 +1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 +2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 +2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 +1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 +1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 +2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 +2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 +1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 +1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 +1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 +1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 +3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 +2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 +2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 +3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 +3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 +1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 +2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 +1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 +2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 +) + + diff --git a/dist/ba_data/python-site-packages/chardet/jpcntx.py b/dist/ba_data/python-site-packages/chardet/jpcntx.py new file mode 100644 index 0000000..20044e4 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/jpcntx.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +# This is hiragana 2-char sequence table, the number in each cell represents its frequency category +jp2CharContext = ( +(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), +(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), +(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), +(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), +(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), +(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), +(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), +(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), +(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), +(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), +(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), +(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), +(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), +(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), +(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), +(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), +(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), +(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), +(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), +(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), +(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), +(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), +(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), +(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), +(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), +(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), +(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), +(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), +(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), +(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), +(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), +(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), +(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), +(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), +(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), +(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), +(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), +(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), +(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), +(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), +(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), +(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), +(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), +(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), +(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), +(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), +(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), +(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), +(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), +(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), +(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), +(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), +(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), +(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), +(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), +(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), +(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), +(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), +(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), +(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), +(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), +(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), +(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), +(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), +(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), +(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), +(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), +(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), +(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), +(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), +(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), +(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), +(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), +(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), +) + +class JapaneseContextAnalysis(object): + NUM_OF_CATEGORY = 6 + DONT_KNOW = -1 + ENOUGH_REL_THRESHOLD = 100 + MAX_REL_THRESHOLD = 1000 + MINIMUM_DATA_THRESHOLD = 4 + + def __init__(self): + self._total_rel = None + self._rel_sample = None + self._need_to_skip_char_num = None + self._last_char_order = None + self._done = None + self.reset() + + def reset(self): + self._total_rel = 0 # total sequence received + # category counters, each integer counts sequence in its category + self._rel_sample = [0] * self.NUM_OF_CATEGORY + # if last byte in current buffer is not the last byte of a character, + # we need to know how many bytes to skip in next buffer + self._need_to_skip_char_num = 0 + self._last_char_order = -1 # The order of previous char + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + + def feed(self, byte_str, num_bytes): + if self._done: + return + + # The buffer we got is byte oriented, and a character may span in more than one + # buffers. In case the last one or two byte in last buffer is not + # complete, we record how many byte needed to complete that character + # and skip these bytes here. We can choose to record those bytes as + # well and analyse the character once it is complete, but since a + # character will not make much difference, by simply skipping + # this character will simply our logic and improve performance. + i = self._need_to_skip_char_num + while i < num_bytes: + order, char_len = self.get_order(byte_str[i:i + 2]) + i += char_len + if i > num_bytes: + self._need_to_skip_char_num = i - num_bytes + self._last_char_order = -1 + else: + if (order != -1) and (self._last_char_order != -1): + self._total_rel += 1 + if self._total_rel > self.MAX_REL_THRESHOLD: + self._done = True + break + self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 + self._last_char_order = order + + def got_enough_data(self): + return self._total_rel > self.ENOUGH_REL_THRESHOLD + + def get_confidence(self): + # This is just one way to calculate confidence. It works well for me. + if self._total_rel > self.MINIMUM_DATA_THRESHOLD: + return (self._total_rel - self._rel_sample[0]) / self._total_rel + else: + return self.DONT_KNOW + + def get_order(self, byte_str): + return -1, 1 + +class SJISContextAnalysis(JapaneseContextAnalysis): + def __init__(self): + super(SJISContextAnalysis, self).__init__() + self._charset_name = "SHIFT_JIS" + + @property + def charset_name(self): + return self._charset_name + + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): + char_len = 2 + if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): + self._charset_name = "CP932" + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 202) and (0x9F <= second_char <= 0xF1): + return second_char - 0x9F, char_len + + return -1, char_len + +class EUCJPContextAnalysis(JapaneseContextAnalysis): + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): + char_len = 2 + elif first_char == 0x8F: + char_len = 3 + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): + return second_char - 0xA1, char_len + + return -1, char_len + + diff --git a/dist/ba_data/python-site-packages/chardet/langbulgarianmodel.py b/dist/ba_data/python-site-packages/chardet/langbulgarianmodel.py new file mode 100644 index 0000000..561bfd9 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/langbulgarianmodel.py @@ -0,0 +1,4650 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +BULGARIAN_LANG_MODEL = { + 63: { # 'e' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 1, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 1, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 0, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 45: { # '\xad' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 1, # 'М' + 36: 0, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 31: { # 'А' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 2, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 1, # 'К' + 46: 2, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Н' + 41: 1, # 'О' + 30: 2, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 2, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 1, # 'е' + 23: 1, # 'ж' + 15: 2, # 'з' + 2: 0, # 'и' + 26: 2, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 0, # 'о' + 13: 2, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 1, # 'у' + 29: 2, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 32: { # 'Б' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 2, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 1, # 'Е' + 55: 1, # 'Ж' + 47: 2, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 1, # 'Щ' + 61: 2, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 1, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 35: { # 'В' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 2, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 2, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 43: { # 'Г' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 1, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 1, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 37: { # 'Д' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 2, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 44: { # 'Е' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 2, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 1, # 'Х' + 53: 2, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 0, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 0, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 1, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 55: { # 'Ж' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 47: { # 'З' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 1, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 40: { # 'И' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 2, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 2, # 'Л' + 38: 2, # 'М' + 36: 2, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 2, # 'Я' + 1: 1, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 1, # 'е' + 23: 0, # 'ж' + 15: 3, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 0, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 0, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 59: { # 'Й' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 1, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 33: { # 'К' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 2, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 3, # 'р' + 8: 1, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 46: { # 'Л' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 2, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 38: { # 'М' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 0, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 36: { # 'Н' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 2, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 1, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 1, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 2, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 41: { # 'О' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 1, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 2, # 'Л' + 38: 2, # 'М' + 36: 2, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 0, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 1, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 0, # 'о' + 13: 2, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 2, # 'ч' + 27: 0, # 'ш' + 24: 2, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 30: { # 'П' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 2, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 3, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 2, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 39: { # 'Р' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 2, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 1, # 'с' + 5: 0, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 28: { # 'С' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 3, # 'А' + 32: 2, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 2, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 34: { # 'Т' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 2, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 3, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 51: { # 'У' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 0, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 2, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 2, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 2, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 2, # 'с' + 5: 1, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 48: { # 'Ф' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 49: { # 'Х' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 53: { # 'Ц' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 1, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 50: { # 'Ч' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 54: { # 'Ш' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 57: { # 'Щ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 1, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 61: { # 'Ъ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 2, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 0, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 60: { # 'Ю' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 0, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 1, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 0, # 'е' + 23: 2, # 'ж' + 15: 1, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 0, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 56: { # 'Я' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 2, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 1, # 'и' + 26: 1, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 0, # 'о' + 13: 2, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 1: { # 'а' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 3, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 18: { # 'б' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 3, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 0, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 2, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 3, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 9: { # 'в' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 1, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 0, # 'в' + 20: 2, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 20: { # 'г' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 11: { # 'д' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 2, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 1, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 3: { # 'е' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 2, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 3, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 23: { # 'ж' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 15: { # 'з' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 2: { # 'и' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 1, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 1, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 3, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 26: { # 'й' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 2, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 2, # 'ф' + 25: 1, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 12: { # 'к' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 3, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 10: { # 'л' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 1, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 2, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 2, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 2, # 'ь' + 42: 3, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 14: { # 'м' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 1, # 'т' + 19: 3, # 'у' + 29: 2, # 'ф' + 25: 1, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 6: { # 'н' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 2, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 3, # 'ф' + 25: 2, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 2, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 4: { # 'о' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 3, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 13: { # 'п' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 7: { # 'р' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 1, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 2, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 2, # 'ч' + 27: 3, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 8: { # 'с' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 2, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 1, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 2, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 2, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 5: { # 'т' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 2, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 19: { # 'у' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 2, # 'и' + 26: 2, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 2, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 2, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 29: { # 'ф' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 1, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 2, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 25: { # 'х' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 1, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 22: { # 'ц' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 2, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 0, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 21: { # 'ч' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 1, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 27: { # 'ш' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 2, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 1, # 'т' + 19: 2, # 'у' + 29: 1, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 24: { # 'щ' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 1, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 17: { # 'ъ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 1, # 'и' + 26: 2, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 2, # 'ш' + 24: 3, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 2, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 52: { # 'ь' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 1, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 1, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 1, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 42: { # 'ю' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 1, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 1, # 'е' + 23: 2, # 'ж' + 15: 2, # 'з' + 2: 1, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 1, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 16: { # 'я' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 1, # 'ж' + 15: 2, # 'з' + 2: 1, # 'и' + 26: 2, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 1, # 'о' + 13: 2, # 'п' + 7: 2, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 3, # 'х' + 22: 2, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 2, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 58: { # 'є' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 62: { # '№' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +ISO_8859_5_BULGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 77, # 'A' + 66: 90, # 'B' + 67: 99, # 'C' + 68: 100, # 'D' + 69: 72, # 'E' + 70: 109, # 'F' + 71: 107, # 'G' + 72: 101, # 'H' + 73: 79, # 'I' + 74: 185, # 'J' + 75: 81, # 'K' + 76: 102, # 'L' + 77: 76, # 'M' + 78: 94, # 'N' + 79: 82, # 'O' + 80: 110, # 'P' + 81: 186, # 'Q' + 82: 108, # 'R' + 83: 91, # 'S' + 84: 74, # 'T' + 85: 119, # 'U' + 86: 84, # 'V' + 87: 96, # 'W' + 88: 111, # 'X' + 89: 187, # 'Y' + 90: 115, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 65, # 'a' + 98: 69, # 'b' + 99: 70, # 'c' + 100: 66, # 'd' + 101: 63, # 'e' + 102: 68, # 'f' + 103: 112, # 'g' + 104: 103, # 'h' + 105: 92, # 'i' + 106: 194, # 'j' + 107: 104, # 'k' + 108: 95, # 'l' + 109: 86, # 'm' + 110: 87, # 'n' + 111: 71, # 'o' + 112: 116, # 'p' + 113: 195, # 'q' + 114: 85, # 'r' + 115: 93, # 's' + 116: 97, # 't' + 117: 113, # 'u' + 118: 196, # 'v' + 119: 197, # 'w' + 120: 198, # 'x' + 121: 199, # 'y' + 122: 200, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 194, # '\x80' + 129: 195, # '\x81' + 130: 196, # '\x82' + 131: 197, # '\x83' + 132: 198, # '\x84' + 133: 199, # '\x85' + 134: 200, # '\x86' + 135: 201, # '\x87' + 136: 202, # '\x88' + 137: 203, # '\x89' + 138: 204, # '\x8a' + 139: 205, # '\x8b' + 140: 206, # '\x8c' + 141: 207, # '\x8d' + 142: 208, # '\x8e' + 143: 209, # '\x8f' + 144: 210, # '\x90' + 145: 211, # '\x91' + 146: 212, # '\x92' + 147: 213, # '\x93' + 148: 214, # '\x94' + 149: 215, # '\x95' + 150: 216, # '\x96' + 151: 217, # '\x97' + 152: 218, # '\x98' + 153: 219, # '\x99' + 154: 220, # '\x9a' + 155: 221, # '\x9b' + 156: 222, # '\x9c' + 157: 223, # '\x9d' + 158: 224, # '\x9e' + 159: 225, # '\x9f' + 160: 81, # '\xa0' + 161: 226, # 'Ё' + 162: 227, # 'Ђ' + 163: 228, # 'Ѓ' + 164: 229, # 'Є' + 165: 230, # 'Ѕ' + 166: 105, # 'І' + 167: 231, # 'Ї' + 168: 232, # 'Ј' + 169: 233, # 'Љ' + 170: 234, # 'Њ' + 171: 235, # 'Ћ' + 172: 236, # 'Ќ' + 173: 45, # '\xad' + 174: 237, # 'Ў' + 175: 238, # 'Џ' + 176: 31, # 'А' + 177: 32, # 'Б' + 178: 35, # 'В' + 179: 43, # 'Г' + 180: 37, # 'Д' + 181: 44, # 'Е' + 182: 55, # 'Ж' + 183: 47, # 'З' + 184: 40, # 'И' + 185: 59, # 'Й' + 186: 33, # 'К' + 187: 46, # 'Л' + 188: 38, # 'М' + 189: 36, # 'Н' + 190: 41, # 'О' + 191: 30, # 'П' + 192: 39, # 'Р' + 193: 28, # 'С' + 194: 34, # 'Т' + 195: 51, # 'У' + 196: 48, # 'Ф' + 197: 49, # 'Х' + 198: 53, # 'Ц' + 199: 50, # 'Ч' + 200: 54, # 'Ш' + 201: 57, # 'Щ' + 202: 61, # 'Ъ' + 203: 239, # 'Ы' + 204: 67, # 'Ь' + 205: 240, # 'Э' + 206: 60, # 'Ю' + 207: 56, # 'Я' + 208: 1, # 'а' + 209: 18, # 'б' + 210: 9, # 'в' + 211: 20, # 'г' + 212: 11, # 'д' + 213: 3, # 'е' + 214: 23, # 'ж' + 215: 15, # 'з' + 216: 2, # 'и' + 217: 26, # 'й' + 218: 12, # 'к' + 219: 10, # 'л' + 220: 14, # 'м' + 221: 6, # 'н' + 222: 4, # 'о' + 223: 13, # 'п' + 224: 7, # 'р' + 225: 8, # 'с' + 226: 5, # 'т' + 227: 19, # 'у' + 228: 29, # 'ф' + 229: 25, # 'х' + 230: 22, # 'ц' + 231: 21, # 'ч' + 232: 27, # 'ш' + 233: 24, # 'щ' + 234: 17, # 'ъ' + 235: 75, # 'ы' + 236: 52, # 'ь' + 237: 241, # 'э' + 238: 42, # 'ю' + 239: 16, # 'я' + 240: 62, # '№' + 241: 242, # 'ё' + 242: 243, # 'ђ' + 243: 244, # 'ѓ' + 244: 58, # 'є' + 245: 245, # 'ѕ' + 246: 98, # 'і' + 247: 246, # 'ї' + 248: 247, # 'ј' + 249: 248, # 'љ' + 250: 249, # 'њ' + 251: 250, # 'ћ' + 252: 251, # 'ќ' + 253: 91, # '§' + 254: 252, # 'ў' + 255: 253, # 'џ' +} + +ISO_8859_5_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', + language='Bulgarian', + char_to_order_map=ISO_8859_5_BULGARIAN_CHAR_TO_ORDER, + language_model=BULGARIAN_LANG_MODEL, + typical_positive_ratio=0.969392, + keep_ascii_letters=False, + alphabet='АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя') + +WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 77, # 'A' + 66: 90, # 'B' + 67: 99, # 'C' + 68: 100, # 'D' + 69: 72, # 'E' + 70: 109, # 'F' + 71: 107, # 'G' + 72: 101, # 'H' + 73: 79, # 'I' + 74: 185, # 'J' + 75: 81, # 'K' + 76: 102, # 'L' + 77: 76, # 'M' + 78: 94, # 'N' + 79: 82, # 'O' + 80: 110, # 'P' + 81: 186, # 'Q' + 82: 108, # 'R' + 83: 91, # 'S' + 84: 74, # 'T' + 85: 119, # 'U' + 86: 84, # 'V' + 87: 96, # 'W' + 88: 111, # 'X' + 89: 187, # 'Y' + 90: 115, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 65, # 'a' + 98: 69, # 'b' + 99: 70, # 'c' + 100: 66, # 'd' + 101: 63, # 'e' + 102: 68, # 'f' + 103: 112, # 'g' + 104: 103, # 'h' + 105: 92, # 'i' + 106: 194, # 'j' + 107: 104, # 'k' + 108: 95, # 'l' + 109: 86, # 'm' + 110: 87, # 'n' + 111: 71, # 'o' + 112: 116, # 'p' + 113: 195, # 'q' + 114: 85, # 'r' + 115: 93, # 's' + 116: 97, # 't' + 117: 113, # 'u' + 118: 196, # 'v' + 119: 197, # 'w' + 120: 198, # 'x' + 121: 199, # 'y' + 122: 200, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 206, # 'Ђ' + 129: 207, # 'Ѓ' + 130: 208, # '‚' + 131: 209, # 'ѓ' + 132: 210, # '„' + 133: 211, # '…' + 134: 212, # '†' + 135: 213, # '‡' + 136: 120, # '€' + 137: 214, # '‰' + 138: 215, # 'Љ' + 139: 216, # '‹' + 140: 217, # 'Њ' + 141: 218, # 'Ќ' + 142: 219, # 'Ћ' + 143: 220, # 'Џ' + 144: 221, # 'ђ' + 145: 78, # '‘' + 146: 64, # '’' + 147: 83, # '“' + 148: 121, # '”' + 149: 98, # '•' + 150: 117, # '–' + 151: 105, # '—' + 152: 222, # None + 153: 223, # '™' + 154: 224, # 'љ' + 155: 225, # '›' + 156: 226, # 'њ' + 157: 227, # 'ќ' + 158: 228, # 'ћ' + 159: 229, # 'џ' + 160: 88, # '\xa0' + 161: 230, # 'Ў' + 162: 231, # 'ў' + 163: 232, # 'Ј' + 164: 233, # '¤' + 165: 122, # 'Ґ' + 166: 89, # '¦' + 167: 106, # '§' + 168: 234, # 'Ё' + 169: 235, # '©' + 170: 236, # 'Є' + 171: 237, # '«' + 172: 238, # '¬' + 173: 45, # '\xad' + 174: 239, # '®' + 175: 240, # 'Ї' + 176: 73, # '°' + 177: 80, # '±' + 178: 118, # 'І' + 179: 114, # 'і' + 180: 241, # 'ґ' + 181: 242, # 'µ' + 182: 243, # '¶' + 183: 244, # '·' + 184: 245, # 'ё' + 185: 62, # '№' + 186: 58, # 'є' + 187: 246, # '»' + 188: 247, # 'ј' + 189: 248, # 'Ѕ' + 190: 249, # 'ѕ' + 191: 250, # 'ї' + 192: 31, # 'А' + 193: 32, # 'Б' + 194: 35, # 'В' + 195: 43, # 'Г' + 196: 37, # 'Д' + 197: 44, # 'Е' + 198: 55, # 'Ж' + 199: 47, # 'З' + 200: 40, # 'И' + 201: 59, # 'Й' + 202: 33, # 'К' + 203: 46, # 'Л' + 204: 38, # 'М' + 205: 36, # 'Н' + 206: 41, # 'О' + 207: 30, # 'П' + 208: 39, # 'Р' + 209: 28, # 'С' + 210: 34, # 'Т' + 211: 51, # 'У' + 212: 48, # 'Ф' + 213: 49, # 'Х' + 214: 53, # 'Ц' + 215: 50, # 'Ч' + 216: 54, # 'Ш' + 217: 57, # 'Щ' + 218: 61, # 'Ъ' + 219: 251, # 'Ы' + 220: 67, # 'Ь' + 221: 252, # 'Э' + 222: 60, # 'Ю' + 223: 56, # 'Я' + 224: 1, # 'а' + 225: 18, # 'б' + 226: 9, # 'в' + 227: 20, # 'г' + 228: 11, # 'д' + 229: 3, # 'е' + 230: 23, # 'ж' + 231: 15, # 'з' + 232: 2, # 'и' + 233: 26, # 'й' + 234: 12, # 'к' + 235: 10, # 'л' + 236: 14, # 'м' + 237: 6, # 'н' + 238: 4, # 'о' + 239: 13, # 'п' + 240: 7, # 'р' + 241: 8, # 'с' + 242: 5, # 'т' + 243: 19, # 'у' + 244: 29, # 'ф' + 245: 25, # 'х' + 246: 22, # 'ц' + 247: 21, # 'ч' + 248: 27, # 'ш' + 249: 24, # 'щ' + 250: 17, # 'ъ' + 251: 75, # 'ы' + 252: 52, # 'ь' + 253: 253, # 'э' + 254: 42, # 'ю' + 255: 16, # 'я' +} + +WINDOWS_1251_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', + language='Bulgarian', + char_to_order_map=WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER, + language_model=BULGARIAN_LANG_MODEL, + typical_positive_ratio=0.969392, + keep_ascii_letters=False, + alphabet='АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя') + diff --git a/dist/ba_data/python-site-packages/chardet/langgreekmodel.py b/dist/ba_data/python-site-packages/chardet/langgreekmodel.py new file mode 100644 index 0000000..02b94de --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/langgreekmodel.py @@ -0,0 +1,4398 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +GREEK_LANG_MODEL = { + 60: { # 'e' + 60: 2, # 'e' + 55: 1, # 'o' + 58: 2, # 't' + 36: 1, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 55: { # 'o' + 60: 0, # 'e' + 55: 2, # 'o' + 58: 2, # 't' + 36: 1, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 1, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 58: { # 't' + 60: 2, # 'e' + 55: 1, # 'o' + 58: 1, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 1, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 36: { # '·' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 61: { # 'Ά' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 1, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 1, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 46: { # 'Έ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 2, # 'β' + 20: 2, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 2, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 1, # 'σ' + 2: 2, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 54: { # 'Ό' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 2, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 31: { # 'Α' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 2, # 'Β' + 43: 2, # 'Γ' + 41: 1, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 2, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 1, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Υ' + 56: 2, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 2, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 1, # 'θ' + 5: 0, # 'ι' + 11: 2, # 'κ' + 16: 3, # 'λ' + 10: 2, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 2, # 'ς' + 7: 2, # 'σ' + 2: 0, # 'τ' + 12: 3, # 'υ' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 51: { # 'Β' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 1, # 'Ι' + 44: 0, # 'Κ' + 53: 1, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 2, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 43: { # 'Γ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 1, # 'Α' + 51: 0, # 'Β' + 43: 2, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 1, # 'Κ' + 53: 1, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 1, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 41: { # 'Δ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 1, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 34: { # 'Ε' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 2, # 'Γ' + 41: 2, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 1, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 2, # 'Χ' + 57: 2, # 'Ω' + 17: 3, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 3, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 1, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 1, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 2, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 2, # 'τ' + 12: 2, # 'υ' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 1, # 'ύ' + 27: 0, # 'ώ' + }, + 40: { # 'Η' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 1, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 2, # 'Θ' + 47: 0, # 'Ι' + 44: 2, # 'Κ' + 53: 0, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 1, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 52: { # 'Θ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 1, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 1, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 47: { # 'Ι' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 1, # 'Β' + 43: 1, # 'Γ' + 41: 2, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Υ' + 56: 2, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 1, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 1, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 44: { # 'Κ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 1, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 1, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 1, # 'Ω' + 17: 3, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 53: { # 'Λ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 2, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 2, # 'Σ' + 33: 0, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 1, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 38: { # 'Μ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 2, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 2, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 2, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 49: { # 'Ν' + 60: 2, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 1, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 1, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 59: { # 'Ξ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 1, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 39: { # 'Ο' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 1, # 'Β' + 43: 2, # 'Γ' + 41: 2, # 'Δ' + 34: 2, # 'Ε' + 40: 1, # 'Η' + 52: 2, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Υ' + 56: 2, # 'Φ' + 50: 2, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 2, # 'κ' + 16: 2, # 'λ' + 10: 2, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 2, # 'τ' + 12: 2, # 'υ' + 28: 1, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 35: { # 'Π' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 2, # 'Λ' + 38: 1, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 2, # 'Ω' + 17: 2, # 'ά' + 18: 1, # 'έ' + 22: 1, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 3, # 'ώ' + }, + 48: { # 'Ρ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 1, # 'Γ' + 41: 1, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 1, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 1, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 1, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 37: { # 'Σ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 1, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 0, # 'Λ' + 38: 2, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 2, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 2, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 2, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 2, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 33: { # 'Τ' + 60: 0, # 'e' + 55: 1, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 1, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 2, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 3, # 'ώ' + }, + 45: { # 'Υ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 2, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 2, # 'Η' + 52: 2, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 1, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 1, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 56: { # 'Φ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 1, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 2, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 1, # 'ύ' + 27: 1, # 'ώ' + }, + 50: { # 'Χ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 1, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 1, # 'Ν' + 59: 0, # 'Ξ' + 39: 1, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 1, # 'Ω' + 17: 2, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 2, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 57: { # 'Ω' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 1, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 1, # 'Λ' + 38: 0, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 2, # 'ς' + 7: 2, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 17: { # 'ά' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 3, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 3, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 18: { # 'έ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 3, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 22: { # 'ή' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 1, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 15: { # 'ί' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 3, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 1, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 1: { # 'α' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 3, # 'ί' + 1: 0, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 2, # 'ε' + 32: 3, # 'ζ' + 13: 1, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 29: { # 'β' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 2, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 3, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 20: { # 'γ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 2, # 'ύ' + 27: 3, # 'ώ' + }, + 21: { # 'δ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 3: { # 'ε' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 3, # 'ί' + 1: 2, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 2, # 'ε' + 32: 2, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 2, # 'ό' + 26: 3, # 'ύ' + 27: 2, # 'ώ' + }, + 32: { # 'ζ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 1, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 2, # 'ώ' + }, + 13: { # 'η' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 25: { # 'θ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 1, # 'λ' + 10: 3, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 5: { # 'ι' + 60: 0, # 'e' + 55: 1, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 0, # 'ύ' + 27: 3, # 'ώ' + }, + 11: { # 'κ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 2, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 2, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 16: { # 'λ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 1, # 'β' + 20: 2, # 'γ' + 21: 1, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 2, # 'κ' + 16: 3, # 'λ' + 10: 2, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 10: { # 'μ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 3, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 3, # 'φ' + 23: 0, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 6: { # 'ν' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 1, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 30: { # 'ξ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 2, # 'ό' + 26: 3, # 'ύ' + 27: 1, # 'ώ' + }, + 4: { # 'ο' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 2, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 2, # 'ω' + 19: 1, # 'ό' + 26: 3, # 'ύ' + 27: 2, # 'ώ' + }, + 9: { # 'π' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 3, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 2, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 2, # 'ύ' + 27: 3, # 'ώ' + }, + 8: { # 'ρ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 1, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 3, # 'ο' + 9: 2, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 14: { # 'ς' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 7: { # 'σ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 3, # 'β' + 20: 0, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 2, # 'ώ' + }, + 2: { # 'τ' + 60: 0, # 'e' + 55: 2, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 2, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 12: { # 'υ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 2, # 'ε' + 32: 2, # 'ζ' + 13: 2, # 'η' + 25: 3, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 2, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 2, # 'ώ' + }, + 28: { # 'φ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 1, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 23: { # 'χ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 2, # 'μ' + 6: 3, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 42: { # 'ψ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 1, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 2, # 'τ' + 12: 1, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 24: { # 'ω' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 1, # 'ά' + 18: 0, # 'έ' + 22: 2, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 19: { # 'ό' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 1, # 'ε' + 32: 2, # 'ζ' + 13: 2, # 'η' + 25: 2, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 1, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 26: { # 'ύ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 2, # 'β' + 20: 2, # 'γ' + 21: 1, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 2, # 'χ' + 42: 2, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 27: { # 'ώ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 1, # 'β' + 20: 0, # 'γ' + 21: 3, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 1, # 'η' + 25: 2, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 1, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 1, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +WINDOWS_1253_GREEK_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 82, # 'A' + 66: 100, # 'B' + 67: 104, # 'C' + 68: 94, # 'D' + 69: 98, # 'E' + 70: 101, # 'F' + 71: 116, # 'G' + 72: 102, # 'H' + 73: 111, # 'I' + 74: 187, # 'J' + 75: 117, # 'K' + 76: 92, # 'L' + 77: 88, # 'M' + 78: 113, # 'N' + 79: 85, # 'O' + 80: 79, # 'P' + 81: 118, # 'Q' + 82: 105, # 'R' + 83: 83, # 'S' + 84: 67, # 'T' + 85: 114, # 'U' + 86: 119, # 'V' + 87: 95, # 'W' + 88: 99, # 'X' + 89: 109, # 'Y' + 90: 188, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 72, # 'a' + 98: 70, # 'b' + 99: 80, # 'c' + 100: 81, # 'd' + 101: 60, # 'e' + 102: 96, # 'f' + 103: 93, # 'g' + 104: 89, # 'h' + 105: 68, # 'i' + 106: 120, # 'j' + 107: 97, # 'k' + 108: 77, # 'l' + 109: 86, # 'm' + 110: 69, # 'n' + 111: 55, # 'o' + 112: 78, # 'p' + 113: 115, # 'q' + 114: 65, # 'r' + 115: 66, # 's' + 116: 58, # 't' + 117: 76, # 'u' + 118: 106, # 'v' + 119: 103, # 'w' + 120: 87, # 'x' + 121: 107, # 'y' + 122: 112, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 255, # '€' + 129: 255, # None + 130: 255, # '‚' + 131: 255, # 'ƒ' + 132: 255, # '„' + 133: 255, # '…' + 134: 255, # '†' + 135: 255, # '‡' + 136: 255, # None + 137: 255, # '‰' + 138: 255, # None + 139: 255, # '‹' + 140: 255, # None + 141: 255, # None + 142: 255, # None + 143: 255, # None + 144: 255, # None + 145: 255, # '‘' + 146: 255, # '’' + 147: 255, # '“' + 148: 255, # '”' + 149: 255, # '•' + 150: 255, # '–' + 151: 255, # '—' + 152: 255, # None + 153: 255, # '™' + 154: 255, # None + 155: 255, # '›' + 156: 255, # None + 157: 255, # None + 158: 255, # None + 159: 255, # None + 160: 253, # '\xa0' + 161: 233, # '΅' + 162: 61, # 'Ά' + 163: 253, # '£' + 164: 253, # '¤' + 165: 253, # '¥' + 166: 253, # '¦' + 167: 253, # '§' + 168: 253, # '¨' + 169: 253, # '©' + 170: 253, # None + 171: 253, # '«' + 172: 253, # '¬' + 173: 74, # '\xad' + 174: 253, # '®' + 175: 253, # '―' + 176: 253, # '°' + 177: 253, # '±' + 178: 253, # '²' + 179: 253, # '³' + 180: 247, # '΄' + 181: 253, # 'µ' + 182: 253, # '¶' + 183: 36, # '·' + 184: 46, # 'Έ' + 185: 71, # 'Ή' + 186: 73, # 'Ί' + 187: 253, # '»' + 188: 54, # 'Ό' + 189: 253, # '½' + 190: 108, # 'Ύ' + 191: 123, # 'Ώ' + 192: 110, # 'ΐ' + 193: 31, # 'Α' + 194: 51, # 'Β' + 195: 43, # 'Γ' + 196: 41, # 'Δ' + 197: 34, # 'Ε' + 198: 91, # 'Ζ' + 199: 40, # 'Η' + 200: 52, # 'Θ' + 201: 47, # 'Ι' + 202: 44, # 'Κ' + 203: 53, # 'Λ' + 204: 38, # 'Μ' + 205: 49, # 'Ν' + 206: 59, # 'Ξ' + 207: 39, # 'Ο' + 208: 35, # 'Π' + 209: 48, # 'Ρ' + 210: 250, # None + 211: 37, # 'Σ' + 212: 33, # 'Τ' + 213: 45, # 'Υ' + 214: 56, # 'Φ' + 215: 50, # 'Χ' + 216: 84, # 'Ψ' + 217: 57, # 'Ω' + 218: 120, # 'Ϊ' + 219: 121, # 'Ϋ' + 220: 17, # 'ά' + 221: 18, # 'έ' + 222: 22, # 'ή' + 223: 15, # 'ί' + 224: 124, # 'ΰ' + 225: 1, # 'α' + 226: 29, # 'β' + 227: 20, # 'γ' + 228: 21, # 'δ' + 229: 3, # 'ε' + 230: 32, # 'ζ' + 231: 13, # 'η' + 232: 25, # 'θ' + 233: 5, # 'ι' + 234: 11, # 'κ' + 235: 16, # 'λ' + 236: 10, # 'μ' + 237: 6, # 'ν' + 238: 30, # 'ξ' + 239: 4, # 'ο' + 240: 9, # 'π' + 241: 8, # 'ρ' + 242: 14, # 'ς' + 243: 7, # 'σ' + 244: 2, # 'τ' + 245: 12, # 'υ' + 246: 28, # 'φ' + 247: 23, # 'χ' + 248: 42, # 'ψ' + 249: 24, # 'ω' + 250: 64, # 'ϊ' + 251: 75, # 'ϋ' + 252: 19, # 'ό' + 253: 26, # 'ύ' + 254: 27, # 'ώ' + 255: 253, # None +} + +WINDOWS_1253_GREEK_MODEL = SingleByteCharSetModel(charset_name='windows-1253', + language='Greek', + char_to_order_map=WINDOWS_1253_GREEK_CHAR_TO_ORDER, + language_model=GREEK_LANG_MODEL, + typical_positive_ratio=0.982851, + keep_ascii_letters=False, + alphabet='ΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρςστυφχψωόύώ') + +ISO_8859_7_GREEK_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 82, # 'A' + 66: 100, # 'B' + 67: 104, # 'C' + 68: 94, # 'D' + 69: 98, # 'E' + 70: 101, # 'F' + 71: 116, # 'G' + 72: 102, # 'H' + 73: 111, # 'I' + 74: 187, # 'J' + 75: 117, # 'K' + 76: 92, # 'L' + 77: 88, # 'M' + 78: 113, # 'N' + 79: 85, # 'O' + 80: 79, # 'P' + 81: 118, # 'Q' + 82: 105, # 'R' + 83: 83, # 'S' + 84: 67, # 'T' + 85: 114, # 'U' + 86: 119, # 'V' + 87: 95, # 'W' + 88: 99, # 'X' + 89: 109, # 'Y' + 90: 188, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 72, # 'a' + 98: 70, # 'b' + 99: 80, # 'c' + 100: 81, # 'd' + 101: 60, # 'e' + 102: 96, # 'f' + 103: 93, # 'g' + 104: 89, # 'h' + 105: 68, # 'i' + 106: 120, # 'j' + 107: 97, # 'k' + 108: 77, # 'l' + 109: 86, # 'm' + 110: 69, # 'n' + 111: 55, # 'o' + 112: 78, # 'p' + 113: 115, # 'q' + 114: 65, # 'r' + 115: 66, # 's' + 116: 58, # 't' + 117: 76, # 'u' + 118: 106, # 'v' + 119: 103, # 'w' + 120: 87, # 'x' + 121: 107, # 'y' + 122: 112, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 255, # '\x80' + 129: 255, # '\x81' + 130: 255, # '\x82' + 131: 255, # '\x83' + 132: 255, # '\x84' + 133: 255, # '\x85' + 134: 255, # '\x86' + 135: 255, # '\x87' + 136: 255, # '\x88' + 137: 255, # '\x89' + 138: 255, # '\x8a' + 139: 255, # '\x8b' + 140: 255, # '\x8c' + 141: 255, # '\x8d' + 142: 255, # '\x8e' + 143: 255, # '\x8f' + 144: 255, # '\x90' + 145: 255, # '\x91' + 146: 255, # '\x92' + 147: 255, # '\x93' + 148: 255, # '\x94' + 149: 255, # '\x95' + 150: 255, # '\x96' + 151: 255, # '\x97' + 152: 255, # '\x98' + 153: 255, # '\x99' + 154: 255, # '\x9a' + 155: 255, # '\x9b' + 156: 255, # '\x9c' + 157: 255, # '\x9d' + 158: 255, # '\x9e' + 159: 255, # '\x9f' + 160: 253, # '\xa0' + 161: 233, # '‘' + 162: 90, # '’' + 163: 253, # '£' + 164: 253, # '€' + 165: 253, # '₯' + 166: 253, # '¦' + 167: 253, # '§' + 168: 253, # '¨' + 169: 253, # '©' + 170: 253, # 'ͺ' + 171: 253, # '«' + 172: 253, # '¬' + 173: 74, # '\xad' + 174: 253, # None + 175: 253, # '―' + 176: 253, # '°' + 177: 253, # '±' + 178: 253, # '²' + 179: 253, # '³' + 180: 247, # '΄' + 181: 248, # '΅' + 182: 61, # 'Ά' + 183: 36, # '·' + 184: 46, # 'Έ' + 185: 71, # 'Ή' + 186: 73, # 'Ί' + 187: 253, # '»' + 188: 54, # 'Ό' + 189: 253, # '½' + 190: 108, # 'Ύ' + 191: 123, # 'Ώ' + 192: 110, # 'ΐ' + 193: 31, # 'Α' + 194: 51, # 'Β' + 195: 43, # 'Γ' + 196: 41, # 'Δ' + 197: 34, # 'Ε' + 198: 91, # 'Ζ' + 199: 40, # 'Η' + 200: 52, # 'Θ' + 201: 47, # 'Ι' + 202: 44, # 'Κ' + 203: 53, # 'Λ' + 204: 38, # 'Μ' + 205: 49, # 'Ν' + 206: 59, # 'Ξ' + 207: 39, # 'Ο' + 208: 35, # 'Π' + 209: 48, # 'Ρ' + 210: 250, # None + 211: 37, # 'Σ' + 212: 33, # 'Τ' + 213: 45, # 'Υ' + 214: 56, # 'Φ' + 215: 50, # 'Χ' + 216: 84, # 'Ψ' + 217: 57, # 'Ω' + 218: 120, # 'Ϊ' + 219: 121, # 'Ϋ' + 220: 17, # 'ά' + 221: 18, # 'έ' + 222: 22, # 'ή' + 223: 15, # 'ί' + 224: 124, # 'ΰ' + 225: 1, # 'α' + 226: 29, # 'β' + 227: 20, # 'γ' + 228: 21, # 'δ' + 229: 3, # 'ε' + 230: 32, # 'ζ' + 231: 13, # 'η' + 232: 25, # 'θ' + 233: 5, # 'ι' + 234: 11, # 'κ' + 235: 16, # 'λ' + 236: 10, # 'μ' + 237: 6, # 'ν' + 238: 30, # 'ξ' + 239: 4, # 'ο' + 240: 9, # 'π' + 241: 8, # 'ρ' + 242: 14, # 'ς' + 243: 7, # 'σ' + 244: 2, # 'τ' + 245: 12, # 'υ' + 246: 28, # 'φ' + 247: 23, # 'χ' + 248: 42, # 'ψ' + 249: 24, # 'ω' + 250: 64, # 'ϊ' + 251: 75, # 'ϋ' + 252: 19, # 'ό' + 253: 26, # 'ύ' + 254: 27, # 'ώ' + 255: 253, # None +} + +ISO_8859_7_GREEK_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-7', + language='Greek', + char_to_order_map=ISO_8859_7_GREEK_CHAR_TO_ORDER, + language_model=GREEK_LANG_MODEL, + typical_positive_ratio=0.982851, + keep_ascii_letters=False, + alphabet='ΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρςστυφχψωόύώ') + diff --git a/dist/ba_data/python-site-packages/chardet/langhebrewmodel.py b/dist/ba_data/python-site-packages/chardet/langhebrewmodel.py new file mode 100644 index 0000000..40fd674 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/langhebrewmodel.py @@ -0,0 +1,4383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +HEBREW_LANG_MODEL = { + 50: { # 'a' + 50: 0, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 2, # 'l' + 54: 2, # 'n' + 49: 0, # 'o' + 51: 2, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 1, # 'ק' + 7: 0, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 60: { # 'c' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 0, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 0, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 61: { # 'd' + 50: 1, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 2, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 0, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 1, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 42: { # 'e' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 2, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 2, # 'l' + 54: 2, # 'n' + 49: 1, # 'o' + 51: 2, # 'r' + 43: 2, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 1, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 53: { # 'i' + 50: 1, # 'a' + 60: 2, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 0, # 'i' + 56: 1, # 'l' + 54: 2, # 'n' + 49: 2, # 'o' + 51: 1, # 'r' + 43: 2, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 56: { # 'l' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 2, # 'e' + 53: 2, # 'i' + 56: 2, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 54: { # 'n' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 49: { # 'o' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 2, # 'n' + 49: 1, # 'o' + 51: 2, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 51: { # 'r' + 50: 2, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 2, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 2, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 43: { # 's' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 0, # 'd' + 42: 2, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 2, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 44: { # 't' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 0, # 'd' + 42: 2, # 'e' + 53: 2, # 'i' + 56: 1, # 'l' + 54: 0, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 63: { # 'u' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 0, # 'o' + 51: 1, # 'r' + 43: 2, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 34: { # '\xa0' + 50: 1, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 0, # 'e' + 53: 1, # 'i' + 56: 0, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 2, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 2, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 55: { # '´' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 2, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 1, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 48: { # '¼' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 39: { # '½' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 57: { # '¾' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 30: { # 'ְ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 1, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 2, # 'ו' + 24: 2, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 2, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 1, # 'ם' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 2, # 'ע' + 26: 0, # 'ף' + 18: 2, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 59: { # 'ֱ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 1, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 0, # 'ם' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 41: { # 'ֲ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 1, # 'י' + 25: 1, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 0, # 'ם' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 1, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 33: { # 'ִ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 1, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 0, # 'ַ' + 29: 1, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 1, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 2, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 37: { # 'ֵ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 1, # 'ַ' + 29: 1, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 2, # 'ח' + 22: 1, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 1, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 1, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 36: { # 'ֶ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 1, # 'ַ' + 29: 1, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 2, # 'ח' + 22: 1, # 'ט' + 1: 2, # 'י' + 25: 2, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 1, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 2, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 31: { # 'ַ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 0, # 'ַ' + 29: 2, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 1, # 'ו' + 24: 2, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 2, # 'ע' + 26: 2, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 29: { # 'ָ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 1, # 'ַ' + 29: 2, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 1, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 3, # 'ה' + 2: 2, # 'ו' + 24: 2, # 'ז' + 14: 2, # 'ח' + 22: 1, # 'ט' + 1: 2, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 35: { # 'ֹ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 1, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 1, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 62: { # 'ֻ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 1, # 'ם' + 6: 1, # 'מ' + 23: 1, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 28: { # 'ּ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 3, # 'ְ' + 59: 0, # 'ֱ' + 41: 1, # 'ֲ' + 33: 3, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 3, # 'ַ' + 29: 3, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 2, # 'ׁ' + 45: 1, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 1, # 'ה' + 2: 2, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 2, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 1, # 'ם' + 6: 2, # 'מ' + 23: 1, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 1, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 38: { # 'ׁ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 2, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 45: { # 'ׂ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 2, # 'ֶ' + 31: 1, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 1, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 2, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 1, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 0, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 9: { # 'א' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 2, # 'ֱ' + 41: 2, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 2, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 8: { # 'ב' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 3, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 1, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 20: { # 'ג' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 2, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 1, # 'ִ' + 37: 1, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 0, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 1, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 16: { # 'ד' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 1, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 3: { # 'ה' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 1, # 'ֱ' + 41: 2, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 3, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 0, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 2: { # 'ו' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 3, # 'ֹ' + 62: 0, # 'ֻ' + 28: 3, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 3, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 24: { # 'ז' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 1, # 'ֲ' + 33: 1, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 2, # 'ח' + 22: 1, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 1, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 14: { # 'ח' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 1, # 'ֱ' + 41: 2, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 1, # 'ע' + 26: 2, # 'ף' + 18: 2, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 22: { # 'ט' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 1, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 1, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 1, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 3, # 'ר' + 10: 2, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 1: { # 'י' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 3, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 25: { # 'ך' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 2, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 1, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 15: { # 'כ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 3, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 2, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 4: { # 'ל' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 3, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 11: { # 'ם' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 1, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 1, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 6: { # 'מ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 0, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 23: { # 'ן' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 1, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 12: { # 'נ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 19: { # 'ס' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 1, # 'ָ' + 35: 1, # 'ֹ' + 62: 2, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 1, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 1, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 13: { # 'ע' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 1, # 'ֱ' + 41: 2, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 1, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 2, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 26: { # 'ף' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 1, # 'ס' + 13: 0, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 18: { # 'פ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 2, # 'ֶ' + 31: 1, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 2, # 'ב' + 20: 3, # 'ג' + 16: 2, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 2, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 27: { # 'ץ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 1, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 0, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 21: { # 'צ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 1, # 'ז' + 14: 3, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 1, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 1, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 0, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 17: { # 'ק' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 1, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 2, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 7: { # 'ר' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 2, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 1, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 3, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 10: { # 'ש' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 1, # 'ִ' + 37: 1, # 'ֵ' + 36: 1, # 'ֶ' + 31: 1, # 'ַ' + 29: 1, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 3, # 'ׁ' + 45: 2, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 5: { # 'ת' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 1, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 2, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 32: { # '–' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 1, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 52: { # '’' + 50: 1, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 1, # 'r' + 43: 2, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 47: { # '“' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 46: { # '”' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 58: { # '†' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 2, # '†' + 40: 0, # '…' + }, + 40: { # '…' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 0, # 'l' + 54: 1, # 'n' + 49: 0, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +WINDOWS_1255_HEBREW_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 69, # 'A' + 66: 91, # 'B' + 67: 79, # 'C' + 68: 80, # 'D' + 69: 92, # 'E' + 70: 89, # 'F' + 71: 97, # 'G' + 72: 90, # 'H' + 73: 68, # 'I' + 74: 111, # 'J' + 75: 112, # 'K' + 76: 82, # 'L' + 77: 73, # 'M' + 78: 95, # 'N' + 79: 85, # 'O' + 80: 78, # 'P' + 81: 121, # 'Q' + 82: 86, # 'R' + 83: 71, # 'S' + 84: 67, # 'T' + 85: 102, # 'U' + 86: 107, # 'V' + 87: 84, # 'W' + 88: 114, # 'X' + 89: 103, # 'Y' + 90: 115, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 50, # 'a' + 98: 74, # 'b' + 99: 60, # 'c' + 100: 61, # 'd' + 101: 42, # 'e' + 102: 76, # 'f' + 103: 70, # 'g' + 104: 64, # 'h' + 105: 53, # 'i' + 106: 105, # 'j' + 107: 93, # 'k' + 108: 56, # 'l' + 109: 65, # 'm' + 110: 54, # 'n' + 111: 49, # 'o' + 112: 66, # 'p' + 113: 110, # 'q' + 114: 51, # 'r' + 115: 43, # 's' + 116: 44, # 't' + 117: 63, # 'u' + 118: 81, # 'v' + 119: 77, # 'w' + 120: 98, # 'x' + 121: 75, # 'y' + 122: 108, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 124, # '€' + 129: 202, # None + 130: 203, # '‚' + 131: 204, # 'ƒ' + 132: 205, # '„' + 133: 40, # '…' + 134: 58, # '†' + 135: 206, # '‡' + 136: 207, # 'ˆ' + 137: 208, # '‰' + 138: 209, # None + 139: 210, # '‹' + 140: 211, # None + 141: 212, # None + 142: 213, # None + 143: 214, # None + 144: 215, # None + 145: 83, # '‘' + 146: 52, # '’' + 147: 47, # '“' + 148: 46, # '”' + 149: 72, # '•' + 150: 32, # '–' + 151: 94, # '—' + 152: 216, # '˜' + 153: 113, # '™' + 154: 217, # None + 155: 109, # '›' + 156: 218, # None + 157: 219, # None + 158: 220, # None + 159: 221, # None + 160: 34, # '\xa0' + 161: 116, # '¡' + 162: 222, # '¢' + 163: 118, # '£' + 164: 100, # '₪' + 165: 223, # '¥' + 166: 224, # '¦' + 167: 117, # '§' + 168: 119, # '¨' + 169: 104, # '©' + 170: 125, # '×' + 171: 225, # '«' + 172: 226, # '¬' + 173: 87, # '\xad' + 174: 99, # '®' + 175: 227, # '¯' + 176: 106, # '°' + 177: 122, # '±' + 178: 123, # '²' + 179: 228, # '³' + 180: 55, # '´' + 181: 229, # 'µ' + 182: 230, # '¶' + 183: 101, # '·' + 184: 231, # '¸' + 185: 232, # '¹' + 186: 120, # '÷' + 187: 233, # '»' + 188: 48, # '¼' + 189: 39, # '½' + 190: 57, # '¾' + 191: 234, # '¿' + 192: 30, # 'ְ' + 193: 59, # 'ֱ' + 194: 41, # 'ֲ' + 195: 88, # 'ֳ' + 196: 33, # 'ִ' + 197: 37, # 'ֵ' + 198: 36, # 'ֶ' + 199: 31, # 'ַ' + 200: 29, # 'ָ' + 201: 35, # 'ֹ' + 202: 235, # None + 203: 62, # 'ֻ' + 204: 28, # 'ּ' + 205: 236, # 'ֽ' + 206: 126, # '־' + 207: 237, # 'ֿ' + 208: 238, # '׀' + 209: 38, # 'ׁ' + 210: 45, # 'ׂ' + 211: 239, # '׃' + 212: 240, # 'װ' + 213: 241, # 'ױ' + 214: 242, # 'ײ' + 215: 243, # '׳' + 216: 127, # '״' + 217: 244, # None + 218: 245, # None + 219: 246, # None + 220: 247, # None + 221: 248, # None + 222: 249, # None + 223: 250, # None + 224: 9, # 'א' + 225: 8, # 'ב' + 226: 20, # 'ג' + 227: 16, # 'ד' + 228: 3, # 'ה' + 229: 2, # 'ו' + 230: 24, # 'ז' + 231: 14, # 'ח' + 232: 22, # 'ט' + 233: 1, # 'י' + 234: 25, # 'ך' + 235: 15, # 'כ' + 236: 4, # 'ל' + 237: 11, # 'ם' + 238: 6, # 'מ' + 239: 23, # 'ן' + 240: 12, # 'נ' + 241: 19, # 'ס' + 242: 13, # 'ע' + 243: 26, # 'ף' + 244: 18, # 'פ' + 245: 27, # 'ץ' + 246: 21, # 'צ' + 247: 17, # 'ק' + 248: 7, # 'ר' + 249: 10, # 'ש' + 250: 5, # 'ת' + 251: 251, # None + 252: 252, # None + 253: 128, # '\u200e' + 254: 96, # '\u200f' + 255: 253, # None +} + +WINDOWS_1255_HEBREW_MODEL = SingleByteCharSetModel(charset_name='windows-1255', + language='Hebrew', + char_to_order_map=WINDOWS_1255_HEBREW_CHAR_TO_ORDER, + language_model=HEBREW_LANG_MODEL, + typical_positive_ratio=0.984004, + keep_ascii_letters=False, + alphabet='אבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ') + diff --git a/dist/ba_data/python-site-packages/chardet/langhungarianmodel.py b/dist/ba_data/python-site-packages/chardet/langhungarianmodel.py new file mode 100644 index 0000000..24a097f --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/langhungarianmodel.py @@ -0,0 +1,4650 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +HUNGARIAN_LANG_MODEL = { + 28: { # 'A' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 2, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 2, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 2, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 1, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 1, # 'Á' + 44: 0, # 'É' + 61: 1, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 40: { # 'B' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 0, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 3, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 54: { # 'C' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 0, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 3, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 45: { # 'D' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 0, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 1, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 32: { # 'E' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 2, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 1, # 't' + 21: 2, # 'u' + 19: 1, # 'v' + 62: 1, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 50: { # 'F' + 28: 1, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 0, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 49: { # 'G' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 2, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 38: { # 'H' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 0, # 'D' + 32: 1, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 1, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 1, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 0, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 2, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 2, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 39: { # 'I' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 2, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 0, # 'e' + 27: 1, # 'f' + 12: 2, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 53: { # 'J' + 28: 2, # 'A' + 40: 0, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 1, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 0, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 36: { # 'K' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 2, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 41: { # 'L' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 34: { # 'M' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 3, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 1, # 'ű' + }, + 35: { # 'N' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 2, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 2, # 'Y' + 52: 1, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 47: { # 'O' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 2, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 2, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 1, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 46: { # 'P' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 0, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 3, # 'á' + 15: 2, # 'é' + 30: 0, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 43: { # 'R' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 2, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 2, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 33: { # 'S' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 3, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 1, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 1, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 37: { # 'T' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 1, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 2, # 'Á' + 44: 2, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 57: { # 'U' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 2, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 1, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 48: { # 'V' + 28: 2, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 0, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 2, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 55: { # 'Y' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 2, # 'Z' + 2: 1, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 52: { # 'Z' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 1, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 1, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 2, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 2: { # 'a' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 2, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 2, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 18: { # 'b' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 2, # 's' + 3: 1, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 26: { # 'c' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 1, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 1, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 2, # 't' + 21: 2, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 2, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 17: { # 'd' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 2, # 'k' + 6: 1, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 1: { # 'e' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 3, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 2, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 2, # 'u' + 19: 3, # 'v' + 62: 2, # 'x' + 16: 2, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 27: { # 'f' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 3, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 2, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 3, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 12: { # 'g' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 2, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 2, # 'k' + 6: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 3, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 20: { # 'h' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 2, # 's' + 3: 1, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 9: { # 'i' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 3, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 2, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 3, # 'ó' + 24: 1, # 'ö' + 31: 2, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 1, # 'ű' + }, + 22: { # 'j' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 1, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 1, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 7: { # 'k' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 2, # 'ó' + 24: 3, # 'ö' + 31: 1, # 'ú' + 29: 3, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 6: { # 'l' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 1, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 3, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 3, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 3, # 'ő' + 56: 1, # 'ű' + }, + 13: { # 'm' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 1, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 3, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 2, # 'ű' + }, + 4: { # 'n' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 1, # 'x' + 16: 3, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 8: { # 'o' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 2, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 23: { # 'p' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 10: { # 'r' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 2, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'ő' + 56: 2, # 'ű' + }, + 5: { # 's' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 2, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 3: { # 't' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 1, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 3, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 3, # 'ü' + 42: 3, # 'ő' + 56: 2, # 'ű' + }, + 21: { # 'u' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 2, # 'b' + 26: 2, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 1, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 0, # 'ö' + 31: 1, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 19: { # 'v' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 2, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 62: { # 'x' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 16: { # 'y' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 2, # 'ű' + }, + 11: { # 'z' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 51: { # 'Á' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 1, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 44: { # 'É' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 0, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 61: { # 'Í' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 0, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 2, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 1, # 'm' + 4: 0, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 0, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 58: { # 'Ó' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 2, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 0, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 59: { # 'Ö' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 0, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 60: { # 'Ú' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 2, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 2, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 63: { # 'Ü' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 0, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 14: { # 'á' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 1, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 2, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 2, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 15: { # 'é' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 3, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 0, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 30: { # 'í' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 2, # 's' + 3: 3, # 't' + 21: 0, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 25: { # 'ó' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 3, # 'd' + 1: 1, # 'e' + 27: 2, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 1, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 24: { # 'ö' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 0, # 'a' + 18: 3, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 0, # 'e' + 27: 1, # 'f' + 12: 2, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 0, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 0, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 31: { # 'ú' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 3, # 'j' + 7: 1, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 2, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 29: { # 'ü' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 0, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 42: { # 'ő' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 56: { # 'ű' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 0, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 28, # 'A' + 66: 40, # 'B' + 67: 54, # 'C' + 68: 45, # 'D' + 69: 32, # 'E' + 70: 50, # 'F' + 71: 49, # 'G' + 72: 38, # 'H' + 73: 39, # 'I' + 74: 53, # 'J' + 75: 36, # 'K' + 76: 41, # 'L' + 77: 34, # 'M' + 78: 35, # 'N' + 79: 47, # 'O' + 80: 46, # 'P' + 81: 72, # 'Q' + 82: 43, # 'R' + 83: 33, # 'S' + 84: 37, # 'T' + 85: 57, # 'U' + 86: 48, # 'V' + 87: 64, # 'W' + 88: 68, # 'X' + 89: 55, # 'Y' + 90: 52, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 2, # 'a' + 98: 18, # 'b' + 99: 26, # 'c' + 100: 17, # 'd' + 101: 1, # 'e' + 102: 27, # 'f' + 103: 12, # 'g' + 104: 20, # 'h' + 105: 9, # 'i' + 106: 22, # 'j' + 107: 7, # 'k' + 108: 6, # 'l' + 109: 13, # 'm' + 110: 4, # 'n' + 111: 8, # 'o' + 112: 23, # 'p' + 113: 67, # 'q' + 114: 10, # 'r' + 115: 5, # 's' + 116: 3, # 't' + 117: 21, # 'u' + 118: 19, # 'v' + 119: 65, # 'w' + 120: 62, # 'x' + 121: 16, # 'y' + 122: 11, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 161, # '€' + 129: 162, # None + 130: 163, # '‚' + 131: 164, # None + 132: 165, # '„' + 133: 166, # '…' + 134: 167, # '†' + 135: 168, # '‡' + 136: 169, # None + 137: 170, # '‰' + 138: 171, # 'Š' + 139: 172, # '‹' + 140: 173, # 'Ś' + 141: 174, # 'Ť' + 142: 175, # 'Ž' + 143: 176, # 'Ź' + 144: 177, # None + 145: 178, # '‘' + 146: 179, # '’' + 147: 180, # '“' + 148: 78, # '”' + 149: 181, # '•' + 150: 69, # '–' + 151: 182, # '—' + 152: 183, # None + 153: 184, # '™' + 154: 185, # 'š' + 155: 186, # '›' + 156: 187, # 'ś' + 157: 188, # 'ť' + 158: 189, # 'ž' + 159: 190, # 'ź' + 160: 191, # '\xa0' + 161: 192, # 'ˇ' + 162: 193, # '˘' + 163: 194, # 'Ł' + 164: 195, # '¤' + 165: 196, # 'Ą' + 166: 197, # '¦' + 167: 76, # '§' + 168: 198, # '¨' + 169: 199, # '©' + 170: 200, # 'Ş' + 171: 201, # '«' + 172: 202, # '¬' + 173: 203, # '\xad' + 174: 204, # '®' + 175: 205, # 'Ż' + 176: 81, # '°' + 177: 206, # '±' + 178: 207, # '˛' + 179: 208, # 'ł' + 180: 209, # '´' + 181: 210, # 'µ' + 182: 211, # '¶' + 183: 212, # '·' + 184: 213, # '¸' + 185: 214, # 'ą' + 186: 215, # 'ş' + 187: 216, # '»' + 188: 217, # 'Ľ' + 189: 218, # '˝' + 190: 219, # 'ľ' + 191: 220, # 'ż' + 192: 221, # 'Ŕ' + 193: 51, # 'Á' + 194: 83, # 'Â' + 195: 222, # 'Ă' + 196: 80, # 'Ä' + 197: 223, # 'Ĺ' + 198: 224, # 'Ć' + 199: 225, # 'Ç' + 200: 226, # 'Č' + 201: 44, # 'É' + 202: 227, # 'Ę' + 203: 228, # 'Ë' + 204: 229, # 'Ě' + 205: 61, # 'Í' + 206: 230, # 'Î' + 207: 231, # 'Ď' + 208: 232, # 'Đ' + 209: 233, # 'Ń' + 210: 234, # 'Ň' + 211: 58, # 'Ó' + 212: 235, # 'Ô' + 213: 66, # 'Ő' + 214: 59, # 'Ö' + 215: 236, # '×' + 216: 237, # 'Ř' + 217: 238, # 'Ů' + 218: 60, # 'Ú' + 219: 70, # 'Ű' + 220: 63, # 'Ü' + 221: 239, # 'Ý' + 222: 240, # 'Ţ' + 223: 241, # 'ß' + 224: 84, # 'ŕ' + 225: 14, # 'á' + 226: 75, # 'â' + 227: 242, # 'ă' + 228: 71, # 'ä' + 229: 82, # 'ĺ' + 230: 243, # 'ć' + 231: 73, # 'ç' + 232: 244, # 'č' + 233: 15, # 'é' + 234: 85, # 'ę' + 235: 79, # 'ë' + 236: 86, # 'ě' + 237: 30, # 'í' + 238: 77, # 'î' + 239: 87, # 'ď' + 240: 245, # 'đ' + 241: 246, # 'ń' + 242: 247, # 'ň' + 243: 25, # 'ó' + 244: 74, # 'ô' + 245: 42, # 'ő' + 246: 24, # 'ö' + 247: 248, # '÷' + 248: 249, # 'ř' + 249: 250, # 'ů' + 250: 31, # 'ú' + 251: 56, # 'ű' + 252: 29, # 'ü' + 253: 251, # 'ý' + 254: 252, # 'ţ' + 255: 253, # '˙' +} + +WINDOWS_1250_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1250', + language='Hungarian', + char_to_order_map=WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER, + language_model=HUNGARIAN_LANG_MODEL, + typical_positive_ratio=0.947368, + keep_ascii_letters=True, + alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÁÉÍÓÖÚÜáéíóöúüŐőŰű') + +ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 28, # 'A' + 66: 40, # 'B' + 67: 54, # 'C' + 68: 45, # 'D' + 69: 32, # 'E' + 70: 50, # 'F' + 71: 49, # 'G' + 72: 38, # 'H' + 73: 39, # 'I' + 74: 53, # 'J' + 75: 36, # 'K' + 76: 41, # 'L' + 77: 34, # 'M' + 78: 35, # 'N' + 79: 47, # 'O' + 80: 46, # 'P' + 81: 71, # 'Q' + 82: 43, # 'R' + 83: 33, # 'S' + 84: 37, # 'T' + 85: 57, # 'U' + 86: 48, # 'V' + 87: 64, # 'W' + 88: 68, # 'X' + 89: 55, # 'Y' + 90: 52, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 2, # 'a' + 98: 18, # 'b' + 99: 26, # 'c' + 100: 17, # 'd' + 101: 1, # 'e' + 102: 27, # 'f' + 103: 12, # 'g' + 104: 20, # 'h' + 105: 9, # 'i' + 106: 22, # 'j' + 107: 7, # 'k' + 108: 6, # 'l' + 109: 13, # 'm' + 110: 4, # 'n' + 111: 8, # 'o' + 112: 23, # 'p' + 113: 67, # 'q' + 114: 10, # 'r' + 115: 5, # 's' + 116: 3, # 't' + 117: 21, # 'u' + 118: 19, # 'v' + 119: 65, # 'w' + 120: 62, # 'x' + 121: 16, # 'y' + 122: 11, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 159, # '\x80' + 129: 160, # '\x81' + 130: 161, # '\x82' + 131: 162, # '\x83' + 132: 163, # '\x84' + 133: 164, # '\x85' + 134: 165, # '\x86' + 135: 166, # '\x87' + 136: 167, # '\x88' + 137: 168, # '\x89' + 138: 169, # '\x8a' + 139: 170, # '\x8b' + 140: 171, # '\x8c' + 141: 172, # '\x8d' + 142: 173, # '\x8e' + 143: 174, # '\x8f' + 144: 175, # '\x90' + 145: 176, # '\x91' + 146: 177, # '\x92' + 147: 178, # '\x93' + 148: 179, # '\x94' + 149: 180, # '\x95' + 150: 181, # '\x96' + 151: 182, # '\x97' + 152: 183, # '\x98' + 153: 184, # '\x99' + 154: 185, # '\x9a' + 155: 186, # '\x9b' + 156: 187, # '\x9c' + 157: 188, # '\x9d' + 158: 189, # '\x9e' + 159: 190, # '\x9f' + 160: 191, # '\xa0' + 161: 192, # 'Ą' + 162: 193, # '˘' + 163: 194, # 'Ł' + 164: 195, # '¤' + 165: 196, # 'Ľ' + 166: 197, # 'Ś' + 167: 75, # '§' + 168: 198, # '¨' + 169: 199, # 'Š' + 170: 200, # 'Ş' + 171: 201, # 'Ť' + 172: 202, # 'Ź' + 173: 203, # '\xad' + 174: 204, # 'Ž' + 175: 205, # 'Ż' + 176: 79, # '°' + 177: 206, # 'ą' + 178: 207, # '˛' + 179: 208, # 'ł' + 180: 209, # '´' + 181: 210, # 'ľ' + 182: 211, # 'ś' + 183: 212, # 'ˇ' + 184: 213, # '¸' + 185: 214, # 'š' + 186: 215, # 'ş' + 187: 216, # 'ť' + 188: 217, # 'ź' + 189: 218, # '˝' + 190: 219, # 'ž' + 191: 220, # 'ż' + 192: 221, # 'Ŕ' + 193: 51, # 'Á' + 194: 81, # 'Â' + 195: 222, # 'Ă' + 196: 78, # 'Ä' + 197: 223, # 'Ĺ' + 198: 224, # 'Ć' + 199: 225, # 'Ç' + 200: 226, # 'Č' + 201: 44, # 'É' + 202: 227, # 'Ę' + 203: 228, # 'Ë' + 204: 229, # 'Ě' + 205: 61, # 'Í' + 206: 230, # 'Î' + 207: 231, # 'Ď' + 208: 232, # 'Đ' + 209: 233, # 'Ń' + 210: 234, # 'Ň' + 211: 58, # 'Ó' + 212: 235, # 'Ô' + 213: 66, # 'Ő' + 214: 59, # 'Ö' + 215: 236, # '×' + 216: 237, # 'Ř' + 217: 238, # 'Ů' + 218: 60, # 'Ú' + 219: 69, # 'Ű' + 220: 63, # 'Ü' + 221: 239, # 'Ý' + 222: 240, # 'Ţ' + 223: 241, # 'ß' + 224: 82, # 'ŕ' + 225: 14, # 'á' + 226: 74, # 'â' + 227: 242, # 'ă' + 228: 70, # 'ä' + 229: 80, # 'ĺ' + 230: 243, # 'ć' + 231: 72, # 'ç' + 232: 244, # 'č' + 233: 15, # 'é' + 234: 83, # 'ę' + 235: 77, # 'ë' + 236: 84, # 'ě' + 237: 30, # 'í' + 238: 76, # 'î' + 239: 85, # 'ď' + 240: 245, # 'đ' + 241: 246, # 'ń' + 242: 247, # 'ň' + 243: 25, # 'ó' + 244: 73, # 'ô' + 245: 42, # 'ő' + 246: 24, # 'ö' + 247: 248, # '÷' + 248: 249, # 'ř' + 249: 250, # 'ů' + 250: 31, # 'ú' + 251: 56, # 'ű' + 252: 29, # 'ü' + 253: 251, # 'ý' + 254: 252, # 'ţ' + 255: 253, # '˙' +} + +ISO_8859_2_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-2', + language='Hungarian', + char_to_order_map=ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER, + language_model=HUNGARIAN_LANG_MODEL, + typical_positive_ratio=0.947368, + keep_ascii_letters=True, + alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÁÉÍÓÖÚÜáéíóöúüŐőŰű') + diff --git a/dist/ba_data/python-site-packages/chardet/langrussianmodel.py b/dist/ba_data/python-site-packages/chardet/langrussianmodel.py new file mode 100644 index 0000000..569689d --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/langrussianmodel.py @@ -0,0 +1,5718 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +RUSSIAN_LANG_MODEL = { + 37: { # 'А' + 37: 0, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 2, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 1, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 0, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 44: { # 'Б' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 2, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 33: { # 'В' + 37: 2, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 2, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 1, # 'ъ' + 18: 3, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 0, # 'ю' + 16: 1, # 'я' + }, + 46: { # 'Г' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 41: { # 'Д' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 2, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 3, # 'ж' + 20: 1, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 48: { # 'Е' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 2, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 2, # 'Р' + 32: 2, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 2, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 1, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 1, # 'р' + 7: 3, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 56: { # 'Ж' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 1, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 2, # 'ю' + 16: 0, # 'я' + }, + 51: { # 'З' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 1, # 'я' + }, + 42: { # 'И' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 2, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 2, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 2, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 1, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 1, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 60: { # 'Й' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 1, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 36: { # 'К' + 37: 2, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 2, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 1, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 49: { # 'Л' + 37: 2, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 0, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 0, # 'м' + 5: 1, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 2, # 'ю' + 16: 1, # 'я' + }, + 38: { # 'М' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 0, # 'Ь' + 47: 1, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 1, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 31: { # 'Н' + 37: 2, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 2, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 3, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 34: { # 'О' + 37: 0, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 2, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 2, # 'Л' + 38: 1, # 'М' + 31: 2, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 2, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 1, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 1, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 35: { # 'П' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 2, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'р' + 7: 1, # 'с' + 6: 1, # 'т' + 14: 2, # 'у' + 39: 1, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 0, # 'ю' + 16: 2, # 'я' + }, + 45: { # 'Р' + 37: 2, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 2, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 2, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 2, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 2, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 2, # 'я' + }, + 32: { # 'С' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 2, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 2, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 1, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 40: { # 'Т' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 2, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 1, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 52: { # 'У' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 1, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 2, # 'и' + 23: 1, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 1, # 'н' + 1: 2, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 0, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 53: { # 'Ф' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 1, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 55: { # 'Х' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 58: { # 'Ц' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 50: { # 'Ч' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 1, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 1, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 57: { # 'Ш' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 2, # 'о' + 15: 2, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 63: { # 'Щ' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 1, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 1, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 62: { # 'Ы' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 0, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 0, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 61: { # 'Ь' + 37: 0, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 1, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 0, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 47: { # 'Э' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 2, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 59: { # 'Ю' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 1, # 'р' + 7: 1, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 43: { # 'Я' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 0, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 0, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 1, # 'й' + 11: 1, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 1, # 'р' + 7: 1, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 3: { # 'а' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 21: { # 'б' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 0, # 'ф' + 26: 2, # 'х' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 3, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 10: { # 'в' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 3, # 'я' + }, + 19: { # 'г' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 13: { # 'д' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 3, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 2: { # 'е' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 24: { # 'ж' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 1, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 0, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 20: { # 'з' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 3, # 'я' + }, + 4: { # 'и' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 23: { # 'й' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 2, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 2, # 'ф' + 26: 1, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 2, # 'я' + }, + 11: { # 'к' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 3, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 8: { # 'л' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 3, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 1, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 1, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 12: { # 'м' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 2, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 3, # 'я' + }, + 5: { # 'н' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 2, # 'щ' + 54: 1, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 1: { # 'о' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 15: { # 'п' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 3, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 0, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 3, # 'я' + }, + 9: { # 'р' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 2, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 2, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 7: { # 'с' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 6: { # 'т' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 2, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 2, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 14: { # 'у' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 2, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 2, # 'я' + }, + 39: { # 'ф' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 1, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 2, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 26: { # 'х' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 3, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 3, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 1, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 28: { # 'ц' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 1, # 'т' + 14: 3, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 1, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 1, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 22: { # 'ч' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 3, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 25: { # 'ш' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 29: { # 'щ' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 1, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 2, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 54: { # 'ъ' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 2, # 'я' + }, + 18: { # 'ы' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 2, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 1, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 2, # 'я' + }, + 17: { # 'ь' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 0, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 2, # 'п' + 9: 1, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 0, # 'у' + 39: 2, # 'ф' + 26: 1, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 30: { # 'э' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 1, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 1, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 2, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 2, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 27: { # 'ю' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 1, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 1, # 'и' + 23: 1, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 1, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 0, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 2, # 'ю' + 16: 1, # 'я' + }, + 16: { # 'я' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 2, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 1, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 2, # 'ю' + 16: 2, # 'я' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +IBM866_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 37, # 'А' + 129: 44, # 'Б' + 130: 33, # 'В' + 131: 46, # 'Г' + 132: 41, # 'Д' + 133: 48, # 'Е' + 134: 56, # 'Ж' + 135: 51, # 'З' + 136: 42, # 'И' + 137: 60, # 'Й' + 138: 36, # 'К' + 139: 49, # 'Л' + 140: 38, # 'М' + 141: 31, # 'Н' + 142: 34, # 'О' + 143: 35, # 'П' + 144: 45, # 'Р' + 145: 32, # 'С' + 146: 40, # 'Т' + 147: 52, # 'У' + 148: 53, # 'Ф' + 149: 55, # 'Х' + 150: 58, # 'Ц' + 151: 50, # 'Ч' + 152: 57, # 'Ш' + 153: 63, # 'Щ' + 154: 70, # 'Ъ' + 155: 62, # 'Ы' + 156: 61, # 'Ь' + 157: 47, # 'Э' + 158: 59, # 'Ю' + 159: 43, # 'Я' + 160: 3, # 'а' + 161: 21, # 'б' + 162: 10, # 'в' + 163: 19, # 'г' + 164: 13, # 'д' + 165: 2, # 'е' + 166: 24, # 'ж' + 167: 20, # 'з' + 168: 4, # 'и' + 169: 23, # 'й' + 170: 11, # 'к' + 171: 8, # 'л' + 172: 12, # 'м' + 173: 5, # 'н' + 174: 1, # 'о' + 175: 15, # 'п' + 176: 191, # '░' + 177: 192, # '▒' + 178: 193, # '▓' + 179: 194, # '│' + 180: 195, # '┤' + 181: 196, # '╡' + 182: 197, # '╢' + 183: 198, # '╖' + 184: 199, # '╕' + 185: 200, # '╣' + 186: 201, # '║' + 187: 202, # '╗' + 188: 203, # '╝' + 189: 204, # '╜' + 190: 205, # '╛' + 191: 206, # '┐' + 192: 207, # '└' + 193: 208, # '┴' + 194: 209, # '┬' + 195: 210, # '├' + 196: 211, # '─' + 197: 212, # '┼' + 198: 213, # '╞' + 199: 214, # '╟' + 200: 215, # '╚' + 201: 216, # '╔' + 202: 217, # '╩' + 203: 218, # '╦' + 204: 219, # '╠' + 205: 220, # '═' + 206: 221, # '╬' + 207: 222, # '╧' + 208: 223, # '╨' + 209: 224, # '╤' + 210: 225, # '╥' + 211: 226, # '╙' + 212: 227, # '╘' + 213: 228, # '╒' + 214: 229, # '╓' + 215: 230, # '╫' + 216: 231, # '╪' + 217: 232, # '┘' + 218: 233, # '┌' + 219: 234, # '█' + 220: 235, # '▄' + 221: 236, # '▌' + 222: 237, # '▐' + 223: 238, # '▀' + 224: 9, # 'р' + 225: 7, # 'с' + 226: 6, # 'т' + 227: 14, # 'у' + 228: 39, # 'ф' + 229: 26, # 'х' + 230: 28, # 'ц' + 231: 22, # 'ч' + 232: 25, # 'ш' + 233: 29, # 'щ' + 234: 54, # 'ъ' + 235: 18, # 'ы' + 236: 17, # 'ь' + 237: 30, # 'э' + 238: 27, # 'ю' + 239: 16, # 'я' + 240: 239, # 'Ё' + 241: 68, # 'ё' + 242: 240, # 'Є' + 243: 241, # 'є' + 244: 242, # 'Ї' + 245: 243, # 'ї' + 246: 244, # 'Ў' + 247: 245, # 'ў' + 248: 246, # '°' + 249: 247, # '∙' + 250: 248, # '·' + 251: 249, # '√' + 252: 250, # '№' + 253: 251, # '¤' + 254: 252, # '■' + 255: 255, # '\xa0' +} + +IBM866_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM866', + language='Russian', + char_to_order_map=IBM866_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # 'Ђ' + 129: 192, # 'Ѓ' + 130: 193, # '‚' + 131: 194, # 'ѓ' + 132: 195, # '„' + 133: 196, # '…' + 134: 197, # '†' + 135: 198, # '‡' + 136: 199, # '€' + 137: 200, # '‰' + 138: 201, # 'Љ' + 139: 202, # '‹' + 140: 203, # 'Њ' + 141: 204, # 'Ќ' + 142: 205, # 'Ћ' + 143: 206, # 'Џ' + 144: 207, # 'ђ' + 145: 208, # '‘' + 146: 209, # '’' + 147: 210, # '“' + 148: 211, # '”' + 149: 212, # '•' + 150: 213, # '–' + 151: 214, # '—' + 152: 215, # None + 153: 216, # '™' + 154: 217, # 'љ' + 155: 218, # '›' + 156: 219, # 'њ' + 157: 220, # 'ќ' + 158: 221, # 'ћ' + 159: 222, # 'џ' + 160: 223, # '\xa0' + 161: 224, # 'Ў' + 162: 225, # 'ў' + 163: 226, # 'Ј' + 164: 227, # '¤' + 165: 228, # 'Ґ' + 166: 229, # '¦' + 167: 230, # '§' + 168: 231, # 'Ё' + 169: 232, # '©' + 170: 233, # 'Є' + 171: 234, # '«' + 172: 235, # '¬' + 173: 236, # '\xad' + 174: 237, # '®' + 175: 238, # 'Ї' + 176: 239, # '°' + 177: 240, # '±' + 178: 241, # 'І' + 179: 242, # 'і' + 180: 243, # 'ґ' + 181: 244, # 'µ' + 182: 245, # '¶' + 183: 246, # '·' + 184: 68, # 'ё' + 185: 247, # '№' + 186: 248, # 'є' + 187: 249, # '»' + 188: 250, # 'ј' + 189: 251, # 'Ѕ' + 190: 252, # 'ѕ' + 191: 253, # 'ї' + 192: 37, # 'А' + 193: 44, # 'Б' + 194: 33, # 'В' + 195: 46, # 'Г' + 196: 41, # 'Д' + 197: 48, # 'Е' + 198: 56, # 'Ж' + 199: 51, # 'З' + 200: 42, # 'И' + 201: 60, # 'Й' + 202: 36, # 'К' + 203: 49, # 'Л' + 204: 38, # 'М' + 205: 31, # 'Н' + 206: 34, # 'О' + 207: 35, # 'П' + 208: 45, # 'Р' + 209: 32, # 'С' + 210: 40, # 'Т' + 211: 52, # 'У' + 212: 53, # 'Ф' + 213: 55, # 'Х' + 214: 58, # 'Ц' + 215: 50, # 'Ч' + 216: 57, # 'Ш' + 217: 63, # 'Щ' + 218: 70, # 'Ъ' + 219: 62, # 'Ы' + 220: 61, # 'Ь' + 221: 47, # 'Э' + 222: 59, # 'Ю' + 223: 43, # 'Я' + 224: 3, # 'а' + 225: 21, # 'б' + 226: 10, # 'в' + 227: 19, # 'г' + 228: 13, # 'д' + 229: 2, # 'е' + 230: 24, # 'ж' + 231: 20, # 'з' + 232: 4, # 'и' + 233: 23, # 'й' + 234: 11, # 'к' + 235: 8, # 'л' + 236: 12, # 'м' + 237: 5, # 'н' + 238: 1, # 'о' + 239: 15, # 'п' + 240: 9, # 'р' + 241: 7, # 'с' + 242: 6, # 'т' + 243: 14, # 'у' + 244: 39, # 'ф' + 245: 26, # 'х' + 246: 28, # 'ц' + 247: 22, # 'ч' + 248: 25, # 'ш' + 249: 29, # 'щ' + 250: 54, # 'ъ' + 251: 18, # 'ы' + 252: 17, # 'ь' + 253: 30, # 'э' + 254: 27, # 'ю' + 255: 16, # 'я' +} + +WINDOWS_1251_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', + language='Russian', + char_to_order_map=WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +IBM855_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # 'ђ' + 129: 192, # 'Ђ' + 130: 193, # 'ѓ' + 131: 194, # 'Ѓ' + 132: 68, # 'ё' + 133: 195, # 'Ё' + 134: 196, # 'є' + 135: 197, # 'Є' + 136: 198, # 'ѕ' + 137: 199, # 'Ѕ' + 138: 200, # 'і' + 139: 201, # 'І' + 140: 202, # 'ї' + 141: 203, # 'Ї' + 142: 204, # 'ј' + 143: 205, # 'Ј' + 144: 206, # 'љ' + 145: 207, # 'Љ' + 146: 208, # 'њ' + 147: 209, # 'Њ' + 148: 210, # 'ћ' + 149: 211, # 'Ћ' + 150: 212, # 'ќ' + 151: 213, # 'Ќ' + 152: 214, # 'ў' + 153: 215, # 'Ў' + 154: 216, # 'џ' + 155: 217, # 'Џ' + 156: 27, # 'ю' + 157: 59, # 'Ю' + 158: 54, # 'ъ' + 159: 70, # 'Ъ' + 160: 3, # 'а' + 161: 37, # 'А' + 162: 21, # 'б' + 163: 44, # 'Б' + 164: 28, # 'ц' + 165: 58, # 'Ц' + 166: 13, # 'д' + 167: 41, # 'Д' + 168: 2, # 'е' + 169: 48, # 'Е' + 170: 39, # 'ф' + 171: 53, # 'Ф' + 172: 19, # 'г' + 173: 46, # 'Г' + 174: 218, # '«' + 175: 219, # '»' + 176: 220, # '░' + 177: 221, # '▒' + 178: 222, # '▓' + 179: 223, # '│' + 180: 224, # '┤' + 181: 26, # 'х' + 182: 55, # 'Х' + 183: 4, # 'и' + 184: 42, # 'И' + 185: 225, # '╣' + 186: 226, # '║' + 187: 227, # '╗' + 188: 228, # '╝' + 189: 23, # 'й' + 190: 60, # 'Й' + 191: 229, # '┐' + 192: 230, # '└' + 193: 231, # '┴' + 194: 232, # '┬' + 195: 233, # '├' + 196: 234, # '─' + 197: 235, # '┼' + 198: 11, # 'к' + 199: 36, # 'К' + 200: 236, # '╚' + 201: 237, # '╔' + 202: 238, # '╩' + 203: 239, # '╦' + 204: 240, # '╠' + 205: 241, # '═' + 206: 242, # '╬' + 207: 243, # '¤' + 208: 8, # 'л' + 209: 49, # 'Л' + 210: 12, # 'м' + 211: 38, # 'М' + 212: 5, # 'н' + 213: 31, # 'Н' + 214: 1, # 'о' + 215: 34, # 'О' + 216: 15, # 'п' + 217: 244, # '┘' + 218: 245, # '┌' + 219: 246, # '█' + 220: 247, # '▄' + 221: 35, # 'П' + 222: 16, # 'я' + 223: 248, # '▀' + 224: 43, # 'Я' + 225: 9, # 'р' + 226: 45, # 'Р' + 227: 7, # 'с' + 228: 32, # 'С' + 229: 6, # 'т' + 230: 40, # 'Т' + 231: 14, # 'у' + 232: 52, # 'У' + 233: 24, # 'ж' + 234: 56, # 'Ж' + 235: 10, # 'в' + 236: 33, # 'В' + 237: 17, # 'ь' + 238: 61, # 'Ь' + 239: 249, # '№' + 240: 250, # '\xad' + 241: 18, # 'ы' + 242: 62, # 'Ы' + 243: 20, # 'з' + 244: 51, # 'З' + 245: 25, # 'ш' + 246: 57, # 'Ш' + 247: 30, # 'э' + 248: 47, # 'Э' + 249: 29, # 'щ' + 250: 63, # 'Щ' + 251: 22, # 'ч' + 252: 50, # 'Ч' + 253: 251, # '§' + 254: 252, # '■' + 255: 255, # '\xa0' +} + +IBM855_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM855', + language='Russian', + char_to_order_map=IBM855_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +KOI8_R_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # '─' + 129: 192, # '│' + 130: 193, # '┌' + 131: 194, # '┐' + 132: 195, # '└' + 133: 196, # '┘' + 134: 197, # '├' + 135: 198, # '┤' + 136: 199, # '┬' + 137: 200, # '┴' + 138: 201, # '┼' + 139: 202, # '▀' + 140: 203, # '▄' + 141: 204, # '█' + 142: 205, # '▌' + 143: 206, # '▐' + 144: 207, # '░' + 145: 208, # '▒' + 146: 209, # '▓' + 147: 210, # '⌠' + 148: 211, # '■' + 149: 212, # '∙' + 150: 213, # '√' + 151: 214, # '≈' + 152: 215, # '≤' + 153: 216, # '≥' + 154: 217, # '\xa0' + 155: 218, # '⌡' + 156: 219, # '°' + 157: 220, # '²' + 158: 221, # '·' + 159: 222, # '÷' + 160: 223, # '═' + 161: 224, # '║' + 162: 225, # '╒' + 163: 68, # 'ё' + 164: 226, # '╓' + 165: 227, # '╔' + 166: 228, # '╕' + 167: 229, # '╖' + 168: 230, # '╗' + 169: 231, # '╘' + 170: 232, # '╙' + 171: 233, # '╚' + 172: 234, # '╛' + 173: 235, # '╜' + 174: 236, # '╝' + 175: 237, # '╞' + 176: 238, # '╟' + 177: 239, # '╠' + 178: 240, # '╡' + 179: 241, # 'Ё' + 180: 242, # '╢' + 181: 243, # '╣' + 182: 244, # '╤' + 183: 245, # '╥' + 184: 246, # '╦' + 185: 247, # '╧' + 186: 248, # '╨' + 187: 249, # '╩' + 188: 250, # '╪' + 189: 251, # '╫' + 190: 252, # '╬' + 191: 253, # '©' + 192: 27, # 'ю' + 193: 3, # 'а' + 194: 21, # 'б' + 195: 28, # 'ц' + 196: 13, # 'д' + 197: 2, # 'е' + 198: 39, # 'ф' + 199: 19, # 'г' + 200: 26, # 'х' + 201: 4, # 'и' + 202: 23, # 'й' + 203: 11, # 'к' + 204: 8, # 'л' + 205: 12, # 'м' + 206: 5, # 'н' + 207: 1, # 'о' + 208: 15, # 'п' + 209: 16, # 'я' + 210: 9, # 'р' + 211: 7, # 'с' + 212: 6, # 'т' + 213: 14, # 'у' + 214: 24, # 'ж' + 215: 10, # 'в' + 216: 17, # 'ь' + 217: 18, # 'ы' + 218: 20, # 'з' + 219: 25, # 'ш' + 220: 30, # 'э' + 221: 29, # 'щ' + 222: 22, # 'ч' + 223: 54, # 'ъ' + 224: 59, # 'Ю' + 225: 37, # 'А' + 226: 44, # 'Б' + 227: 58, # 'Ц' + 228: 41, # 'Д' + 229: 48, # 'Е' + 230: 53, # 'Ф' + 231: 46, # 'Г' + 232: 55, # 'Х' + 233: 42, # 'И' + 234: 60, # 'Й' + 235: 36, # 'К' + 236: 49, # 'Л' + 237: 38, # 'М' + 238: 31, # 'Н' + 239: 34, # 'О' + 240: 35, # 'П' + 241: 43, # 'Я' + 242: 45, # 'Р' + 243: 32, # 'С' + 244: 40, # 'Т' + 245: 52, # 'У' + 246: 56, # 'Ж' + 247: 33, # 'В' + 248: 61, # 'Ь' + 249: 62, # 'Ы' + 250: 51, # 'З' + 251: 57, # 'Ш' + 252: 47, # 'Э' + 253: 63, # 'Щ' + 254: 50, # 'Ч' + 255: 70, # 'Ъ' +} + +KOI8_R_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='KOI8-R', + language='Russian', + char_to_order_map=KOI8_R_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 37, # 'А' + 129: 44, # 'Б' + 130: 33, # 'В' + 131: 46, # 'Г' + 132: 41, # 'Д' + 133: 48, # 'Е' + 134: 56, # 'Ж' + 135: 51, # 'З' + 136: 42, # 'И' + 137: 60, # 'Й' + 138: 36, # 'К' + 139: 49, # 'Л' + 140: 38, # 'М' + 141: 31, # 'Н' + 142: 34, # 'О' + 143: 35, # 'П' + 144: 45, # 'Р' + 145: 32, # 'С' + 146: 40, # 'Т' + 147: 52, # 'У' + 148: 53, # 'Ф' + 149: 55, # 'Х' + 150: 58, # 'Ц' + 151: 50, # 'Ч' + 152: 57, # 'Ш' + 153: 63, # 'Щ' + 154: 70, # 'Ъ' + 155: 62, # 'Ы' + 156: 61, # 'Ь' + 157: 47, # 'Э' + 158: 59, # 'Ю' + 159: 43, # 'Я' + 160: 191, # '†' + 161: 192, # '°' + 162: 193, # 'Ґ' + 163: 194, # '£' + 164: 195, # '§' + 165: 196, # '•' + 166: 197, # '¶' + 167: 198, # 'І' + 168: 199, # '®' + 169: 200, # '©' + 170: 201, # '™' + 171: 202, # 'Ђ' + 172: 203, # 'ђ' + 173: 204, # '≠' + 174: 205, # 'Ѓ' + 175: 206, # 'ѓ' + 176: 207, # '∞' + 177: 208, # '±' + 178: 209, # '≤' + 179: 210, # '≥' + 180: 211, # 'і' + 181: 212, # 'µ' + 182: 213, # 'ґ' + 183: 214, # 'Ј' + 184: 215, # 'Є' + 185: 216, # 'є' + 186: 217, # 'Ї' + 187: 218, # 'ї' + 188: 219, # 'Љ' + 189: 220, # 'љ' + 190: 221, # 'Њ' + 191: 222, # 'њ' + 192: 223, # 'ј' + 193: 224, # 'Ѕ' + 194: 225, # '¬' + 195: 226, # '√' + 196: 227, # 'ƒ' + 197: 228, # '≈' + 198: 229, # '∆' + 199: 230, # '«' + 200: 231, # '»' + 201: 232, # '…' + 202: 233, # '\xa0' + 203: 234, # 'Ћ' + 204: 235, # 'ћ' + 205: 236, # 'Ќ' + 206: 237, # 'ќ' + 207: 238, # 'ѕ' + 208: 239, # '–' + 209: 240, # '—' + 210: 241, # '“' + 211: 242, # '”' + 212: 243, # '‘' + 213: 244, # '’' + 214: 245, # '÷' + 215: 246, # '„' + 216: 247, # 'Ў' + 217: 248, # 'ў' + 218: 249, # 'Џ' + 219: 250, # 'џ' + 220: 251, # '№' + 221: 252, # 'Ё' + 222: 68, # 'ё' + 223: 16, # 'я' + 224: 3, # 'а' + 225: 21, # 'б' + 226: 10, # 'в' + 227: 19, # 'г' + 228: 13, # 'д' + 229: 2, # 'е' + 230: 24, # 'ж' + 231: 20, # 'з' + 232: 4, # 'и' + 233: 23, # 'й' + 234: 11, # 'к' + 235: 8, # 'л' + 236: 12, # 'м' + 237: 5, # 'н' + 238: 1, # 'о' + 239: 15, # 'п' + 240: 9, # 'р' + 241: 7, # 'с' + 242: 6, # 'т' + 243: 14, # 'у' + 244: 39, # 'ф' + 245: 26, # 'х' + 246: 28, # 'ц' + 247: 22, # 'ч' + 248: 25, # 'ш' + 249: 29, # 'щ' + 250: 54, # 'ъ' + 251: 18, # 'ы' + 252: 17, # 'ь' + 253: 30, # 'э' + 254: 27, # 'ю' + 255: 255, # '€' +} + +MACCYRILLIC_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='MacCyrillic', + language='Russian', + char_to_order_map=MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +ISO_8859_5_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # '\x80' + 129: 192, # '\x81' + 130: 193, # '\x82' + 131: 194, # '\x83' + 132: 195, # '\x84' + 133: 196, # '\x85' + 134: 197, # '\x86' + 135: 198, # '\x87' + 136: 199, # '\x88' + 137: 200, # '\x89' + 138: 201, # '\x8a' + 139: 202, # '\x8b' + 140: 203, # '\x8c' + 141: 204, # '\x8d' + 142: 205, # '\x8e' + 143: 206, # '\x8f' + 144: 207, # '\x90' + 145: 208, # '\x91' + 146: 209, # '\x92' + 147: 210, # '\x93' + 148: 211, # '\x94' + 149: 212, # '\x95' + 150: 213, # '\x96' + 151: 214, # '\x97' + 152: 215, # '\x98' + 153: 216, # '\x99' + 154: 217, # '\x9a' + 155: 218, # '\x9b' + 156: 219, # '\x9c' + 157: 220, # '\x9d' + 158: 221, # '\x9e' + 159: 222, # '\x9f' + 160: 223, # '\xa0' + 161: 224, # 'Ё' + 162: 225, # 'Ђ' + 163: 226, # 'Ѓ' + 164: 227, # 'Є' + 165: 228, # 'Ѕ' + 166: 229, # 'І' + 167: 230, # 'Ї' + 168: 231, # 'Ј' + 169: 232, # 'Љ' + 170: 233, # 'Њ' + 171: 234, # 'Ћ' + 172: 235, # 'Ќ' + 173: 236, # '\xad' + 174: 237, # 'Ў' + 175: 238, # 'Џ' + 176: 37, # 'А' + 177: 44, # 'Б' + 178: 33, # 'В' + 179: 46, # 'Г' + 180: 41, # 'Д' + 181: 48, # 'Е' + 182: 56, # 'Ж' + 183: 51, # 'З' + 184: 42, # 'И' + 185: 60, # 'Й' + 186: 36, # 'К' + 187: 49, # 'Л' + 188: 38, # 'М' + 189: 31, # 'Н' + 190: 34, # 'О' + 191: 35, # 'П' + 192: 45, # 'Р' + 193: 32, # 'С' + 194: 40, # 'Т' + 195: 52, # 'У' + 196: 53, # 'Ф' + 197: 55, # 'Х' + 198: 58, # 'Ц' + 199: 50, # 'Ч' + 200: 57, # 'Ш' + 201: 63, # 'Щ' + 202: 70, # 'Ъ' + 203: 62, # 'Ы' + 204: 61, # 'Ь' + 205: 47, # 'Э' + 206: 59, # 'Ю' + 207: 43, # 'Я' + 208: 3, # 'а' + 209: 21, # 'б' + 210: 10, # 'в' + 211: 19, # 'г' + 212: 13, # 'д' + 213: 2, # 'е' + 214: 24, # 'ж' + 215: 20, # 'з' + 216: 4, # 'и' + 217: 23, # 'й' + 218: 11, # 'к' + 219: 8, # 'л' + 220: 12, # 'м' + 221: 5, # 'н' + 222: 1, # 'о' + 223: 15, # 'п' + 224: 9, # 'р' + 225: 7, # 'с' + 226: 6, # 'т' + 227: 14, # 'у' + 228: 39, # 'ф' + 229: 26, # 'х' + 230: 28, # 'ц' + 231: 22, # 'ч' + 232: 25, # 'ш' + 233: 29, # 'щ' + 234: 54, # 'ъ' + 235: 18, # 'ы' + 236: 17, # 'ь' + 237: 30, # 'э' + 238: 27, # 'ю' + 239: 16, # 'я' + 240: 239, # '№' + 241: 68, # 'ё' + 242: 240, # 'ђ' + 243: 241, # 'ѓ' + 244: 242, # 'є' + 245: 243, # 'ѕ' + 246: 244, # 'і' + 247: 245, # 'ї' + 248: 246, # 'ј' + 249: 247, # 'љ' + 250: 248, # 'њ' + 251: 249, # 'ћ' + 252: 250, # 'ќ' + 253: 251, # '§' + 254: 252, # 'ў' + 255: 255, # 'џ' +} + +ISO_8859_5_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', + language='Russian', + char_to_order_map=ISO_8859_5_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + diff --git a/dist/ba_data/python-site-packages/chardet/langthaimodel.py b/dist/ba_data/python-site-packages/chardet/langthaimodel.py new file mode 100644 index 0000000..d0191f2 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/langthaimodel.py @@ -0,0 +1,4383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +THAI_LANG_MODEL = { + 5: { # 'ก' + 5: 2, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 3, # 'ฎ' + 57: 2, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 2, # 'ณ' + 20: 2, # 'ด' + 19: 3, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 1, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 1, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 2, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 3, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 2, # 'ื' + 32: 2, # 'ุ' + 35: 1, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 3, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 30: { # 'ข' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 2, # 'ณ' + 20: 0, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 2, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 2, # 'ี' + 40: 3, # 'ึ' + 27: 1, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 2, # '่' + 7: 3, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 24: { # 'ค' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 2, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 0, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 2, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 3, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 8: { # 'ง' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 2, # 'ง' + 26: 2, # 'จ' + 52: 1, # 'ฉ' + 34: 2, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 2, # 'ศ' + 46: 1, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 1, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 1, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 3, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 26: { # 'จ' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 0, # 'ค' + 8: 2, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 3, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 2, # 'ิ' + 13: 1, # 'ี' + 40: 3, # 'ึ' + 27: 1, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 52: { # 'ฉ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 3, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 3, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 1, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 1, # 'ั' + 1: 1, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 34: { # 'ช' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 1, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 1, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 1, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 51: { # 'ซ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 1, # 'ั' + 1: 1, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 2, # 'ี' + 40: 3, # 'ึ' + 27: 2, # 'ื' + 32: 1, # 'ุ' + 35: 1, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 1, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 47: { # 'ญ' + 5: 1, # 'ก' + 30: 1, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 3, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 2, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 58: { # 'ฎ' + 5: 2, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 1, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 57: { # 'ฏ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 49: { # 'ฐ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 53: { # 'ฑ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 55: { # 'ฒ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 43: { # 'ณ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 3, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 3, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 3, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 20: { # 'ด' + 5: 2, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 3, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 2, # 'า' + 36: 2, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 1, # 'ึ' + 27: 2, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 2, # 'ๆ' + 37: 2, # '็' + 6: 1, # '่' + 7: 3, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 19: { # 'ต' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 2, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 2, # 'ภ' + 9: 1, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 0, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 1, # 'ึ' + 27: 1, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 2, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 44: { # 'ถ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 1, # 'ี' + 40: 3, # 'ึ' + 27: 2, # 'ื' + 32: 2, # 'ุ' + 35: 3, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 14: { # 'ท' + 5: 1, # 'ก' + 30: 1, # 'ข' + 24: 3, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 3, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 1, # 'ฤ' + 15: 1, # 'ล' + 12: 2, # 'ว' + 42: 3, # 'ศ' + 46: 1, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 1, # 'ื' + 32: 3, # 'ุ' + 35: 1, # 'ู' + 11: 0, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 48: { # 'ธ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 2, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 2, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 3: { # 'น' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 1, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 1, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 2, # 'ถ' + 14: 3, # 'ท' + 48: 3, # 'ธ' + 3: 2, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 1, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 3, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 3, # 'โ' + 29: 3, # 'ใ' + 33: 3, # 'ไ' + 50: 2, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 17: { # 'บ' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 1, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 2, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 2, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 2, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 25: { # 'ป' + 5: 2, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 1, # 'ฎ' + 57: 3, # 'ฏ' + 49: 1, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 1, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 1, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 3, # 'ั' + 1: 1, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 2, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 3, # '็' + 6: 1, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 39: { # 'ผ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 1, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 1, # 'ื' + 32: 0, # 'ุ' + 35: 3, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 1, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 62: { # 'ฝ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 1, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 1, # 'ี' + 40: 2, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 1, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 31: { # 'พ' + 5: 1, # 'ก' + 30: 1, # 'ข' + 24: 1, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 2, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 1, # 'ึ' + 27: 3, # 'ื' + 32: 1, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 0, # '่' + 7: 1, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 54: { # 'ฟ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 2, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 1, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 45: { # 'ภ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 2, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 9: { # 'ม' + 5: 2, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 3, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 2, # 'ร' + 61: 2, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 1, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 2, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 16: { # 'ย' + 5: 3, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 2, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 3, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 1, # 'ึ' + 27: 2, # 'ื' + 32: 2, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 2, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 2: { # 'ร' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 2, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 3, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 3, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 3, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 2, # 'น' + 17: 2, # 'บ' + 25: 3, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'ฝ' + 31: 2, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 2, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 3, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 3, # 'ู' + 11: 3, # 'เ' + 28: 3, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 3, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 61: { # 'ฤ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 2, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 15: { # 'ล' + 5: 2, # 'ก' + 30: 3, # 'ข' + 24: 1, # 'ค' + 8: 3, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 3, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 3, # 'อ' + 63: 2, # 'ฯ' + 22: 3, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 3, # 'ื' + 32: 2, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 2, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 12: { # 'ว' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 1, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 2, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 42: { # 'ศ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 1, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 2, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 0, # 'ี' + 40: 3, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 2, # 'ู' + 11: 0, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 46: { # 'ษ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 2, # 'ฎ' + 57: 1, # 'ฏ' + 49: 2, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 3, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 18: { # 'ส' + 5: 2, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 2, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 3, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 2, # 'ภ' + 9: 3, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 0, # 'แ' + 41: 1, # 'โ' + 29: 0, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 1, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 21: { # 'ห' + 5: 3, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 3, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 0, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 1, # 'ุ' + 35: 1, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 3, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 4: { # 'อ' + 5: 3, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 1, # '็' + 6: 2, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 63: { # 'ฯ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 22: { # 'ะ' + 5: 3, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 1, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 2, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 1, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 10: { # 'ั' + 5: 3, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 3, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 3, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 2, # 'ฐ' + 53: 0, # 'ฑ' + 55: 3, # 'ฒ' + 43: 3, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 1: { # 'า' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 3, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 1, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 3, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 2, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 1, # 'ฝ' + 31: 3, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 3, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 3, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 36: { # 'ำ' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 3, # 'ค' + 8: 2, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 1, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 3, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 23: { # 'ิ' + 5: 3, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 3, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 3, # 'พ' + 54: 1, # 'ฟ' + 45: 2, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 3, # 'ศ' + 46: 2, # 'ษ' + 18: 2, # 'ส' + 21: 3, # 'ห' + 4: 1, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 13: { # 'ี' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 3, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 40: { # 'ึ' + 5: 3, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 3, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 27: { # 'ื' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 3, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 32: { # 'ุ' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 3, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 1, # 'ฒ' + 43: 3, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 2, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 1, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 1, # 'ศ' + 46: 2, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 1, # 'โ' + 29: 0, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 35: { # 'ู' + 5: 3, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 2, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 3, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 11: { # 'เ' + 5: 3, # 'ก' + 30: 3, # 'ข' + 24: 3, # 'ค' + 8: 2, # 'ง' + 26: 3, # 'จ' + 52: 3, # 'ฉ' + 34: 3, # 'ช' + 51: 2, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 3, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'ฝ' + 31: 3, # 'พ' + 54: 1, # 'ฟ' + 45: 3, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 28: { # 'แ' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 1, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 3, # 'ต' + 44: 2, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 3, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 2, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 41: { # 'โ' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 1, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 3, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 0, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 29: { # 'ใ' + 5: 2, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 1, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 33: { # 'ไ' + 5: 1, # 'ก' + 30: 2, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 1, # 'บ' + 25: 3, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 2, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 0, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 2, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 50: { # 'ๆ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 37: { # '็' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 1, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 6: { # '่' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 1, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 7: { # '้' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 3, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 38: { # '์' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 1, # 'ฤ' + 15: 1, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 56: { # '๑' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 2, # '๑' + 59: 1, # '๒' + 60: 1, # '๕' + }, + 59: { # '๒' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 1, # '๑' + 59: 1, # '๒' + 60: 3, # '๕' + }, + 60: { # '๕' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 2, # '๑' + 59: 1, # '๒' + 60: 0, # '๕' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +TIS_620_THAI_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 182, # 'A' + 66: 106, # 'B' + 67: 107, # 'C' + 68: 100, # 'D' + 69: 183, # 'E' + 70: 184, # 'F' + 71: 185, # 'G' + 72: 101, # 'H' + 73: 94, # 'I' + 74: 186, # 'J' + 75: 187, # 'K' + 76: 108, # 'L' + 77: 109, # 'M' + 78: 110, # 'N' + 79: 111, # 'O' + 80: 188, # 'P' + 81: 189, # 'Q' + 82: 190, # 'R' + 83: 89, # 'S' + 84: 95, # 'T' + 85: 112, # 'U' + 86: 113, # 'V' + 87: 191, # 'W' + 88: 192, # 'X' + 89: 193, # 'Y' + 90: 194, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 64, # 'a' + 98: 72, # 'b' + 99: 73, # 'c' + 100: 114, # 'd' + 101: 74, # 'e' + 102: 115, # 'f' + 103: 116, # 'g' + 104: 102, # 'h' + 105: 81, # 'i' + 106: 201, # 'j' + 107: 117, # 'k' + 108: 90, # 'l' + 109: 103, # 'm' + 110: 78, # 'n' + 111: 82, # 'o' + 112: 96, # 'p' + 113: 202, # 'q' + 114: 91, # 'r' + 115: 79, # 's' + 116: 84, # 't' + 117: 104, # 'u' + 118: 105, # 'v' + 119: 97, # 'w' + 120: 98, # 'x' + 121: 92, # 'y' + 122: 203, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 209, # '\x80' + 129: 210, # '\x81' + 130: 211, # '\x82' + 131: 212, # '\x83' + 132: 213, # '\x84' + 133: 88, # '\x85' + 134: 214, # '\x86' + 135: 215, # '\x87' + 136: 216, # '\x88' + 137: 217, # '\x89' + 138: 218, # '\x8a' + 139: 219, # '\x8b' + 140: 220, # '\x8c' + 141: 118, # '\x8d' + 142: 221, # '\x8e' + 143: 222, # '\x8f' + 144: 223, # '\x90' + 145: 224, # '\x91' + 146: 99, # '\x92' + 147: 85, # '\x93' + 148: 83, # '\x94' + 149: 225, # '\x95' + 150: 226, # '\x96' + 151: 227, # '\x97' + 152: 228, # '\x98' + 153: 229, # '\x99' + 154: 230, # '\x9a' + 155: 231, # '\x9b' + 156: 232, # '\x9c' + 157: 233, # '\x9d' + 158: 234, # '\x9e' + 159: 235, # '\x9f' + 160: 236, # None + 161: 5, # 'ก' + 162: 30, # 'ข' + 163: 237, # 'ฃ' + 164: 24, # 'ค' + 165: 238, # 'ฅ' + 166: 75, # 'ฆ' + 167: 8, # 'ง' + 168: 26, # 'จ' + 169: 52, # 'ฉ' + 170: 34, # 'ช' + 171: 51, # 'ซ' + 172: 119, # 'ฌ' + 173: 47, # 'ญ' + 174: 58, # 'ฎ' + 175: 57, # 'ฏ' + 176: 49, # 'ฐ' + 177: 53, # 'ฑ' + 178: 55, # 'ฒ' + 179: 43, # 'ณ' + 180: 20, # 'ด' + 181: 19, # 'ต' + 182: 44, # 'ถ' + 183: 14, # 'ท' + 184: 48, # 'ธ' + 185: 3, # 'น' + 186: 17, # 'บ' + 187: 25, # 'ป' + 188: 39, # 'ผ' + 189: 62, # 'ฝ' + 190: 31, # 'พ' + 191: 54, # 'ฟ' + 192: 45, # 'ภ' + 193: 9, # 'ม' + 194: 16, # 'ย' + 195: 2, # 'ร' + 196: 61, # 'ฤ' + 197: 15, # 'ล' + 198: 239, # 'ฦ' + 199: 12, # 'ว' + 200: 42, # 'ศ' + 201: 46, # 'ษ' + 202: 18, # 'ส' + 203: 21, # 'ห' + 204: 76, # 'ฬ' + 205: 4, # 'อ' + 206: 66, # 'ฮ' + 207: 63, # 'ฯ' + 208: 22, # 'ะ' + 209: 10, # 'ั' + 210: 1, # 'า' + 211: 36, # 'ำ' + 212: 23, # 'ิ' + 213: 13, # 'ี' + 214: 40, # 'ึ' + 215: 27, # 'ื' + 216: 32, # 'ุ' + 217: 35, # 'ู' + 218: 86, # 'ฺ' + 219: 240, # None + 220: 241, # None + 221: 242, # None + 222: 243, # None + 223: 244, # '฿' + 224: 11, # 'เ' + 225: 28, # 'แ' + 226: 41, # 'โ' + 227: 29, # 'ใ' + 228: 33, # 'ไ' + 229: 245, # 'ๅ' + 230: 50, # 'ๆ' + 231: 37, # '็' + 232: 6, # '่' + 233: 7, # '้' + 234: 67, # '๊' + 235: 77, # '๋' + 236: 38, # '์' + 237: 93, # 'ํ' + 238: 246, # '๎' + 239: 247, # '๏' + 240: 68, # '๐' + 241: 56, # '๑' + 242: 59, # '๒' + 243: 65, # '๓' + 244: 69, # '๔' + 245: 60, # '๕' + 246: 70, # '๖' + 247: 80, # '๗' + 248: 71, # '๘' + 249: 87, # '๙' + 250: 248, # '๚' + 251: 249, # '๛' + 252: 250, # None + 253: 251, # None + 254: 252, # None + 255: 253, # None +} + +TIS_620_THAI_MODEL = SingleByteCharSetModel(charset_name='TIS-620', + language='Thai', + char_to_order_map=TIS_620_THAI_CHAR_TO_ORDER, + language_model=THAI_LANG_MODEL, + typical_positive_ratio=0.926386, + keep_ascii_letters=False, + alphabet='กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛') + diff --git a/dist/ba_data/python-site-packages/chardet/langturkishmodel.py b/dist/ba_data/python-site-packages/chardet/langturkishmodel.py new file mode 100644 index 0000000..8ba9322 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/langturkishmodel.py @@ -0,0 +1,4383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +TURKISH_LANG_MODEL = { + 23: { # 'A' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 1, # 'i' + 24: 0, # 'j' + 10: 2, # 'k' + 5: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 37: { # 'B' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 2, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 47: { # 'C' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 2, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 39: { # 'D' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Ş' + 19: 0, # 'ş' + }, + 29: { # 'E' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 1, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 52: { # 'F' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 1, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 1, # 'c' + 12: 1, # 'd' + 2: 0, # 'e' + 18: 1, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 2, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 2, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 2, # 'ş' + }, + 36: { # 'G' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 2, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 2, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 1, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 1, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 45: { # 'H' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 2, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 2, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 2, # 'ğ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 53: { # 'I' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 60: { # 'J' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 0, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 16: { # 'K' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 1, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 0, # 'u' + 32: 3, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 49: { # 'L' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 2, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 2, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 2, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 1, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 20: { # 'M' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 0, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 46: { # 'N' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 42: { # 'O' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 2, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 2, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 48: { # 'P' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 2, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 44: { # 'R' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 1, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 1, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 35: { # 'S' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 1, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 2, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 2, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 31: { # 'T' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 2, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 2, # 'r' + 8: 0, # 's' + 9: 2, # 't' + 14: 2, # 'u' + 32: 1, # 'v' + 57: 1, # 'w' + 58: 1, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 51: { # 'U' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 1, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 38: { # 'V' + 23: 1, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 1, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 62: { # 'W' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 43: { # 'Y' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 2, # 'N' + 42: 0, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 1, # 'Ü' + 59: 1, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 56: { # 'Z' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 2, # 'Z' + 1: 2, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 1, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 1: { # 'a' + 23: 3, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 2, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 1, # 'î' + 34: 1, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 21: { # 'b' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 3, # 'g' + 25: 1, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 1, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 2, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 28: { # 'c' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 2, # 'E' + 52: 0, # 'F' + 36: 2, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 2, # 'T' + 51: 2, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 3, # 'Y' + 56: 0, # 'Z' + 1: 1, # 'a' + 21: 1, # 'b' + 28: 2, # 'c' + 12: 2, # 'd' + 2: 1, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 1, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 1, # 'î' + 34: 2, # 'ö' + 17: 2, # 'ü' + 30: 2, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 2, # 'ş' + }, + 12: { # 'd' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 2: { # 'e' + 23: 2, # 'A' + 37: 0, # 'B' + 47: 2, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 18: { # 'f' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 1, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 1, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 27: { # 'g' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 2, # 'r' + 8: 2, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 25: { # 'h' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 3: { # 'i' + 23: 2, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 1, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 3, # 'g' + 25: 1, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 1, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 24: { # 'j' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 2, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 10: { # 'k' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 2, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 3, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 5: { # 'l' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 1, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 1, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 2, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 13: { # 'm' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 2, # 'u' + 32: 2, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 4: { # 'n' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 3, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 2, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 15: { # 'o' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 2, # 'L' + 20: 0, # 'M' + 46: 2, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 2, # 'ğ' + 41: 2, # 'İ' + 6: 3, # 'ı' + 40: 2, # 'Ş' + 19: 2, # 'ş' + }, + 26: { # 'p' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 2, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 7: { # 'r' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 1, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 3, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 8: { # 's' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 2, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 9: { # 't' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 14: { # 'u' + 23: 3, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 2, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 2, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 2, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 32: { # 'v' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 2, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 57: { # 'w' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 1, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 1, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 0, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 58: { # 'x' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 1, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 2, # 's' + 9: 1, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 11: { # 'y' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 2, # 'r' + 8: 1, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 22: { # 'z' + 23: 2, # 'A' + 37: 2, # 'B' + 47: 1, # 'C' + 39: 2, # 'D' + 29: 3, # 'E' + 52: 1, # 'F' + 36: 2, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 2, # 'N' + 42: 2, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 3, # 'T' + 51: 2, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 1, # 'Z' + 1: 1, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 2, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 0, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 2, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 2, # 'Ü' + 59: 1, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 2, # 'ü' + 30: 2, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 1, # 'Ş' + 19: 2, # 'ş' + }, + 63: { # '·' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 1, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 54: { # 'Ç' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 3, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 2, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 0, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 2, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 50: { # 'Ö' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 2, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 2, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 1, # 'N' + 42: 2, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 1, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 0, # 'j' + 10: 2, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 1, # 's' + 9: 2, # 't' + 14: 0, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 2, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 55: { # 'Ü' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 59: { # 'â' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Ş' + 19: 0, # 'ş' + }, + 33: { # 'ç' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 2, # 'f' + 27: 1, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 0, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 2, # 's' + 9: 3, # 't' + 14: 0, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 61: { # 'î' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 1, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 34: { # 'ö' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 2, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 1, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 3, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 2, # 'ğ' + 41: 1, # 'İ' + 6: 1, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 17: { # 'ü' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 2, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 30: { # 'ğ' + 23: 0, # 'A' + 37: 2, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 2, # 'N' + 42: 2, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 3, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 2, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 2, # 'İ' + 6: 2, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 41: { # 'İ' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 2, # 'G' + 45: 2, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 1, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 2, # 'd' + 2: 1, # 'e' + 18: 0, # 'f' + 27: 3, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 2, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 1, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 1, # 'ü' + 30: 2, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 6: { # 'ı' + 23: 2, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 1, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 40: { # 'Ş' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 2, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 1, # 'Z' + 1: 0, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 3, # 'f' + 27: 0, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 3, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 1, # 'u' + 32: 3, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 1, # 'ü' + 30: 2, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 1, # 'Ş' + 19: 2, # 'ş' + }, + 19: { # 'ş' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 2, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 1, # 'h' + 3: 1, # 'i' + 24: 0, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 1, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +ISO_8859_9_TURKISH_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 255, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 255, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 255, # ' ' + 33: 255, # '!' + 34: 255, # '"' + 35: 255, # '#' + 36: 255, # '$' + 37: 255, # '%' + 38: 255, # '&' + 39: 255, # "'" + 40: 255, # '(' + 41: 255, # ')' + 42: 255, # '*' + 43: 255, # '+' + 44: 255, # ',' + 45: 255, # '-' + 46: 255, # '.' + 47: 255, # '/' + 48: 255, # '0' + 49: 255, # '1' + 50: 255, # '2' + 51: 255, # '3' + 52: 255, # '4' + 53: 255, # '5' + 54: 255, # '6' + 55: 255, # '7' + 56: 255, # '8' + 57: 255, # '9' + 58: 255, # ':' + 59: 255, # ';' + 60: 255, # '<' + 61: 255, # '=' + 62: 255, # '>' + 63: 255, # '?' + 64: 255, # '@' + 65: 23, # 'A' + 66: 37, # 'B' + 67: 47, # 'C' + 68: 39, # 'D' + 69: 29, # 'E' + 70: 52, # 'F' + 71: 36, # 'G' + 72: 45, # 'H' + 73: 53, # 'I' + 74: 60, # 'J' + 75: 16, # 'K' + 76: 49, # 'L' + 77: 20, # 'M' + 78: 46, # 'N' + 79: 42, # 'O' + 80: 48, # 'P' + 81: 69, # 'Q' + 82: 44, # 'R' + 83: 35, # 'S' + 84: 31, # 'T' + 85: 51, # 'U' + 86: 38, # 'V' + 87: 62, # 'W' + 88: 65, # 'X' + 89: 43, # 'Y' + 90: 56, # 'Z' + 91: 255, # '[' + 92: 255, # '\\' + 93: 255, # ']' + 94: 255, # '^' + 95: 255, # '_' + 96: 255, # '`' + 97: 1, # 'a' + 98: 21, # 'b' + 99: 28, # 'c' + 100: 12, # 'd' + 101: 2, # 'e' + 102: 18, # 'f' + 103: 27, # 'g' + 104: 25, # 'h' + 105: 3, # 'i' + 106: 24, # 'j' + 107: 10, # 'k' + 108: 5, # 'l' + 109: 13, # 'm' + 110: 4, # 'n' + 111: 15, # 'o' + 112: 26, # 'p' + 113: 64, # 'q' + 114: 7, # 'r' + 115: 8, # 's' + 116: 9, # 't' + 117: 14, # 'u' + 118: 32, # 'v' + 119: 57, # 'w' + 120: 58, # 'x' + 121: 11, # 'y' + 122: 22, # 'z' + 123: 255, # '{' + 124: 255, # '|' + 125: 255, # '}' + 126: 255, # '~' + 127: 255, # '\x7f' + 128: 180, # '\x80' + 129: 179, # '\x81' + 130: 178, # '\x82' + 131: 177, # '\x83' + 132: 176, # '\x84' + 133: 175, # '\x85' + 134: 174, # '\x86' + 135: 173, # '\x87' + 136: 172, # '\x88' + 137: 171, # '\x89' + 138: 170, # '\x8a' + 139: 169, # '\x8b' + 140: 168, # '\x8c' + 141: 167, # '\x8d' + 142: 166, # '\x8e' + 143: 165, # '\x8f' + 144: 164, # '\x90' + 145: 163, # '\x91' + 146: 162, # '\x92' + 147: 161, # '\x93' + 148: 160, # '\x94' + 149: 159, # '\x95' + 150: 101, # '\x96' + 151: 158, # '\x97' + 152: 157, # '\x98' + 153: 156, # '\x99' + 154: 155, # '\x9a' + 155: 154, # '\x9b' + 156: 153, # '\x9c' + 157: 152, # '\x9d' + 158: 151, # '\x9e' + 159: 106, # '\x9f' + 160: 150, # '\xa0' + 161: 149, # '¡' + 162: 148, # '¢' + 163: 147, # '£' + 164: 146, # '¤' + 165: 145, # '¥' + 166: 144, # '¦' + 167: 100, # '§' + 168: 143, # '¨' + 169: 142, # '©' + 170: 141, # 'ª' + 171: 140, # '«' + 172: 139, # '¬' + 173: 138, # '\xad' + 174: 137, # '®' + 175: 136, # '¯' + 176: 94, # '°' + 177: 80, # '±' + 178: 93, # '²' + 179: 135, # '³' + 180: 105, # '´' + 181: 134, # 'µ' + 182: 133, # '¶' + 183: 63, # '·' + 184: 132, # '¸' + 185: 131, # '¹' + 186: 130, # 'º' + 187: 129, # '»' + 188: 128, # '¼' + 189: 127, # '½' + 190: 126, # '¾' + 191: 125, # '¿' + 192: 124, # 'À' + 193: 104, # 'Á' + 194: 73, # 'Â' + 195: 99, # 'Ã' + 196: 79, # 'Ä' + 197: 85, # 'Å' + 198: 123, # 'Æ' + 199: 54, # 'Ç' + 200: 122, # 'È' + 201: 98, # 'É' + 202: 92, # 'Ê' + 203: 121, # 'Ë' + 204: 120, # 'Ì' + 205: 91, # 'Í' + 206: 103, # 'Î' + 207: 119, # 'Ï' + 208: 68, # 'Ğ' + 209: 118, # 'Ñ' + 210: 117, # 'Ò' + 211: 97, # 'Ó' + 212: 116, # 'Ô' + 213: 115, # 'Õ' + 214: 50, # 'Ö' + 215: 90, # '×' + 216: 114, # 'Ø' + 217: 113, # 'Ù' + 218: 112, # 'Ú' + 219: 111, # 'Û' + 220: 55, # 'Ü' + 221: 41, # 'İ' + 222: 40, # 'Ş' + 223: 86, # 'ß' + 224: 89, # 'à' + 225: 70, # 'á' + 226: 59, # 'â' + 227: 78, # 'ã' + 228: 71, # 'ä' + 229: 82, # 'å' + 230: 88, # 'æ' + 231: 33, # 'ç' + 232: 77, # 'è' + 233: 66, # 'é' + 234: 84, # 'ê' + 235: 83, # 'ë' + 236: 110, # 'ì' + 237: 75, # 'í' + 238: 61, # 'î' + 239: 96, # 'ï' + 240: 30, # 'ğ' + 241: 67, # 'ñ' + 242: 109, # 'ò' + 243: 74, # 'ó' + 244: 87, # 'ô' + 245: 102, # 'õ' + 246: 34, # 'ö' + 247: 95, # '÷' + 248: 81, # 'ø' + 249: 108, # 'ù' + 250: 76, # 'ú' + 251: 72, # 'û' + 252: 17, # 'ü' + 253: 6, # 'ı' + 254: 19, # 'ş' + 255: 107, # 'ÿ' +} + +ISO_8859_9_TURKISH_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-9', + language='Turkish', + char_to_order_map=ISO_8859_9_TURKISH_CHAR_TO_ORDER, + language_model=TURKISH_LANG_MODEL, + typical_positive_ratio=0.97029, + keep_ascii_letters=True, + alphabet='ABCDEFGHIJKLMNOPRSTUVYZabcdefghijklmnoprstuvyzÂÇÎÖÛÜâçîöûüĞğİıŞş') + diff --git a/dist/ba_data/python-site-packages/chardet/latin1prober.py b/dist/ba_data/python-site-packages/chardet/latin1prober.py new file mode 100644 index 0000000..7d1e8c2 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/latin1prober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +FREQ_CAT_NUM = 4 + +UDF = 0 # undefined +OTH = 1 # other +ASC = 2 # ascii capital letter +ASS = 3 # ascii small letter +ACV = 4 # accent capital vowel +ACO = 5 # accent capital other +ASV = 6 # accent small vowel +ASO = 7 # accent small other +CLASS_NUM = 8 # total classes + +Latin1_CharToClass = ( + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF +) + +# 0 : illegal +# 1 : very unlikely +# 2 : normal +# 3 : very likely +Latin1ClassModel = ( +# UDF OTH ASC ASS ACV ACO ASV ASO + 0, 0, 0, 0, 0, 0, 0, 0, # UDF + 0, 3, 3, 3, 3, 3, 3, 3, # OTH + 0, 3, 3, 3, 3, 3, 3, 3, # ASC + 0, 3, 3, 3, 1, 1, 3, 3, # ASS + 0, 3, 3, 3, 1, 2, 1, 2, # ACV + 0, 3, 3, 3, 3, 3, 3, 3, # ACO + 0, 3, 1, 3, 1, 1, 1, 3, # ASV + 0, 3, 1, 3, 1, 1, 3, 3, # ASO +) + + +class Latin1Prober(CharSetProber): + def __init__(self): + super(Latin1Prober, self).__init__() + self._last_char_class = None + self._freq_counter = None + self.reset() + + def reset(self): + self._last_char_class = OTH + self._freq_counter = [0] * FREQ_CAT_NUM + CharSetProber.reset(self) + + @property + def charset_name(self): + return "ISO-8859-1" + + @property + def language(self): + return "" + + def feed(self, byte_str): + byte_str = self.filter_with_english_letters(byte_str) + for c in byte_str: + char_class = Latin1_CharToClass[c] + freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) + + char_class] + if freq == 0: + self._state = ProbingState.NOT_ME + break + self._freq_counter[freq] += 1 + self._last_char_class = char_class + + return self.state + + def get_confidence(self): + if self.state == ProbingState.NOT_ME: + return 0.01 + + total = sum(self._freq_counter) + if total < 0.01: + confidence = 0.0 + else: + confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) + / total) + if confidence < 0.0: + confidence = 0.0 + # lower the confidence of latin1 so that other more accurate + # detector can take priority. + confidence = confidence * 0.73 + return confidence diff --git a/dist/ba_data/python-site-packages/chardet/mbcharsetprober.py b/dist/ba_data/python-site-packages/chardet/mbcharsetprober.py new file mode 100644 index 0000000..6256ecf --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/mbcharsetprober.py @@ -0,0 +1,91 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState + + +class MultiByteCharSetProber(CharSetProber): + """ + MultiByteCharSetProber + """ + + def __init__(self, lang_filter=None): + super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) + self.distribution_analyzer = None + self.coding_sm = None + self._last_char = [0, 0] + + def reset(self): + super(MultiByteCharSetProber, self).reset() + if self.coding_sm: + self.coding_sm.reset() + if self.distribution_analyzer: + self.distribution_analyzer.reset() + self._last_char = [0, 0] + + @property + def charset_name(self): + raise NotImplementedError + + @property + def language(self): + raise NotImplementedError + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.distribution_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + return self.distribution_analyzer.get_confidence() diff --git a/dist/ba_data/python-site-packages/chardet/mbcsgroupprober.py b/dist/ba_data/python-site-packages/chardet/mbcsgroupprober.py new file mode 100644 index 0000000..530abe7 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/mbcsgroupprober.py @@ -0,0 +1,54 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .utf8prober import UTF8Prober +from .sjisprober import SJISProber +from .eucjpprober import EUCJPProber +from .gb2312prober import GB2312Prober +from .euckrprober import EUCKRProber +from .cp949prober import CP949Prober +from .big5prober import Big5Prober +from .euctwprober import EUCTWProber + + +class MBCSGroupProber(CharSetGroupProber): + def __init__(self, lang_filter=None): + super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) + self.probers = [ + UTF8Prober(), + SJISProber(), + EUCJPProber(), + GB2312Prober(), + EUCKRProber(), + CP949Prober(), + Big5Prober(), + EUCTWProber() + ] + self.reset() diff --git a/dist/ba_data/python-site-packages/chardet/mbcssm.py b/dist/ba_data/python-site-packages/chardet/mbcssm.py new file mode 100644 index 0000000..8360d0f --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/mbcssm.py @@ -0,0 +1,572 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +# BIG5 + +BIG5_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 4,4,4,4,4,4,4,4, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 4,3,3,3,3,3,3,3, # a0 - a7 + 3,3,3,3,3,3,3,3, # a8 - af + 3,3,3,3,3,3,3,3, # b0 - b7 + 3,3,3,3,3,3,3,3, # b8 - bf + 3,3,3,3,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +BIG5_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 +) + +BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) + +BIG5_SM_MODEL = {'class_table': BIG5_CLS, + 'class_factor': 5, + 'state_table': BIG5_ST, + 'char_len_table': BIG5_CHAR_LEN_TABLE, + 'name': 'Big5'} + +# CP949 + +CP949_CLS = ( + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f + 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f + 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f + 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f + 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f + 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f + 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f + 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af + 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf + 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff +) + +CP949_ST = ( +#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 +) + +CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) + +CP949_SM_MODEL = {'class_table': CP949_CLS, + 'class_factor': 10, + 'state_table': CP949_ST, + 'char_len_table': CP949_CHAR_LEN_TABLE, + 'name': 'CP949'} + +# EUC-JP + +EUCJP_CLS = ( + 4,4,4,4,4,4,4,4, # 00 - 07 + 4,4,4,4,4,4,5,5, # 08 - 0f + 4,4,4,4,4,4,4,4, # 10 - 17 + 4,4,4,5,4,4,4,4, # 18 - 1f + 4,4,4,4,4,4,4,4, # 20 - 27 + 4,4,4,4,4,4,4,4, # 28 - 2f + 4,4,4,4,4,4,4,4, # 30 - 37 + 4,4,4,4,4,4,4,4, # 38 - 3f + 4,4,4,4,4,4,4,4, # 40 - 47 + 4,4,4,4,4,4,4,4, # 48 - 4f + 4,4,4,4,4,4,4,4, # 50 - 57 + 4,4,4,4,4,4,4,4, # 58 - 5f + 4,4,4,4,4,4,4,4, # 60 - 67 + 4,4,4,4,4,4,4,4, # 68 - 6f + 4,4,4,4,4,4,4,4, # 70 - 77 + 4,4,4,4,4,4,4,4, # 78 - 7f + 5,5,5,5,5,5,5,5, # 80 - 87 + 5,5,5,5,5,5,1,3, # 88 - 8f + 5,5,5,5,5,5,5,5, # 90 - 97 + 5,5,5,5,5,5,5,5, # 98 - 9f + 5,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,0,5 # f8 - ff +) + +EUCJP_ST = ( + 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f + 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 +) + +EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) + +EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, + 'class_factor': 6, + 'state_table': EUCJP_ST, + 'char_len_table': EUCJP_CHAR_LEN_TABLE, + 'name': 'EUC-JP'} + +# EUC-KR + +EUCKR_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,3,3,3, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,3,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 2,2,2,2,2,2,2,2, # e0 - e7 + 2,2,2,2,2,2,2,2, # e8 - ef + 2,2,2,2,2,2,2,2, # f0 - f7 + 2,2,2,2,2,2,2,0 # f8 - ff +) + +EUCKR_ST = ( + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f +) + +EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) + +EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, + 'class_factor': 4, + 'state_table': EUCKR_ST, + 'char_len_table': EUCKR_CHAR_LEN_TABLE, + 'name': 'EUC-KR'} + +# EUC-TW + +EUCTW_CLS = ( + 2,2,2,2,2,2,2,2, # 00 - 07 + 2,2,2,2,2,2,0,0, # 08 - 0f + 2,2,2,2,2,2,2,2, # 10 - 17 + 2,2,2,0,2,2,2,2, # 18 - 1f + 2,2,2,2,2,2,2,2, # 20 - 27 + 2,2,2,2,2,2,2,2, # 28 - 2f + 2,2,2,2,2,2,2,2, # 30 - 37 + 2,2,2,2,2,2,2,2, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,2, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,6,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,3,4,4,4,4,4,4, # a0 - a7 + 5,5,1,1,1,1,1,1, # a8 - af + 1,1,1,1,1,1,1,1, # b0 - b7 + 1,1,1,1,1,1,1,1, # b8 - bf + 1,1,3,1,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +EUCTW_ST = ( + MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 + MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 + MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) + +EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, + 'class_factor': 7, + 'state_table': EUCTW_ST, + 'char_len_table': EUCTW_CHAR_LEN_TABLE, + 'name': 'x-euc-tw'} + +# GB2312 + +GB2312_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 3,3,3,3,3,3,3,3, # 30 - 37 + 3,3,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,4, # 78 - 7f + 5,6,6,6,6,6,6,6, # 80 - 87 + 6,6,6,6,6,6,6,6, # 88 - 8f + 6,6,6,6,6,6,6,6, # 90 - 97 + 6,6,6,6,6,6,6,6, # 98 - 9f + 6,6,6,6,6,6,6,6, # a0 - a7 + 6,6,6,6,6,6,6,6, # a8 - af + 6,6,6,6,6,6,6,6, # b0 - b7 + 6,6,6,6,6,6,6,6, # b8 - bf + 6,6,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 6,6,6,6,6,6,6,6, # e0 - e7 + 6,6,6,6,6,6,6,6, # e8 - ef + 6,6,6,6,6,6,6,6, # f0 - f7 + 6,6,6,6,6,6,6,0 # f8 - ff +) + +GB2312_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 + 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +# To be accurate, the length of class 6 can be either 2 or 4. +# But it is not necessary to discriminate between the two since +# it is used for frequency analysis only, and we are validating +# each code range there as well. So it is safe to set it to be +# 2 here. +GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) + +GB2312_SM_MODEL = {'class_table': GB2312_CLS, + 'class_factor': 7, + 'state_table': GB2312_ST, + 'char_len_table': GB2312_CHAR_LEN_TABLE, + 'name': 'GB2312'} + +# Shift_JIS + +SJIS_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 3,3,3,3,3,2,2,3, # 80 - 87 + 3,3,3,3,3,3,3,3, # 88 - 8f + 3,3,3,3,3,3,3,3, # 90 - 97 + 3,3,3,3,3,3,3,3, # 98 - 9f + #0xa0 is illegal in sjis encoding, but some pages does + #contain such byte. We need to be more error forgiven. + 2,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,4,4,4, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,0,0,0) # f8 - ff + + +SJIS_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 +) + +SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) + +SJIS_SM_MODEL = {'class_table': SJIS_CLS, + 'class_factor': 6, + 'state_table': SJIS_ST, + 'char_len_table': SJIS_CHAR_LEN_TABLE, + 'name': 'Shift_JIS'} + +# UCS2-BE + +UCS2BE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2BE_ST = ( + 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 + 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f + 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 + 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f + 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) + +UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, + 'class_factor': 6, + 'state_table': UCS2BE_ST, + 'char_len_table': UCS2BE_CHAR_LEN_TABLE, + 'name': 'UTF-16BE'} + +# UCS2-LE + +UCS2LE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2LE_ST = ( + 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f + 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 + 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) + +UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, + 'class_factor': 6, + 'state_table': UCS2LE_ST, + 'char_len_table': UCS2LE_CHAR_LEN_TABLE, + 'name': 'UTF-16LE'} + +# UTF-8 + +UTF8_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 2,2,2,2,3,3,3,3, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 5,5,5,5,5,5,5,5, # a0 - a7 + 5,5,5,5,5,5,5,5, # a8 - af + 5,5,5,5,5,5,5,5, # b0 - b7 + 5,5,5,5,5,5,5,5, # b8 - bf + 0,0,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 7,8,8,8,8,8,8,8, # e0 - e7 + 8,8,8,8,8,9,8,8, # e8 - ef + 10,11,11,11,11,11,11,11, # f0 - f7 + 12,13,13,13,14,15,0,0 # f8 - ff +) + +UTF8_ST = ( + MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 + 9, 11, 8, 7, 6, 5, 4, 3,#08-0f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f + MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f + MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f + MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f + MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af + MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf +) + +UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) + +UTF8_SM_MODEL = {'class_table': UTF8_CLS, + 'class_factor': 16, + 'state_table': UTF8_ST, + 'char_len_table': UTF8_CHAR_LEN_TABLE, + 'name': 'UTF-8'} diff --git a/dist/ba_data/python-site-packages/chardet/metadata/__init__.py b/dist/ba_data/python-site-packages/chardet/metadata/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dist/ba_data/python-site-packages/chardet/metadata/languages.py b/dist/ba_data/python-site-packages/chardet/metadata/languages.py new file mode 100644 index 0000000..3237d5a --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/metadata/languages.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Metadata about languages used by our model training code for our +SingleByteCharSetProbers. Could be used for other things in the future. + +This code is based on the language metadata from the uchardet project. +""" +from __future__ import absolute_import, print_function + +from string import ascii_letters + + +# TODO: Add Ukranian (KOI8-U) + +class Language(object): + """Metadata about a language useful for training models + + :ivar name: The human name for the language, in English. + :type name: str + :ivar iso_code: 2-letter ISO 639-1 if possible, 3-letter ISO code otherwise, + or use another catalog as a last resort. + :type iso_code: str + :ivar use_ascii: Whether or not ASCII letters should be included in trained + models. + :type use_ascii: bool + :ivar charsets: The charsets we want to support and create data for. + :type charsets: list of str + :ivar alphabet: The characters in the language's alphabet. If `use_ascii` is + `True`, you only need to add those not in the ASCII set. + :type alphabet: str + :ivar wiki_start_pages: The Wikipedia pages to start from if we're crawling + Wikipedia for training data. + :type wiki_start_pages: list of str + """ + def __init__(self, name=None, iso_code=None, use_ascii=True, charsets=None, + alphabet=None, wiki_start_pages=None): + super(Language, self).__init__() + self.name = name + self.iso_code = iso_code + self.use_ascii = use_ascii + self.charsets = charsets + if self.use_ascii: + if alphabet: + alphabet += ascii_letters + else: + alphabet = ascii_letters + elif not alphabet: + raise ValueError('Must supply alphabet if use_ascii is False') + self.alphabet = ''.join(sorted(set(alphabet))) if alphabet else None + self.wiki_start_pages = wiki_start_pages + + def __repr__(self): + return '{}({})'.format(self.__class__.__name__, + ', '.join('{}={!r}'.format(k, v) + for k, v in self.__dict__.items() + if not k.startswith('_'))) + + +LANGUAGES = {'Arabic': Language(name='Arabic', + iso_code='ar', + use_ascii=False, + # We only support encodings that use isolated + # forms, because the current recommendation is + # that the rendering system handles presentation + # forms. This means we purposefully skip IBM864. + charsets=['ISO-8859-6', 'WINDOWS-1256', + 'CP720', 'CP864'], + alphabet=u'ءآأؤإئابةتثجحخدذرزسشصضطظعغػؼؽؾؿـفقكلمنهوىيًٌٍَُِّ', + wiki_start_pages=[u'الصفحة_الرئيسية']), + 'Belarusian': Language(name='Belarusian', + iso_code='be', + use_ascii=False, + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'IBM866', 'MacCyrillic'], + alphabet=(u'АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШЫЬЭЮЯ' + u'абвгдеёжзійклмнопрстуўфхцчшыьэюяʼ'), + wiki_start_pages=[u'Галоўная_старонка']), + 'Bulgarian': Language(name='Bulgarian', + iso_code='bg', + use_ascii=False, + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'IBM855'], + alphabet=(u'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯ' + u'абвгдежзийклмнопрстуфхцчшщъьюя'), + wiki_start_pages=[u'Начална_страница']), + 'Czech': Language(name='Czech', + iso_code='cz', + use_ascii=True, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=u'áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ', + wiki_start_pages=[u'Hlavní_strana']), + 'Danish': Language(name='Danish', + iso_code='da', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'æøåÆØÅ', + wiki_start_pages=[u'Forside']), + 'German': Language(name='German', + iso_code='de', + use_ascii=True, + charsets=['ISO-8859-1', 'WINDOWS-1252'], + alphabet=u'äöüßÄÖÜ', + wiki_start_pages=[u'Wikipedia:Hauptseite']), + 'Greek': Language(name='Greek', + iso_code='el', + use_ascii=False, + charsets=['ISO-8859-7', 'WINDOWS-1253'], + alphabet=(u'αβγδεζηθικλμνξοπρσςτυφχψωάέήίόύώ' + u'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΣΤΥΦΧΨΩΆΈΉΊΌΎΏ'), + wiki_start_pages=[u'Πύλη:Κύρια']), + 'English': Language(name='English', + iso_code='en', + use_ascii=True, + charsets=['ISO-8859-1', 'WINDOWS-1252'], + wiki_start_pages=[u'Main_Page']), + 'Esperanto': Language(name='Esperanto', + iso_code='eo', + # Q, W, X, and Y not used at all + use_ascii=False, + charsets=['ISO-8859-3'], + alphabet=(u'abcĉdefgĝhĥijĵklmnoprsŝtuŭvz' + u'ABCĈDEFGĜHĤIJĴKLMNOPRSŜTUŬVZ'), + wiki_start_pages=[u'Vikipedio:Ĉefpaĝo']), + 'Spanish': Language(name='Spanish', + iso_code='es', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'ñáéíóúüÑÁÉÍÓÚÜ', + wiki_start_pages=[u'Wikipedia:Portada']), + 'Estonian': Language(name='Estonian', + iso_code='et', + use_ascii=False, + charsets=['ISO-8859-4', 'ISO-8859-13', + 'WINDOWS-1257'], + # C, F, Š, Q, W, X, Y, Z, Ž are only for + # loanwords + alphabet=(u'ABDEGHIJKLMNOPRSTUVÕÄÖÜ' + u'abdeghijklmnoprstuvõäöü'), + wiki_start_pages=[u'Esileht']), + 'Finnish': Language(name='Finnish', + iso_code='fi', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'ÅÄÖŠŽåäöšž', + wiki_start_pages=[u'Wikipedia:Etusivu']), + 'French': Language(name='French', + iso_code='fr', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'œàâçèéîïùûêŒÀÂÇÈÉÎÏÙÛÊ', + wiki_start_pages=[u'Wikipédia:Accueil_principal', + u'Bœuf (animal)']), + 'Hebrew': Language(name='Hebrew', + iso_code='he', + use_ascii=False, + charsets=['ISO-8859-8', 'WINDOWS-1255'], + alphabet=u'אבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ', + wiki_start_pages=[u'עמוד_ראשי']), + 'Croatian': Language(name='Croatian', + iso_code='hr', + # Q, W, X, Y are only used for foreign words. + use_ascii=False, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=(u'abcčćdđefghijklmnoprsštuvzž' + u'ABCČĆDĐEFGHIJKLMNOPRSŠTUVZŽ'), + wiki_start_pages=[u'Glavna_stranica']), + 'Hungarian': Language(name='Hungarian', + iso_code='hu', + # Q, W, X, Y are only used for foreign words. + use_ascii=False, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=(u'abcdefghijklmnoprstuvzáéíóöőúüű' + u'ABCDEFGHIJKLMNOPRSTUVZÁÉÍÓÖŐÚÜŰ'), + wiki_start_pages=[u'Kezdőlap']), + 'Italian': Language(name='Italian', + iso_code='it', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'ÀÈÉÌÒÓÙàèéìòóù', + wiki_start_pages=[u'Pagina_principale']), + 'Lithuanian': Language(name='Lithuanian', + iso_code='lt', + use_ascii=False, + charsets=['ISO-8859-13', 'WINDOWS-1257', + 'ISO-8859-4'], + # Q, W, and X not used at all + alphabet=(u'AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ' + u'aąbcčdeęėfghiįyjklmnoprsštuųūvzž'), + wiki_start_pages=[u'Pagrindinis_puslapis']), + 'Latvian': Language(name='Latvian', + iso_code='lv', + use_ascii=False, + charsets=['ISO-8859-13', 'WINDOWS-1257', + 'ISO-8859-4'], + # Q, W, X, Y are only for loanwords + alphabet=(u'AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ' + u'aābcčdeēfgģhiījkķlļmnņoprsštuūvzž'), + wiki_start_pages=[u'Sākumlapa']), + 'Macedonian': Language(name='Macedonian', + iso_code='mk', + use_ascii=False, + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'MacCyrillic', 'IBM855'], + alphabet=(u'АБВГДЃЕЖЗЅИЈКЛЉМНЊОПРСТЌУФХЦЧЏШ' + u'абвгдѓежзѕијклљмнњопрстќуфхцчџш'), + wiki_start_pages=[u'Главна_страница']), + 'Dutch': Language(name='Dutch', + iso_code='nl', + use_ascii=True, + charsets=['ISO-8859-1', 'WINDOWS-1252'], + wiki_start_pages=[u'Hoofdpagina']), + 'Polish': Language(name='Polish', + iso_code='pl', + # Q and X are only used for foreign words. + use_ascii=False, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=(u'AĄBCĆDEĘFGHIJKLŁMNŃOÓPRSŚTUWYZŹŻ' + u'aąbcćdeęfghijklłmnńoóprsśtuwyzźż'), + wiki_start_pages=[u'Wikipedia:Strona_główna']), + 'Portuguese': Language(name='Portuguese', + iso_code='pt', + use_ascii=True, + charsets=['ISO-8859-1', 'ISO-8859-15', + 'WINDOWS-1252'], + alphabet=u'ÁÂÃÀÇÉÊÍÓÔÕÚáâãàçéêíóôõú', + wiki_start_pages=[u'Wikipédia:Página_principal']), + 'Romanian': Language(name='Romanian', + iso_code='ro', + use_ascii=True, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=u'ăâîșțĂÂÎȘȚ', + wiki_start_pages=[u'Pagina_principală']), + 'Russian': Language(name='Russian', + iso_code='ru', + use_ascii=False, + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'KOI8-R', 'MacCyrillic', 'IBM866', + 'IBM855'], + alphabet=(u'абвгдеёжзийклмнопрстуфхцчшщъыьэюя' + u'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'), + wiki_start_pages=[u'Заглавная_страница']), + 'Slovak': Language(name='Slovak', + iso_code='sk', + use_ascii=True, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=u'áäčďéíĺľňóôŕšťúýžÁÄČĎÉÍĹĽŇÓÔŔŠŤÚÝŽ', + wiki_start_pages=[u'Hlavná_stránka']), + 'Slovene': Language(name='Slovene', + iso_code='sl', + # Q, W, X, Y are only used for foreign words. + use_ascii=False, + charsets=['ISO-8859-2', 'WINDOWS-1250'], + alphabet=(u'abcčdefghijklmnoprsštuvzž' + u'ABCČDEFGHIJKLMNOPRSŠTUVZŽ'), + wiki_start_pages=[u'Glavna_stran']), + # Serbian can be written in both Latin and Cyrillic, but there's no + # simple way to get the Latin alphabet pages from Wikipedia through + # the API, so for now we just support Cyrillic. + 'Serbian': Language(name='Serbian', + iso_code='sr', + alphabet=(u'АБВГДЂЕЖЗИЈКЛЉМНЊОПРСТЋУФХЦЧЏШ' + u'абвгдђежзијклљмнњопрстћуфхцчџш'), + charsets=['ISO-8859-5', 'WINDOWS-1251', + 'MacCyrillic', 'IBM855'], + wiki_start_pages=[u'Главна_страна']), + 'Thai': Language(name='Thai', + iso_code='th', + use_ascii=False, + charsets=['ISO-8859-11', 'TIS-620', 'CP874'], + alphabet=u'กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛', + wiki_start_pages=[u'หน้าหลัก']), + 'Turkish': Language(name='Turkish', + iso_code='tr', + # Q, W, and X are not used by Turkish + use_ascii=False, + charsets=['ISO-8859-3', 'ISO-8859-9', + 'WINDOWS-1254'], + alphabet=(u'abcçdefgğhıijklmnoöprsştuüvyzâîû' + u'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZÂÎÛ'), + wiki_start_pages=[u'Ana_Sayfa']), + 'Vietnamese': Language(name='Vietnamese', + iso_code='vi', + use_ascii=False, + # Windows-1258 is the only common 8-bit + # Vietnamese encoding supported by Python. + # From Wikipedia: + # For systems that lack support for Unicode, + # dozens of 8-bit Vietnamese code pages are + # available.[1] The most common are VISCII + # (TCVN 5712:1993), VPS, and Windows-1258.[3] + # Where ASCII is required, such as when + # ensuring readability in plain text e-mail, + # Vietnamese letters are often encoded + # according to Vietnamese Quoted-Readable + # (VIQR) or VSCII Mnemonic (VSCII-MNEM),[4] + # though usage of either variable-width + # scheme has declined dramatically following + # the adoption of Unicode on the World Wide + # Web. + charsets=['WINDOWS-1258'], + alphabet=(u'aăâbcdđeêghiklmnoôơpqrstuưvxy' + u'AĂÂBCDĐEÊGHIKLMNOÔƠPQRSTUƯVXY'), + wiki_start_pages=[u'Chữ_Quốc_ngữ']), + } diff --git a/dist/ba_data/python-site-packages/chardet/sbcharsetprober.py b/dist/ba_data/python-site-packages/chardet/sbcharsetprober.py new file mode 100644 index 0000000..46ba835 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/sbcharsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from collections import namedtuple + +from .charsetprober import CharSetProber +from .enums import CharacterCategory, ProbingState, SequenceLikelihood + + +SingleByteCharSetModel = namedtuple('SingleByteCharSetModel', + ['charset_name', + 'language', + 'char_to_order_map', + 'language_model', + 'typical_positive_ratio', + 'keep_ascii_letters', + 'alphabet']) + + +class SingleByteCharSetProber(CharSetProber): + SAMPLE_SIZE = 64 + SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 + POSITIVE_SHORTCUT_THRESHOLD = 0.95 + NEGATIVE_SHORTCUT_THRESHOLD = 0.05 + + def __init__(self, model, reversed=False, name_prober=None): + super(SingleByteCharSetProber, self).__init__() + self._model = model + # TRUE if we need to reverse every pair in the model lookup + self._reversed = reversed + # Optional auxiliary prober for name decision + self._name_prober = name_prober + self._last_order = None + self._seq_counters = None + self._total_seqs = None + self._total_char = None + self._freq_char = None + self.reset() + + def reset(self): + super(SingleByteCharSetProber, self).reset() + # char order of last character + self._last_order = 255 + self._seq_counters = [0] * SequenceLikelihood.get_num_categories() + self._total_seqs = 0 + self._total_char = 0 + # characters that fall in our sampling range + self._freq_char = 0 + + @property + def charset_name(self): + if self._name_prober: + return self._name_prober.charset_name + else: + return self._model.charset_name + + @property + def language(self): + if self._name_prober: + return self._name_prober.language + else: + return self._model.language + + def feed(self, byte_str): + # TODO: Make filter_international_words keep things in self.alphabet + if not self._model.keep_ascii_letters: + byte_str = self.filter_international_words(byte_str) + if not byte_str: + return self.state + char_to_order_map = self._model.char_to_order_map + language_model = self._model.language_model + for char in byte_str: + order = char_to_order_map.get(char, CharacterCategory.UNDEFINED) + # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but + # CharacterCategory.SYMBOL is actually 253, so we use CONTROL + # to make it closer to the original intent. The only difference + # is whether or not we count digits and control characters for + # _total_char purposes. + if order < CharacterCategory.CONTROL: + self._total_char += 1 + # TODO: Follow uchardet's lead and discount confidence for frequent + # control characters. + # See https://github.com/BYVoid/uchardet/commit/55b4f23971db61 + if order < self.SAMPLE_SIZE: + self._freq_char += 1 + if self._last_order < self.SAMPLE_SIZE: + self._total_seqs += 1 + if not self._reversed: + lm_cat = language_model[self._last_order][order] + else: + lm_cat = language_model[order][self._last_order] + self._seq_counters[lm_cat] += 1 + self._last_order = order + + charset_name = self._model.charset_name + if self.state == ProbingState.DETECTING: + if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: + confidence = self.get_confidence() + if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, we have a winner', + charset_name, confidence) + self._state = ProbingState.FOUND_IT + elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, below negative ' + 'shortcut threshhold %s', charset_name, + confidence, + self.NEGATIVE_SHORTCUT_THRESHOLD) + self._state = ProbingState.NOT_ME + + return self.state + + def get_confidence(self): + r = 0.01 + if self._total_seqs > 0: + r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / + self._total_seqs / self._model.typical_positive_ratio) + r = r * self._freq_char / self._total_char + if r >= 1.0: + r = 0.99 + return r diff --git a/dist/ba_data/python-site-packages/chardet/sbcsgroupprober.py b/dist/ba_data/python-site-packages/chardet/sbcsgroupprober.py new file mode 100644 index 0000000..bdeef4e --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/sbcsgroupprober.py @@ -0,0 +1,83 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .hebrewprober import HebrewProber +from .langbulgarianmodel import (ISO_8859_5_BULGARIAN_MODEL, + WINDOWS_1251_BULGARIAN_MODEL) +from .langgreekmodel import ISO_8859_7_GREEK_MODEL, WINDOWS_1253_GREEK_MODEL +from .langhebrewmodel import WINDOWS_1255_HEBREW_MODEL +# from .langhungarianmodel import (ISO_8859_2_HUNGARIAN_MODEL, +# WINDOWS_1250_HUNGARIAN_MODEL) +from .langrussianmodel import (IBM855_RUSSIAN_MODEL, IBM866_RUSSIAN_MODEL, + ISO_8859_5_RUSSIAN_MODEL, KOI8_R_RUSSIAN_MODEL, + MACCYRILLIC_RUSSIAN_MODEL, + WINDOWS_1251_RUSSIAN_MODEL) +from .langthaimodel import TIS_620_THAI_MODEL +from .langturkishmodel import ISO_8859_9_TURKISH_MODEL +from .sbcharsetprober import SingleByteCharSetProber + + +class SBCSGroupProber(CharSetGroupProber): + def __init__(self): + super(SBCSGroupProber, self).__init__() + hebrew_prober = HebrewProber() + logical_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, + False, hebrew_prober) + # TODO: See if using ISO-8859-8 Hebrew model works better here, since + # it's actually the visual one + visual_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, + True, hebrew_prober) + hebrew_prober.set_model_probers(logical_hebrew_prober, + visual_hebrew_prober) + # TODO: ORDER MATTERS HERE. I changed the order vs what was in master + # and several tests failed that did not before. Some thought + # should be put into the ordering, and we should consider making + # order not matter here, because that is very counter-intuitive. + self.probers = [ + SingleByteCharSetProber(WINDOWS_1251_RUSSIAN_MODEL), + SingleByteCharSetProber(KOI8_R_RUSSIAN_MODEL), + SingleByteCharSetProber(ISO_8859_5_RUSSIAN_MODEL), + SingleByteCharSetProber(MACCYRILLIC_RUSSIAN_MODEL), + SingleByteCharSetProber(IBM866_RUSSIAN_MODEL), + SingleByteCharSetProber(IBM855_RUSSIAN_MODEL), + SingleByteCharSetProber(ISO_8859_7_GREEK_MODEL), + SingleByteCharSetProber(WINDOWS_1253_GREEK_MODEL), + SingleByteCharSetProber(ISO_8859_5_BULGARIAN_MODEL), + SingleByteCharSetProber(WINDOWS_1251_BULGARIAN_MODEL), + # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) + # after we retrain model. + # SingleByteCharSetProber(ISO_8859_2_HUNGARIAN_MODEL), + # SingleByteCharSetProber(WINDOWS_1250_HUNGARIAN_MODEL), + SingleByteCharSetProber(TIS_620_THAI_MODEL), + SingleByteCharSetProber(ISO_8859_9_TURKISH_MODEL), + hebrew_prober, + logical_hebrew_prober, + visual_hebrew_prober, + ] + self.reset() diff --git a/dist/ba_data/python-site-packages/chardet/sjisprober.py b/dist/ba_data/python-site-packages/chardet/sjisprober.py new file mode 100644 index 0000000..9e29623 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/sjisprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import SJISDistributionAnalysis +from .jpcntx import SJISContextAnalysis +from .mbcssm import SJIS_SM_MODEL +from .enums import ProbingState, MachineState + + +class SJISProber(MultiByteCharSetProber): + def __init__(self): + super(SJISProber, self).__init__() + self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) + self.distribution_analyzer = SJISDistributionAnalysis() + self.context_analyzer = SJISContextAnalysis() + self.reset() + + def reset(self): + super(SJISProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return self.context_analyzer.charset_name + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char[2 - char_len:], + char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 + - char_len], char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/dist/ba_data/python-site-packages/chardet/universaldetector.py b/dist/ba_data/python-site-packages/chardet/universaldetector.py new file mode 100644 index 0000000..055a8ac --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/universaldetector.py @@ -0,0 +1,286 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### +""" +Module containing the UniversalDetector detector class, which is the primary +class a user of ``chardet`` should use. + +:author: Mark Pilgrim (initial port to Python) +:author: Shy Shalom (original C code) +:author: Dan Blanchard (major refactoring for 3.0) +:author: Ian Cordasco +""" + + +import codecs +import logging +import re + +from .charsetgroupprober import CharSetGroupProber +from .enums import InputState, LanguageFilter, ProbingState +from .escprober import EscCharSetProber +from .latin1prober import Latin1Prober +from .mbcsgroupprober import MBCSGroupProber +from .sbcsgroupprober import SBCSGroupProber + + +class UniversalDetector(object): + """ + The ``UniversalDetector`` class underlies the ``chardet.detect`` function + and coordinates all of the different charset probers. + + To get a ``dict`` containing an encoding and its confidence, you can simply + run: + + .. code:: + + u = UniversalDetector() + u.feed(some_bytes) + u.close() + detected = u.result + + """ + + MINIMUM_THRESHOLD = 0.20 + HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') + ESC_DETECTOR = re.compile(b'(\033|~{)') + WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') + ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', + 'iso-8859-2': 'Windows-1250', + 'iso-8859-5': 'Windows-1251', + 'iso-8859-6': 'Windows-1256', + 'iso-8859-7': 'Windows-1253', + 'iso-8859-8': 'Windows-1255', + 'iso-8859-9': 'Windows-1254', + 'iso-8859-13': 'Windows-1257'} + + def __init__(self, lang_filter=LanguageFilter.ALL): + self._esc_charset_prober = None + self._charset_probers = [] + self.result = None + self.done = None + self._got_data = None + self._input_state = None + self._last_char = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + self._has_win_bytes = None + self.reset() + + def reset(self): + """ + Reset the UniversalDetector and all of its probers back to their + initial states. This is called by ``__init__``, so you only need to + call this directly in between analyses of different documents. + """ + self.result = {'encoding': None, 'confidence': 0.0, 'language': None} + self.done = False + self._got_data = False + self._has_win_bytes = False + self._input_state = InputState.PURE_ASCII + self._last_char = b'' + if self._esc_charset_prober: + self._esc_charset_prober.reset() + for prober in self._charset_probers: + prober.reset() + + def feed(self, byte_str): + """ + Takes a chunk of a document and feeds it through all of the relevant + charset probers. + + After calling ``feed``, you can check the value of the ``done`` + attribute to see if you need to continue feeding the + ``UniversalDetector`` more data, or if it has made a prediction + (in the ``result`` attribute). + + .. note:: + You should always call ``close`` when you're done feeding in your + document if ``done`` is not already ``True``. + """ + if self.done: + return + + if not len(byte_str): + return + + if not isinstance(byte_str, bytearray): + byte_str = bytearray(byte_str) + + # First check for known BOMs, since these are guaranteed to be correct + if not self._got_data: + # If the data starts with BOM, we know it is UTF + if byte_str.startswith(codecs.BOM_UTF8): + # EF BB BF UTF-8 with BOM + self.result = {'encoding': "UTF-8-SIG", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_UTF32_LE, + codecs.BOM_UTF32_BE)): + # FF FE 00 00 UTF-32, little-endian BOM + # 00 00 FE FF UTF-32, big-endian BOM + self.result = {'encoding': "UTF-32", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\xFE\xFF\x00\x00'): + # FE FF 00 00 UCS-4, unusual octet order BOM (3412) + self.result = {'encoding': "X-ISO-10646-UCS-4-3412", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\x00\x00\xFF\xFE'): + # 00 00 FF FE UCS-4, unusual octet order BOM (2143) + self.result = {'encoding': "X-ISO-10646-UCS-4-2143", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): + # FF FE UTF-16, little endian BOM + # FE FF UTF-16, big endian BOM + self.result = {'encoding': "UTF-16", + 'confidence': 1.0, + 'language': ''} + + self._got_data = True + if self.result['encoding'] is not None: + self.done = True + return + + # If none of those matched and we've only see ASCII so far, check + # for high bytes and escape sequences + if self._input_state == InputState.PURE_ASCII: + if self.HIGH_BYTE_DETECTOR.search(byte_str): + self._input_state = InputState.HIGH_BYTE + elif self._input_state == InputState.PURE_ASCII and \ + self.ESC_DETECTOR.search(self._last_char + byte_str): + self._input_state = InputState.ESC_ASCII + + self._last_char = byte_str[-1:] + + # If we've seen escape sequences, use the EscCharSetProber, which + # uses a simple state machine to check for known escape sequences in + # HZ and ISO-2022 encodings, since those are the only encodings that + # use such sequences. + if self._input_state == InputState.ESC_ASCII: + if not self._esc_charset_prober: + self._esc_charset_prober = EscCharSetProber(self.lang_filter) + if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': + self._esc_charset_prober.charset_name, + 'confidence': + self._esc_charset_prober.get_confidence(), + 'language': + self._esc_charset_prober.language} + self.done = True + # If we've seen high bytes (i.e., those with values greater than 127), + # we need to do more complicated checks using all our multi-byte and + # single-byte probers that are left. The single-byte probers + # use character bigram distributions to determine the encoding, whereas + # the multi-byte probers use a combination of character unigram and + # bigram distributions. + elif self._input_state == InputState.HIGH_BYTE: + if not self._charset_probers: + self._charset_probers = [MBCSGroupProber(self.lang_filter)] + # If we're checking non-CJK encodings, use single-byte prober + if self.lang_filter & LanguageFilter.NON_CJK: + self._charset_probers.append(SBCSGroupProber()) + self._charset_probers.append(Latin1Prober()) + for prober in self._charset_probers: + if prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': prober.charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language} + self.done = True + break + if self.WIN_BYTE_DETECTOR.search(byte_str): + self._has_win_bytes = True + + def close(self): + """ + Stop analyzing the current document and come up with a final + prediction. + + :returns: The ``result`` attribute, a ``dict`` with the keys + `encoding`, `confidence`, and `language`. + """ + # Don't bother with checks if we're already done + if self.done: + return self.result + self.done = True + + if not self._got_data: + self.logger.debug('no data received!') + + # Default to ASCII if it is all we've seen so far + elif self._input_state == InputState.PURE_ASCII: + self.result = {'encoding': 'ascii', + 'confidence': 1.0, + 'language': ''} + + # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD + elif self._input_state == InputState.HIGH_BYTE: + prober_confidence = None + max_prober_confidence = 0.0 + max_prober = None + for prober in self._charset_probers: + if not prober: + continue + prober_confidence = prober.get_confidence() + if prober_confidence > max_prober_confidence: + max_prober_confidence = prober_confidence + max_prober = prober + if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): + charset_name = max_prober.charset_name + lower_charset_name = max_prober.charset_name.lower() + confidence = max_prober.get_confidence() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if self._has_win_bytes: + charset_name = self.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + self.result = {'encoding': charset_name, + 'confidence': confidence, + 'language': max_prober.language} + + # Log all prober confidences if none met MINIMUM_THRESHOLD + if self.logger.getEffectiveLevel() <= logging.DEBUG: + if self.result['encoding'] is None: + self.logger.debug('no probers hit minimum threshold') + for group_prober in self._charset_probers: + if not group_prober: + continue + if isinstance(group_prober, CharSetGroupProber): + for prober in group_prober.probers: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + else: + self.logger.debug('%s %s confidence = %s', + group_prober.charset_name, + group_prober.language, + group_prober.get_confidence()) + return self.result diff --git a/dist/ba_data/python-site-packages/chardet/utf8prober.py b/dist/ba_data/python-site-packages/chardet/utf8prober.py new file mode 100644 index 0000000..6c3196c --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/utf8prober.py @@ -0,0 +1,82 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState +from .codingstatemachine import CodingStateMachine +from .mbcssm import UTF8_SM_MODEL + + + +class UTF8Prober(CharSetProber): + ONE_CHAR_PROB = 0.5 + + def __init__(self): + super(UTF8Prober, self).__init__() + self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) + self._num_mb_chars = None + self.reset() + + def reset(self): + super(UTF8Prober, self).reset() + self.coding_sm.reset() + self._num_mb_chars = 0 + + @property + def charset_name(self): + return "utf-8" + + @property + def language(self): + return "" + + def feed(self, byte_str): + for c in byte_str: + coding_state = self.coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + if self.coding_sm.get_current_charlen() >= 2: + self._num_mb_chars += 1 + + if self.state == ProbingState.DETECTING: + if self.get_confidence() > self.SHORTCUT_THRESHOLD: + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + unlike = 0.99 + if self._num_mb_chars < 6: + unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars + return 1.0 - unlike + else: + return unlike diff --git a/dist/ba_data/python-site-packages/chardet/version.py b/dist/ba_data/python-site-packages/chardet/version.py new file mode 100644 index 0000000..70369b9 --- /dev/null +++ b/dist/ba_data/python-site-packages/chardet/version.py @@ -0,0 +1,9 @@ +""" +This module exists only to simplify retrieving the version number of chardet +from within setup.py and from chardet subpackages. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + +__version__ = "4.0.0" +VERSION = __version__.split('.') diff --git a/dist/ba_data/python-site-packages/click/__init__.py b/dist/ba_data/python-site-packages/click/__init__.py new file mode 100644 index 0000000..35176c7 --- /dev/null +++ b/dist/ba_data/python-site-packages/click/__init__.py @@ -0,0 +1,75 @@ +""" +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. +""" +from .core import Argument as Argument +from .core import BaseCommand as BaseCommand +from .core import Command as Command +from .core import CommandCollection as CommandCollection +from .core import Context as Context +from .core import Group as Group +from .core import MultiCommand as MultiCommand +from .core import Option as Option +from .core import Parameter as Parameter +from .decorators import argument as argument +from .decorators import command as command +from .decorators import confirmation_option as confirmation_option +from .decorators import group as group +from .decorators import help_option as help_option +from .decorators import make_pass_decorator as make_pass_decorator +from .decorators import option as option +from .decorators import pass_context as pass_context +from .decorators import pass_obj as pass_obj +from .decorators import password_option as password_option +from .decorators import version_option as version_option +from .exceptions import Abort as Abort +from .exceptions import BadArgumentUsage as BadArgumentUsage +from .exceptions import BadOptionUsage as BadOptionUsage +from .exceptions import BadParameter as BadParameter +from .exceptions import ClickException as ClickException +from .exceptions import FileError as FileError +from .exceptions import MissingParameter as MissingParameter +from .exceptions import NoSuchOption as NoSuchOption +from .exceptions import UsageError as UsageError +from .formatting import HelpFormatter as HelpFormatter +from .formatting import wrap_text as wrap_text +from .globals import get_current_context as get_current_context +from .parser import OptionParser as OptionParser +from .termui import clear as clear +from .termui import confirm as confirm +from .termui import echo_via_pager as echo_via_pager +from .termui import edit as edit +from .termui import get_terminal_size as get_terminal_size +from .termui import getchar as getchar +from .termui import launch as launch +from .termui import pause as pause +from .termui import progressbar as progressbar +from .termui import prompt as prompt +from .termui import secho as secho +from .termui import style as style +from .termui import unstyle as unstyle +from .types import BOOL as BOOL +from .types import Choice as Choice +from .types import DateTime as DateTime +from .types import File as File +from .types import FLOAT as FLOAT +from .types import FloatRange as FloatRange +from .types import INT as INT +from .types import IntRange as IntRange +from .types import ParamType as ParamType +from .types import Path as Path +from .types import STRING as STRING +from .types import Tuple as Tuple +from .types import UNPROCESSED as UNPROCESSED +from .types import UUID as UUID +from .utils import echo as echo +from .utils import format_filename as format_filename +from .utils import get_app_dir as get_app_dir +from .utils import get_binary_stream as get_binary_stream +from .utils import get_os_args as get_os_args +from .utils import get_text_stream as get_text_stream +from .utils import open_file as open_file + +__version__ = "8.0.4" diff --git a/dist/ba_data/python-site-packages/click/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..98bbdff Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/_compat.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/_compat.cpython-310.opt-1.pyc new file mode 100644 index 0000000..0f7c87a Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/_compat.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/_unicodefun.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/_unicodefun.cpython-310.opt-1.pyc new file mode 100644 index 0000000..7b137a2 Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/_unicodefun.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/core.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/core.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9a81f6d Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/core.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/decorators.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/decorators.cpython-310.opt-1.pyc new file mode 100644 index 0000000..c172b1a Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/decorators.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/exceptions.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/exceptions.cpython-310.opt-1.pyc new file mode 100644 index 0000000..55ccead Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/exceptions.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/formatting.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/formatting.cpython-310.opt-1.pyc new file mode 100644 index 0000000..2e31aff Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/formatting.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/globals.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/globals.cpython-310.opt-1.pyc new file mode 100644 index 0000000..51c6104 Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/globals.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/parser.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/parser.cpython-310.opt-1.pyc new file mode 100644 index 0000000..1b92cfc Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/parser.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/termui.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/termui.cpython-310.opt-1.pyc new file mode 100644 index 0000000..862b52d Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/termui.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/types.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/types.cpython-310.opt-1.pyc new file mode 100644 index 0000000..17f14f5 Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/types.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/__pycache__/utils.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/click/__pycache__/utils.cpython-310.opt-1.pyc new file mode 100644 index 0000000..6560e5d Binary files /dev/null and b/dist/ba_data/python-site-packages/click/__pycache__/utils.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/click/_compat.py b/dist/ba_data/python-site-packages/click/_compat.py new file mode 100644 index 0000000..766d286 --- /dev/null +++ b/dist/ba_data/python-site-packages/click/_compat.py @@ -0,0 +1,626 @@ +import codecs +import io +import os +import re +import sys +import typing as t +from weakref import WeakKeyDictionary + +CYGWIN = sys.platform.startswith("cygwin") +MSYS2 = sys.platform.startswith("win") and ("GCC" in sys.version) +# Determine local App Engine environment, per Google's own suggestion +APP_ENGINE = "APPENGINE_RUNTIME" in os.environ and "Development/" in os.environ.get( + "SERVER_SOFTWARE", "" +) +WIN = sys.platform.startswith("win") and not APP_ENGINE and not MSYS2 +auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None +_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") + + +def get_filesystem_encoding() -> str: + return sys.getfilesystemencoding() or sys.getdefaultencoding() + + +def _make_text_stream( + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = "replace" + return _NonClosingTextIOWrapper( + stream, + encoding, + errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def is_ascii_encoding(encoding: str) -> bool: + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +def get_best_encoding(stream: t.IO) -> str: + """Returns the default stream encoding if not found.""" + rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return "utf-8" + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + def __init__( + self, + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, + **extra: t.Any, + ) -> None: + self._stream = stream = t.cast( + t.BinaryIO, _FixupStream(stream, force_readable, force_writable) + ) + super().__init__(stream, encoding, errors, **extra) + + def __del__(self) -> None: + try: + self.detach() + except Exception: + pass + + def isatty(self) -> bool: + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream: + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__( + self, + stream: t.BinaryIO, + force_readable: bool = False, + force_writable: bool = False, + ): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._stream, name) + + def read1(self, size: int) -> bytes: + f = getattr(self._stream, "read1", None) + + if f is not None: + return t.cast(bytes, f(size)) + + return self._stream.read(size) + + def readable(self) -> bool: + if self._force_readable: + return True + x = getattr(self._stream, "readable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self) -> bool: + if self._force_writable: + return True + x = getattr(self._stream, "writable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.write("") # type: ignore + except Exception: + try: + self._stream.write(b"") + except Exception: + return False + return True + + def seekable(self) -> bool: + x = getattr(self._stream, "seekable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +def _is_binary_reader(stream: t.IO, default: bool = False) -> bool: + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + +def _is_binary_writer(stream: t.IO, default: bool = False) -> bool: + try: + stream.write(b"") + except Exception: + try: + stream.write("") + return False + except Exception: + pass + return default + return True + + +def _find_binary_reader(stream: t.IO) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _find_binary_writer(stream: t.IO) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _stream_is_misconfigured(stream: t.TextIO) -> bool: + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") + + +def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: + """A stream attribute is compatible if it is equal to the + desired value or the desired value is unset and the attribute + has a value. + """ + stream_value = getattr(stream, attr, None) + return stream_value == value or (value is None and stream_value is not None) + + +def _is_compatible_text_stream( + stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> bool: + """Check if a stream's encoding and errors attributes are + compatible with the desired values. + """ + return _is_compat_stream_attr( + stream, "encoding", encoding + ) and _is_compat_stream_attr(stream, "errors", errors) + + +def _force_correct_text_stream( + text_stream: t.IO, + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO, bool], bool], + find_binary: t.Callable[[t.IO], t.Optional[t.BinaryIO]], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if is_binary(text_stream, False): + binary_reader = t.cast(t.BinaryIO, text_stream) + else: + text_stream = t.cast(t.TextIO, text_stream) + # If the stream looks compatible, and won't default to a + # misconfigured ascii encoding, return it as-is. + if _is_compatible_text_stream(text_stream, encoding, errors) and not ( + encoding is None and _stream_is_misconfigured(text_stream) + ): + return text_stream + + # Otherwise, get the underlying binary reader. + possible_binary_reader = find_binary(text_stream) + + # If that's not possible, silently use the original reader + # and get mojibake instead of exceptions. + if possible_binary_reader is None: + return text_stream + + binary_reader = possible_binary_reader + + # Default errors to replace instead of strict in order to get + # something that works. + if errors is None: + errors = "replace" + + # Wrap the binary stream in a text stream with the correct + # encoding parameters. + return _make_text_stream( + binary_reader, + encoding, + errors, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def _force_correct_text_reader( + text_reader: t.IO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_reader, + encoding, + errors, + _is_binary_reader, + _find_binary_reader, + force_readable=force_readable, + ) + + +def _force_correct_text_writer( + text_writer: t.IO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_writable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_writer, + encoding, + errors, + _is_binary_writer, + _find_binary_writer, + force_writable=force_writable, + ) + + +def get_binary_stdin() -> t.BinaryIO: + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdin.") + return reader + + +def get_binary_stdout() -> t.BinaryIO: + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdout.") + return writer + + +def get_binary_stderr() -> t.BinaryIO: + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stderr.") + return writer + + +def get_text_stdin( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) + + +def get_text_stdout( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) + + +def get_text_stderr( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) + + +def _wrap_io_open( + file: t.Union[str, os.PathLike, int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO: + """Handles not passing ``encoding`` and ``errors`` in binary mode.""" + if "b" in mode: + return open(file, mode) + + return open(file, mode, encoding=encoding, errors=errors) + + +def open_stream( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO, bool]: + binary = "b" in mode + + # Standard streams first. These are simple because they ignore the + # atomic flag. Use fsdecode to handle Path("-"). + if os.fsdecode(filename) == "-": + if any(m in mode for m in ["w", "a", "x"]): + if binary: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if binary: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + return _wrap_io_open(filename, mode, encoding, errors), True + + # Some usability stuff for atomic writes + if "a" in mode: + raise ValueError( + "Appending to an existing file is not supported, because that" + " would involve an expensive `copy`-operation to a temporary" + " file. Open the file in normal `w`-mode and copy explicitly" + " if that's what you're after." + ) + if "x" in mode: + raise ValueError("Use the `overwrite`-parameter instead.") + if "w" not in mode: + raise ValueError("Atomic writes only make sense with `w`-mode.") + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import errno + import random + + try: + perm: t.Optional[int] = os.stat(filename).st_mode + except OSError: + perm = None + + flags = os.O_RDWR | os.O_CREAT | os.O_EXCL + + if binary: + flags |= getattr(os, "O_BINARY", 0) + + while True: + tmp_filename = os.path.join( + os.path.dirname(filename), + f".__atomic-write{random.randrange(1 << 32):08x}", + ) + try: + fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) + break + except OSError as e: + if e.errno == errno.EEXIST or ( + os.name == "nt" + and e.errno == errno.EACCES + and os.path.isdir(e.filename) + and os.access(e.filename, os.W_OK) + ): + continue + raise + + if perm is not None: + os.chmod(tmp_filename, perm) # in case perm includes bits in umask + + f = _wrap_io_open(fd, mode, encoding, errors) + af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) + return t.cast(t.IO, af), True + + +class _AtomicFile: + def __init__(self, f: t.IO, tmp_filename: str, real_filename: str) -> None: + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self) -> str: + return self._real_filename + + def close(self, delete: bool = False) -> None: + if self.closed: + return + self._f.close() + os.replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._f, name) + + def __enter__(self) -> "_AtomicFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.close(delete=exc_type is not None) + + def __repr__(self) -> str: + return repr(self._f) + + +def strip_ansi(value: str) -> str: + return _ansi_re.sub("", value) + + +def _is_jupyter_kernel_output(stream: t.IO) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None +) -> bool: + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) and not _is_jupyter_kernel_output(stream) + return not color + + +# On Windows, wrap the output streams with colorama to support ANSI +# color codes. +# NOTE: double check is needed so mypy does not analyze this on Linux +if sys.platform.startswith("win") and WIN: + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding() -> str: + import locale + + return locale.getpreferredencoding() + + _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def auto_wrap_for_ansi( + stream: t.TextIO, color: t.Optional[bool] = None + ) -> t.TextIO: + """Support ANSI color and style codes on Windows by wrapping a + stream with colorama. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + + if cached is not None: + return cached + + import colorama + + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = t.cast(t.TextIO, ansi_wrapper.stream) + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except BaseException: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + + return rv + +else: + + def _get_argv_encoding() -> str: + return getattr(sys.stdin, "encoding", None) or get_filesystem_encoding() + + def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] + ) -> t.Optional[t.TextIO]: + return None + + +def term_len(x: str) -> int: + return len(strip_ansi(x)) + + +def isatty(stream: t.IO) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.TextIO], wrapper_func: t.Callable[[], t.TextIO] +) -> t.Callable[[], t.TextIO]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.TextIO: + stream = src_func() + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + + return func + + +_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) + + +binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { + "stdin": get_binary_stdin, + "stdout": get_binary_stdout, + "stderr": get_binary_stderr, +} + +text_streams: t.Mapping[ + str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] +] = { + "stdin": get_text_stdin, + "stdout": get_text_stdout, + "stderr": get_text_stderr, +} diff --git a/dist/ba_data/python-site-packages/click/_termui_impl.py b/dist/ba_data/python-site-packages/click/_termui_impl.py new file mode 100644 index 0000000..4b979bc --- /dev/null +++ b/dist/ba_data/python-site-packages/click/_termui_impl.py @@ -0,0 +1,717 @@ +""" +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. +""" +import contextlib +import math +import os +import sys +import time +import typing as t +from gettext import gettext as _ + +from ._compat import _default_text_stdout +from ._compat import CYGWIN +from ._compat import get_best_encoding +from ._compat import isatty +from ._compat import open_stream +from ._compat import strip_ansi +from ._compat import term_len +from ._compat import WIN +from .exceptions import ClickException +from .utils import echo + +V = t.TypeVar("V") + +if os.name == "nt": + BEFORE_BAR = "\r" + AFTER_BAR = "\n" +else: + BEFORE_BAR = "\r\033[?25l" + AFTER_BAR = "\033[?25h\n" + + +class ProgressBar(t.Generic[V]): + def __init__( + self, + iterable: t.Optional[t.Iterable[V]], + length: t.Optional[int] = None, + fill_char: str = "#", + empty_char: str = " ", + bar_template: str = "%(bar)s", + info_sep: str = " ", + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + label: t.Optional[str] = None, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, + width: int = 30, + ) -> None: + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label = label or "" + if file is None: + file = _default_text_stdout() + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width = width + self.autowidth = width == 0 + + if length is None: + from operator import length_hint + + length = length_hint(iterable, -1) + + if length == -1: + length = None + if iterable is None: + if length is None: + raise TypeError("iterable or length is required") + iterable = t.cast(t.Iterable[V], range(length)) + self.iter = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.start = self.last_eta = time.time() + self.eta_known = False + self.finished = False + self.max_width: t.Optional[int] = None + self.entered = False + self.current_item: t.Optional[V] = None + self.is_hidden = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar": + self.entered = True + self.render_progress() + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.render_finish() + + def __iter__(self) -> t.Iterator[V]: + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + self.render_progress() + return self.generator() + + def __next__(self) -> V: + # Iteration is defined in terms of a generator function, + # returned by iter(self); use that to define next(). This works + # because `self.iter` is an iterable consumed by that generator, + # so it is re-entry safe. Calling `next(self.generator())` + # twice works and does "what you want". + return next(iter(self)) + + def render_finish(self) -> None: + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self) -> float: + if self.finished: + return 1.0 + return min(self.pos / (float(self.length or 1) or 1), 1.0) + + @property + def time_per_iteration(self) -> float: + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self) -> float: + if self.length is not None and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self) -> str: + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" + else: + return f"{hours:02}:{minutes:02}:{seconds:02}" + return "" + + def format_pos(self) -> str: + pos = str(self.pos) + if self.length is not None: + pos += f"/{self.length}" + return pos + + def format_pct(self) -> str: + return f"{int(self.pct * 100): 4}%"[1:] + + def format_bar(self) -> str: + if self.length is not None: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + chars = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + chars[ + int( + (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) + * self.width + ) + ] = self.fill_char + bar = "".join(chars) + return bar + + def format_progress_line(self) -> str: + show_percent = self.show_percent + + info_bits = [] + if self.length is not None and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return ( + self.bar_template + % { + "label": self.label, + "bar": self.format_bar(), + "info": self.info_sep.join(info_bits), + } + ).rstrip() + + def render_progress(self) -> None: + import shutil + + if self.is_hidden: + # Only output the label as it changes if the output is not a + # TTY. Use file=stderr if you expect to be piping stdout. + if self._last_line != self.label: + self._last_line = self.label + echo(self.label, file=self.file, color=self.color) + + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, shutil.get_terminal_size().columns - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(" " * self.max_width) # type: ignore + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(" " * (clear_width - line_len)) + line = "".join(buf) + # Render the line only if it changed. + + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps: int) -> None: + self.pos += n_steps + if self.length is not None and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length is not None + + def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: + """Update the progress bar by advancing a specified number of + steps, and optionally set the ``current_item`` for this new + position. + + :param n_steps: Number of steps to advance. + :param current_item: Optional item to set as ``current_item`` + for the updated position. + + .. versionchanged:: 8.0 + Added the ``current_item`` optional parameter. + + .. versionchanged:: 8.0 + Only render when the number of steps meets the + ``update_min_steps`` threshold. + """ + if current_item is not None: + self.current_item = current_item + + self._completed_intervals += n_steps + + if self._completed_intervals >= self.update_min_steps: + self.make_step(self._completed_intervals) + self.render_progress() + self._completed_intervals = 0 + + def finish(self) -> None: + self.eta_known = False + self.current_item = None + self.finished = True + + def generator(self) -> t.Iterator[V]: + """Return a generator which yields the items added to the bar + during construction, and updates the progress bar *after* the + yielded block returns. + """ + # WARNING: the iterator interface for `ProgressBar` relies on + # this and only works because this is a simple generator which + # doesn't create or manage additional state. If this function + # changes, the impact should be evaluated both against + # `iter(bar)` and `next(bar)`. `next()` in particular may call + # `self.generator()` repeatedly, and this must remain safe in + # order for that interface to work. + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + + if self.is_hidden: + yield from self.iter + else: + for rv in self.iter: + self.current_item = rv + + # This allows show_item_func to be updated before the + # item is processed. Only trigger at the beginning of + # the update interval. + if self._completed_intervals == 0: + self.render_progress() + + yield rv + self.update(1) + + self.finish() + self.render_progress() + + +def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith("os2"): + return _tempfilepager(generator, "more <", color) + if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: + return _pipepager(generator, "less", color) + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: + return _pipepager(generator, "more", color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env) + stdin = t.cast(t.BinaryIO, c.stdin) + encoding = get_best_encoding(stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + stdin.write(text.encode(encoding, "replace")) + except (OSError, KeyboardInterrupt): + pass + else: + stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager( + generator: t.Iterable[str], cmd: str, color: t.Optional[bool] +) -> None: + """Page through text by invoking a program on a temporary file.""" + import tempfile + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + os.system(f'{cmd} "{filename}"') + finally: + os.close(fd) + os.unlink(filename) + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if os.system(f"which {editor} >/dev/null 2>&1") == 0: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/dist/ba_data/python-site-packages/click/_textwrap.py b/dist/ba_data/python-site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/dist/ba_data/python-site-packages/click/_textwrap.py @@ -0,0 +1,49 @@ +import textwrap +import typing as t +from contextlib import contextmanager + + +class TextWrapper(textwrap.TextWrapper): + def _handle_long_word( + self, + reversed_chunks: t.List[str], + cur_line: t.List[str], + cur_len: int, + width: int, + ) -> None: + space_left = max(width - cur_len, 1) + + if self.break_long_words: + last = reversed_chunks[-1] + cut = last[:space_left] + res = last[space_left:] + cur_line.append(cut) + reversed_chunks[-1] = res + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + @contextmanager + def extra_indent(self, indent: str) -> t.Iterator[None]: + old_initial_indent = self.initial_indent + old_subsequent_indent = self.subsequent_indent + self.initial_indent += indent + self.subsequent_indent += indent + + try: + yield + finally: + self.initial_indent = old_initial_indent + self.subsequent_indent = old_subsequent_indent + + def indent_only(self, text: str) -> str: + rv = [] + + for idx, line in enumerate(text.splitlines()): + indent = self.initial_indent + + if idx > 0: + indent = self.subsequent_indent + + rv.append(f"{indent}{line}") + + return "\n".join(rv) diff --git a/dist/ba_data/python-site-packages/click/_unicodefun.py b/dist/ba_data/python-site-packages/click/_unicodefun.py new file mode 100644 index 0000000..9cb30c3 --- /dev/null +++ b/dist/ba_data/python-site-packages/click/_unicodefun.py @@ -0,0 +1,100 @@ +import codecs +import os +from gettext import gettext as _ + + +def _verify_python_env() -> None: + """Ensures that the environment is good for Unicode.""" + try: + from locale import getpreferredencoding + + fs_enc = codecs.lookup(getpreferredencoding()).name + except Exception: + fs_enc = "ascii" + + if fs_enc != "ascii": + return + + extra = [ + _( + "Click will abort further execution because Python was" + " configured to use ASCII as encoding for the environment." + " Consult https://click.palletsprojects.com/unicode-support/" + " for mitigation steps." + ) + ] + + if os.name == "posix": + import subprocess + + try: + rv = subprocess.Popen( + ["locale", "-a"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding="ascii", + errors="replace", + ).communicate()[0] + except OSError: + rv = "" + + good_locales = set() + has_c_utf8 = False + + for line in rv.splitlines(): + locale = line.strip() + + if locale.lower().endswith((".utf-8", ".utf8")): + good_locales.add(locale) + + if locale.lower() in ("c.utf8", "c.utf-8"): + has_c_utf8 = True + + if not good_locales: + extra.append( + _( + "Additional information: on this system no suitable" + " UTF-8 locales were discovered. This most likely" + " requires resolving by reconfiguring the locale" + " system." + ) + ) + elif has_c_utf8: + extra.append( + _( + "This system supports the C.UTF-8 locale which is" + " recommended. You might be able to resolve your" + " issue by exporting the following environment" + " variables:" + ) + ) + extra.append(" export LC_ALL=C.UTF-8\n export LANG=C.UTF-8") + else: + extra.append( + _( + "This system lists some UTF-8 supporting locales" + " that you can pick from. The following suitable" + " locales were discovered: {locales}" + ).format(locales=", ".join(sorted(good_locales))) + ) + + bad_locale = None + + for env_locale in os.environ.get("LC_ALL"), os.environ.get("LANG"): + if env_locale and env_locale.lower().endswith((".utf-8", ".utf8")): + bad_locale = env_locale + + if env_locale is not None: + break + + if bad_locale is not None: + extra.append( + _( + "Click discovered that you exported a UTF-8 locale" + " but the locale system could not pick up from it" + " because it does not exist. The exported locale is" + " {locale!r} but it is not supported." + ).format(locale=bad_locale) + ) + + raise RuntimeError("\n\n".join(extra)) diff --git a/dist/ba_data/python-site-packages/click/_winconsole.py b/dist/ba_data/python-site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/dist/ba_data/python-site-packages/click/_winconsole.py @@ -0,0 +1,279 @@ +# This module is based on the excellent work by Adam Bartoš who +# provided a lot of what went into the implementation here in +# the discussion to issue1602 in the Python bug tracker. +# +# There are some general differences in regards to how this works +# compared to the original patches as we do not need to patch +# the entire interpreter but just work in our little world of +# echo and prompt. +import io +import sys +import time +import typing as t +from ctypes import byref +from ctypes import c_char +from ctypes import c_char_p +from ctypes import c_int +from ctypes import c_ssize_t +from ctypes import c_ulong +from ctypes import c_void_p +from ctypes import POINTER +from ctypes import py_object +from ctypes import Structure +from ctypes.wintypes import DWORD +from ctypes.wintypes import HANDLE +from ctypes.wintypes import LPCWSTR +from ctypes.wintypes import LPWSTR + +from ._compat import _NonClosingTextIOWrapper + +assert sys.platform == "win32" +import msvcrt # noqa: E402 +from ctypes import windll # noqa: E402 +from ctypes import WINFUNCTYPE # noqa: E402 + +c_ssize_p = POINTER(c_ssize_t) + +kernel32 = windll.kernel32 +GetStdHandle = kernel32.GetStdHandle +ReadConsoleW = kernel32.ReadConsoleW +WriteConsoleW = kernel32.WriteConsoleW +GetConsoleMode = kernel32.GetConsoleMode +GetLastError = kernel32.GetLastError +GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) +CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( + ("CommandLineToArgvW", windll.shell32) +) +LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32)) + +STDIN_HANDLE = GetStdHandle(-10) +STDOUT_HANDLE = GetStdHandle(-11) +STDERR_HANDLE = GetStdHandle(-12) + +PyBUF_SIMPLE = 0 +PyBUF_WRITABLE = 1 + +ERROR_SUCCESS = 0 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_OPERATION_ABORTED = 995 + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +EOF = b"\x1a" +MAX_BYTES_WRITTEN = 32767 + +try: + from ctypes import pythonapi +except ImportError: + # On PyPy we cannot get buffers so our ability to operate here is + # severely limited. + get_buffer = None +else: + + class Py_buffer(Structure): + _fields_ = [ + ("buf", c_void_p), + ("obj", py_object), + ("len", c_ssize_t), + ("itemsize", c_ssize_t), + ("readonly", c_int), + ("ndim", c_int), + ("format", c_char_p), + ("shape", c_ssize_p), + ("strides", c_ssize_p), + ("suboffsets", c_ssize_p), + ("internal", c_void_p), + ] + + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer + PyBuffer_Release = pythonapi.PyBuffer_Release + + def get_buffer(obj, writable=False): + buf = Py_buffer() + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE + PyObject_GetBuffer(py_object(obj), byref(buf), flags) + + try: + buffer_type = c_char * buf.len + return buffer_type.from_address(buf.buf) + finally: + PyBuffer_Release(byref(buf)) + + +class _WindowsConsoleRawIOBase(io.RawIOBase): + def __init__(self, handle): + self.handle = handle + + def isatty(self): + super().isatty() + return True + + +class _WindowsConsoleReader(_WindowsConsoleRawIOBase): + def readable(self): + return True + + def readinto(self, b): + bytes_to_be_read = len(b) + if not bytes_to_be_read: + return 0 + elif bytes_to_be_read % 2: + raise ValueError( + "cannot read odd number of bytes from UTF-16-LE encoded console" + ) + + buffer = get_buffer(b, writable=True) + code_units_to_be_read = bytes_to_be_read // 2 + code_units_read = c_ulong() + + rv = ReadConsoleW( + HANDLE(self.handle), + buffer, + code_units_to_be_read, + byref(code_units_read), + None, + ) + if GetLastError() == ERROR_OPERATION_ABORTED: + # wait for KeyboardInterrupt + time.sleep(0.1) + if not rv: + raise OSError(f"Windows error: {GetLastError()}") + + if buffer[0] == EOF: + return 0 + return 2 * code_units_read.value + + +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): + def writable(self): + return True + + @staticmethod + def _get_error_message(errno): + if errno == ERROR_SUCCESS: + return "ERROR_SUCCESS" + elif errno == ERROR_NOT_ENOUGH_MEMORY: + return "ERROR_NOT_ENOUGH_MEMORY" + return f"Windows error {errno}" + + def write(self, b): + bytes_to_be_written = len(b) + buf = get_buffer(b) + code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2 + code_units_written = c_ulong() + + WriteConsoleW( + HANDLE(self.handle), + buf, + code_units_to_be_written, + byref(code_units_written), + None, + ) + bytes_written = 2 * code_units_written.value + + if bytes_written == 0 and bytes_to_be_written > 0: + raise OSError(self._get_error_message(GetLastError())) + return bytes_written + + +class ConsoleStream: + def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None: + self._text_stream = text_stream + self.buffer = byte_stream + + @property + def name(self) -> str: + return self.buffer.name + + def write(self, x: t.AnyStr) -> int: + if isinstance(x, str): + return self._text_stream.write(x) + try: + self.flush() + except Exception: + pass + return self.buffer.write(x) + + def writelines(self, lines: t.Iterable[t.AnyStr]) -> None: + for line in lines: + self.write(line) + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._text_stream, name) + + def isatty(self) -> bool: + return self.buffer.isatty() + + def __repr__(self): + return f"" + + +def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +_stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = { + 0: _get_text_stdin, + 1: _get_text_stdout, + 2: _get_text_stderr, +} + + +def _is_console(f: t.TextIO) -> bool: + if not hasattr(f, "fileno"): + return False + + try: + fileno = f.fileno() + except (OSError, io.UnsupportedOperation): + return False + + handle = msvcrt.get_osfhandle(fileno) + return bool(GetConsoleMode(handle, byref(DWORD()))) + + +def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> t.Optional[t.TextIO]: + if ( + get_buffer is not None + and encoding in {"utf-16-le", None} + and errors in {"strict", None} + and _is_console(f) + ): + func = _stream_factories.get(f.fileno()) + if func is not None: + b = getattr(f, "buffer", None) + + if b is None: + return None + + return func(b) diff --git a/dist/ba_data/python-site-packages/click/core.py b/dist/ba_data/python-site-packages/click/core.py new file mode 100644 index 0000000..6d8cace --- /dev/null +++ b/dist/ba_data/python-site-packages/click/core.py @@ -0,0 +1,2953 @@ +import enum +import errno +import inspect +import os +import sys +import typing as t +from collections import abc +from contextlib import contextmanager +from contextlib import ExitStack +from functools import partial +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat + +from . import types +from ._unicodefun import _verify_python_env +from .exceptions import Abort +from .exceptions import BadParameter +from .exceptions import ClickException +from .exceptions import Exit +from .exceptions import MissingParameter +from .exceptions import UsageError +from .formatting import HelpFormatter +from .formatting import join_options +from .globals import pop_context +from .globals import push_context +from .parser import _flag_needs_value +from .parser import OptionParser +from .parser import split_opt +from .termui import confirm +from .termui import prompt +from .termui import style +from .utils import _detect_program_name +from .utils import _expand_args +from .utils import echo +from .utils import make_default_short_help +from .utils import make_str +from .utils import PacifyFlushWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + from .shell_completion import CompletionItem + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +V = t.TypeVar("V") + + +def _complete_visible_commands( + ctx: "Context", incomplete: str +) -> t.Iterator[t.Tuple[str, "Command"]]: + """List all the subcommands of a group that start with the + incomplete value and aren't hidden. + + :param ctx: Invocation context for the group. + :param incomplete: Value being completed. May be empty. + """ + multi = t.cast(MultiCommand, ctx.command) + + for name in multi.list_commands(ctx): + if name.startswith(incomplete): + command = multi.get_command(ctx, name) + + if command is not None and not command.hidden: + yield name, command + + +def _check_multicommand( + base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False +) -> None: + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = ( + "It is not possible to add multi commands as children to" + " another multi command that is in chain mode." + ) + else: + hint = ( + "Found a multi command as subcommand to a multi command" + " that is in chain mode. This is not supported." + ) + raise RuntimeError( + f"{hint}. Command {base_command.name!r} is set to chain and" + f" {cmd_name!r} was added as a subcommand but it in itself is a" + f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" + f" within a chained {type(base_command).__name__} named" + f" {base_command.name!r})." + ) + + +def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: + return list(zip(*repeat(iter(iterable), batch_size))) + + +@contextmanager +def augment_usage_errors( + ctx: "Context", param: t.Optional["Parameter"] = None +) -> t.Iterator[None]: + """Context manager that attaches extra information to exceptions.""" + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing( + invocation_order: t.Sequence["Parameter"], + declaration_order: t.Sequence["Parameter"], +) -> t.List["Parameter"]: + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + + def sort_key(item: "Parameter") -> t.Tuple[bool, float]: + try: + idx: float = invocation_order.index(item) + except ValueError: + idx = float("inf") + + return not item.is_eager, idx + + return sorted(declaration_order, key=sort_key) + + +class ParameterSource(enum.Enum): + """This is an :class:`~enum.Enum` that indicates the source of a + parameter's value. + + Use :meth:`click.Context.get_parameter_source` to get the + source for a parameter by name. + + .. versionchanged:: 8.0 + Use :class:`~enum.Enum` and drop the ``validate`` method. + + .. versionchanged:: 8.0 + Added the ``PROMPT`` value. + """ + + COMMANDLINE = enum.auto() + """The value was provided by the command line args.""" + ENVIRONMENT = enum.auto() + """The value was provided with an environment variable.""" + DEFAULT = enum.auto() + """Used the default specified by the parameter.""" + DEFAULT_MAP = enum.auto() + """Used a default provided by :attr:`Context.default_map`.""" + PROMPT = enum.auto() + """Used a prompt to confirm a default or provide a value.""" + + +class Context: + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + :param show_default: Show defaults for all options. If not set, + defaults to the value from a parent context. Overrides an + option's ``show_default`` argument. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.Dict[str, t.Any]] = None, + terminal_width: t.Optional[int] = None, + max_content_width: t.Optional[int] = None, + resilient_parsing: bool = False, + allow_extra_args: t.Optional[bool] = None, + allow_interspersed_args: t.Optional[bool] = None, + ignore_unknown_options: t.Optional[bool] = None, + help_option_names: t.Optional[t.List[str]] = None, + token_normalize_func: t.Optional[t.Callable[[str], str]] = None, + color: t.Optional[bool] = None, + show_default: t.Optional[bool] = None, + ) -> None: + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: Map of parameter names to their parsed values. Parameters + #: with ``expose_value=False`` are not stored. + self.params: t.Dict[str, t.Any] = {} + #: the leftover arguments. + self.args: t.List[str] = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args: t.List[str] = [] + + if obj is None and parent is not None: + obj = parent.obj + + #: the user object stored. + self.obj: t.Any = obj + self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) + + #: A dictionary (-like object) with defaults for parameters. + if ( + default_map is None + and info_name is not None + and parent is not None + and parent.default_map is not None + ): + default_map = parent.default_map.get(info_name) + + self.default_map: t.Optional[t.Dict[str, t.Any]] = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`result_callback`. + self.invoked_subcommand: t.Optional[str] = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + + #: The width of the terminal (None is autodetection). + self.terminal_width: t.Optional[int] = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width: t.Optional[int] = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args: bool = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options: bool = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ["--help"] + + #: The names for the help options. + self.help_option_names: t.List[str] = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func: t.Optional[ + t.Callable[[str], str] + ] = token_normalize_func + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing: bool = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if ( + parent is not None + and parent.auto_envvar_prefix is not None + and self.info_name is not None + ): + auto_envvar_prefix = ( + f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" + ) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + + if auto_envvar_prefix is not None: + auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") + + self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color: t.Optional[bool] = color + + if show_default is None and parent is not None: + show_default = parent.show_default + + #: Show option default values when formatting help text. + self.show_default: t.Optional[bool] = show_default + + self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] + self._depth = 0 + self._parameter_source: t.Dict[str, ParameterSource] = {} + self._exit_stack = ExitStack() + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire CLI + structure. + + .. code-block:: python + + with Context(cli) as ctx: + info = ctx.to_info_dict() + + .. versionadded:: 8.0 + """ + return { + "command": self.command.to_info_dict(self), + "info_name": self.info_name, + "allow_extra_args": self.allow_extra_args, + "allow_interspersed_args": self.allow_interspersed_args, + "ignore_unknown_options": self.ignore_unknown_options, + "auto_envvar_prefix": self.auto_envvar_prefix, + } + + def __enter__(self) -> "Context": + self._depth += 1 + push_context(self) + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self) -> t.Dict[str, t.Any]: + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = f'{__name__}.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self) -> HelpFormatter: + """Creates the :class:`~click.HelpFormatter` for the help and + usage output. + + To quickly customize the formatter class used without overriding + this method, set the :attr:`formatter_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`formatter_class` attribute. + """ + return self.formatter_class( + width=self.terminal_width, max_width=self.max_content_width + ) + + def with_resource(self, context_manager: t.ContextManager[V]) -> V: + """Register a resource as if it were used in a ``with`` + statement. The resource will be cleaned up when the context is + popped. + + Uses :meth:`contextlib.ExitStack.enter_context`. It calls the + resource's ``__enter__()`` method and returns the result. When + the context is popped, it closes the stack, which calls the + resource's ``__exit__()`` method. + + To register a cleanup function for something that isn't a + context manager, use :meth:`call_on_close`. Or use something + from :mod:`contextlib` to turn it into a context manager first. + + .. code-block:: python + + @click.group() + @click.option("--name") + @click.pass_context + def cli(ctx): + ctx.obj = ctx.with_resource(connect_db(name)) + + :param context_manager: The context manager to enter. + :return: Whatever ``context_manager.__enter__()`` returns. + + .. versionadded:: 8.0 + """ + return self._exit_stack.enter_context(context_manager) + + def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Register a function to be called when the context tears down. + + This can be used to close resources opened during the script + execution. Resources that support Python's context manager + protocol which would be used in a ``with`` statement should be + registered with :meth:`with_resource` instead. + + :param f: The function to execute on teardown. + """ + return self._exit_stack.callback(f) + + def close(self) -> None: + """Invoke all close callbacks registered with + :meth:`call_on_close`, and exit all context managers entered + with :meth:`with_resource`. + """ + self._exit_stack.close() + # In case the context is reused, create a new exit stack. + self._exit_stack = ExitStack() + + @property + def command_path(self) -> str: + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = "" + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + parent_command_path = [self.parent.command_path] + + if isinstance(self.parent.command, Command): + for param in self.parent.command.get_params(self): + parent_command_path.extend(param.get_usage_pieces(self)) + + rv = f"{' '.join(parent_command_path)} {rv}" + return rv.lstrip() + + def find_root(self) -> "Context": + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: + """Finds the closest object of a given type.""" + node: t.Optional["Context"] = self + + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + + node = node.parent + + return None + + def ensure_object(self, object_type: t.Type[V]) -> V: + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[False]" = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: + """Get the default for a parameter from :attr:`default_map`. + + :param name: Name of the parameter. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + if self.default_map is not None: + value = self.default_map.get(name) + + if call and callable(value): + return value() + + return value + + return None + + def fail(self, message: str) -> "te.NoReturn": + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self) -> "te.NoReturn": + """Aborts the script.""" + raise Abort() + + def exit(self, code: int = 0) -> "te.NoReturn": + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self) -> str: + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self) -> str: + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def _make_sub_context(self, command: "Command") -> "Context": + """Create a new context of the same type as this context, but + for a new command. + + :meta private: + """ + return type(self)(command, info_name=command.name, parent=self) + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", t.Callable[..., t.Any]], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if :meth:`forward` is called at multiple levels. + """ + if isinstance(__callback, Command): + other_cmd = __callback + + if other_cmd.callback is None: + raise TypeError( + "The given command does not have a callback that can be invoked." + ) + else: + __callback = other_cmd.callback + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.type_cast_value( # type: ignore + ctx, param.get_default(ctx) + ) + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward( + __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 + ) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.Dict[str, t.Any]] = None, + ) -> None: + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + + if context_settings is None: + context_settings = {} + + #: an optional dictionary with defaults passed to the context. + self.context_settings: t.Dict[str, t.Any] = context_settings + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire structure + below this command. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + :param ctx: A :class:`Context` representing this command. + + .. versionadded:: 8.0 + """ + return {"name": self.name} + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def get_usage(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get usage") + + def get_help(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get help") + + def make_context( + self, + info_name: t.Optional[str], + args: t.List[str], + parent: t.Optional[Context] = None, + **extra: t.Any, + ) -> Context: + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + To quickly customize the context class used without overriding + this method, set the :attr:`context_class` attribute. + + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, info_name=info_name, parent=parent, **extra # type: ignore + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invokable by default") + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of chained multi-commands. + + Any command could be part of a chained multi-command, so sibling + commands are valid at any point during command completion. Other + command classes will return more completions. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + while ctx.parent is not None: + ctx = ctx.parent + + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + results.extend( + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + if name not in ctx.protected_args + ) + + return results + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: "te.Literal[True]" = True, + **extra: t.Any, + ) -> "te.NoReturn": + ... + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = ..., + **extra: t.Any, + ) -> t.Any: + ... + + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = True, + windows_expand_args: bool = True, + **extra: t.Any, + ) -> t.Any: + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog_name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param windows_expand_args: Expand glob patterns, user dir, and + env vars in command line args on Windows. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + + .. versionchanged:: 8.0.1 + Added the ``windows_expand_args`` parameter to allow + disabling command line arg expansion on Windows. + + .. versionchanged:: 8.0 + When taking arguments from ``sys.argv`` on Windows, glob + patterns, user dir, and env vars are expanded. + + .. versionchanged:: 3.0 + Added the ``standalone_mode`` parameter. + """ + # Verify that the environment is configured correctly, or reject + # further execution to avoid a broken script. + _verify_python_env() + + if args is None: + args = sys.argv[1:] + + if os.name == "nt" and windows_expand_args: + args = _expand_args(args) + else: + args = list(args) + + if prog_name is None: + prog_name = _detect_program_name() + + # Process shell completion requests and exit early. + self._main_shell_completion(extra, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt): + echo(file=sys.stderr) + raise Abort() from None + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except OSError as e: + if e.errno == errno.EPIPE: + sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) + sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo(_("Aborted!"), file=sys.stderr) + sys.exit(1) + + def _main_shell_completion( + self, + ctx_args: t.Dict[str, t.Any], + prog_name: str, + complete_var: t.Optional[str] = None, + ) -> None: + """Check if the shell is asking for tab completion, process + that, then exit early. Called from :meth:`main` before the + program is invoked. + + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. Defaults to + ``_{PROG_NAME}_COMPLETE``. + """ + if complete_var is None: + complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper() + + instruction = os.environ.get(complete_var) + + if not instruction: + return + + from .shell_completion import shell_complete + + rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) + sys.exit(rv) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + .. versionchanged:: 8.0 + Added repr showing the command name + .. versionchanged:: 7.1 + Added the `no_args_is_help` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is disabled by default. + If enabled this will add ``--help`` as argument + if no arguments are passed + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.Dict[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List["Parameter"] = params or [] + + # if a form feed (page break) is found in the help text, truncate help + # text to the content preceding the first form feed + if help and "\f" in help: + help = help.split("\f", 1)[0] + + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self.no_args_is_help = no_args_is_help + self.hidden = hidden + self.deprecated = deprecated + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + info_dict.update( + params=[param.to_info_dict() for param in self.get_params(ctx)], + help=self.help, + epilog=self.epilog, + short_help=self.short_help, + hidden=self.hidden, + deprecated=self.deprecated, + ) + return info_dict + + def get_usage(self, ctx: Context) -> str: + """Formats the usage line into a string and returns it. + + Calls :meth:`format_usage` internally. + """ + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_params(self, ctx: Context) -> t.List["Parameter"]: + rv = self.params + help_option = self.get_help_option(ctx) + + if help_option is not None: + rv = [*rv, help_option] + + return rv + + def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the usage line into the formatter. + + This is a low-level method called by :meth:`get_usage`. + """ + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, " ".join(pieces)) + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] if self.options_metavar else [] + + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + + return rv + + def get_help_option_names(self, ctx: Context) -> t.List[str]: + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return list(all_names) + + def get_help_option(self, ctx: Context) -> t.Optional["Option"]: + """Returns the help option object.""" + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + def show_help(ctx: Context, param: "Parameter", value: str) -> None: + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + return Option( + help_options, + is_flag=True, + is_eager=True, + expose_value=False, + callback=show_help, + help=_("Show this message and exit."), + ) + + def make_parser(self, ctx: Context) -> OptionParser: + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx: Context) -> str: + """Formats the help into a string and returns it. + + Calls :meth:`format_help` internally. + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_short_help_str(self, limit: int = 45) -> str: + """Gets short help for the command or makes it by shortening the + long help string. + """ + text = self.short_help or "" + + if not text and self.help: + text = make_default_short_help(self.help, limit) + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + text = self.help or "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + if text: + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(text) + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section(_("Options")): + formatter.write_dl(opts) + + def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + formatter.write_paragraph() + with formatter.indentation(): + formatter.write_text(self.epilog) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing(param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail( + ngettext( + "Got unexpected extra argument ({args})", + "Got unexpected extra arguments ({args})", + len(args), + ).format(args=" ".join(map(str, args))) + ) + + ctx.args = args + return args + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.deprecated: + message = _( + "DeprecationWarning: The command {name!r} is deprecated." + ).format(name=self.name) + echo(style(message, fg="red"), err=True) + + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options and chained multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + if incomplete and not incomplete[0].isalnum(): + for param in self.get_params(ctx): + if ( + not isinstance(param, Option) + or param.hidden + or ( + not param.multiple + and ctx.get_parameter_source(param.name) # type: ignore + is ParameterSource.COMMANDLINE + ) + ): + continue + + results.extend( + CompletionItem(name, help=param.help) + for name in [*param.opts, *param.secondary_opts] + if name.startswith(incomplete) + ) + + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: The result callback to attach to this multi + command. This can be set or changed later with the + :meth:`result_callback` decorator. + """ + + allow_extra_args = True + allow_interspersed_args = False + + def __init__( + self, + name: t.Optional[str] = None, + invoke_without_command: bool = False, + no_args_is_help: t.Optional[bool] = None, + subcommand_metavar: t.Optional[str] = None, + chain: bool = False, + result_callback: t.Optional[t.Callable[..., t.Any]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + + if subcommand_metavar is None: + if chain: + subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." + else: + subcommand_metavar = "COMMAND [ARGS]..." + + self.subcommand_metavar = subcommand_metavar + self.chain = chain + # The result callback that is stored. This can be set or + # overridden with the :func:`result_callback` decorator. + self._result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError( + "Multi commands in chain mode cannot have" + " optional arguments." + ) + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + commands = {} + + for name in self.list_commands(ctx): + command = self.get_command(ctx, name) + + if command is None: + continue + + sub_ctx = ctx._make_sub_context(command) + + with sub_ctx.scope(cleanup=False): + commands[name] = command.to_info_dict(sub_ctx) + + info_dict.update(commands=commands, chain=self.chain) + return info_dict + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + rv = super().collect_usage_pieces(ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + super().format_options(ctx, formatter) + self.format_commands(ctx, formatter) + + def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: + """Adds a result callback to the command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.result_callback() + def process_result(result, input): + return result + input + + :param replace: if set to `True` an already existing result + callback will be removed. + + .. versionchanged:: 8.0 + Renamed from ``resultcallback``. + + .. versionadded:: 3.0 + """ + + def decorator(f: F) -> F: + old_callback = self._result_callback + + if old_callback is None or replace: + self._result_callback = f + return f + + def function(__value, *args, **kwargs): # type: ignore + inner = old_callback(__value, *args, **kwargs) # type: ignore + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv + + return decorator + + def resultcallback(self, replace: bool = False) -> t.Callable[[F], F]: + import warnings + + warnings.warn( + "'resultcallback' has been renamed to 'result_callback'." + " The old name will be removed in Click 8.1.", + DeprecationWarning, + stacklevel=2, + ) + return self.result_callback(replace=replace) + + def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section(_("Commands")): + formatter.write_dl(rows) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = super().parse_args(ctx, args) + + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx: Context) -> t.Any: + def _process_result(value: t.Any) -> t.Any: + if self._result_callback is not None: + value = ctx.invoke(self._result_callback, value, **ctx.params) + return value + + if not ctx.protected_args: + if self.invoke_without_command: + # No subcommand was invoked, so the result callback is + # invoked with None for regular groups, or an empty list + # for chained groups. + with ctx: + super().invoke(ctx) + return _process_result([] if self.chain else None) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commmands`` argument can be a list of command objects. + """ + + #: If set, this is used by the group's :meth:`command` decorator + #: as the default :class:`Command` class. This is useful to make all + #: subcommands use a custom command class. + #: + #: .. versionadded:: 8.0 + command_class: t.Optional[t.Type[Command]] = None + + #: If set, this is used by the group's :meth:`group` decorator + #: as the default :class:`Group` class. This is useful to make all + #: subgroups use a custom group class. + #: + #: If set to the special value :class:`type` (literally + #: ``group_class = type``), this group's class will be used as the + #: default class. This makes a custom group class continue to make + #: custom groups. + #: + #: .. versionadded:: 8.0 + group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None + # Literal[type] isn't valid, so use Type[type] + + def __init__( + self, + name: t.Optional[str] = None, + commands: t.Optional[t.Union[t.Dict[str, Command], t.Sequence[Command]]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if commands is None: + commands = {} + elif isinstance(commands, abc.Sequence): + commands = {c.name: c for c in commands if c.name is not None} + + #: The registered subcommands by their exported names. + self.commands: t.Dict[str, Command] = commands + + def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError("Command has no name.") + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], Command]: + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` and + immediately registers the created command with this group by + calling :meth:`add_command`. + + To customize the command class used, set the + :attr:`command_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + if self.command_class is not None and "cls" not in kwargs: + kwargs["cls"] = self.command_class + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + return decorator + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` and + immediately registers the created group with this group by + calling :meth:`add_command`. + + To customize the group class used, set the :attr:`group_class` + attribute. + + .. versionchanged:: 8.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + if self.group_class is not None and "cls" not in kwargs: + if self.group_class is type: + kwargs["cls"] = type(self) + else: + kwargs["cls"] = self.group_class + + def decorator(f: t.Callable[..., t.Any]) -> "Group": + cmd = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + return decorator + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + return self.commands.get(cmd_name) + + def list_commands(self, ctx: Context) -> t.List[str]: + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + """ + + def __init__( + self, + name: t.Optional[str] = None, + sources: t.Optional[t.List[MultiCommand]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + #: The list of registered multi commands. + self.sources: t.List[MultiCommand] = sources or [] + + def add_source(self, multi_cmd: MultiCommand) -> None: + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + + return rv + + return None + + def list_commands(self, ctx: Context) -> t.List[str]: + rv: t.Set[str] = set() + + for source in self.sources: + rv.update(source.list_commands(ctx)) + + return sorted(rv) + + +def _check_iter(value: t.Any) -> t.Iterator[t.Any]: + """Check if the value is iterable but not a string. Raises a type + error, or return an iterator over the value. + """ + if isinstance(value, str): + raise TypeError + + return iter(value) + + +class Parameter: + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The later is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: A function to further process or validate the value + after type conversion. It is called as ``f(ctx, param, value)`` + and must return the value. It is called for all sources, + including prompts. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). If ``nargs=-1``, all remaining + parameters are collected. + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + :param shell_complete: A function that returns custom shell + completions. Used instead of the param's type completion if + given. Takes ``ctx, param, incomplete`` and must return a list + of :class:`~click.shell_completion.CompletionItem` or a list of + strings. + + .. versionchanged:: 8.0 + ``process_value`` validates required parameters and bounded + ``nargs``, and invokes the parameter callback before returning + the value. This allows the callback to validate prompts. + ``full_process_value`` is removed. + + .. versionchanged:: 8.0 + ``autocompletion`` is renamed to ``shell_complete`` and has new + semantics described above. The old name is deprecated and will + be removed in 8.1, until then it will be wrapped to match the + new requirements. + + .. versionchanged:: 8.0 + For ``multiple=True, nargs>1``, the default must be a list of + tuples. + + .. versionchanged:: 8.0 + Setting a default is no longer required for ``nargs>1``, it will + default to ``None``. ``multiple=True`` or ``nargs=-1`` will + default to ``()``. + + .. versionchanged:: 7.1 + Empty environment variables are ignored rather than taking the + empty string value. This makes it possible for scripts to clear + variables if they can't unset them. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. The old callback format will still work, but it will + raise a warning to give you a chance to migrate the code easier. + """ + + param_type_name = "parameter" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + required: bool = False, + default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, + callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, + nargs: t.Optional[int] = None, + multiple: bool = False, + metavar: t.Optional[str] = None, + expose_value: bool = True, + is_eager: bool = False, + envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, + shell_complete: t.Optional[ + t.Callable[ + [Context, "Parameter", str], + t.Union[t.List["CompletionItem"], t.List[str]], + ] + ] = None, + autocompletion: t.Optional[ + t.Callable[ + [Context, t.List[str], str], t.List[t.Union[t.Tuple[str, str], str]] + ] + ] = None, + ) -> None: + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type = types.convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = multiple + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + + if autocompletion is not None: + import warnings + + warnings.warn( + "'autocompletion' is renamed to 'shell_complete'. The old name is" + " deprecated and will be removed in Click 8.1. See the docs about" + " 'Parameter' for information about new behavior.", + DeprecationWarning, + stacklevel=2, + ) + + def shell_complete( + ctx: Context, param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + from click.shell_completion import CompletionItem + + out = [] + + for c in autocompletion(ctx, [], incomplete): # type: ignore + if isinstance(c, tuple): + c = CompletionItem(c[0], help=c[1]) + elif isinstance(c, str): + c = CompletionItem(c) + + if c.value.startswith(incomplete): + out.append(c) + + return out + + self._custom_shell_complete = shell_complete + + if __debug__: + if self.type.is_composite and nargs != self.type.arity: + raise ValueError( + f"'nargs' must be {self.type.arity} (or None) for" + f" type {self.type!r}, but it was {nargs}." + ) + + # Skip no default or callable default. + check_default = default if not callable(default) else None + + if check_default is not None: + if multiple: + try: + # Only check the first value against nargs. + check_default = next(_check_iter(check_default), None) + except TypeError: + raise ValueError( + "'default' must be a list when 'multiple' is true." + ) from None + + # Can be None for multiple with empty default. + if nargs != 1 and check_default is not None: + try: + _check_iter(check_default) + except TypeError: + if multiple: + message = ( + "'default' must be a list of lists when 'multiple' is" + " true and 'nargs' != 1." + ) + else: + message = "'default' must be a list when 'nargs' != 1." + + raise ValueError(message) from None + + if nargs > 1 and len(check_default) != nargs: + subject = "item length" if multiple else "length" + raise ValueError( + f"'default' {subject} must match nargs={nargs}." + ) + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + return { + "name": self.name, + "param_type_name": self.param_type_name, + "opts": self.opts, + "secondary_opts": self.secondary_opts, + "type": self.type.to_info_dict(), + "required": self.required, + "nargs": self.nargs, + "multiple": self.multiple, + "default": self.default, + "envvar": self.envvar, + } + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + raise NotImplementedError() + + @property + def human_readable_name(self) -> str: + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + + metavar = self.type.get_metavar(self) + + if metavar is None: + metavar = self.type.name.upper() + + if self.nargs != 1: + metavar += "..." + + return metavar + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + """Get the default for the parameter. Tries + :meth:`Context.lookup_default` first, then the local default. + + :param ctx: Current context. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0.2 + Type casting is no longer performed when getting a default. + + .. versionchanged:: 8.0.1 + Type casting can fail in resilient parsing mode. Invalid + defaults will not prevent showing help text. + + .. versionchanged:: 8.0 + Looks at ``ctx.default_map`` first. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + value = ctx.lookup_default(self.name, call=False) # type: ignore + + if value is None: + value = self.default + + if call and callable(value): + value = value() + + return value + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + raise NotImplementedError() + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, t.Any] + ) -> t.Tuple[t.Any, ParameterSource]: + value = opts.get(self.name) # type: ignore + source = ParameterSource.COMMANDLINE + + if value is None: + value = self.value_from_envvar(ctx) + source = ParameterSource.ENVIRONMENT + + if value is None: + value = ctx.lookup_default(self.name) # type: ignore + source = ParameterSource.DEFAULT_MAP + + if value is None: + value = self.get_default(ctx) + source = ParameterSource.DEFAULT + + return value, source + + def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: + """Convert and validate a value against the option's + :attr:`type`, :attr:`multiple`, and :attr:`nargs`. + """ + if value is None: + return () if self.multiple or self.nargs == -1 else None + + def check_iter(value: t.Any) -> t.Iterator: + try: + return _check_iter(value) + except TypeError: + # This should only happen when passing in args manually, + # the parser should construct an iterable when parsing + # the command line. + raise BadParameter( + _("Value must be an iterable."), ctx=ctx, param=self + ) from None + + if self.nargs == 1 or self.type.is_composite: + convert: t.Callable[[t.Any], t.Any] = partial( + self.type, param=self, ctx=ctx + ) + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Tuple: + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Tuple: + value = tuple(check_iter(value)) + + if len(value) != self.nargs: + raise BadParameter( + ngettext( + "Takes {nargs} values but 1 was given.", + "Takes {nargs} values but {len} were given.", + len(value), + ).format(nargs=self.nargs, len=len(value)), + ctx=ctx, + param=self, + ) + + return tuple(self.type(x, self, ctx) for x in value) + + if self.multiple: + return tuple(convert(x) for x in check_iter(value)) + + return convert(value) + + def value_is_missing(self, value: t.Any) -> bool: + if value is None: + return True + + if (self.nargs != 1 or self.multiple) and value == (): + return True + + return False + + def process_value(self, ctx: Context, value: t.Any) -> t.Any: + value = self.type_cast_value(ctx, value) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + if self.callback is not None: + value = self.callback(ctx, self, value) + + return value + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + if self.envvar is None: + return None + + if isinstance(self.envvar, str): + rv = os.environ.get(self.envvar) + + if rv: + return rv + else: + for envvar in self.envvar: + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + + return rv + + def handle_parse_result( + self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str] + ) -> t.Tuple[t.Any, t.List[str]]: + with augment_usage_errors(ctx, param=self): + value, source = self.consume_value(ctx, opts) + ctx.set_parameter_source(self.name, source) # type: ignore + + try: + value = self.process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + + value = None + + if self.expose_value: + ctx.params[self.name] = value # type: ignore + + return value, args + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + pass + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [] + + def get_error_hint(self, ctx: Context) -> str: + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return " / ".join(f"'{x}'" for x in hint_list) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. If a + ``shell_complete`` function was given during init, it is used. + Otherwise, the :attr:`type` + :meth:`~click.types.ParamType.shell_complete` function is used. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + if self._custom_shell_complete is not None: + results = self._custom_shell_complete(ctx, self, incomplete) + + if results and isinstance(results[0], str): + from click.shell_completion import CompletionItem + + results = [CompletionItem(c) for c in results] + + return t.cast(t.List["CompletionItem"], results) + + return self.type.shell_complete(ctx, self, incomplete) + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: controls if the default value should be shown on the + help page. Normally, defaults are not shown. If this + value is a string, it shows the string instead of the + value. This is particularly useful for dynamic options. + :param show_envvar: controls if an environment variable should be shown on + the help page. Normally, environment variables + are not shown. + :param prompt: if set to `True` or a non empty string then the user will be + prompted for input. If set to `True` the prompt will be the + option name capitalized. + :param confirmation_prompt: Prompt a second time to confirm the + value if it was prompted for. Can be set to a string instead of + ``True`` to customize the message. + :param prompt_required: If set to ``False``, the user will be + prompted for input only when the option was specified as a flag + without a value. + :param hide_input: if this is `True` then the input on the prompt will be + hidden from the user. This is useful for password + input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + + .. versionchanged:: 8.0.1 + ``type`` is detected from ``flag_value`` if given. + """ + + param_type_name = "option" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + show_default: t.Union[bool, str] = False, + prompt: t.Union[bool, str] = False, + confirmation_prompt: t.Union[bool, str] = False, + prompt_required: bool = True, + hide_input: bool = False, + is_flag: t.Optional[bool] = None, + flag_value: t.Optional[t.Any] = None, + multiple: bool = False, + count: bool = False, + allow_from_autoenv: bool = True, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + help: t.Optional[str] = None, + hidden: bool = False, + show_choices: bool = True, + show_envvar: bool = False, + **attrs: t.Any, + ) -> None: + default_is_missing = "default" not in attrs + super().__init__(param_decls, type=type, multiple=multiple, **attrs) + + if prompt is True: + if self.name is None: + raise TypeError("'name' is required with 'prompt=True'.") + + prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.prompt_required = prompt_required + self.hide_input = hide_input + self.hidden = hidden + + # If prompt is enabled but not required, then the option can be + # used as a flag to indicate using prompt or flag_value. + self._flag_needs_value = self.prompt is not None and not self.prompt_required + + if is_flag is None: + if flag_value is not None: + # Implicitly a flag because flag_value was set. + is_flag = True + elif self._flag_needs_value: + # Not a flag, but when used as a flag it shows a prompt. + is_flag = False + else: + # Implicitly a flag because flag options were given. + is_flag = bool(self.secondary_opts) + elif is_flag is False and not self._flag_needs_value: + # Not a flag, and prompt is not enabled, can be used as a + # flag if flag_value is set. + self._flag_needs_value = flag_value is not None + + if is_flag and default_is_missing: + self.default: t.Union[t.Any, t.Callable[[], t.Any]] = False + + if flag_value is None: + flag_value = not self.default + + if is_flag and type is None: + # Re-guess the type from the flag value instead of the + # default. + self.type = types.convert_type(None, flag_value) + + self.is_flag: bool = is_flag + self.is_bool_flag = is_flag and isinstance(self.type, types.BoolParamType) + self.flag_value: t.Any = flag_value + + # Counting + self.count = count + if count: + if type is None: + self.type = types.IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + self.show_choices = show_choices + self.show_envvar = show_envvar + + if __debug__: + if self.nargs == -1: + raise TypeError("nargs=-1 is not supported for options.") + + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError("'prompt' is not valid for non-boolean flag.") + + if not self.is_bool_flag and self.secondary_opts: + raise TypeError("Secondary flag is not valid for non-boolean flag.") + + if self.is_bool_flag and self.hide_input and self.prompt is not None: + raise TypeError( + "'prompt' with 'hide_input' is not valid for boolean flag." + ) + + if self.count: + if self.multiple: + raise TypeError("'count' is not valid with 'multiple'.") + + if self.is_flag: + raise TypeError("'count' is not valid with 'is_flag'.") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + help=self.help, + prompt=self.prompt, + is_flag=self.is_flag, + flag_value=self.flag_value, + count=self.count, + hidden=self.hidden, + ) + return info_dict + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if decl.isidentifier(): + if name is not None: + raise TypeError(f"Name '{name}' defined twice") + name = decl + else: + split_char = ";" if decl[:1] == "/" else "/" + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + if first == second: + raise ValueError( + f"Boolean option {decl!r} cannot use the" + " same flag for true/false." + ) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace("-", "_").lower() + if not name.isidentifier(): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError("Could not determine name for option") + + if not opts and not secondary_opts: + raise TypeError( + f"No options defined but a name was passed ({name})." + " Did you mean to declare an argument instead? Did" + f" you mean to pass '--{name}'?" + ) + + return name, opts, secondary_opts + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + if self.multiple: + action = "append" + elif self.count: + action = "count" + else: + action = "store" + + if self.is_flag: + action = f"{action}_const" + + if self.is_bool_flag and self.secondary_opts: + parser.add_option( + obj=self, opts=self.opts, dest=self.name, action=action, const=True + ) + parser.add_option( + obj=self, + opts=self.secondary_opts, + dest=self.name, + action=action, + const=False, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + const=self.flag_value, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + nargs=self.nargs, + ) + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: t.Sequence[str]) -> str: + nonlocal any_prefix_is_slash + + rv, any_slashes = join_options(opts) + + if any_slashes: + any_prefix_is_slash = True + + if not self.is_flag and not self.count: + rv += f" {self.make_metavar()}" + + return rv + + rv = [_write_opts(self.opts)] + + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or "" + extra = [] + + if self.show_envvar: + envvar = self.envvar + + if envvar is None: + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + + if envvar is not None: + var_str = ( + envvar + if isinstance(envvar, str) + else ", ".join(str(d) for d in envvar) + ) + extra.append(_("env var: {var}").format(var=var_str)) + + # Temporarily enable resilient parsing to avoid type casting + # failing for the default. Might be possible to extend this to + # help formatting in general. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + + try: + default_value = self.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + show_default_is_str = isinstance(self.show_default, str) + + if show_default_is_str or ( + default_value is not None and (self.show_default or ctx.show_default) + ): + if show_default_is_str: + default_string = f"({self.show_default})" + elif isinstance(default_value, (list, tuple)): + default_string = ", ".join(str(d) for d in default_value) + elif inspect.isfunction(default_value): + default_string = _("(dynamic)") + elif self.is_bool_flag and self.secondary_opts: + # For boolean flags that have distinct True/False opts, + # use the opt without prefix instead of the value. + default_string = split_opt( + (self.opts if self.default else self.secondary_opts)[0] + )[1] + else: + default_string = str(default_value) + + if default_string: + extra.append(_("default: {default}").format(default=default_string)) + + if ( + isinstance(self.type, types._NumberRangeBase) + # skip count with default range type + and not (self.count and self.type.min == 0 and self.type.max is None) + ): + range_str = self.type._describe_range() + + if range_str: + extra.append(range_str) + + if self.required: + extra.append(_("required")) + + if extra: + extra_str = "; ".join(extra) + help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" + + return ("; " if any_prefix_is_slash else " / ").join(rv), help + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + # If we're a non boolean flag our default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return param.flag_value # type: ignore + + return None + + return super().get_default(ctx, call=call) + + def prompt_for_value(self, ctx: Context) -> t.Any: + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + assert self.prompt is not None + + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt( + self.prompt, + default=default, + type=self.type, + hide_input=self.hide_input, + show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x), + ) + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + rv = super().resolve_envvar_value(ctx) + + if rv is not None: + return rv + + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + rv = os.environ.get(envvar) + + return rv + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is None: + return None + + value_depth = (self.nargs != 1) + bool(self.multiple) + + if value_depth > 0: + rv = self.type.split_envvar_value(rv) + + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + + return rv + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, "Parameter"] + ) -> t.Tuple[t.Any, ParameterSource]: + value, source = super().consume_value(ctx, opts) + + # The parser will emit a sentinel value if the option can be + # given as a flag without a value. This is different from None + # to distinguish from the flag not being given at all. + if value is _flag_needs_value: + if self.prompt is not None and not ctx.resilient_parsing: + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + else: + value = self.flag_value + source = ParameterSource.COMMANDLINE + + elif ( + self.multiple + and value is not None + and any(v is _flag_needs_value for v in value) + ): + value = [self.flag_value if v is _flag_needs_value else v for v in value] + source = ParameterSource.COMMANDLINE + + # The value wasn't set, or used the param's default, prompt if + # prompting is enabled. + elif ( + source in {None, ParameterSource.DEFAULT} + and self.prompt is not None + and (self.required or self.prompt_required) + and not ctx.resilient_parsing + ): + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + + return value, source + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the parameter constructor. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Could not determine name for argument") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/dist/ba_data/python-site-packages/click/decorators.py b/dist/ba_data/python-site-packages/click/decorators.py new file mode 100644 index 0000000..7930a16 --- /dev/null +++ b/dist/ba_data/python-site-packages/click/decorators.py @@ -0,0 +1,436 @@ +import inspect +import types +import typing as t +from functools import update_wrapper +from gettext import gettext as _ + +from .core import Argument +from .core import Command +from .core import Context +from .core import Group +from .core import Option +from .core import Parameter +from .globals import get_current_context +from .utils import echo + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +FC = t.TypeVar("FC", bound=t.Union[t.Callable[..., t.Any], Command]) + + +def pass_context(f: F) -> F: + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args, **kwargs): # type: ignore + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def pass_obj(f: F) -> F: + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + + def new_func(*args, **kwargs): # type: ignore + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def make_pass_decorator( + object_type: t.Type, ensure: bool = False +) -> "t.Callable[[F], F]": + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + + def decorator(f: F) -> F: + def new_func(*args, **kwargs): # type: ignore + ctx = get_current_context() + + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + + if obj is None: + raise RuntimeError( + "Managed to invoke callback without a context" + f" object of type {object_type.__name__!r}" + " existing." + ) + + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + return decorator + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[F], F]": + """Create a decorator that passes a key from + :attr:`click.Context.meta` as the first argument to the decorated + function. + + :param key: Key in ``Context.meta`` to pass. + :param doc_description: Description of the object being passed, + inserted into the decorator's docstring. Defaults to "the 'key' + key from Context.meta". + + .. versionadded:: 8.0 + """ + + def decorator(f: F) -> F: + def new_func(*args, **kwargs): # type: ignore + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + if doc_description is None: + doc_description = f"the {key!r} key from :attr:`click.Context.meta`" + + decorator.__doc__ = ( + f"Decorator that passes {doc_description} as the first argument" + " to the decorated function." + ) + return decorator + + +def _make_command( + f: F, + name: t.Optional[str], + attrs: t.MutableMapping[str, t.Any], + cls: t.Type[Command], +) -> Command: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + try: + params = f.__click_params__ # type: ignore + params.reverse() + del f.__click_params__ # type: ignore + except AttributeError: + params = [] + + help = attrs.get("help") + + if help is None: + help = inspect.getdoc(f) + else: + help = inspect.cleandoc(help) + + attrs["help"] = help + return cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) + + +def command( + name: t.Optional[str] = None, + cls: t.Optional[t.Type[Command]] = None, + **attrs: t.Any, +) -> t.Callable[[F], Command]: + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function with + underscores replaced by dashes. If you want to change that, you can + pass the intended name as the first argument. + + All keyword arguments are forwarded to the underlying command class. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name with underscores replaced by dashes. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + """ + if cls is None: + cls = Command + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd = _make_command(f, name, attrs, cls) # type: ignore + cmd.__doc__ = f.__doc__ + return cmd + + return decorator + + +def group(name: t.Optional[str] = None, **attrs: t.Any) -> t.Callable[[F], Group]: + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + """ + attrs.setdefault("cls", Group) + return t.cast(Group, command(name, **attrs)) + + +def _param_memo(f: FC, param: Parameter) -> None: + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, "__click_params__"): + f.__click_params__ = [] # type: ignore + + f.__click_params__.append(param) # type: ignore + + +def argument(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + """ + + def decorator(f: FC) -> FC: + ArgumentClass = attrs.pop("cls", Argument) + _param_memo(f, ArgumentClass(param_decls, **attrs)) + return f + + return decorator + + +def option(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + """ + + def decorator(f: FC) -> FC: + # Issue 926, copy attrs, so pre-defined options can re-use the same cls= + option_attrs = attrs.copy() + + if "help" in option_attrs: + option_attrs["help"] = inspect.cleandoc(option_attrs["help"]) + OptionClass = option_attrs.pop("cls", Option) + _param_memo(f, OptionClass(param_decls, **option_attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None + # break reference cycle + # https://docs.python.org/3/library/inspect.html#the-interpreter-stack + del frame + + if f_globals is not None: + package_name = f_globals.get("__name__") + + if package_name == "__main__": + package_name = f_globals.get("__package__") + + if package_name: + package_name = package_name.partition(".")[0] + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + nonlocal prog_name + nonlocal version + + if prog_name is None: + prog_name = ctx.find_root().info_name + + if version is None and package_name is not None: + metadata: t.Optional[types.ModuleType] + + try: + from importlib import metadata # type: ignore + except ImportError: + # Python < 3.8 + import importlib_metadata as metadata # type: ignore + + try: + version = metadata.version(package_name) # type: ignore + except metadata.PackageNotFoundError: # type: ignore + raise RuntimeError( + f"{package_name!r} is not installed. Try passing" + " 'package_name' instead." + ) from None + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + t.cast(str, message) + % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--help`` option which immediately prints the help page + and exits the program. + + This is usually unnecessary, as the ``--help`` option is added to + each command automatically unless ``add_help_option=False`` is + passed. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) diff --git a/dist/ba_data/python-site-packages/click/exceptions.py b/dist/ba_data/python-site-packages/click/exceptions.py new file mode 100644 index 0000000..9e20b3e --- /dev/null +++ b/dist/ba_data/python-site-packages/click/exceptions.py @@ -0,0 +1,287 @@ +import os +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .utils import echo + +if t.TYPE_CHECKING: + from .core import Context + from .core import Parameter + + +def _join_param_hints( + param_hint: t.Optional[t.Union[t.Sequence[str], str]] +) -> t.Optional[str]: + if param_hint is not None and not isinstance(param_hint, str): + return " / ".join(repr(x) for x in param_hint) + + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception. + exit_code = 1 + + def __init__(self, message: str) -> None: + super().__init__(message) + self.message = message + + def format_message(self) -> str: + return self.message + + def __str__(self) -> str: + return self.message + + def show(self, file: t.Optional[t.IO] = None) -> None: + if file is None: + file = get_text_stderr() + + echo(_("Error: {message}").format(message=self.format_message()), file=file) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + + exit_code = 2 + + def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: + super().__init__(message) + self.ctx = ctx + self.cmd = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO] = None) -> None: + if file is None: + file = get_text_stderr() + color = None + hint = "" + if ( + self.ctx is not None + and self.ctx.command.get_help_option(self.ctx) is not None + ): + hint = _("Try '{command} {option}' for help.").format( + command=self.ctx.command_path, option=self.ctx.help_option_names[0] + ) + hint = f"{hint}\n" + if self.ctx is not None: + color = self.ctx.color + echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color) + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=color, + ) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__( + self, + message: str, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + ) -> None: + super().__init__(message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + return _("Invalid value: {message}").format(message=self.message) + + return _("Invalid value for {param_hint}: {message}").format( + param_hint=_join_param_hints(param_hint), message=self.message + ) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__( + self, + message: t.Optional[str] = None, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + param_type: t.Optional[str] = None, + ) -> None: + super().__init__(message or "", ctx, param, param_hint) + self.param_type = param_type + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint: t.Optional[str] = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + param_hint = None + + param_hint = _join_param_hints(param_hint) + param_hint = f" {param_hint}" if param_hint else "" + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += f". {msg_extra}" + else: + msg = msg_extra + + msg = f" {msg}" if msg else "" + + # Translate param_type for known types. + if param_type == "argument": + missing = _("Missing argument") + elif param_type == "option": + missing = _("Missing option") + elif param_type == "parameter": + missing = _("Missing parameter") + else: + missing = _("Missing {param_type}").format(param_type=param_type) + + return f"{missing}{param_hint}.{msg}" + + def __str__(self) -> str: + if not self.message: + param_name = self.param.name if self.param else None + return _("Missing parameter: {param_name}").format(param_name=param_name) + else: + return self.message + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__( + self, + option_name: str, + message: t.Optional[str] = None, + possibilities: t.Optional[t.Sequence[str]] = None, + ctx: t.Optional["Context"] = None, + ) -> None: + if message is None: + message = _("No such option: {name}").format(name=option_name) + + super().__init__(message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self) -> str: + if not self.possibilities: + return self.message + + possibility_str = ", ".join(sorted(self.possibilities)) + suggest = ngettext( + "Did you mean {possibility}?", + "(Possible options: {possibilities})", + len(self.possibilities), + ).format(possibility=possibility_str, possibilities=possibility_str) + return f"{self.message} {suggest}" + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__( + self, option_name: str, message: str, ctx: t.Optional["Context"] = None + ) -> None: + super().__init__(message, ctx) + self.option_name = option_name + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: + if hint is None: + hint = _("unknown error") + + super().__init__(hint) + self.ui_filename = os.fsdecode(filename) + self.filename = filename + + def format_message(self) -> str: + return _("Could not open file {filename!r}: {message}").format( + filename=self.ui_filename, message=self.message + ) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + + __slots__ = ("exit_code",) + + def __init__(self, code: int = 0) -> None: + self.exit_code = code diff --git a/dist/ba_data/python-site-packages/click/formatting.py b/dist/ba_data/python-site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/dist/ba_data/python-site-packages/click/formatting.py @@ -0,0 +1,301 @@ +import typing as t +from contextlib import contextmanager +from gettext import gettext as _ + +from ._compat import term_len +from .parser import split_opt + +# Can force a width. This is used by the test system +FORCED_WIDTH: t.Optional[int] = None + + +def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]: + widths: t.Dict[int, int] = {} + + for row in rows: + for idx, col in enumerate(row): + widths[idx] = max(widths.get(idx, 0), term_len(col)) + + return tuple(y for x, y in sorted(widths.items())) + + +def iter_rows( + rows: t.Iterable[t.Tuple[str, str]], col_count: int +) -> t.Iterator[t.Tuple[str, ...]]: + for row in rows: + yield row + ("",) * (col_count - len(row)) + + +def wrap_text( + text: str, + width: int = 78, + initial_indent: str = "", + subsequent_indent: str = "", + preserve_paragraphs: bool = False, +) -> str: + """A helper function that intelligently wraps text. By default, it + assumes that it operates on a single paragraph of text but if the + `preserve_paragraphs` parameter is provided it will intelligently + handle paragraphs (defined by two empty lines). + + If paragraphs are handled, a paragraph can be prefixed with an empty + line containing the ``\\b`` character (``\\x08``) to indicate that + no rewrapping should happen in that block. + + :param text: the text that should be rewrapped. + :param width: the maximum width for the text. + :param initial_indent: the initial indent that should be placed on the + first line as a string. + :param subsequent_indent: the indent string that should be placed on + each consecutive line. + :param preserve_paragraphs: if this flag is set then the wrapping will + intelligently handle paragraphs. + """ + from ._textwrap import TextWrapper + + text = text.expandtabs() + wrapper = TextWrapper( + width, + initial_indent=initial_indent, + subsequent_indent=subsequent_indent, + replace_whitespace=False, + ) + if not preserve_paragraphs: + return wrapper.fill(text) + + p: t.List[t.Tuple[int, bool, str]] = [] + buf: t.List[str] = [] + indent = None + + def _flush_par() -> None: + if not buf: + return + if buf[0].strip() == "\b": + p.append((indent or 0, True, "\n".join(buf[1:]))) + else: + p.append((indent or 0, False, " ".join(buf))) + del buf[:] + + for line in text.splitlines(): + if not line: + _flush_par() + indent = None + else: + if indent is None: + orig_len = term_len(line) + line = line.lstrip() + indent = orig_len - term_len(line) + buf.append(line) + _flush_par() + + rv = [] + for indent, raw, text in p: + with wrapper.extra_indent(" " * indent): + if raw: + rv.append(wrapper.indent_only(text)) + else: + rv.append(wrapper.fill(text)) + + return "\n\n".join(rv) + + +class HelpFormatter: + """This class helps with formatting text-based help pages. It's + usually just needed for very special internal cases, but it's also + exposed so that developers can write their own fancy outputs. + + At present, it always writes into memory. + + :param indent_increment: the additional increment for each level. + :param width: the width for the text. This defaults to the terminal + width clamped to a maximum of 78. + """ + + def __init__( + self, + indent_increment: int = 2, + width: t.Optional[int] = None, + max_width: t.Optional[int] = None, + ) -> None: + import shutil + + self.indent_increment = indent_increment + if max_width is None: + max_width = 80 + if width is None: + width = FORCED_WIDTH + if width is None: + width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50) + self.width = width + self.current_indent = 0 + self.buffer: t.List[str] = [] + + def write(self, string: str) -> None: + """Writes a unicode string into the internal buffer.""" + self.buffer.append(string) + + def indent(self) -> None: + """Increases the indentation.""" + self.current_indent += self.indent_increment + + def dedent(self) -> None: + """Decreases the indentation.""" + self.current_indent -= self.indent_increment + + def write_usage( + self, prog: str, args: str = "", prefix: t.Optional[str] = None + ) -> None: + """Writes a usage line into the buffer. + + :param prog: the program name. + :param args: whitespace separated list of arguments. + :param prefix: The prefix for the first line. Defaults to + ``"Usage: "``. + """ + if prefix is None: + prefix = f"{_('Usage:')} " + + usage_prefix = f"{prefix:>{self.current_indent}}{prog} " + text_width = self.width - self.current_indent + + if text_width >= (term_len(usage_prefix) + 20): + # The arguments will fit to the right of the prefix. + indent = " " * term_len(usage_prefix) + self.write( + wrap_text( + args, + text_width, + initial_indent=usage_prefix, + subsequent_indent=indent, + ) + ) + else: + # The prefix is too long, put the arguments on the next line. + self.write(usage_prefix) + self.write("\n") + indent = " " * (max(self.current_indent, term_len(prefix)) + 4) + self.write( + wrap_text( + args, text_width, initial_indent=indent, subsequent_indent=indent + ) + ) + + self.write("\n") + + def write_heading(self, heading: str) -> None: + """Writes a heading into the buffer.""" + self.write(f"{'':>{self.current_indent}}{heading}:\n") + + def write_paragraph(self) -> None: + """Writes a paragraph into the buffer.""" + if self.buffer: + self.write("\n") + + def write_text(self, text: str) -> None: + """Writes re-indented text into the buffer. This rewraps and + preserves paragraphs. + """ + indent = " " * self.current_indent + self.write( + wrap_text( + text, + self.width, + initial_indent=indent, + subsequent_indent=indent, + preserve_paragraphs=True, + ) + ) + self.write("\n") + + def write_dl( + self, + rows: t.Sequence[t.Tuple[str, str]], + col_max: int = 30, + col_spacing: int = 2, + ) -> None: + """Writes a definition list into the buffer. This is how options + and commands are usually formatted. + + :param rows: a list of two item tuples for the terms and values. + :param col_max: the maximum width of the first column. + :param col_spacing: the number of spaces between the first and + second column. + """ + rows = list(rows) + widths = measure_table(rows) + if len(widths) != 2: + raise TypeError("Expected two columns for definition list") + + first_col = min(widths[0], col_max) + col_spacing + + for first, second in iter_rows(rows, len(widths)): + self.write(f"{'':>{self.current_indent}}{first}") + if not second: + self.write("\n") + continue + if term_len(first) <= first_col - col_spacing: + self.write(" " * (first_col - term_len(first))) + else: + self.write("\n") + self.write(" " * (first_col + self.current_indent)) + + text_width = max(self.width - first_col - 2, 10) + wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True) + lines = wrapped_text.splitlines() + + if lines: + self.write(f"{lines[0]}\n") + + for line in lines[1:]: + self.write(f"{'':>{first_col + self.current_indent}}{line}\n") + else: + self.write("\n") + + @contextmanager + def section(self, name: str) -> t.Iterator[None]: + """Helpful context manager that writes a paragraph, a heading, + and the indents. + + :param name: the section name that is written as heading. + """ + self.write_paragraph() + self.write_heading(name) + self.indent() + try: + yield + finally: + self.dedent() + + @contextmanager + def indentation(self) -> t.Iterator[None]: + """A context manager that increases the indentation.""" + self.indent() + try: + yield + finally: + self.dedent() + + def getvalue(self) -> str: + """Returns the buffer contents.""" + return "".join(self.buffer) + + +def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]: + """Given a list of option strings this joins them in the most appropriate + way and returns them in the form ``(formatted_string, + any_prefix_is_slash)`` where the second item in the tuple is a flag that + indicates if any of the option prefixes was a slash. + """ + rv = [] + any_prefix_is_slash = False + + for opt in options: + prefix = split_opt(opt)[0] + + if prefix == "/": + any_prefix_is_slash = True + + rv.append((len(prefix), opt)) + + rv.sort(key=lambda x: x[0]) + return ", ".join(x[1] for x in rv), any_prefix_is_slash diff --git a/dist/ba_data/python-site-packages/click/globals.py b/dist/ba_data/python-site-packages/click/globals.py new file mode 100644 index 0000000..480058f --- /dev/null +++ b/dist/ba_data/python-site-packages/click/globals.py @@ -0,0 +1,68 @@ +import typing as t +from threading import local + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + +_local = local() + + +@t.overload +def get_current_context(silent: "te.Literal[False]" = False) -> "Context": + ... + + +@t.overload +def get_current_context(silent: bool = ...) -> t.Optional["Context"]: + ... + + +def get_current_context(silent: bool = False) -> t.Optional["Context"]: + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing its behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: if set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return t.cast("Context", _local.stack[-1]) + except (AttributeError, IndexError) as e: + if not silent: + raise RuntimeError("There is no active click context.") from e + + return None + + +def push_context(ctx: "Context") -> None: + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault("stack", []).append(ctx) + + +def pop_context() -> None: + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: + """Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + + ctx = get_current_context(silent=True) + + if ctx is not None: + return ctx.color + + return None diff --git a/dist/ba_data/python-site-packages/click/parser.py b/dist/ba_data/python-site-packages/click/parser.py new file mode 100644 index 0000000..2d5a2ed --- /dev/null +++ b/dist/ba_data/python-site-packages/click/parser.py @@ -0,0 +1,529 @@ +""" +This module started out as largely a copy paste from the stdlib's +optparse module with the features removed that we do not need from +optparse because we implement them in Click on a higher level (for +instance type handling, help formatting and a lot more). + +The plan is to remove more and more from here over time. + +The reason this is a different module and not optparse from the stdlib +is that there are differences in 2.x and 3.x about the error messages +generated and optparse in the stdlib uses gettext for no good reason +and might cause us issues. + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright 2001-2006 Gregory P. Ward. All rights reserved. +Copyright 2002-2006 Python Software Foundation. All rights reserved. +""" +# This code uses parts of optparse written by Gregory P. Ward and +# maintained by the Python Software Foundation. +# Copyright 2001-2006 Gregory P. Ward +# Copyright 2002-2006 Python Software Foundation +import typing as t +from collections import deque +from gettext import gettext as _ +from gettext import ngettext + +from .exceptions import BadArgumentUsage +from .exceptions import BadOptionUsage +from .exceptions import NoSuchOption +from .exceptions import UsageError + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Argument as CoreArgument + from .core import Context + from .core import Option as CoreOption + from .core import Parameter as CoreParameter + +V = t.TypeVar("V") + +# Sentinel value that indicates an option was passed as a flag without a +# value but is not a flag option. Option.consume_value uses this to +# prompt or use the flag_value. +_flag_needs_value = object() + + +def _unpack_args( + args: t.Sequence[str], nargs_spec: t.Sequence[int] +) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]: + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = [] + spos: t.Optional[int] = None + + def _fetch(c: "te.Deque[V]") -> t.Optional[V]: + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + + if nargs is None: + continue + + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError("Cannot have two nargs < 0") + + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1 :] = reversed(rv[spos + 1 :]) + + return tuple(rv), list(args) + + +def split_opt(opt: str) -> t.Tuple[str, str]: + first = opt[:1] + if first.isalnum(): + return "", opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str: + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return f"{prefix}{ctx.token_normalize_func(opt)}" + + +def split_arg_string(string: str) -> t.List[str]: + """Split an argument string as with :func:`shlex.split`, but don't + fail if the string is incomplete. Ignores a missing closing quote or + incomplete escape sequence and uses the partial token as-is. + + .. code-block:: python + + split_arg_string("example 'my file") + ["example", "my file"] + + split_arg_string("example my\\") + ["example", "my"] + + :param string: String to split. + """ + import shlex + + lex = shlex.shlex(string, posix=True) + lex.whitespace_split = True + lex.commenters = "" + out = [] + + try: + for token in lex: + out.append(token) + except ValueError: + # Raised when end-of-string is reached in an invalid state. Use + # the partial token as-is. The quote or escape character is in + # lex.state, not lex.token. + out.append(lex.token) + + return out + + +class Option: + def __init__( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ): + self._short_opts = [] + self._long_opts = [] + self.prefixes = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError(f"Invalid start character for option ({opt})") + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = "store" + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self) -> bool: + return self.action in ("store", "append") + + def process(self, value: str, state: "ParsingState") -> None: + if self.action == "store": + state.opts[self.dest] = value # type: ignore + elif self.action == "store_const": + state.opts[self.dest] = self.const # type: ignore + elif self.action == "append": + state.opts.setdefault(self.dest, []).append(value) # type: ignore + elif self.action == "append_const": + state.opts.setdefault(self.dest, []).append(self.const) # type: ignore + elif self.action == "count": + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore + else: + raise ValueError(f"unknown action '{self.action}'") + state.order.append(self.obj) + + +class Argument: + def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process( + self, + value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]], + state: "ParsingState", + ) -> None: + if self.nargs > 1: + assert value is not None + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage( + _("Argument {name!r} takes {nargs} values.").format( + name=self.dest, nargs=self.nargs + ) + ) + + if self.nargs == -1 and self.obj.envvar is not None and value == (): + # Replace empty tuple with None so that a value from the + # environment may be tried. + value = None + + state.opts[self.dest] = value # type: ignore + state.order.append(self.obj) + + +class ParsingState: + def __init__(self, rargs: t.List[str]) -> None: + self.opts: t.Dict[str, t.Any] = {} + self.largs: t.List[str] = [] + self.rargs = rargs + self.order: t.List["CoreParameter"] = [] + + +class OptionParser: + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx: t.Optional["Context"] = None) -> None: + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options = False + + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + + self._short_opt: t.Dict[str, Option] = {} + self._long_opt: t.Dict[str, Option] = {} + self._opt_prefixes = {"-", "--"} + self._args: t.List[Argument] = [] + + def add_option( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ) -> None: + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``append_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument( + self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 + ) -> None: + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + self._args.append(Argument(obj, dest=dest, nargs=nargs)) + + def parse_args( + self, args: t.List[str] + ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state: ParsingState) -> None: + pargs, args = _unpack_args( + state.largs + state.rargs, [x.nargs for x in self._args] + ) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state: ParsingState) -> None: + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == "--": + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt( + self, opt: str, explicit_value: t.Optional[str], state: ParsingState + ) -> None: + if opt not in self._long_opt: + from difflib import get_close_matches + + possibilities = get_close_matches(opt, self._long_opt) + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + value = self._get_value_from_state(opt, option, state) + + elif explicit_value is not None: + raise BadOptionUsage( + opt, _("Option {name!r} does not take a value.").format(name=opt) + ) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg: str, state: ParsingState) -> None: + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(f"{prefix}{ch}", self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + value = self._get_value_from_state(opt, option, state) + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we re-combinate the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(f"{prefix}{''.join(unknown_options)}") + + def _get_value_from_state( + self, option_name: str, option: Option, state: ParsingState + ) -> t.Any: + nargs = option.nargs + + if len(state.rargs) < nargs: + if option.obj._flag_needs_value: + # Option allows omitting the value. + value = _flag_needs_value + else: + raise BadOptionUsage( + option_name, + ngettext( + "Option {name!r} requires an argument.", + "Option {name!r} requires {nargs} arguments.", + nargs, + ).format(name=option_name, nargs=nargs), + ) + elif nargs == 1: + next_rarg = state.rargs[0] + + if ( + option.obj._flag_needs_value + and isinstance(next_rarg, str) + and next_rarg[:1] in self._opt_prefixes + and len(next_rarg) > 1 + ): + # The next arg looks like the start of an option, don't + # use it as the value if omitting the value is allowed. + value = _flag_needs_value + else: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + return value + + def _process_opts(self, arg: str, state: ParsingState) -> None: + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if "=" in arg: + long_opt, explicit_value = arg.split("=", 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + self._match_short_opt(arg, state) + return + + if not self.ignore_unknown_options: + raise + + state.largs.append(arg) diff --git a/dist/ba_data/python-site-packages/click/py.typed b/dist/ba_data/python-site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/dist/ba_data/python-site-packages/click/shell_completion.py b/dist/ba_data/python-site-packages/click/shell_completion.py new file mode 100644 index 0000000..1e9df6f --- /dev/null +++ b/dist/ba_data/python-site-packages/click/shell_completion.py @@ -0,0 +1,581 @@ +import os +import re +import typing as t +from gettext import gettext as _ + +from .core import Argument +from .core import BaseCommand +from .core import Context +from .core import MultiCommand +from .core import Option +from .core import Parameter +from .core import ParameterSource +from .parser import split_arg_string +from .utils import echo + + +def shell_complete( + cli: BaseCommand, + ctx_args: t.Dict[str, t.Any], + prog_name: str, + complete_var: str, + instruction: str, +) -> int: + """Perform shell completion for the given CLI program. + + :param cli: Command being called. + :param ctx_args: Extra arguments to pass to + ``cli.make_context``. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + :param instruction: Value of ``complete_var`` with the completion + instruction and shell, in the form ``instruction_shell``. + :return: Status code to exit with. + """ + shell, _, instruction = instruction.partition("_") + comp_cls = get_completion_class(shell) + + if comp_cls is None: + return 1 + + comp = comp_cls(cli, ctx_args, prog_name, complete_var) + + if instruction == "source": + echo(comp.source()) + return 0 + + if instruction == "complete": + echo(comp.complete()) + return 0 + + return 1 + + +class CompletionItem: + """Represents a completion value and metadata about the value. The + default metadata is ``type`` to indicate special shell handling, + and ``help`` if a shell supports showing a help string next to the + value. + + Arbitrary parameters can be passed when creating the object, and + accessed using ``item.attr``. If an attribute wasn't passed, + accessing it returns ``None``. + + :param value: The completion suggestion. + :param type: Tells the shell script to provide special completion + support for the type. Click uses ``"dir"`` and ``"file"``. + :param help: String shown next to the value if supported. + :param kwargs: Arbitrary metadata. The built-in implementations + don't use this, but custom type completions paired with custom + shell support could use it. + """ + + __slots__ = ("value", "type", "help", "_info") + + def __init__( + self, + value: t.Any, + type: str = "plain", + help: t.Optional[str] = None, + **kwargs: t.Any, + ) -> None: + self.value = value + self.type = type + self.help = help + self._info = kwargs + + def __getattr__(self, name: str) -> t.Any: + return self._info.get(name) + + +# Only Bash >= 4.4 has the nosort option. +_SOURCE_BASH = """\ +%(complete_func)s() { + local IFS=$'\\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ +%(complete_var)s=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMPREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMPREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +%(complete_func)s_setup() { + complete -o nosort -F %(complete_func)s %(prog_name)s +} + +%(complete_func)s_setup; +""" + +_SOURCE_ZSH = """\ +#compdef %(prog_name)s + +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[%(prog_name)s] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ +%(complete_var)s=zsh_complete %(prog_name)s)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +compdef %(complete_func)s %(prog_name)s; +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response; + + for value in (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + set response $response $value; + end; + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command %(prog_name)s --arguments \ +"(%(complete_func)s)"; +""" + + +class ShellComplete: + """Base class for providing shell completion support. A subclass for + a given shell will override attributes and methods to implement the + completion instructions (``source`` and ``complete``). + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + + .. versionadded:: 8.0 + """ + + name: t.ClassVar[str] + """Name to register the shell as with :func:`add_completion_class`. + This is used in completion instructions (``{name}_source`` and + ``{name}_complete``). + """ + + source_template: t.ClassVar[str] + """Completion script template formatted by :meth:`source`. This must + be provided by subclasses. + """ + + def __init__( + self, + cli: BaseCommand, + ctx_args: t.Dict[str, t.Any], + prog_name: str, + complete_var: str, + ) -> None: + self.cli = cli + self.ctx_args = ctx_args + self.prog_name = prog_name + self.complete_var = complete_var + + @property + def func_name(self) -> str: + """The name of the shell function defined by the completion + script. + """ + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), re.ASCII) + return f"_{safe_name}_completion" + + def source_vars(self) -> t.Dict[str, t.Any]: + """Vars for formatting :attr:`source_template`. + + By default this provides ``complete_func``, ``complete_var``, + and ``prog_name``. + """ + return { + "complete_func": self.func_name, + "complete_var": self.complete_var, + "prog_name": self.prog_name, + } + + def source(self) -> str: + """Produce the shell script that defines the completion + function. By default this ``%``-style formats + :attr:`source_template` with the dict returned by + :meth:`source_vars`. + """ + return self.source_template % self.source_vars() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + """Use the env vars defined by the shell script to return a + tuple of ``args, incomplete``. This must be implemented by + subclasses. + """ + raise NotImplementedError + + def get_completions( + self, args: t.List[str], incomplete: str + ) -> t.List[CompletionItem]: + """Determine the context and last complete command or parameter + from the complete args. Call that object's ``shell_complete`` + method to get the completions for the incomplete value. + + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) + obj, incomplete = _resolve_incomplete(ctx, args, incomplete) + return obj.shell_complete(ctx, incomplete) + + def format_completion(self, item: CompletionItem) -> str: + """Format a completion item into the form recognized by the + shell script. This must be implemented by subclasses. + + :param item: Completion item to format. + """ + raise NotImplementedError + + def complete(self) -> str: + """Produce the completion data to send back to the shell. + + By default this calls :meth:`get_completion_args`, gets the + completions, then calls :meth:`format_completion` for each + completion. + """ + args, incomplete = self.get_completion_args() + completions = self.get_completions(args, incomplete) + out = [self.format_completion(item) for item in completions] + return "\n".join(out) + + +class BashComplete(ShellComplete): + """Shell completion for Bash.""" + + name = "bash" + source_template = _SOURCE_BASH + + def _check_version(self) -> None: + import subprocess + + output = subprocess.run( + ["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE + ) + match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + raise RuntimeError( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ) + ) + else: + raise RuntimeError( + _("Couldn't detect Bash version, shell completion is not supported.") + ) + + def source(self) -> str: + self._check_version() + return super().source() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type},{item.value}" + + +class ZshComplete(ShellComplete): + """Shell completion for Zsh.""" + + name = "zsh" + source_template = _SOURCE_ZSH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" + + +class FishComplete(ShellComplete): + """Shell completion for Fish.""" + + name = "fish" + source_template = _SOURCE_FISH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + incomplete = os.environ["COMP_CWORD"] + args = cwords[1:] + + # Fish stores the partial word in both COMP_WORDS and + # COMP_CWORD, remove it from complete args. + if incomplete and args and args[-1] == incomplete: + args.pop() + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + if item.help: + return f"{item.type},{item.value}\t{item.help}" + + return f"{item.type},{item.value}" + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: t.Type[ShellComplete], name: t.Optional[str] = None +) -> None: + """Register a :class:`ShellComplete` subclass under the given name. + The name will be provided by the completion instruction environment + variable during completion. + + :param cls: The completion class that will handle completion for the + shell. + :param name: Name to register the class under. Defaults to the + class's ``name`` attribute. + """ + if name is None: + name = cls.name + + _available_shells[name] = cls + + +def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: + """Look up a registered :class:`ShellComplete` subclass by the name + provided by the completion instruction environment variable. If the + name isn't registered, returns ``None``. + + :param shell: Name the class is registered under. + """ + return _available_shells.get(shell) + + +def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: + """Determine if the given parameter is an argument that can still + accept values. + + :param ctx: Invocation context for the command represented by the + parsed complete args. + :param param: Argument object being checked. + """ + if not isinstance(param, Argument): + return False + + assert param.name is not None + value = ctx.params[param.name] + return ( + param.nargs == -1 + or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE + or ( + param.nargs > 1 + and isinstance(value, (tuple, list)) + and len(value) < param.nargs + ) + ) + + +def _start_of_option(value: str) -> bool: + """Check if the value looks like the start of an option.""" + if not value: + return False + + c = value[0] + # Allow "/" since that starts a path. + return not c.isalnum() and c != "/" + + +def _is_incomplete_option(args: t.List[str], param: Parameter) -> bool: + """Determine if the given parameter is an option that needs a value. + + :param args: List of complete args before the incomplete value. + :param param: Option object being checked. + """ + if not isinstance(param, Option): + return False + + if param.is_flag: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, ctx_args: t.Dict[str, t.Any], prog_name: str, args: t.List[str] +) -> Context: + """Produce the context hierarchy starting with the command and + traversing the complete arguments. This only follows the commands, + it doesn't trigger input prompts or callbacks. + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param args: List of complete args before the incomplete value. + """ + ctx_args["resilient_parsing"] = True + ctx = cli.make_context(prog_name, args.copy(), **ctx_args) + args = ctx.protected_args + ctx.args + + while args: + command = ctx.command + + if isinstance(command, MultiCommand): + if not command.chain: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + while args: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + sub_ctx = cmd.make_context( + name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True, + ) + args = sub_ctx.args + + ctx = sub_ctx + args = [*sub_ctx.protected_args, *sub_ctx.args] + else: + break + + return ctx + + +def _resolve_incomplete( + ctx: Context, args: t.List[str], incomplete: str +) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: + """Find the Click object that will handle the completion of the + incomplete value. Return the object and the incomplete value. + + :param ctx: Invocation context for the command represented by + the parsed complete args. + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + # Different shells treat an "=" between a long option name and + # value differently. Might keep the value joined, return the "=" + # as a separate item, or return the split name and value. Always + # split and discard the "=" to make completion easier. + if incomplete == "=": + incomplete = "" + elif "=" in incomplete and _start_of_option(incomplete): + name, _, incomplete = incomplete.partition("=") + args.append(name) + + # The "--" marker tells Click to stop treating values as options + # even if they start with the option character. If it hasn't been + # given and the incomplete arg looks like an option, the current + # command will provide option name completions. + if "--" not in args and _start_of_option(incomplete): + return ctx.command, incomplete + + params = ctx.command.get_params(ctx) + + # If the last complete arg is an option name with an incomplete + # value, the option will provide value completions. + for param in params: + if _is_incomplete_option(args, param): + return param, incomplete + + # It's not an option name or value. The first argument without a + # parsed value will provide value completions. + for param in params: + if _is_incomplete_argument(ctx, param): + return param, incomplete + + # There were no unparsed arguments, the command may be a group that + # will provide command name completions. + return ctx.command, incomplete diff --git a/dist/ba_data/python-site-packages/click/termui.py b/dist/ba_data/python-site-packages/click/termui.py new file mode 100644 index 0000000..07b5257 --- /dev/null +++ b/dist/ba_data/python-site-packages/click/termui.py @@ -0,0 +1,806 @@ +import inspect +import io +import itertools +import os +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from ._compat import WIN +from .exceptions import Abort +from .exceptions import UsageError +from .globals import resolve_color_default +from .types import Choice +from .types import convert_type +from .types import ParamType +from .utils import echo +from .utils import LazyFile + +if t.TYPE_CHECKING: + from ._termui_impl import ProgressBar + +V = t.TypeVar("V") + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func: t.Callable[[str], str] = input + +_ansi_colors = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "reset": 39, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} +_ansi_reset_all = "\033[0m" + + +def hidden_prompt_func(prompt: str) -> str: + import getpass + + return getpass.getpass(prompt) + + +def _build_prompt( + text: str, + suffix: str, + show_default: bool = False, + default: t.Optional[t.Any] = None, + show_choices: bool = True, + type: t.Optional[ParamType] = None, +) -> str: + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += f" ({', '.join(map(str, type.choices))})" + if default is not None and show_default: + prompt = f"{prompt} [{_format_default(default)}]" + return f"{prompt}{suffix}" + + +def _format_default(default: t.Any) -> t.Any: + if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): + return default.name # type: ignore + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[t.Union[ParamType, t.Any]] = None, + value_proc: t.Optional[t.Callable[[str], t.Any]] = None, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, + show_choices: bool = True, +) -> t.Any: + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending an interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: Prompt a second time to confirm the + value. Can be set to a string instead of ``True`` to customize + the message. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + + .. versionadded:: 8.0 + ``confirmation_prompt`` can be a custom string. + + .. versionadded:: 7.0 + Added the ``show_choices`` parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + """ + + def prompt_func(text: str) -> str: + f = hidden_prompt_func if hide_input else visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + return f(" ") + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() from None + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt( + text, prompt_suffix, show_default, default, show_choices, type + ) + + if confirmation_prompt: + if confirmation_prompt is True: + confirmation_prompt = _("Repeat for confirmation") + + confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) + + while True: + while True: + value = prompt_func(prompt) + if value: + break + elif default is not None: + value = default + break + try: + result = value_proc(value) + except UsageError as e: + if hide_input: + echo(_("Error: The value you entered was invalid."), err=err) + else: + echo(_("Error: {e.message}").format(e=e), err=err) # noqa: B306 + continue + if not confirmation_prompt: + return result + while True: + value2 = prompt_func(confirmation_prompt) + if value2: + break + if value == value2: + return result + echo(_("Error: The two entered values do not match."), err=err) + + +def confirm( + text: str, + default: t.Optional[bool] = False, + abort: bool = False, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, +) -> bool: + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the question to ask. + :param default: The default value to use when no input is given. If + ``None``, repeat until input is given. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + + .. versionchanged:: 8.0 + Repeat until input is given if ``default`` is ``None``. + + .. versionadded:: 4.0 + Added the ``err`` parameter. + """ + prompt = _build_prompt( + text, + prompt_suffix, + show_default, + "y/n" if default is None else ("Y/n" if default else "y/N"), + ) + + while True: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + value = visible_prompt_func(" ").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() from None + if value in ("y", "yes"): + rv = True + elif value in ("n", "no"): + rv = False + elif default is not None and value == "": + rv = default + else: + echo(_("Error: invalid input"), err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def get_terminal_size() -> os.terminal_size: + """Returns the current size of the terminal as tuple in the form + ``(width, height)`` in columns and rows. + + .. deprecated:: 8.0 + Will be removed in Click 8.1. Use + :func:`shutil.get_terminal_size` instead. + """ + import shutil + import warnings + + warnings.warn( + "'click.get_terminal_size()' is deprecated and will be removed" + " in Click 8.1. Use 'shutil.get_terminal_size()' instead.", + DeprecationWarning, + stacklevel=2, + ) + return shutil.get_terminal_size() + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + if WIN: + os.system("cls") + else: + sys.stdout.write("\033[2J\033[1;1H") + + +def _interpret_color( + color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 +) -> str: + if isinstance(color, int): + return f"{38 + offset};5;{color:d}" + + if isinstance(color, (tuple, list)): + r, g, b = color + return f"{38 + offset};2;{r:d};{g:d};{b:d}" + + return str(_ansi_colors[color] + offset) + + +def style( + text: t.Any, + fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bold: t.Optional[bool] = None, + dim: t.Optional[bool] = None, + underline: t.Optional[bool] = None, + overline: t.Optional[bool] = None, + italic: t.Optional[bool] = None, + blink: t.Optional[bool] = None, + reverse: t.Optional[bool] = None, + strikethrough: t.Optional[bool] = None, + reset: bool = True, +) -> str: + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + If the terminal supports it, color may also be specified as: + + - An integer in the interval [0, 255]. The terminal must support + 8-bit/256-color mode. + - An RGB tuple of three integers in [0, 255]. The terminal must + support 24-bit/true-color mode. + + See https://en.wikipedia.org/wiki/ANSI_color and + https://gist.github.com/XVilka/8346728 for more information. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param overline: if provided this will enable or disable overline. + :param italic: if provided this will enable or disable italic. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param strikethrough: if provided this will enable or disable + striking through text. + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. + + .. versionchanged:: 8.0 + Added support for 256 and RGB color codes. + + .. versionchanged:: 8.0 + Added the ``strikethrough``, ``italic``, and ``overline`` + parameters. + + .. versionchanged:: 7.0 + Added support for bright colors. + + .. versionadded:: 2.0 + """ + if not isinstance(text, str): + text = str(text) + + bits = [] + + if fg: + try: + bits.append(f"\033[{_interpret_color(fg)}m") + except KeyError: + raise TypeError(f"Unknown color {fg!r}") from None + + if bg: + try: + bits.append(f"\033[{_interpret_color(bg, 10)}m") + except KeyError: + raise TypeError(f"Unknown color {bg!r}") from None + + if bold is not None: + bits.append(f"\033[{1 if bold else 22}m") + if dim is not None: + bits.append(f"\033[{2 if dim else 22}m") + if underline is not None: + bits.append(f"\033[{4 if underline else 24}m") + if overline is not None: + bits.append(f"\033[{53 if overline else 55}m") + if italic is not None: + bits.append(f"\033[{3 if italic else 23}m") + if blink is not None: + bits.append(f"\033[{5 if blink else 25}m") + if reverse is not None: + bits.append(f"\033[{7 if reverse else 27}m") + if strikethrough is not None: + bits.append(f"\033[{9 if strikethrough else 29}m") + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return "".join(bits) + + +def unstyle(text: str) -> str: + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.AnyStr]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, + **styles: t.Any, +) -> None: + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + Non-string types will be converted to :class:`str`. However, + :class:`bytes` are passed directly to :meth:`echo` without applying + style. If you want to style bytes that represent text, call + :meth:`bytes.decode` first. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. Bytes are + passed through without style applied. + + .. versionadded:: 2.0 + """ + if message is not None and not isinstance(message, (bytes, bytearray)): + message = style(message, **styles) + + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit( + text: t.Optional[t.AnyStr] = None, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + filename: t.Optional[str] = None, +) -> t.Optional[t.AnyStr]: + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + + ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) + + if filename is None: + return ed.edit(text) + + ed.edit_file(filename) + return None + + +def launch(url: str, wait: bool = False, locate: bool = False) -> int: + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: Wait for the program to exit before returning. This + only works if the launched program blocks. In particular, + ``xdg-open`` on Linux does not block. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar: t.Optional[t.Callable[[bool], str]] = None + + +def getchar(echo: bool = False) -> str: + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + global _getchar + + if _getchar is None: + from ._termui_impl import getchar as f + + _getchar = f + + return _getchar(echo) + + +def raw_terminal() -> t.ContextManager[int]: + from ._termui_impl import raw_terminal as f + + return f() + + +def pause(info: t.Optional[str] = None, err: bool = False) -> None: + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: The message to print before pausing. Defaults to + ``"Press any key to continue..."``. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + + if info is None: + info = _("Press any key to continue...") + + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/dist/ba_data/python-site-packages/click/testing.py b/dist/ba_data/python-site-packages/click/testing.py new file mode 100644 index 0000000..e395c2e --- /dev/null +++ b/dist/ba_data/python-site-packages/click/testing.py @@ -0,0 +1,479 @@ +import contextlib +import io +import os +import shlex +import shutil +import sys +import tempfile +import typing as t +from types import TracebackType + +from . import formatting +from . import termui +from . import utils +from ._compat import _find_binary_reader + +if t.TYPE_CHECKING: + from .core import BaseCommand + + +class EchoingStdin: + def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: + self._input = input + self._output = output + self._paused = False + + def __getattr__(self, x: str) -> t.Any: + return getattr(self._input, x) + + def _echo(self, rv: bytes) -> bytes: + if not self._paused: + self._output.write(rv) + + return rv + + def read(self, n: int = -1) -> bytes: + return self._echo(self._input.read(n)) + + def read1(self, n: int = -1) -> bytes: + return self._echo(self._input.read1(n)) # type: ignore + + def readline(self, n: int = -1) -> bytes: + return self._echo(self._input.readline(n)) + + def readlines(self) -> t.List[bytes]: + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self) -> t.Iterator[bytes]: + return iter(self._echo(x) for x in self._input) + + def __repr__(self) -> str: + return repr(self._input) + + +@contextlib.contextmanager +def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]: + if stream is None: + yield + else: + stream._paused = True + yield + stream._paused = False + + +class _NamedTextIOWrapper(io.TextIOWrapper): + def __init__( + self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any + ) -> None: + super().__init__(buffer, **kwargs) + self._name = name + self._mode = mode + + @property + def name(self) -> str: + return self._name + + @property + def mode(self) -> str: + return self._mode + + +def make_input_stream( + input: t.Optional[t.Union[str, bytes, t.IO]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO, input)) + + if rv is not None: + return rv + + raise TypeError("Could not find binary reader for input stream.") + + if input is None: + input = b"" + elif isinstance(input, str): + input = input.encode(charset) + + return io.BytesIO(t.cast(bytes, input)) + + +class Result: + """Holds the captured result of an invoked CLI script.""" + + def __init__( + self, + runner: "CliRunner", + stdout_bytes: bytes, + stderr_bytes: t.Optional[bytes], + return_value: t.Any, + exit_code: int, + exception: t.Optional[BaseException], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = None, + ): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or None if not available + self.stderr_bytes = stderr_bytes + #: The value returned from the invoked command. + #: + #: .. versionadded:: 8.0 + self.return_value = return_value + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self) -> str: + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self) -> str: + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + @property + def stderr(self) -> str: + """The standard error as unicode string.""" + if self.stderr_bytes is None: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + def __repr__(self) -> str: + exc_str = repr(self.exception) if self.exception else "okay" + return f"<{type(self).__name__} {exc_str}>" + + +class CliRunner: + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__( + self, + charset: str = "utf-8", + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + echo_stdin: bool = False, + mix_stderr: bool = True, + ) -> None: + self.charset = charset + self.env = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + def get_default_prog_name(self, cli: "BaseCommand") -> str: + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or "root" + + def make_env( + self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None + ) -> t.Mapping[str, t.Optional[str]]: + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation( + self, + input: t.Optional[t.Union[str, bytes, t.IO]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + color: bool = False, + ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + ``stderr`` is opened with ``errors="backslashreplace"`` + instead of the default ``"strict"``. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + """ + bytes_input = make_input_stream(input, self.charset) + echo_input = None + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = formatting.FORCED_WIDTH + formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + bytes_output = io.BytesIO() + + if self.echo_stdin: + bytes_input = echo_input = t.cast( + t.BinaryIO, EchoingStdin(bytes_input, bytes_output) + ) + + sys.stdin = text_input = _NamedTextIOWrapper( + bytes_input, encoding=self.charset, name="", mode="r" + ) + + if self.echo_stdin: + # Force unbuffered reads, otherwise TextIOWrapper reads a + # large chunk which is echoed early. + text_input._CHUNK_SIZE = 1 # type: ignore + + sys.stdout = _NamedTextIOWrapper( + bytes_output, encoding=self.charset, name="", mode="w" + ) + + bytes_error = None + if self.mix_stderr: + sys.stderr = sys.stdout + else: + bytes_error = io.BytesIO() + sys.stderr = _NamedTextIOWrapper( + bytes_error, + encoding=self.charset, + name="", + mode="w", + errors="backslashreplace", + ) + + @_pause_echo(echo_input) # type: ignore + def visible_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(prompt or "") + val = text_input.readline().rstrip("\r\n") + sys.stdout.write(f"{val}\n") + sys.stdout.flush() + return val + + @_pause_echo(echo_input) # type: ignore + def hidden_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(f"{prompt or ''}\n") + sys.stdout.flush() + return text_input.readline().rstrip("\r\n") + + @_pause_echo(echo_input) # type: ignore + def _getchar(echo: bool) -> str: + char = sys.stdin.read(1) + + if echo: + sys.stdout.write(char) + + sys.stdout.flush() + return char + + default_color = color + + def should_strip_ansi( + stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None + ) -> bool: + if color is None: + return not default_color + return not color + + old_visible_prompt_func = termui.visible_prompt_func + old_hidden_prompt_func = termui.hidden_prompt_func + old__getchar_func = termui._getchar + old_should_strip_ansi = utils.should_strip_ansi # type: ignore + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + + old_env = {} + try: + for key, value in env.items(): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, bytes_error) + finally: + for key, value in old_env.items(): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + termui.visible_prompt_func = old_visible_prompt_func + termui.hidden_prompt_func = old_hidden_prompt_func + termui._getchar = old__getchar_func + utils.should_strip_ansi = old_should_strip_ansi # type: ignore + formatting.FORCED_WIDTH = old_forced_width + + def invoke( + self, + cli: "BaseCommand", + args: t.Optional[t.Union[str, t.Sequence[str]]] = None, + input: t.Optional[t.Union[str, bytes, t.IO]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + catch_exceptions: bool = True, + color: bool = False, + **extra: t.Any, + ) -> Result: + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + :param cli: the command to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + The result object has the ``return_value`` attribute with + the value returned from the invoked command. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionchanged:: 3.0 + Added the ``catch_exceptions`` parameter. + + .. versionchanged:: 3.0 + The result object has the ``exc_info`` attribute with the + traceback if available. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as outstreams: + return_value = None + exception: t.Optional[BaseException] = None + exit_code = 0 + + if isinstance(args, str): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + return_value = cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code) + + if e_code is None: + e_code = 0 + + if e_code != 0: + exception = e + + if not isinstance(e_code, int): + sys.stdout.write(str(e_code)) + sys.stdout.write("\n") + e_code = 1 + + exit_code = e_code + + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = 1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + stdout = outstreams[0].getvalue() + if self.mix_stderr: + stderr = None + else: + stderr = outstreams[1].getvalue() # type: ignore + + return Result( + runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + return_value=return_value, + exit_code=exit_code, + exception=exception, + exc_info=exc_info, # type: ignore + ) + + @contextlib.contextmanager + def isolated_filesystem( + self, temp_dir: t.Optional[t.Union[str, os.PathLike]] = None + ) -> t.Iterator[str]: + """A context manager that creates a temporary directory and + changes the current working directory to it. This isolates tests + that affect the contents of the CWD to prevent them from + interfering with each other. + + :param temp_dir: Create the temporary directory under this + directory. If given, the created directory is not removed + when exiting. + + .. versionchanged:: 8.0 + Added the ``temp_dir`` parameter. + """ + cwd = os.getcwd() + dt = tempfile.mkdtemp(dir=temp_dir) # type: ignore[type-var] + os.chdir(dt) + + try: + yield t.cast(str, dt) + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: # noqa: B014 + pass diff --git a/dist/ba_data/python-site-packages/click/types.py b/dist/ba_data/python-site-packages/click/types.py new file mode 100644 index 0000000..550c6ff --- /dev/null +++ b/dist/ba_data/python-site-packages/click/types.py @@ -0,0 +1,1049 @@ +import os +import stat +import typing as t +from datetime import datetime +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import _get_argv_encoding +from ._compat import get_filesystem_encoding +from ._compat import open_stream +from .exceptions import BadParameter +from .utils import LazyFile +from .utils import safecall + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + from .core import Parameter + from .shell_completion import CompletionItem + + +class ParamType: + """Represents the type of a parameter. Validates and converts values + from the command line or Python into the correct type. + + To implement a custom type, subclass and implement at least the + following: + + - The :attr:`name` class attribute must be set. + - Calling an instance of the type with ``None`` must return + ``None``. This is already implemented by default. + - :meth:`convert` must convert string values to the correct type. + - :meth:`convert` must accept values that are already the correct + type. + - It must be able to convert a value if the ``ctx`` and ``param`` + arguments are ``None``. This can occur when converting prompt + input. + """ + + is_composite: t.ClassVar[bool] = False + arity: t.ClassVar[int] = 1 + + #: the descriptive name of this type + name: str + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter: t.ClassVar[t.Optional[str]] = None + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + # The class name without the "ParamType" suffix. + param_type = type(self).__name__.partition("ParamType")[0] + param_type = param_type.partition("ParameterType")[0] + return {"param_type": param_type, "name": self.name} + + def __call__( + self, + value: t.Any, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> t.Any: + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param: "Parameter") -> t.Optional[str]: + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param: "Parameter") -> t.Optional[str]: + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + """Convert the value to the correct type. This is not called if + the value is ``None`` (the missing value). + + This must accept string values from the command line, as well as + values that are already the correct type. It may also convert + other compatible types. + + The ``param`` and ``ctx`` arguments may be ``None`` in certain + situations, such as when converting prompt input. + + If the value cannot be converted, call :meth:`fail` with a + descriptive message. + + :param value: The value to convert. + :param param: The parameter that is using this type to convert + its value. May be ``None``. + :param ctx: The current context that arrived at this value. May + be ``None``. + """ + return value + + def split_envvar_value(self, rv: str) -> t.Sequence[str]: + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or "").split(self.envvar_list_splitter) + + def fail( + self, + message: str, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> "t.NoReturn": + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a list of + :class:`~click.shell_completion.CompletionItem` objects for the + incomplete value. Most types do not provide completions, but + some do, and this allows custom types to provide custom + completions as well. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + return [] + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self) -> int: # type: ignore + raise NotImplementedError() + + +class FuncParamType(ParamType): + def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: + self.name = func.__name__ + self.func = func + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["func"] = self.func + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self.func(value) + except ValueError: + try: + value = str(value) + except UnicodeError: + value = value.decode("utf-8", "replace") + + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + return value + + def __repr__(self) -> str: + return "UNPROCESSED" + + +class StringParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = get_filesystem_encoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode("utf-8", "replace") + else: + value = value.decode("utf-8", "replace") + return value + return str(value) + + def __repr__(self) -> str: + return "STRING" + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + The resulting value will always be one of the originally passed choices + regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` + being specified. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = "choice" + + def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: + self.choices = choices + self.case_sensitive = case_sensitive + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["choices"] = self.choices + info_dict["case_sensitive"] = self.case_sensitive + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + choices_str = "|".join(self.choices) + + # Use curly braces to indicate a required argument. + if param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + + # Use square braces to indicate an option or optional argument. + return f"[{choices_str}]" + + def get_missing_message(self, param: "Parameter") -> str: + return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = {choice: choice for choice in self.choices} + + if ctx is not None and ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = { + ctx.token_normalize_func(normed_choice): original + for normed_choice, original in normed_choices.items() + } + + if not self.case_sensitive: + normed_value = normed_value.casefold() + normed_choices = { + normed_choice.casefold(): original + for normed_choice, original in normed_choices.items() + } + + if normed_value in normed_choices: + return normed_choices[normed_value] + + choices_str = ", ".join(map(repr, self.choices)) + self.fail( + ngettext( + "{value!r} is not {choice}.", + "{value!r} is not one of {choices}.", + len(self.choices), + ).format(value=value, choice=choices_str, choices=choices_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return f"Choice({list(self.choices)})" + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Complete choices that start with the incomplete value. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + str_choices = map(str, self.choices) + + if self.case_sensitive: + matched = (c for c in str_choices if c.startswith(incomplete)) + else: + incomplete = incomplete.lower() + matched = (c for c in str_choices if c.lower().startswith(incomplete)) + + return [CompletionItem(c) for c in matched] + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + + name = "datetime" + + def __init__(self, formats: t.Optional[t.Sequence[str]] = None): + self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["formats"] = self.formats + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + return f"[{'|'.join(self.formats)}]" + + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, datetime): + return value + + for format in self.formats: + converted = self._try_to_convert_date(value, format) + + if converted is not None: + return converted + + formats_str = ", ".join(map(repr, self.formats)) + self.fail( + ngettext( + "{value!r} does not match the format {format}.", + "{value!r} does not match the formats {formats}.", + len(self.formats), + ).format(value=value, format=formats_str, formats=formats_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return "DateTime" + + +class _NumberParamTypeBase(ParamType): + _number_class: t.ClassVar[t.Type] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + + name = "filename" + envvar_list_splitter = os.path.pathsep + + def __init__( + self, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: t.Optional[bool] = None, + atomic: bool = False, + ) -> None: + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update(mode=self.mode, encoding=self.encoding) + return info_dict + + def resolve_lazy_flag(self, value: t.Any) -> bool: + if self.lazy is not None: + return self.lazy + if value == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + if hasattr(value, "read") or hasattr(value, "write"): + return value + + lazy = self.resolve_lazy_flag(value) + + if lazy: + f: t.IO = t.cast( + t.IO, + LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ), + ) + + if ctx is not None: + ctx.call_on_close(f.close_intelligently) # type: ignore + + return f + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: # noqa: B014 + self.fail(f"{os.fsdecode(value)!r}: {e.strerror}", param, ctx) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide file path completions. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + return [CompletionItem(incomplete, type="file")] + + +class Path(ParamType): + """The ``Path`` type is similar to the :class:`File` type, but + returns the filename instead of an open file. Various checks can be + enabled to validate the type of file and permissions. + + :param exists: The file or directory needs to exist for the value to + be valid. If this is not set to ``True``, and the file does not + exist, then all further checks are silently skipped. + :param file_okay: Allow a file as a value. + :param dir_okay: Allow a directory as a value. + :param writable: The file or directory must be writable. + :param readable: The file or directory must be readable. + :param resolve_path: Make the value absolute and resolve any + symlinks. A ``~`` is not expanded, as this is supposed to be + done by the shell only. + :param allow_dash: Allow a single dash as a value, which indicates + a standard stream (but does not open it). Use + :func:`~click.open_file` to handle opening this value. + :param path_type: Convert the incoming path value to this type. If + ``None``, keep Python's default, which is ``str``. Useful to + convert to :class:`pathlib.Path`. + + .. versionchanged:: 8.0 + Allow passing ``type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter = os.path.pathsep + + def __init__( + self, + exists: bool = False, + file_okay: bool = True, + dir_okay: bool = True, + writable: bool = False, + readable: bool = True, + resolve_path: bool = False, + allow_dash: bool = False, + path_type: t.Optional[t.Type] = None, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.writable = writable + self.readable = readable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name = _("file") + elif self.dir_okay and not self.file_okay: + self.name = _("directory") + else: + self.name = _("path") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + exists=self.exists, + file_okay=self.file_okay, + dir_okay=self.dir_okay, + writable=self.writable, + readable=self.readable, + allow_dash=self.allow_dash, + ) + return info_dict + + def coerce_path_result(self, rv: t.Any) -> t.Any: + if self.type is not None and not isinstance(rv, self.type): + if self.type is str: + rv = os.fsdecode(rv) + elif self.type is bytes: + rv = os.fsencode(rv) + else: + rv = self.type(rv) + + return rv + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") + + if not is_dash: + if self.resolve_path: + # os.path.realpath doesn't resolve symlinks on Windows + # until Python 3.8. Use pathlib for now. + import pathlib + + rv = os.fsdecode(pathlib.Path(rv).resolve()) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail( + _("{name} {filename!r} does not exist.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail( + _("{name} {filename!r} is a file.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} {filename!r} is a directory.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + if self.writable and not os.access(rv, os.W_OK): + self.fail( + _("{name} {filename!r} is not writable.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + if self.readable and not os.access(rv, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + + return self.coerce_path_result(rv) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide path completions for only + directories or any paths. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + type = "dir" if self.dir_okay and not self.file_okay else "file" + return [CompletionItem(incomplete, type=type)] + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types: t.Sequence[t.Union[t.Type, ParamType]]) -> None: + self.types = [convert_type(ty) for ty in types] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["types"] = [t.to_info_dict() for t in self.types] + return info_dict + + @property + def name(self) -> str: # type: ignore + return f"<{' '.join(ty.name for ty in self.types)}>" + + @property + def arity(self) -> int: # type: ignore + return len(self.types) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + len_type = len(self.types) + len_value = len(value) + + if len_value != len_type: + self.fail( + ngettext( + "{len_type} values are required, but {len_value} was given.", + "{len_type} values are required, but {len_value} were given.", + len_value, + ).format(len_type=len_type, len_value=len_value), + param=param, + ctx=ctx, + ) + + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: + """Find the most appropriate :class:`ParamType` for the given Python + type. If the type isn't provided, it can be inferred from a default + value. + """ + guessed_type = False + + if ty is None and default is not None: + if isinstance(default, (tuple, list)): + # If the default is empty, ty will remain None and will + # return STRING. + if default: + item = default[0] + + # A tuple of tuples needs to detect the inner types. + # Can't call convert recursively because that would + # incorrectly unwind the tuple to a single type. + if isinstance(item, (tuple, list)): + ty = tuple(map(type, item)) + else: + ty = type(item) + else: + ty = type(default) + + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + + if isinstance(ty, ParamType): + return ty + + if ty is str or ty is None: + return STRING + + if ty is int: + return INT + + if ty is float: + return FLOAT + + if ty is bool: + return BOOL + + if guessed_type: + return STRING + + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError( + f"Attempted to use an uninstantiated parameter type ({ty})." + ) + except TypeError: + # ty is an instance (correct), so issubclass fails. + pass + + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but +#: internally no string conversion takes place if the input was bytes. +#: This is usually useful when working with file paths as they can +#: appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/dist/ba_data/python-site-packages/click/utils.py b/dist/ba_data/python-site-packages/click/utils.py new file mode 100644 index 0000000..8dd3a00 --- /dev/null +++ b/dist/ba_data/python-site-packages/click/utils.py @@ -0,0 +1,588 @@ +import os +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType + +from ._compat import _default_text_stderr +from ._compat import _default_text_stdout +from ._compat import _find_binary_writer +from ._compat import auto_wrap_for_ansi +from ._compat import binary_streams +from ._compat import get_filesystem_encoding +from ._compat import open_stream +from ._compat import should_strip_ansi +from ._compat import strip_ansi +from ._compat import text_streams +from ._compat import WIN +from .globals import resolve_color_default + +if t.TYPE_CHECKING: + import typing_extensions as te + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: F) -> F: + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args, **kwargs): # type: ignore + try: + return func(*args, **kwargs) + except Exception: + pass + + return update_wrapper(t.cast(F, wrapper), func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(get_filesystem_encoding()) + except UnicodeError: + return value.decode("utf-8", "replace") + return str(value) + + +def make_default_short_help(help: str, max_length: int = 45) -> str: + """Returns a condensed version of help string.""" + # Consider only the first paragraph. + paragraph_end = help.find("\n\n") + + if paragraph_end != -1: + help = help[:paragraph_end] + + # Collapse newlines, tabs, and spaces. + words = help.split() + + if not words: + return "" + + # The first paragraph started with a "no rewrap" marker, ignore it. + if words[0] == "\b": + words = words[1:] + + total_length = 0 + last_index = len(words) - 1 + + for i, word in enumerate(words): + total_length += len(word) + (i > 0) + + if total_length > max_length: # too long, truncate + break + + if word[-1] == ".": # sentence end, truncate without "..." + return " ".join(words[: i + 1]) + + if total_length == max_length and i != last_index: + break # not at sentence end, truncate with "..." + else: + return " ".join(words) # no truncation needed + + # Account for the length of the suffix. + total_length += len("...") + + # remove words until the length is short enough + while i > 0: + total_length -= len(words[i]) + (i > 0) + + if total_length <= max_length: + break + + i -= 1 + + return " ".join(words[:i]) + "..." + + +class LazyFile: + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__( + self, + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name = filename + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO] + + if filename == "-": + self._f, self.should_close = open_stream(filename, mode, encoding, errors) + else: + if "r" in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self.open(), name) + + def __repr__(self) -> str: + if self._f is not None: + return repr(self._f) + return f"" + + def open(self) -> t.IO: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: # noqa: E402 + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) from e + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.close_intelligently() + + def __iter__(self) -> t.Iterator[t.AnyStr]: + self.open() + return iter(self._f) # type: ignore + + +class KeepOpenFile: + def __init__(self, file: t.IO) -> None: + self._file = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + pass + + def __repr__(self) -> str: + return repr(self._file) + + def __iter__(self) -> t.Iterator[t.AnyStr]: + return iter(self._file) + + +def echo( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.Any]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, +) -> None: + """Print a message and newline to stdout or a file. This should be + used instead of :func:`print` because it provides better support + for different data, files, and environments. + + Compared to :func:`print`, this does the following: + + - Ensures that the output encoding is not misconfigured on Linux. + - Supports Unicode in the Windows console. + - Supports writing to binary outputs, and supports writing bytes + to text outputs. + - Supports colors and styles on Windows. + - Removes ANSI color and style codes if the output does not look + like an interactive terminal. + - Always flushes the output. + + :param message: The string or bytes to output. Other objects are + converted to strings. + :param file: The file to write to. Defaults to ``stdout``. + :param err: Write to ``stderr`` instead of ``stdout``. + :param nl: Print a newline after the message. Enabled by default. + :param color: Force showing or hiding colors and other styles. By + default Click will remove color if the output does not look like + an interactive terminal. + + .. versionchanged:: 6.0 + Support Unicode output on the Windows console. Click does not + modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` + will still not support Unicode. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionadded:: 3.0 + Added the ``err`` parameter. + + .. versionchanged:: 2.0 + Support colors on Windows if colorama is installed. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO: + """Open a file, with extra behavior to handle ``'-'`` to indicate + a standard stream, lazy open on write, and atomic write. Similar to + the behavior of the :class:`~click.File` param type. + + If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is + wrapped so that using it in a context manager will not close it. + This makes it possible to use the function without accidentally + closing a standard stream: + + .. code-block:: python + + with open_file(filename) as f: + ... + + :param filename: The name of the file to open, or ``'-'`` for + ``stdin``/``stdout``. + :param mode: The mode in which to open the file. + :param encoding: The encoding to decode or encode a file opened in + text mode. + :param errors: The error handling mode. + :param lazy: Wait to open the file until it is accessed. For read + mode, the file is temporarily opened to raise access errors + early, then closed until it is read again. + :param atomic: Write to a temporary file and replace the given file + on close. + + .. versionadded:: 3.0 + """ + if lazy: + return t.cast(t.IO, LazyFile(filename, mode, encoding, errors, atomic=atomic)) + + f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) + + if not should_close: + f = t.cast(t.IO, KeepOpenFile(f)) + + return f + + +def get_os_args() -> t.Sequence[str]: + """Returns the argument part of ``sys.argv``, removing the first + value which is the name of the script. + + .. deprecated:: 8.0 + Will be removed in Click 8.1. Access ``sys.argv[1:]`` directly + instead. + """ + import warnings + + warnings.warn( + "'get_os_args' is deprecated and will be removed in Click 8.1." + " Access 'sys.argv[1:]' directly instead.", + DeprecationWarning, + stacklevel=2, + ) + return sys.argv[1:] + + +def format_filename( + filename: t.Union[str, bytes, os.PathLike], shorten: bool = False +) -> str: + """Formats a filename for user display. The main purpose of this + function is to ensure that the filename can be displayed at all. This + will decode the filename to unicode if necessary in a way that it will + not fail. Optionally, it can shorten the filename to not include the + full path to the filename. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + + return os.fsdecode(filename) + + +def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Windows (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Windows (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no affect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = "APPDATA" if roaming else "LOCALAPPDATA" + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser("~") + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) + if sys.platform == "darwin": + return os.path.join( + os.path.expanduser("~/Library/Application Support"), app_name + ) + return os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), + _posixify(app_name), + ) + + +class PacifyFlushWrapper: + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped: t.IO) -> None: + self.wrapped = wrapped + + def flush(self) -> None: + try: + self.wrapped.flush() + except OSError as e: + import errno + + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr: str) -> t.Any: + return getattr(self.wrapped, attr) + + +def _detect_program_name( + path: t.Optional[str] = None, _main: ModuleType = sys.modules["__main__"] +) -> str: + """Determine the command used to run the program, for use in help + text. If a file or entry point was executed, the file name is + returned. If ``python -m`` was used to execute a module or package, + ``python -m name`` is returned. + + This doesn't try to be too precise, the goal is to give a concise + name for help text. Files are only shown as their name without the + path. ``python`` is only shown for modules, and the full path to + ``sys.executable`` is not shown. + + :param path: The Python file being executed. Python puts this in + ``sys.argv[0]``, which is used by default. + :param _main: The ``__main__`` module. This should only be passed + during internal testing. + + .. versionadded:: 8.0 + Based on command args detection in the Werkzeug reloader. + + :meta private: + """ + if not path: + path = sys.argv[0] + + # The value of __package__ indicates how Python was called. It may + # not exist if a setuptools script is installed as an egg. It may be + # set incorrectly for entry points created with pip on Windows. + if getattr(_main, "__package__", None) is None or ( + os.name == "nt" + and _main.__package__ == "" + and not os.path.exists(path) + and os.path.exists(f"{path}.exe") + ): + # Executed a file, like "python app.py". + return os.path.basename(path) + + # Executed a module, like "python -m example". + # Rewritten by Python from "-m script" to "/path/to/script.py". + # Need to look at main module to determine how it was executed. + py_module = t.cast(str, _main.__package__) + name = os.path.splitext(os.path.basename(path))[0] + + # A submodule like "example.cli". + if name != "__main__": + py_module = f"{py_module}.{name}" + + return f"python -m {py_module.lstrip('.')}" + + +def _expand_args( + args: t.Iterable[str], + *, + user: bool = True, + env: bool = True, + glob_recursive: bool = True, +) -> t.List[str]: + """Simulate Unix shell expansion with Python functions. + + See :func:`glob.glob`, :func:`os.path.expanduser`, and + :func:`os.path.expandvars`. + + This intended for use on Windows, where the shell does not do any + expansion. It may not exactly match what a Unix shell would do. + + :param args: List of command line arguments to expand. + :param user: Expand user home directory. + :param env: Expand environment variables. + :param glob_recursive: ``**`` matches directories recursively. + + .. versionadded:: 8.0 + + :meta private: + """ + from glob import glob + + out = [] + + for arg in args: + if user: + arg = os.path.expanduser(arg) + + if env: + arg = os.path.expandvars(arg) + + matches = glob(arg, recursive=glob_recursive) + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/dist/ba_data/python-site-packages/cryptography/__about__.py b/dist/ba_data/python-site-packages/cryptography/__about__.py new file mode 100644 index 0000000..a77b057 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/__about__.py @@ -0,0 +1,17 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +__all__ = [ + "__version__", + "__author__", + "__copyright__", +] + +__version__ = "41.0.1" + + +__author__ = "The Python Cryptographic Authority and individual contributors" +__copyright__ = f"Copyright 2013-2023 {__author__}" diff --git a/dist/ba_data/python-site-packages/cryptography/__init__.py b/dist/ba_data/python-site-packages/cryptography/__init__.py new file mode 100644 index 0000000..86b9a25 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/__init__.py @@ -0,0 +1,13 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography.__about__ import __author__, __copyright__, __version__ + +__all__ = [ + "__version__", + "__author__", + "__copyright__", +] diff --git a/dist/ba_data/python-site-packages/cryptography/__pycache__/__about__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/__pycache__/__about__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..401e141 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/__pycache__/__about__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8bca418 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/__pycache__/exceptions.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/__pycache__/exceptions.cpython-310.opt-1.pyc new file mode 100644 index 0000000..ee4f572 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/__pycache__/exceptions.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/__pycache__/utils.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/__pycache__/utils.cpython-310.opt-1.pyc new file mode 100644 index 0000000..c76e0dc Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/__pycache__/utils.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/exceptions.py b/dist/ba_data/python-site-packages/cryptography/exceptions.py new file mode 100644 index 0000000..47fdd18 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/exceptions.py @@ -0,0 +1,54 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.hazmat.bindings._rust import exceptions as rust_exceptions + +if typing.TYPE_CHECKING: + from cryptography.hazmat.bindings._rust import openssl as rust_openssl + +_Reasons = rust_exceptions._Reasons + + +class UnsupportedAlgorithm(Exception): + def __init__( + self, message: str, reason: typing.Optional[_Reasons] = None + ) -> None: + super().__init__(message) + self._reason = reason + + +class AlreadyFinalized(Exception): + pass + + +class AlreadyUpdated(Exception): + pass + + +class NotYetFinalized(Exception): + pass + + +class InvalidTag(Exception): + pass + + +class InvalidSignature(Exception): + pass + + +class InternalError(Exception): + def __init__( + self, msg: str, err_code: typing.List[rust_openssl.OpenSSLError] + ) -> None: + super().__init__(msg) + self.err_code = err_code + + +class InvalidKey(Exception): + pass diff --git a/dist/ba_data/python-site-packages/cryptography/fernet.py b/dist/ba_data/python-site-packages/cryptography/fernet.py new file mode 100644 index 0000000..ad8fb40 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/fernet.py @@ -0,0 +1,221 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import base64 +import binascii +import os +import time +import typing + +from cryptography import utils +from cryptography.exceptions import InvalidSignature +from cryptography.hazmat.primitives import hashes, padding +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.primitives.hmac import HMAC + + +class InvalidToken(Exception): + pass + + +_MAX_CLOCK_SKEW = 60 + + +class Fernet: + def __init__( + self, + key: typing.Union[bytes, str], + backend: typing.Any = None, + ) -> None: + try: + key = base64.urlsafe_b64decode(key) + except binascii.Error as exc: + raise ValueError( + "Fernet key must be 32 url-safe base64-encoded bytes." + ) from exc + if len(key) != 32: + raise ValueError( + "Fernet key must be 32 url-safe base64-encoded bytes." + ) + + self._signing_key = key[:16] + self._encryption_key = key[16:] + + @classmethod + def generate_key(cls) -> bytes: + return base64.urlsafe_b64encode(os.urandom(32)) + + def encrypt(self, data: bytes) -> bytes: + return self.encrypt_at_time(data, int(time.time())) + + def encrypt_at_time(self, data: bytes, current_time: int) -> bytes: + iv = os.urandom(16) + return self._encrypt_from_parts(data, current_time, iv) + + def _encrypt_from_parts( + self, data: bytes, current_time: int, iv: bytes + ) -> bytes: + utils._check_bytes("data", data) + + padder = padding.PKCS7(algorithms.AES.block_size).padder() + padded_data = padder.update(data) + padder.finalize() + encryptor = Cipher( + algorithms.AES(self._encryption_key), + modes.CBC(iv), + ).encryptor() + ciphertext = encryptor.update(padded_data) + encryptor.finalize() + + basic_parts = ( + b"\x80" + + current_time.to_bytes(length=8, byteorder="big") + + iv + + ciphertext + ) + + h = HMAC(self._signing_key, hashes.SHA256()) + h.update(basic_parts) + hmac = h.finalize() + return base64.urlsafe_b64encode(basic_parts + hmac) + + def decrypt( + self, token: typing.Union[bytes, str], ttl: typing.Optional[int] = None + ) -> bytes: + timestamp, data = Fernet._get_unverified_token_data(token) + if ttl is None: + time_info = None + else: + time_info = (ttl, int(time.time())) + return self._decrypt_data(data, timestamp, time_info) + + def decrypt_at_time( + self, token: typing.Union[bytes, str], ttl: int, current_time: int + ) -> bytes: + if ttl is None: + raise ValueError( + "decrypt_at_time() can only be used with a non-None ttl" + ) + timestamp, data = Fernet._get_unverified_token_data(token) + return self._decrypt_data(data, timestamp, (ttl, current_time)) + + def extract_timestamp(self, token: typing.Union[bytes, str]) -> int: + timestamp, data = Fernet._get_unverified_token_data(token) + # Verify the token was not tampered with. + self._verify_signature(data) + return timestamp + + @staticmethod + def _get_unverified_token_data( + token: typing.Union[bytes, str] + ) -> typing.Tuple[int, bytes]: + if not isinstance(token, (str, bytes)): + raise TypeError("token must be bytes or str") + + try: + data = base64.urlsafe_b64decode(token) + except (TypeError, binascii.Error): + raise InvalidToken + + if not data or data[0] != 0x80: + raise InvalidToken + + if len(data) < 9: + raise InvalidToken + + timestamp = int.from_bytes(data[1:9], byteorder="big") + return timestamp, data + + def _verify_signature(self, data: bytes) -> None: + h = HMAC(self._signing_key, hashes.SHA256()) + h.update(data[:-32]) + try: + h.verify(data[-32:]) + except InvalidSignature: + raise InvalidToken + + def _decrypt_data( + self, + data: bytes, + timestamp: int, + time_info: typing.Optional[typing.Tuple[int, int]], + ) -> bytes: + if time_info is not None: + ttl, current_time = time_info + if timestamp + ttl < current_time: + raise InvalidToken + + if current_time + _MAX_CLOCK_SKEW < timestamp: + raise InvalidToken + + self._verify_signature(data) + + iv = data[9:25] + ciphertext = data[25:-32] + decryptor = Cipher( + algorithms.AES(self._encryption_key), modes.CBC(iv) + ).decryptor() + plaintext_padded = decryptor.update(ciphertext) + try: + plaintext_padded += decryptor.finalize() + except ValueError: + raise InvalidToken + unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() + + unpadded = unpadder.update(plaintext_padded) + try: + unpadded += unpadder.finalize() + except ValueError: + raise InvalidToken + return unpadded + + +class MultiFernet: + def __init__(self, fernets: typing.Iterable[Fernet]): + fernets = list(fernets) + if not fernets: + raise ValueError( + "MultiFernet requires at least one Fernet instance" + ) + self._fernets = fernets + + def encrypt(self, msg: bytes) -> bytes: + return self.encrypt_at_time(msg, int(time.time())) + + def encrypt_at_time(self, msg: bytes, current_time: int) -> bytes: + return self._fernets[0].encrypt_at_time(msg, current_time) + + def rotate(self, msg: typing.Union[bytes, str]) -> bytes: + timestamp, data = Fernet._get_unverified_token_data(msg) + for f in self._fernets: + try: + p = f._decrypt_data(data, timestamp, None) + break + except InvalidToken: + pass + else: + raise InvalidToken + + iv = os.urandom(16) + return self._fernets[0]._encrypt_from_parts(p, timestamp, iv) + + def decrypt( + self, msg: typing.Union[bytes, str], ttl: typing.Optional[int] = None + ) -> bytes: + for f in self._fernets: + try: + return f.decrypt(msg, ttl) + except InvalidToken: + pass + raise InvalidToken + + def decrypt_at_time( + self, msg: typing.Union[bytes, str], ttl: int, current_time: int + ) -> bytes: + for f in self._fernets: + try: + return f.decrypt_at_time(msg, ttl, current_time) + except InvalidToken: + pass + raise InvalidToken diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/__init__.py new file mode 100644 index 0000000..b9f1187 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/__init__.py @@ -0,0 +1,13 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +""" +Hazardous Materials + +This is a "Hazardous Materials" module. You should ONLY use it if you're +100% absolutely sure that you know what you're doing because this module +is full of land mines, dragons, and dinosaurs with laser guns. +""" diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..78c8669 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/__pycache__/_oid.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/__pycache__/_oid.cpython-310.opt-1.pyc new file mode 100644 index 0000000..2259d22 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/__pycache__/_oid.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/_oid.py b/dist/ba_data/python-site-packages/cryptography/hazmat/_oid.py new file mode 100644 index 0000000..01d4b34 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/_oid.py @@ -0,0 +1,299 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.hazmat.bindings._rust import ( + ObjectIdentifier as ObjectIdentifier, +) +from cryptography.hazmat.primitives import hashes + + +class ExtensionOID: + SUBJECT_DIRECTORY_ATTRIBUTES = ObjectIdentifier("2.5.29.9") + SUBJECT_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.14") + KEY_USAGE = ObjectIdentifier("2.5.29.15") + SUBJECT_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.17") + ISSUER_ALTERNATIVE_NAME = ObjectIdentifier("2.5.29.18") + BASIC_CONSTRAINTS = ObjectIdentifier("2.5.29.19") + NAME_CONSTRAINTS = ObjectIdentifier("2.5.29.30") + CRL_DISTRIBUTION_POINTS = ObjectIdentifier("2.5.29.31") + CERTIFICATE_POLICIES = ObjectIdentifier("2.5.29.32") + POLICY_MAPPINGS = ObjectIdentifier("2.5.29.33") + AUTHORITY_KEY_IDENTIFIER = ObjectIdentifier("2.5.29.35") + POLICY_CONSTRAINTS = ObjectIdentifier("2.5.29.36") + EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37") + FRESHEST_CRL = ObjectIdentifier("2.5.29.46") + INHIBIT_ANY_POLICY = ObjectIdentifier("2.5.29.54") + ISSUING_DISTRIBUTION_POINT = ObjectIdentifier("2.5.29.28") + AUTHORITY_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.1") + SUBJECT_INFORMATION_ACCESS = ObjectIdentifier("1.3.6.1.5.5.7.1.11") + OCSP_NO_CHECK = ObjectIdentifier("1.3.6.1.5.5.7.48.1.5") + TLS_FEATURE = ObjectIdentifier("1.3.6.1.5.5.7.1.24") + CRL_NUMBER = ObjectIdentifier("2.5.29.20") + DELTA_CRL_INDICATOR = ObjectIdentifier("2.5.29.27") + PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS = ObjectIdentifier( + "1.3.6.1.4.1.11129.2.4.2" + ) + PRECERT_POISON = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.3") + SIGNED_CERTIFICATE_TIMESTAMPS = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.5") + MS_CERTIFICATE_TEMPLATE = ObjectIdentifier("1.3.6.1.4.1.311.21.7") + + +class OCSPExtensionOID: + NONCE = ObjectIdentifier("1.3.6.1.5.5.7.48.1.2") + ACCEPTABLE_RESPONSES = ObjectIdentifier("1.3.6.1.5.5.7.48.1.4") + + +class CRLEntryExtensionOID: + CERTIFICATE_ISSUER = ObjectIdentifier("2.5.29.29") + CRL_REASON = ObjectIdentifier("2.5.29.21") + INVALIDITY_DATE = ObjectIdentifier("2.5.29.24") + + +class NameOID: + COMMON_NAME = ObjectIdentifier("2.5.4.3") + COUNTRY_NAME = ObjectIdentifier("2.5.4.6") + LOCALITY_NAME = ObjectIdentifier("2.5.4.7") + STATE_OR_PROVINCE_NAME = ObjectIdentifier("2.5.4.8") + STREET_ADDRESS = ObjectIdentifier("2.5.4.9") + ORGANIZATION_NAME = ObjectIdentifier("2.5.4.10") + ORGANIZATIONAL_UNIT_NAME = ObjectIdentifier("2.5.4.11") + SERIAL_NUMBER = ObjectIdentifier("2.5.4.5") + SURNAME = ObjectIdentifier("2.5.4.4") + GIVEN_NAME = ObjectIdentifier("2.5.4.42") + TITLE = ObjectIdentifier("2.5.4.12") + INITIALS = ObjectIdentifier("2.5.4.43") + GENERATION_QUALIFIER = ObjectIdentifier("2.5.4.44") + X500_UNIQUE_IDENTIFIER = ObjectIdentifier("2.5.4.45") + DN_QUALIFIER = ObjectIdentifier("2.5.4.46") + PSEUDONYM = ObjectIdentifier("2.5.4.65") + USER_ID = ObjectIdentifier("0.9.2342.19200300.100.1.1") + DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25") + EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1") + JURISDICTION_COUNTRY_NAME = ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.3") + JURISDICTION_LOCALITY_NAME = ObjectIdentifier("1.3.6.1.4.1.311.60.2.1.1") + JURISDICTION_STATE_OR_PROVINCE_NAME = ObjectIdentifier( + "1.3.6.1.4.1.311.60.2.1.2" + ) + BUSINESS_CATEGORY = ObjectIdentifier("2.5.4.15") + POSTAL_ADDRESS = ObjectIdentifier("2.5.4.16") + POSTAL_CODE = ObjectIdentifier("2.5.4.17") + INN = ObjectIdentifier("1.2.643.3.131.1.1") + OGRN = ObjectIdentifier("1.2.643.100.1") + SNILS = ObjectIdentifier("1.2.643.100.3") + UNSTRUCTURED_NAME = ObjectIdentifier("1.2.840.113549.1.9.2") + + +class SignatureAlgorithmOID: + RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4") + RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5") + # This is an alternate OID for RSA with SHA1 that is occasionally seen + _RSA_WITH_SHA1 = ObjectIdentifier("1.3.14.3.2.29") + RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14") + RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11") + RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12") + RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13") + RSA_WITH_SHA3_224 = ObjectIdentifier("2.16.840.1.101.3.4.3.13") + RSA_WITH_SHA3_256 = ObjectIdentifier("2.16.840.1.101.3.4.3.14") + RSA_WITH_SHA3_384 = ObjectIdentifier("2.16.840.1.101.3.4.3.15") + RSA_WITH_SHA3_512 = ObjectIdentifier("2.16.840.1.101.3.4.3.16") + RSASSA_PSS = ObjectIdentifier("1.2.840.113549.1.1.10") + ECDSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10045.4.1") + ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1") + ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2") + ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3") + ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4") + ECDSA_WITH_SHA3_224 = ObjectIdentifier("2.16.840.1.101.3.4.3.9") + ECDSA_WITH_SHA3_256 = ObjectIdentifier("2.16.840.1.101.3.4.3.10") + ECDSA_WITH_SHA3_384 = ObjectIdentifier("2.16.840.1.101.3.4.3.11") + ECDSA_WITH_SHA3_512 = ObjectIdentifier("2.16.840.1.101.3.4.3.12") + DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3") + DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1") + DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2") + DSA_WITH_SHA384 = ObjectIdentifier("2.16.840.1.101.3.4.3.3") + DSA_WITH_SHA512 = ObjectIdentifier("2.16.840.1.101.3.4.3.4") + ED25519 = ObjectIdentifier("1.3.101.112") + ED448 = ObjectIdentifier("1.3.101.113") + GOSTR3411_94_WITH_3410_2001 = ObjectIdentifier("1.2.643.2.2.3") + GOSTR3410_2012_WITH_3411_2012_256 = ObjectIdentifier("1.2.643.7.1.1.3.2") + GOSTR3410_2012_WITH_3411_2012_512 = ObjectIdentifier("1.2.643.7.1.1.3.3") + + +_SIG_OIDS_TO_HASH: typing.Dict[ + ObjectIdentifier, typing.Optional[hashes.HashAlgorithm] +] = { + SignatureAlgorithmOID.RSA_WITH_MD5: hashes.MD5(), + SignatureAlgorithmOID.RSA_WITH_SHA1: hashes.SHA1(), + SignatureAlgorithmOID._RSA_WITH_SHA1: hashes.SHA1(), + SignatureAlgorithmOID.RSA_WITH_SHA224: hashes.SHA224(), + SignatureAlgorithmOID.RSA_WITH_SHA256: hashes.SHA256(), + SignatureAlgorithmOID.RSA_WITH_SHA384: hashes.SHA384(), + SignatureAlgorithmOID.RSA_WITH_SHA512: hashes.SHA512(), + SignatureAlgorithmOID.RSA_WITH_SHA3_224: hashes.SHA3_224(), + SignatureAlgorithmOID.RSA_WITH_SHA3_256: hashes.SHA3_256(), + SignatureAlgorithmOID.RSA_WITH_SHA3_384: hashes.SHA3_384(), + SignatureAlgorithmOID.RSA_WITH_SHA3_512: hashes.SHA3_512(), + SignatureAlgorithmOID.ECDSA_WITH_SHA1: hashes.SHA1(), + SignatureAlgorithmOID.ECDSA_WITH_SHA224: hashes.SHA224(), + SignatureAlgorithmOID.ECDSA_WITH_SHA256: hashes.SHA256(), + SignatureAlgorithmOID.ECDSA_WITH_SHA384: hashes.SHA384(), + SignatureAlgorithmOID.ECDSA_WITH_SHA512: hashes.SHA512(), + SignatureAlgorithmOID.ECDSA_WITH_SHA3_224: hashes.SHA3_224(), + SignatureAlgorithmOID.ECDSA_WITH_SHA3_256: hashes.SHA3_256(), + SignatureAlgorithmOID.ECDSA_WITH_SHA3_384: hashes.SHA3_384(), + SignatureAlgorithmOID.ECDSA_WITH_SHA3_512: hashes.SHA3_512(), + SignatureAlgorithmOID.DSA_WITH_SHA1: hashes.SHA1(), + SignatureAlgorithmOID.DSA_WITH_SHA224: hashes.SHA224(), + SignatureAlgorithmOID.DSA_WITH_SHA256: hashes.SHA256(), + SignatureAlgorithmOID.ED25519: None, + SignatureAlgorithmOID.ED448: None, + SignatureAlgorithmOID.GOSTR3411_94_WITH_3410_2001: None, + SignatureAlgorithmOID.GOSTR3410_2012_WITH_3411_2012_256: None, + SignatureAlgorithmOID.GOSTR3410_2012_WITH_3411_2012_512: None, +} + + +class ExtendedKeyUsageOID: + SERVER_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.1") + CLIENT_AUTH = ObjectIdentifier("1.3.6.1.5.5.7.3.2") + CODE_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.3") + EMAIL_PROTECTION = ObjectIdentifier("1.3.6.1.5.5.7.3.4") + TIME_STAMPING = ObjectIdentifier("1.3.6.1.5.5.7.3.8") + OCSP_SIGNING = ObjectIdentifier("1.3.6.1.5.5.7.3.9") + ANY_EXTENDED_KEY_USAGE = ObjectIdentifier("2.5.29.37.0") + SMARTCARD_LOGON = ObjectIdentifier("1.3.6.1.4.1.311.20.2.2") + KERBEROS_PKINIT_KDC = ObjectIdentifier("1.3.6.1.5.2.3.5") + IPSEC_IKE = ObjectIdentifier("1.3.6.1.5.5.7.3.17") + CERTIFICATE_TRANSPARENCY = ObjectIdentifier("1.3.6.1.4.1.11129.2.4.4") + + +class AuthorityInformationAccessOID: + CA_ISSUERS = ObjectIdentifier("1.3.6.1.5.5.7.48.2") + OCSP = ObjectIdentifier("1.3.6.1.5.5.7.48.1") + + +class SubjectInformationAccessOID: + CA_REPOSITORY = ObjectIdentifier("1.3.6.1.5.5.7.48.5") + + +class CertificatePoliciesOID: + CPS_QUALIFIER = ObjectIdentifier("1.3.6.1.5.5.7.2.1") + CPS_USER_NOTICE = ObjectIdentifier("1.3.6.1.5.5.7.2.2") + ANY_POLICY = ObjectIdentifier("2.5.29.32.0") + + +class AttributeOID: + CHALLENGE_PASSWORD = ObjectIdentifier("1.2.840.113549.1.9.7") + UNSTRUCTURED_NAME = ObjectIdentifier("1.2.840.113549.1.9.2") + + +_OID_NAMES = { + NameOID.COMMON_NAME: "commonName", + NameOID.COUNTRY_NAME: "countryName", + NameOID.LOCALITY_NAME: "localityName", + NameOID.STATE_OR_PROVINCE_NAME: "stateOrProvinceName", + NameOID.STREET_ADDRESS: "streetAddress", + NameOID.ORGANIZATION_NAME: "organizationName", + NameOID.ORGANIZATIONAL_UNIT_NAME: "organizationalUnitName", + NameOID.SERIAL_NUMBER: "serialNumber", + NameOID.SURNAME: "surname", + NameOID.GIVEN_NAME: "givenName", + NameOID.TITLE: "title", + NameOID.GENERATION_QUALIFIER: "generationQualifier", + NameOID.X500_UNIQUE_IDENTIFIER: "x500UniqueIdentifier", + NameOID.DN_QUALIFIER: "dnQualifier", + NameOID.PSEUDONYM: "pseudonym", + NameOID.USER_ID: "userID", + NameOID.DOMAIN_COMPONENT: "domainComponent", + NameOID.EMAIL_ADDRESS: "emailAddress", + NameOID.JURISDICTION_COUNTRY_NAME: "jurisdictionCountryName", + NameOID.JURISDICTION_LOCALITY_NAME: "jurisdictionLocalityName", + NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME: ( + "jurisdictionStateOrProvinceName" + ), + NameOID.BUSINESS_CATEGORY: "businessCategory", + NameOID.POSTAL_ADDRESS: "postalAddress", + NameOID.POSTAL_CODE: "postalCode", + NameOID.INN: "INN", + NameOID.OGRN: "OGRN", + NameOID.SNILS: "SNILS", + NameOID.UNSTRUCTURED_NAME: "unstructuredName", + SignatureAlgorithmOID.RSA_WITH_MD5: "md5WithRSAEncryption", + SignatureAlgorithmOID.RSA_WITH_SHA1: "sha1WithRSAEncryption", + SignatureAlgorithmOID.RSA_WITH_SHA224: "sha224WithRSAEncryption", + SignatureAlgorithmOID.RSA_WITH_SHA256: "sha256WithRSAEncryption", + SignatureAlgorithmOID.RSA_WITH_SHA384: "sha384WithRSAEncryption", + SignatureAlgorithmOID.RSA_WITH_SHA512: "sha512WithRSAEncryption", + SignatureAlgorithmOID.RSASSA_PSS: "RSASSA-PSS", + SignatureAlgorithmOID.ECDSA_WITH_SHA1: "ecdsa-with-SHA1", + SignatureAlgorithmOID.ECDSA_WITH_SHA224: "ecdsa-with-SHA224", + SignatureAlgorithmOID.ECDSA_WITH_SHA256: "ecdsa-with-SHA256", + SignatureAlgorithmOID.ECDSA_WITH_SHA384: "ecdsa-with-SHA384", + SignatureAlgorithmOID.ECDSA_WITH_SHA512: "ecdsa-with-SHA512", + SignatureAlgorithmOID.DSA_WITH_SHA1: "dsa-with-sha1", + SignatureAlgorithmOID.DSA_WITH_SHA224: "dsa-with-sha224", + SignatureAlgorithmOID.DSA_WITH_SHA256: "dsa-with-sha256", + SignatureAlgorithmOID.ED25519: "ed25519", + SignatureAlgorithmOID.ED448: "ed448", + SignatureAlgorithmOID.GOSTR3411_94_WITH_3410_2001: ( + "GOST R 34.11-94 with GOST R 34.10-2001" + ), + SignatureAlgorithmOID.GOSTR3410_2012_WITH_3411_2012_256: ( + "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)" + ), + SignatureAlgorithmOID.GOSTR3410_2012_WITH_3411_2012_512: ( + "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)" + ), + ExtendedKeyUsageOID.SERVER_AUTH: "serverAuth", + ExtendedKeyUsageOID.CLIENT_AUTH: "clientAuth", + ExtendedKeyUsageOID.CODE_SIGNING: "codeSigning", + ExtendedKeyUsageOID.EMAIL_PROTECTION: "emailProtection", + ExtendedKeyUsageOID.TIME_STAMPING: "timeStamping", + ExtendedKeyUsageOID.OCSP_SIGNING: "OCSPSigning", + ExtendedKeyUsageOID.SMARTCARD_LOGON: "msSmartcardLogin", + ExtendedKeyUsageOID.KERBEROS_PKINIT_KDC: "pkInitKDC", + ExtensionOID.SUBJECT_DIRECTORY_ATTRIBUTES: "subjectDirectoryAttributes", + ExtensionOID.SUBJECT_KEY_IDENTIFIER: "subjectKeyIdentifier", + ExtensionOID.KEY_USAGE: "keyUsage", + ExtensionOID.SUBJECT_ALTERNATIVE_NAME: "subjectAltName", + ExtensionOID.ISSUER_ALTERNATIVE_NAME: "issuerAltName", + ExtensionOID.BASIC_CONSTRAINTS: "basicConstraints", + ExtensionOID.PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS: ( + "signedCertificateTimestampList" + ), + ExtensionOID.SIGNED_CERTIFICATE_TIMESTAMPS: ( + "signedCertificateTimestampList" + ), + ExtensionOID.PRECERT_POISON: "ctPoison", + ExtensionOID.MS_CERTIFICATE_TEMPLATE: "msCertificateTemplate", + CRLEntryExtensionOID.CRL_REASON: "cRLReason", + CRLEntryExtensionOID.INVALIDITY_DATE: "invalidityDate", + CRLEntryExtensionOID.CERTIFICATE_ISSUER: "certificateIssuer", + ExtensionOID.NAME_CONSTRAINTS: "nameConstraints", + ExtensionOID.CRL_DISTRIBUTION_POINTS: "cRLDistributionPoints", + ExtensionOID.CERTIFICATE_POLICIES: "certificatePolicies", + ExtensionOID.POLICY_MAPPINGS: "policyMappings", + ExtensionOID.AUTHORITY_KEY_IDENTIFIER: "authorityKeyIdentifier", + ExtensionOID.POLICY_CONSTRAINTS: "policyConstraints", + ExtensionOID.EXTENDED_KEY_USAGE: "extendedKeyUsage", + ExtensionOID.FRESHEST_CRL: "freshestCRL", + ExtensionOID.INHIBIT_ANY_POLICY: "inhibitAnyPolicy", + ExtensionOID.ISSUING_DISTRIBUTION_POINT: ("issuingDistributionPoint"), + ExtensionOID.AUTHORITY_INFORMATION_ACCESS: "authorityInfoAccess", + ExtensionOID.SUBJECT_INFORMATION_ACCESS: "subjectInfoAccess", + ExtensionOID.OCSP_NO_CHECK: "OCSPNoCheck", + ExtensionOID.CRL_NUMBER: "cRLNumber", + ExtensionOID.DELTA_CRL_INDICATOR: "deltaCRLIndicator", + ExtensionOID.TLS_FEATURE: "TLSFeature", + AuthorityInformationAccessOID.OCSP: "OCSP", + AuthorityInformationAccessOID.CA_ISSUERS: "caIssuers", + SubjectInformationAccessOID.CA_REPOSITORY: "caRepository", + CertificatePoliciesOID.CPS_QUALIFIER: "id-qt-cps", + CertificatePoliciesOID.CPS_USER_NOTICE: "id-qt-unotice", + OCSPExtensionOID.NONCE: "OCSPNonce", + AttributeOID.CHALLENGE_PASSWORD: "challengePassword", +} diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/__init__.py new file mode 100644 index 0000000..b4400aa --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/__init__.py @@ -0,0 +1,13 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from typing import Any + + +def default_backend() -> Any: + from cryptography.hazmat.backends.openssl.backend import backend + + return backend diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9973f9d Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/__init__.py new file mode 100644 index 0000000..51b0447 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/__init__.py @@ -0,0 +1,9 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography.hazmat.backends.openssl.backend import backend + +__all__ = ["backend"] diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/aead.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/aead.py new file mode 100644 index 0000000..b36f535 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/aead.py @@ -0,0 +1,527 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.exceptions import InvalidTag + +if typing.TYPE_CHECKING: + from cryptography.hazmat.backends.openssl.backend import Backend + from cryptography.hazmat.primitives.ciphers.aead import ( + AESCCM, + AESGCM, + AESOCB3, + AESSIV, + ChaCha20Poly1305, + ) + + _AEADTypes = typing.Union[ + AESCCM, AESGCM, AESOCB3, AESSIV, ChaCha20Poly1305 + ] + + +def _is_evp_aead_supported_cipher( + backend: Backend, cipher: _AEADTypes +) -> bool: + """ + Checks whether the given cipher is supported through + EVP_AEAD rather than the normal OpenSSL EVP_CIPHER API. + """ + from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 + + return backend._lib.Cryptography_HAS_EVP_AEAD and isinstance( + cipher, ChaCha20Poly1305 + ) + + +def _aead_cipher_supported(backend: Backend, cipher: _AEADTypes) -> bool: + if _is_evp_aead_supported_cipher(backend, cipher): + return True + else: + cipher_name = _evp_cipher_cipher_name(cipher) + if backend._fips_enabled and cipher_name not in backend._fips_aead: + return False + # SIV isn't loaded through get_cipherbyname but instead a new fetch API + # only available in 3.0+. But if we know we're on 3.0+ then we know + # it's supported. + if cipher_name.endswith(b"-siv"): + return backend._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER == 1 + else: + return ( + backend._lib.EVP_get_cipherbyname(cipher_name) + != backend._ffi.NULL + ) + + +def _aead_create_ctx( + backend: Backend, + cipher: _AEADTypes, + key: bytes, +): + if _is_evp_aead_supported_cipher(backend, cipher): + return _evp_aead_create_ctx(backend, cipher, key) + else: + return _evp_cipher_create_ctx(backend, cipher, key) + + +def _encrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any = None, +) -> bytes: + if _is_evp_aead_supported_cipher(backend, cipher): + return _evp_aead_encrypt( + backend, cipher, nonce, data, associated_data, tag_length, ctx + ) + else: + return _evp_cipher_encrypt( + backend, cipher, nonce, data, associated_data, tag_length, ctx + ) + + +def _decrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any = None, +) -> bytes: + if _is_evp_aead_supported_cipher(backend, cipher): + return _evp_aead_decrypt( + backend, cipher, nonce, data, associated_data, tag_length, ctx + ) + else: + return _evp_cipher_decrypt( + backend, cipher, nonce, data, associated_data, tag_length, ctx + ) + + +def _evp_aead_create_ctx( + backend: Backend, + cipher: _AEADTypes, + key: bytes, + tag_len: typing.Optional[int] = None, +): + aead_cipher = _evp_aead_get_cipher(backend, cipher) + assert aead_cipher is not None + key_ptr = backend._ffi.from_buffer(key) + tag_len = ( + backend._lib.EVP_AEAD_DEFAULT_TAG_LENGTH + if tag_len is None + else tag_len + ) + ctx = backend._lib.Cryptography_EVP_AEAD_CTX_new( + aead_cipher, key_ptr, len(key), tag_len + ) + backend.openssl_assert(ctx != backend._ffi.NULL) + ctx = backend._ffi.gc(ctx, backend._lib.EVP_AEAD_CTX_free) + return ctx + + +def _evp_aead_get_cipher(backend: Backend, cipher: _AEADTypes): + from cryptography.hazmat.primitives.ciphers.aead import ( + ChaCha20Poly1305, + ) + + # Currently only ChaCha20-Poly1305 is supported using this API + assert isinstance(cipher, ChaCha20Poly1305) + return backend._lib.EVP_aead_chacha20_poly1305() + + +def _evp_aead_encrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any, +) -> bytes: + assert ctx is not None + + aead_cipher = _evp_aead_get_cipher(backend, cipher) + assert aead_cipher is not None + + out_len = backend._ffi.new("size_t *") + # max_out_len should be in_len plus the result of + # EVP_AEAD_max_overhead. + max_out_len = len(data) + backend._lib.EVP_AEAD_max_overhead(aead_cipher) + out_buf = backend._ffi.new("uint8_t[]", max_out_len) + data_ptr = backend._ffi.from_buffer(data) + nonce_ptr = backend._ffi.from_buffer(nonce) + aad = b"".join(associated_data) + aad_ptr = backend._ffi.from_buffer(aad) + + res = backend._lib.EVP_AEAD_CTX_seal( + ctx, + out_buf, + out_len, + max_out_len, + nonce_ptr, + len(nonce), + data_ptr, + len(data), + aad_ptr, + len(aad), + ) + backend.openssl_assert(res == 1) + encrypted_data = backend._ffi.buffer(out_buf, out_len[0])[:] + return encrypted_data + + +def _evp_aead_decrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any, +) -> bytes: + if len(data) < tag_length: + raise InvalidTag + + assert ctx is not None + + out_len = backend._ffi.new("size_t *") + # max_out_len should at least in_len + max_out_len = len(data) + out_buf = backend._ffi.new("uint8_t[]", max_out_len) + data_ptr = backend._ffi.from_buffer(data) + nonce_ptr = backend._ffi.from_buffer(nonce) + aad = b"".join(associated_data) + aad_ptr = backend._ffi.from_buffer(aad) + + res = backend._lib.EVP_AEAD_CTX_open( + ctx, + out_buf, + out_len, + max_out_len, + nonce_ptr, + len(nonce), + data_ptr, + len(data), + aad_ptr, + len(aad), + ) + + if res == 0: + backend._consume_errors() + raise InvalidTag + + decrypted_data = backend._ffi.buffer(out_buf, out_len[0])[:] + return decrypted_data + + +_ENCRYPT = 1 +_DECRYPT = 0 + + +def _evp_cipher_cipher_name(cipher: _AEADTypes) -> bytes: + from cryptography.hazmat.primitives.ciphers.aead import ( + AESCCM, + AESGCM, + AESOCB3, + AESSIV, + ChaCha20Poly1305, + ) + + if isinstance(cipher, ChaCha20Poly1305): + return b"chacha20-poly1305" + elif isinstance(cipher, AESCCM): + return f"aes-{len(cipher._key) * 8}-ccm".encode("ascii") + elif isinstance(cipher, AESOCB3): + return f"aes-{len(cipher._key) * 8}-ocb".encode("ascii") + elif isinstance(cipher, AESSIV): + return f"aes-{len(cipher._key) * 8 // 2}-siv".encode("ascii") + else: + assert isinstance(cipher, AESGCM) + return f"aes-{len(cipher._key) * 8}-gcm".encode("ascii") + + +def _evp_cipher(cipher_name: bytes, backend: Backend): + if cipher_name.endswith(b"-siv"): + evp_cipher = backend._lib.EVP_CIPHER_fetch( + backend._ffi.NULL, + cipher_name, + backend._ffi.NULL, + ) + backend.openssl_assert(evp_cipher != backend._ffi.NULL) + evp_cipher = backend._ffi.gc(evp_cipher, backend._lib.EVP_CIPHER_free) + else: + evp_cipher = backend._lib.EVP_get_cipherbyname(cipher_name) + backend.openssl_assert(evp_cipher != backend._ffi.NULL) + + return evp_cipher + + +def _evp_cipher_create_ctx( + backend: Backend, + cipher: _AEADTypes, + key: bytes, +): + ctx = backend._lib.EVP_CIPHER_CTX_new() + backend.openssl_assert(ctx != backend._ffi.NULL) + ctx = backend._ffi.gc(ctx, backend._lib.EVP_CIPHER_CTX_free) + cipher_name = _evp_cipher_cipher_name(cipher) + evp_cipher = _evp_cipher(cipher_name, backend) + key_ptr = backend._ffi.from_buffer(key) + res = backend._lib.EVP_CipherInit_ex( + ctx, + evp_cipher, + backend._ffi.NULL, + key_ptr, + backend._ffi.NULL, + 0, + ) + backend.openssl_assert(res != 0) + return ctx + + +def _evp_cipher_aead_setup( + backend: Backend, + cipher_name: bytes, + key: bytes, + nonce: bytes, + tag: typing.Optional[bytes], + tag_len: int, + operation: int, +): + evp_cipher = _evp_cipher(cipher_name, backend) + ctx = backend._lib.EVP_CIPHER_CTX_new() + ctx = backend._ffi.gc(ctx, backend._lib.EVP_CIPHER_CTX_free) + res = backend._lib.EVP_CipherInit_ex( + ctx, + evp_cipher, + backend._ffi.NULL, + backend._ffi.NULL, + backend._ffi.NULL, + int(operation == _ENCRYPT), + ) + backend.openssl_assert(res != 0) + # CCM requires the IVLEN to be set before calling SET_TAG on decrypt + res = backend._lib.EVP_CIPHER_CTX_ctrl( + ctx, + backend._lib.EVP_CTRL_AEAD_SET_IVLEN, + len(nonce), + backend._ffi.NULL, + ) + backend.openssl_assert(res != 0) + if operation == _DECRYPT: + assert tag is not None + _evp_cipher_set_tag(backend, ctx, tag) + elif cipher_name.endswith(b"-ccm"): + res = backend._lib.EVP_CIPHER_CTX_ctrl( + ctx, + backend._lib.EVP_CTRL_AEAD_SET_TAG, + tag_len, + backend._ffi.NULL, + ) + backend.openssl_assert(res != 0) + + nonce_ptr = backend._ffi.from_buffer(nonce) + key_ptr = backend._ffi.from_buffer(key) + res = backend._lib.EVP_CipherInit_ex( + ctx, + backend._ffi.NULL, + backend._ffi.NULL, + key_ptr, + nonce_ptr, + int(operation == _ENCRYPT), + ) + backend.openssl_assert(res != 0) + return ctx + + +def _evp_cipher_set_tag(backend, ctx, tag: bytes) -> None: + tag_ptr = backend._ffi.from_buffer(tag) + res = backend._lib.EVP_CIPHER_CTX_ctrl( + ctx, backend._lib.EVP_CTRL_AEAD_SET_TAG, len(tag), tag_ptr + ) + backend.openssl_assert(res != 0) + + +def _evp_cipher_set_nonce_operation( + backend, ctx, nonce: bytes, operation: int +) -> None: + nonce_ptr = backend._ffi.from_buffer(nonce) + res = backend._lib.EVP_CipherInit_ex( + ctx, + backend._ffi.NULL, + backend._ffi.NULL, + backend._ffi.NULL, + nonce_ptr, + int(operation == _ENCRYPT), + ) + backend.openssl_assert(res != 0) + + +def _evp_cipher_set_length(backend: Backend, ctx, data_len: int) -> None: + intptr = backend._ffi.new("int *") + res = backend._lib.EVP_CipherUpdate( + ctx, backend._ffi.NULL, intptr, backend._ffi.NULL, data_len + ) + backend.openssl_assert(res != 0) + + +def _evp_cipher_process_aad( + backend: Backend, ctx, associated_data: bytes +) -> None: + outlen = backend._ffi.new("int *") + a_data_ptr = backend._ffi.from_buffer(associated_data) + res = backend._lib.EVP_CipherUpdate( + ctx, backend._ffi.NULL, outlen, a_data_ptr, len(associated_data) + ) + backend.openssl_assert(res != 0) + + +def _evp_cipher_process_data(backend: Backend, ctx, data: bytes) -> bytes: + outlen = backend._ffi.new("int *") + buf = backend._ffi.new("unsigned char[]", len(data)) + data_ptr = backend._ffi.from_buffer(data) + res = backend._lib.EVP_CipherUpdate(ctx, buf, outlen, data_ptr, len(data)) + if res == 0: + # AES SIV can error here if the data is invalid on decrypt + backend._consume_errors() + raise InvalidTag + return backend._ffi.buffer(buf, outlen[0])[:] + + +def _evp_cipher_encrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any = None, +) -> bytes: + from cryptography.hazmat.primitives.ciphers.aead import AESCCM, AESSIV + + if ctx is None: + cipher_name = _evp_cipher_cipher_name(cipher) + ctx = _evp_cipher_aead_setup( + backend, + cipher_name, + cipher._key, + nonce, + None, + tag_length, + _ENCRYPT, + ) + else: + _evp_cipher_set_nonce_operation(backend, ctx, nonce, _ENCRYPT) + + # CCM requires us to pass the length of the data before processing + # anything. + # However calling this with any other AEAD results in an error + if isinstance(cipher, AESCCM): + _evp_cipher_set_length(backend, ctx, len(data)) + + for ad in associated_data: + _evp_cipher_process_aad(backend, ctx, ad) + processed_data = _evp_cipher_process_data(backend, ctx, data) + outlen = backend._ffi.new("int *") + # All AEADs we support besides OCB are streaming so they return nothing + # in finalization. OCB can return up to (16 byte block - 1) bytes so + # we need a buffer here too. + buf = backend._ffi.new("unsigned char[]", 16) + res = backend._lib.EVP_CipherFinal_ex(ctx, buf, outlen) + backend.openssl_assert(res != 0) + processed_data += backend._ffi.buffer(buf, outlen[0])[:] + tag_buf = backend._ffi.new("unsigned char[]", tag_length) + res = backend._lib.EVP_CIPHER_CTX_ctrl( + ctx, backend._lib.EVP_CTRL_AEAD_GET_TAG, tag_length, tag_buf + ) + backend.openssl_assert(res != 0) + tag = backend._ffi.buffer(tag_buf)[:] + + if isinstance(cipher, AESSIV): + # RFC 5297 defines the output as IV || C, where the tag we generate + # is the "IV" and C is the ciphertext. This is the opposite of our + # other AEADs, which are Ciphertext || Tag + backend.openssl_assert(len(tag) == 16) + return tag + processed_data + else: + return processed_data + tag + + +def _evp_cipher_decrypt( + backend: Backend, + cipher: _AEADTypes, + nonce: bytes, + data: bytes, + associated_data: typing.List[bytes], + tag_length: int, + ctx: typing.Any = None, +) -> bytes: + from cryptography.hazmat.primitives.ciphers.aead import AESCCM, AESSIV + + if len(data) < tag_length: + raise InvalidTag + + if isinstance(cipher, AESSIV): + # RFC 5297 defines the output as IV || C, where the tag we generate + # is the "IV" and C is the ciphertext. This is the opposite of our + # other AEADs, which are Ciphertext || Tag + tag = data[:tag_length] + data = data[tag_length:] + else: + tag = data[-tag_length:] + data = data[:-tag_length] + if ctx is None: + cipher_name = _evp_cipher_cipher_name(cipher) + ctx = _evp_cipher_aead_setup( + backend, + cipher_name, + cipher._key, + nonce, + tag, + tag_length, + _DECRYPT, + ) + else: + _evp_cipher_set_nonce_operation(backend, ctx, nonce, _DECRYPT) + _evp_cipher_set_tag(backend, ctx, tag) + + # CCM requires us to pass the length of the data before processing + # anything. + # However calling this with any other AEAD results in an error + if isinstance(cipher, AESCCM): + _evp_cipher_set_length(backend, ctx, len(data)) + + for ad in associated_data: + _evp_cipher_process_aad(backend, ctx, ad) + # CCM has a different error path if the tag doesn't match. Errors are + # raised in Update and Final is irrelevant. + if isinstance(cipher, AESCCM): + outlen = backend._ffi.new("int *") + buf = backend._ffi.new("unsigned char[]", len(data)) + d_ptr = backend._ffi.from_buffer(data) + res = backend._lib.EVP_CipherUpdate(ctx, buf, outlen, d_ptr, len(data)) + if res != 1: + backend._consume_errors() + raise InvalidTag + + processed_data = backend._ffi.buffer(buf, outlen[0])[:] + else: + processed_data = _evp_cipher_process_data(backend, ctx, data) + outlen = backend._ffi.new("int *") + # OCB can return up to 15 bytes (16 byte block - 1) in finalization + buf = backend._ffi.new("unsigned char[]", 16) + res = backend._lib.EVP_CipherFinal_ex(ctx, buf, outlen) + processed_data += backend._ffi.buffer(buf, outlen[0])[:] + if res == 0: + backend._consume_errors() + raise InvalidTag + + return processed_data diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/backend.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/backend.py new file mode 100644 index 0000000..02d5109 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/backend.py @@ -0,0 +1,1935 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import collections +import contextlib +import itertools +import typing +from contextlib import contextmanager + +from cryptography import utils, x509 +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.backends.openssl import aead +from cryptography.hazmat.backends.openssl.ciphers import _CipherContext +from cryptography.hazmat.backends.openssl.cmac import _CMACContext +from cryptography.hazmat.backends.openssl.ec import ( + _EllipticCurvePrivateKey, + _EllipticCurvePublicKey, +) +from cryptography.hazmat.backends.openssl.rsa import ( + _RSAPrivateKey, + _RSAPublicKey, +) +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.bindings.openssl import binding +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives._asymmetric import AsymmetricPadding +from cryptography.hazmat.primitives.asymmetric import ( + dh, + dsa, + ec, + ed448, + ed25519, + rsa, + x448, + x25519, +) +from cryptography.hazmat.primitives.asymmetric.padding import ( + MGF1, + OAEP, + PSS, + PKCS1v15, +) +from cryptography.hazmat.primitives.asymmetric.types import ( + PrivateKeyTypes, + PublicKeyTypes, +) +from cryptography.hazmat.primitives.ciphers import ( + BlockCipherAlgorithm, + CipherAlgorithm, +) +from cryptography.hazmat.primitives.ciphers.algorithms import ( + AES, + AES128, + AES256, + ARC4, + SM4, + Camellia, + ChaCha20, + TripleDES, + _BlowfishInternal, + _CAST5Internal, + _IDEAInternal, + _SEEDInternal, +) +from cryptography.hazmat.primitives.ciphers.modes import ( + CBC, + CFB, + CFB8, + CTR, + ECB, + GCM, + OFB, + XTS, + Mode, +) +from cryptography.hazmat.primitives.serialization import ssh +from cryptography.hazmat.primitives.serialization.pkcs12 import ( + PBES, + PKCS12Certificate, + PKCS12KeyAndCertificates, + PKCS12PrivateKeyTypes, + _PKCS12CATypes, +) + +_MemoryBIO = collections.namedtuple("_MemoryBIO", ["bio", "char_ptr"]) + + +# Not actually supported, just used as a marker for some serialization tests. +class _RC2: + pass + + +class Backend: + """ + OpenSSL API binding interfaces. + """ + + name = "openssl" + + # FIPS has opinions about acceptable algorithms and key sizes, but the + # disallowed algorithms are still present in OpenSSL. They just error if + # you try to use them. To avoid that we allowlist the algorithms in + # FIPS 140-3. This isn't ideal, but FIPS 140-3 is trash so here we are. + _fips_aead = { + b"aes-128-ccm", + b"aes-192-ccm", + b"aes-256-ccm", + b"aes-128-gcm", + b"aes-192-gcm", + b"aes-256-gcm", + } + # TripleDES encryption is disallowed/deprecated throughout 2023 in + # FIPS 140-3. To keep it simple we denylist any use of TripleDES (TDEA). + _fips_ciphers = (AES,) + # Sometimes SHA1 is still permissible. That logic is contained + # within the various *_supported methods. + _fips_hashes = ( + hashes.SHA224, + hashes.SHA256, + hashes.SHA384, + hashes.SHA512, + hashes.SHA512_224, + hashes.SHA512_256, + hashes.SHA3_224, + hashes.SHA3_256, + hashes.SHA3_384, + hashes.SHA3_512, + hashes.SHAKE128, + hashes.SHAKE256, + ) + _fips_ecdh_curves = ( + ec.SECP224R1, + ec.SECP256R1, + ec.SECP384R1, + ec.SECP521R1, + ) + _fips_rsa_min_key_size = 2048 + _fips_rsa_min_public_exponent = 65537 + _fips_dsa_min_modulus = 1 << 2048 + _fips_dh_min_key_size = 2048 + _fips_dh_min_modulus = 1 << _fips_dh_min_key_size + + def __init__(self) -> None: + self._binding = binding.Binding() + self._ffi = self._binding.ffi + self._lib = self._binding.lib + self._fips_enabled = rust_openssl.is_fips_enabled() + + self._cipher_registry: typing.Dict[ + typing.Tuple[typing.Type[CipherAlgorithm], typing.Type[Mode]], + typing.Callable, + ] = {} + self._register_default_ciphers() + self._dh_types = [self._lib.EVP_PKEY_DH] + if self._lib.Cryptography_HAS_EVP_PKEY_DHX: + self._dh_types.append(self._lib.EVP_PKEY_DHX) + + def __repr__(self) -> str: + return "".format( + self.openssl_version_text(), + self._fips_enabled, + self._binding._legacy_provider_loaded, + ) + + def openssl_assert( + self, + ok: bool, + errors: typing.Optional[typing.List[rust_openssl.OpenSSLError]] = None, + ) -> None: + return binding._openssl_assert(self._lib, ok, errors=errors) + + def _enable_fips(self) -> None: + # This function enables FIPS mode for OpenSSL 3.0.0 on installs that + # have the FIPS provider installed properly. + self._binding._enable_fips() + assert rust_openssl.is_fips_enabled() + self._fips_enabled = rust_openssl.is_fips_enabled() + + def openssl_version_text(self) -> str: + """ + Friendly string name of the loaded OpenSSL library. This is not + necessarily the same version as it was compiled against. + + Example: OpenSSL 1.1.1d 10 Sep 2019 + """ + return self._ffi.string( + self._lib.OpenSSL_version(self._lib.OPENSSL_VERSION) + ).decode("ascii") + + def openssl_version_number(self) -> int: + return self._lib.OpenSSL_version_num() + + def _evp_md_from_algorithm(self, algorithm: hashes.HashAlgorithm): + if algorithm.name == "blake2b" or algorithm.name == "blake2s": + alg = "{}{}".format( + algorithm.name, algorithm.digest_size * 8 + ).encode("ascii") + else: + alg = algorithm.name.encode("ascii") + + evp_md = self._lib.EVP_get_digestbyname(alg) + return evp_md + + def _evp_md_non_null_from_algorithm(self, algorithm: hashes.HashAlgorithm): + evp_md = self._evp_md_from_algorithm(algorithm) + self.openssl_assert(evp_md != self._ffi.NULL) + return evp_md + + def hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool: + if self._fips_enabled and not isinstance(algorithm, self._fips_hashes): + return False + + evp_md = self._evp_md_from_algorithm(algorithm) + return evp_md != self._ffi.NULL + + def signature_hash_supported( + self, algorithm: hashes.HashAlgorithm + ) -> bool: + # Dedicated check for hashing algorithm use in message digest for + # signatures, e.g. RSA PKCS#1 v1.5 SHA1 (sha1WithRSAEncryption). + if self._fips_enabled and isinstance(algorithm, hashes.SHA1): + return False + return self.hash_supported(algorithm) + + def scrypt_supported(self) -> bool: + if self._fips_enabled: + return False + else: + return self._lib.Cryptography_HAS_SCRYPT == 1 + + def hmac_supported(self, algorithm: hashes.HashAlgorithm) -> bool: + # FIPS mode still allows SHA1 for HMAC + if self._fips_enabled and isinstance(algorithm, hashes.SHA1): + return True + + return self.hash_supported(algorithm) + + def cipher_supported(self, cipher: CipherAlgorithm, mode: Mode) -> bool: + if self._fips_enabled: + # FIPS mode requires AES. TripleDES is disallowed/deprecated in + # FIPS 140-3. + if not isinstance(cipher, self._fips_ciphers): + return False + + try: + adapter = self._cipher_registry[type(cipher), type(mode)] + except KeyError: + return False + evp_cipher = adapter(self, cipher, mode) + return self._ffi.NULL != evp_cipher + + def register_cipher_adapter(self, cipher_cls, mode_cls, adapter) -> None: + if (cipher_cls, mode_cls) in self._cipher_registry: + raise ValueError( + "Duplicate registration for: {} {}.".format( + cipher_cls, mode_cls + ) + ) + self._cipher_registry[cipher_cls, mode_cls] = adapter + + def _register_default_ciphers(self) -> None: + for cipher_cls in [AES, AES128, AES256]: + for mode_cls in [CBC, CTR, ECB, OFB, CFB, CFB8, GCM]: + self.register_cipher_adapter( + cipher_cls, + mode_cls, + GetCipherByName( + "{cipher.name}-{cipher.key_size}-{mode.name}" + ), + ) + for mode_cls in [CBC, CTR, ECB, OFB, CFB]: + self.register_cipher_adapter( + Camellia, + mode_cls, + GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}"), + ) + for mode_cls in [CBC, CFB, CFB8, OFB]: + self.register_cipher_adapter( + TripleDES, mode_cls, GetCipherByName("des-ede3-{mode.name}") + ) + self.register_cipher_adapter( + TripleDES, ECB, GetCipherByName("des-ede3") + ) + self.register_cipher_adapter( + ChaCha20, type(None), GetCipherByName("chacha20") + ) + self.register_cipher_adapter(AES, XTS, _get_xts_cipher) + for mode_cls in [ECB, CBC, OFB, CFB, CTR]: + self.register_cipher_adapter( + SM4, mode_cls, GetCipherByName("sm4-{mode.name}") + ) + # Don't register legacy ciphers if they're unavailable. Hypothetically + # this wouldn't be necessary because we test availability by seeing if + # we get an EVP_CIPHER * in the _CipherContext __init__, but OpenSSL 3 + # will return a valid pointer even though the cipher is unavailable. + if ( + self._binding._legacy_provider_loaded + or not self._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER + ): + for mode_cls in [CBC, CFB, OFB, ECB]: + self.register_cipher_adapter( + _BlowfishInternal, + mode_cls, + GetCipherByName("bf-{mode.name}"), + ) + for mode_cls in [CBC, CFB, OFB, ECB]: + self.register_cipher_adapter( + _SEEDInternal, + mode_cls, + GetCipherByName("seed-{mode.name}"), + ) + for cipher_cls, mode_cls in itertools.product( + [_CAST5Internal, _IDEAInternal], + [CBC, OFB, CFB, ECB], + ): + self.register_cipher_adapter( + cipher_cls, + mode_cls, + GetCipherByName("{cipher.name}-{mode.name}"), + ) + self.register_cipher_adapter( + ARC4, type(None), GetCipherByName("rc4") + ) + # We don't actually support RC2, this is just used by some tests. + self.register_cipher_adapter( + _RC2, type(None), GetCipherByName("rc2") + ) + + def create_symmetric_encryption_ctx( + self, cipher: CipherAlgorithm, mode: Mode + ) -> _CipherContext: + return _CipherContext(self, cipher, mode, _CipherContext._ENCRYPT) + + def create_symmetric_decryption_ctx( + self, cipher: CipherAlgorithm, mode: Mode + ) -> _CipherContext: + return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT) + + def pbkdf2_hmac_supported(self, algorithm: hashes.HashAlgorithm) -> bool: + return self.hmac_supported(algorithm) + + def _consume_errors(self) -> typing.List[rust_openssl.OpenSSLError]: + return rust_openssl.capture_error_stack() + + def _bn_to_int(self, bn) -> int: + assert bn != self._ffi.NULL + self.openssl_assert(not self._lib.BN_is_negative(bn)) + + bn_num_bytes = self._lib.BN_num_bytes(bn) + bin_ptr = self._ffi.new("unsigned char[]", bn_num_bytes) + bin_len = self._lib.BN_bn2bin(bn, bin_ptr) + # A zero length means the BN has value 0 + self.openssl_assert(bin_len >= 0) + val = int.from_bytes(self._ffi.buffer(bin_ptr)[:bin_len], "big") + return val + + def _int_to_bn(self, num: int): + """ + Converts a python integer to a BIGNUM. The returned BIGNUM will not + be garbage collected (to support adding them to structs that take + ownership of the object). Be sure to register it for GC if it will + be discarded after use. + """ + binary = num.to_bytes(int(num.bit_length() / 8.0 + 1), "big") + bn_ptr = self._lib.BN_bin2bn(binary, len(binary), self._ffi.NULL) + self.openssl_assert(bn_ptr != self._ffi.NULL) + return bn_ptr + + def generate_rsa_private_key( + self, public_exponent: int, key_size: int + ) -> rsa.RSAPrivateKey: + rsa._verify_rsa_parameters(public_exponent, key_size) + + rsa_cdata = self._lib.RSA_new() + self.openssl_assert(rsa_cdata != self._ffi.NULL) + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + + bn = self._int_to_bn(public_exponent) + bn = self._ffi.gc(bn, self._lib.BN_free) + + res = self._lib.RSA_generate_key_ex( + rsa_cdata, key_size, bn, self._ffi.NULL + ) + self.openssl_assert(res == 1) + evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) + + # We can skip RSA key validation here since we just generated the key + return _RSAPrivateKey( + self, rsa_cdata, evp_pkey, unsafe_skip_rsa_key_validation=True + ) + + def generate_rsa_parameters_supported( + self, public_exponent: int, key_size: int + ) -> bool: + return ( + public_exponent >= 3 + and public_exponent & 1 != 0 + and key_size >= 512 + ) + + def load_rsa_private_numbers( + self, + numbers: rsa.RSAPrivateNumbers, + unsafe_skip_rsa_key_validation: bool, + ) -> rsa.RSAPrivateKey: + rsa._check_private_key_components( + numbers.p, + numbers.q, + numbers.d, + numbers.dmp1, + numbers.dmq1, + numbers.iqmp, + numbers.public_numbers.e, + numbers.public_numbers.n, + ) + rsa_cdata = self._lib.RSA_new() + self.openssl_assert(rsa_cdata != self._ffi.NULL) + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + p = self._int_to_bn(numbers.p) + q = self._int_to_bn(numbers.q) + d = self._int_to_bn(numbers.d) + dmp1 = self._int_to_bn(numbers.dmp1) + dmq1 = self._int_to_bn(numbers.dmq1) + iqmp = self._int_to_bn(numbers.iqmp) + e = self._int_to_bn(numbers.public_numbers.e) + n = self._int_to_bn(numbers.public_numbers.n) + res = self._lib.RSA_set0_factors(rsa_cdata, p, q) + self.openssl_assert(res == 1) + res = self._lib.RSA_set0_key(rsa_cdata, n, e, d) + self.openssl_assert(res == 1) + res = self._lib.RSA_set0_crt_params(rsa_cdata, dmp1, dmq1, iqmp) + self.openssl_assert(res == 1) + evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) + + return _RSAPrivateKey( + self, + rsa_cdata, + evp_pkey, + unsafe_skip_rsa_key_validation=unsafe_skip_rsa_key_validation, + ) + + def load_rsa_public_numbers( + self, numbers: rsa.RSAPublicNumbers + ) -> rsa.RSAPublicKey: + rsa._check_public_key_components(numbers.e, numbers.n) + rsa_cdata = self._lib.RSA_new() + self.openssl_assert(rsa_cdata != self._ffi.NULL) + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + e = self._int_to_bn(numbers.e) + n = self._int_to_bn(numbers.n) + res = self._lib.RSA_set0_key(rsa_cdata, n, e, self._ffi.NULL) + self.openssl_assert(res == 1) + evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) + + return _RSAPublicKey(self, rsa_cdata, evp_pkey) + + def _create_evp_pkey_gc(self): + evp_pkey = self._lib.EVP_PKEY_new() + self.openssl_assert(evp_pkey != self._ffi.NULL) + evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + return evp_pkey + + def _rsa_cdata_to_evp_pkey(self, rsa_cdata): + evp_pkey = self._create_evp_pkey_gc() + res = self._lib.EVP_PKEY_set1_RSA(evp_pkey, rsa_cdata) + self.openssl_assert(res == 1) + return evp_pkey + + def _bytes_to_bio(self, data: bytes) -> _MemoryBIO: + """ + Return a _MemoryBIO namedtuple of (BIO, char*). + + The char* is the storage for the BIO and it must stay alive until the + BIO is finished with. + """ + data_ptr = self._ffi.from_buffer(data) + bio = self._lib.BIO_new_mem_buf(data_ptr, len(data)) + self.openssl_assert(bio != self._ffi.NULL) + + return _MemoryBIO(self._ffi.gc(bio, self._lib.BIO_free), data_ptr) + + def _create_mem_bio_gc(self): + """ + Creates an empty memory BIO. + """ + bio_method = self._lib.BIO_s_mem() + self.openssl_assert(bio_method != self._ffi.NULL) + bio = self._lib.BIO_new(bio_method) + self.openssl_assert(bio != self._ffi.NULL) + bio = self._ffi.gc(bio, self._lib.BIO_free) + return bio + + def _read_mem_bio(self, bio) -> bytes: + """ + Reads a memory BIO. This only works on memory BIOs. + """ + buf = self._ffi.new("char **") + buf_len = self._lib.BIO_get_mem_data(bio, buf) + self.openssl_assert(buf_len > 0) + self.openssl_assert(buf[0] != self._ffi.NULL) + bio_data = self._ffi.buffer(buf[0], buf_len)[:] + return bio_data + + def _evp_pkey_to_private_key( + self, evp_pkey, unsafe_skip_rsa_key_validation: bool + ) -> PrivateKeyTypes: + """ + Return the appropriate type of PrivateKey given an evp_pkey cdata + pointer. + """ + + key_type = self._lib.EVP_PKEY_id(evp_pkey) + + if key_type == self._lib.EVP_PKEY_RSA: + rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) + self.openssl_assert(rsa_cdata != self._ffi.NULL) + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + return _RSAPrivateKey( + self, + rsa_cdata, + evp_pkey, + unsafe_skip_rsa_key_validation=unsafe_skip_rsa_key_validation, + ) + elif ( + key_type == self._lib.EVP_PKEY_RSA_PSS + and not self._lib.CRYPTOGRAPHY_IS_LIBRESSL + and not self._lib.CRYPTOGRAPHY_IS_BORINGSSL + and not self._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E + ): + # At the moment the way we handle RSA PSS keys is to strip the + # PSS constraints from them and treat them as normal RSA keys + # Unfortunately the RSA * itself tracks this data so we need to + # extract, serialize, and reload it without the constraints. + rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) + self.openssl_assert(rsa_cdata != self._ffi.NULL) + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + bio = self._create_mem_bio_gc() + res = self._lib.i2d_RSAPrivateKey_bio(bio, rsa_cdata) + self.openssl_assert(res == 1) + return self.load_der_private_key( + self._read_mem_bio(bio), + password=None, + unsafe_skip_rsa_key_validation=unsafe_skip_rsa_key_validation, + ) + elif key_type == self._lib.EVP_PKEY_DSA: + return rust_openssl.dsa.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == self._lib.EVP_PKEY_EC: + ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) + self.openssl_assert(ec_cdata != self._ffi.NULL) + ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) + return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) + elif key_type in self._dh_types: + return rust_openssl.dh.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == getattr(self._lib, "EVP_PKEY_ED25519", None): + # EVP_PKEY_ED25519 is not present in CRYPTOGRAPHY_IS_LIBRESSL + return rust_openssl.ed25519.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == getattr(self._lib, "EVP_PKEY_X448", None): + # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL + return rust_openssl.x448.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == self._lib.EVP_PKEY_X25519: + return rust_openssl.x25519.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): + # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL + return rust_openssl.ed448.private_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + else: + raise UnsupportedAlgorithm("Unsupported key type.") + + def _evp_pkey_to_public_key(self, evp_pkey) -> PublicKeyTypes: + """ + Return the appropriate type of PublicKey given an evp_pkey cdata + pointer. + """ + + key_type = self._lib.EVP_PKEY_id(evp_pkey) + + if key_type == self._lib.EVP_PKEY_RSA: + rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) + self.openssl_assert(rsa_cdata != self._ffi.NULL) + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + return _RSAPublicKey(self, rsa_cdata, evp_pkey) + elif ( + key_type == self._lib.EVP_PKEY_RSA_PSS + and not self._lib.CRYPTOGRAPHY_IS_LIBRESSL + and not self._lib.CRYPTOGRAPHY_IS_BORINGSSL + and not self._lib.CRYPTOGRAPHY_OPENSSL_LESS_THAN_111E + ): + rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) + self.openssl_assert(rsa_cdata != self._ffi.NULL) + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + bio = self._create_mem_bio_gc() + res = self._lib.i2d_RSAPublicKey_bio(bio, rsa_cdata) + self.openssl_assert(res == 1) + return self.load_der_public_key(self._read_mem_bio(bio)) + elif key_type == self._lib.EVP_PKEY_DSA: + return rust_openssl.dsa.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == self._lib.EVP_PKEY_EC: + ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) + if ec_cdata == self._ffi.NULL: + errors = self._consume_errors() + raise ValueError("Unable to load EC key", errors) + ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) + return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) + elif key_type in self._dh_types: + return rust_openssl.dh.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == getattr(self._lib, "EVP_PKEY_ED25519", None): + # EVP_PKEY_ED25519 is not present in CRYPTOGRAPHY_IS_LIBRESSL + return rust_openssl.ed25519.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == getattr(self._lib, "EVP_PKEY_X448", None): + # EVP_PKEY_X448 is not present in CRYPTOGRAPHY_IS_LIBRESSL + return rust_openssl.x448.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == self._lib.EVP_PKEY_X25519: + return rust_openssl.x25519.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + elif key_type == getattr(self._lib, "EVP_PKEY_ED448", None): + # EVP_PKEY_ED448 is not present in CRYPTOGRAPHY_IS_LIBRESSL + return rust_openssl.ed448.public_key_from_ptr( + int(self._ffi.cast("uintptr_t", evp_pkey)) + ) + else: + raise UnsupportedAlgorithm("Unsupported key type.") + + def _oaep_hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool: + if self._fips_enabled and isinstance(algorithm, hashes.SHA1): + return False + + return isinstance( + algorithm, + ( + hashes.SHA1, + hashes.SHA224, + hashes.SHA256, + hashes.SHA384, + hashes.SHA512, + ), + ) + + def rsa_padding_supported(self, padding: AsymmetricPadding) -> bool: + if isinstance(padding, PKCS1v15): + return True + elif isinstance(padding, PSS) and isinstance(padding._mgf, MGF1): + # SHA1 is permissible in MGF1 in FIPS even when SHA1 is blocked + # as signature algorithm. + if self._fips_enabled and isinstance( + padding._mgf._algorithm, hashes.SHA1 + ): + return True + else: + return self.hash_supported(padding._mgf._algorithm) + elif isinstance(padding, OAEP) and isinstance(padding._mgf, MGF1): + return self._oaep_hash_supported( + padding._mgf._algorithm + ) and self._oaep_hash_supported(padding._algorithm) + else: + return False + + def rsa_encryption_supported(self, padding: AsymmetricPadding) -> bool: + if self._fips_enabled and isinstance(padding, PKCS1v15): + return False + else: + return self.rsa_padding_supported(padding) + + def generate_dsa_parameters(self, key_size: int) -> dsa.DSAParameters: + if key_size not in (1024, 2048, 3072, 4096): + raise ValueError( + "Key size must be 1024, 2048, 3072, or 4096 bits." + ) + + return rust_openssl.dsa.generate_parameters(key_size) + + def generate_dsa_private_key( + self, parameters: dsa.DSAParameters + ) -> dsa.DSAPrivateKey: + return parameters.generate_private_key() + + def generate_dsa_private_key_and_parameters( + self, key_size: int + ) -> dsa.DSAPrivateKey: + parameters = self.generate_dsa_parameters(key_size) + return self.generate_dsa_private_key(parameters) + + def load_dsa_private_numbers( + self, numbers: dsa.DSAPrivateNumbers + ) -> dsa.DSAPrivateKey: + dsa._check_dsa_private_numbers(numbers) + return rust_openssl.dsa.from_private_numbers(numbers) + + def load_dsa_public_numbers( + self, numbers: dsa.DSAPublicNumbers + ) -> dsa.DSAPublicKey: + dsa._check_dsa_parameters(numbers.parameter_numbers) + return rust_openssl.dsa.from_public_numbers(numbers) + + def load_dsa_parameter_numbers( + self, numbers: dsa.DSAParameterNumbers + ) -> dsa.DSAParameters: + dsa._check_dsa_parameters(numbers) + return rust_openssl.dsa.from_parameter_numbers(numbers) + + def dsa_supported(self) -> bool: + return ( + not self._lib.CRYPTOGRAPHY_IS_BORINGSSL and not self._fips_enabled + ) + + def dsa_hash_supported(self, algorithm: hashes.HashAlgorithm) -> bool: + if not self.dsa_supported(): + return False + return self.signature_hash_supported(algorithm) + + def cmac_algorithm_supported(self, algorithm) -> bool: + return self.cipher_supported( + algorithm, CBC(b"\x00" * algorithm.block_size) + ) + + def create_cmac_ctx(self, algorithm: BlockCipherAlgorithm) -> _CMACContext: + return _CMACContext(self, algorithm) + + def load_pem_private_key( + self, + data: bytes, + password: typing.Optional[bytes], + unsafe_skip_rsa_key_validation: bool, + ) -> PrivateKeyTypes: + return self._load_key( + self._lib.PEM_read_bio_PrivateKey, + data, + password, + unsafe_skip_rsa_key_validation, + ) + + def load_pem_public_key(self, data: bytes) -> PublicKeyTypes: + mem_bio = self._bytes_to_bio(data) + # In OpenSSL 3.0.x the PEM_read_bio_PUBKEY function will invoke + # the default password callback if you pass an encrypted private + # key. This is very, very, very bad as the default callback can + # trigger an interactive console prompt, which will hang the + # Python process. We therefore provide our own callback to + # catch this and error out properly. + userdata = self._ffi.new("CRYPTOGRAPHY_PASSWORD_DATA *") + evp_pkey = self._lib.PEM_read_bio_PUBKEY( + mem_bio.bio, + self._ffi.NULL, + self._ffi.addressof( + self._lib._original_lib, "Cryptography_pem_password_cb" + ), + userdata, + ) + if evp_pkey != self._ffi.NULL: + evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + return self._evp_pkey_to_public_key(evp_pkey) + else: + # It's not a (RSA/DSA/ECDSA) subjectPublicKeyInfo, but we still + # need to check to see if it is a pure PKCS1 RSA public key (not + # embedded in a subjectPublicKeyInfo) + self._consume_errors() + res = self._lib.BIO_reset(mem_bio.bio) + self.openssl_assert(res == 1) + rsa_cdata = self._lib.PEM_read_bio_RSAPublicKey( + mem_bio.bio, + self._ffi.NULL, + self._ffi.addressof( + self._lib._original_lib, "Cryptography_pem_password_cb" + ), + userdata, + ) + if rsa_cdata != self._ffi.NULL: + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) + return _RSAPublicKey(self, rsa_cdata, evp_pkey) + else: + self._handle_key_loading_error() + + def load_pem_parameters(self, data: bytes) -> dh.DHParameters: + return rust_openssl.dh.from_pem_parameters(data) + + def load_der_private_key( + self, + data: bytes, + password: typing.Optional[bytes], + unsafe_skip_rsa_key_validation: bool, + ) -> PrivateKeyTypes: + # OpenSSL has a function called d2i_AutoPrivateKey that in theory + # handles this automatically, however it doesn't handle encrypted + # private keys. Instead we try to load the key two different ways. + # First we'll try to load it as a traditional key. + bio_data = self._bytes_to_bio(data) + key = self._evp_pkey_from_der_traditional_key(bio_data, password) + if key: + return self._evp_pkey_to_private_key( + key, unsafe_skip_rsa_key_validation + ) + else: + # Finally we try to load it with the method that handles encrypted + # PKCS8 properly. + return self._load_key( + self._lib.d2i_PKCS8PrivateKey_bio, + data, + password, + unsafe_skip_rsa_key_validation, + ) + + def _evp_pkey_from_der_traditional_key(self, bio_data, password): + key = self._lib.d2i_PrivateKey_bio(bio_data.bio, self._ffi.NULL) + if key != self._ffi.NULL: + key = self._ffi.gc(key, self._lib.EVP_PKEY_free) + if password is not None: + raise TypeError( + "Password was given but private key is not encrypted." + ) + + return key + else: + self._consume_errors() + return None + + def load_der_public_key(self, data: bytes) -> PublicKeyTypes: + mem_bio = self._bytes_to_bio(data) + evp_pkey = self._lib.d2i_PUBKEY_bio(mem_bio.bio, self._ffi.NULL) + if evp_pkey != self._ffi.NULL: + evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + return self._evp_pkey_to_public_key(evp_pkey) + else: + # It's not a (RSA/DSA/ECDSA) subjectPublicKeyInfo, but we still + # need to check to see if it is a pure PKCS1 RSA public key (not + # embedded in a subjectPublicKeyInfo) + self._consume_errors() + res = self._lib.BIO_reset(mem_bio.bio) + self.openssl_assert(res == 1) + rsa_cdata = self._lib.d2i_RSAPublicKey_bio( + mem_bio.bio, self._ffi.NULL + ) + if rsa_cdata != self._ffi.NULL: + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + evp_pkey = self._rsa_cdata_to_evp_pkey(rsa_cdata) + return _RSAPublicKey(self, rsa_cdata, evp_pkey) + else: + self._handle_key_loading_error() + + def load_der_parameters(self, data: bytes) -> dh.DHParameters: + return rust_openssl.dh.from_der_parameters(data) + + def _cert2ossl(self, cert: x509.Certificate) -> typing.Any: + data = cert.public_bytes(serialization.Encoding.DER) + mem_bio = self._bytes_to_bio(data) + x509 = self._lib.d2i_X509_bio(mem_bio.bio, self._ffi.NULL) + self.openssl_assert(x509 != self._ffi.NULL) + x509 = self._ffi.gc(x509, self._lib.X509_free) + return x509 + + def _ossl2cert(self, x509_ptr: typing.Any) -> x509.Certificate: + bio = self._create_mem_bio_gc() + res = self._lib.i2d_X509_bio(bio, x509_ptr) + self.openssl_assert(res == 1) + return x509.load_der_x509_certificate(self._read_mem_bio(bio)) + + def _key2ossl(self, key: PKCS12PrivateKeyTypes) -> typing.Any: + data = key.private_bytes( + serialization.Encoding.DER, + serialization.PrivateFormat.PKCS8, + serialization.NoEncryption(), + ) + mem_bio = self._bytes_to_bio(data) + + evp_pkey = self._lib.d2i_PrivateKey_bio( + mem_bio.bio, + self._ffi.NULL, + ) + self.openssl_assert(evp_pkey != self._ffi.NULL) + return self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + + def _load_key( + self, openssl_read_func, data, password, unsafe_skip_rsa_key_validation + ) -> PrivateKeyTypes: + mem_bio = self._bytes_to_bio(data) + + userdata = self._ffi.new("CRYPTOGRAPHY_PASSWORD_DATA *") + if password is not None: + utils._check_byteslike("password", password) + password_ptr = self._ffi.from_buffer(password) + userdata.password = password_ptr + userdata.length = len(password) + + evp_pkey = openssl_read_func( + mem_bio.bio, + self._ffi.NULL, + self._ffi.addressof( + self._lib._original_lib, "Cryptography_pem_password_cb" + ), + userdata, + ) + + if evp_pkey == self._ffi.NULL: + if userdata.error != 0: + self._consume_errors() + if userdata.error == -1: + raise TypeError( + "Password was not given but private key is encrypted" + ) + else: + assert userdata.error == -2 + raise ValueError( + "Passwords longer than {} bytes are not supported " + "by this backend.".format(userdata.maxsize - 1) + ) + else: + self._handle_key_loading_error() + + evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + + if password is not None and userdata.called == 0: + raise TypeError( + "Password was given but private key is not encrypted." + ) + + assert ( + password is not None and userdata.called == 1 + ) or password is None + + return self._evp_pkey_to_private_key( + evp_pkey, unsafe_skip_rsa_key_validation + ) + + def _handle_key_loading_error(self) -> typing.NoReturn: + errors = self._consume_errors() + + if not errors: + raise ValueError( + "Could not deserialize key data. The data may be in an " + "incorrect format or it may be encrypted with an unsupported " + "algorithm." + ) + + elif ( + errors[0]._lib_reason_match( + self._lib.ERR_LIB_EVP, self._lib.EVP_R_BAD_DECRYPT + ) + or errors[0]._lib_reason_match( + self._lib.ERR_LIB_PKCS12, + self._lib.PKCS12_R_PKCS12_CIPHERFINAL_ERROR, + ) + or ( + self._lib.Cryptography_HAS_PROVIDERS + and errors[0]._lib_reason_match( + self._lib.ERR_LIB_PROV, + self._lib.PROV_R_BAD_DECRYPT, + ) + ) + ): + raise ValueError("Bad decrypt. Incorrect password?") + + elif any( + error._lib_reason_match( + self._lib.ERR_LIB_EVP, + self._lib.EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM, + ) + for error in errors + ): + raise ValueError("Unsupported public key algorithm.") + + else: + raise ValueError( + "Could not deserialize key data. The data may be in an " + "incorrect format, it may be encrypted with an unsupported " + "algorithm, or it may be an unsupported key type (e.g. EC " + "curves with explicit parameters).", + errors, + ) + + def elliptic_curve_supported(self, curve: ec.EllipticCurve) -> bool: + try: + curve_nid = self._elliptic_curve_to_nid(curve) + except UnsupportedAlgorithm: + curve_nid = self._lib.NID_undef + + group = self._lib.EC_GROUP_new_by_curve_name(curve_nid) + + if group == self._ffi.NULL: + self._consume_errors() + return False + else: + self.openssl_assert(curve_nid != self._lib.NID_undef) + self._lib.EC_GROUP_free(group) + return True + + def elliptic_curve_signature_algorithm_supported( + self, + signature_algorithm: ec.EllipticCurveSignatureAlgorithm, + curve: ec.EllipticCurve, + ) -> bool: + # We only support ECDSA right now. + if not isinstance(signature_algorithm, ec.ECDSA): + return False + + return self.elliptic_curve_supported(curve) + + def generate_elliptic_curve_private_key( + self, curve: ec.EllipticCurve + ) -> ec.EllipticCurvePrivateKey: + """ + Generate a new private key on the named curve. + """ + + if self.elliptic_curve_supported(curve): + ec_cdata = self._ec_key_new_by_curve(curve) + + res = self._lib.EC_KEY_generate_key(ec_cdata) + self.openssl_assert(res == 1) + + evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) + + return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) + else: + raise UnsupportedAlgorithm( + f"Backend object does not support {curve.name}.", + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE, + ) + + def load_elliptic_curve_private_numbers( + self, numbers: ec.EllipticCurvePrivateNumbers + ) -> ec.EllipticCurvePrivateKey: + public = numbers.public_numbers + + ec_cdata = self._ec_key_new_by_curve(public.curve) + + private_value = self._ffi.gc( + self._int_to_bn(numbers.private_value), self._lib.BN_clear_free + ) + res = self._lib.EC_KEY_set_private_key(ec_cdata, private_value) + if res != 1: + self._consume_errors() + raise ValueError("Invalid EC key.") + + with self._tmp_bn_ctx() as bn_ctx: + self._ec_key_set_public_key_affine_coordinates( + ec_cdata, public.x, public.y, bn_ctx + ) + # derive the expected public point and compare it to the one we + # just set based on the values we were given. If they don't match + # this isn't a valid key pair. + group = self._lib.EC_KEY_get0_group(ec_cdata) + self.openssl_assert(group != self._ffi.NULL) + set_point = backend._lib.EC_KEY_get0_public_key(ec_cdata) + self.openssl_assert(set_point != self._ffi.NULL) + computed_point = self._lib.EC_POINT_new(group) + self.openssl_assert(computed_point != self._ffi.NULL) + computed_point = self._ffi.gc( + computed_point, self._lib.EC_POINT_free + ) + res = self._lib.EC_POINT_mul( + group, + computed_point, + private_value, + self._ffi.NULL, + self._ffi.NULL, + bn_ctx, + ) + self.openssl_assert(res == 1) + if ( + self._lib.EC_POINT_cmp( + group, set_point, computed_point, bn_ctx + ) + != 0 + ): + raise ValueError("Invalid EC key.") + + evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) + + return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) + + def load_elliptic_curve_public_numbers( + self, numbers: ec.EllipticCurvePublicNumbers + ) -> ec.EllipticCurvePublicKey: + ec_cdata = self._ec_key_new_by_curve(numbers.curve) + with self._tmp_bn_ctx() as bn_ctx: + self._ec_key_set_public_key_affine_coordinates( + ec_cdata, numbers.x, numbers.y, bn_ctx + ) + evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) + + return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) + + def load_elliptic_curve_public_bytes( + self, curve: ec.EllipticCurve, point_bytes: bytes + ) -> ec.EllipticCurvePublicKey: + ec_cdata = self._ec_key_new_by_curve(curve) + group = self._lib.EC_KEY_get0_group(ec_cdata) + self.openssl_assert(group != self._ffi.NULL) + point = self._lib.EC_POINT_new(group) + self.openssl_assert(point != self._ffi.NULL) + point = self._ffi.gc(point, self._lib.EC_POINT_free) + with self._tmp_bn_ctx() as bn_ctx: + res = self._lib.EC_POINT_oct2point( + group, point, point_bytes, len(point_bytes), bn_ctx + ) + if res != 1: + self._consume_errors() + raise ValueError("Invalid public bytes for the given curve") + + res = self._lib.EC_KEY_set_public_key(ec_cdata, point) + self.openssl_assert(res == 1) + evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) + return _EllipticCurvePublicKey(self, ec_cdata, evp_pkey) + + def derive_elliptic_curve_private_key( + self, private_value: int, curve: ec.EllipticCurve + ) -> ec.EllipticCurvePrivateKey: + ec_cdata = self._ec_key_new_by_curve(curve) + + group = self._lib.EC_KEY_get0_group(ec_cdata) + self.openssl_assert(group != self._ffi.NULL) + + point = self._lib.EC_POINT_new(group) + self.openssl_assert(point != self._ffi.NULL) + point = self._ffi.gc(point, self._lib.EC_POINT_free) + + value = self._int_to_bn(private_value) + value = self._ffi.gc(value, self._lib.BN_clear_free) + + with self._tmp_bn_ctx() as bn_ctx: + res = self._lib.EC_POINT_mul( + group, point, value, self._ffi.NULL, self._ffi.NULL, bn_ctx + ) + self.openssl_assert(res == 1) + + bn_x = self._lib.BN_CTX_get(bn_ctx) + bn_y = self._lib.BN_CTX_get(bn_ctx) + + res = self._lib.EC_POINT_get_affine_coordinates( + group, point, bn_x, bn_y, bn_ctx + ) + if res != 1: + self._consume_errors() + raise ValueError("Unable to derive key from private_value") + + res = self._lib.EC_KEY_set_public_key(ec_cdata, point) + self.openssl_assert(res == 1) + private = self._int_to_bn(private_value) + private = self._ffi.gc(private, self._lib.BN_clear_free) + res = self._lib.EC_KEY_set_private_key(ec_cdata, private) + self.openssl_assert(res == 1) + + evp_pkey = self._ec_cdata_to_evp_pkey(ec_cdata) + + return _EllipticCurvePrivateKey(self, ec_cdata, evp_pkey) + + def _ec_key_new_by_curve(self, curve: ec.EllipticCurve): + curve_nid = self._elliptic_curve_to_nid(curve) + return self._ec_key_new_by_curve_nid(curve_nid) + + def _ec_key_new_by_curve_nid(self, curve_nid: int): + ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) + self.openssl_assert(ec_cdata != self._ffi.NULL) + return self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) + + def elliptic_curve_exchange_algorithm_supported( + self, algorithm: ec.ECDH, curve: ec.EllipticCurve + ) -> bool: + if self._fips_enabled and not isinstance( + curve, self._fips_ecdh_curves + ): + return False + + return self.elliptic_curve_supported(curve) and isinstance( + algorithm, ec.ECDH + ) + + def _ec_cdata_to_evp_pkey(self, ec_cdata): + evp_pkey = self._create_evp_pkey_gc() + res = self._lib.EVP_PKEY_set1_EC_KEY(evp_pkey, ec_cdata) + self.openssl_assert(res == 1) + return evp_pkey + + def _elliptic_curve_to_nid(self, curve: ec.EllipticCurve) -> int: + """ + Get the NID for a curve name. + """ + + curve_aliases = {"secp192r1": "prime192v1", "secp256r1": "prime256v1"} + + curve_name = curve_aliases.get(curve.name, curve.name) + + curve_nid = self._lib.OBJ_sn2nid(curve_name.encode()) + if curve_nid == self._lib.NID_undef: + raise UnsupportedAlgorithm( + f"{curve.name} is not a supported elliptic curve", + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE, + ) + return curve_nid + + @contextmanager + def _tmp_bn_ctx(self): + bn_ctx = self._lib.BN_CTX_new() + self.openssl_assert(bn_ctx != self._ffi.NULL) + bn_ctx = self._ffi.gc(bn_ctx, self._lib.BN_CTX_free) + self._lib.BN_CTX_start(bn_ctx) + try: + yield bn_ctx + finally: + self._lib.BN_CTX_end(bn_ctx) + + def _ec_key_set_public_key_affine_coordinates( + self, + ec_cdata, + x: int, + y: int, + bn_ctx, + ) -> None: + """ + Sets the public key point in the EC_KEY context to the affine x and y + values. + """ + + if x < 0 or y < 0: + raise ValueError( + "Invalid EC key. Both x and y must be non-negative." + ) + + x = self._ffi.gc(self._int_to_bn(x), self._lib.BN_free) + y = self._ffi.gc(self._int_to_bn(y), self._lib.BN_free) + group = self._lib.EC_KEY_get0_group(ec_cdata) + self.openssl_assert(group != self._ffi.NULL) + point = self._lib.EC_POINT_new(group) + self.openssl_assert(point != self._ffi.NULL) + point = self._ffi.gc(point, self._lib.EC_POINT_free) + res = self._lib.EC_POINT_set_affine_coordinates( + group, point, x, y, bn_ctx + ) + if res != 1: + self._consume_errors() + raise ValueError("Invalid EC key.") + res = self._lib.EC_KEY_set_public_key(ec_cdata, point) + self.openssl_assert(res == 1) + + def _private_key_bytes( + self, + encoding: serialization.Encoding, + format: serialization.PrivateFormat, + encryption_algorithm: serialization.KeySerializationEncryption, + key, + evp_pkey, + cdata, + ) -> bytes: + # validate argument types + if not isinstance(encoding, serialization.Encoding): + raise TypeError("encoding must be an item from the Encoding enum") + if not isinstance(format, serialization.PrivateFormat): + raise TypeError( + "format must be an item from the PrivateFormat enum" + ) + if not isinstance( + encryption_algorithm, serialization.KeySerializationEncryption + ): + raise TypeError( + "Encryption algorithm must be a KeySerializationEncryption " + "instance" + ) + + # validate password + if isinstance(encryption_algorithm, serialization.NoEncryption): + password = b"" + elif isinstance( + encryption_algorithm, serialization.BestAvailableEncryption + ): + password = encryption_algorithm.password + if len(password) > 1023: + raise ValueError( + "Passwords longer than 1023 bytes are not supported by " + "this backend" + ) + elif ( + isinstance( + encryption_algorithm, serialization._KeySerializationEncryption + ) + and encryption_algorithm._format + is format + is serialization.PrivateFormat.OpenSSH + ): + password = encryption_algorithm.password + else: + raise ValueError("Unsupported encryption type") + + # PKCS8 + PEM/DER + if format is serialization.PrivateFormat.PKCS8: + if encoding is serialization.Encoding.PEM: + write_bio = self._lib.PEM_write_bio_PKCS8PrivateKey + elif encoding is serialization.Encoding.DER: + write_bio = self._lib.i2d_PKCS8PrivateKey_bio + else: + raise ValueError("Unsupported encoding for PKCS8") + return self._private_key_bytes_via_bio( + write_bio, evp_pkey, password + ) + + # TraditionalOpenSSL + PEM/DER + if format is serialization.PrivateFormat.TraditionalOpenSSL: + if self._fips_enabled and not isinstance( + encryption_algorithm, serialization.NoEncryption + ): + raise ValueError( + "Encrypted traditional OpenSSL format is not " + "supported in FIPS mode." + ) + key_type = self._lib.EVP_PKEY_id(evp_pkey) + + if encoding is serialization.Encoding.PEM: + if key_type == self._lib.EVP_PKEY_RSA: + write_bio = self._lib.PEM_write_bio_RSAPrivateKey + else: + assert key_type == self._lib.EVP_PKEY_EC + write_bio = self._lib.PEM_write_bio_ECPrivateKey + return self._private_key_bytes_via_bio( + write_bio, cdata, password + ) + + if encoding is serialization.Encoding.DER: + if password: + raise ValueError( + "Encryption is not supported for DER encoded " + "traditional OpenSSL keys" + ) + if key_type == self._lib.EVP_PKEY_RSA: + write_bio = self._lib.i2d_RSAPrivateKey_bio + else: + assert key_type == self._lib.EVP_PKEY_EC + write_bio = self._lib.i2d_ECPrivateKey_bio + return self._bio_func_output(write_bio, cdata) + + raise ValueError("Unsupported encoding for TraditionalOpenSSL") + + # OpenSSH + PEM + if format is serialization.PrivateFormat.OpenSSH: + if encoding is serialization.Encoding.PEM: + return ssh._serialize_ssh_private_key( + key, password, encryption_algorithm + ) + + raise ValueError( + "OpenSSH private key format can only be used" + " with PEM encoding" + ) + + # Anything that key-specific code was supposed to handle earlier, + # like Raw. + raise ValueError("format is invalid with this key") + + def _private_key_bytes_via_bio( + self, write_bio, evp_pkey, password + ) -> bytes: + if not password: + evp_cipher = self._ffi.NULL + else: + # This is a curated value that we will update over time. + evp_cipher = self._lib.EVP_get_cipherbyname(b"aes-256-cbc") + + return self._bio_func_output( + write_bio, + evp_pkey, + evp_cipher, + password, + len(password), + self._ffi.NULL, + self._ffi.NULL, + ) + + def _bio_func_output(self, write_bio, *args) -> bytes: + bio = self._create_mem_bio_gc() + res = write_bio(bio, *args) + self.openssl_assert(res == 1) + return self._read_mem_bio(bio) + + def _public_key_bytes( + self, + encoding: serialization.Encoding, + format: serialization.PublicFormat, + key, + evp_pkey, + cdata, + ) -> bytes: + if not isinstance(encoding, serialization.Encoding): + raise TypeError("encoding must be an item from the Encoding enum") + if not isinstance(format, serialization.PublicFormat): + raise TypeError( + "format must be an item from the PublicFormat enum" + ) + + # SubjectPublicKeyInfo + PEM/DER + if format is serialization.PublicFormat.SubjectPublicKeyInfo: + if encoding is serialization.Encoding.PEM: + write_bio = self._lib.PEM_write_bio_PUBKEY + elif encoding is serialization.Encoding.DER: + write_bio = self._lib.i2d_PUBKEY_bio + else: + raise ValueError( + "SubjectPublicKeyInfo works only with PEM or DER encoding" + ) + return self._bio_func_output(write_bio, evp_pkey) + + # PKCS1 + PEM/DER + if format is serialization.PublicFormat.PKCS1: + # Only RSA is supported here. + key_type = self._lib.EVP_PKEY_id(evp_pkey) + if key_type != self._lib.EVP_PKEY_RSA: + raise ValueError("PKCS1 format is supported only for RSA keys") + + if encoding is serialization.Encoding.PEM: + write_bio = self._lib.PEM_write_bio_RSAPublicKey + elif encoding is serialization.Encoding.DER: + write_bio = self._lib.i2d_RSAPublicKey_bio + else: + raise ValueError("PKCS1 works only with PEM or DER encoding") + return self._bio_func_output(write_bio, cdata) + + # OpenSSH + OpenSSH + if format is serialization.PublicFormat.OpenSSH: + if encoding is serialization.Encoding.OpenSSH: + return ssh.serialize_ssh_public_key(key) + + raise ValueError( + "OpenSSH format must be used with OpenSSH encoding" + ) + + # Anything that key-specific code was supposed to handle earlier, + # like Raw, CompressedPoint, UncompressedPoint + raise ValueError("format is invalid with this key") + + def dh_supported(self) -> bool: + return not self._lib.CRYPTOGRAPHY_IS_BORINGSSL + + def generate_dh_parameters( + self, generator: int, key_size: int + ) -> dh.DHParameters: + return rust_openssl.dh.generate_parameters(generator, key_size) + + def generate_dh_private_key( + self, parameters: dh.DHParameters + ) -> dh.DHPrivateKey: + return parameters.generate_private_key() + + def generate_dh_private_key_and_parameters( + self, generator: int, key_size: int + ) -> dh.DHPrivateKey: + return self.generate_dh_private_key( + self.generate_dh_parameters(generator, key_size) + ) + + def load_dh_private_numbers( + self, numbers: dh.DHPrivateNumbers + ) -> dh.DHPrivateKey: + return rust_openssl.dh.from_private_numbers(numbers) + + def load_dh_public_numbers( + self, numbers: dh.DHPublicNumbers + ) -> dh.DHPublicKey: + return rust_openssl.dh.from_public_numbers(numbers) + + def load_dh_parameter_numbers( + self, numbers: dh.DHParameterNumbers + ) -> dh.DHParameters: + return rust_openssl.dh.from_parameter_numbers(numbers) + + def dh_parameters_supported( + self, p: int, g: int, q: typing.Optional[int] = None + ) -> bool: + try: + rust_openssl.dh.from_parameter_numbers( + dh.DHParameterNumbers(p=p, g=g, q=q) + ) + except ValueError: + return False + else: + return True + + def dh_x942_serialization_supported(self) -> bool: + return self._lib.Cryptography_HAS_EVP_PKEY_DHX == 1 + + def x25519_load_public_bytes(self, data: bytes) -> x25519.X25519PublicKey: + return rust_openssl.x25519.from_public_bytes(data) + + def x25519_load_private_bytes( + self, data: bytes + ) -> x25519.X25519PrivateKey: + return rust_openssl.x25519.from_private_bytes(data) + + def x25519_generate_key(self) -> x25519.X25519PrivateKey: + return rust_openssl.x25519.generate_key() + + def x25519_supported(self) -> bool: + if self._fips_enabled: + return False + return not self._lib.CRYPTOGRAPHY_LIBRESSL_LESS_THAN_370 + + def x448_load_public_bytes(self, data: bytes) -> x448.X448PublicKey: + return rust_openssl.x448.from_public_bytes(data) + + def x448_load_private_bytes(self, data: bytes) -> x448.X448PrivateKey: + return rust_openssl.x448.from_private_bytes(data) + + def x448_generate_key(self) -> x448.X448PrivateKey: + return rust_openssl.x448.generate_key() + + def x448_supported(self) -> bool: + if self._fips_enabled: + return False + return ( + not self._lib.CRYPTOGRAPHY_IS_LIBRESSL + and not self._lib.CRYPTOGRAPHY_IS_BORINGSSL + ) + + def ed25519_supported(self) -> bool: + if self._fips_enabled: + return False + return self._lib.CRYPTOGRAPHY_HAS_WORKING_ED25519 + + def ed25519_load_public_bytes( + self, data: bytes + ) -> ed25519.Ed25519PublicKey: + return rust_openssl.ed25519.from_public_bytes(data) + + def ed25519_load_private_bytes( + self, data: bytes + ) -> ed25519.Ed25519PrivateKey: + return rust_openssl.ed25519.from_private_bytes(data) + + def ed25519_generate_key(self) -> ed25519.Ed25519PrivateKey: + return rust_openssl.ed25519.generate_key() + + def ed448_supported(self) -> bool: + if self._fips_enabled: + return False + return ( + not self._lib.CRYPTOGRAPHY_IS_LIBRESSL + and not self._lib.CRYPTOGRAPHY_IS_BORINGSSL + ) + + def ed448_load_public_bytes(self, data: bytes) -> ed448.Ed448PublicKey: + return rust_openssl.ed448.from_public_bytes(data) + + def ed448_load_private_bytes(self, data: bytes) -> ed448.Ed448PrivateKey: + return rust_openssl.ed448.from_private_bytes(data) + + def ed448_generate_key(self) -> ed448.Ed448PrivateKey: + return rust_openssl.ed448.generate_key() + + def aead_cipher_supported(self, cipher) -> bool: + return aead._aead_cipher_supported(self, cipher) + + def _zero_data(self, data, length: int) -> None: + # We clear things this way because at the moment we're not + # sure of a better way that can guarantee it overwrites the + # memory of a bytearray and doesn't just replace the underlying char *. + for i in range(length): + data[i] = 0 + + @contextlib.contextmanager + def _zeroed_null_terminated_buf(self, data): + """ + This method takes bytes, which can be a bytestring or a mutable + buffer like a bytearray, and yields a null-terminated version of that + data. This is required because PKCS12_parse doesn't take a length with + its password char * and ffi.from_buffer doesn't provide null + termination. So, to support zeroing the data via bytearray we + need to build this ridiculous construct that copies the memory, but + zeroes it after use. + """ + if data is None: + yield self._ffi.NULL + else: + data_len = len(data) + buf = self._ffi.new("char[]", data_len + 1) + self._ffi.memmove(buf, data, data_len) + try: + yield buf + finally: + # Cast to a uint8_t * so we can assign by integer + self._zero_data(self._ffi.cast("uint8_t *", buf), data_len) + + def load_key_and_certificates_from_pkcs12( + self, data: bytes, password: typing.Optional[bytes] + ) -> typing.Tuple[ + typing.Optional[PrivateKeyTypes], + typing.Optional[x509.Certificate], + typing.List[x509.Certificate], + ]: + pkcs12 = self.load_pkcs12(data, password) + return ( + pkcs12.key, + pkcs12.cert.certificate if pkcs12.cert else None, + [cert.certificate for cert in pkcs12.additional_certs], + ) + + def load_pkcs12( + self, data: bytes, password: typing.Optional[bytes] + ) -> PKCS12KeyAndCertificates: + if password is not None: + utils._check_byteslike("password", password) + + bio = self._bytes_to_bio(data) + p12 = self._lib.d2i_PKCS12_bio(bio.bio, self._ffi.NULL) + if p12 == self._ffi.NULL: + self._consume_errors() + raise ValueError("Could not deserialize PKCS12 data") + + p12 = self._ffi.gc(p12, self._lib.PKCS12_free) + evp_pkey_ptr = self._ffi.new("EVP_PKEY **") + x509_ptr = self._ffi.new("X509 **") + sk_x509_ptr = self._ffi.new("Cryptography_STACK_OF_X509 **") + with self._zeroed_null_terminated_buf(password) as password_buf: + res = self._lib.PKCS12_parse( + p12, password_buf, evp_pkey_ptr, x509_ptr, sk_x509_ptr + ) + if res == 0: + self._consume_errors() + raise ValueError("Invalid password or PKCS12 data") + + cert = None + key = None + additional_certificates = [] + + if evp_pkey_ptr[0] != self._ffi.NULL: + evp_pkey = self._ffi.gc(evp_pkey_ptr[0], self._lib.EVP_PKEY_free) + # We don't support turning off RSA key validation when loading + # PKCS12 keys + key = self._evp_pkey_to_private_key( + evp_pkey, unsafe_skip_rsa_key_validation=False + ) + + if x509_ptr[0] != self._ffi.NULL: + x509 = self._ffi.gc(x509_ptr[0], self._lib.X509_free) + cert_obj = self._ossl2cert(x509) + name = None + maybe_name = self._lib.X509_alias_get0(x509, self._ffi.NULL) + if maybe_name != self._ffi.NULL: + name = self._ffi.string(maybe_name) + cert = PKCS12Certificate(cert_obj, name) + + if sk_x509_ptr[0] != self._ffi.NULL: + sk_x509 = self._ffi.gc(sk_x509_ptr[0], self._lib.sk_X509_free) + num = self._lib.sk_X509_num(sk_x509_ptr[0]) + + # In OpenSSL < 3.0.0 PKCS12 parsing reverses the order of the + # certificates. + indices: typing.Iterable[int] + if ( + self._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER + or self._lib.CRYPTOGRAPHY_IS_BORINGSSL + ): + indices = range(num) + else: + indices = reversed(range(num)) + + for i in indices: + x509 = self._lib.sk_X509_value(sk_x509, i) + self.openssl_assert(x509 != self._ffi.NULL) + x509 = self._ffi.gc(x509, self._lib.X509_free) + addl_cert = self._ossl2cert(x509) + addl_name = None + maybe_name = self._lib.X509_alias_get0(x509, self._ffi.NULL) + if maybe_name != self._ffi.NULL: + addl_name = self._ffi.string(maybe_name) + additional_certificates.append( + PKCS12Certificate(addl_cert, addl_name) + ) + + return PKCS12KeyAndCertificates(key, cert, additional_certificates) + + def serialize_key_and_certificates_to_pkcs12( + self, + name: typing.Optional[bytes], + key: typing.Optional[PKCS12PrivateKeyTypes], + cert: typing.Optional[x509.Certificate], + cas: typing.Optional[typing.List[_PKCS12CATypes]], + encryption_algorithm: serialization.KeySerializationEncryption, + ) -> bytes: + password = None + if name is not None: + utils._check_bytes("name", name) + + if isinstance(encryption_algorithm, serialization.NoEncryption): + nid_cert = -1 + nid_key = -1 + pkcs12_iter = 0 + mac_iter = 0 + mac_alg = self._ffi.NULL + elif isinstance( + encryption_algorithm, serialization.BestAvailableEncryption + ): + # PKCS12 encryption is hopeless trash and can never be fixed. + # OpenSSL 3 supports PBESv2, but Libre and Boring do not, so + # we use PBESv1 with 3DES on the older paths. + if self._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER: + nid_cert = self._lib.NID_aes_256_cbc + nid_key = self._lib.NID_aes_256_cbc + else: + nid_cert = self._lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC + nid_key = self._lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC + # At least we can set this higher than OpenSSL's default + pkcs12_iter = 20000 + # mac_iter chosen for compatibility reasons, see: + # https://www.openssl.org/docs/man1.1.1/man3/PKCS12_create.html + # Did we mention how lousy PKCS12 encryption is? + mac_iter = 1 + # MAC algorithm can only be set on OpenSSL 3.0.0+ + mac_alg = self._ffi.NULL + password = encryption_algorithm.password + elif ( + isinstance( + encryption_algorithm, serialization._KeySerializationEncryption + ) + and encryption_algorithm._format + is serialization.PrivateFormat.PKCS12 + ): + # Default to OpenSSL's defaults. Behavior will vary based on the + # version of OpenSSL cryptography is compiled against. + nid_cert = 0 + nid_key = 0 + # Use the default iters we use in best available + pkcs12_iter = 20000 + # See the Best Available comment for why this is 1 + mac_iter = 1 + password = encryption_algorithm.password + keycertalg = encryption_algorithm._key_cert_algorithm + if keycertalg is PBES.PBESv1SHA1And3KeyTripleDESCBC: + nid_cert = self._lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC + nid_key = self._lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC + elif keycertalg is PBES.PBESv2SHA256AndAES256CBC: + if not self._lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER: + raise UnsupportedAlgorithm( + "PBESv2 is not supported by this version of OpenSSL" + ) + nid_cert = self._lib.NID_aes_256_cbc + nid_key = self._lib.NID_aes_256_cbc + else: + assert keycertalg is None + # We use OpenSSL's defaults + + if encryption_algorithm._hmac_hash is not None: + if not self._lib.Cryptography_HAS_PKCS12_SET_MAC: + raise UnsupportedAlgorithm( + "Setting MAC algorithm is not supported by this " + "version of OpenSSL." + ) + mac_alg = self._evp_md_non_null_from_algorithm( + encryption_algorithm._hmac_hash + ) + self.openssl_assert(mac_alg != self._ffi.NULL) + else: + mac_alg = self._ffi.NULL + + if encryption_algorithm._kdf_rounds is not None: + pkcs12_iter = encryption_algorithm._kdf_rounds + + else: + raise ValueError("Unsupported key encryption type") + + if cas is None or len(cas) == 0: + sk_x509 = self._ffi.NULL + else: + sk_x509 = self._lib.sk_X509_new_null() + sk_x509 = self._ffi.gc(sk_x509, self._lib.sk_X509_free) + + # This list is to keep the x509 values alive until end of function + ossl_cas = [] + for ca in cas: + if isinstance(ca, PKCS12Certificate): + ca_alias = ca.friendly_name + ossl_ca = self._cert2ossl(ca.certificate) + if ca_alias is None: + res = self._lib.X509_alias_set1( + ossl_ca, self._ffi.NULL, -1 + ) + else: + res = self._lib.X509_alias_set1( + ossl_ca, ca_alias, len(ca_alias) + ) + self.openssl_assert(res == 1) + else: + ossl_ca = self._cert2ossl(ca) + ossl_cas.append(ossl_ca) + res = self._lib.sk_X509_push(sk_x509, ossl_ca) + backend.openssl_assert(res >= 1) + + with self._zeroed_null_terminated_buf(password) as password_buf: + with self._zeroed_null_terminated_buf(name) as name_buf: + ossl_cert = self._cert2ossl(cert) if cert else self._ffi.NULL + ossl_pkey = ( + self._key2ossl(key) if key is not None else self._ffi.NULL + ) + + p12 = self._lib.PKCS12_create( + password_buf, + name_buf, + ossl_pkey, + ossl_cert, + sk_x509, + nid_key, + nid_cert, + pkcs12_iter, + mac_iter, + 0, + ) + + if ( + self._lib.Cryptography_HAS_PKCS12_SET_MAC + and mac_alg != self._ffi.NULL + ): + self._lib.PKCS12_set_mac( + p12, + password_buf, + -1, + self._ffi.NULL, + 0, + mac_iter, + mac_alg, + ) + + self.openssl_assert(p12 != self._ffi.NULL) + p12 = self._ffi.gc(p12, self._lib.PKCS12_free) + + bio = self._create_mem_bio_gc() + res = self._lib.i2d_PKCS12_bio(bio, p12) + self.openssl_assert(res > 0) + return self._read_mem_bio(bio) + + def poly1305_supported(self) -> bool: + if self._fips_enabled: + return False + return self._lib.Cryptography_HAS_POLY1305 == 1 + + def pkcs7_supported(self) -> bool: + return not self._lib.CRYPTOGRAPHY_IS_BORINGSSL + + def load_pem_pkcs7_certificates( + self, data: bytes + ) -> typing.List[x509.Certificate]: + utils._check_bytes("data", data) + bio = self._bytes_to_bio(data) + p7 = self._lib.PEM_read_bio_PKCS7( + bio.bio, self._ffi.NULL, self._ffi.NULL, self._ffi.NULL + ) + if p7 == self._ffi.NULL: + self._consume_errors() + raise ValueError("Unable to parse PKCS7 data") + + p7 = self._ffi.gc(p7, self._lib.PKCS7_free) + return self._load_pkcs7_certificates(p7) + + def load_der_pkcs7_certificates( + self, data: bytes + ) -> typing.List[x509.Certificate]: + utils._check_bytes("data", data) + bio = self._bytes_to_bio(data) + p7 = self._lib.d2i_PKCS7_bio(bio.bio, self._ffi.NULL) + if p7 == self._ffi.NULL: + self._consume_errors() + raise ValueError("Unable to parse PKCS7 data") + + p7 = self._ffi.gc(p7, self._lib.PKCS7_free) + return self._load_pkcs7_certificates(p7) + + def _load_pkcs7_certificates(self, p7) -> typing.List[x509.Certificate]: + nid = self._lib.OBJ_obj2nid(p7.type) + self.openssl_assert(nid != self._lib.NID_undef) + if nid != self._lib.NID_pkcs7_signed: + raise UnsupportedAlgorithm( + "Only basic signed structures are currently supported. NID" + " for this data was {}".format(nid), + _Reasons.UNSUPPORTED_SERIALIZATION, + ) + + sk_x509 = p7.d.sign.cert + num = self._lib.sk_X509_num(sk_x509) + certs = [] + for i in range(num): + x509 = self._lib.sk_X509_value(sk_x509, i) + self.openssl_assert(x509 != self._ffi.NULL) + cert = self._ossl2cert(x509) + certs.append(cert) + + return certs + + +class GetCipherByName: + def __init__(self, fmt: str): + self._fmt = fmt + + def __call__(self, backend: Backend, cipher: CipherAlgorithm, mode: Mode): + cipher_name = self._fmt.format(cipher=cipher, mode=mode).lower() + evp_cipher = backend._lib.EVP_get_cipherbyname( + cipher_name.encode("ascii") + ) + + # try EVP_CIPHER_fetch if present + if ( + evp_cipher == backend._ffi.NULL + and backend._lib.Cryptography_HAS_300_EVP_CIPHER + ): + evp_cipher = backend._lib.EVP_CIPHER_fetch( + backend._ffi.NULL, + cipher_name.encode("ascii"), + backend._ffi.NULL, + ) + + backend._consume_errors() + return evp_cipher + + +def _get_xts_cipher(backend: Backend, cipher: AES, mode): + cipher_name = f"aes-{cipher.key_size // 2}-xts" + return backend._lib.EVP_get_cipherbyname(cipher_name.encode("ascii")) + + +backend = Backend() diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ciphers.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ciphers.py new file mode 100644 index 0000000..bc42adb --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ciphers.py @@ -0,0 +1,281 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.exceptions import InvalidTag, UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.primitives import ciphers +from cryptography.hazmat.primitives.ciphers import algorithms, modes + +if typing.TYPE_CHECKING: + from cryptography.hazmat.backends.openssl.backend import Backend + + +class _CipherContext: + _ENCRYPT = 1 + _DECRYPT = 0 + _MAX_CHUNK_SIZE = 2**30 - 1 + + def __init__(self, backend: Backend, cipher, mode, operation: int) -> None: + self._backend = backend + self._cipher = cipher + self._mode = mode + self._operation = operation + self._tag: typing.Optional[bytes] = None + + if isinstance(self._cipher, ciphers.BlockCipherAlgorithm): + self._block_size_bytes = self._cipher.block_size // 8 + else: + self._block_size_bytes = 1 + + ctx = self._backend._lib.EVP_CIPHER_CTX_new() + ctx = self._backend._ffi.gc( + ctx, self._backend._lib.EVP_CIPHER_CTX_free + ) + + registry = self._backend._cipher_registry + try: + adapter = registry[type(cipher), type(mode)] + except KeyError: + raise UnsupportedAlgorithm( + "cipher {} in {} mode is not supported " + "by this backend.".format( + cipher.name, mode.name if mode else mode + ), + _Reasons.UNSUPPORTED_CIPHER, + ) + + evp_cipher = adapter(self._backend, cipher, mode) + if evp_cipher == self._backend._ffi.NULL: + msg = f"cipher {cipher.name} " + if mode is not None: + msg += f"in {mode.name} mode " + msg += ( + "is not supported by this backend (Your version of OpenSSL " + "may be too old. Current version: {}.)" + ).format(self._backend.openssl_version_text()) + raise UnsupportedAlgorithm(msg, _Reasons.UNSUPPORTED_CIPHER) + + if isinstance(mode, modes.ModeWithInitializationVector): + iv_nonce = self._backend._ffi.from_buffer( + mode.initialization_vector + ) + elif isinstance(mode, modes.ModeWithTweak): + iv_nonce = self._backend._ffi.from_buffer(mode.tweak) + elif isinstance(mode, modes.ModeWithNonce): + iv_nonce = self._backend._ffi.from_buffer(mode.nonce) + elif isinstance(cipher, algorithms.ChaCha20): + iv_nonce = self._backend._ffi.from_buffer(cipher.nonce) + else: + iv_nonce = self._backend._ffi.NULL + # begin init with cipher and operation type + res = self._backend._lib.EVP_CipherInit_ex( + ctx, + evp_cipher, + self._backend._ffi.NULL, + self._backend._ffi.NULL, + self._backend._ffi.NULL, + operation, + ) + self._backend.openssl_assert(res != 0) + # set the key length to handle variable key ciphers + res = self._backend._lib.EVP_CIPHER_CTX_set_key_length( + ctx, len(cipher.key) + ) + self._backend.openssl_assert(res != 0) + if isinstance(mode, modes.GCM): + res = self._backend._lib.EVP_CIPHER_CTX_ctrl( + ctx, + self._backend._lib.EVP_CTRL_AEAD_SET_IVLEN, + len(iv_nonce), + self._backend._ffi.NULL, + ) + self._backend.openssl_assert(res != 0) + if mode.tag is not None: + res = self._backend._lib.EVP_CIPHER_CTX_ctrl( + ctx, + self._backend._lib.EVP_CTRL_AEAD_SET_TAG, + len(mode.tag), + mode.tag, + ) + self._backend.openssl_assert(res != 0) + self._tag = mode.tag + + # pass key/iv + res = self._backend._lib.EVP_CipherInit_ex( + ctx, + self._backend._ffi.NULL, + self._backend._ffi.NULL, + self._backend._ffi.from_buffer(cipher.key), + iv_nonce, + operation, + ) + + # Check for XTS mode duplicate keys error + errors = self._backend._consume_errors() + lib = self._backend._lib + if res == 0 and ( + ( + not lib.CRYPTOGRAPHY_IS_LIBRESSL + and errors[0]._lib_reason_match( + lib.ERR_LIB_EVP, lib.EVP_R_XTS_DUPLICATED_KEYS + ) + ) + or ( + lib.Cryptography_HAS_PROVIDERS + and errors[0]._lib_reason_match( + lib.ERR_LIB_PROV, lib.PROV_R_XTS_DUPLICATED_KEYS + ) + ) + ): + raise ValueError("In XTS mode duplicated keys are not allowed") + + self._backend.openssl_assert(res != 0, errors=errors) + + # We purposely disable padding here as it's handled higher up in the + # API. + self._backend._lib.EVP_CIPHER_CTX_set_padding(ctx, 0) + self._ctx = ctx + + def update(self, data: bytes) -> bytes: + buf = bytearray(len(data) + self._block_size_bytes - 1) + n = self.update_into(data, buf) + return bytes(buf[:n]) + + def update_into(self, data: bytes, buf: bytes) -> int: + total_data_len = len(data) + if len(buf) < (total_data_len + self._block_size_bytes - 1): + raise ValueError( + "buffer must be at least {} bytes for this " + "payload".format(len(data) + self._block_size_bytes - 1) + ) + + data_processed = 0 + total_out = 0 + outlen = self._backend._ffi.new("int *") + baseoutbuf = self._backend._ffi.from_buffer(buf, require_writable=True) + baseinbuf = self._backend._ffi.from_buffer(data) + + while data_processed != total_data_len: + outbuf = baseoutbuf + total_out + inbuf = baseinbuf + data_processed + inlen = min(self._MAX_CHUNK_SIZE, total_data_len - data_processed) + + res = self._backend._lib.EVP_CipherUpdate( + self._ctx, outbuf, outlen, inbuf, inlen + ) + if res == 0 and isinstance(self._mode, modes.XTS): + self._backend._consume_errors() + raise ValueError( + "In XTS mode you must supply at least a full block in the " + "first update call. For AES this is 16 bytes." + ) + else: + self._backend.openssl_assert(res != 0) + data_processed += inlen + total_out += outlen[0] + + return total_out + + def finalize(self) -> bytes: + if ( + self._operation == self._DECRYPT + and isinstance(self._mode, modes.ModeWithAuthenticationTag) + and self.tag is None + ): + raise ValueError( + "Authentication tag must be provided when decrypting." + ) + + buf = self._backend._ffi.new("unsigned char[]", self._block_size_bytes) + outlen = self._backend._ffi.new("int *") + res = self._backend._lib.EVP_CipherFinal_ex(self._ctx, buf, outlen) + if res == 0: + errors = self._backend._consume_errors() + + if not errors and isinstance(self._mode, modes.GCM): + raise InvalidTag + + lib = self._backend._lib + self._backend.openssl_assert( + errors[0]._lib_reason_match( + lib.ERR_LIB_EVP, + lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH, + ) + or ( + lib.Cryptography_HAS_PROVIDERS + and errors[0]._lib_reason_match( + lib.ERR_LIB_PROV, + lib.PROV_R_WRONG_FINAL_BLOCK_LENGTH, + ) + ) + or ( + lib.CRYPTOGRAPHY_IS_BORINGSSL + and errors[0].reason + == lib.CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH + ), + errors=errors, + ) + raise ValueError( + "The length of the provided data is not a multiple of " + "the block length." + ) + + if ( + isinstance(self._mode, modes.GCM) + and self._operation == self._ENCRYPT + ): + tag_buf = self._backend._ffi.new( + "unsigned char[]", self._block_size_bytes + ) + res = self._backend._lib.EVP_CIPHER_CTX_ctrl( + self._ctx, + self._backend._lib.EVP_CTRL_AEAD_GET_TAG, + self._block_size_bytes, + tag_buf, + ) + self._backend.openssl_assert(res != 0) + self._tag = self._backend._ffi.buffer(tag_buf)[:] + + res = self._backend._lib.EVP_CIPHER_CTX_reset(self._ctx) + self._backend.openssl_assert(res == 1) + return self._backend._ffi.buffer(buf)[: outlen[0]] + + def finalize_with_tag(self, tag: bytes) -> bytes: + tag_len = len(tag) + if tag_len < self._mode._min_tag_length: + raise ValueError( + "Authentication tag must be {} bytes or longer.".format( + self._mode._min_tag_length + ) + ) + elif tag_len > self._block_size_bytes: + raise ValueError( + "Authentication tag cannot be more than {} bytes.".format( + self._block_size_bytes + ) + ) + res = self._backend._lib.EVP_CIPHER_CTX_ctrl( + self._ctx, self._backend._lib.EVP_CTRL_AEAD_SET_TAG, len(tag), tag + ) + self._backend.openssl_assert(res != 0) + self._tag = tag + return self.finalize() + + def authenticate_additional_data(self, data: bytes) -> None: + outlen = self._backend._ffi.new("int *") + res = self._backend._lib.EVP_CipherUpdate( + self._ctx, + self._backend._ffi.NULL, + outlen, + self._backend._ffi.from_buffer(data), + len(data), + ) + self._backend.openssl_assert(res != 0) + + @property + def tag(self) -> typing.Optional[bytes]: + return self._tag diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/cmac.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/cmac.py new file mode 100644 index 0000000..bdd7fec --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/cmac.py @@ -0,0 +1,89 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.exceptions import ( + InvalidSignature, + UnsupportedAlgorithm, + _Reasons, +) +from cryptography.hazmat.primitives import constant_time +from cryptography.hazmat.primitives.ciphers.modes import CBC + +if typing.TYPE_CHECKING: + from cryptography.hazmat.backends.openssl.backend import Backend + from cryptography.hazmat.primitives import ciphers + + +class _CMACContext: + def __init__( + self, + backend: Backend, + algorithm: ciphers.BlockCipherAlgorithm, + ctx=None, + ) -> None: + if not backend.cmac_algorithm_supported(algorithm): + raise UnsupportedAlgorithm( + "This backend does not support CMAC.", + _Reasons.UNSUPPORTED_CIPHER, + ) + + self._backend = backend + self._key = algorithm.key + self._algorithm = algorithm + self._output_length = algorithm.block_size // 8 + + if ctx is None: + registry = self._backend._cipher_registry + adapter = registry[type(algorithm), CBC] + + evp_cipher = adapter(self._backend, algorithm, CBC) + + ctx = self._backend._lib.CMAC_CTX_new() + + self._backend.openssl_assert(ctx != self._backend._ffi.NULL) + ctx = self._backend._ffi.gc(ctx, self._backend._lib.CMAC_CTX_free) + + key_ptr = self._backend._ffi.from_buffer(self._key) + res = self._backend._lib.CMAC_Init( + ctx, + key_ptr, + len(self._key), + evp_cipher, + self._backend._ffi.NULL, + ) + self._backend.openssl_assert(res == 1) + + self._ctx = ctx + + def update(self, data: bytes) -> None: + res = self._backend._lib.CMAC_Update(self._ctx, data, len(data)) + self._backend.openssl_assert(res == 1) + + def finalize(self) -> bytes: + buf = self._backend._ffi.new("unsigned char[]", self._output_length) + length = self._backend._ffi.new("size_t *", self._output_length) + res = self._backend._lib.CMAC_Final(self._ctx, buf, length) + self._backend.openssl_assert(res == 1) + + self._ctx = None + + return self._backend._ffi.buffer(buf)[:] + + def copy(self) -> _CMACContext: + copied_ctx = self._backend._lib.CMAC_CTX_new() + copied_ctx = self._backend._ffi.gc( + copied_ctx, self._backend._lib.CMAC_CTX_free + ) + res = self._backend._lib.CMAC_CTX_copy(copied_ctx, self._ctx) + self._backend.openssl_assert(res == 1) + return _CMACContext(self._backend, self._algorithm, ctx=copied_ctx) + + def verify(self, signature: bytes) -> None: + digest = self.finalize() + if not constant_time.bytes_eq(digest, signature): + raise InvalidSignature("Signature did not match digest.") diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/decode_asn1.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/decode_asn1.py new file mode 100644 index 0000000..bf123b6 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/decode_asn1.py @@ -0,0 +1,32 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography import x509 + +# CRLReason ::= ENUMERATED { +# unspecified (0), +# keyCompromise (1), +# cACompromise (2), +# affiliationChanged (3), +# superseded (4), +# cessationOfOperation (5), +# certificateHold (6), +# -- value 7 is not used +# removeFromCRL (8), +# privilegeWithdrawn (9), +# aACompromise (10) } +_CRL_ENTRY_REASON_ENUM_TO_CODE = { + x509.ReasonFlags.unspecified: 0, + x509.ReasonFlags.key_compromise: 1, + x509.ReasonFlags.ca_compromise: 2, + x509.ReasonFlags.affiliation_changed: 3, + x509.ReasonFlags.superseded: 4, + x509.ReasonFlags.cessation_of_operation: 5, + x509.ReasonFlags.certificate_hold: 6, + x509.ReasonFlags.remove_from_crl: 8, + x509.ReasonFlags.privilege_withdrawn: 9, + x509.ReasonFlags.aa_compromise: 10, +} diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ec.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ec.py new file mode 100644 index 0000000..9821bd1 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/ec.py @@ -0,0 +1,328 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.exceptions import ( + InvalidSignature, + UnsupportedAlgorithm, + _Reasons, +) +from cryptography.hazmat.backends.openssl.utils import ( + _calculate_digest_and_algorithm, + _evp_pkey_derive, +) +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ec + +if typing.TYPE_CHECKING: + from cryptography.hazmat.backends.openssl.backend import Backend + + +def _check_signature_algorithm( + signature_algorithm: ec.EllipticCurveSignatureAlgorithm, +) -> None: + if not isinstance(signature_algorithm, ec.ECDSA): + raise UnsupportedAlgorithm( + "Unsupported elliptic curve signature algorithm.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, + ) + + +def _ec_key_curve_sn(backend: Backend, ec_key) -> str: + group = backend._lib.EC_KEY_get0_group(ec_key) + backend.openssl_assert(group != backend._ffi.NULL) + + nid = backend._lib.EC_GROUP_get_curve_name(group) + # The following check is to find EC keys with unnamed curves and raise + # an error for now. + if nid == backend._lib.NID_undef: + raise ValueError( + "ECDSA keys with explicit parameters are unsupported at this time" + ) + + # This is like the above check, but it also catches the case where you + # explicitly encoded a curve with the same parameters as a named curve. + # Don't do that. + if ( + not backend._lib.CRYPTOGRAPHY_IS_LIBRESSL + and backend._lib.EC_GROUP_get_asn1_flag(group) == 0 + ): + raise ValueError( + "ECDSA keys with explicit parameters are unsupported at this time" + ) + + curve_name = backend._lib.OBJ_nid2sn(nid) + backend.openssl_assert(curve_name != backend._ffi.NULL) + + sn = backend._ffi.string(curve_name).decode("ascii") + return sn + + +def _mark_asn1_named_ec_curve(backend: Backend, ec_cdata): + """ + Set the named curve flag on the EC_KEY. This causes OpenSSL to + serialize EC keys along with their curve OID which makes + deserialization easier. + """ + + backend._lib.EC_KEY_set_asn1_flag( + ec_cdata, backend._lib.OPENSSL_EC_NAMED_CURVE + ) + + +def _check_key_infinity(backend: Backend, ec_cdata) -> None: + point = backend._lib.EC_KEY_get0_public_key(ec_cdata) + backend.openssl_assert(point != backend._ffi.NULL) + group = backend._lib.EC_KEY_get0_group(ec_cdata) + backend.openssl_assert(group != backend._ffi.NULL) + if backend._lib.EC_POINT_is_at_infinity(group, point): + raise ValueError( + "Cannot load an EC public key where the point is at infinity" + ) + + +def _sn_to_elliptic_curve(backend: Backend, sn: str) -> ec.EllipticCurve: + try: + return ec._CURVE_TYPES[sn]() + except KeyError: + raise UnsupportedAlgorithm( + f"{sn} is not a supported elliptic curve", + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE, + ) + + +def _ecdsa_sig_sign( + backend: Backend, private_key: _EllipticCurvePrivateKey, data: bytes +) -> bytes: + max_size = backend._lib.ECDSA_size(private_key._ec_key) + backend.openssl_assert(max_size > 0) + + sigbuf = backend._ffi.new("unsigned char[]", max_size) + siglen_ptr = backend._ffi.new("unsigned int[]", 1) + res = backend._lib.ECDSA_sign( + 0, data, len(data), sigbuf, siglen_ptr, private_key._ec_key + ) + backend.openssl_assert(res == 1) + return backend._ffi.buffer(sigbuf)[: siglen_ptr[0]] + + +def _ecdsa_sig_verify( + backend: Backend, + public_key: _EllipticCurvePublicKey, + signature: bytes, + data: bytes, +) -> None: + res = backend._lib.ECDSA_verify( + 0, data, len(data), signature, len(signature), public_key._ec_key + ) + if res != 1: + backend._consume_errors() + raise InvalidSignature + + +class _EllipticCurvePrivateKey(ec.EllipticCurvePrivateKey): + def __init__(self, backend: Backend, ec_key_cdata, evp_pkey): + self._backend = backend + self._ec_key = ec_key_cdata + self._evp_pkey = evp_pkey + + sn = _ec_key_curve_sn(backend, ec_key_cdata) + self._curve = _sn_to_elliptic_curve(backend, sn) + _mark_asn1_named_ec_curve(backend, ec_key_cdata) + _check_key_infinity(backend, ec_key_cdata) + + @property + def curve(self) -> ec.EllipticCurve: + return self._curve + + @property + def key_size(self) -> int: + return self.curve.key_size + + def exchange( + self, algorithm: ec.ECDH, peer_public_key: ec.EllipticCurvePublicKey + ) -> bytes: + if not ( + self._backend.elliptic_curve_exchange_algorithm_supported( + algorithm, self.curve + ) + ): + raise UnsupportedAlgorithm( + "This backend does not support the ECDH algorithm.", + _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, + ) + + if peer_public_key.curve.name != self.curve.name: + raise ValueError( + "peer_public_key and self are not on the same curve" + ) + + return _evp_pkey_derive(self._backend, self._evp_pkey, peer_public_key) + + def public_key(self) -> ec.EllipticCurvePublicKey: + group = self._backend._lib.EC_KEY_get0_group(self._ec_key) + self._backend.openssl_assert(group != self._backend._ffi.NULL) + + curve_nid = self._backend._lib.EC_GROUP_get_curve_name(group) + public_ec_key = self._backend._ec_key_new_by_curve_nid(curve_nid) + + point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) + self._backend.openssl_assert(point != self._backend._ffi.NULL) + + res = self._backend._lib.EC_KEY_set_public_key(public_ec_key, point) + self._backend.openssl_assert(res == 1) + + evp_pkey = self._backend._ec_cdata_to_evp_pkey(public_ec_key) + + return _EllipticCurvePublicKey(self._backend, public_ec_key, evp_pkey) + + def private_numbers(self) -> ec.EllipticCurvePrivateNumbers: + bn = self._backend._lib.EC_KEY_get0_private_key(self._ec_key) + private_value = self._backend._bn_to_int(bn) + return ec.EllipticCurvePrivateNumbers( + private_value=private_value, + public_numbers=self.public_key().public_numbers(), + ) + + def private_bytes( + self, + encoding: serialization.Encoding, + format: serialization.PrivateFormat, + encryption_algorithm: serialization.KeySerializationEncryption, + ) -> bytes: + return self._backend._private_key_bytes( + encoding, + format, + encryption_algorithm, + self, + self._evp_pkey, + self._ec_key, + ) + + def sign( + self, + data: bytes, + signature_algorithm: ec.EllipticCurveSignatureAlgorithm, + ) -> bytes: + _check_signature_algorithm(signature_algorithm) + data, _ = _calculate_digest_and_algorithm( + data, + signature_algorithm.algorithm, + ) + return _ecdsa_sig_sign(self._backend, self, data) + + +class _EllipticCurvePublicKey(ec.EllipticCurvePublicKey): + def __init__(self, backend: Backend, ec_key_cdata, evp_pkey): + self._backend = backend + self._ec_key = ec_key_cdata + self._evp_pkey = evp_pkey + + sn = _ec_key_curve_sn(backend, ec_key_cdata) + self._curve = _sn_to_elliptic_curve(backend, sn) + _mark_asn1_named_ec_curve(backend, ec_key_cdata) + _check_key_infinity(backend, ec_key_cdata) + + @property + def curve(self) -> ec.EllipticCurve: + return self._curve + + @property + def key_size(self) -> int: + return self.curve.key_size + + def __eq__(self, other: object) -> bool: + if not isinstance(other, _EllipticCurvePublicKey): + return NotImplemented + + return ( + self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) + == 1 + ) + + def public_numbers(self) -> ec.EllipticCurvePublicNumbers: + group = self._backend._lib.EC_KEY_get0_group(self._ec_key) + self._backend.openssl_assert(group != self._backend._ffi.NULL) + + point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) + self._backend.openssl_assert(point != self._backend._ffi.NULL) + + with self._backend._tmp_bn_ctx() as bn_ctx: + bn_x = self._backend._lib.BN_CTX_get(bn_ctx) + bn_y = self._backend._lib.BN_CTX_get(bn_ctx) + + res = self._backend._lib.EC_POINT_get_affine_coordinates( + group, point, bn_x, bn_y, bn_ctx + ) + self._backend.openssl_assert(res == 1) + + x = self._backend._bn_to_int(bn_x) + y = self._backend._bn_to_int(bn_y) + + return ec.EllipticCurvePublicNumbers(x=x, y=y, curve=self._curve) + + def _encode_point(self, format: serialization.PublicFormat) -> bytes: + if format is serialization.PublicFormat.CompressedPoint: + conversion = self._backend._lib.POINT_CONVERSION_COMPRESSED + else: + assert format is serialization.PublicFormat.UncompressedPoint + conversion = self._backend._lib.POINT_CONVERSION_UNCOMPRESSED + + group = self._backend._lib.EC_KEY_get0_group(self._ec_key) + self._backend.openssl_assert(group != self._backend._ffi.NULL) + point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) + self._backend.openssl_assert(point != self._backend._ffi.NULL) + with self._backend._tmp_bn_ctx() as bn_ctx: + buflen = self._backend._lib.EC_POINT_point2oct( + group, point, conversion, self._backend._ffi.NULL, 0, bn_ctx + ) + self._backend.openssl_assert(buflen > 0) + buf = self._backend._ffi.new("char[]", buflen) + res = self._backend._lib.EC_POINT_point2oct( + group, point, conversion, buf, buflen, bn_ctx + ) + self._backend.openssl_assert(buflen == res) + + return self._backend._ffi.buffer(buf)[:] + + def public_bytes( + self, + encoding: serialization.Encoding, + format: serialization.PublicFormat, + ) -> bytes: + if ( + encoding is serialization.Encoding.X962 + or format is serialization.PublicFormat.CompressedPoint + or format is serialization.PublicFormat.UncompressedPoint + ): + if encoding is not serialization.Encoding.X962 or format not in ( + serialization.PublicFormat.CompressedPoint, + serialization.PublicFormat.UncompressedPoint, + ): + raise ValueError( + "X962 encoding must be used with CompressedPoint or " + "UncompressedPoint format" + ) + + return self._encode_point(format) + else: + return self._backend._public_key_bytes( + encoding, format, self, self._evp_pkey, None + ) + + def verify( + self, + signature: bytes, + data: bytes, + signature_algorithm: ec.EllipticCurveSignatureAlgorithm, + ) -> None: + _check_signature_algorithm(signature_algorithm) + data, _ = _calculate_digest_and_algorithm( + data, + signature_algorithm.algorithm, + ) + _ecdsa_sig_verify(self._backend, self, signature, data) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/rsa.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/rsa.py new file mode 100644 index 0000000..ef27d4e --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/rsa.py @@ -0,0 +1,599 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import threading +import typing + +from cryptography.exceptions import ( + InvalidSignature, + UnsupportedAlgorithm, + _Reasons, +) +from cryptography.hazmat.backends.openssl.utils import ( + _calculate_digest_and_algorithm, +) +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import utils as asym_utils +from cryptography.hazmat.primitives.asymmetric.padding import ( + MGF1, + OAEP, + PSS, + AsymmetricPadding, + PKCS1v15, + _Auto, + _DigestLength, + _MaxLength, + calculate_max_pss_salt_length, +) +from cryptography.hazmat.primitives.asymmetric.rsa import ( + RSAPrivateKey, + RSAPrivateNumbers, + RSAPublicKey, + RSAPublicNumbers, +) + +if typing.TYPE_CHECKING: + from cryptography.hazmat.backends.openssl.backend import Backend + + +def _get_rsa_pss_salt_length( + backend: Backend, + pss: PSS, + key: typing.Union[RSAPrivateKey, RSAPublicKey], + hash_algorithm: hashes.HashAlgorithm, +) -> int: + salt = pss._salt_length + + if isinstance(salt, _MaxLength): + return calculate_max_pss_salt_length(key, hash_algorithm) + elif isinstance(salt, _DigestLength): + return hash_algorithm.digest_size + elif isinstance(salt, _Auto): + if isinstance(key, RSAPrivateKey): + raise ValueError( + "PSS salt length can only be set to AUTO when verifying" + ) + return backend._lib.RSA_PSS_SALTLEN_AUTO + else: + return salt + + +def _enc_dec_rsa( + backend: Backend, + key: typing.Union[_RSAPrivateKey, _RSAPublicKey], + data: bytes, + padding: AsymmetricPadding, +) -> bytes: + if not isinstance(padding, AsymmetricPadding): + raise TypeError("Padding must be an instance of AsymmetricPadding.") + + if isinstance(padding, PKCS1v15): + padding_enum = backend._lib.RSA_PKCS1_PADDING + elif isinstance(padding, OAEP): + padding_enum = backend._lib.RSA_PKCS1_OAEP_PADDING + + if not isinstance(padding._mgf, MGF1): + raise UnsupportedAlgorithm( + "Only MGF1 is supported by this backend.", + _Reasons.UNSUPPORTED_MGF, + ) + + if not backend.rsa_padding_supported(padding): + raise UnsupportedAlgorithm( + "This combination of padding and hash algorithm is not " + "supported by this backend.", + _Reasons.UNSUPPORTED_PADDING, + ) + + else: + raise UnsupportedAlgorithm( + f"{padding.name} is not supported by this backend.", + _Reasons.UNSUPPORTED_PADDING, + ) + + return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding) + + +def _enc_dec_rsa_pkey_ctx( + backend: Backend, + key: typing.Union[_RSAPrivateKey, _RSAPublicKey], + data: bytes, + padding_enum: int, + padding: AsymmetricPadding, +) -> bytes: + init: typing.Callable[[typing.Any], int] + crypt: typing.Callable[[typing.Any, typing.Any, int, bytes, int], int] + if isinstance(key, _RSAPublicKey): + init = backend._lib.EVP_PKEY_encrypt_init + crypt = backend._lib.EVP_PKEY_encrypt + else: + init = backend._lib.EVP_PKEY_decrypt_init + crypt = backend._lib.EVP_PKEY_decrypt + + pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL) + backend.openssl_assert(pkey_ctx != backend._ffi.NULL) + pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free) + res = init(pkey_ctx) + backend.openssl_assert(res == 1) + res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum) + backend.openssl_assert(res > 0) + buf_size = backend._lib.EVP_PKEY_size(key._evp_pkey) + backend.openssl_assert(buf_size > 0) + if isinstance(padding, OAEP): + mgf1_md = backend._evp_md_non_null_from_algorithm( + padding._mgf._algorithm + ) + res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md) + backend.openssl_assert(res > 0) + oaep_md = backend._evp_md_non_null_from_algorithm(padding._algorithm) + res = backend._lib.EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, oaep_md) + backend.openssl_assert(res > 0) + + if ( + isinstance(padding, OAEP) + and padding._label is not None + and len(padding._label) > 0 + ): + # set0_rsa_oaep_label takes ownership of the char * so we need to + # copy it into some new memory + labelptr = backend._lib.OPENSSL_malloc(len(padding._label)) + backend.openssl_assert(labelptr != backend._ffi.NULL) + backend._ffi.memmove(labelptr, padding._label, len(padding._label)) + res = backend._lib.EVP_PKEY_CTX_set0_rsa_oaep_label( + pkey_ctx, labelptr, len(padding._label) + ) + backend.openssl_assert(res == 1) + + outlen = backend._ffi.new("size_t *", buf_size) + buf = backend._ffi.new("unsigned char[]", buf_size) + # Everything from this line onwards is written with the goal of being as + # constant-time as is practical given the constraints of Python and our + # API. See Bleichenbacher's '98 attack on RSA, and its many many variants. + # As such, you should not attempt to change this (particularly to "clean it + # up") without understanding why it was written this way (see + # Chesterton's Fence), and without measuring to verify you have not + # introduced observable time differences. + res = crypt(pkey_ctx, buf, outlen, data, len(data)) + resbuf = backend._ffi.buffer(buf)[: outlen[0]] + backend._lib.ERR_clear_error() + if res <= 0: + raise ValueError("Encryption/decryption failed.") + return resbuf + + +def _rsa_sig_determine_padding( + backend: Backend, + key: typing.Union[_RSAPrivateKey, _RSAPublicKey], + padding: AsymmetricPadding, + algorithm: typing.Optional[hashes.HashAlgorithm], +) -> int: + if not isinstance(padding, AsymmetricPadding): + raise TypeError("Expected provider of AsymmetricPadding.") + + pkey_size = backend._lib.EVP_PKEY_size(key._evp_pkey) + backend.openssl_assert(pkey_size > 0) + + if isinstance(padding, PKCS1v15): + # Hash algorithm is ignored for PKCS1v15-padding, may be None. + padding_enum = backend._lib.RSA_PKCS1_PADDING + elif isinstance(padding, PSS): + if not isinstance(padding._mgf, MGF1): + raise UnsupportedAlgorithm( + "Only MGF1 is supported by this backend.", + _Reasons.UNSUPPORTED_MGF, + ) + + # PSS padding requires a hash algorithm + if not isinstance(algorithm, hashes.HashAlgorithm): + raise TypeError("Expected instance of hashes.HashAlgorithm.") + + # Size of key in bytes - 2 is the maximum + # PSS signature length (salt length is checked later) + if pkey_size - algorithm.digest_size - 2 < 0: + raise ValueError( + "Digest too large for key size. Use a larger " + "key or different digest." + ) + + padding_enum = backend._lib.RSA_PKCS1_PSS_PADDING + else: + raise UnsupportedAlgorithm( + f"{padding.name} is not supported by this backend.", + _Reasons.UNSUPPORTED_PADDING, + ) + + return padding_enum + + +# Hash algorithm can be absent (None) to initialize the context without setting +# any message digest algorithm. This is currently only valid for the PKCS1v15 +# padding type, where it means that the signature data is encoded/decoded +# as provided, without being wrapped in a DigestInfo structure. +def _rsa_sig_setup( + backend: Backend, + padding: AsymmetricPadding, + algorithm: typing.Optional[hashes.HashAlgorithm], + key: typing.Union[_RSAPublicKey, _RSAPrivateKey], + init_func: typing.Callable[[typing.Any], int], +): + padding_enum = _rsa_sig_determine_padding(backend, key, padding, algorithm) + pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL) + backend.openssl_assert(pkey_ctx != backend._ffi.NULL) + pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free) + res = init_func(pkey_ctx) + if res != 1: + errors = backend._consume_errors() + raise ValueError("Unable to sign/verify with this key", errors) + + if algorithm is not None: + evp_md = backend._evp_md_non_null_from_algorithm(algorithm) + res = backend._lib.EVP_PKEY_CTX_set_signature_md(pkey_ctx, evp_md) + if res <= 0: + backend._consume_errors() + raise UnsupportedAlgorithm( + "{} is not supported by this backend for RSA signing.".format( + algorithm.name + ), + _Reasons.UNSUPPORTED_HASH, + ) + res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum) + if res <= 0: + backend._consume_errors() + raise UnsupportedAlgorithm( + "{} is not supported for the RSA signature operation.".format( + padding.name + ), + _Reasons.UNSUPPORTED_PADDING, + ) + if isinstance(padding, PSS): + assert isinstance(algorithm, hashes.HashAlgorithm) + res = backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen( + pkey_ctx, + _get_rsa_pss_salt_length(backend, padding, key, algorithm), + ) + backend.openssl_assert(res > 0) + + mgf1_md = backend._evp_md_non_null_from_algorithm( + padding._mgf._algorithm + ) + res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md) + backend.openssl_assert(res > 0) + + return pkey_ctx + + +def _rsa_sig_sign( + backend: Backend, + padding: AsymmetricPadding, + algorithm: hashes.HashAlgorithm, + private_key: _RSAPrivateKey, + data: bytes, +) -> bytes: + pkey_ctx = _rsa_sig_setup( + backend, + padding, + algorithm, + private_key, + backend._lib.EVP_PKEY_sign_init, + ) + buflen = backend._ffi.new("size_t *") + res = backend._lib.EVP_PKEY_sign( + pkey_ctx, backend._ffi.NULL, buflen, data, len(data) + ) + backend.openssl_assert(res == 1) + buf = backend._ffi.new("unsigned char[]", buflen[0]) + res = backend._lib.EVP_PKEY_sign(pkey_ctx, buf, buflen, data, len(data)) + if res != 1: + errors = backend._consume_errors() + raise ValueError( + "Digest or salt length too long for key size. Use a larger key " + "or shorter salt length if you are specifying a PSS salt", + errors, + ) + + return backend._ffi.buffer(buf)[:] + + +def _rsa_sig_verify( + backend: Backend, + padding: AsymmetricPadding, + algorithm: hashes.HashAlgorithm, + public_key: _RSAPublicKey, + signature: bytes, + data: bytes, +) -> None: + pkey_ctx = _rsa_sig_setup( + backend, + padding, + algorithm, + public_key, + backend._lib.EVP_PKEY_verify_init, + ) + res = backend._lib.EVP_PKEY_verify( + pkey_ctx, signature, len(signature), data, len(data) + ) + # The previous call can return negative numbers in the event of an + # error. This is not a signature failure but we need to fail if it + # occurs. + backend.openssl_assert(res >= 0) + if res == 0: + backend._consume_errors() + raise InvalidSignature + + +def _rsa_sig_recover( + backend: Backend, + padding: AsymmetricPadding, + algorithm: typing.Optional[hashes.HashAlgorithm], + public_key: _RSAPublicKey, + signature: bytes, +) -> bytes: + pkey_ctx = _rsa_sig_setup( + backend, + padding, + algorithm, + public_key, + backend._lib.EVP_PKEY_verify_recover_init, + ) + + # Attempt to keep the rest of the code in this function as constant/time + # as possible. See the comment in _enc_dec_rsa_pkey_ctx. Note that the + # buflen parameter is used even though its value may be undefined in the + # error case. Due to the tolerant nature of Python slicing this does not + # trigger any exceptions. + maxlen = backend._lib.EVP_PKEY_size(public_key._evp_pkey) + backend.openssl_assert(maxlen > 0) + buf = backend._ffi.new("unsigned char[]", maxlen) + buflen = backend._ffi.new("size_t *", maxlen) + res = backend._lib.EVP_PKEY_verify_recover( + pkey_ctx, buf, buflen, signature, len(signature) + ) + resbuf = backend._ffi.buffer(buf)[: buflen[0]] + backend._lib.ERR_clear_error() + # Assume that all parameter errors are handled during the setup phase and + # any error here is due to invalid signature. + if res != 1: + raise InvalidSignature + return resbuf + + +class _RSAPrivateKey(RSAPrivateKey): + _evp_pkey: object + _rsa_cdata: object + _key_size: int + + def __init__( + self, + backend: Backend, + rsa_cdata, + evp_pkey, + *, + unsafe_skip_rsa_key_validation: bool, + ): + res: int + # RSA_check_key is slower in OpenSSL 3.0.0 due to improved + # primality checking. In normal use this is unlikely to be a problem + # since users don't load new keys constantly, but for TESTING we've + # added an init arg that allows skipping the checks. You should not + # use this in production code unless you understand the consequences. + if not unsafe_skip_rsa_key_validation: + res = backend._lib.RSA_check_key(rsa_cdata) + if res != 1: + errors = backend._consume_errors() + raise ValueError("Invalid private key", errors) + # 2 is prime and passes an RSA key check, so we also check + # if p and q are odd just to be safe. + p = backend._ffi.new("BIGNUM **") + q = backend._ffi.new("BIGNUM **") + backend._lib.RSA_get0_factors(rsa_cdata, p, q) + backend.openssl_assert(p[0] != backend._ffi.NULL) + backend.openssl_assert(q[0] != backend._ffi.NULL) + p_odd = backend._lib.BN_is_odd(p[0]) + q_odd = backend._lib.BN_is_odd(q[0]) + if p_odd != 1 or q_odd != 1: + errors = backend._consume_errors() + raise ValueError("Invalid private key", errors) + + self._backend = backend + self._rsa_cdata = rsa_cdata + self._evp_pkey = evp_pkey + # Used for lazy blinding + self._blinded = False + self._blinding_lock = threading.Lock() + + n = self._backend._ffi.new("BIGNUM **") + self._backend._lib.RSA_get0_key( + self._rsa_cdata, + n, + self._backend._ffi.NULL, + self._backend._ffi.NULL, + ) + self._backend.openssl_assert(n[0] != self._backend._ffi.NULL) + self._key_size = self._backend._lib.BN_num_bits(n[0]) + + def _enable_blinding(self) -> None: + # If you call blind on an already blinded RSA key OpenSSL will turn + # it off and back on, which is a performance hit we want to avoid. + if not self._blinded: + with self._blinding_lock: + self._non_threadsafe_enable_blinding() + + def _non_threadsafe_enable_blinding(self) -> None: + # This is only a separate function to allow for testing to cover both + # branches. It should never be invoked except through _enable_blinding. + # Check if it's not True again in case another thread raced past the + # first non-locked check. + if not self._blinded: + res = self._backend._lib.RSA_blinding_on( + self._rsa_cdata, self._backend._ffi.NULL + ) + self._backend.openssl_assert(res == 1) + self._blinded = True + + @property + def key_size(self) -> int: + return self._key_size + + def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes: + self._enable_blinding() + key_size_bytes = (self.key_size + 7) // 8 + if key_size_bytes != len(ciphertext): + raise ValueError("Ciphertext length must be equal to key size.") + + return _enc_dec_rsa(self._backend, self, ciphertext, padding) + + def public_key(self) -> RSAPublicKey: + ctx = self._backend._lib.RSAPublicKey_dup(self._rsa_cdata) + self._backend.openssl_assert(ctx != self._backend._ffi.NULL) + ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free) + evp_pkey = self._backend._rsa_cdata_to_evp_pkey(ctx) + return _RSAPublicKey(self._backend, ctx, evp_pkey) + + def private_numbers(self) -> RSAPrivateNumbers: + n = self._backend._ffi.new("BIGNUM **") + e = self._backend._ffi.new("BIGNUM **") + d = self._backend._ffi.new("BIGNUM **") + p = self._backend._ffi.new("BIGNUM **") + q = self._backend._ffi.new("BIGNUM **") + dmp1 = self._backend._ffi.new("BIGNUM **") + dmq1 = self._backend._ffi.new("BIGNUM **") + iqmp = self._backend._ffi.new("BIGNUM **") + self._backend._lib.RSA_get0_key(self._rsa_cdata, n, e, d) + self._backend.openssl_assert(n[0] != self._backend._ffi.NULL) + self._backend.openssl_assert(e[0] != self._backend._ffi.NULL) + self._backend.openssl_assert(d[0] != self._backend._ffi.NULL) + self._backend._lib.RSA_get0_factors(self._rsa_cdata, p, q) + self._backend.openssl_assert(p[0] != self._backend._ffi.NULL) + self._backend.openssl_assert(q[0] != self._backend._ffi.NULL) + self._backend._lib.RSA_get0_crt_params( + self._rsa_cdata, dmp1, dmq1, iqmp + ) + self._backend.openssl_assert(dmp1[0] != self._backend._ffi.NULL) + self._backend.openssl_assert(dmq1[0] != self._backend._ffi.NULL) + self._backend.openssl_assert(iqmp[0] != self._backend._ffi.NULL) + return RSAPrivateNumbers( + p=self._backend._bn_to_int(p[0]), + q=self._backend._bn_to_int(q[0]), + d=self._backend._bn_to_int(d[0]), + dmp1=self._backend._bn_to_int(dmp1[0]), + dmq1=self._backend._bn_to_int(dmq1[0]), + iqmp=self._backend._bn_to_int(iqmp[0]), + public_numbers=RSAPublicNumbers( + e=self._backend._bn_to_int(e[0]), + n=self._backend._bn_to_int(n[0]), + ), + ) + + def private_bytes( + self, + encoding: serialization.Encoding, + format: serialization.PrivateFormat, + encryption_algorithm: serialization.KeySerializationEncryption, + ) -> bytes: + return self._backend._private_key_bytes( + encoding, + format, + encryption_algorithm, + self, + self._evp_pkey, + self._rsa_cdata, + ) + + def sign( + self, + data: bytes, + padding: AsymmetricPadding, + algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + ) -> bytes: + self._enable_blinding() + data, algorithm = _calculate_digest_and_algorithm(data, algorithm) + return _rsa_sig_sign(self._backend, padding, algorithm, self, data) + + +class _RSAPublicKey(RSAPublicKey): + _evp_pkey: object + _rsa_cdata: object + _key_size: int + + def __init__(self, backend: Backend, rsa_cdata, evp_pkey): + self._backend = backend + self._rsa_cdata = rsa_cdata + self._evp_pkey = evp_pkey + + n = self._backend._ffi.new("BIGNUM **") + self._backend._lib.RSA_get0_key( + self._rsa_cdata, + n, + self._backend._ffi.NULL, + self._backend._ffi.NULL, + ) + self._backend.openssl_assert(n[0] != self._backend._ffi.NULL) + self._key_size = self._backend._lib.BN_num_bits(n[0]) + + @property + def key_size(self) -> int: + return self._key_size + + def __eq__(self, other: object) -> bool: + if not isinstance(other, _RSAPublicKey): + return NotImplemented + + return ( + self._backend._lib.EVP_PKEY_cmp(self._evp_pkey, other._evp_pkey) + == 1 + ) + + def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes: + return _enc_dec_rsa(self._backend, self, plaintext, padding) + + def public_numbers(self) -> RSAPublicNumbers: + n = self._backend._ffi.new("BIGNUM **") + e = self._backend._ffi.new("BIGNUM **") + self._backend._lib.RSA_get0_key( + self._rsa_cdata, n, e, self._backend._ffi.NULL + ) + self._backend.openssl_assert(n[0] != self._backend._ffi.NULL) + self._backend.openssl_assert(e[0] != self._backend._ffi.NULL) + return RSAPublicNumbers( + e=self._backend._bn_to_int(e[0]), + n=self._backend._bn_to_int(n[0]), + ) + + def public_bytes( + self, + encoding: serialization.Encoding, + format: serialization.PublicFormat, + ) -> bytes: + return self._backend._public_key_bytes( + encoding, format, self, self._evp_pkey, self._rsa_cdata + ) + + def verify( + self, + signature: bytes, + data: bytes, + padding: AsymmetricPadding, + algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + ) -> None: + data, algorithm = _calculate_digest_and_algorithm(data, algorithm) + _rsa_sig_verify( + self._backend, padding, algorithm, self, signature, data + ) + + def recover_data_from_signature( + self, + signature: bytes, + padding: AsymmetricPadding, + algorithm: typing.Optional[hashes.HashAlgorithm], + ) -> bytes: + if isinstance(algorithm, asym_utils.Prehashed): + raise TypeError( + "Prehashed is only supported in the sign and verify methods. " + "It cannot be used with recover_data_from_signature." + ) + return _rsa_sig_recover( + self._backend, padding, algorithm, self, signature + ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/utils.py b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/utils.py new file mode 100644 index 0000000..5b404de --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/backends/openssl/utils.py @@ -0,0 +1,63 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric.utils import Prehashed + +if typing.TYPE_CHECKING: + from cryptography.hazmat.backends.openssl.backend import Backend + + +def _evp_pkey_derive(backend: Backend, evp_pkey, peer_public_key) -> bytes: + ctx = backend._lib.EVP_PKEY_CTX_new(evp_pkey, backend._ffi.NULL) + backend.openssl_assert(ctx != backend._ffi.NULL) + ctx = backend._ffi.gc(ctx, backend._lib.EVP_PKEY_CTX_free) + res = backend._lib.EVP_PKEY_derive_init(ctx) + backend.openssl_assert(res == 1) + + if backend._lib.Cryptography_HAS_EVP_PKEY_SET_PEER_EX: + res = backend._lib.EVP_PKEY_derive_set_peer_ex( + ctx, peer_public_key._evp_pkey, 0 + ) + else: + res = backend._lib.EVP_PKEY_derive_set_peer( + ctx, peer_public_key._evp_pkey + ) + backend.openssl_assert(res == 1) + + keylen = backend._ffi.new("size_t *") + res = backend._lib.EVP_PKEY_derive(ctx, backend._ffi.NULL, keylen) + backend.openssl_assert(res == 1) + backend.openssl_assert(keylen[0] > 0) + buf = backend._ffi.new("unsigned char[]", keylen[0]) + res = backend._lib.EVP_PKEY_derive(ctx, buf, keylen) + if res != 1: + errors = backend._consume_errors() + raise ValueError("Error computing shared key.", errors) + + return backend._ffi.buffer(buf, keylen[0])[:] + + +def _calculate_digest_and_algorithm( + data: bytes, + algorithm: typing.Union[Prehashed, hashes.HashAlgorithm], +) -> typing.Tuple[bytes, hashes.HashAlgorithm]: + if not isinstance(algorithm, Prehashed): + hash_ctx = hashes.Hash(algorithm) + hash_ctx.update(data) + data = hash_ctx.finalize() + else: + algorithm = algorithm._algorithm + + if len(data) != algorithm.digest_size: + raise ValueError( + "The provided data must be the same length as the hash " + "algorithm's digest size." + ) + + return (data, algorithm) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/__init__.py new file mode 100644 index 0000000..b509336 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/__init__.py @@ -0,0 +1,3 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..07b5c74 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust.abi3.so b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust.abi3.so new file mode 100644 index 0000000..9984207 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust.abi3.so differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi new file mode 100644 index 0000000..94a37a2 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/__init__.pyi @@ -0,0 +1,34 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import types +import typing + +def check_pkcs7_padding(data: bytes) -> bool: ... +def check_ansix923_padding(data: bytes) -> bool: ... + +class ObjectIdentifier: + def __init__(self, val: str) -> None: ... + @property + def dotted_string(self) -> str: ... + @property + def _name(self) -> str: ... + +T = typing.TypeVar("T") + +class FixedPool(typing.Generic[T]): + def __init__( + self, + create: typing.Callable[[], T], + ) -> None: ... + def acquire(self) -> PoolAcquisition[T]: ... + +class PoolAcquisition(typing.Generic[T]): + def __enter__(self) -> T: ... + def __exit__( + self, + exc_type: typing.Optional[typing.Type[BaseException]], + exc_value: typing.Optional[BaseException], + exc_tb: typing.Optional[types.TracebackType], + ) -> None: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/_openssl.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/_openssl.pyi new file mode 100644 index 0000000..8010008 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/_openssl.pyi @@ -0,0 +1,8 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +lib = typing.Any +ffi = typing.Any diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi new file mode 100644 index 0000000..a8369ba --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/asn1.pyi @@ -0,0 +1,16 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +class TestCertificate: + not_after_tag: int + not_before_tag: int + issuer_value_tags: typing.List[int] + subject_value_tags: typing.List[int] + +def decode_dss_signature(signature: bytes) -> typing.Tuple[int, int]: ... +def encode_dss_signature(r: int, s: int) -> bytes: ... +def parse_spki_for_data(data: bytes) -> bytes: ... +def test_parse_certificate(data: bytes) -> TestCertificate: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/exceptions.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/exceptions.pyi new file mode 100644 index 0000000..09f46b1 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/exceptions.pyi @@ -0,0 +1,17 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +class _Reasons: + BACKEND_MISSING_INTERFACE: _Reasons + UNSUPPORTED_HASH: _Reasons + UNSUPPORTED_CIPHER: _Reasons + UNSUPPORTED_PADDING: _Reasons + UNSUPPORTED_MGF: _Reasons + UNSUPPORTED_PUBLIC_KEY_ALGORITHM: _Reasons + UNSUPPORTED_ELLIPTIC_CURVE: _Reasons + UNSUPPORTED_SERIALIZATION: _Reasons + UNSUPPORTED_X509: _Reasons + UNSUPPORTED_EXCHANGE_ALGORITHM: _Reasons + UNSUPPORTED_DIFFIE_HELLMAN: _Reasons + UNSUPPORTED_MAC: _Reasons diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi new file mode 100644 index 0000000..4671eb9 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/ocsp.pyi @@ -0,0 +1,25 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes +from cryptography.x509.ocsp import ( + OCSPRequest, + OCSPRequestBuilder, + OCSPResponse, + OCSPResponseBuilder, + OCSPResponseStatus, +) + +def load_der_ocsp_request(data: bytes) -> OCSPRequest: ... +def load_der_ocsp_response(data: bytes) -> OCSPResponse: ... +def create_ocsp_request(builder: OCSPRequestBuilder) -> OCSPRequest: ... +def create_ocsp_response( + status: OCSPResponseStatus, + builder: typing.Optional[OCSPResponseBuilder], + private_key: typing.Optional[PrivateKeyTypes], + hash_algorithm: typing.Optional[hashes.HashAlgorithm], +) -> OCSPResponse: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi new file mode 100644 index 0000000..82f30d2 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi @@ -0,0 +1,47 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +from cryptography.hazmat.bindings._rust.openssl import ( + dh, + dsa, + ed448, + ed25519, + hashes, + hmac, + kdf, + poly1305, + x448, + x25519, +) + +__all__ = [ + "openssl_version", + "raise_openssl_error", + "dh", + "dsa", + "hashes", + "hmac", + "kdf", + "ed448", + "ed25519", + "poly1305", + "x448", + "x25519", +] + +def openssl_version() -> int: ... +def raise_openssl_error() -> typing.NoReturn: ... +def capture_error_stack() -> typing.List[OpenSSLError]: ... +def is_fips_enabled() -> bool: ... + +class OpenSSLError: + @property + def lib(self) -> int: ... + @property + def reason(self) -> int: ... + @property + def reason_text(self) -> bytes: ... + def _lib_reason_match(self, lib: int, reason: int) -> bool: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi new file mode 100644 index 0000000..bfd005d --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dh.pyi @@ -0,0 +1,22 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from cryptography.hazmat.primitives.asymmetric import dh + +MIN_MODULUS_SIZE: int + +class DHPrivateKey: ... +class DHPublicKey: ... +class DHParameters: ... + +def generate_parameters(generator: int, key_size: int) -> dh.DHParameters: ... +def private_key_from_ptr(ptr: int) -> dh.DHPrivateKey: ... +def public_key_from_ptr(ptr: int) -> dh.DHPublicKey: ... +def from_pem_parameters(data: bytes) -> dh.DHParameters: ... +def from_der_parameters(data: bytes) -> dh.DHParameters: ... +def from_private_numbers(numbers: dh.DHPrivateNumbers) -> dh.DHPrivateKey: ... +def from_public_numbers(numbers: dh.DHPublicNumbers) -> dh.DHPublicKey: ... +def from_parameter_numbers( + numbers: dh.DHParameterNumbers, +) -> dh.DHParameters: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi new file mode 100644 index 0000000..5a56f25 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/dsa.pyi @@ -0,0 +1,20 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from cryptography.hazmat.primitives.asymmetric import dsa + +class DSAPrivateKey: ... +class DSAPublicKey: ... +class DSAParameters: ... + +def generate_parameters(key_size: int) -> dsa.DSAParameters: ... +def private_key_from_ptr(ptr: int) -> dsa.DSAPrivateKey: ... +def public_key_from_ptr(ptr: int) -> dsa.DSAPublicKey: ... +def from_private_numbers( + numbers: dsa.DSAPrivateNumbers, +) -> dsa.DSAPrivateKey: ... +def from_public_numbers(numbers: dsa.DSAPublicNumbers) -> dsa.DSAPublicKey: ... +def from_parameter_numbers( + numbers: dsa.DSAParameterNumbers, +) -> dsa.DSAParameters: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi new file mode 100644 index 0000000..c7f127f --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed25519.pyi @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from cryptography.hazmat.primitives.asymmetric import ed25519 + +class Ed25519PrivateKey: ... +class Ed25519PublicKey: ... + +def generate_key() -> ed25519.Ed25519PrivateKey: ... +def private_key_from_ptr(ptr: int) -> ed25519.Ed25519PrivateKey: ... +def public_key_from_ptr(ptr: int) -> ed25519.Ed25519PublicKey: ... +def from_private_bytes(data: bytes) -> ed25519.Ed25519PrivateKey: ... +def from_public_bytes(data: bytes) -> ed25519.Ed25519PublicKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi new file mode 100644 index 0000000..1cf5f17 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/ed448.pyi @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from cryptography.hazmat.primitives.asymmetric import ed448 + +class Ed448PrivateKey: ... +class Ed448PublicKey: ... + +def generate_key() -> ed448.Ed448PrivateKey: ... +def private_key_from_ptr(ptr: int) -> ed448.Ed448PrivateKey: ... +def public_key_from_ptr(ptr: int) -> ed448.Ed448PublicKey: ... +def from_private_bytes(data: bytes) -> ed448.Ed448PrivateKey: ... +def from_public_bytes(data: bytes) -> ed448.Ed448PublicKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi new file mode 100644 index 0000000..ca5f42a --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/hashes.pyi @@ -0,0 +1,17 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +from cryptography.hazmat.primitives import hashes + +class Hash(hashes.HashContext): + def __init__( + self, algorithm: hashes.HashAlgorithm, backend: typing.Any = None + ) -> None: ... + @property + def algorithm(self) -> hashes.HashAlgorithm: ... + def update(self, data: bytes) -> None: ... + def finalize(self) -> bytes: ... + def copy(self) -> Hash: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi new file mode 100644 index 0000000..e38d9b5 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/hmac.pyi @@ -0,0 +1,21 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +from cryptography.hazmat.primitives import hashes + +class HMAC(hashes.HashContext): + def __init__( + self, + key: bytes, + algorithm: hashes.HashAlgorithm, + backend: typing.Any = None, + ) -> None: ... + @property + def algorithm(self) -> hashes.HashAlgorithm: ... + def update(self, data: bytes) -> None: ... + def finalize(self) -> bytes: ... + def verify(self, signature: bytes) -> None: ... + def copy(self) -> HMAC: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi new file mode 100644 index 0000000..034a8fe --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/kdf.pyi @@ -0,0 +1,22 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from cryptography.hazmat.primitives.hashes import HashAlgorithm + +def derive_pbkdf2_hmac( + key_material: bytes, + algorithm: HashAlgorithm, + salt: bytes, + iterations: int, + length: int, +) -> bytes: ... +def derive_scrypt( + key_material: bytes, + salt: bytes, + n: int, + r: int, + p: int, + max_mem: int, + length: int, +) -> bytes: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi new file mode 100644 index 0000000..2e9b0a9 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/poly1305.pyi @@ -0,0 +1,13 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +class Poly1305: + def __init__(self, key: bytes) -> None: ... + @staticmethod + def generate_tag(key: bytes, data: bytes) -> bytes: ... + @staticmethod + def verify_tag(key: bytes, data: bytes, tag: bytes) -> None: ... + def update(self, data: bytes) -> None: ... + def finalize(self) -> bytes: ... + def verify(self, tag: bytes) -> None: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi new file mode 100644 index 0000000..90f7cbd --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x25519.pyi @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from cryptography.hazmat.primitives.asymmetric import x25519 + +class X25519PrivateKey: ... +class X25519PublicKey: ... + +def generate_key() -> x25519.X25519PrivateKey: ... +def private_key_from_ptr(ptr: int) -> x25519.X25519PrivateKey: ... +def public_key_from_ptr(ptr: int) -> x25519.X25519PublicKey: ... +def from_private_bytes(data: bytes) -> x25519.X25519PrivateKey: ... +def from_public_bytes(data: bytes) -> x25519.X25519PublicKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi new file mode 100644 index 0000000..d326c8d --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/openssl/x448.pyi @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from cryptography.hazmat.primitives.asymmetric import x448 + +class X448PrivateKey: ... +class X448PublicKey: ... + +def generate_key() -> x448.X448PrivateKey: ... +def private_key_from_ptr(ptr: int) -> x448.X448PrivateKey: ... +def public_key_from_ptr(ptr: int) -> x448.X448PublicKey: ... +def from_private_bytes(data: bytes) -> x448.X448PrivateKey: ... +def from_public_bytes(data: bytes) -> x448.X448PublicKey: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi new file mode 100644 index 0000000..66bd850 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/pkcs7.pyi @@ -0,0 +1,15 @@ +import typing + +from cryptography import x509 +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.serialization import pkcs7 + +def serialize_certificates( + certs: typing.List[x509.Certificate], + encoding: serialization.Encoding, +) -> bytes: ... +def sign_and_serialize( + builder: pkcs7.PKCS7SignatureBuilder, + encoding: serialization.Encoding, + options: typing.Iterable[pkcs7.PKCS7Options], +) -> bytes: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/x509.pyi b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/x509.pyi new file mode 100644 index 0000000..24b2f5e --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/_rust/x509.pyi @@ -0,0 +1,44 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +import typing + +from cryptography import x509 +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric.padding import PSS, PKCS1v15 +from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes + +def load_pem_x509_certificate(data: bytes) -> x509.Certificate: ... +def load_pem_x509_certificates( + data: bytes, +) -> typing.List[x509.Certificate]: ... +def load_der_x509_certificate(data: bytes) -> x509.Certificate: ... +def load_pem_x509_crl(data: bytes) -> x509.CertificateRevocationList: ... +def load_der_x509_crl(data: bytes) -> x509.CertificateRevocationList: ... +def load_pem_x509_csr(data: bytes) -> x509.CertificateSigningRequest: ... +def load_der_x509_csr(data: bytes) -> x509.CertificateSigningRequest: ... +def encode_name_bytes(name: x509.Name) -> bytes: ... +def encode_extension_value(extension: x509.ExtensionType) -> bytes: ... +def create_x509_certificate( + builder: x509.CertificateBuilder, + private_key: PrivateKeyTypes, + hash_algorithm: typing.Optional[hashes.HashAlgorithm], + padding: typing.Optional[typing.Union[PKCS1v15, PSS]], +) -> x509.Certificate: ... +def create_x509_csr( + builder: x509.CertificateSigningRequestBuilder, + private_key: PrivateKeyTypes, + hash_algorithm: typing.Optional[hashes.HashAlgorithm], +) -> x509.CertificateSigningRequest: ... +def create_x509_crl( + builder: x509.CertificateRevocationListBuilder, + private_key: PrivateKeyTypes, + hash_algorithm: typing.Optional[hashes.HashAlgorithm], +) -> x509.CertificateRevocationList: ... + +class Sct: ... +class Certificate: ... +class RevokedCertificate: ... +class CertificateRevocationList: ... +class CertificateSigningRequest: ... diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/__init__.py new file mode 100644 index 0000000..b509336 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/__init__.py @@ -0,0 +1,3 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/_conditional.py b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/_conditional.py new file mode 100644 index 0000000..5e8ecd0 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/_conditional.py @@ -0,0 +1,329 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + + +def cryptography_has_set_cert_cb() -> typing.List[str]: + return [ + "SSL_CTX_set_cert_cb", + "SSL_set_cert_cb", + ] + + +def cryptography_has_ssl_st() -> typing.List[str]: + return [ + "SSL_ST_BEFORE", + "SSL_ST_OK", + "SSL_ST_INIT", + "SSL_ST_RENEGOTIATE", + ] + + +def cryptography_has_tls_st() -> typing.List[str]: + return [ + "TLS_ST_BEFORE", + "TLS_ST_OK", + ] + + +def cryptography_has_evp_pkey_dhx() -> typing.List[str]: + return [ + "EVP_PKEY_DHX", + ] + + +def cryptography_has_mem_functions() -> typing.List[str]: + return [ + "Cryptography_CRYPTO_set_mem_functions", + ] + + +def cryptography_has_x509_store_ctx_get_issuer() -> typing.List[str]: + return [ + "X509_STORE_set_get_issuer", + ] + + +def cryptography_has_ed448() -> typing.List[str]: + return [ + "EVP_PKEY_ED448", + "NID_ED448", + ] + + +def cryptography_has_ed25519() -> typing.List[str]: + return [ + "NID_ED25519", + "EVP_PKEY_ED25519", + ] + + +def cryptography_has_poly1305() -> typing.List[str]: + return [ + "NID_poly1305", + "EVP_PKEY_POLY1305", + ] + + +def cryptography_has_evp_digestfinal_xof() -> typing.List[str]: + return [ + "EVP_DigestFinalXOF", + ] + + +def cryptography_has_fips() -> typing.List[str]: + return [ + "FIPS_mode_set", + "FIPS_mode", + ] + + +def cryptography_has_ssl_sigalgs() -> typing.List[str]: + return [ + "SSL_CTX_set1_sigalgs_list", + ] + + +def cryptography_has_psk() -> typing.List[str]: + return [ + "SSL_CTX_use_psk_identity_hint", + "SSL_CTX_set_psk_server_callback", + "SSL_CTX_set_psk_client_callback", + ] + + +def cryptography_has_psk_tlsv13() -> typing.List[str]: + return [ + "SSL_CTX_set_psk_find_session_callback", + "SSL_CTX_set_psk_use_session_callback", + "Cryptography_SSL_SESSION_new", + "SSL_CIPHER_find", + "SSL_SESSION_set1_master_key", + "SSL_SESSION_set_cipher", + "SSL_SESSION_set_protocol_version", + ] + + +def cryptography_has_custom_ext() -> typing.List[str]: + return [ + "SSL_CTX_add_client_custom_ext", + "SSL_CTX_add_server_custom_ext", + "SSL_extension_supported", + ] + + +def cryptography_has_tlsv13_functions() -> typing.List[str]: + return [ + "SSL_VERIFY_POST_HANDSHAKE", + "SSL_CTX_set_ciphersuites", + "SSL_verify_client_post_handshake", + "SSL_CTX_set_post_handshake_auth", + "SSL_set_post_handshake_auth", + "SSL_SESSION_get_max_early_data", + "SSL_write_early_data", + "SSL_read_early_data", + "SSL_CTX_set_max_early_data", + ] + + +def cryptography_has_raw_key() -> typing.List[str]: + return [ + "EVP_PKEY_new_raw_private_key", + "EVP_PKEY_new_raw_public_key", + "EVP_PKEY_get_raw_private_key", + "EVP_PKEY_get_raw_public_key", + ] + + +def cryptography_has_engine() -> typing.List[str]: + return [ + "ENGINE_by_id", + "ENGINE_init", + "ENGINE_finish", + "ENGINE_get_default_RAND", + "ENGINE_set_default_RAND", + "ENGINE_unregister_RAND", + "ENGINE_ctrl_cmd", + "ENGINE_free", + "ENGINE_get_name", + "ENGINE_ctrl_cmd_string", + "ENGINE_load_builtin_engines", + "ENGINE_load_private_key", + "ENGINE_load_public_key", + "SSL_CTX_set_client_cert_engine", + ] + + +def cryptography_has_verified_chain() -> typing.List[str]: + return [ + "SSL_get0_verified_chain", + ] + + +def cryptography_has_srtp() -> typing.List[str]: + return [ + "SSL_CTX_set_tlsext_use_srtp", + "SSL_set_tlsext_use_srtp", + "SSL_get_selected_srtp_profile", + ] + + +def cryptography_has_providers() -> typing.List[str]: + return [ + "OSSL_PROVIDER_load", + "OSSL_PROVIDER_unload", + "ERR_LIB_PROV", + "PROV_R_WRONG_FINAL_BLOCK_LENGTH", + "PROV_R_BAD_DECRYPT", + ] + + +def cryptography_has_op_no_renegotiation() -> typing.List[str]: + return [ + "SSL_OP_NO_RENEGOTIATION", + ] + + +def cryptography_has_dtls_get_data_mtu() -> typing.List[str]: + return [ + "DTLS_get_data_mtu", + ] + + +def cryptography_has_300_fips() -> typing.List[str]: + return [ + "EVP_default_properties_is_fips_enabled", + "EVP_default_properties_enable_fips", + ] + + +def cryptography_has_ssl_cookie() -> typing.List[str]: + return [ + "SSL_OP_COOKIE_EXCHANGE", + "DTLSv1_listen", + "SSL_CTX_set_cookie_generate_cb", + "SSL_CTX_set_cookie_verify_cb", + ] + + +def cryptography_has_pkcs7_funcs() -> typing.List[str]: + return [ + "SMIME_write_PKCS7", + "PEM_write_bio_PKCS7_stream", + "PKCS7_sign_add_signer", + "PKCS7_final", + "PKCS7_verify", + "SMIME_read_PKCS7", + "PKCS7_get0_signers", + ] + + +def cryptography_has_bn_flags() -> typing.List[str]: + return [ + "BN_FLG_CONSTTIME", + "BN_set_flags", + "BN_prime_checks_for_size", + ] + + +def cryptography_has_evp_pkey_dh() -> typing.List[str]: + return [ + "EVP_PKEY_set1_DH", + ] + + +def cryptography_has_300_evp_cipher() -> typing.List[str]: + return ["EVP_CIPHER_fetch", "EVP_CIPHER_free"] + + +def cryptography_has_unexpected_eof_while_reading() -> typing.List[str]: + return ["SSL_R_UNEXPECTED_EOF_WHILE_READING"] + + +def cryptography_has_pkcs12_set_mac() -> typing.List[str]: + return ["PKCS12_set_mac"] + + +def cryptography_has_ssl_op_ignore_unexpected_eof() -> typing.List[str]: + return [ + "SSL_OP_IGNORE_UNEXPECTED_EOF", + ] + + +def cryptography_has_get_extms_support() -> typing.List[str]: + return ["SSL_get_extms_support"] + + +def cryptography_has_evp_pkey_set_peer_ex() -> typing.List[str]: + return ["EVP_PKEY_derive_set_peer_ex"] + + +def cryptography_has_evp_aead() -> typing.List[str]: + return [ + "EVP_aead_chacha20_poly1305", + "EVP_AEAD_CTX_free", + "EVP_AEAD_CTX_seal", + "EVP_AEAD_CTX_open", + "EVP_AEAD_max_overhead", + "Cryptography_EVP_AEAD_CTX_new", + ] + + +# This is a mapping of +# {condition: function-returning-names-dependent-on-that-condition} so we can +# loop over them and delete unsupported names at runtime. It will be removed +# when cffi supports #if in cdef. We use functions instead of just a dict of +# lists so we can use coverage to measure which are used. +CONDITIONAL_NAMES = { + "Cryptography_HAS_SET_CERT_CB": cryptography_has_set_cert_cb, + "Cryptography_HAS_SSL_ST": cryptography_has_ssl_st, + "Cryptography_HAS_TLS_ST": cryptography_has_tls_st, + "Cryptography_HAS_EVP_PKEY_DHX": cryptography_has_evp_pkey_dhx, + "Cryptography_HAS_MEM_FUNCTIONS": cryptography_has_mem_functions, + "Cryptography_HAS_X509_STORE_CTX_GET_ISSUER": ( + cryptography_has_x509_store_ctx_get_issuer + ), + "Cryptography_HAS_ED448": cryptography_has_ed448, + "Cryptography_HAS_ED25519": cryptography_has_ed25519, + "Cryptography_HAS_POLY1305": cryptography_has_poly1305, + "Cryptography_HAS_FIPS": cryptography_has_fips, + "Cryptography_HAS_SIGALGS": cryptography_has_ssl_sigalgs, + "Cryptography_HAS_PSK": cryptography_has_psk, + "Cryptography_HAS_PSK_TLSv1_3": cryptography_has_psk_tlsv13, + "Cryptography_HAS_CUSTOM_EXT": cryptography_has_custom_ext, + "Cryptography_HAS_TLSv1_3_FUNCTIONS": cryptography_has_tlsv13_functions, + "Cryptography_HAS_RAW_KEY": cryptography_has_raw_key, + "Cryptography_HAS_EVP_DIGESTFINAL_XOF": ( + cryptography_has_evp_digestfinal_xof + ), + "Cryptography_HAS_ENGINE": cryptography_has_engine, + "Cryptography_HAS_VERIFIED_CHAIN": cryptography_has_verified_chain, + "Cryptography_HAS_SRTP": cryptography_has_srtp, + "Cryptography_HAS_PROVIDERS": cryptography_has_providers, + "Cryptography_HAS_OP_NO_RENEGOTIATION": ( + cryptography_has_op_no_renegotiation + ), + "Cryptography_HAS_DTLS_GET_DATA_MTU": cryptography_has_dtls_get_data_mtu, + "Cryptography_HAS_300_FIPS": cryptography_has_300_fips, + "Cryptography_HAS_SSL_COOKIE": cryptography_has_ssl_cookie, + "Cryptography_HAS_PKCS7_FUNCS": cryptography_has_pkcs7_funcs, + "Cryptography_HAS_BN_FLAGS": cryptography_has_bn_flags, + "Cryptography_HAS_EVP_PKEY_DH": cryptography_has_evp_pkey_dh, + "Cryptography_HAS_300_EVP_CIPHER": cryptography_has_300_evp_cipher, + "Cryptography_HAS_UNEXPECTED_EOF_WHILE_READING": ( + cryptography_has_unexpected_eof_while_reading + ), + "Cryptography_HAS_PKCS12_SET_MAC": cryptography_has_pkcs12_set_mac, + "Cryptography_HAS_SSL_OP_IGNORE_UNEXPECTED_EOF": ( + cryptography_has_ssl_op_ignore_unexpected_eof + ), + "Cryptography_HAS_GET_EXTMS_SUPPORT": cryptography_has_get_extms_support, + "Cryptography_HAS_EVP_PKEY_SET_PEER_EX": ( + cryptography_has_evp_pkey_set_peer_ex + ), + "Cryptography_HAS_EVP_AEAD": (cryptography_has_evp_aead), +} diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/binding.py b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/binding.py new file mode 100644 index 0000000..b50d631 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/bindings/openssl/binding.py @@ -0,0 +1,179 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import os +import sys +import threading +import types +import typing +import warnings + +import cryptography +from cryptography.exceptions import InternalError +from cryptography.hazmat.bindings._rust import _openssl, openssl +from cryptography.hazmat.bindings.openssl._conditional import CONDITIONAL_NAMES + + +def _openssl_assert( + lib, + ok: bool, + errors: typing.Optional[typing.List[openssl.OpenSSLError]] = None, +) -> None: + if not ok: + if errors is None: + errors = openssl.capture_error_stack() + + raise InternalError( + "Unknown OpenSSL error. This error is commonly encountered when " + "another library is not cleaning up the OpenSSL error stack. If " + "you are using cryptography with another library that uses " + "OpenSSL try disabling it before reporting a bug. Otherwise " + "please file an issue at https://github.com/pyca/cryptography/" + "issues with information on how to reproduce " + "this. ({!r})".format(errors), + errors, + ) + + +def _legacy_provider_error(loaded: bool) -> None: + if not loaded: + raise RuntimeError( + "OpenSSL 3.0's legacy provider failed to load. This is a fatal " + "error by default, but cryptography supports running without " + "legacy algorithms by setting the environment variable " + "CRYPTOGRAPHY_OPENSSL_NO_LEGACY. If you did not expect this error," + " you have likely made a mistake with your OpenSSL configuration." + ) + + +def build_conditional_library( + lib: typing.Any, + conditional_names: typing.Dict[str, typing.Callable[[], typing.List[str]]], +) -> typing.Any: + conditional_lib = types.ModuleType("lib") + conditional_lib._original_lib = lib # type: ignore[attr-defined] + excluded_names = set() + for condition, names_cb in conditional_names.items(): + if not getattr(lib, condition): + excluded_names.update(names_cb()) + + for attr in dir(lib): + if attr not in excluded_names: + setattr(conditional_lib, attr, getattr(lib, attr)) + + return conditional_lib + + +class Binding: + """ + OpenSSL API wrapper. + """ + + lib: typing.ClassVar = None + ffi = _openssl.ffi + _lib_loaded = False + _init_lock = threading.Lock() + _legacy_provider: typing.Any = ffi.NULL + _legacy_provider_loaded = False + _default_provider: typing.Any = ffi.NULL + + def __init__(self) -> None: + self._ensure_ffi_initialized() + + def _enable_fips(self) -> None: + # This function enables FIPS mode for OpenSSL 3.0.0 on installs that + # have the FIPS provider installed properly. + _openssl_assert(self.lib, self.lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER) + self._base_provider = self.lib.OSSL_PROVIDER_load( + self.ffi.NULL, b"base" + ) + _openssl_assert(self.lib, self._base_provider != self.ffi.NULL) + self.lib._fips_provider = self.lib.OSSL_PROVIDER_load( + self.ffi.NULL, b"fips" + ) + _openssl_assert(self.lib, self.lib._fips_provider != self.ffi.NULL) + + res = self.lib.EVP_default_properties_enable_fips(self.ffi.NULL, 1) + _openssl_assert(self.lib, res == 1) + + @classmethod + def _ensure_ffi_initialized(cls) -> None: + with cls._init_lock: + if not cls._lib_loaded: + cls.lib = build_conditional_library( + _openssl.lib, CONDITIONAL_NAMES + ) + cls._lib_loaded = True + # As of OpenSSL 3.0.0 we must register a legacy cipher provider + # to get RC2 (needed for junk asymmetric private key + # serialization), RC4, Blowfish, IDEA, SEED, etc. These things + # are ugly legacy, but we aren't going to get rid of them + # any time soon. + if cls.lib.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER: + if not os.environ.get("CRYPTOGRAPHY_OPENSSL_NO_LEGACY"): + cls._legacy_provider = cls.lib.OSSL_PROVIDER_load( + cls.ffi.NULL, b"legacy" + ) + cls._legacy_provider_loaded = ( + cls._legacy_provider != cls.ffi.NULL + ) + _legacy_provider_error(cls._legacy_provider_loaded) + + cls._default_provider = cls.lib.OSSL_PROVIDER_load( + cls.ffi.NULL, b"default" + ) + _openssl_assert( + cls.lib, cls._default_provider != cls.ffi.NULL + ) + + @classmethod + def init_static_locks(cls) -> None: + cls._ensure_ffi_initialized() + + +def _verify_package_version(version: str) -> None: + # Occasionally we run into situations where the version of the Python + # package does not match the version of the shared object that is loaded. + # This may occur in environments where multiple versions of cryptography + # are installed and available in the python path. To avoid errors cropping + # up later this code checks that the currently imported package and the + # shared object that were loaded have the same version and raise an + # ImportError if they do not + so_package_version = _openssl.ffi.string( + _openssl.lib.CRYPTOGRAPHY_PACKAGE_VERSION + ) + if version.encode("ascii") != so_package_version: + raise ImportError( + "The version of cryptography does not match the loaded " + "shared object. This can happen if you have multiple copies of " + "cryptography installed in your Python path. Please try creating " + "a new virtual environment to resolve this issue. " + "Loaded python version: {}, shared object version: {}".format( + version, so_package_version + ) + ) + + _openssl_assert( + _openssl.lib, + _openssl.lib.OpenSSL_version_num() == openssl.openssl_version(), + ) + + +_verify_package_version(cryptography.__version__) + +Binding.init_static_locks() + +if ( + sys.platform == "win32" + and os.environ.get("PROCESSOR_ARCHITEW6432") is not None +): + warnings.warn( + "You are using cryptography on a 32-bit Python on a 64-bit Windows " + "Operating System. Cryptography will be significantly faster if you " + "switch to using a 64-bit Python.", + UserWarning, + stacklevel=2, + ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__init__.py new file mode 100644 index 0000000..b509336 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__init__.py @@ -0,0 +1,3 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8388e6a Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/_asymmetric.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/_asymmetric.cpython-310.opt-1.pyc new file mode 100644 index 0000000..e7e99d0 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/_asymmetric.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/_cipheralgorithm.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/_cipheralgorithm.cpython-310.opt-1.pyc new file mode 100644 index 0000000..062a372 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/_cipheralgorithm.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/_serialization.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/_serialization.cpython-310.opt-1.pyc new file mode 100644 index 0000000..ca1f5f5 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/_serialization.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/constant_time.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/constant_time.cpython-310.opt-1.pyc new file mode 100644 index 0000000..7554afc Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/constant_time.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/hashes.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/hashes.cpython-310.opt-1.pyc new file mode 100644 index 0000000..189b02e Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/hashes.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/hmac.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/hmac.cpython-310.opt-1.pyc new file mode 100644 index 0000000..c0f98a2 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/__pycache__/hmac.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_asymmetric.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_asymmetric.py new file mode 100644 index 0000000..ea55ffd --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_asymmetric.py @@ -0,0 +1,19 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc + +# This exists to break an import cycle. It is normally accessible from the +# asymmetric padding module. + + +class AsymmetricPadding(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def name(self) -> str: + """ + A string naming this padding (e.g. "PSS", "PKCS1"). + """ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py new file mode 100644 index 0000000..3b880b6 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_cipheralgorithm.py @@ -0,0 +1,45 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +# This exists to break an import cycle. It is normally accessible from the +# ciphers module. + + +class CipherAlgorithm(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def name(self) -> str: + """ + A string naming this mode (e.g. "AES", "Camellia"). + """ + + @property + @abc.abstractmethod + def key_sizes(self) -> typing.FrozenSet[int]: + """ + Valid key sizes for this algorithm in bits + """ + + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + The size of the key being used as an integer in bits (e.g. 128, 256). + """ + + +class BlockCipherAlgorithm(CipherAlgorithm): + key: bytes + + @property + @abc.abstractmethod + def block_size(self) -> int: + """ + The size of a block as an integer in bits (e.g. 64, 128). + """ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_serialization.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_serialization.py new file mode 100644 index 0000000..34f3fbc --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/_serialization.py @@ -0,0 +1,170 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +from cryptography import utils +from cryptography.hazmat.primitives.hashes import HashAlgorithm + +# This exists to break an import cycle. These classes are normally accessible +# from the serialization module. + + +class PBES(utils.Enum): + PBESv1SHA1And3KeyTripleDESCBC = "PBESv1 using SHA1 and 3-Key TripleDES" + PBESv2SHA256AndAES256CBC = "PBESv2 using SHA256 PBKDF2 and AES256 CBC" + + +class Encoding(utils.Enum): + PEM = "PEM" + DER = "DER" + OpenSSH = "OpenSSH" + Raw = "Raw" + X962 = "ANSI X9.62" + SMIME = "S/MIME" + + +class PrivateFormat(utils.Enum): + PKCS8 = "PKCS8" + TraditionalOpenSSL = "TraditionalOpenSSL" + Raw = "Raw" + OpenSSH = "OpenSSH" + PKCS12 = "PKCS12" + + def encryption_builder(self) -> KeySerializationEncryptionBuilder: + if self not in (PrivateFormat.OpenSSH, PrivateFormat.PKCS12): + raise ValueError( + "encryption_builder only supported with PrivateFormat.OpenSSH" + " and PrivateFormat.PKCS12" + ) + return KeySerializationEncryptionBuilder(self) + + +class PublicFormat(utils.Enum): + SubjectPublicKeyInfo = "X.509 subjectPublicKeyInfo with PKCS#1" + PKCS1 = "Raw PKCS#1" + OpenSSH = "OpenSSH" + Raw = "Raw" + CompressedPoint = "X9.62 Compressed Point" + UncompressedPoint = "X9.62 Uncompressed Point" + + +class ParameterFormat(utils.Enum): + PKCS3 = "PKCS3" + + +class KeySerializationEncryption(metaclass=abc.ABCMeta): + pass + + +class BestAvailableEncryption(KeySerializationEncryption): + def __init__(self, password: bytes): + if not isinstance(password, bytes) or len(password) == 0: + raise ValueError("Password must be 1 or more bytes.") + + self.password = password + + +class NoEncryption(KeySerializationEncryption): + pass + + +class KeySerializationEncryptionBuilder: + def __init__( + self, + format: PrivateFormat, + *, + _kdf_rounds: typing.Optional[int] = None, + _hmac_hash: typing.Optional[HashAlgorithm] = None, + _key_cert_algorithm: typing.Optional[PBES] = None, + ) -> None: + self._format = format + + self._kdf_rounds = _kdf_rounds + self._hmac_hash = _hmac_hash + self._key_cert_algorithm = _key_cert_algorithm + + def kdf_rounds(self, rounds: int) -> KeySerializationEncryptionBuilder: + if self._kdf_rounds is not None: + raise ValueError("kdf_rounds already set") + + if not isinstance(rounds, int): + raise TypeError("kdf_rounds must be an integer") + + if rounds < 1: + raise ValueError("kdf_rounds must be a positive integer") + + return KeySerializationEncryptionBuilder( + self._format, + _kdf_rounds=rounds, + _hmac_hash=self._hmac_hash, + _key_cert_algorithm=self._key_cert_algorithm, + ) + + def hmac_hash( + self, algorithm: HashAlgorithm + ) -> KeySerializationEncryptionBuilder: + if self._format is not PrivateFormat.PKCS12: + raise TypeError( + "hmac_hash only supported with PrivateFormat.PKCS12" + ) + + if self._hmac_hash is not None: + raise ValueError("hmac_hash already set") + return KeySerializationEncryptionBuilder( + self._format, + _kdf_rounds=self._kdf_rounds, + _hmac_hash=algorithm, + _key_cert_algorithm=self._key_cert_algorithm, + ) + + def key_cert_algorithm( + self, algorithm: PBES + ) -> KeySerializationEncryptionBuilder: + if self._format is not PrivateFormat.PKCS12: + raise TypeError( + "key_cert_algorithm only supported with " + "PrivateFormat.PKCS12" + ) + if self._key_cert_algorithm is not None: + raise ValueError("key_cert_algorithm already set") + return KeySerializationEncryptionBuilder( + self._format, + _kdf_rounds=self._kdf_rounds, + _hmac_hash=self._hmac_hash, + _key_cert_algorithm=algorithm, + ) + + def build(self, password: bytes) -> KeySerializationEncryption: + if not isinstance(password, bytes) or len(password) == 0: + raise ValueError("Password must be 1 or more bytes.") + + return _KeySerializationEncryption( + self._format, + password, + kdf_rounds=self._kdf_rounds, + hmac_hash=self._hmac_hash, + key_cert_algorithm=self._key_cert_algorithm, + ) + + +class _KeySerializationEncryption(KeySerializationEncryption): + def __init__( + self, + format: PrivateFormat, + password: bytes, + *, + kdf_rounds: typing.Optional[int], + hmac_hash: typing.Optional[HashAlgorithm], + key_cert_algorithm: typing.Optional[PBES], + ): + self._format = format + self.password = password + + self._kdf_rounds = kdf_rounds + self._hmac_hash = hmac_hash + self._key_cert_algorithm = key_cert_algorithm diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__init__.py new file mode 100644 index 0000000..b509336 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__init__.py @@ -0,0 +1,3 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..7ddd9dd Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/dh.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/dh.cpython-310.opt-1.pyc new file mode 100644 index 0000000..da6aef3 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/dh.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/dsa.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/dsa.cpython-310.opt-1.pyc new file mode 100644 index 0000000..fda82e5 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/dsa.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/ec.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/ec.cpython-310.opt-1.pyc new file mode 100644 index 0000000..372072f Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/ec.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/ed25519.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/ed25519.cpython-310.opt-1.pyc new file mode 100644 index 0000000..24ffcbf Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/ed25519.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/ed448.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/ed448.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8589c35 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/ed448.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/padding.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/padding.cpython-310.opt-1.pyc new file mode 100644 index 0000000..39f0fde Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/padding.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/rsa.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/rsa.cpython-310.opt-1.pyc new file mode 100644 index 0000000..f2f9f71 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/rsa.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/types.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/types.cpython-310.opt-1.pyc new file mode 100644 index 0000000..7a19b99 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/types.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/utils.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/utils.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d03a52a Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/utils.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/x25519.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/x25519.cpython-310.opt-1.pyc new file mode 100644 index 0000000..c319f4d Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/x25519.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/x448.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/x448.cpython-310.opt-1.pyc new file mode 100644 index 0000000..86cdcc5 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/__pycache__/x448.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dh.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dh.py new file mode 100644 index 0000000..751bcc4 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dh.py @@ -0,0 +1,261 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.primitives import _serialization + + +def generate_parameters( + generator: int, key_size: int, backend: typing.Any = None +) -> DHParameters: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.generate_dh_parameters(generator, key_size) + + +class DHParameterNumbers: + def __init__(self, p: int, g: int, q: typing.Optional[int] = None) -> None: + if not isinstance(p, int) or not isinstance(g, int): + raise TypeError("p and g must be integers") + if q is not None and not isinstance(q, int): + raise TypeError("q must be integer or None") + + if g < 2: + raise ValueError("DH generator must be 2 or greater") + + if p.bit_length() < rust_openssl.dh.MIN_MODULUS_SIZE: + raise ValueError( + f"p (modulus) must be at least " + f"{rust_openssl.dh.MIN_MODULUS_SIZE}-bit" + ) + + self._p = p + self._g = g + self._q = q + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DHParameterNumbers): + return NotImplemented + + return ( + self._p == other._p and self._g == other._g and self._q == other._q + ) + + def parameters(self, backend: typing.Any = None) -> DHParameters: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_dh_parameter_numbers(self) + + @property + def p(self) -> int: + return self._p + + @property + def g(self) -> int: + return self._g + + @property + def q(self) -> typing.Optional[int]: + return self._q + + +class DHPublicNumbers: + def __init__(self, y: int, parameter_numbers: DHParameterNumbers) -> None: + if not isinstance(y, int): + raise TypeError("y must be an integer.") + + if not isinstance(parameter_numbers, DHParameterNumbers): + raise TypeError( + "parameters must be an instance of DHParameterNumbers." + ) + + self._y = y + self._parameter_numbers = parameter_numbers + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DHPublicNumbers): + return NotImplemented + + return ( + self._y == other._y + and self._parameter_numbers == other._parameter_numbers + ) + + def public_key(self, backend: typing.Any = None) -> DHPublicKey: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_dh_public_numbers(self) + + @property + def y(self) -> int: + return self._y + + @property + def parameter_numbers(self) -> DHParameterNumbers: + return self._parameter_numbers + + +class DHPrivateNumbers: + def __init__(self, x: int, public_numbers: DHPublicNumbers) -> None: + if not isinstance(x, int): + raise TypeError("x must be an integer.") + + if not isinstance(public_numbers, DHPublicNumbers): + raise TypeError( + "public_numbers must be an instance of " "DHPublicNumbers." + ) + + self._x = x + self._public_numbers = public_numbers + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DHPrivateNumbers): + return NotImplemented + + return ( + self._x == other._x + and self._public_numbers == other._public_numbers + ) + + def private_key(self, backend: typing.Any = None) -> DHPrivateKey: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_dh_private_numbers(self) + + @property + def public_numbers(self) -> DHPublicNumbers: + return self._public_numbers + + @property + def x(self) -> int: + return self._x + + +class DHParameters(metaclass=abc.ABCMeta): + @abc.abstractmethod + def generate_private_key(self) -> DHPrivateKey: + """ + Generates and returns a DHPrivateKey. + """ + + @abc.abstractmethod + def parameter_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.ParameterFormat, + ) -> bytes: + """ + Returns the parameters serialized as bytes. + """ + + @abc.abstractmethod + def parameter_numbers(self) -> DHParameterNumbers: + """ + Returns a DHParameterNumbers. + """ + + +DHParametersWithSerialization = DHParameters +DHParameters.register(rust_openssl.dh.DHParameters) + + +class DHPublicKey(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + The bit length of the prime modulus. + """ + + @abc.abstractmethod + def parameters(self) -> DHParameters: + """ + The DHParameters object associated with this public key. + """ + + @abc.abstractmethod + def public_numbers(self) -> DHPublicNumbers: + """ + Returns a DHPublicNumbers. + """ + + @abc.abstractmethod + def public_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PublicFormat, + ) -> bytes: + """ + Returns the key serialized as bytes. + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + +DHPublicKeyWithSerialization = DHPublicKey +DHPublicKey.register(rust_openssl.dh.DHPublicKey) + + +class DHPrivateKey(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + The bit length of the prime modulus. + """ + + @abc.abstractmethod + def public_key(self) -> DHPublicKey: + """ + The DHPublicKey associated with this private key. + """ + + @abc.abstractmethod + def parameters(self) -> DHParameters: + """ + The DHParameters object associated with this private key. + """ + + @abc.abstractmethod + def exchange(self, peer_public_key: DHPublicKey) -> bytes: + """ + Given peer's DHPublicKey, carry out the key exchange and + return shared key as bytes. + """ + + @abc.abstractmethod + def private_numbers(self) -> DHPrivateNumbers: + """ + Returns a DHPrivateNumbers. + """ + + @abc.abstractmethod + def private_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PrivateFormat, + encryption_algorithm: _serialization.KeySerializationEncryption, + ) -> bytes: + """ + Returns the key serialized as bytes. + """ + + +DHPrivateKeyWithSerialization = DHPrivateKey +DHPrivateKey.register(rust_openssl.dh.DHPrivateKey) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py new file mode 100644 index 0000000..a8c52de --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -0,0 +1,299 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.primitives import _serialization, hashes +from cryptography.hazmat.primitives.asymmetric import utils as asym_utils + + +class DSAParameters(metaclass=abc.ABCMeta): + @abc.abstractmethod + def generate_private_key(self) -> DSAPrivateKey: + """ + Generates and returns a DSAPrivateKey. + """ + + @abc.abstractmethod + def parameter_numbers(self) -> DSAParameterNumbers: + """ + Returns a DSAParameterNumbers. + """ + + +DSAParametersWithNumbers = DSAParameters +DSAParameters.register(rust_openssl.dsa.DSAParameters) + + +class DSAPrivateKey(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + The bit length of the prime modulus. + """ + + @abc.abstractmethod + def public_key(self) -> DSAPublicKey: + """ + The DSAPublicKey associated with this private key. + """ + + @abc.abstractmethod + def parameters(self) -> DSAParameters: + """ + The DSAParameters object associated with this private key. + """ + + @abc.abstractmethod + def sign( + self, + data: bytes, + algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + ) -> bytes: + """ + Signs the data + """ + + @abc.abstractmethod + def private_numbers(self) -> DSAPrivateNumbers: + """ + Returns a DSAPrivateNumbers. + """ + + @abc.abstractmethod + def private_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PrivateFormat, + encryption_algorithm: _serialization.KeySerializationEncryption, + ) -> bytes: + """ + Returns the key serialized as bytes. + """ + + +DSAPrivateKeyWithSerialization = DSAPrivateKey +DSAPrivateKey.register(rust_openssl.dsa.DSAPrivateKey) + + +class DSAPublicKey(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + The bit length of the prime modulus. + """ + + @abc.abstractmethod + def parameters(self) -> DSAParameters: + """ + The DSAParameters object associated with this public key. + """ + + @abc.abstractmethod + def public_numbers(self) -> DSAPublicNumbers: + """ + Returns a DSAPublicNumbers. + """ + + @abc.abstractmethod + def public_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PublicFormat, + ) -> bytes: + """ + Returns the key serialized as bytes. + """ + + @abc.abstractmethod + def verify( + self, + signature: bytes, + data: bytes, + algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + ) -> None: + """ + Verifies the signature of the data. + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + +DSAPublicKeyWithSerialization = DSAPublicKey +DSAPublicKey.register(rust_openssl.dsa.DSAPublicKey) + + +class DSAParameterNumbers: + def __init__(self, p: int, q: int, g: int): + if ( + not isinstance(p, int) + or not isinstance(q, int) + or not isinstance(g, int) + ): + raise TypeError( + "DSAParameterNumbers p, q, and g arguments must be integers." + ) + + self._p = p + self._q = q + self._g = g + + @property + def p(self) -> int: + return self._p + + @property + def q(self) -> int: + return self._q + + @property + def g(self) -> int: + return self._g + + def parameters(self, backend: typing.Any = None) -> DSAParameters: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_dsa_parameter_numbers(self) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DSAParameterNumbers): + return NotImplemented + + return self.p == other.p and self.q == other.q and self.g == other.g + + def __repr__(self) -> str: + return ( + "".format(self=self) + ) + + +class DSAPublicNumbers: + def __init__(self, y: int, parameter_numbers: DSAParameterNumbers): + if not isinstance(y, int): + raise TypeError("DSAPublicNumbers y argument must be an integer.") + + if not isinstance(parameter_numbers, DSAParameterNumbers): + raise TypeError( + "parameter_numbers must be a DSAParameterNumbers instance." + ) + + self._y = y + self._parameter_numbers = parameter_numbers + + @property + def y(self) -> int: + return self._y + + @property + def parameter_numbers(self) -> DSAParameterNumbers: + return self._parameter_numbers + + def public_key(self, backend: typing.Any = None) -> DSAPublicKey: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_dsa_public_numbers(self) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DSAPublicNumbers): + return NotImplemented + + return ( + self.y == other.y + and self.parameter_numbers == other.parameter_numbers + ) + + def __repr__(self) -> str: + return ( + "".format(self=self) + ) + + +class DSAPrivateNumbers: + def __init__(self, x: int, public_numbers: DSAPublicNumbers): + if not isinstance(x, int): + raise TypeError("DSAPrivateNumbers x argument must be an integer.") + + if not isinstance(public_numbers, DSAPublicNumbers): + raise TypeError( + "public_numbers must be a DSAPublicNumbers instance." + ) + self._public_numbers = public_numbers + self._x = x + + @property + def x(self) -> int: + return self._x + + @property + def public_numbers(self) -> DSAPublicNumbers: + return self._public_numbers + + def private_key(self, backend: typing.Any = None) -> DSAPrivateKey: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_dsa_private_numbers(self) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DSAPrivateNumbers): + return NotImplemented + + return ( + self.x == other.x and self.public_numbers == other.public_numbers + ) + + +def generate_parameters( + key_size: int, backend: typing.Any = None +) -> DSAParameters: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.generate_dsa_parameters(key_size) + + +def generate_private_key( + key_size: int, backend: typing.Any = None +) -> DSAPrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.generate_dsa_private_key_and_parameters(key_size) + + +def _check_dsa_parameters(parameters: DSAParameterNumbers) -> None: + if parameters.p.bit_length() not in [1024, 2048, 3072, 4096]: + raise ValueError( + "p must be exactly 1024, 2048, 3072, or 4096 bits long" + ) + if parameters.q.bit_length() not in [160, 224, 256]: + raise ValueError("q must be exactly 160, 224, or 256 bits long") + + if not (1 < parameters.g < parameters.p): + raise ValueError("g, p don't satisfy 1 < g < p.") + + +def _check_dsa_private_numbers(numbers: DSAPrivateNumbers) -> None: + parameters = numbers.public_numbers.parameter_numbers + _check_dsa_parameters(parameters) + if numbers.x <= 0 or numbers.x >= parameters.q: + raise ValueError("x must be > 0 and < q.") + + if numbers.public_numbers.y != pow(parameters.g, numbers.x, parameters.p): + raise ValueError("y must be equal to (g ** x % p).") diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ec.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ec.py new file mode 100644 index 0000000..ddfaabf --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ec.py @@ -0,0 +1,490 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +from cryptography import utils +from cryptography.hazmat._oid import ObjectIdentifier +from cryptography.hazmat.primitives import _serialization, hashes +from cryptography.hazmat.primitives.asymmetric import utils as asym_utils + + +class EllipticCurveOID: + SECP192R1 = ObjectIdentifier("1.2.840.10045.3.1.1") + SECP224R1 = ObjectIdentifier("1.3.132.0.33") + SECP256K1 = ObjectIdentifier("1.3.132.0.10") + SECP256R1 = ObjectIdentifier("1.2.840.10045.3.1.7") + SECP384R1 = ObjectIdentifier("1.3.132.0.34") + SECP521R1 = ObjectIdentifier("1.3.132.0.35") + BRAINPOOLP256R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.7") + BRAINPOOLP384R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.11") + BRAINPOOLP512R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.13") + SECT163K1 = ObjectIdentifier("1.3.132.0.1") + SECT163R2 = ObjectIdentifier("1.3.132.0.15") + SECT233K1 = ObjectIdentifier("1.3.132.0.26") + SECT233R1 = ObjectIdentifier("1.3.132.0.27") + SECT283K1 = ObjectIdentifier("1.3.132.0.16") + SECT283R1 = ObjectIdentifier("1.3.132.0.17") + SECT409K1 = ObjectIdentifier("1.3.132.0.36") + SECT409R1 = ObjectIdentifier("1.3.132.0.37") + SECT571K1 = ObjectIdentifier("1.3.132.0.38") + SECT571R1 = ObjectIdentifier("1.3.132.0.39") + + +class EllipticCurve(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def name(self) -> str: + """ + The name of the curve. e.g. secp256r1. + """ + + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + Bit size of a secret scalar for the curve. + """ + + +class EllipticCurveSignatureAlgorithm(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def algorithm( + self, + ) -> typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm]: + """ + The digest algorithm used with this signature. + """ + + +class EllipticCurvePrivateKey(metaclass=abc.ABCMeta): + @abc.abstractmethod + def exchange( + self, algorithm: ECDH, peer_public_key: EllipticCurvePublicKey + ) -> bytes: + """ + Performs a key exchange operation using the provided algorithm with the + provided peer's public key. + """ + + @abc.abstractmethod + def public_key(self) -> EllipticCurvePublicKey: + """ + The EllipticCurvePublicKey for this private key. + """ + + @property + @abc.abstractmethod + def curve(self) -> EllipticCurve: + """ + The EllipticCurve that this key is on. + """ + + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + Bit size of a secret scalar for the curve. + """ + + @abc.abstractmethod + def sign( + self, + data: bytes, + signature_algorithm: EllipticCurveSignatureAlgorithm, + ) -> bytes: + """ + Signs the data + """ + + @abc.abstractmethod + def private_numbers(self) -> EllipticCurvePrivateNumbers: + """ + Returns an EllipticCurvePrivateNumbers. + """ + + @abc.abstractmethod + def private_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PrivateFormat, + encryption_algorithm: _serialization.KeySerializationEncryption, + ) -> bytes: + """ + Returns the key serialized as bytes. + """ + + +EllipticCurvePrivateKeyWithSerialization = EllipticCurvePrivateKey + + +class EllipticCurvePublicKey(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def curve(self) -> EllipticCurve: + """ + The EllipticCurve that this key is on. + """ + + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + Bit size of a secret scalar for the curve. + """ + + @abc.abstractmethod + def public_numbers(self) -> EllipticCurvePublicNumbers: + """ + Returns an EllipticCurvePublicNumbers. + """ + + @abc.abstractmethod + def public_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PublicFormat, + ) -> bytes: + """ + Returns the key serialized as bytes. + """ + + @abc.abstractmethod + def verify( + self, + signature: bytes, + data: bytes, + signature_algorithm: EllipticCurveSignatureAlgorithm, + ) -> None: + """ + Verifies the signature of the data. + """ + + @classmethod + def from_encoded_point( + cls, curve: EllipticCurve, data: bytes + ) -> EllipticCurvePublicKey: + utils._check_bytes("data", data) + + if not isinstance(curve, EllipticCurve): + raise TypeError("curve must be an EllipticCurve instance") + + if len(data) == 0: + raise ValueError("data must not be an empty byte string") + + if data[0] not in [0x02, 0x03, 0x04]: + raise ValueError("Unsupported elliptic curve point type") + + from cryptography.hazmat.backends.openssl.backend import backend + + return backend.load_elliptic_curve_public_bytes(curve, data) + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + +EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey + + +class SECT571R1(EllipticCurve): + name = "sect571r1" + key_size = 570 + + +class SECT409R1(EllipticCurve): + name = "sect409r1" + key_size = 409 + + +class SECT283R1(EllipticCurve): + name = "sect283r1" + key_size = 283 + + +class SECT233R1(EllipticCurve): + name = "sect233r1" + key_size = 233 + + +class SECT163R2(EllipticCurve): + name = "sect163r2" + key_size = 163 + + +class SECT571K1(EllipticCurve): + name = "sect571k1" + key_size = 571 + + +class SECT409K1(EllipticCurve): + name = "sect409k1" + key_size = 409 + + +class SECT283K1(EllipticCurve): + name = "sect283k1" + key_size = 283 + + +class SECT233K1(EllipticCurve): + name = "sect233k1" + key_size = 233 + + +class SECT163K1(EllipticCurve): + name = "sect163k1" + key_size = 163 + + +class SECP521R1(EllipticCurve): + name = "secp521r1" + key_size = 521 + + +class SECP384R1(EllipticCurve): + name = "secp384r1" + key_size = 384 + + +class SECP256R1(EllipticCurve): + name = "secp256r1" + key_size = 256 + + +class SECP256K1(EllipticCurve): + name = "secp256k1" + key_size = 256 + + +class SECP224R1(EllipticCurve): + name = "secp224r1" + key_size = 224 + + +class SECP192R1(EllipticCurve): + name = "secp192r1" + key_size = 192 + + +class BrainpoolP256R1(EllipticCurve): + name = "brainpoolP256r1" + key_size = 256 + + +class BrainpoolP384R1(EllipticCurve): + name = "brainpoolP384r1" + key_size = 384 + + +class BrainpoolP512R1(EllipticCurve): + name = "brainpoolP512r1" + key_size = 512 + + +_CURVE_TYPES: typing.Dict[str, typing.Type[EllipticCurve]] = { + "prime192v1": SECP192R1, + "prime256v1": SECP256R1, + "secp192r1": SECP192R1, + "secp224r1": SECP224R1, + "secp256r1": SECP256R1, + "secp384r1": SECP384R1, + "secp521r1": SECP521R1, + "secp256k1": SECP256K1, + "sect163k1": SECT163K1, + "sect233k1": SECT233K1, + "sect283k1": SECT283K1, + "sect409k1": SECT409K1, + "sect571k1": SECT571K1, + "sect163r2": SECT163R2, + "sect233r1": SECT233R1, + "sect283r1": SECT283R1, + "sect409r1": SECT409R1, + "sect571r1": SECT571R1, + "brainpoolP256r1": BrainpoolP256R1, + "brainpoolP384r1": BrainpoolP384R1, + "brainpoolP512r1": BrainpoolP512R1, +} + + +class ECDSA(EllipticCurveSignatureAlgorithm): + def __init__( + self, + algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + ): + self._algorithm = algorithm + + @property + def algorithm( + self, + ) -> typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm]: + return self._algorithm + + +def generate_private_key( + curve: EllipticCurve, backend: typing.Any = None +) -> EllipticCurvePrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.generate_elliptic_curve_private_key(curve) + + +def derive_private_key( + private_value: int, + curve: EllipticCurve, + backend: typing.Any = None, +) -> EllipticCurvePrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + if not isinstance(private_value, int): + raise TypeError("private_value must be an integer type.") + + if private_value <= 0: + raise ValueError("private_value must be a positive integer.") + + if not isinstance(curve, EllipticCurve): + raise TypeError("curve must provide the EllipticCurve interface.") + + return ossl.derive_elliptic_curve_private_key(private_value, curve) + + +class EllipticCurvePublicNumbers: + def __init__(self, x: int, y: int, curve: EllipticCurve): + if not isinstance(x, int) or not isinstance(y, int): + raise TypeError("x and y must be integers.") + + if not isinstance(curve, EllipticCurve): + raise TypeError("curve must provide the EllipticCurve interface.") + + self._y = y + self._x = x + self._curve = curve + + def public_key(self, backend: typing.Any = None) -> EllipticCurvePublicKey: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_elliptic_curve_public_numbers(self) + + @property + def curve(self) -> EllipticCurve: + return self._curve + + @property + def x(self) -> int: + return self._x + + @property + def y(self) -> int: + return self._y + + def __eq__(self, other: object) -> bool: + if not isinstance(other, EllipticCurvePublicNumbers): + return NotImplemented + + return ( + self.x == other.x + and self.y == other.y + and self.curve.name == other.curve.name + and self.curve.key_size == other.curve.key_size + ) + + def __hash__(self) -> int: + return hash((self.x, self.y, self.curve.name, self.curve.key_size)) + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + +class EllipticCurvePrivateNumbers: + def __init__( + self, private_value: int, public_numbers: EllipticCurvePublicNumbers + ): + if not isinstance(private_value, int): + raise TypeError("private_value must be an integer.") + + if not isinstance(public_numbers, EllipticCurvePublicNumbers): + raise TypeError( + "public_numbers must be an EllipticCurvePublicNumbers " + "instance." + ) + + self._private_value = private_value + self._public_numbers = public_numbers + + def private_key( + self, backend: typing.Any = None + ) -> EllipticCurvePrivateKey: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_elliptic_curve_private_numbers(self) + + @property + def private_value(self) -> int: + return self._private_value + + @property + def public_numbers(self) -> EllipticCurvePublicNumbers: + return self._public_numbers + + def __eq__(self, other: object) -> bool: + if not isinstance(other, EllipticCurvePrivateNumbers): + return NotImplemented + + return ( + self.private_value == other.private_value + and self.public_numbers == other.public_numbers + ) + + def __hash__(self) -> int: + return hash((self.private_value, self.public_numbers)) + + +class ECDH: + pass + + +_OID_TO_CURVE = { + EllipticCurveOID.SECP192R1: SECP192R1, + EllipticCurveOID.SECP224R1: SECP224R1, + EllipticCurveOID.SECP256K1: SECP256K1, + EllipticCurveOID.SECP256R1: SECP256R1, + EllipticCurveOID.SECP384R1: SECP384R1, + EllipticCurveOID.SECP521R1: SECP521R1, + EllipticCurveOID.BRAINPOOLP256R1: BrainpoolP256R1, + EllipticCurveOID.BRAINPOOLP384R1: BrainpoolP384R1, + EllipticCurveOID.BRAINPOOLP512R1: BrainpoolP512R1, + EllipticCurveOID.SECT163K1: SECT163K1, + EllipticCurveOID.SECT163R2: SECT163R2, + EllipticCurveOID.SECT233K1: SECT233K1, + EllipticCurveOID.SECT233R1: SECT233R1, + EllipticCurveOID.SECT283K1: SECT283K1, + EllipticCurveOID.SECT283R1: SECT283R1, + EllipticCurveOID.SECT409K1: SECT409K1, + EllipticCurveOID.SECT409R1: SECT409R1, + EllipticCurveOID.SECT571K1: SECT571K1, + EllipticCurveOID.SECT571R1: SECT571R1, +} + + +def get_curve_for_oid(oid: ObjectIdentifier) -> typing.Type[EllipticCurve]: + try: + return _OID_TO_CURVE[oid] + except KeyError: + raise LookupError( + "The provided object identifier has no matching elliptic " + "curve class" + ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py new file mode 100644 index 0000000..f26e54d --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed25519.py @@ -0,0 +1,118 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc + +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.primitives import _serialization + + +class Ed25519PublicKey(metaclass=abc.ABCMeta): + @classmethod + def from_public_bytes(cls, data: bytes) -> Ed25519PublicKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.ed25519_supported(): + raise UnsupportedAlgorithm( + "ed25519 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, + ) + + return backend.ed25519_load_public_bytes(data) + + @abc.abstractmethod + def public_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PublicFormat, + ) -> bytes: + """ + The serialized bytes of the public key. + """ + + @abc.abstractmethod + def public_bytes_raw(self) -> bytes: + """ + The raw bytes of the public key. + Equivalent to public_bytes(Raw, Raw). + """ + + @abc.abstractmethod + def verify(self, signature: bytes, data: bytes) -> None: + """ + Verify the signature. + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + +if hasattr(rust_openssl, "ed25519"): + Ed25519PublicKey.register(rust_openssl.ed25519.Ed25519PublicKey) + + +class Ed25519PrivateKey(metaclass=abc.ABCMeta): + @classmethod + def generate(cls) -> Ed25519PrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.ed25519_supported(): + raise UnsupportedAlgorithm( + "ed25519 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, + ) + + return backend.ed25519_generate_key() + + @classmethod + def from_private_bytes(cls, data: bytes) -> Ed25519PrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.ed25519_supported(): + raise UnsupportedAlgorithm( + "ed25519 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, + ) + + return backend.ed25519_load_private_bytes(data) + + @abc.abstractmethod + def public_key(self) -> Ed25519PublicKey: + """ + The Ed25519PublicKey derived from the private key. + """ + + @abc.abstractmethod + def private_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PrivateFormat, + encryption_algorithm: _serialization.KeySerializationEncryption, + ) -> bytes: + """ + The serialized bytes of the private key. + """ + + @abc.abstractmethod + def private_bytes_raw(self) -> bytes: + """ + The raw bytes of the private key. + Equivalent to private_bytes(Raw, Raw, NoEncryption()). + """ + + @abc.abstractmethod + def sign(self, data: bytes) -> bytes: + """ + Signs the data. + """ + + +if hasattr(rust_openssl, "x25519"): + Ed25519PrivateKey.register(rust_openssl.ed25519.Ed25519PrivateKey) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py new file mode 100644 index 0000000..a9a34b2 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/ed448.py @@ -0,0 +1,117 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc + +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.primitives import _serialization + + +class Ed448PublicKey(metaclass=abc.ABCMeta): + @classmethod + def from_public_bytes(cls, data: bytes) -> Ed448PublicKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.ed448_supported(): + raise UnsupportedAlgorithm( + "ed448 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, + ) + + return backend.ed448_load_public_bytes(data) + + @abc.abstractmethod + def public_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PublicFormat, + ) -> bytes: + """ + The serialized bytes of the public key. + """ + + @abc.abstractmethod + def public_bytes_raw(self) -> bytes: + """ + The raw bytes of the public key. + Equivalent to public_bytes(Raw, Raw). + """ + + @abc.abstractmethod + def verify(self, signature: bytes, data: bytes) -> None: + """ + Verify the signature. + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + +if hasattr(rust_openssl, "ed448"): + Ed448PublicKey.register(rust_openssl.ed448.Ed448PublicKey) + + +class Ed448PrivateKey(metaclass=abc.ABCMeta): + @classmethod + def generate(cls) -> Ed448PrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.ed448_supported(): + raise UnsupportedAlgorithm( + "ed448 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, + ) + return backend.ed448_generate_key() + + @classmethod + def from_private_bytes(cls, data: bytes) -> Ed448PrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.ed448_supported(): + raise UnsupportedAlgorithm( + "ed448 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM, + ) + + return backend.ed448_load_private_bytes(data) + + @abc.abstractmethod + def public_key(self) -> Ed448PublicKey: + """ + The Ed448PublicKey derived from the private key. + """ + + @abc.abstractmethod + def sign(self, data: bytes) -> bytes: + """ + Signs the data. + """ + + @abc.abstractmethod + def private_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PrivateFormat, + encryption_algorithm: _serialization.KeySerializationEncryption, + ) -> bytes: + """ + The serialized bytes of the private key. + """ + + @abc.abstractmethod + def private_bytes_raw(self) -> bytes: + """ + The raw bytes of the private key. + Equivalent to private_bytes(Raw, Raw, NoEncryption()). + """ + + +if hasattr(rust_openssl, "x448"): + Ed448PrivateKey.register(rust_openssl.ed448.Ed448PrivateKey) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/padding.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/padding.py new file mode 100644 index 0000000..7198808 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/padding.py @@ -0,0 +1,102 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives._asymmetric import ( + AsymmetricPadding as AsymmetricPadding, +) +from cryptography.hazmat.primitives.asymmetric import rsa + + +class PKCS1v15(AsymmetricPadding): + name = "EMSA-PKCS1-v1_5" + + +class _MaxLength: + "Sentinel value for `MAX_LENGTH`." + + +class _Auto: + "Sentinel value for `AUTO`." + + +class _DigestLength: + "Sentinel value for `DIGEST_LENGTH`." + + +class PSS(AsymmetricPadding): + MAX_LENGTH = _MaxLength() + AUTO = _Auto() + DIGEST_LENGTH = _DigestLength() + name = "EMSA-PSS" + _salt_length: typing.Union[int, _MaxLength, _Auto, _DigestLength] + + def __init__( + self, + mgf: MGF, + salt_length: typing.Union[int, _MaxLength, _Auto, _DigestLength], + ) -> None: + self._mgf = mgf + + if not isinstance( + salt_length, (int, _MaxLength, _Auto, _DigestLength) + ): + raise TypeError( + "salt_length must be an integer, MAX_LENGTH, " + "DIGEST_LENGTH, or AUTO" + ) + + if isinstance(salt_length, int) and salt_length < 0: + raise ValueError("salt_length must be zero or greater.") + + self._salt_length = salt_length + + +class OAEP(AsymmetricPadding): + name = "EME-OAEP" + + def __init__( + self, + mgf: MGF, + algorithm: hashes.HashAlgorithm, + label: typing.Optional[bytes], + ): + if not isinstance(algorithm, hashes.HashAlgorithm): + raise TypeError("Expected instance of hashes.HashAlgorithm.") + + self._mgf = mgf + self._algorithm = algorithm + self._label = label + + +class MGF(metaclass=abc.ABCMeta): + _algorithm: hashes.HashAlgorithm + + +class MGF1(MGF): + MAX_LENGTH = _MaxLength() + + def __init__(self, algorithm: hashes.HashAlgorithm): + if not isinstance(algorithm, hashes.HashAlgorithm): + raise TypeError("Expected instance of hashes.HashAlgorithm.") + + self._algorithm = algorithm + + +def calculate_max_pss_salt_length( + key: typing.Union[rsa.RSAPrivateKey, rsa.RSAPublicKey], + hash_algorithm: hashes.HashAlgorithm, +) -> int: + if not isinstance(key, (rsa.RSAPrivateKey, rsa.RSAPublicKey)): + raise TypeError("key must be an RSA public or private key") + # bit length - 1 per RFC 3447 + emlen = (key.key_size + 6) // 8 + salt_length = emlen - hash_algorithm.digest_size - 2 + assert salt_length >= 0 + return salt_length diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py new file mode 100644 index 0000000..b740f01 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -0,0 +1,439 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing +from math import gcd + +from cryptography.hazmat.primitives import _serialization, hashes +from cryptography.hazmat.primitives._asymmetric import AsymmetricPadding +from cryptography.hazmat.primitives.asymmetric import utils as asym_utils + + +class RSAPrivateKey(metaclass=abc.ABCMeta): + @abc.abstractmethod + def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes: + """ + Decrypts the provided ciphertext. + """ + + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + The bit length of the public modulus. + """ + + @abc.abstractmethod + def public_key(self) -> RSAPublicKey: + """ + The RSAPublicKey associated with this private key. + """ + + @abc.abstractmethod + def sign( + self, + data: bytes, + padding: AsymmetricPadding, + algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + ) -> bytes: + """ + Signs the data. + """ + + @abc.abstractmethod + def private_numbers(self) -> RSAPrivateNumbers: + """ + Returns an RSAPrivateNumbers. + """ + + @abc.abstractmethod + def private_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PrivateFormat, + encryption_algorithm: _serialization.KeySerializationEncryption, + ) -> bytes: + """ + Returns the key serialized as bytes. + """ + + +RSAPrivateKeyWithSerialization = RSAPrivateKey + + +class RSAPublicKey(metaclass=abc.ABCMeta): + @abc.abstractmethod + def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes: + """ + Encrypts the given plaintext. + """ + + @property + @abc.abstractmethod + def key_size(self) -> int: + """ + The bit length of the public modulus. + """ + + @abc.abstractmethod + def public_numbers(self) -> RSAPublicNumbers: + """ + Returns an RSAPublicNumbers + """ + + @abc.abstractmethod + def public_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PublicFormat, + ) -> bytes: + """ + Returns the key serialized as bytes. + """ + + @abc.abstractmethod + def verify( + self, + signature: bytes, + data: bytes, + padding: AsymmetricPadding, + algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm], + ) -> None: + """ + Verifies the signature of the data. + """ + + @abc.abstractmethod + def recover_data_from_signature( + self, + signature: bytes, + padding: AsymmetricPadding, + algorithm: typing.Optional[hashes.HashAlgorithm], + ) -> bytes: + """ + Recovers the original data from the signature. + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + +RSAPublicKeyWithSerialization = RSAPublicKey + + +def generate_private_key( + public_exponent: int, + key_size: int, + backend: typing.Any = None, +) -> RSAPrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + _verify_rsa_parameters(public_exponent, key_size) + return ossl.generate_rsa_private_key(public_exponent, key_size) + + +def _verify_rsa_parameters(public_exponent: int, key_size: int) -> None: + if public_exponent not in (3, 65537): + raise ValueError( + "public_exponent must be either 3 (for legacy compatibility) or " + "65537. Almost everyone should choose 65537 here!" + ) + + if key_size < 512: + raise ValueError("key_size must be at least 512-bits.") + + +def _check_private_key_components( + p: int, + q: int, + private_exponent: int, + dmp1: int, + dmq1: int, + iqmp: int, + public_exponent: int, + modulus: int, +) -> None: + if modulus < 3: + raise ValueError("modulus must be >= 3.") + + if p >= modulus: + raise ValueError("p must be < modulus.") + + if q >= modulus: + raise ValueError("q must be < modulus.") + + if dmp1 >= modulus: + raise ValueError("dmp1 must be < modulus.") + + if dmq1 >= modulus: + raise ValueError("dmq1 must be < modulus.") + + if iqmp >= modulus: + raise ValueError("iqmp must be < modulus.") + + if private_exponent >= modulus: + raise ValueError("private_exponent must be < modulus.") + + if public_exponent < 3 or public_exponent >= modulus: + raise ValueError("public_exponent must be >= 3 and < modulus.") + + if public_exponent & 1 == 0: + raise ValueError("public_exponent must be odd.") + + if dmp1 & 1 == 0: + raise ValueError("dmp1 must be odd.") + + if dmq1 & 1 == 0: + raise ValueError("dmq1 must be odd.") + + if p * q != modulus: + raise ValueError("p*q must equal modulus.") + + +def _check_public_key_components(e: int, n: int) -> None: + if n < 3: + raise ValueError("n must be >= 3.") + + if e < 3 or e >= n: + raise ValueError("e must be >= 3 and < n.") + + if e & 1 == 0: + raise ValueError("e must be odd.") + + +def _modinv(e: int, m: int) -> int: + """ + Modular Multiplicative Inverse. Returns x such that: (x*e) mod m == 1 + """ + x1, x2 = 1, 0 + a, b = e, m + while b > 0: + q, r = divmod(a, b) + xn = x1 - q * x2 + a, b, x1, x2 = b, r, x2, xn + return x1 % m + + +def rsa_crt_iqmp(p: int, q: int) -> int: + """ + Compute the CRT (q ** -1) % p value from RSA primes p and q. + """ + return _modinv(q, p) + + +def rsa_crt_dmp1(private_exponent: int, p: int) -> int: + """ + Compute the CRT private_exponent % (p - 1) value from the RSA + private_exponent (d) and p. + """ + return private_exponent % (p - 1) + + +def rsa_crt_dmq1(private_exponent: int, q: int) -> int: + """ + Compute the CRT private_exponent % (q - 1) value from the RSA + private_exponent (d) and q. + """ + return private_exponent % (q - 1) + + +# Controls the number of iterations rsa_recover_prime_factors will perform +# to obtain the prime factors. Each iteration increments by 2 so the actual +# maximum attempts is half this number. +_MAX_RECOVERY_ATTEMPTS = 1000 + + +def rsa_recover_prime_factors( + n: int, e: int, d: int +) -> typing.Tuple[int, int]: + """ + Compute factors p and q from the private exponent d. We assume that n has + no more than two factors. This function is adapted from code in PyCrypto. + """ + # See 8.2.2(i) in Handbook of Applied Cryptography. + ktot = d * e - 1 + # The quantity d*e-1 is a multiple of phi(n), even, + # and can be represented as t*2^s. + t = ktot + while t % 2 == 0: + t = t // 2 + # Cycle through all multiplicative inverses in Zn. + # The algorithm is non-deterministic, but there is a 50% chance + # any candidate a leads to successful factoring. + # See "Digitalized Signatures and Public Key Functions as Intractable + # as Factorization", M. Rabin, 1979 + spotted = False + a = 2 + while not spotted and a < _MAX_RECOVERY_ATTEMPTS: + k = t + # Cycle through all values a^{t*2^i}=a^k + while k < ktot: + cand = pow(a, k, n) + # Check if a^k is a non-trivial root of unity (mod n) + if cand != 1 and cand != (n - 1) and pow(cand, 2, n) == 1: + # We have found a number such that (cand-1)(cand+1)=0 (mod n). + # Either of the terms divides n. + p = gcd(cand + 1, n) + spotted = True + break + k *= 2 + # This value was not any good... let's try another! + a += 2 + if not spotted: + raise ValueError("Unable to compute factors p and q from exponent d.") + # Found ! + q, r = divmod(n, p) + assert r == 0 + p, q = sorted((p, q), reverse=True) + return (p, q) + + +class RSAPrivateNumbers: + def __init__( + self, + p: int, + q: int, + d: int, + dmp1: int, + dmq1: int, + iqmp: int, + public_numbers: RSAPublicNumbers, + ): + if ( + not isinstance(p, int) + or not isinstance(q, int) + or not isinstance(d, int) + or not isinstance(dmp1, int) + or not isinstance(dmq1, int) + or not isinstance(iqmp, int) + ): + raise TypeError( + "RSAPrivateNumbers p, q, d, dmp1, dmq1, iqmp arguments must" + " all be an integers." + ) + + if not isinstance(public_numbers, RSAPublicNumbers): + raise TypeError( + "RSAPrivateNumbers public_numbers must be an RSAPublicNumbers" + " instance." + ) + + self._p = p + self._q = q + self._d = d + self._dmp1 = dmp1 + self._dmq1 = dmq1 + self._iqmp = iqmp + self._public_numbers = public_numbers + + @property + def p(self) -> int: + return self._p + + @property + def q(self) -> int: + return self._q + + @property + def d(self) -> int: + return self._d + + @property + def dmp1(self) -> int: + return self._dmp1 + + @property + def dmq1(self) -> int: + return self._dmq1 + + @property + def iqmp(self) -> int: + return self._iqmp + + @property + def public_numbers(self) -> RSAPublicNumbers: + return self._public_numbers + + def private_key( + self, + backend: typing.Any = None, + *, + unsafe_skip_rsa_key_validation: bool = False, + ) -> RSAPrivateKey: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_rsa_private_numbers( + self, unsafe_skip_rsa_key_validation + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, RSAPrivateNumbers): + return NotImplemented + + return ( + self.p == other.p + and self.q == other.q + and self.d == other.d + and self.dmp1 == other.dmp1 + and self.dmq1 == other.dmq1 + and self.iqmp == other.iqmp + and self.public_numbers == other.public_numbers + ) + + def __hash__(self) -> int: + return hash( + ( + self.p, + self.q, + self.d, + self.dmp1, + self.dmq1, + self.iqmp, + self.public_numbers, + ) + ) + + +class RSAPublicNumbers: + def __init__(self, e: int, n: int): + if not isinstance(e, int) or not isinstance(n, int): + raise TypeError("RSAPublicNumbers arguments must be integers.") + + self._e = e + self._n = n + + @property + def e(self) -> int: + return self._e + + @property + def n(self) -> int: + return self._n + + def public_key(self, backend: typing.Any = None) -> RSAPublicKey: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + return ossl.load_rsa_public_numbers(self) + + def __repr__(self) -> str: + return "".format(self) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, RSAPublicNumbers): + return NotImplemented + + return self.e == other.e and self.n == other.n + + def __hash__(self) -> int: + return hash((self.e, self.n)) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/types.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/types.py new file mode 100644 index 0000000..1fe4eaf --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/types.py @@ -0,0 +1,111 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography import utils +from cryptography.hazmat.primitives.asymmetric import ( + dh, + dsa, + ec, + ed448, + ed25519, + rsa, + x448, + x25519, +) + +# Every asymmetric key type +PublicKeyTypes = typing.Union[ + dh.DHPublicKey, + dsa.DSAPublicKey, + rsa.RSAPublicKey, + ec.EllipticCurvePublicKey, + ed25519.Ed25519PublicKey, + ed448.Ed448PublicKey, + x25519.X25519PublicKey, + x448.X448PublicKey, +] +PUBLIC_KEY_TYPES = PublicKeyTypes +utils.deprecated( + PUBLIC_KEY_TYPES, + __name__, + "Use PublicKeyTypes instead", + utils.DeprecatedIn40, + name="PUBLIC_KEY_TYPES", +) +# Every asymmetric key type +PrivateKeyTypes = typing.Union[ + dh.DHPrivateKey, + ed25519.Ed25519PrivateKey, + ed448.Ed448PrivateKey, + rsa.RSAPrivateKey, + dsa.DSAPrivateKey, + ec.EllipticCurvePrivateKey, + x25519.X25519PrivateKey, + x448.X448PrivateKey, +] +PRIVATE_KEY_TYPES = PrivateKeyTypes +utils.deprecated( + PRIVATE_KEY_TYPES, + __name__, + "Use PrivateKeyTypes instead", + utils.DeprecatedIn40, + name="PRIVATE_KEY_TYPES", +) +# Just the key types we allow to be used for x509 signing. This mirrors +# the certificate public key types +CertificateIssuerPrivateKeyTypes = typing.Union[ + ed25519.Ed25519PrivateKey, + ed448.Ed448PrivateKey, + rsa.RSAPrivateKey, + dsa.DSAPrivateKey, + ec.EllipticCurvePrivateKey, +] +CERTIFICATE_PRIVATE_KEY_TYPES = CertificateIssuerPrivateKeyTypes +utils.deprecated( + CERTIFICATE_PRIVATE_KEY_TYPES, + __name__, + "Use CertificateIssuerPrivateKeyTypes instead", + utils.DeprecatedIn40, + name="CERTIFICATE_PRIVATE_KEY_TYPES", +) +# Just the key types we allow to be used for x509 signing. This mirrors +# the certificate private key types +CertificateIssuerPublicKeyTypes = typing.Union[ + dsa.DSAPublicKey, + rsa.RSAPublicKey, + ec.EllipticCurvePublicKey, + ed25519.Ed25519PublicKey, + ed448.Ed448PublicKey, +] +CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES = CertificateIssuerPublicKeyTypes +utils.deprecated( + CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES, + __name__, + "Use CertificateIssuerPublicKeyTypes instead", + utils.DeprecatedIn40, + name="CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES", +) +# This type removes DHPublicKey. x448/x25519 can be a public key +# but cannot be used in signing so they are allowed here. +CertificatePublicKeyTypes = typing.Union[ + dsa.DSAPublicKey, + rsa.RSAPublicKey, + ec.EllipticCurvePublicKey, + ed25519.Ed25519PublicKey, + ed448.Ed448PublicKey, + x25519.X25519PublicKey, + x448.X448PublicKey, +] +CERTIFICATE_PUBLIC_KEY_TYPES = CertificatePublicKeyTypes +utils.deprecated( + CERTIFICATE_PUBLIC_KEY_TYPES, + __name__, + "Use CertificatePublicKeyTypes instead", + utils.DeprecatedIn40, + name="CERTIFICATE_PUBLIC_KEY_TYPES", +) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/utils.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/utils.py new file mode 100644 index 0000000..826b956 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/utils.py @@ -0,0 +1,24 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography.hazmat.bindings._rust import asn1 +from cryptography.hazmat.primitives import hashes + +decode_dss_signature = asn1.decode_dss_signature +encode_dss_signature = asn1.encode_dss_signature + + +class Prehashed: + def __init__(self, algorithm: hashes.HashAlgorithm): + if not isinstance(algorithm, hashes.HashAlgorithm): + raise TypeError("Expected instance of HashAlgorithm.") + + self._algorithm = algorithm + self._digest_size = algorithm.digest_size + + @property + def digest_size(self) -> int: + return self._digest_size diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py new file mode 100644 index 0000000..699054c --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x25519.py @@ -0,0 +1,113 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc + +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.primitives import _serialization + + +class X25519PublicKey(metaclass=abc.ABCMeta): + @classmethod + def from_public_bytes(cls, data: bytes) -> X25519PublicKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.x25519_supported(): + raise UnsupportedAlgorithm( + "X25519 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, + ) + + return backend.x25519_load_public_bytes(data) + + @abc.abstractmethod + def public_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PublicFormat, + ) -> bytes: + """ + The serialized bytes of the public key. + """ + + @abc.abstractmethod + def public_bytes_raw(self) -> bytes: + """ + The raw bytes of the public key. + Equivalent to public_bytes(Raw, Raw). + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + +# For LibreSSL +if hasattr(rust_openssl, "x25519"): + X25519PublicKey.register(rust_openssl.x25519.X25519PublicKey) + + +class X25519PrivateKey(metaclass=abc.ABCMeta): + @classmethod + def generate(cls) -> X25519PrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.x25519_supported(): + raise UnsupportedAlgorithm( + "X25519 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, + ) + return backend.x25519_generate_key() + + @classmethod + def from_private_bytes(cls, data: bytes) -> X25519PrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.x25519_supported(): + raise UnsupportedAlgorithm( + "X25519 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, + ) + + return backend.x25519_load_private_bytes(data) + + @abc.abstractmethod + def public_key(self) -> X25519PublicKey: + """ + Returns the public key assosciated with this private key + """ + + @abc.abstractmethod + def private_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PrivateFormat, + encryption_algorithm: _serialization.KeySerializationEncryption, + ) -> bytes: + """ + The serialized bytes of the private key. + """ + + @abc.abstractmethod + def private_bytes_raw(self) -> bytes: + """ + The raw bytes of the private key. + Equivalent to private_bytes(Raw, Raw, NoEncryption()). + """ + + @abc.abstractmethod + def exchange(self, peer_public_key: X25519PublicKey) -> bytes: + """ + Performs a key exchange operation using the provided peer's public key. + """ + + +# For LibreSSL +if hasattr(rust_openssl, "x25519"): + X25519PrivateKey.register(rust_openssl.x25519.X25519PrivateKey) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x448.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x448.py new file mode 100644 index 0000000..abf7848 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/asymmetric/x448.py @@ -0,0 +1,111 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc + +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.primitives import _serialization + + +class X448PublicKey(metaclass=abc.ABCMeta): + @classmethod + def from_public_bytes(cls, data: bytes) -> X448PublicKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.x448_supported(): + raise UnsupportedAlgorithm( + "X448 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, + ) + + return backend.x448_load_public_bytes(data) + + @abc.abstractmethod + def public_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PublicFormat, + ) -> bytes: + """ + The serialized bytes of the public key. + """ + + @abc.abstractmethod + def public_bytes_raw(self) -> bytes: + """ + The raw bytes of the public key. + Equivalent to public_bytes(Raw, Raw). + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + +if hasattr(rust_openssl, "x448"): + X448PublicKey.register(rust_openssl.x448.X448PublicKey) + + +class X448PrivateKey(metaclass=abc.ABCMeta): + @classmethod + def generate(cls) -> X448PrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.x448_supported(): + raise UnsupportedAlgorithm( + "X448 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, + ) + return backend.x448_generate_key() + + @classmethod + def from_private_bytes(cls, data: bytes) -> X448PrivateKey: + from cryptography.hazmat.backends.openssl.backend import backend + + if not backend.x448_supported(): + raise UnsupportedAlgorithm( + "X448 is not supported by this version of OpenSSL.", + _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM, + ) + + return backend.x448_load_private_bytes(data) + + @abc.abstractmethod + def public_key(self) -> X448PublicKey: + """ + Returns the public key associated with this private key + """ + + @abc.abstractmethod + def private_bytes( + self, + encoding: _serialization.Encoding, + format: _serialization.PrivateFormat, + encryption_algorithm: _serialization.KeySerializationEncryption, + ) -> bytes: + """ + The serialized bytes of the private key. + """ + + @abc.abstractmethod + def private_bytes_raw(self) -> bytes: + """ + The raw bytes of the private key. + Equivalent to private_bytes(Raw, Raw, NoEncryption()). + """ + + @abc.abstractmethod + def exchange(self, peer_public_key: X448PublicKey) -> bytes: + """ + Performs a key exchange operation using the provided peer's public key. + """ + + +if hasattr(rust_openssl, "x448"): + X448PrivateKey.register(rust_openssl.x448.X448PrivateKey) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__init__.py new file mode 100644 index 0000000..cc88fbf --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__init__.py @@ -0,0 +1,27 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography.hazmat.primitives._cipheralgorithm import ( + BlockCipherAlgorithm, + CipherAlgorithm, +) +from cryptography.hazmat.primitives.ciphers.base import ( + AEADCipherContext, + AEADDecryptionContext, + AEADEncryptionContext, + Cipher, + CipherContext, +) + +__all__ = [ + "Cipher", + "CipherAlgorithm", + "BlockCipherAlgorithm", + "CipherContext", + "AEADCipherContext", + "AEADDecryptionContext", + "AEADEncryptionContext", +] diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..5133851 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/algorithms.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/algorithms.cpython-310.opt-1.pyc new file mode 100644 index 0000000..43c068b Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/algorithms.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/base.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/base.cpython-310.opt-1.pyc new file mode 100644 index 0000000..07eea5d Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/base.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/modes.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/modes.cpython-310.opt-1.pyc new file mode 100644 index 0000000..ca8e6a8 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/__pycache__/modes.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/aead.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/aead.py new file mode 100644 index 0000000..957b2d2 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/aead.py @@ -0,0 +1,378 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import os +import typing + +from cryptography import exceptions, utils +from cryptography.hazmat.backends.openssl import aead +from cryptography.hazmat.backends.openssl.backend import backend +from cryptography.hazmat.bindings._rust import FixedPool + + +class ChaCha20Poly1305: + _MAX_SIZE = 2**31 - 1 + + def __init__(self, key: bytes): + if not backend.aead_cipher_supported(self): + raise exceptions.UnsupportedAlgorithm( + "ChaCha20Poly1305 is not supported by this version of OpenSSL", + exceptions._Reasons.UNSUPPORTED_CIPHER, + ) + utils._check_byteslike("key", key) + + if len(key) != 32: + raise ValueError("ChaCha20Poly1305 key must be 32 bytes.") + + self._key = key + self._pool = FixedPool(self._create_fn) + + @classmethod + def generate_key(cls) -> bytes: + return os.urandom(32) + + def _create_fn(self): + return aead._aead_create_ctx(backend, self, self._key) + + def encrypt( + self, + nonce: bytes, + data: bytes, + associated_data: typing.Optional[bytes], + ) -> bytes: + if associated_data is None: + associated_data = b"" + + if len(data) > self._MAX_SIZE or len(associated_data) > self._MAX_SIZE: + # This is OverflowError to match what cffi would raise + raise OverflowError( + "Data or associated data too long. Max 2**31 - 1 bytes" + ) + + self._check_params(nonce, data, associated_data) + with self._pool.acquire() as ctx: + return aead._encrypt( + backend, self, nonce, data, [associated_data], 16, ctx + ) + + def decrypt( + self, + nonce: bytes, + data: bytes, + associated_data: typing.Optional[bytes], + ) -> bytes: + if associated_data is None: + associated_data = b"" + + self._check_params(nonce, data, associated_data) + with self._pool.acquire() as ctx: + return aead._decrypt( + backend, self, nonce, data, [associated_data], 16, ctx + ) + + def _check_params( + self, + nonce: bytes, + data: bytes, + associated_data: bytes, + ) -> None: + utils._check_byteslike("nonce", nonce) + utils._check_byteslike("data", data) + utils._check_byteslike("associated_data", associated_data) + if len(nonce) != 12: + raise ValueError("Nonce must be 12 bytes") + + +class AESCCM: + _MAX_SIZE = 2**31 - 1 + + def __init__(self, key: bytes, tag_length: int = 16): + utils._check_byteslike("key", key) + if len(key) not in (16, 24, 32): + raise ValueError("AESCCM key must be 128, 192, or 256 bits.") + + self._key = key + if not isinstance(tag_length, int): + raise TypeError("tag_length must be an integer") + + if tag_length not in (4, 6, 8, 10, 12, 14, 16): + raise ValueError("Invalid tag_length") + + self._tag_length = tag_length + + if not backend.aead_cipher_supported(self): + raise exceptions.UnsupportedAlgorithm( + "AESCCM is not supported by this version of OpenSSL", + exceptions._Reasons.UNSUPPORTED_CIPHER, + ) + + @classmethod + def generate_key(cls, bit_length: int) -> bytes: + if not isinstance(bit_length, int): + raise TypeError("bit_length must be an integer") + + if bit_length not in (128, 192, 256): + raise ValueError("bit_length must be 128, 192, or 256") + + return os.urandom(bit_length // 8) + + def encrypt( + self, + nonce: bytes, + data: bytes, + associated_data: typing.Optional[bytes], + ) -> bytes: + if associated_data is None: + associated_data = b"" + + if len(data) > self._MAX_SIZE or len(associated_data) > self._MAX_SIZE: + # This is OverflowError to match what cffi would raise + raise OverflowError( + "Data or associated data too long. Max 2**31 - 1 bytes" + ) + + self._check_params(nonce, data, associated_data) + self._validate_lengths(nonce, len(data)) + return aead._encrypt( + backend, self, nonce, data, [associated_data], self._tag_length + ) + + def decrypt( + self, + nonce: bytes, + data: bytes, + associated_data: typing.Optional[bytes], + ) -> bytes: + if associated_data is None: + associated_data = b"" + + self._check_params(nonce, data, associated_data) + return aead._decrypt( + backend, self, nonce, data, [associated_data], self._tag_length + ) + + def _validate_lengths(self, nonce: bytes, data_len: int) -> None: + # For information about computing this, see + # https://tools.ietf.org/html/rfc3610#section-2.1 + l_val = 15 - len(nonce) + if 2 ** (8 * l_val) < data_len: + raise ValueError("Data too long for nonce") + + def _check_params( + self, nonce: bytes, data: bytes, associated_data: bytes + ) -> None: + utils._check_byteslike("nonce", nonce) + utils._check_byteslike("data", data) + utils._check_byteslike("associated_data", associated_data) + if not 7 <= len(nonce) <= 13: + raise ValueError("Nonce must be between 7 and 13 bytes") + + +class AESGCM: + _MAX_SIZE = 2**31 - 1 + + def __init__(self, key: bytes): + utils._check_byteslike("key", key) + if len(key) not in (16, 24, 32): + raise ValueError("AESGCM key must be 128, 192, or 256 bits.") + + self._key = key + + @classmethod + def generate_key(cls, bit_length: int) -> bytes: + if not isinstance(bit_length, int): + raise TypeError("bit_length must be an integer") + + if bit_length not in (128, 192, 256): + raise ValueError("bit_length must be 128, 192, or 256") + + return os.urandom(bit_length // 8) + + def encrypt( + self, + nonce: bytes, + data: bytes, + associated_data: typing.Optional[bytes], + ) -> bytes: + if associated_data is None: + associated_data = b"" + + if len(data) > self._MAX_SIZE or len(associated_data) > self._MAX_SIZE: + # This is OverflowError to match what cffi would raise + raise OverflowError( + "Data or associated data too long. Max 2**31 - 1 bytes" + ) + + self._check_params(nonce, data, associated_data) + return aead._encrypt(backend, self, nonce, data, [associated_data], 16) + + def decrypt( + self, + nonce: bytes, + data: bytes, + associated_data: typing.Optional[bytes], + ) -> bytes: + if associated_data is None: + associated_data = b"" + + self._check_params(nonce, data, associated_data) + return aead._decrypt(backend, self, nonce, data, [associated_data], 16) + + def _check_params( + self, + nonce: bytes, + data: bytes, + associated_data: bytes, + ) -> None: + utils._check_byteslike("nonce", nonce) + utils._check_byteslike("data", data) + utils._check_byteslike("associated_data", associated_data) + if len(nonce) < 8 or len(nonce) > 128: + raise ValueError("Nonce must be between 8 and 128 bytes") + + +class AESOCB3: + _MAX_SIZE = 2**31 - 1 + + def __init__(self, key: bytes): + utils._check_byteslike("key", key) + if len(key) not in (16, 24, 32): + raise ValueError("AESOCB3 key must be 128, 192, or 256 bits.") + + self._key = key + + if not backend.aead_cipher_supported(self): + raise exceptions.UnsupportedAlgorithm( + "OCB3 is not supported by this version of OpenSSL", + exceptions._Reasons.UNSUPPORTED_CIPHER, + ) + + @classmethod + def generate_key(cls, bit_length: int) -> bytes: + if not isinstance(bit_length, int): + raise TypeError("bit_length must be an integer") + + if bit_length not in (128, 192, 256): + raise ValueError("bit_length must be 128, 192, or 256") + + return os.urandom(bit_length // 8) + + def encrypt( + self, + nonce: bytes, + data: bytes, + associated_data: typing.Optional[bytes], + ) -> bytes: + if associated_data is None: + associated_data = b"" + + if len(data) > self._MAX_SIZE or len(associated_data) > self._MAX_SIZE: + # This is OverflowError to match what cffi would raise + raise OverflowError( + "Data or associated data too long. Max 2**31 - 1 bytes" + ) + + self._check_params(nonce, data, associated_data) + return aead._encrypt(backend, self, nonce, data, [associated_data], 16) + + def decrypt( + self, + nonce: bytes, + data: bytes, + associated_data: typing.Optional[bytes], + ) -> bytes: + if associated_data is None: + associated_data = b"" + + self._check_params(nonce, data, associated_data) + return aead._decrypt(backend, self, nonce, data, [associated_data], 16) + + def _check_params( + self, + nonce: bytes, + data: bytes, + associated_data: bytes, + ) -> None: + utils._check_byteslike("nonce", nonce) + utils._check_byteslike("data", data) + utils._check_byteslike("associated_data", associated_data) + if len(nonce) < 12 or len(nonce) > 15: + raise ValueError("Nonce must be between 12 and 15 bytes") + + +class AESSIV: + _MAX_SIZE = 2**31 - 1 + + def __init__(self, key: bytes): + utils._check_byteslike("key", key) + if len(key) not in (32, 48, 64): + raise ValueError("AESSIV key must be 256, 384, or 512 bits.") + + self._key = key + + if not backend.aead_cipher_supported(self): + raise exceptions.UnsupportedAlgorithm( + "AES-SIV is not supported by this version of OpenSSL", + exceptions._Reasons.UNSUPPORTED_CIPHER, + ) + + @classmethod + def generate_key(cls, bit_length: int) -> bytes: + if not isinstance(bit_length, int): + raise TypeError("bit_length must be an integer") + + if bit_length not in (256, 384, 512): + raise ValueError("bit_length must be 256, 384, or 512") + + return os.urandom(bit_length // 8) + + def encrypt( + self, + data: bytes, + associated_data: typing.Optional[typing.List[bytes]], + ) -> bytes: + if associated_data is None: + associated_data = [] + + self._check_params(data, associated_data) + + if len(data) > self._MAX_SIZE or any( + len(ad) > self._MAX_SIZE for ad in associated_data + ): + # This is OverflowError to match what cffi would raise + raise OverflowError( + "Data or associated data too long. Max 2**31 - 1 bytes" + ) + + return aead._encrypt(backend, self, b"", data, associated_data, 16) + + def decrypt( + self, + data: bytes, + associated_data: typing.Optional[typing.List[bytes]], + ) -> bytes: + if associated_data is None: + associated_data = [] + + self._check_params(data, associated_data) + + return aead._decrypt(backend, self, b"", data, associated_data, 16) + + def _check_params( + self, + data: bytes, + associated_data: typing.List[bytes], + ) -> None: + utils._check_byteslike("data", data) + if len(data) == 0: + raise ValueError("data must not be zero length") + + if not isinstance(associated_data, list): + raise TypeError( + "associated_data must be a list of bytes-like objects or None" + ) + for x in associated_data: + utils._check_byteslike("associated_data elements", x) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py new file mode 100644 index 0000000..4bfc5d8 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py @@ -0,0 +1,228 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography import utils +from cryptography.hazmat.primitives.ciphers import ( + BlockCipherAlgorithm, + CipherAlgorithm, +) + + +def _verify_key_size(algorithm: CipherAlgorithm, key: bytes) -> bytes: + # Verify that the key is instance of bytes + utils._check_byteslike("key", key) + + # Verify that the key size matches the expected key size + if len(key) * 8 not in algorithm.key_sizes: + raise ValueError( + "Invalid key size ({}) for {}.".format( + len(key) * 8, algorithm.name + ) + ) + return key + + +class AES(BlockCipherAlgorithm): + name = "AES" + block_size = 128 + # 512 added to support AES-256-XTS, which uses 512-bit keys + key_sizes = frozenset([128, 192, 256, 512]) + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + @property + def key_size(self) -> int: + return len(self.key) * 8 + + +class AES128(BlockCipherAlgorithm): + name = "AES" + block_size = 128 + key_sizes = frozenset([128]) + key_size = 128 + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + +class AES256(BlockCipherAlgorithm): + name = "AES" + block_size = 128 + key_sizes = frozenset([256]) + key_size = 256 + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + +class Camellia(BlockCipherAlgorithm): + name = "camellia" + block_size = 128 + key_sizes = frozenset([128, 192, 256]) + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + @property + def key_size(self) -> int: + return len(self.key) * 8 + + +class TripleDES(BlockCipherAlgorithm): + name = "3DES" + block_size = 64 + key_sizes = frozenset([64, 128, 192]) + + def __init__(self, key: bytes): + if len(key) == 8: + key += key + key + elif len(key) == 16: + key += key[:8] + self.key = _verify_key_size(self, key) + + @property + def key_size(self) -> int: + return len(self.key) * 8 + + +class Blowfish(BlockCipherAlgorithm): + name = "Blowfish" + block_size = 64 + key_sizes = frozenset(range(32, 449, 8)) + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + @property + def key_size(self) -> int: + return len(self.key) * 8 + + +_BlowfishInternal = Blowfish +utils.deprecated( + Blowfish, + __name__, + "Blowfish has been deprecated", + utils.DeprecatedIn37, + name="Blowfish", +) + + +class CAST5(BlockCipherAlgorithm): + name = "CAST5" + block_size = 64 + key_sizes = frozenset(range(40, 129, 8)) + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + @property + def key_size(self) -> int: + return len(self.key) * 8 + + +_CAST5Internal = CAST5 +utils.deprecated( + CAST5, + __name__, + "CAST5 has been deprecated", + utils.DeprecatedIn37, + name="CAST5", +) + + +class ARC4(CipherAlgorithm): + name = "RC4" + key_sizes = frozenset([40, 56, 64, 80, 128, 160, 192, 256]) + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + @property + def key_size(self) -> int: + return len(self.key) * 8 + + +class IDEA(BlockCipherAlgorithm): + name = "IDEA" + block_size = 64 + key_sizes = frozenset([128]) + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + @property + def key_size(self) -> int: + return len(self.key) * 8 + + +_IDEAInternal = IDEA +utils.deprecated( + IDEA, + __name__, + "IDEA has been deprecated", + utils.DeprecatedIn37, + name="IDEA", +) + + +class SEED(BlockCipherAlgorithm): + name = "SEED" + block_size = 128 + key_sizes = frozenset([128]) + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + @property + def key_size(self) -> int: + return len(self.key) * 8 + + +_SEEDInternal = SEED +utils.deprecated( + SEED, + __name__, + "SEED has been deprecated", + utils.DeprecatedIn37, + name="SEED", +) + + +class ChaCha20(CipherAlgorithm): + name = "ChaCha20" + key_sizes = frozenset([256]) + + def __init__(self, key: bytes, nonce: bytes): + self.key = _verify_key_size(self, key) + utils._check_byteslike("nonce", nonce) + + if len(nonce) != 16: + raise ValueError("nonce must be 128-bits (16 bytes)") + + self._nonce = nonce + + @property + def nonce(self) -> bytes: + return self._nonce + + @property + def key_size(self) -> int: + return len(self.key) * 8 + + +class SM4(BlockCipherAlgorithm): + name = "SM4" + block_size = 128 + key_sizes = frozenset([128]) + + def __init__(self, key: bytes): + self.key = _verify_key_size(self, key) + + @property + def key_size(self) -> int: + return len(self.key) * 8 diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/base.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/base.py new file mode 100644 index 0000000..38a2ebb --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/base.py @@ -0,0 +1,269 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +from cryptography.exceptions import ( + AlreadyFinalized, + AlreadyUpdated, + NotYetFinalized, +) +from cryptography.hazmat.primitives._cipheralgorithm import CipherAlgorithm +from cryptography.hazmat.primitives.ciphers import modes + +if typing.TYPE_CHECKING: + from cryptography.hazmat.backends.openssl.ciphers import ( + _CipherContext as _BackendCipherContext, + ) + + +class CipherContext(metaclass=abc.ABCMeta): + @abc.abstractmethod + def update(self, data: bytes) -> bytes: + """ + Processes the provided bytes through the cipher and returns the results + as bytes. + """ + + @abc.abstractmethod + def update_into(self, data: bytes, buf: bytes) -> int: + """ + Processes the provided bytes and writes the resulting data into the + provided buffer. Returns the number of bytes written. + """ + + @abc.abstractmethod + def finalize(self) -> bytes: + """ + Returns the results of processing the final block as bytes. + """ + + +class AEADCipherContext(CipherContext, metaclass=abc.ABCMeta): + @abc.abstractmethod + def authenticate_additional_data(self, data: bytes) -> None: + """ + Authenticates the provided bytes. + """ + + +class AEADDecryptionContext(AEADCipherContext, metaclass=abc.ABCMeta): + @abc.abstractmethod + def finalize_with_tag(self, tag: bytes) -> bytes: + """ + Returns the results of processing the final block as bytes and allows + delayed passing of the authentication tag. + """ + + +class AEADEncryptionContext(AEADCipherContext, metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def tag(self) -> bytes: + """ + Returns tag bytes. This is only available after encryption is + finalized. + """ + + +Mode = typing.TypeVar( + "Mode", bound=typing.Optional[modes.Mode], covariant=True +) + + +class Cipher(typing.Generic[Mode]): + def __init__( + self, + algorithm: CipherAlgorithm, + mode: Mode, + backend: typing.Any = None, + ) -> None: + if not isinstance(algorithm, CipherAlgorithm): + raise TypeError("Expected interface of CipherAlgorithm.") + + if mode is not None: + # mypy needs this assert to narrow the type from our generic + # type. Maybe it won't some time in the future. + assert isinstance(mode, modes.Mode) + mode.validate_for_algorithm(algorithm) + + self.algorithm = algorithm + self.mode = mode + + @typing.overload + def encryptor( + self: Cipher[modes.ModeWithAuthenticationTag], + ) -> AEADEncryptionContext: + ... + + @typing.overload + def encryptor( + self: _CIPHER_TYPE, + ) -> CipherContext: + ... + + def encryptor(self): + if isinstance(self.mode, modes.ModeWithAuthenticationTag): + if self.mode.tag is not None: + raise ValueError( + "Authentication tag must be None when encrypting." + ) + from cryptography.hazmat.backends.openssl.backend import backend + + ctx = backend.create_symmetric_encryption_ctx( + self.algorithm, self.mode + ) + return self._wrap_ctx(ctx, encrypt=True) + + @typing.overload + def decryptor( + self: Cipher[modes.ModeWithAuthenticationTag], + ) -> AEADDecryptionContext: + ... + + @typing.overload + def decryptor( + self: _CIPHER_TYPE, + ) -> CipherContext: + ... + + def decryptor(self): + from cryptography.hazmat.backends.openssl.backend import backend + + ctx = backend.create_symmetric_decryption_ctx( + self.algorithm, self.mode + ) + return self._wrap_ctx(ctx, encrypt=False) + + def _wrap_ctx( + self, ctx: _BackendCipherContext, encrypt: bool + ) -> typing.Union[ + AEADEncryptionContext, AEADDecryptionContext, CipherContext + ]: + if isinstance(self.mode, modes.ModeWithAuthenticationTag): + if encrypt: + return _AEADEncryptionContext(ctx) + else: + return _AEADDecryptionContext(ctx) + else: + return _CipherContext(ctx) + + +_CIPHER_TYPE = Cipher[ + typing.Union[ + modes.ModeWithNonce, + modes.ModeWithTweak, + None, + modes.ECB, + modes.ModeWithInitializationVector, + ] +] + + +class _CipherContext(CipherContext): + _ctx: typing.Optional[_BackendCipherContext] + + def __init__(self, ctx: _BackendCipherContext) -> None: + self._ctx = ctx + + def update(self, data: bytes) -> bytes: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + return self._ctx.update(data) + + def update_into(self, data: bytes, buf: bytes) -> int: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + return self._ctx.update_into(data, buf) + + def finalize(self) -> bytes: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + data = self._ctx.finalize() + self._ctx = None + return data + + +class _AEADCipherContext(AEADCipherContext): + _ctx: typing.Optional[_BackendCipherContext] + _tag: typing.Optional[bytes] + + def __init__(self, ctx: _BackendCipherContext) -> None: + self._ctx = ctx + self._bytes_processed = 0 + self._aad_bytes_processed = 0 + self._tag = None + self._updated = False + + def _check_limit(self, data_size: int) -> None: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + self._updated = True + self._bytes_processed += data_size + if self._bytes_processed > self._ctx._mode._MAX_ENCRYPTED_BYTES: + raise ValueError( + "{} has a maximum encrypted byte limit of {}".format( + self._ctx._mode.name, self._ctx._mode._MAX_ENCRYPTED_BYTES + ) + ) + + def update(self, data: bytes) -> bytes: + self._check_limit(len(data)) + # mypy needs this assert even though _check_limit already checked + assert self._ctx is not None + return self._ctx.update(data) + + def update_into(self, data: bytes, buf: bytes) -> int: + self._check_limit(len(data)) + # mypy needs this assert even though _check_limit already checked + assert self._ctx is not None + return self._ctx.update_into(data, buf) + + def finalize(self) -> bytes: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + data = self._ctx.finalize() + self._tag = self._ctx.tag + self._ctx = None + return data + + def authenticate_additional_data(self, data: bytes) -> None: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + if self._updated: + raise AlreadyUpdated("Update has been called on this context.") + + self._aad_bytes_processed += len(data) + if self._aad_bytes_processed > self._ctx._mode._MAX_AAD_BYTES: + raise ValueError( + "{} has a maximum AAD byte limit of {}".format( + self._ctx._mode.name, self._ctx._mode._MAX_AAD_BYTES + ) + ) + + self._ctx.authenticate_additional_data(data) + + +class _AEADDecryptionContext(_AEADCipherContext, AEADDecryptionContext): + def finalize_with_tag(self, tag: bytes) -> bytes: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + data = self._ctx.finalize_with_tag(tag) + self._tag = self._ctx.tag + self._ctx = None + return data + + +class _AEADEncryptionContext(_AEADCipherContext, AEADEncryptionContext): + @property + def tag(self) -> bytes: + if self._ctx is not None: + raise NotYetFinalized( + "You must finalize encryption before " "getting the tag." + ) + assert self._tag is not None + return self._tag diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/modes.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/modes.py new file mode 100644 index 0000000..d8ea188 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/ciphers/modes.py @@ -0,0 +1,274 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +from cryptography import utils +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.primitives._cipheralgorithm import ( + BlockCipherAlgorithm, + CipherAlgorithm, +) +from cryptography.hazmat.primitives.ciphers import algorithms + + +class Mode(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def name(self) -> str: + """ + A string naming this mode (e.g. "ECB", "CBC"). + """ + + @abc.abstractmethod + def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: + """ + Checks that all the necessary invariants of this (mode, algorithm) + combination are met. + """ + + +class ModeWithInitializationVector(Mode, metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def initialization_vector(self) -> bytes: + """ + The value of the initialization vector for this mode as bytes. + """ + + +class ModeWithTweak(Mode, metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def tweak(self) -> bytes: + """ + The value of the tweak for this mode as bytes. + """ + + +class ModeWithNonce(Mode, metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def nonce(self) -> bytes: + """ + The value of the nonce for this mode as bytes. + """ + + +class ModeWithAuthenticationTag(Mode, metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def tag(self) -> typing.Optional[bytes]: + """ + The value of the tag supplied to the constructor of this mode. + """ + + +def _check_aes_key_length(self: Mode, algorithm: CipherAlgorithm) -> None: + if algorithm.key_size > 256 and algorithm.name == "AES": + raise ValueError( + "Only 128, 192, and 256 bit keys are allowed for this AES mode" + ) + + +def _check_iv_length( + self: ModeWithInitializationVector, algorithm: BlockCipherAlgorithm +) -> None: + if len(self.initialization_vector) * 8 != algorithm.block_size: + raise ValueError( + "Invalid IV size ({}) for {}.".format( + len(self.initialization_vector), self.name + ) + ) + + +def _check_nonce_length( + nonce: bytes, name: str, algorithm: CipherAlgorithm +) -> None: + if not isinstance(algorithm, BlockCipherAlgorithm): + raise UnsupportedAlgorithm( + f"{name} requires a block cipher algorithm", + _Reasons.UNSUPPORTED_CIPHER, + ) + if len(nonce) * 8 != algorithm.block_size: + raise ValueError(f"Invalid nonce size ({len(nonce)}) for {name}.") + + +def _check_iv_and_key_length( + self: ModeWithInitializationVector, algorithm: CipherAlgorithm +) -> None: + if not isinstance(algorithm, BlockCipherAlgorithm): + raise UnsupportedAlgorithm( + f"{self} requires a block cipher algorithm", + _Reasons.UNSUPPORTED_CIPHER, + ) + _check_aes_key_length(self, algorithm) + _check_iv_length(self, algorithm) + + +class CBC(ModeWithInitializationVector): + name = "CBC" + + def __init__(self, initialization_vector: bytes): + utils._check_byteslike("initialization_vector", initialization_vector) + self._initialization_vector = initialization_vector + + @property + def initialization_vector(self) -> bytes: + return self._initialization_vector + + validate_for_algorithm = _check_iv_and_key_length + + +class XTS(ModeWithTweak): + name = "XTS" + + def __init__(self, tweak: bytes): + utils._check_byteslike("tweak", tweak) + + if len(tweak) != 16: + raise ValueError("tweak must be 128-bits (16 bytes)") + + self._tweak = tweak + + @property + def tweak(self) -> bytes: + return self._tweak + + def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: + if isinstance(algorithm, (algorithms.AES128, algorithms.AES256)): + raise TypeError( + "The AES128 and AES256 classes do not support XTS, please use " + "the standard AES class instead." + ) + + if algorithm.key_size not in (256, 512): + raise ValueError( + "The XTS specification requires a 256-bit key for AES-128-XTS" + " and 512-bit key for AES-256-XTS" + ) + + +class ECB(Mode): + name = "ECB" + + validate_for_algorithm = _check_aes_key_length + + +class OFB(ModeWithInitializationVector): + name = "OFB" + + def __init__(self, initialization_vector: bytes): + utils._check_byteslike("initialization_vector", initialization_vector) + self._initialization_vector = initialization_vector + + @property + def initialization_vector(self) -> bytes: + return self._initialization_vector + + validate_for_algorithm = _check_iv_and_key_length + + +class CFB(ModeWithInitializationVector): + name = "CFB" + + def __init__(self, initialization_vector: bytes): + utils._check_byteslike("initialization_vector", initialization_vector) + self._initialization_vector = initialization_vector + + @property + def initialization_vector(self) -> bytes: + return self._initialization_vector + + validate_for_algorithm = _check_iv_and_key_length + + +class CFB8(ModeWithInitializationVector): + name = "CFB8" + + def __init__(self, initialization_vector: bytes): + utils._check_byteslike("initialization_vector", initialization_vector) + self._initialization_vector = initialization_vector + + @property + def initialization_vector(self) -> bytes: + return self._initialization_vector + + validate_for_algorithm = _check_iv_and_key_length + + +class CTR(ModeWithNonce): + name = "CTR" + + def __init__(self, nonce: bytes): + utils._check_byteslike("nonce", nonce) + self._nonce = nonce + + @property + def nonce(self) -> bytes: + return self._nonce + + def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: + _check_aes_key_length(self, algorithm) + _check_nonce_length(self.nonce, self.name, algorithm) + + +class GCM(ModeWithInitializationVector, ModeWithAuthenticationTag): + name = "GCM" + _MAX_ENCRYPTED_BYTES = (2**39 - 256) // 8 + _MAX_AAD_BYTES = (2**64) // 8 + + def __init__( + self, + initialization_vector: bytes, + tag: typing.Optional[bytes] = None, + min_tag_length: int = 16, + ): + # OpenSSL 3.0.0 constrains GCM IVs to [64, 1024] bits inclusive + # This is a sane limit anyway so we'll enforce it here. + utils._check_byteslike("initialization_vector", initialization_vector) + if len(initialization_vector) < 8 or len(initialization_vector) > 128: + raise ValueError( + "initialization_vector must be between 8 and 128 bytes (64 " + "and 1024 bits)." + ) + self._initialization_vector = initialization_vector + if tag is not None: + utils._check_bytes("tag", tag) + if min_tag_length < 4: + raise ValueError("min_tag_length must be >= 4") + if len(tag) < min_tag_length: + raise ValueError( + "Authentication tag must be {} bytes or longer.".format( + min_tag_length + ) + ) + self._tag = tag + self._min_tag_length = min_tag_length + + @property + def tag(self) -> typing.Optional[bytes]: + return self._tag + + @property + def initialization_vector(self) -> bytes: + return self._initialization_vector + + def validate_for_algorithm(self, algorithm: CipherAlgorithm) -> None: + _check_aes_key_length(self, algorithm) + if not isinstance(algorithm, BlockCipherAlgorithm): + raise UnsupportedAlgorithm( + "GCM requires a block cipher algorithm", + _Reasons.UNSUPPORTED_CIPHER, + ) + block_size_bytes = algorithm.block_size // 8 + if self._tag is not None and len(self._tag) > block_size_bytes: + raise ValueError( + "Authentication tag cannot be more than {} bytes.".format( + block_size_bytes + ) + ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/cmac.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/cmac.py new file mode 100644 index 0000000..8aa1d79 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/cmac.py @@ -0,0 +1,65 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography import utils +from cryptography.exceptions import AlreadyFinalized +from cryptography.hazmat.primitives import ciphers + +if typing.TYPE_CHECKING: + from cryptography.hazmat.backends.openssl.cmac import _CMACContext + + +class CMAC: + _ctx: typing.Optional[_CMACContext] + _algorithm: ciphers.BlockCipherAlgorithm + + def __init__( + self, + algorithm: ciphers.BlockCipherAlgorithm, + backend: typing.Any = None, + ctx: typing.Optional[_CMACContext] = None, + ) -> None: + if not isinstance(algorithm, ciphers.BlockCipherAlgorithm): + raise TypeError("Expected instance of BlockCipherAlgorithm.") + self._algorithm = algorithm + + if ctx is None: + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + self._ctx = ossl.create_cmac_ctx(self._algorithm) + else: + self._ctx = ctx + + def update(self, data: bytes) -> None: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + + utils._check_bytes("data", data) + self._ctx.update(data) + + def finalize(self) -> bytes: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + digest = self._ctx.finalize() + self._ctx = None + return digest + + def verify(self, signature: bytes) -> None: + utils._check_bytes("signature", signature) + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + + ctx, self._ctx = self._ctx, None + ctx.verify(signature) + + def copy(self) -> CMAC: + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + return CMAC(self._algorithm, ctx=self._ctx.copy()) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/constant_time.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/constant_time.py new file mode 100644 index 0000000..3975c71 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/constant_time.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import hmac + + +def bytes_eq(a: bytes, b: bytes) -> bool: + if not isinstance(a, bytes) or not isinstance(b, bytes): + raise TypeError("a and b must be bytes.") + + return hmac.compare_digest(a, b) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hashes.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hashes.py new file mode 100644 index 0000000..b6a7ff1 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hashes.py @@ -0,0 +1,243 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +from cryptography.hazmat.bindings._rust import openssl as rust_openssl + +__all__ = [ + "HashAlgorithm", + "HashContext", + "Hash", + "ExtendableOutputFunction", + "SHA1", + "SHA512_224", + "SHA512_256", + "SHA224", + "SHA256", + "SHA384", + "SHA512", + "SHA3_224", + "SHA3_256", + "SHA3_384", + "SHA3_512", + "SHAKE128", + "SHAKE256", + "MD5", + "BLAKE2b", + "BLAKE2s", + "SM3", +] + + +class HashAlgorithm(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def name(self) -> str: + """ + A string naming this algorithm (e.g. "sha256", "md5"). + """ + + @property + @abc.abstractmethod + def digest_size(self) -> int: + """ + The size of the resulting digest in bytes. + """ + + @property + @abc.abstractmethod + def block_size(self) -> typing.Optional[int]: + """ + The internal block size of the hash function, or None if the hash + function does not use blocks internally (e.g. SHA3). + """ + + +class HashContext(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def algorithm(self) -> HashAlgorithm: + """ + A HashAlgorithm that will be used by this context. + """ + + @abc.abstractmethod + def update(self, data: bytes) -> None: + """ + Processes the provided bytes through the hash. + """ + + @abc.abstractmethod + def finalize(self) -> bytes: + """ + Finalizes the hash context and returns the hash digest as bytes. + """ + + @abc.abstractmethod + def copy(self) -> HashContext: + """ + Return a HashContext that is a copy of the current context. + """ + + +Hash = rust_openssl.hashes.Hash +HashContext.register(Hash) + + +class ExtendableOutputFunction(metaclass=abc.ABCMeta): + """ + An interface for extendable output functions. + """ + + +class SHA1(HashAlgorithm): + name = "sha1" + digest_size = 20 + block_size = 64 + + +class SHA512_224(HashAlgorithm): # noqa: N801 + name = "sha512-224" + digest_size = 28 + block_size = 128 + + +class SHA512_256(HashAlgorithm): # noqa: N801 + name = "sha512-256" + digest_size = 32 + block_size = 128 + + +class SHA224(HashAlgorithm): + name = "sha224" + digest_size = 28 + block_size = 64 + + +class SHA256(HashAlgorithm): + name = "sha256" + digest_size = 32 + block_size = 64 + + +class SHA384(HashAlgorithm): + name = "sha384" + digest_size = 48 + block_size = 128 + + +class SHA512(HashAlgorithm): + name = "sha512" + digest_size = 64 + block_size = 128 + + +class SHA3_224(HashAlgorithm): # noqa: N801 + name = "sha3-224" + digest_size = 28 + block_size = None + + +class SHA3_256(HashAlgorithm): # noqa: N801 + name = "sha3-256" + digest_size = 32 + block_size = None + + +class SHA3_384(HashAlgorithm): # noqa: N801 + name = "sha3-384" + digest_size = 48 + block_size = None + + +class SHA3_512(HashAlgorithm): # noqa: N801 + name = "sha3-512" + digest_size = 64 + block_size = None + + +class SHAKE128(HashAlgorithm, ExtendableOutputFunction): + name = "shake128" + block_size = None + + def __init__(self, digest_size: int): + if not isinstance(digest_size, int): + raise TypeError("digest_size must be an integer") + + if digest_size < 1: + raise ValueError("digest_size must be a positive integer") + + self._digest_size = digest_size + + @property + def digest_size(self) -> int: + return self._digest_size + + +class SHAKE256(HashAlgorithm, ExtendableOutputFunction): + name = "shake256" + block_size = None + + def __init__(self, digest_size: int): + if not isinstance(digest_size, int): + raise TypeError("digest_size must be an integer") + + if digest_size < 1: + raise ValueError("digest_size must be a positive integer") + + self._digest_size = digest_size + + @property + def digest_size(self) -> int: + return self._digest_size + + +class MD5(HashAlgorithm): + name = "md5" + digest_size = 16 + block_size = 64 + + +class BLAKE2b(HashAlgorithm): + name = "blake2b" + _max_digest_size = 64 + _min_digest_size = 1 + block_size = 128 + + def __init__(self, digest_size: int): + if digest_size != 64: + raise ValueError("Digest size must be 64") + + self._digest_size = digest_size + + @property + def digest_size(self) -> int: + return self._digest_size + + +class BLAKE2s(HashAlgorithm): + name = "blake2s" + block_size = 64 + _max_digest_size = 32 + _min_digest_size = 1 + + def __init__(self, digest_size: int): + if digest_size != 32: + raise ValueError("Digest size must be 32") + + self._digest_size = digest_size + + @property + def digest_size(self) -> int: + return self._digest_size + + +class SM3(HashAlgorithm): + name = "sm3" + digest_size = 32 + block_size = 64 diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hmac.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hmac.py new file mode 100644 index 0000000..a9442d5 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/hmac.py @@ -0,0 +1,13 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.primitives import hashes + +__all__ = ["HMAC"] + +HMAC = rust_openssl.hmac.HMAC +hashes.HashContext.register(HMAC) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/__init__.py new file mode 100644 index 0000000..79bb459 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/__init__.py @@ -0,0 +1,23 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc + + +class KeyDerivationFunction(metaclass=abc.ABCMeta): + @abc.abstractmethod + def derive(self, key_material: bytes) -> bytes: + """ + Deterministically generates and returns a new key based on the existing + key material. + """ + + @abc.abstractmethod + def verify(self, key_material: bytes, expected_key: bytes) -> None: + """ + Checks whether the key generated by the key material matches the + expected derived key. Raises an exception if they do not match. + """ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..5675397 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/__pycache__/hkdf.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/__pycache__/hkdf.cpython-310.opt-1.pyc new file mode 100644 index 0000000..6955282 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/__pycache__/hkdf.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py new file mode 100644 index 0000000..d5ea58a --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/concatkdf.py @@ -0,0 +1,124 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography import utils +from cryptography.exceptions import AlreadyFinalized, InvalidKey +from cryptography.hazmat.primitives import constant_time, hashes, hmac +from cryptography.hazmat.primitives.kdf import KeyDerivationFunction + + +def _int_to_u32be(n: int) -> bytes: + return n.to_bytes(length=4, byteorder="big") + + +def _common_args_checks( + algorithm: hashes.HashAlgorithm, + length: int, + otherinfo: typing.Optional[bytes], +) -> None: + max_length = algorithm.digest_size * (2**32 - 1) + if length > max_length: + raise ValueError(f"Cannot derive keys larger than {max_length} bits.") + if otherinfo is not None: + utils._check_bytes("otherinfo", otherinfo) + + +def _concatkdf_derive( + key_material: bytes, + length: int, + auxfn: typing.Callable[[], hashes.HashContext], + otherinfo: bytes, +) -> bytes: + utils._check_byteslike("key_material", key_material) + output = [b""] + outlen = 0 + counter = 1 + + while length > outlen: + h = auxfn() + h.update(_int_to_u32be(counter)) + h.update(key_material) + h.update(otherinfo) + output.append(h.finalize()) + outlen += len(output[-1]) + counter += 1 + + return b"".join(output)[:length] + + +class ConcatKDFHash(KeyDerivationFunction): + def __init__( + self, + algorithm: hashes.HashAlgorithm, + length: int, + otherinfo: typing.Optional[bytes], + backend: typing.Any = None, + ): + _common_args_checks(algorithm, length, otherinfo) + self._algorithm = algorithm + self._length = length + self._otherinfo: bytes = otherinfo if otherinfo is not None else b"" + + self._used = False + + def _hash(self) -> hashes.Hash: + return hashes.Hash(self._algorithm) + + def derive(self, key_material: bytes) -> bytes: + if self._used: + raise AlreadyFinalized + self._used = True + return _concatkdf_derive( + key_material, self._length, self._hash, self._otherinfo + ) + + def verify(self, key_material: bytes, expected_key: bytes) -> None: + if not constant_time.bytes_eq(self.derive(key_material), expected_key): + raise InvalidKey + + +class ConcatKDFHMAC(KeyDerivationFunction): + def __init__( + self, + algorithm: hashes.HashAlgorithm, + length: int, + salt: typing.Optional[bytes], + otherinfo: typing.Optional[bytes], + backend: typing.Any = None, + ): + _common_args_checks(algorithm, length, otherinfo) + self._algorithm = algorithm + self._length = length + self._otherinfo: bytes = otherinfo if otherinfo is not None else b"" + + if algorithm.block_size is None: + raise TypeError(f"{algorithm.name} is unsupported for ConcatKDF") + + if salt is None: + salt = b"\x00" * algorithm.block_size + else: + utils._check_bytes("salt", salt) + + self._salt = salt + + self._used = False + + def _hmac(self) -> hmac.HMAC: + return hmac.HMAC(self._salt, self._algorithm) + + def derive(self, key_material: bytes) -> bytes: + if self._used: + raise AlreadyFinalized + self._used = True + return _concatkdf_derive( + key_material, self._length, self._hmac, self._otherinfo + ) + + def verify(self, key_material: bytes, expected_key: bytes) -> None: + if not constant_time.bytes_eq(self.derive(key_material), expected_key): + raise InvalidKey diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/hkdf.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/hkdf.py new file mode 100644 index 0000000..d476894 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/hkdf.py @@ -0,0 +1,101 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography import utils +from cryptography.exceptions import AlreadyFinalized, InvalidKey +from cryptography.hazmat.primitives import constant_time, hashes, hmac +from cryptography.hazmat.primitives.kdf import KeyDerivationFunction + + +class HKDF(KeyDerivationFunction): + def __init__( + self, + algorithm: hashes.HashAlgorithm, + length: int, + salt: typing.Optional[bytes], + info: typing.Optional[bytes], + backend: typing.Any = None, + ): + self._algorithm = algorithm + + if salt is None: + salt = b"\x00" * self._algorithm.digest_size + else: + utils._check_bytes("salt", salt) + + self._salt = salt + + self._hkdf_expand = HKDFExpand(self._algorithm, length, info) + + def _extract(self, key_material: bytes) -> bytes: + h = hmac.HMAC(self._salt, self._algorithm) + h.update(key_material) + return h.finalize() + + def derive(self, key_material: bytes) -> bytes: + utils._check_byteslike("key_material", key_material) + return self._hkdf_expand.derive(self._extract(key_material)) + + def verify(self, key_material: bytes, expected_key: bytes) -> None: + if not constant_time.bytes_eq(self.derive(key_material), expected_key): + raise InvalidKey + + +class HKDFExpand(KeyDerivationFunction): + def __init__( + self, + algorithm: hashes.HashAlgorithm, + length: int, + info: typing.Optional[bytes], + backend: typing.Any = None, + ): + self._algorithm = algorithm + + max_length = 255 * algorithm.digest_size + + if length > max_length: + raise ValueError( + f"Cannot derive keys larger than {max_length} octets." + ) + + self._length = length + + if info is None: + info = b"" + else: + utils._check_bytes("info", info) + + self._info = info + + self._used = False + + def _expand(self, key_material: bytes) -> bytes: + output = [b""] + counter = 1 + + while self._algorithm.digest_size * (len(output) - 1) < self._length: + h = hmac.HMAC(key_material, self._algorithm) + h.update(output[-1]) + h.update(self._info) + h.update(bytes([counter])) + output.append(h.finalize()) + counter += 1 + + return b"".join(output)[: self._length] + + def derive(self, key_material: bytes) -> bytes: + utils._check_byteslike("key_material", key_material) + if self._used: + raise AlreadyFinalized + + self._used = True + return self._expand(key_material) + + def verify(self, key_material: bytes, expected_key: bytes) -> None: + if not constant_time.bytes_eq(self.derive(key_material), expected_key): + raise InvalidKey diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py new file mode 100644 index 0000000..9677638 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/kbkdf.py @@ -0,0 +1,299 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography import utils +from cryptography.exceptions import ( + AlreadyFinalized, + InvalidKey, + UnsupportedAlgorithm, + _Reasons, +) +from cryptography.hazmat.primitives import ( + ciphers, + cmac, + constant_time, + hashes, + hmac, +) +from cryptography.hazmat.primitives.kdf import KeyDerivationFunction + + +class Mode(utils.Enum): + CounterMode = "ctr" + + +class CounterLocation(utils.Enum): + BeforeFixed = "before_fixed" + AfterFixed = "after_fixed" + MiddleFixed = "middle_fixed" + + +class _KBKDFDeriver: + def __init__( + self, + prf: typing.Callable, + mode: Mode, + length: int, + rlen: int, + llen: typing.Optional[int], + location: CounterLocation, + break_location: typing.Optional[int], + label: typing.Optional[bytes], + context: typing.Optional[bytes], + fixed: typing.Optional[bytes], + ): + assert callable(prf) + + if not isinstance(mode, Mode): + raise TypeError("mode must be of type Mode") + + if not isinstance(location, CounterLocation): + raise TypeError("location must be of type CounterLocation") + + if break_location is None and location is CounterLocation.MiddleFixed: + raise ValueError("Please specify a break_location") + + if ( + break_location is not None + and location != CounterLocation.MiddleFixed + ): + raise ValueError( + "break_location is ignored when location is not" + " CounterLocation.MiddleFixed" + ) + + if break_location is not None and not isinstance(break_location, int): + raise TypeError("break_location must be an integer") + + if break_location is not None and break_location < 0: + raise ValueError("break_location must be a positive integer") + + if (label or context) and fixed: + raise ValueError( + "When supplying fixed data, " "label and context are ignored." + ) + + if rlen is None or not self._valid_byte_length(rlen): + raise ValueError("rlen must be between 1 and 4") + + if llen is None and fixed is None: + raise ValueError("Please specify an llen") + + if llen is not None and not isinstance(llen, int): + raise TypeError("llen must be an integer") + + if label is None: + label = b"" + + if context is None: + context = b"" + + utils._check_bytes("label", label) + utils._check_bytes("context", context) + self._prf = prf + self._mode = mode + self._length = length + self._rlen = rlen + self._llen = llen + self._location = location + self._break_location = break_location + self._label = label + self._context = context + self._used = False + self._fixed_data = fixed + + @staticmethod + def _valid_byte_length(value: int) -> bool: + if not isinstance(value, int): + raise TypeError("value must be of type int") + + value_bin = utils.int_to_bytes(1, value) + if not 1 <= len(value_bin) <= 4: + return False + return True + + def derive(self, key_material: bytes, prf_output_size: int) -> bytes: + if self._used: + raise AlreadyFinalized + + utils._check_byteslike("key_material", key_material) + self._used = True + + # inverse floor division (equivalent to ceiling) + rounds = -(-self._length // prf_output_size) + + output = [b""] + + # For counter mode, the number of iterations shall not be + # larger than 2^r-1, where r <= 32 is the binary length of the counter + # This ensures that the counter values used as an input to the + # PRF will not repeat during a particular call to the KDF function. + r_bin = utils.int_to_bytes(1, self._rlen) + if rounds > pow(2, len(r_bin) * 8) - 1: + raise ValueError("There are too many iterations.") + + fixed = self._generate_fixed_input() + + if self._location == CounterLocation.BeforeFixed: + data_before_ctr = b"" + data_after_ctr = fixed + elif self._location == CounterLocation.AfterFixed: + data_before_ctr = fixed + data_after_ctr = b"" + else: + if isinstance( + self._break_location, int + ) and self._break_location > len(fixed): + raise ValueError("break_location offset > len(fixed)") + data_before_ctr = fixed[: self._break_location] + data_after_ctr = fixed[self._break_location :] + + for i in range(1, rounds + 1): + h = self._prf(key_material) + + counter = utils.int_to_bytes(i, self._rlen) + input_data = data_before_ctr + counter + data_after_ctr + + h.update(input_data) + + output.append(h.finalize()) + + return b"".join(output)[: self._length] + + def _generate_fixed_input(self) -> bytes: + if self._fixed_data and isinstance(self._fixed_data, bytes): + return self._fixed_data + + l_val = utils.int_to_bytes(self._length * 8, self._llen) + + return b"".join([self._label, b"\x00", self._context, l_val]) + + +class KBKDFHMAC(KeyDerivationFunction): + def __init__( + self, + algorithm: hashes.HashAlgorithm, + mode: Mode, + length: int, + rlen: int, + llen: typing.Optional[int], + location: CounterLocation, + label: typing.Optional[bytes], + context: typing.Optional[bytes], + fixed: typing.Optional[bytes], + backend: typing.Any = None, + *, + break_location: typing.Optional[int] = None, + ): + if not isinstance(algorithm, hashes.HashAlgorithm): + raise UnsupportedAlgorithm( + "Algorithm supplied is not a supported hash algorithm.", + _Reasons.UNSUPPORTED_HASH, + ) + + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + if not ossl.hmac_supported(algorithm): + raise UnsupportedAlgorithm( + "Algorithm supplied is not a supported hmac algorithm.", + _Reasons.UNSUPPORTED_HASH, + ) + + self._algorithm = algorithm + + self._deriver = _KBKDFDeriver( + self._prf, + mode, + length, + rlen, + llen, + location, + break_location, + label, + context, + fixed, + ) + + def _prf(self, key_material: bytes) -> hmac.HMAC: + return hmac.HMAC(key_material, self._algorithm) + + def derive(self, key_material: bytes) -> bytes: + return self._deriver.derive(key_material, self._algorithm.digest_size) + + def verify(self, key_material: bytes, expected_key: bytes) -> None: + if not constant_time.bytes_eq(self.derive(key_material), expected_key): + raise InvalidKey + + +class KBKDFCMAC(KeyDerivationFunction): + def __init__( + self, + algorithm, + mode: Mode, + length: int, + rlen: int, + llen: typing.Optional[int], + location: CounterLocation, + label: typing.Optional[bytes], + context: typing.Optional[bytes], + fixed: typing.Optional[bytes], + backend: typing.Any = None, + *, + break_location: typing.Optional[int] = None, + ): + if not issubclass( + algorithm, ciphers.BlockCipherAlgorithm + ) or not issubclass(algorithm, ciphers.CipherAlgorithm): + raise UnsupportedAlgorithm( + "Algorithm supplied is not a supported cipher algorithm.", + _Reasons.UNSUPPORTED_CIPHER, + ) + + self._algorithm = algorithm + self._cipher: typing.Optional[ciphers.BlockCipherAlgorithm] = None + + self._deriver = _KBKDFDeriver( + self._prf, + mode, + length, + rlen, + llen, + location, + break_location, + label, + context, + fixed, + ) + + def _prf(self, _: bytes) -> cmac.CMAC: + assert self._cipher is not None + + return cmac.CMAC(self._cipher) + + def derive(self, key_material: bytes) -> bytes: + self._cipher = self._algorithm(key_material) + + assert self._cipher is not None + + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + if not ossl.cmac_algorithm_supported(self._cipher): + raise UnsupportedAlgorithm( + "Algorithm supplied is not a supported cipher algorithm.", + _Reasons.UNSUPPORTED_CIPHER, + ) + + return self._deriver.derive(key_material, self._cipher.block_size // 8) + + def verify(self, key_material: bytes, expected_key: bytes) -> None: + if not constant_time.bytes_eq(self.derive(key_material), expected_key): + raise InvalidKey diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py new file mode 100644 index 0000000..623e1ca --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/pbkdf2.py @@ -0,0 +1,64 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography import utils +from cryptography.exceptions import ( + AlreadyFinalized, + InvalidKey, + UnsupportedAlgorithm, + _Reasons, +) +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.primitives import constant_time, hashes +from cryptography.hazmat.primitives.kdf import KeyDerivationFunction + + +class PBKDF2HMAC(KeyDerivationFunction): + def __init__( + self, + algorithm: hashes.HashAlgorithm, + length: int, + salt: bytes, + iterations: int, + backend: typing.Any = None, + ): + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + if not ossl.pbkdf2_hmac_supported(algorithm): + raise UnsupportedAlgorithm( + "{} is not supported for PBKDF2 by this backend.".format( + algorithm.name + ), + _Reasons.UNSUPPORTED_HASH, + ) + self._used = False + self._algorithm = algorithm + self._length = length + utils._check_bytes("salt", salt) + self._salt = salt + self._iterations = iterations + + def derive(self, key_material: bytes) -> bytes: + if self._used: + raise AlreadyFinalized("PBKDF2 instances can only be used once.") + self._used = True + + return rust_openssl.kdf.derive_pbkdf2_hmac( + key_material, + self._algorithm, + self._salt, + self._iterations, + self._length, + ) + + def verify(self, key_material: bytes, expected_key: bytes) -> None: + derived_key = self.derive(key_material) + if not constant_time.bytes_eq(derived_key, expected_key): + raise InvalidKey("Keys do not match.") diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/scrypt.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/scrypt.py new file mode 100644 index 0000000..05a4f67 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/scrypt.py @@ -0,0 +1,80 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import sys +import typing + +from cryptography import utils +from cryptography.exceptions import ( + AlreadyFinalized, + InvalidKey, + UnsupportedAlgorithm, +) +from cryptography.hazmat.bindings._rust import openssl as rust_openssl +from cryptography.hazmat.primitives import constant_time +from cryptography.hazmat.primitives.kdf import KeyDerivationFunction + +# This is used by the scrypt tests to skip tests that require more memory +# than the MEM_LIMIT +_MEM_LIMIT = sys.maxsize // 2 + + +class Scrypt(KeyDerivationFunction): + def __init__( + self, + salt: bytes, + length: int, + n: int, + r: int, + p: int, + backend: typing.Any = None, + ): + from cryptography.hazmat.backends.openssl.backend import ( + backend as ossl, + ) + + if not ossl.scrypt_supported(): + raise UnsupportedAlgorithm( + "This version of OpenSSL does not support scrypt" + ) + self._length = length + utils._check_bytes("salt", salt) + if n < 2 or (n & (n - 1)) != 0: + raise ValueError("n must be greater than 1 and be a power of 2.") + + if r < 1: + raise ValueError("r must be greater than or equal to 1.") + + if p < 1: + raise ValueError("p must be greater than or equal to 1.") + + self._used = False + self._salt = salt + self._n = n + self._r = r + self._p = p + + def derive(self, key_material: bytes) -> bytes: + if self._used: + raise AlreadyFinalized("Scrypt instances can only be used once.") + self._used = True + + utils._check_byteslike("key_material", key_material) + + return rust_openssl.kdf.derive_scrypt( + key_material, + self._salt, + self._n, + self._r, + self._p, + _MEM_LIMIT, + self._length, + ) + + def verify(self, key_material: bytes, expected_key: bytes) -> None: + derived_key = self.derive(key_material) + if not constant_time.bytes_eq(derived_key, expected_key): + raise InvalidKey("Keys do not match.") diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py new file mode 100644 index 0000000..17acc51 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/kdf/x963kdf.py @@ -0,0 +1,61 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography import utils +from cryptography.exceptions import AlreadyFinalized, InvalidKey +from cryptography.hazmat.primitives import constant_time, hashes +from cryptography.hazmat.primitives.kdf import KeyDerivationFunction + + +def _int_to_u32be(n: int) -> bytes: + return n.to_bytes(length=4, byteorder="big") + + +class X963KDF(KeyDerivationFunction): + def __init__( + self, + algorithm: hashes.HashAlgorithm, + length: int, + sharedinfo: typing.Optional[bytes], + backend: typing.Any = None, + ): + max_len = algorithm.digest_size * (2**32 - 1) + if length > max_len: + raise ValueError(f"Cannot derive keys larger than {max_len} bits.") + if sharedinfo is not None: + utils._check_bytes("sharedinfo", sharedinfo) + + self._algorithm = algorithm + self._length = length + self._sharedinfo = sharedinfo + self._used = False + + def derive(self, key_material: bytes) -> bytes: + if self._used: + raise AlreadyFinalized + self._used = True + utils._check_byteslike("key_material", key_material) + output = [b""] + outlen = 0 + counter = 1 + + while self._length > outlen: + h = hashes.Hash(self._algorithm) + h.update(key_material) + h.update(_int_to_u32be(counter)) + if self._sharedinfo is not None: + h.update(self._sharedinfo) + output.append(h.finalize()) + outlen += len(output[-1]) + counter += 1 + + return b"".join(output)[: self._length] + + def verify(self, key_material: bytes, expected_key: bytes) -> None: + if not constant_time.bytes_eq(self.derive(key_material), expected_key): + raise InvalidKey diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/keywrap.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/keywrap.py new file mode 100644 index 0000000..59b0326 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/keywrap.py @@ -0,0 +1,177 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.hazmat.primitives.ciphers import Cipher +from cryptography.hazmat.primitives.ciphers.algorithms import AES +from cryptography.hazmat.primitives.ciphers.modes import ECB +from cryptography.hazmat.primitives.constant_time import bytes_eq + + +def _wrap_core( + wrapping_key: bytes, + a: bytes, + r: typing.List[bytes], +) -> bytes: + # RFC 3394 Key Wrap - 2.2.1 (index method) + encryptor = Cipher(AES(wrapping_key), ECB()).encryptor() + n = len(r) + for j in range(6): + for i in range(n): + # every encryption operation is a discrete 16 byte chunk (because + # AES has a 128-bit block size) and since we're using ECB it is + # safe to reuse the encryptor for the entire operation + b = encryptor.update(a + r[i]) + a = ( + int.from_bytes(b[:8], byteorder="big") ^ ((n * j) + i + 1) + ).to_bytes(length=8, byteorder="big") + r[i] = b[-8:] + + assert encryptor.finalize() == b"" + + return a + b"".join(r) + + +def aes_key_wrap( + wrapping_key: bytes, + key_to_wrap: bytes, + backend: typing.Any = None, +) -> bytes: + if len(wrapping_key) not in [16, 24, 32]: + raise ValueError("The wrapping key must be a valid AES key length") + + if len(key_to_wrap) < 16: + raise ValueError("The key to wrap must be at least 16 bytes") + + if len(key_to_wrap) % 8 != 0: + raise ValueError("The key to wrap must be a multiple of 8 bytes") + + a = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6" + r = [key_to_wrap[i : i + 8] for i in range(0, len(key_to_wrap), 8)] + return _wrap_core(wrapping_key, a, r) + + +def _unwrap_core( + wrapping_key: bytes, + a: bytes, + r: typing.List[bytes], +) -> typing.Tuple[bytes, typing.List[bytes]]: + # Implement RFC 3394 Key Unwrap - 2.2.2 (index method) + decryptor = Cipher(AES(wrapping_key), ECB()).decryptor() + n = len(r) + for j in reversed(range(6)): + for i in reversed(range(n)): + atr = ( + int.from_bytes(a, byteorder="big") ^ ((n * j) + i + 1) + ).to_bytes(length=8, byteorder="big") + r[i] + # every decryption operation is a discrete 16 byte chunk so + # it is safe to reuse the decryptor for the entire operation + b = decryptor.update(atr) + a = b[:8] + r[i] = b[-8:] + + assert decryptor.finalize() == b"" + return a, r + + +def aes_key_wrap_with_padding( + wrapping_key: bytes, + key_to_wrap: bytes, + backend: typing.Any = None, +) -> bytes: + if len(wrapping_key) not in [16, 24, 32]: + raise ValueError("The wrapping key must be a valid AES key length") + + aiv = b"\xA6\x59\x59\xA6" + len(key_to_wrap).to_bytes( + length=4, byteorder="big" + ) + # pad the key to wrap if necessary + pad = (8 - (len(key_to_wrap) % 8)) % 8 + key_to_wrap = key_to_wrap + b"\x00" * pad + if len(key_to_wrap) == 8: + # RFC 5649 - 4.1 - exactly 8 octets after padding + encryptor = Cipher(AES(wrapping_key), ECB()).encryptor() + b = encryptor.update(aiv + key_to_wrap) + assert encryptor.finalize() == b"" + return b + else: + r = [key_to_wrap[i : i + 8] for i in range(0, len(key_to_wrap), 8)] + return _wrap_core(wrapping_key, aiv, r) + + +def aes_key_unwrap_with_padding( + wrapping_key: bytes, + wrapped_key: bytes, + backend: typing.Any = None, +) -> bytes: + if len(wrapped_key) < 16: + raise InvalidUnwrap("Must be at least 16 bytes") + + if len(wrapping_key) not in [16, 24, 32]: + raise ValueError("The wrapping key must be a valid AES key length") + + if len(wrapped_key) == 16: + # RFC 5649 - 4.2 - exactly two 64-bit blocks + decryptor = Cipher(AES(wrapping_key), ECB()).decryptor() + out = decryptor.update(wrapped_key) + assert decryptor.finalize() == b"" + a = out[:8] + data = out[8:] + n = 1 + else: + r = [wrapped_key[i : i + 8] for i in range(0, len(wrapped_key), 8)] + encrypted_aiv = r.pop(0) + n = len(r) + a, r = _unwrap_core(wrapping_key, encrypted_aiv, r) + data = b"".join(r) + + # 1) Check that MSB(32,A) = A65959A6. + # 2) Check that 8*(n-1) < LSB(32,A) <= 8*n. If so, let + # MLI = LSB(32,A). + # 3) Let b = (8*n)-MLI, and then check that the rightmost b octets of + # the output data are zero. + mli = int.from_bytes(a[4:], byteorder="big") + b = (8 * n) - mli + if ( + not bytes_eq(a[:4], b"\xa6\x59\x59\xa6") + or not 8 * (n - 1) < mli <= 8 * n + or (b != 0 and not bytes_eq(data[-b:], b"\x00" * b)) + ): + raise InvalidUnwrap() + + if b == 0: + return data + else: + return data[:-b] + + +def aes_key_unwrap( + wrapping_key: bytes, + wrapped_key: bytes, + backend: typing.Any = None, +) -> bytes: + if len(wrapped_key) < 24: + raise InvalidUnwrap("Must be at least 24 bytes") + + if len(wrapped_key) % 8 != 0: + raise InvalidUnwrap("The wrapped key must be a multiple of 8 bytes") + + if len(wrapping_key) not in [16, 24, 32]: + raise ValueError("The wrapping key must be a valid AES key length") + + aiv = b"\xa6\xa6\xa6\xa6\xa6\xa6\xa6\xa6" + r = [wrapped_key[i : i + 8] for i in range(0, len(wrapped_key), 8)] + a = r.pop(0) + a, r = _unwrap_core(wrapping_key, a, r) + if not bytes_eq(a, aiv): + raise InvalidUnwrap() + + return b"".join(r) + + +class InvalidUnwrap(Exception): + pass diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/padding.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/padding.py new file mode 100644 index 0000000..fde3094 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/padding.py @@ -0,0 +1,225 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import typing + +from cryptography import utils +from cryptography.exceptions import AlreadyFinalized +from cryptography.hazmat.bindings._rust import ( + check_ansix923_padding, + check_pkcs7_padding, +) + + +class PaddingContext(metaclass=abc.ABCMeta): + @abc.abstractmethod + def update(self, data: bytes) -> bytes: + """ + Pads the provided bytes and returns any available data as bytes. + """ + + @abc.abstractmethod + def finalize(self) -> bytes: + """ + Finalize the padding, returns bytes. + """ + + +def _byte_padding_check(block_size: int) -> None: + if not (0 <= block_size <= 2040): + raise ValueError("block_size must be in range(0, 2041).") + + if block_size % 8 != 0: + raise ValueError("block_size must be a multiple of 8.") + + +def _byte_padding_update( + buffer_: typing.Optional[bytes], data: bytes, block_size: int +) -> typing.Tuple[bytes, bytes]: + if buffer_ is None: + raise AlreadyFinalized("Context was already finalized.") + + utils._check_byteslike("data", data) + + buffer_ += bytes(data) + + finished_blocks = len(buffer_) // (block_size // 8) + + result = buffer_[: finished_blocks * (block_size // 8)] + buffer_ = buffer_[finished_blocks * (block_size // 8) :] + + return buffer_, result + + +def _byte_padding_pad( + buffer_: typing.Optional[bytes], + block_size: int, + paddingfn: typing.Callable[[int], bytes], +) -> bytes: + if buffer_ is None: + raise AlreadyFinalized("Context was already finalized.") + + pad_size = block_size // 8 - len(buffer_) + return buffer_ + paddingfn(pad_size) + + +def _byte_unpadding_update( + buffer_: typing.Optional[bytes], data: bytes, block_size: int +) -> typing.Tuple[bytes, bytes]: + if buffer_ is None: + raise AlreadyFinalized("Context was already finalized.") + + utils._check_byteslike("data", data) + + buffer_ += bytes(data) + + finished_blocks = max(len(buffer_) // (block_size // 8) - 1, 0) + + result = buffer_[: finished_blocks * (block_size // 8)] + buffer_ = buffer_[finished_blocks * (block_size // 8) :] + + return buffer_, result + + +def _byte_unpadding_check( + buffer_: typing.Optional[bytes], + block_size: int, + checkfn: typing.Callable[[bytes], int], +) -> bytes: + if buffer_ is None: + raise AlreadyFinalized("Context was already finalized.") + + if len(buffer_) != block_size // 8: + raise ValueError("Invalid padding bytes.") + + valid = checkfn(buffer_) + + if not valid: + raise ValueError("Invalid padding bytes.") + + pad_size = buffer_[-1] + return buffer_[:-pad_size] + + +class PKCS7: + def __init__(self, block_size: int): + _byte_padding_check(block_size) + self.block_size = block_size + + def padder(self) -> PaddingContext: + return _PKCS7PaddingContext(self.block_size) + + def unpadder(self) -> PaddingContext: + return _PKCS7UnpaddingContext(self.block_size) + + +class _PKCS7PaddingContext(PaddingContext): + _buffer: typing.Optional[bytes] + + def __init__(self, block_size: int): + self.block_size = block_size + # TODO: more copies than necessary, we should use zero-buffer (#193) + self._buffer = b"" + + def update(self, data: bytes) -> bytes: + self._buffer, result = _byte_padding_update( + self._buffer, data, self.block_size + ) + return result + + def _padding(self, size: int) -> bytes: + return bytes([size]) * size + + def finalize(self) -> bytes: + result = _byte_padding_pad( + self._buffer, self.block_size, self._padding + ) + self._buffer = None + return result + + +class _PKCS7UnpaddingContext(PaddingContext): + _buffer: typing.Optional[bytes] + + def __init__(self, block_size: int): + self.block_size = block_size + # TODO: more copies than necessary, we should use zero-buffer (#193) + self._buffer = b"" + + def update(self, data: bytes) -> bytes: + self._buffer, result = _byte_unpadding_update( + self._buffer, data, self.block_size + ) + return result + + def finalize(self) -> bytes: + result = _byte_unpadding_check( + self._buffer, self.block_size, check_pkcs7_padding + ) + self._buffer = None + return result + + +class ANSIX923: + def __init__(self, block_size: int): + _byte_padding_check(block_size) + self.block_size = block_size + + def padder(self) -> PaddingContext: + return _ANSIX923PaddingContext(self.block_size) + + def unpadder(self) -> PaddingContext: + return _ANSIX923UnpaddingContext(self.block_size) + + +class _ANSIX923PaddingContext(PaddingContext): + _buffer: typing.Optional[bytes] + + def __init__(self, block_size: int): + self.block_size = block_size + # TODO: more copies than necessary, we should use zero-buffer (#193) + self._buffer = b"" + + def update(self, data: bytes) -> bytes: + self._buffer, result = _byte_padding_update( + self._buffer, data, self.block_size + ) + return result + + def _padding(self, size: int) -> bytes: + return bytes([0]) * (size - 1) + bytes([size]) + + def finalize(self) -> bytes: + result = _byte_padding_pad( + self._buffer, self.block_size, self._padding + ) + self._buffer = None + return result + + +class _ANSIX923UnpaddingContext(PaddingContext): + _buffer: typing.Optional[bytes] + + def __init__(self, block_size: int): + self.block_size = block_size + # TODO: more copies than necessary, we should use zero-buffer (#193) + self._buffer = b"" + + def update(self, data: bytes) -> bytes: + self._buffer, result = _byte_unpadding_update( + self._buffer, data, self.block_size + ) + return result + + def finalize(self) -> bytes: + result = _byte_unpadding_check( + self._buffer, + self.block_size, + check_ansix923_padding, + ) + self._buffer = None + return result diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/poly1305.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/poly1305.py new file mode 100644 index 0000000..7f5a77a --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/poly1305.py @@ -0,0 +1,11 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography.hazmat.bindings._rust import openssl as rust_openssl + +__all__ = ["Poly1305"] + +Poly1305 = rust_openssl.poly1305.Poly1305 diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__init__.py new file mode 100644 index 0000000..b6c9a5c --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__init__.py @@ -0,0 +1,63 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography.hazmat.primitives._serialization import ( + BestAvailableEncryption, + Encoding, + KeySerializationEncryption, + NoEncryption, + ParameterFormat, + PrivateFormat, + PublicFormat, + _KeySerializationEncryption, +) +from cryptography.hazmat.primitives.serialization.base import ( + load_der_parameters, + load_der_private_key, + load_der_public_key, + load_pem_parameters, + load_pem_private_key, + load_pem_public_key, +) +from cryptography.hazmat.primitives.serialization.ssh import ( + SSHCertificate, + SSHCertificateBuilder, + SSHCertificateType, + SSHCertPrivateKeyTypes, + SSHCertPublicKeyTypes, + SSHPrivateKeyTypes, + SSHPublicKeyTypes, + load_ssh_private_key, + load_ssh_public_identity, + load_ssh_public_key, +) + +__all__ = [ + "load_der_parameters", + "load_der_private_key", + "load_der_public_key", + "load_pem_parameters", + "load_pem_private_key", + "load_pem_public_key", + "load_ssh_private_key", + "load_ssh_public_identity", + "load_ssh_public_key", + "Encoding", + "PrivateFormat", + "PublicFormat", + "ParameterFormat", + "KeySerializationEncryption", + "BestAvailableEncryption", + "NoEncryption", + "_KeySerializationEncryption", + "SSHCertificateBuilder", + "SSHCertificate", + "SSHCertificateType", + "SSHCertPublicKeyTypes", + "SSHCertPrivateKeyTypes", + "SSHPrivateKeyTypes", + "SSHPublicKeyTypes", +] diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8abd71e Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__pycache__/base.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__pycache__/base.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8771460 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__pycache__/base.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__pycache__/ssh.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__pycache__/ssh.cpython-310.opt-1.pyc new file mode 100644 index 0000000..7478156 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/__pycache__/ssh.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/base.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/base.py new file mode 100644 index 0000000..18a96cc --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/base.py @@ -0,0 +1,73 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.hazmat.primitives.asymmetric import dh +from cryptography.hazmat.primitives.asymmetric.types import ( + PrivateKeyTypes, + PublicKeyTypes, +) + + +def load_pem_private_key( + data: bytes, + password: typing.Optional[bytes], + backend: typing.Any = None, + *, + unsafe_skip_rsa_key_validation: bool = False, +) -> PrivateKeyTypes: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.load_pem_private_key( + data, password, unsafe_skip_rsa_key_validation + ) + + +def load_pem_public_key( + data: bytes, backend: typing.Any = None +) -> PublicKeyTypes: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.load_pem_public_key(data) + + +def load_pem_parameters( + data: bytes, backend: typing.Any = None +) -> dh.DHParameters: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.load_pem_parameters(data) + + +def load_der_private_key( + data: bytes, + password: typing.Optional[bytes], + backend: typing.Any = None, + *, + unsafe_skip_rsa_key_validation: bool = False, +) -> PrivateKeyTypes: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.load_der_private_key( + data, password, unsafe_skip_rsa_key_validation + ) + + +def load_der_public_key( + data: bytes, backend: typing.Any = None +) -> PublicKeyTypes: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.load_der_public_key(data) + + +def load_der_parameters( + data: bytes, backend: typing.Any = None +) -> dh.DHParameters: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.load_der_parameters(data) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py new file mode 100644 index 0000000..27133a3 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs12.py @@ -0,0 +1,229 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography import x509 +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives._serialization import PBES as PBES +from cryptography.hazmat.primitives.asymmetric import ( + dsa, + ec, + ed448, + ed25519, + rsa, +) +from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes + +__all__ = [ + "PBES", + "PKCS12PrivateKeyTypes", + "PKCS12Certificate", + "PKCS12KeyAndCertificates", + "load_key_and_certificates", + "load_pkcs12", + "serialize_key_and_certificates", +] + +PKCS12PrivateKeyTypes = typing.Union[ + rsa.RSAPrivateKey, + dsa.DSAPrivateKey, + ec.EllipticCurvePrivateKey, + ed25519.Ed25519PrivateKey, + ed448.Ed448PrivateKey, +] + + +class PKCS12Certificate: + def __init__( + self, + cert: x509.Certificate, + friendly_name: typing.Optional[bytes], + ): + if not isinstance(cert, x509.Certificate): + raise TypeError("Expecting x509.Certificate object") + if friendly_name is not None and not isinstance(friendly_name, bytes): + raise TypeError("friendly_name must be bytes or None") + self._cert = cert + self._friendly_name = friendly_name + + @property + def friendly_name(self) -> typing.Optional[bytes]: + return self._friendly_name + + @property + def certificate(self) -> x509.Certificate: + return self._cert + + def __eq__(self, other: object) -> bool: + if not isinstance(other, PKCS12Certificate): + return NotImplemented + + return ( + self.certificate == other.certificate + and self.friendly_name == other.friendly_name + ) + + def __hash__(self) -> int: + return hash((self.certificate, self.friendly_name)) + + def __repr__(self) -> str: + return "".format( + self.certificate, self.friendly_name + ) + + +class PKCS12KeyAndCertificates: + def __init__( + self, + key: typing.Optional[PrivateKeyTypes], + cert: typing.Optional[PKCS12Certificate], + additional_certs: typing.List[PKCS12Certificate], + ): + if key is not None and not isinstance( + key, + ( + rsa.RSAPrivateKey, + dsa.DSAPrivateKey, + ec.EllipticCurvePrivateKey, + ed25519.Ed25519PrivateKey, + ed448.Ed448PrivateKey, + ), + ): + raise TypeError( + "Key must be RSA, DSA, EllipticCurve, ED25519, or ED448" + " private key, or None." + ) + if cert is not None and not isinstance(cert, PKCS12Certificate): + raise TypeError("cert must be a PKCS12Certificate object or None") + if not all( + isinstance(add_cert, PKCS12Certificate) + for add_cert in additional_certs + ): + raise TypeError( + "all values in additional_certs must be PKCS12Certificate" + " objects" + ) + self._key = key + self._cert = cert + self._additional_certs = additional_certs + + @property + def key(self) -> typing.Optional[PrivateKeyTypes]: + return self._key + + @property + def cert(self) -> typing.Optional[PKCS12Certificate]: + return self._cert + + @property + def additional_certs(self) -> typing.List[PKCS12Certificate]: + return self._additional_certs + + def __eq__(self, other: object) -> bool: + if not isinstance(other, PKCS12KeyAndCertificates): + return NotImplemented + + return ( + self.key == other.key + and self.cert == other.cert + and self.additional_certs == other.additional_certs + ) + + def __hash__(self) -> int: + return hash((self.key, self.cert, tuple(self.additional_certs))) + + def __repr__(self) -> str: + fmt = ( + "" + ) + return fmt.format(self.key, self.cert, self.additional_certs) + + +def load_key_and_certificates( + data: bytes, + password: typing.Optional[bytes], + backend: typing.Any = None, +) -> typing.Tuple[ + typing.Optional[PrivateKeyTypes], + typing.Optional[x509.Certificate], + typing.List[x509.Certificate], +]: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.load_key_and_certificates_from_pkcs12(data, password) + + +def load_pkcs12( + data: bytes, + password: typing.Optional[bytes], + backend: typing.Any = None, +) -> PKCS12KeyAndCertificates: + from cryptography.hazmat.backends.openssl.backend import backend as ossl + + return ossl.load_pkcs12(data, password) + + +_PKCS12CATypes = typing.Union[ + x509.Certificate, + PKCS12Certificate, +] + + +def serialize_key_and_certificates( + name: typing.Optional[bytes], + key: typing.Optional[PKCS12PrivateKeyTypes], + cert: typing.Optional[x509.Certificate], + cas: typing.Optional[typing.Iterable[_PKCS12CATypes]], + encryption_algorithm: serialization.KeySerializationEncryption, +) -> bytes: + if key is not None and not isinstance( + key, + ( + rsa.RSAPrivateKey, + dsa.DSAPrivateKey, + ec.EllipticCurvePrivateKey, + ed25519.Ed25519PrivateKey, + ed448.Ed448PrivateKey, + ), + ): + raise TypeError( + "Key must be RSA, DSA, EllipticCurve, ED25519, or ED448" + " private key, or None." + ) + if cert is not None and not isinstance(cert, x509.Certificate): + raise TypeError("cert must be a certificate or None") + + if cas is not None: + cas = list(cas) + if not all( + isinstance( + val, + ( + x509.Certificate, + PKCS12Certificate, + ), + ) + for val in cas + ): + raise TypeError("all values in cas must be certificates") + + if not isinstance( + encryption_algorithm, serialization.KeySerializationEncryption + ): + raise TypeError( + "Key encryption algorithm must be a " + "KeySerializationEncryption instance" + ) + + if key is None and cert is None and not cas: + raise ValueError("You must supply at least one of key, cert, or cas") + + from cryptography.hazmat.backends.openssl.backend import backend + + return backend.serialize_key_and_certificates_to_pkcs12( + name, key, cert, cas, encryption_algorithm + ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py new file mode 100644 index 0000000..9998bca --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/pkcs7.py @@ -0,0 +1,235 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import email.base64mime +import email.generator +import email.message +import email.policy +import io +import typing + +from cryptography import utils, x509 +from cryptography.hazmat.bindings._rust import pkcs7 as rust_pkcs7 +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import ec, rsa +from cryptography.utils import _check_byteslike + + +def load_pem_pkcs7_certificates(data: bytes) -> typing.List[x509.Certificate]: + from cryptography.hazmat.backends.openssl.backend import backend + + return backend.load_pem_pkcs7_certificates(data) + + +def load_der_pkcs7_certificates(data: bytes) -> typing.List[x509.Certificate]: + from cryptography.hazmat.backends.openssl.backend import backend + + return backend.load_der_pkcs7_certificates(data) + + +def serialize_certificates( + certs: typing.List[x509.Certificate], + encoding: serialization.Encoding, +) -> bytes: + return rust_pkcs7.serialize_certificates(certs, encoding) + + +PKCS7HashTypes = typing.Union[ + hashes.SHA224, + hashes.SHA256, + hashes.SHA384, + hashes.SHA512, +] + +PKCS7PrivateKeyTypes = typing.Union[ + rsa.RSAPrivateKey, ec.EllipticCurvePrivateKey +] + + +class PKCS7Options(utils.Enum): + Text = "Add text/plain MIME type" + Binary = "Don't translate input data into canonical MIME format" + DetachedSignature = "Don't embed data in the PKCS7 structure" + NoCapabilities = "Don't embed SMIME capabilities" + NoAttributes = "Don't embed authenticatedAttributes" + NoCerts = "Don't embed signer certificate" + + +class PKCS7SignatureBuilder: + def __init__( + self, + data: typing.Optional[bytes] = None, + signers: typing.List[ + typing.Tuple[ + x509.Certificate, + PKCS7PrivateKeyTypes, + PKCS7HashTypes, + ] + ] = [], + additional_certs: typing.List[x509.Certificate] = [], + ): + self._data = data + self._signers = signers + self._additional_certs = additional_certs + + def set_data(self, data: bytes) -> PKCS7SignatureBuilder: + _check_byteslike("data", data) + if self._data is not None: + raise ValueError("data may only be set once") + + return PKCS7SignatureBuilder(data, self._signers) + + def add_signer( + self, + certificate: x509.Certificate, + private_key: PKCS7PrivateKeyTypes, + hash_algorithm: PKCS7HashTypes, + ) -> PKCS7SignatureBuilder: + if not isinstance( + hash_algorithm, + ( + hashes.SHA224, + hashes.SHA256, + hashes.SHA384, + hashes.SHA512, + ), + ): + raise TypeError( + "hash_algorithm must be one of hashes.SHA224, " + "SHA256, SHA384, or SHA512" + ) + if not isinstance(certificate, x509.Certificate): + raise TypeError("certificate must be a x509.Certificate") + + if not isinstance( + private_key, (rsa.RSAPrivateKey, ec.EllipticCurvePrivateKey) + ): + raise TypeError("Only RSA & EC keys are supported at this time.") + + return PKCS7SignatureBuilder( + self._data, + self._signers + [(certificate, private_key, hash_algorithm)], + ) + + def add_certificate( + self, certificate: x509.Certificate + ) -> PKCS7SignatureBuilder: + if not isinstance(certificate, x509.Certificate): + raise TypeError("certificate must be a x509.Certificate") + + return PKCS7SignatureBuilder( + self._data, self._signers, self._additional_certs + [certificate] + ) + + def sign( + self, + encoding: serialization.Encoding, + options: typing.Iterable[PKCS7Options], + backend: typing.Any = None, + ) -> bytes: + if len(self._signers) == 0: + raise ValueError("Must have at least one signer") + if self._data is None: + raise ValueError("You must add data to sign") + options = list(options) + if not all(isinstance(x, PKCS7Options) for x in options): + raise ValueError("options must be from the PKCS7Options enum") + if encoding not in ( + serialization.Encoding.PEM, + serialization.Encoding.DER, + serialization.Encoding.SMIME, + ): + raise ValueError( + "Must be PEM, DER, or SMIME from the Encoding enum" + ) + + # Text is a meaningless option unless it is accompanied by + # DetachedSignature + if ( + PKCS7Options.Text in options + and PKCS7Options.DetachedSignature not in options + ): + raise ValueError( + "When passing the Text option you must also pass " + "DetachedSignature" + ) + + if PKCS7Options.Text in options and encoding in ( + serialization.Encoding.DER, + serialization.Encoding.PEM, + ): + raise ValueError( + "The Text option is only available for SMIME serialization" + ) + + # No attributes implies no capabilities so we'll error if you try to + # pass both. + if ( + PKCS7Options.NoAttributes in options + and PKCS7Options.NoCapabilities in options + ): + raise ValueError( + "NoAttributes is a superset of NoCapabilities. Do not pass " + "both values." + ) + + return rust_pkcs7.sign_and_serialize(self, encoding, options) + + +def _smime_encode( + data: bytes, signature: bytes, micalg: str, text_mode: bool +) -> bytes: + # This function works pretty hard to replicate what OpenSSL does + # precisely. For good and for ill. + + m = email.message.Message() + m.add_header("MIME-Version", "1.0") + m.add_header( + "Content-Type", + "multipart/signed", + protocol="application/x-pkcs7-signature", + micalg=micalg, + ) + + m.preamble = "This is an S/MIME signed message\n" + + msg_part = OpenSSLMimePart() + msg_part.set_payload(data) + if text_mode: + msg_part.add_header("Content-Type", "text/plain") + m.attach(msg_part) + + sig_part = email.message.MIMEPart() + sig_part.add_header( + "Content-Type", "application/x-pkcs7-signature", name="smime.p7s" + ) + sig_part.add_header("Content-Transfer-Encoding", "base64") + sig_part.add_header( + "Content-Disposition", "attachment", filename="smime.p7s" + ) + sig_part.set_payload( + email.base64mime.body_encode(signature, maxlinelen=65) + ) + del sig_part["MIME-Version"] + m.attach(sig_part) + + fp = io.BytesIO() + g = email.generator.BytesGenerator( + fp, + maxheaderlen=0, + mangle_from_=False, + policy=m.policy.clone(linesep="\r\n"), + ) + g.flatten(m) + return fp.getvalue() + + +class OpenSSLMimePart(email.message.MIMEPart): + # A MIMEPart subclass that replicates OpenSSL's behavior of not including + # a newline if there are no headers. + def _write_headers(self, generator) -> None: + if list(self.raw_items()): + generator._write_headers(self) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/ssh.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/ssh.py new file mode 100644 index 0000000..7725c83 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/serialization/ssh.py @@ -0,0 +1,1510 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import binascii +import enum +import os +import re +import typing +import warnings +from base64 import encodebytes as _base64_encode +from dataclasses import dataclass + +from cryptography import utils +from cryptography.exceptions import UnsupportedAlgorithm +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import ( + dsa, + ec, + ed25519, + padding, + rsa, +) +from cryptography.hazmat.primitives.asymmetric import utils as asym_utils +from cryptography.hazmat.primitives.ciphers import ( + AEADDecryptionContext, + Cipher, + algorithms, + modes, +) +from cryptography.hazmat.primitives.serialization import ( + Encoding, + KeySerializationEncryption, + NoEncryption, + PrivateFormat, + PublicFormat, + _KeySerializationEncryption, +) + +try: + from bcrypt import kdf as _bcrypt_kdf + + _bcrypt_supported = True +except ImportError: + _bcrypt_supported = False + + def _bcrypt_kdf( + password: bytes, + salt: bytes, + desired_key_bytes: int, + rounds: int, + ignore_few_rounds: bool = False, + ) -> bytes: + raise UnsupportedAlgorithm("Need bcrypt module") + + +_SSH_ED25519 = b"ssh-ed25519" +_SSH_RSA = b"ssh-rsa" +_SSH_DSA = b"ssh-dss" +_ECDSA_NISTP256 = b"ecdsa-sha2-nistp256" +_ECDSA_NISTP384 = b"ecdsa-sha2-nistp384" +_ECDSA_NISTP521 = b"ecdsa-sha2-nistp521" +_CERT_SUFFIX = b"-cert-v01@openssh.com" + +# These are not key types, only algorithms, so they cannot appear +# as a public key type +_SSH_RSA_SHA256 = b"rsa-sha2-256" +_SSH_RSA_SHA512 = b"rsa-sha2-512" + +_SSH_PUBKEY_RC = re.compile(rb"\A(\S+)[ \t]+(\S+)") +_SK_MAGIC = b"openssh-key-v1\0" +_SK_START = b"-----BEGIN OPENSSH PRIVATE KEY-----" +_SK_END = b"-----END OPENSSH PRIVATE KEY-----" +_BCRYPT = b"bcrypt" +_NONE = b"none" +_DEFAULT_CIPHER = b"aes256-ctr" +_DEFAULT_ROUNDS = 16 + +# re is only way to work on bytes-like data +_PEM_RC = re.compile(_SK_START + b"(.*?)" + _SK_END, re.DOTALL) + +# padding for max blocksize +_PADDING = memoryview(bytearray(range(1, 1 + 16))) + + +@dataclass +class _SSHCipher: + alg: typing.Type[algorithms.AES] + key_len: int + mode: typing.Union[ + typing.Type[modes.CTR], + typing.Type[modes.CBC], + typing.Type[modes.GCM], + ] + block_len: int + iv_len: int + tag_len: typing.Optional[int] + is_aead: bool + + +# ciphers that are actually used in key wrapping +_SSH_CIPHERS: typing.Dict[bytes, _SSHCipher] = { + b"aes256-ctr": _SSHCipher( + alg=algorithms.AES, + key_len=32, + mode=modes.CTR, + block_len=16, + iv_len=16, + tag_len=None, + is_aead=False, + ), + b"aes256-cbc": _SSHCipher( + alg=algorithms.AES, + key_len=32, + mode=modes.CBC, + block_len=16, + iv_len=16, + tag_len=None, + is_aead=False, + ), + b"aes256-gcm@openssh.com": _SSHCipher( + alg=algorithms.AES, + key_len=32, + mode=modes.GCM, + block_len=16, + iv_len=12, + tag_len=16, + is_aead=True, + ), +} + +# map local curve name to key type +_ECDSA_KEY_TYPE = { + "secp256r1": _ECDSA_NISTP256, + "secp384r1": _ECDSA_NISTP384, + "secp521r1": _ECDSA_NISTP521, +} + + +def _get_ssh_key_type( + key: typing.Union[SSHPrivateKeyTypes, SSHPublicKeyTypes] +) -> bytes: + if isinstance(key, ec.EllipticCurvePrivateKey): + key_type = _ecdsa_key_type(key.public_key()) + elif isinstance(key, ec.EllipticCurvePublicKey): + key_type = _ecdsa_key_type(key) + elif isinstance(key, (rsa.RSAPrivateKey, rsa.RSAPublicKey)): + key_type = _SSH_RSA + elif isinstance(key, (dsa.DSAPrivateKey, dsa.DSAPublicKey)): + key_type = _SSH_DSA + elif isinstance( + key, (ed25519.Ed25519PrivateKey, ed25519.Ed25519PublicKey) + ): + key_type = _SSH_ED25519 + else: + raise ValueError("Unsupported key type") + + return key_type + + +def _ecdsa_key_type(public_key: ec.EllipticCurvePublicKey) -> bytes: + """Return SSH key_type and curve_name for private key.""" + curve = public_key.curve + if curve.name not in _ECDSA_KEY_TYPE: + raise ValueError( + f"Unsupported curve for ssh private key: {curve.name!r}" + ) + return _ECDSA_KEY_TYPE[curve.name] + + +def _ssh_pem_encode( + data: bytes, + prefix: bytes = _SK_START + b"\n", + suffix: bytes = _SK_END + b"\n", +) -> bytes: + return b"".join([prefix, _base64_encode(data), suffix]) + + +def _check_block_size(data: bytes, block_len: int) -> None: + """Require data to be full blocks""" + if not data or len(data) % block_len != 0: + raise ValueError("Corrupt data: missing padding") + + +def _check_empty(data: bytes) -> None: + """All data should have been parsed.""" + if data: + raise ValueError("Corrupt data: unparsed data") + + +def _init_cipher( + ciphername: bytes, + password: typing.Optional[bytes], + salt: bytes, + rounds: int, +) -> Cipher[typing.Union[modes.CBC, modes.CTR, modes.GCM]]: + """Generate key + iv and return cipher.""" + if not password: + raise ValueError("Key is password-protected.") + + ciph = _SSH_CIPHERS[ciphername] + seed = _bcrypt_kdf( + password, salt, ciph.key_len + ciph.iv_len, rounds, True + ) + return Cipher( + ciph.alg(seed[: ciph.key_len]), + ciph.mode(seed[ciph.key_len :]), + ) + + +def _get_u32(data: memoryview) -> typing.Tuple[int, memoryview]: + """Uint32""" + if len(data) < 4: + raise ValueError("Invalid data") + return int.from_bytes(data[:4], byteorder="big"), data[4:] + + +def _get_u64(data: memoryview) -> typing.Tuple[int, memoryview]: + """Uint64""" + if len(data) < 8: + raise ValueError("Invalid data") + return int.from_bytes(data[:8], byteorder="big"), data[8:] + + +def _get_sshstr(data: memoryview) -> typing.Tuple[memoryview, memoryview]: + """Bytes with u32 length prefix""" + n, data = _get_u32(data) + if n > len(data): + raise ValueError("Invalid data") + return data[:n], data[n:] + + +def _get_mpint(data: memoryview) -> typing.Tuple[int, memoryview]: + """Big integer.""" + val, data = _get_sshstr(data) + if val and val[0] > 0x7F: + raise ValueError("Invalid data") + return int.from_bytes(val, "big"), data + + +def _to_mpint(val: int) -> bytes: + """Storage format for signed bigint.""" + if val < 0: + raise ValueError("negative mpint not allowed") + if not val: + return b"" + nbytes = (val.bit_length() + 8) // 8 + return utils.int_to_bytes(val, nbytes) + + +class _FragList: + """Build recursive structure without data copy.""" + + flist: typing.List[bytes] + + def __init__( + self, init: typing.Optional[typing.List[bytes]] = None + ) -> None: + self.flist = [] + if init: + self.flist.extend(init) + + def put_raw(self, val: bytes) -> None: + """Add plain bytes""" + self.flist.append(val) + + def put_u32(self, val: int) -> None: + """Big-endian uint32""" + self.flist.append(val.to_bytes(length=4, byteorder="big")) + + def put_u64(self, val: int) -> None: + """Big-endian uint64""" + self.flist.append(val.to_bytes(length=8, byteorder="big")) + + def put_sshstr(self, val: typing.Union[bytes, _FragList]) -> None: + """Bytes prefixed with u32 length""" + if isinstance(val, (bytes, memoryview, bytearray)): + self.put_u32(len(val)) + self.flist.append(val) + else: + self.put_u32(val.size()) + self.flist.extend(val.flist) + + def put_mpint(self, val: int) -> None: + """Big-endian bigint prefixed with u32 length""" + self.put_sshstr(_to_mpint(val)) + + def size(self) -> int: + """Current number of bytes""" + return sum(map(len, self.flist)) + + def render(self, dstbuf: memoryview, pos: int = 0) -> int: + """Write into bytearray""" + for frag in self.flist: + flen = len(frag) + start, pos = pos, pos + flen + dstbuf[start:pos] = frag + return pos + + def tobytes(self) -> bytes: + """Return as bytes""" + buf = memoryview(bytearray(self.size())) + self.render(buf) + return buf.tobytes() + + +class _SSHFormatRSA: + """Format for RSA keys. + + Public: + mpint e, n + Private: + mpint n, e, d, iqmp, p, q + """ + + def get_public(self, data: memoryview): + """RSA public fields""" + e, data = _get_mpint(data) + n, data = _get_mpint(data) + return (e, n), data + + def load_public( + self, data: memoryview + ) -> typing.Tuple[rsa.RSAPublicKey, memoryview]: + """Make RSA public key from data.""" + (e, n), data = self.get_public(data) + public_numbers = rsa.RSAPublicNumbers(e, n) + public_key = public_numbers.public_key() + return public_key, data + + def load_private( + self, data: memoryview, pubfields + ) -> typing.Tuple[rsa.RSAPrivateKey, memoryview]: + """Make RSA private key from data.""" + n, data = _get_mpint(data) + e, data = _get_mpint(data) + d, data = _get_mpint(data) + iqmp, data = _get_mpint(data) + p, data = _get_mpint(data) + q, data = _get_mpint(data) + + if (e, n) != pubfields: + raise ValueError("Corrupt data: rsa field mismatch") + dmp1 = rsa.rsa_crt_dmp1(d, p) + dmq1 = rsa.rsa_crt_dmq1(d, q) + public_numbers = rsa.RSAPublicNumbers(e, n) + private_numbers = rsa.RSAPrivateNumbers( + p, q, d, dmp1, dmq1, iqmp, public_numbers + ) + private_key = private_numbers.private_key() + return private_key, data + + def encode_public( + self, public_key: rsa.RSAPublicKey, f_pub: _FragList + ) -> None: + """Write RSA public key""" + pubn = public_key.public_numbers() + f_pub.put_mpint(pubn.e) + f_pub.put_mpint(pubn.n) + + def encode_private( + self, private_key: rsa.RSAPrivateKey, f_priv: _FragList + ) -> None: + """Write RSA private key""" + private_numbers = private_key.private_numbers() + public_numbers = private_numbers.public_numbers + + f_priv.put_mpint(public_numbers.n) + f_priv.put_mpint(public_numbers.e) + + f_priv.put_mpint(private_numbers.d) + f_priv.put_mpint(private_numbers.iqmp) + f_priv.put_mpint(private_numbers.p) + f_priv.put_mpint(private_numbers.q) + + +class _SSHFormatDSA: + """Format for DSA keys. + + Public: + mpint p, q, g, y + Private: + mpint p, q, g, y, x + """ + + def get_public( + self, data: memoryview + ) -> typing.Tuple[typing.Tuple, memoryview]: + """DSA public fields""" + p, data = _get_mpint(data) + q, data = _get_mpint(data) + g, data = _get_mpint(data) + y, data = _get_mpint(data) + return (p, q, g, y), data + + def load_public( + self, data: memoryview + ) -> typing.Tuple[dsa.DSAPublicKey, memoryview]: + """Make DSA public key from data.""" + (p, q, g, y), data = self.get_public(data) + parameter_numbers = dsa.DSAParameterNumbers(p, q, g) + public_numbers = dsa.DSAPublicNumbers(y, parameter_numbers) + self._validate(public_numbers) + public_key = public_numbers.public_key() + return public_key, data + + def load_private( + self, data: memoryview, pubfields + ) -> typing.Tuple[dsa.DSAPrivateKey, memoryview]: + """Make DSA private key from data.""" + (p, q, g, y), data = self.get_public(data) + x, data = _get_mpint(data) + + if (p, q, g, y) != pubfields: + raise ValueError("Corrupt data: dsa field mismatch") + parameter_numbers = dsa.DSAParameterNumbers(p, q, g) + public_numbers = dsa.DSAPublicNumbers(y, parameter_numbers) + self._validate(public_numbers) + private_numbers = dsa.DSAPrivateNumbers(x, public_numbers) + private_key = private_numbers.private_key() + return private_key, data + + def encode_public( + self, public_key: dsa.DSAPublicKey, f_pub: _FragList + ) -> None: + """Write DSA public key""" + public_numbers = public_key.public_numbers() + parameter_numbers = public_numbers.parameter_numbers + self._validate(public_numbers) + + f_pub.put_mpint(parameter_numbers.p) + f_pub.put_mpint(parameter_numbers.q) + f_pub.put_mpint(parameter_numbers.g) + f_pub.put_mpint(public_numbers.y) + + def encode_private( + self, private_key: dsa.DSAPrivateKey, f_priv: _FragList + ) -> None: + """Write DSA private key""" + self.encode_public(private_key.public_key(), f_priv) + f_priv.put_mpint(private_key.private_numbers().x) + + def _validate(self, public_numbers: dsa.DSAPublicNumbers) -> None: + parameter_numbers = public_numbers.parameter_numbers + if parameter_numbers.p.bit_length() != 1024: + raise ValueError("SSH supports only 1024 bit DSA keys") + + +class _SSHFormatECDSA: + """Format for ECDSA keys. + + Public: + str curve + bytes point + Private: + str curve + bytes point + mpint secret + """ + + def __init__(self, ssh_curve_name: bytes, curve: ec.EllipticCurve): + self.ssh_curve_name = ssh_curve_name + self.curve = curve + + def get_public( + self, data: memoryview + ) -> typing.Tuple[typing.Tuple, memoryview]: + """ECDSA public fields""" + curve, data = _get_sshstr(data) + point, data = _get_sshstr(data) + if curve != self.ssh_curve_name: + raise ValueError("Curve name mismatch") + if point[0] != 4: + raise NotImplementedError("Need uncompressed point") + return (curve, point), data + + def load_public( + self, data: memoryview + ) -> typing.Tuple[ec.EllipticCurvePublicKey, memoryview]: + """Make ECDSA public key from data.""" + (curve_name, point), data = self.get_public(data) + public_key = ec.EllipticCurvePublicKey.from_encoded_point( + self.curve, point.tobytes() + ) + return public_key, data + + def load_private( + self, data: memoryview, pubfields + ) -> typing.Tuple[ec.EllipticCurvePrivateKey, memoryview]: + """Make ECDSA private key from data.""" + (curve_name, point), data = self.get_public(data) + secret, data = _get_mpint(data) + + if (curve_name, point) != pubfields: + raise ValueError("Corrupt data: ecdsa field mismatch") + private_key = ec.derive_private_key(secret, self.curve) + return private_key, data + + def encode_public( + self, public_key: ec.EllipticCurvePublicKey, f_pub: _FragList + ) -> None: + """Write ECDSA public key""" + point = public_key.public_bytes( + Encoding.X962, PublicFormat.UncompressedPoint + ) + f_pub.put_sshstr(self.ssh_curve_name) + f_pub.put_sshstr(point) + + def encode_private( + self, private_key: ec.EllipticCurvePrivateKey, f_priv: _FragList + ) -> None: + """Write ECDSA private key""" + public_key = private_key.public_key() + private_numbers = private_key.private_numbers() + + self.encode_public(public_key, f_priv) + f_priv.put_mpint(private_numbers.private_value) + + +class _SSHFormatEd25519: + """Format for Ed25519 keys. + + Public: + bytes point + Private: + bytes point + bytes secret_and_point + """ + + def get_public( + self, data: memoryview + ) -> typing.Tuple[typing.Tuple, memoryview]: + """Ed25519 public fields""" + point, data = _get_sshstr(data) + return (point,), data + + def load_public( + self, data: memoryview + ) -> typing.Tuple[ed25519.Ed25519PublicKey, memoryview]: + """Make Ed25519 public key from data.""" + (point,), data = self.get_public(data) + public_key = ed25519.Ed25519PublicKey.from_public_bytes( + point.tobytes() + ) + return public_key, data + + def load_private( + self, data: memoryview, pubfields + ) -> typing.Tuple[ed25519.Ed25519PrivateKey, memoryview]: + """Make Ed25519 private key from data.""" + (point,), data = self.get_public(data) + keypair, data = _get_sshstr(data) + + secret = keypair[:32] + point2 = keypair[32:] + if point != point2 or (point,) != pubfields: + raise ValueError("Corrupt data: ed25519 field mismatch") + private_key = ed25519.Ed25519PrivateKey.from_private_bytes(secret) + return private_key, data + + def encode_public( + self, public_key: ed25519.Ed25519PublicKey, f_pub: _FragList + ) -> None: + """Write Ed25519 public key""" + raw_public_key = public_key.public_bytes( + Encoding.Raw, PublicFormat.Raw + ) + f_pub.put_sshstr(raw_public_key) + + def encode_private( + self, private_key: ed25519.Ed25519PrivateKey, f_priv: _FragList + ) -> None: + """Write Ed25519 private key""" + public_key = private_key.public_key() + raw_private_key = private_key.private_bytes( + Encoding.Raw, PrivateFormat.Raw, NoEncryption() + ) + raw_public_key = public_key.public_bytes( + Encoding.Raw, PublicFormat.Raw + ) + f_keypair = _FragList([raw_private_key, raw_public_key]) + + self.encode_public(public_key, f_priv) + f_priv.put_sshstr(f_keypair) + + +_KEY_FORMATS = { + _SSH_RSA: _SSHFormatRSA(), + _SSH_DSA: _SSHFormatDSA(), + _SSH_ED25519: _SSHFormatEd25519(), + _ECDSA_NISTP256: _SSHFormatECDSA(b"nistp256", ec.SECP256R1()), + _ECDSA_NISTP384: _SSHFormatECDSA(b"nistp384", ec.SECP384R1()), + _ECDSA_NISTP521: _SSHFormatECDSA(b"nistp521", ec.SECP521R1()), +} + + +def _lookup_kformat(key_type: bytes): + """Return valid format or throw error""" + if not isinstance(key_type, bytes): + key_type = memoryview(key_type).tobytes() + if key_type in _KEY_FORMATS: + return _KEY_FORMATS[key_type] + raise UnsupportedAlgorithm(f"Unsupported key type: {key_type!r}") + + +SSHPrivateKeyTypes = typing.Union[ + ec.EllipticCurvePrivateKey, + rsa.RSAPrivateKey, + dsa.DSAPrivateKey, + ed25519.Ed25519PrivateKey, +] + + +def load_ssh_private_key( + data: bytes, + password: typing.Optional[bytes], + backend: typing.Any = None, +) -> SSHPrivateKeyTypes: + """Load private key from OpenSSH custom encoding.""" + utils._check_byteslike("data", data) + if password is not None: + utils._check_bytes("password", password) + + m = _PEM_RC.search(data) + if not m: + raise ValueError("Not OpenSSH private key format") + p1 = m.start(1) + p2 = m.end(1) + data = binascii.a2b_base64(memoryview(data)[p1:p2]) + if not data.startswith(_SK_MAGIC): + raise ValueError("Not OpenSSH private key format") + data = memoryview(data)[len(_SK_MAGIC) :] + + # parse header + ciphername, data = _get_sshstr(data) + kdfname, data = _get_sshstr(data) + kdfoptions, data = _get_sshstr(data) + nkeys, data = _get_u32(data) + if nkeys != 1: + raise ValueError("Only one key supported") + + # load public key data + pubdata, data = _get_sshstr(data) + pub_key_type, pubdata = _get_sshstr(pubdata) + kformat = _lookup_kformat(pub_key_type) + pubfields, pubdata = kformat.get_public(pubdata) + _check_empty(pubdata) + + if (ciphername, kdfname) != (_NONE, _NONE): + ciphername_bytes = ciphername.tobytes() + if ciphername_bytes not in _SSH_CIPHERS: + raise UnsupportedAlgorithm( + f"Unsupported cipher: {ciphername_bytes!r}" + ) + if kdfname != _BCRYPT: + raise UnsupportedAlgorithm(f"Unsupported KDF: {kdfname!r}") + blklen = _SSH_CIPHERS[ciphername_bytes].block_len + tag_len = _SSH_CIPHERS[ciphername_bytes].tag_len + # load secret data + edata, data = _get_sshstr(data) + # see https://bugzilla.mindrot.org/show_bug.cgi?id=3553 for + # information about how OpenSSH handles AEAD tags + if _SSH_CIPHERS[ciphername_bytes].is_aead: + tag = bytes(data) + if len(tag) != tag_len: + raise ValueError("Corrupt data: invalid tag length for cipher") + else: + _check_empty(data) + _check_block_size(edata, blklen) + salt, kbuf = _get_sshstr(kdfoptions) + rounds, kbuf = _get_u32(kbuf) + _check_empty(kbuf) + ciph = _init_cipher(ciphername_bytes, password, salt.tobytes(), rounds) + dec = ciph.decryptor() + edata = memoryview(dec.update(edata)) + if _SSH_CIPHERS[ciphername_bytes].is_aead: + assert isinstance(dec, AEADDecryptionContext) + _check_empty(dec.finalize_with_tag(tag)) + else: + # _check_block_size requires data to be a full block so there + # should be no output from finalize + _check_empty(dec.finalize()) + else: + # load secret data + edata, data = _get_sshstr(data) + _check_empty(data) + blklen = 8 + _check_block_size(edata, blklen) + ck1, edata = _get_u32(edata) + ck2, edata = _get_u32(edata) + if ck1 != ck2: + raise ValueError("Corrupt data: broken checksum") + + # load per-key struct + key_type, edata = _get_sshstr(edata) + if key_type != pub_key_type: + raise ValueError("Corrupt data: key type mismatch") + private_key, edata = kformat.load_private(edata, pubfields) + comment, edata = _get_sshstr(edata) + + # yes, SSH does padding check *after* all other parsing is done. + # need to follow as it writes zero-byte padding too. + if edata != _PADDING[: len(edata)]: + raise ValueError("Corrupt data: invalid padding") + + if isinstance(private_key, dsa.DSAPrivateKey): + warnings.warn( + "SSH DSA keys are deprecated and will be removed in a future " + "release.", + utils.DeprecatedIn40, + stacklevel=2, + ) + + return private_key + + +def _serialize_ssh_private_key( + private_key: SSHPrivateKeyTypes, + password: bytes, + encryption_algorithm: KeySerializationEncryption, +) -> bytes: + """Serialize private key with OpenSSH custom encoding.""" + utils._check_bytes("password", password) + if isinstance(private_key, dsa.DSAPrivateKey): + warnings.warn( + "SSH DSA key support is deprecated and will be " + "removed in a future release", + utils.DeprecatedIn40, + stacklevel=4, + ) + + key_type = _get_ssh_key_type(private_key) + kformat = _lookup_kformat(key_type) + + # setup parameters + f_kdfoptions = _FragList() + if password: + ciphername = _DEFAULT_CIPHER + blklen = _SSH_CIPHERS[ciphername].block_len + kdfname = _BCRYPT + rounds = _DEFAULT_ROUNDS + if ( + isinstance(encryption_algorithm, _KeySerializationEncryption) + and encryption_algorithm._kdf_rounds is not None + ): + rounds = encryption_algorithm._kdf_rounds + salt = os.urandom(16) + f_kdfoptions.put_sshstr(salt) + f_kdfoptions.put_u32(rounds) + ciph = _init_cipher(ciphername, password, salt, rounds) + else: + ciphername = kdfname = _NONE + blklen = 8 + ciph = None + nkeys = 1 + checkval = os.urandom(4) + comment = b"" + + # encode public and private parts together + f_public_key = _FragList() + f_public_key.put_sshstr(key_type) + kformat.encode_public(private_key.public_key(), f_public_key) + + f_secrets = _FragList([checkval, checkval]) + f_secrets.put_sshstr(key_type) + kformat.encode_private(private_key, f_secrets) + f_secrets.put_sshstr(comment) + f_secrets.put_raw(_PADDING[: blklen - (f_secrets.size() % blklen)]) + + # top-level structure + f_main = _FragList() + f_main.put_raw(_SK_MAGIC) + f_main.put_sshstr(ciphername) + f_main.put_sshstr(kdfname) + f_main.put_sshstr(f_kdfoptions) + f_main.put_u32(nkeys) + f_main.put_sshstr(f_public_key) + f_main.put_sshstr(f_secrets) + + # copy result info bytearray + slen = f_secrets.size() + mlen = f_main.size() + buf = memoryview(bytearray(mlen + blklen)) + f_main.render(buf) + ofs = mlen - slen + + # encrypt in-place + if ciph is not None: + ciph.encryptor().update_into(buf[ofs:mlen], buf[ofs:]) + + return _ssh_pem_encode(buf[:mlen]) + + +SSHPublicKeyTypes = typing.Union[ + ec.EllipticCurvePublicKey, + rsa.RSAPublicKey, + dsa.DSAPublicKey, + ed25519.Ed25519PublicKey, +] + +SSHCertPublicKeyTypes = typing.Union[ + ec.EllipticCurvePublicKey, + rsa.RSAPublicKey, + ed25519.Ed25519PublicKey, +] + + +class SSHCertificateType(enum.Enum): + USER = 1 + HOST = 2 + + +class SSHCertificate: + def __init__( + self, + _nonce: memoryview, + _public_key: SSHPublicKeyTypes, + _serial: int, + _cctype: int, + _key_id: memoryview, + _valid_principals: typing.List[bytes], + _valid_after: int, + _valid_before: int, + _critical_options: typing.Dict[bytes, bytes], + _extensions: typing.Dict[bytes, bytes], + _sig_type: memoryview, + _sig_key: memoryview, + _inner_sig_type: memoryview, + _signature: memoryview, + _tbs_cert_body: memoryview, + _cert_key_type: bytes, + _cert_body: memoryview, + ): + self._nonce = _nonce + self._public_key = _public_key + self._serial = _serial + try: + self._type = SSHCertificateType(_cctype) + except ValueError: + raise ValueError("Invalid certificate type") + self._key_id = _key_id + self._valid_principals = _valid_principals + self._valid_after = _valid_after + self._valid_before = _valid_before + self._critical_options = _critical_options + self._extensions = _extensions + self._sig_type = _sig_type + self._sig_key = _sig_key + self._inner_sig_type = _inner_sig_type + self._signature = _signature + self._cert_key_type = _cert_key_type + self._cert_body = _cert_body + self._tbs_cert_body = _tbs_cert_body + + @property + def nonce(self) -> bytes: + return bytes(self._nonce) + + def public_key(self) -> SSHCertPublicKeyTypes: + # make mypy happy until we remove DSA support entirely and + # the underlying union won't have a disallowed type + return typing.cast(SSHCertPublicKeyTypes, self._public_key) + + @property + def serial(self) -> int: + return self._serial + + @property + def type(self) -> SSHCertificateType: + return self._type + + @property + def key_id(self) -> bytes: + return bytes(self._key_id) + + @property + def valid_principals(self) -> typing.List[bytes]: + return self._valid_principals + + @property + def valid_before(self) -> int: + return self._valid_before + + @property + def valid_after(self) -> int: + return self._valid_after + + @property + def critical_options(self) -> typing.Dict[bytes, bytes]: + return self._critical_options + + @property + def extensions(self) -> typing.Dict[bytes, bytes]: + return self._extensions + + def signature_key(self) -> SSHCertPublicKeyTypes: + sigformat = _lookup_kformat(self._sig_type) + signature_key, sigkey_rest = sigformat.load_public(self._sig_key) + _check_empty(sigkey_rest) + return signature_key + + def public_bytes(self) -> bytes: + return ( + bytes(self._cert_key_type) + + b" " + + binascii.b2a_base64(bytes(self._cert_body), newline=False) + ) + + def verify_cert_signature(self) -> None: + signature_key = self.signature_key() + if isinstance(signature_key, ed25519.Ed25519PublicKey): + signature_key.verify( + bytes(self._signature), bytes(self._tbs_cert_body) + ) + elif isinstance(signature_key, ec.EllipticCurvePublicKey): + # The signature is encoded as a pair of big-endian integers + r, data = _get_mpint(self._signature) + s, data = _get_mpint(data) + _check_empty(data) + computed_sig = asym_utils.encode_dss_signature(r, s) + hash_alg = _get_ec_hash_alg(signature_key.curve) + signature_key.verify( + computed_sig, bytes(self._tbs_cert_body), ec.ECDSA(hash_alg) + ) + else: + assert isinstance(signature_key, rsa.RSAPublicKey) + if self._inner_sig_type == _SSH_RSA: + hash_alg = hashes.SHA1() + elif self._inner_sig_type == _SSH_RSA_SHA256: + hash_alg = hashes.SHA256() + else: + assert self._inner_sig_type == _SSH_RSA_SHA512 + hash_alg = hashes.SHA512() + signature_key.verify( + bytes(self._signature), + bytes(self._tbs_cert_body), + padding.PKCS1v15(), + hash_alg, + ) + + +def _get_ec_hash_alg(curve: ec.EllipticCurve) -> hashes.HashAlgorithm: + if isinstance(curve, ec.SECP256R1): + return hashes.SHA256() + elif isinstance(curve, ec.SECP384R1): + return hashes.SHA384() + else: + assert isinstance(curve, ec.SECP521R1) + return hashes.SHA512() + + +def _load_ssh_public_identity( + data: bytes, + _legacy_dsa_allowed=False, +) -> typing.Union[SSHCertificate, SSHPublicKeyTypes]: + utils._check_byteslike("data", data) + + m = _SSH_PUBKEY_RC.match(data) + if not m: + raise ValueError("Invalid line format") + key_type = orig_key_type = m.group(1) + key_body = m.group(2) + with_cert = False + if key_type.endswith(_CERT_SUFFIX): + with_cert = True + key_type = key_type[: -len(_CERT_SUFFIX)] + if key_type == _SSH_DSA and not _legacy_dsa_allowed: + raise UnsupportedAlgorithm( + "DSA keys aren't supported in SSH certificates" + ) + kformat = _lookup_kformat(key_type) + + try: + rest = memoryview(binascii.a2b_base64(key_body)) + except (TypeError, binascii.Error): + raise ValueError("Invalid format") + + if with_cert: + cert_body = rest + inner_key_type, rest = _get_sshstr(rest) + if inner_key_type != orig_key_type: + raise ValueError("Invalid key format") + if with_cert: + nonce, rest = _get_sshstr(rest) + public_key, rest = kformat.load_public(rest) + if with_cert: + serial, rest = _get_u64(rest) + cctype, rest = _get_u32(rest) + key_id, rest = _get_sshstr(rest) + principals, rest = _get_sshstr(rest) + valid_principals = [] + while principals: + principal, principals = _get_sshstr(principals) + valid_principals.append(bytes(principal)) + valid_after, rest = _get_u64(rest) + valid_before, rest = _get_u64(rest) + crit_options, rest = _get_sshstr(rest) + critical_options = _parse_exts_opts(crit_options) + exts, rest = _get_sshstr(rest) + extensions = _parse_exts_opts(exts) + # Get the reserved field, which is unused. + _, rest = _get_sshstr(rest) + sig_key_raw, rest = _get_sshstr(rest) + sig_type, sig_key = _get_sshstr(sig_key_raw) + if sig_type == _SSH_DSA and not _legacy_dsa_allowed: + raise UnsupportedAlgorithm( + "DSA signatures aren't supported in SSH certificates" + ) + # Get the entire cert body and subtract the signature + tbs_cert_body = cert_body[: -len(rest)] + signature_raw, rest = _get_sshstr(rest) + _check_empty(rest) + inner_sig_type, sig_rest = _get_sshstr(signature_raw) + # RSA certs can have multiple algorithm types + if ( + sig_type == _SSH_RSA + and inner_sig_type + not in [_SSH_RSA_SHA256, _SSH_RSA_SHA512, _SSH_RSA] + ) or (sig_type != _SSH_RSA and inner_sig_type != sig_type): + raise ValueError("Signature key type does not match") + signature, sig_rest = _get_sshstr(sig_rest) + _check_empty(sig_rest) + return SSHCertificate( + nonce, + public_key, + serial, + cctype, + key_id, + valid_principals, + valid_after, + valid_before, + critical_options, + extensions, + sig_type, + sig_key, + inner_sig_type, + signature, + tbs_cert_body, + orig_key_type, + cert_body, + ) + else: + _check_empty(rest) + return public_key + + +def load_ssh_public_identity( + data: bytes, +) -> typing.Union[SSHCertificate, SSHPublicKeyTypes]: + return _load_ssh_public_identity(data) + + +def _parse_exts_opts(exts_opts: memoryview) -> typing.Dict[bytes, bytes]: + result: typing.Dict[bytes, bytes] = {} + last_name = None + while exts_opts: + name, exts_opts = _get_sshstr(exts_opts) + bname: bytes = bytes(name) + if bname in result: + raise ValueError("Duplicate name") + if last_name is not None and bname < last_name: + raise ValueError("Fields not lexically sorted") + value, exts_opts = _get_sshstr(exts_opts) + result[bname] = bytes(value) + last_name = bname + return result + + +def load_ssh_public_key( + data: bytes, backend: typing.Any = None +) -> SSHPublicKeyTypes: + cert_or_key = _load_ssh_public_identity(data, _legacy_dsa_allowed=True) + public_key: SSHPublicKeyTypes + if isinstance(cert_or_key, SSHCertificate): + public_key = cert_or_key.public_key() + else: + public_key = cert_or_key + + if isinstance(public_key, dsa.DSAPublicKey): + warnings.warn( + "SSH DSA keys are deprecated and will be removed in a future " + "release.", + utils.DeprecatedIn40, + stacklevel=2, + ) + return public_key + + +def serialize_ssh_public_key(public_key: SSHPublicKeyTypes) -> bytes: + """One-line public key format for OpenSSH""" + if isinstance(public_key, dsa.DSAPublicKey): + warnings.warn( + "SSH DSA key support is deprecated and will be " + "removed in a future release", + utils.DeprecatedIn40, + stacklevel=4, + ) + key_type = _get_ssh_key_type(public_key) + kformat = _lookup_kformat(key_type) + + f_pub = _FragList() + f_pub.put_sshstr(key_type) + kformat.encode_public(public_key, f_pub) + + pub = binascii.b2a_base64(f_pub.tobytes()).strip() + return b"".join([key_type, b" ", pub]) + + +SSHCertPrivateKeyTypes = typing.Union[ + ec.EllipticCurvePrivateKey, + rsa.RSAPrivateKey, + ed25519.Ed25519PrivateKey, +] + + +# This is an undocumented limit enforced in the openssh codebase for sshd and +# ssh-keygen, but it is undefined in the ssh certificates spec. +_SSHKEY_CERT_MAX_PRINCIPALS = 256 + + +class SSHCertificateBuilder: + def __init__( + self, + _public_key: typing.Optional[SSHCertPublicKeyTypes] = None, + _serial: typing.Optional[int] = None, + _type: typing.Optional[SSHCertificateType] = None, + _key_id: typing.Optional[bytes] = None, + _valid_principals: typing.List[bytes] = [], + _valid_for_all_principals: bool = False, + _valid_before: typing.Optional[int] = None, + _valid_after: typing.Optional[int] = None, + _critical_options: typing.List[typing.Tuple[bytes, bytes]] = [], + _extensions: typing.List[typing.Tuple[bytes, bytes]] = [], + ): + self._public_key = _public_key + self._serial = _serial + self._type = _type + self._key_id = _key_id + self._valid_principals = _valid_principals + self._valid_for_all_principals = _valid_for_all_principals + self._valid_before = _valid_before + self._valid_after = _valid_after + self._critical_options = _critical_options + self._extensions = _extensions + + def public_key( + self, public_key: SSHCertPublicKeyTypes + ) -> SSHCertificateBuilder: + if not isinstance( + public_key, + ( + ec.EllipticCurvePublicKey, + rsa.RSAPublicKey, + ed25519.Ed25519PublicKey, + ), + ): + raise TypeError("Unsupported key type") + if self._public_key is not None: + raise ValueError("public_key already set") + + return SSHCertificateBuilder( + _public_key=public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def serial(self, serial: int) -> SSHCertificateBuilder: + if not isinstance(serial, int): + raise TypeError("serial must be an integer") + if not 0 <= serial < 2**64: + raise ValueError("serial must be between 0 and 2**64") + if self._serial is not None: + raise ValueError("serial already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def type(self, type: SSHCertificateType) -> SSHCertificateBuilder: + if not isinstance(type, SSHCertificateType): + raise TypeError("type must be an SSHCertificateType") + if self._type is not None: + raise ValueError("type already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def key_id(self, key_id: bytes) -> SSHCertificateBuilder: + if not isinstance(key_id, bytes): + raise TypeError("key_id must be bytes") + if self._key_id is not None: + raise ValueError("key_id already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def valid_principals( + self, valid_principals: typing.List[bytes] + ) -> SSHCertificateBuilder: + if self._valid_for_all_principals: + raise ValueError( + "Principals can't be set because the cert is valid " + "for all principals" + ) + if ( + not all(isinstance(x, bytes) for x in valid_principals) + or not valid_principals + ): + raise TypeError( + "principals must be a list of bytes and can't be empty" + ) + if self._valid_principals: + raise ValueError("valid_principals already set") + + if len(valid_principals) > _SSHKEY_CERT_MAX_PRINCIPALS: + raise ValueError( + "Reached or exceeded the maximum number of valid_principals" + ) + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def valid_for_all_principals(self): + if self._valid_principals: + raise ValueError( + "valid_principals already set, can't set " + "valid_for_all_principals" + ) + if self._valid_for_all_principals: + raise ValueError("valid_for_all_principals already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=True, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def valid_before( + self, valid_before: typing.Union[int, float] + ) -> SSHCertificateBuilder: + if not isinstance(valid_before, (int, float)): + raise TypeError("valid_before must be an int or float") + valid_before = int(valid_before) + if valid_before < 0 or valid_before >= 2**64: + raise ValueError("valid_before must [0, 2**64)") + if self._valid_before is not None: + raise ValueError("valid_before already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def valid_after( + self, valid_after: typing.Union[int, float] + ) -> SSHCertificateBuilder: + if not isinstance(valid_after, (int, float)): + raise TypeError("valid_after must be an int or float") + valid_after = int(valid_after) + if valid_after < 0 or valid_after >= 2**64: + raise ValueError("valid_after must [0, 2**64)") + if self._valid_after is not None: + raise ValueError("valid_after already set") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions, + ) + + def add_critical_option( + self, name: bytes, value: bytes + ) -> SSHCertificateBuilder: + if not isinstance(name, bytes) or not isinstance(value, bytes): + raise TypeError("name and value must be bytes") + # This is O(n**2) + if name in [name for name, _ in self._critical_options]: + raise ValueError("Duplicate critical option name") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options + [(name, value)], + _extensions=self._extensions, + ) + + def add_extension( + self, name: bytes, value: bytes + ) -> SSHCertificateBuilder: + if not isinstance(name, bytes) or not isinstance(value, bytes): + raise TypeError("name and value must be bytes") + # This is O(n**2) + if name in [name for name, _ in self._extensions]: + raise ValueError("Duplicate extension name") + + return SSHCertificateBuilder( + _public_key=self._public_key, + _serial=self._serial, + _type=self._type, + _key_id=self._key_id, + _valid_principals=self._valid_principals, + _valid_for_all_principals=self._valid_for_all_principals, + _valid_before=self._valid_before, + _valid_after=self._valid_after, + _critical_options=self._critical_options, + _extensions=self._extensions + [(name, value)], + ) + + def sign(self, private_key: SSHCertPrivateKeyTypes) -> SSHCertificate: + if not isinstance( + private_key, + ( + ec.EllipticCurvePrivateKey, + rsa.RSAPrivateKey, + ed25519.Ed25519PrivateKey, + ), + ): + raise TypeError("Unsupported private key type") + + if self._public_key is None: + raise ValueError("public_key must be set") + + # Not required + serial = 0 if self._serial is None else self._serial + + if self._type is None: + raise ValueError("type must be set") + + # Not required + key_id = b"" if self._key_id is None else self._key_id + + # A zero length list is valid, but means the certificate + # is valid for any principal of the specified type. We require + # the user to explicitly set valid_for_all_principals to get + # that behavior. + if not self._valid_principals and not self._valid_for_all_principals: + raise ValueError( + "valid_principals must be set if valid_for_all_principals " + "is False" + ) + + if self._valid_before is None: + raise ValueError("valid_before must be set") + + if self._valid_after is None: + raise ValueError("valid_after must be set") + + if self._valid_after > self._valid_before: + raise ValueError("valid_after must be earlier than valid_before") + + # lexically sort our byte strings + self._critical_options.sort(key=lambda x: x[0]) + self._extensions.sort(key=lambda x: x[0]) + + key_type = _get_ssh_key_type(self._public_key) + cert_prefix = key_type + _CERT_SUFFIX + + # Marshal the bytes to be signed + nonce = os.urandom(32) + kformat = _lookup_kformat(key_type) + f = _FragList() + f.put_sshstr(cert_prefix) + f.put_sshstr(nonce) + kformat.encode_public(self._public_key, f) + f.put_u64(serial) + f.put_u32(self._type.value) + f.put_sshstr(key_id) + fprincipals = _FragList() + for p in self._valid_principals: + fprincipals.put_sshstr(p) + f.put_sshstr(fprincipals.tobytes()) + f.put_u64(self._valid_after) + f.put_u64(self._valid_before) + fcrit = _FragList() + for name, value in self._critical_options: + fcrit.put_sshstr(name) + fcrit.put_sshstr(value) + f.put_sshstr(fcrit.tobytes()) + fext = _FragList() + for name, value in self._extensions: + fext.put_sshstr(name) + fext.put_sshstr(value) + f.put_sshstr(fext.tobytes()) + f.put_sshstr(b"") # RESERVED FIELD + # encode CA public key + ca_type = _get_ssh_key_type(private_key) + caformat = _lookup_kformat(ca_type) + caf = _FragList() + caf.put_sshstr(ca_type) + caformat.encode_public(private_key.public_key(), caf) + f.put_sshstr(caf.tobytes()) + # Sigs according to the rules defined for the CA's public key + # (RFC4253 section 6.6 for ssh-rsa, RFC5656 for ECDSA, + # and RFC8032 for Ed25519). + if isinstance(private_key, ed25519.Ed25519PrivateKey): + signature = private_key.sign(f.tobytes()) + fsig = _FragList() + fsig.put_sshstr(ca_type) + fsig.put_sshstr(signature) + f.put_sshstr(fsig.tobytes()) + elif isinstance(private_key, ec.EllipticCurvePrivateKey): + hash_alg = _get_ec_hash_alg(private_key.curve) + signature = private_key.sign(f.tobytes(), ec.ECDSA(hash_alg)) + r, s = asym_utils.decode_dss_signature(signature) + fsig = _FragList() + fsig.put_sshstr(ca_type) + fsigblob = _FragList() + fsigblob.put_mpint(r) + fsigblob.put_mpint(s) + fsig.put_sshstr(fsigblob.tobytes()) + f.put_sshstr(fsig.tobytes()) + + else: + assert isinstance(private_key, rsa.RSAPrivateKey) + # Just like Golang, we're going to use SHA512 for RSA + # https://cs.opensource.google/go/x/crypto/+/refs/tags/ + # v0.4.0:ssh/certs.go;l=445 + # RFC 8332 defines SHA256 and 512 as options + fsig = _FragList() + fsig.put_sshstr(_SSH_RSA_SHA512) + signature = private_key.sign( + f.tobytes(), padding.PKCS1v15(), hashes.SHA512() + ) + fsig.put_sshstr(signature) + f.put_sshstr(fsig.tobytes()) + + cert_data = binascii.b2a_base64(f.tobytes()).strip() + # load_ssh_public_identity returns a union, but this is + # guaranteed to be an SSHCertificate, so we cast to make + # mypy happy. + return typing.cast( + SSHCertificate, + load_ssh_public_identity(b"".join([cert_prefix, b" ", cert_data])), + ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/__init__.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/__init__.py new file mode 100644 index 0000000..c1af423 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/__init__.py @@ -0,0 +1,9 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + + +class InvalidToken(Exception): + pass diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/hotp.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/hotp.py new file mode 100644 index 0000000..2067108 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/hotp.py @@ -0,0 +1,92 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import base64 +import typing +from urllib.parse import quote, urlencode + +from cryptography.hazmat.primitives import constant_time, hmac +from cryptography.hazmat.primitives.hashes import SHA1, SHA256, SHA512 +from cryptography.hazmat.primitives.twofactor import InvalidToken + +HOTPHashTypes = typing.Union[SHA1, SHA256, SHA512] + + +def _generate_uri( + hotp: HOTP, + type_name: str, + account_name: str, + issuer: typing.Optional[str], + extra_parameters: typing.List[typing.Tuple[str, int]], +) -> str: + parameters = [ + ("digits", hotp._length), + ("secret", base64.b32encode(hotp._key)), + ("algorithm", hotp._algorithm.name.upper()), + ] + + if issuer is not None: + parameters.append(("issuer", issuer)) + + parameters.extend(extra_parameters) + + label = ( + f"{quote(issuer)}:{quote(account_name)}" + if issuer + else quote(account_name) + ) + return f"otpauth://{type_name}/{label}?{urlencode(parameters)}" + + +class HOTP: + def __init__( + self, + key: bytes, + length: int, + algorithm: HOTPHashTypes, + backend: typing.Any = None, + enforce_key_length: bool = True, + ) -> None: + if len(key) < 16 and enforce_key_length is True: + raise ValueError("Key length has to be at least 128 bits.") + + if not isinstance(length, int): + raise TypeError("Length parameter must be an integer type.") + + if length < 6 or length > 8: + raise ValueError("Length of HOTP has to be between 6 and 8.") + + if not isinstance(algorithm, (SHA1, SHA256, SHA512)): + raise TypeError("Algorithm must be SHA1, SHA256 or SHA512.") + + self._key = key + self._length = length + self._algorithm = algorithm + + def generate(self, counter: int) -> bytes: + truncated_value = self._dynamic_truncate(counter) + hotp = truncated_value % (10**self._length) + return "{0:0{1}}".format(hotp, self._length).encode() + + def verify(self, hotp: bytes, counter: int) -> None: + if not constant_time.bytes_eq(self.generate(counter), hotp): + raise InvalidToken("Supplied HOTP value does not match.") + + def _dynamic_truncate(self, counter: int) -> int: + ctx = hmac.HMAC(self._key, self._algorithm) + ctx.update(counter.to_bytes(length=8, byteorder="big")) + hmac_value = ctx.finalize() + + offset = hmac_value[len(hmac_value) - 1] & 0b1111 + p = hmac_value[offset : offset + 4] + return int.from_bytes(p, byteorder="big") & 0x7FFFFFFF + + def get_provisioning_uri( + self, account_name: str, counter: int, issuer: typing.Optional[str] + ) -> str: + return _generate_uri( + self, "hotp", account_name, issuer, [("counter", int(counter))] + ) diff --git a/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/totp.py b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/totp.py new file mode 100644 index 0000000..daddcea --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/hazmat/primitives/twofactor/totp.py @@ -0,0 +1,50 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import typing + +from cryptography.hazmat.primitives import constant_time +from cryptography.hazmat.primitives.twofactor import InvalidToken +from cryptography.hazmat.primitives.twofactor.hotp import ( + HOTP, + HOTPHashTypes, + _generate_uri, +) + + +class TOTP: + def __init__( + self, + key: bytes, + length: int, + algorithm: HOTPHashTypes, + time_step: int, + backend: typing.Any = None, + enforce_key_length: bool = True, + ): + self._time_step = time_step + self._hotp = HOTP( + key, length, algorithm, enforce_key_length=enforce_key_length + ) + + def generate(self, time: typing.Union[int, float]) -> bytes: + counter = int(time / self._time_step) + return self._hotp.generate(counter) + + def verify(self, totp: bytes, time: int) -> None: + if not constant_time.bytes_eq(self.generate(time), totp): + raise InvalidToken("Supplied TOTP value does not match.") + + def get_provisioning_uri( + self, account_name: str, issuer: typing.Optional[str] + ) -> str: + return _generate_uri( + self._hotp, + "totp", + account_name, + issuer, + [("period", int(self._time_step))], + ) diff --git a/dist/ba_data/python-site-packages/cryptography/py.typed b/dist/ba_data/python-site-packages/cryptography/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/dist/ba_data/python-site-packages/cryptography/utils.py b/dist/ba_data/python-site-packages/cryptography/utils.py new file mode 100644 index 0000000..7191681 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/utils.py @@ -0,0 +1,130 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import enum +import sys +import types +import typing +import warnings + + +# We use a UserWarning subclass, instead of DeprecationWarning, because CPython +# decided deprecation warnings should be invisble by default. +class CryptographyDeprecationWarning(UserWarning): + pass + + +# Several APIs were deprecated with no specific end-of-life date because of the +# ubiquity of their use. They should not be removed until we agree on when that +# cycle ends. +DeprecatedIn36 = CryptographyDeprecationWarning +DeprecatedIn37 = CryptographyDeprecationWarning +DeprecatedIn40 = CryptographyDeprecationWarning +DeprecatedIn41 = CryptographyDeprecationWarning + + +def _check_bytes(name: str, value: bytes) -> None: + if not isinstance(value, bytes): + raise TypeError(f"{name} must be bytes") + + +def _check_byteslike(name: str, value: bytes) -> None: + try: + memoryview(value) + except TypeError: + raise TypeError(f"{name} must be bytes-like") + + +def int_to_bytes(integer: int, length: typing.Optional[int] = None) -> bytes: + return integer.to_bytes( + length or (integer.bit_length() + 7) // 8 or 1, "big" + ) + + +def _extract_buffer_length(obj: typing.Any) -> typing.Tuple[typing.Any, int]: + from cryptography.hazmat.bindings._rust import _openssl + + buf = _openssl.ffi.from_buffer(obj) + return buf, int(_openssl.ffi.cast("uintptr_t", buf)) + + +class InterfaceNotImplemented(Exception): + pass + + +class _DeprecatedValue: + def __init__(self, value: object, message: str, warning_class): + self.value = value + self.message = message + self.warning_class = warning_class + + +class _ModuleWithDeprecations(types.ModuleType): + def __init__(self, module: types.ModuleType): + super().__init__(module.__name__) + self.__dict__["_module"] = module + + def __getattr__(self, attr: str) -> object: + obj = getattr(self._module, attr) + if isinstance(obj, _DeprecatedValue): + warnings.warn(obj.message, obj.warning_class, stacklevel=2) + obj = obj.value + return obj + + def __setattr__(self, attr: str, value: object) -> None: + setattr(self._module, attr, value) + + def __delattr__(self, attr: str) -> None: + obj = getattr(self._module, attr) + if isinstance(obj, _DeprecatedValue): + warnings.warn(obj.message, obj.warning_class, stacklevel=2) + + delattr(self._module, attr) + + def __dir__(self) -> typing.Sequence[str]: + return ["_module"] + dir(self._module) + + +def deprecated( + value: object, + module_name: str, + message: str, + warning_class: typing.Type[Warning], + name: typing.Optional[str] = None, +) -> _DeprecatedValue: + module = sys.modules[module_name] + if not isinstance(module, _ModuleWithDeprecations): + sys.modules[module_name] = module = _ModuleWithDeprecations(module) + dv = _DeprecatedValue(value, message, warning_class) + # Maintain backwards compatibility with `name is None` for pyOpenSSL. + if name is not None: + setattr(module, name, dv) + return dv + + +def cached_property(func: typing.Callable) -> property: + cached_name = f"_cached_{func}" + sentinel = object() + + def inner(instance: object): + cache = getattr(instance, cached_name, sentinel) + if cache is not sentinel: + return cache + result = func(instance) + setattr(instance, cached_name, result) + return result + + return property(inner) + + +# Python 3.10 changed representation of enums. We use well-defined object +# representation and string representation from Python 3.9. +class Enum(enum.Enum): + def __repr__(self) -> str: + return f"<{self.__class__.__name__}.{self._name_}: {self._value_!r}>" + + def __str__(self) -> str: + return f"{self.__class__.__name__}.{self._name_}" diff --git a/dist/ba_data/python-site-packages/cryptography/x509/__init__.py b/dist/ba_data/python-site-packages/cryptography/x509/__init__.py new file mode 100644 index 0000000..d77694a --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/x509/__init__.py @@ -0,0 +1,255 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography.x509 import certificate_transparency +from cryptography.x509.base import ( + Attribute, + AttributeNotFound, + Attributes, + Certificate, + CertificateBuilder, + CertificateRevocationList, + CertificateRevocationListBuilder, + CertificateSigningRequest, + CertificateSigningRequestBuilder, + InvalidVersion, + RevokedCertificate, + RevokedCertificateBuilder, + Version, + load_der_x509_certificate, + load_der_x509_crl, + load_der_x509_csr, + load_pem_x509_certificate, + load_pem_x509_certificates, + load_pem_x509_crl, + load_pem_x509_csr, + random_serial_number, +) +from cryptography.x509.extensions import ( + AccessDescription, + AuthorityInformationAccess, + AuthorityKeyIdentifier, + BasicConstraints, + CertificateIssuer, + CertificatePolicies, + CRLDistributionPoints, + CRLNumber, + CRLReason, + DeltaCRLIndicator, + DistributionPoint, + DuplicateExtension, + ExtendedKeyUsage, + Extension, + ExtensionNotFound, + Extensions, + ExtensionType, + FreshestCRL, + GeneralNames, + InhibitAnyPolicy, + InvalidityDate, + IssuerAlternativeName, + IssuingDistributionPoint, + KeyUsage, + MSCertificateTemplate, + NameConstraints, + NoticeReference, + OCSPAcceptableResponses, + OCSPNoCheck, + OCSPNonce, + PolicyConstraints, + PolicyInformation, + PrecertificateSignedCertificateTimestamps, + PrecertPoison, + ReasonFlags, + SignedCertificateTimestamps, + SubjectAlternativeName, + SubjectInformationAccess, + SubjectKeyIdentifier, + TLSFeature, + TLSFeatureType, + UnrecognizedExtension, + UserNotice, +) +from cryptography.x509.general_name import ( + DirectoryName, + DNSName, + GeneralName, + IPAddress, + OtherName, + RegisteredID, + RFC822Name, + UniformResourceIdentifier, + UnsupportedGeneralNameType, +) +from cryptography.x509.name import ( + Name, + NameAttribute, + RelativeDistinguishedName, +) +from cryptography.x509.oid import ( + AuthorityInformationAccessOID, + CertificatePoliciesOID, + CRLEntryExtensionOID, + ExtendedKeyUsageOID, + ExtensionOID, + NameOID, + ObjectIdentifier, + SignatureAlgorithmOID, +) + +OID_AUTHORITY_INFORMATION_ACCESS = ExtensionOID.AUTHORITY_INFORMATION_ACCESS +OID_AUTHORITY_KEY_IDENTIFIER = ExtensionOID.AUTHORITY_KEY_IDENTIFIER +OID_BASIC_CONSTRAINTS = ExtensionOID.BASIC_CONSTRAINTS +OID_CERTIFICATE_POLICIES = ExtensionOID.CERTIFICATE_POLICIES +OID_CRL_DISTRIBUTION_POINTS = ExtensionOID.CRL_DISTRIBUTION_POINTS +OID_EXTENDED_KEY_USAGE = ExtensionOID.EXTENDED_KEY_USAGE +OID_FRESHEST_CRL = ExtensionOID.FRESHEST_CRL +OID_INHIBIT_ANY_POLICY = ExtensionOID.INHIBIT_ANY_POLICY +OID_ISSUER_ALTERNATIVE_NAME = ExtensionOID.ISSUER_ALTERNATIVE_NAME +OID_KEY_USAGE = ExtensionOID.KEY_USAGE +OID_NAME_CONSTRAINTS = ExtensionOID.NAME_CONSTRAINTS +OID_OCSP_NO_CHECK = ExtensionOID.OCSP_NO_CHECK +OID_POLICY_CONSTRAINTS = ExtensionOID.POLICY_CONSTRAINTS +OID_POLICY_MAPPINGS = ExtensionOID.POLICY_MAPPINGS +OID_SUBJECT_ALTERNATIVE_NAME = ExtensionOID.SUBJECT_ALTERNATIVE_NAME +OID_SUBJECT_DIRECTORY_ATTRIBUTES = ExtensionOID.SUBJECT_DIRECTORY_ATTRIBUTES +OID_SUBJECT_INFORMATION_ACCESS = ExtensionOID.SUBJECT_INFORMATION_ACCESS +OID_SUBJECT_KEY_IDENTIFIER = ExtensionOID.SUBJECT_KEY_IDENTIFIER + +OID_DSA_WITH_SHA1 = SignatureAlgorithmOID.DSA_WITH_SHA1 +OID_DSA_WITH_SHA224 = SignatureAlgorithmOID.DSA_WITH_SHA224 +OID_DSA_WITH_SHA256 = SignatureAlgorithmOID.DSA_WITH_SHA256 +OID_ECDSA_WITH_SHA1 = SignatureAlgorithmOID.ECDSA_WITH_SHA1 +OID_ECDSA_WITH_SHA224 = SignatureAlgorithmOID.ECDSA_WITH_SHA224 +OID_ECDSA_WITH_SHA256 = SignatureAlgorithmOID.ECDSA_WITH_SHA256 +OID_ECDSA_WITH_SHA384 = SignatureAlgorithmOID.ECDSA_WITH_SHA384 +OID_ECDSA_WITH_SHA512 = SignatureAlgorithmOID.ECDSA_WITH_SHA512 +OID_RSA_WITH_MD5 = SignatureAlgorithmOID.RSA_WITH_MD5 +OID_RSA_WITH_SHA1 = SignatureAlgorithmOID.RSA_WITH_SHA1 +OID_RSA_WITH_SHA224 = SignatureAlgorithmOID.RSA_WITH_SHA224 +OID_RSA_WITH_SHA256 = SignatureAlgorithmOID.RSA_WITH_SHA256 +OID_RSA_WITH_SHA384 = SignatureAlgorithmOID.RSA_WITH_SHA384 +OID_RSA_WITH_SHA512 = SignatureAlgorithmOID.RSA_WITH_SHA512 +OID_RSASSA_PSS = SignatureAlgorithmOID.RSASSA_PSS + +OID_COMMON_NAME = NameOID.COMMON_NAME +OID_COUNTRY_NAME = NameOID.COUNTRY_NAME +OID_DOMAIN_COMPONENT = NameOID.DOMAIN_COMPONENT +OID_DN_QUALIFIER = NameOID.DN_QUALIFIER +OID_EMAIL_ADDRESS = NameOID.EMAIL_ADDRESS +OID_GENERATION_QUALIFIER = NameOID.GENERATION_QUALIFIER +OID_GIVEN_NAME = NameOID.GIVEN_NAME +OID_LOCALITY_NAME = NameOID.LOCALITY_NAME +OID_ORGANIZATIONAL_UNIT_NAME = NameOID.ORGANIZATIONAL_UNIT_NAME +OID_ORGANIZATION_NAME = NameOID.ORGANIZATION_NAME +OID_PSEUDONYM = NameOID.PSEUDONYM +OID_SERIAL_NUMBER = NameOID.SERIAL_NUMBER +OID_STATE_OR_PROVINCE_NAME = NameOID.STATE_OR_PROVINCE_NAME +OID_SURNAME = NameOID.SURNAME +OID_TITLE = NameOID.TITLE + +OID_CLIENT_AUTH = ExtendedKeyUsageOID.CLIENT_AUTH +OID_CODE_SIGNING = ExtendedKeyUsageOID.CODE_SIGNING +OID_EMAIL_PROTECTION = ExtendedKeyUsageOID.EMAIL_PROTECTION +OID_OCSP_SIGNING = ExtendedKeyUsageOID.OCSP_SIGNING +OID_SERVER_AUTH = ExtendedKeyUsageOID.SERVER_AUTH +OID_TIME_STAMPING = ExtendedKeyUsageOID.TIME_STAMPING + +OID_ANY_POLICY = CertificatePoliciesOID.ANY_POLICY +OID_CPS_QUALIFIER = CertificatePoliciesOID.CPS_QUALIFIER +OID_CPS_USER_NOTICE = CertificatePoliciesOID.CPS_USER_NOTICE + +OID_CERTIFICATE_ISSUER = CRLEntryExtensionOID.CERTIFICATE_ISSUER +OID_CRL_REASON = CRLEntryExtensionOID.CRL_REASON +OID_INVALIDITY_DATE = CRLEntryExtensionOID.INVALIDITY_DATE + +OID_CA_ISSUERS = AuthorityInformationAccessOID.CA_ISSUERS +OID_OCSP = AuthorityInformationAccessOID.OCSP + +__all__ = [ + "certificate_transparency", + "load_pem_x509_certificate", + "load_pem_x509_certificates", + "load_der_x509_certificate", + "load_pem_x509_csr", + "load_der_x509_csr", + "load_pem_x509_crl", + "load_der_x509_crl", + "random_serial_number", + "Attribute", + "AttributeNotFound", + "Attributes", + "InvalidVersion", + "DeltaCRLIndicator", + "DuplicateExtension", + "ExtensionNotFound", + "UnsupportedGeneralNameType", + "NameAttribute", + "Name", + "RelativeDistinguishedName", + "ObjectIdentifier", + "ExtensionType", + "Extensions", + "Extension", + "ExtendedKeyUsage", + "FreshestCRL", + "IssuingDistributionPoint", + "TLSFeature", + "TLSFeatureType", + "OCSPAcceptableResponses", + "OCSPNoCheck", + "BasicConstraints", + "CRLNumber", + "KeyUsage", + "AuthorityInformationAccess", + "SubjectInformationAccess", + "AccessDescription", + "CertificatePolicies", + "PolicyInformation", + "UserNotice", + "NoticeReference", + "SubjectKeyIdentifier", + "NameConstraints", + "CRLDistributionPoints", + "DistributionPoint", + "ReasonFlags", + "InhibitAnyPolicy", + "SubjectAlternativeName", + "IssuerAlternativeName", + "AuthorityKeyIdentifier", + "GeneralNames", + "GeneralName", + "RFC822Name", + "DNSName", + "UniformResourceIdentifier", + "RegisteredID", + "DirectoryName", + "IPAddress", + "OtherName", + "Certificate", + "CertificateRevocationList", + "CertificateRevocationListBuilder", + "CertificateSigningRequest", + "RevokedCertificate", + "RevokedCertificateBuilder", + "CertificateSigningRequestBuilder", + "CertificateBuilder", + "Version", + "OID_CA_ISSUERS", + "OID_OCSP", + "CertificateIssuer", + "CRLReason", + "InvalidityDate", + "UnrecognizedExtension", + "PolicyConstraints", + "PrecertificateSignedCertificateTimestamps", + "PrecertPoison", + "OCSPNonce", + "SignedCertificateTimestamps", + "SignatureAlgorithmOID", + "NameOID", + "MSCertificateTemplate", +] diff --git a/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8778bda Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/base.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/base.cpython-310.opt-1.pyc new file mode 100644 index 0000000..bc968c3 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/base.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/certificate_transparency.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/certificate_transparency.cpython-310.opt-1.pyc new file mode 100644 index 0000000..4a59a78 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/certificate_transparency.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/extensions.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/extensions.cpython-310.opt-1.pyc new file mode 100644 index 0000000..cd53dfa Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/extensions.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/general_name.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/general_name.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8a5d170 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/general_name.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/name.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/name.cpython-310.opt-1.pyc new file mode 100644 index 0000000..4eac49a Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/name.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/oid.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/oid.cpython-310.opt-1.pyc new file mode 100644 index 0000000..415a6d4 Binary files /dev/null and b/dist/ba_data/python-site-packages/cryptography/x509/__pycache__/oid.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/cryptography/x509/base.py b/dist/ba_data/python-site-packages/cryptography/x509/base.py new file mode 100644 index 0000000..576385e --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/x509/base.py @@ -0,0 +1,1173 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import datetime +import os +import typing + +from cryptography import utils +from cryptography.hazmat.bindings._rust import x509 as rust_x509 +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import ( + dsa, + ec, + ed448, + ed25519, + padding, + rsa, + x448, + x25519, +) +from cryptography.hazmat.primitives.asymmetric.types import ( + CertificateIssuerPrivateKeyTypes, + CertificateIssuerPublicKeyTypes, + CertificatePublicKeyTypes, +) +from cryptography.x509.extensions import ( + Extension, + Extensions, + ExtensionType, + _make_sequence_methods, +) +from cryptography.x509.name import Name, _ASN1Type +from cryptography.x509.oid import ObjectIdentifier + +_EARLIEST_UTC_TIME = datetime.datetime(1950, 1, 1) + +# This must be kept in sync with sign.rs's list of allowable types in +# identify_hash_type +_AllowedHashTypes = typing.Union[ + hashes.SHA224, + hashes.SHA256, + hashes.SHA384, + hashes.SHA512, + hashes.SHA3_224, + hashes.SHA3_256, + hashes.SHA3_384, + hashes.SHA3_512, +] + + +class AttributeNotFound(Exception): + def __init__(self, msg: str, oid: ObjectIdentifier) -> None: + super().__init__(msg) + self.oid = oid + + +def _reject_duplicate_extension( + extension: Extension[ExtensionType], + extensions: typing.List[Extension[ExtensionType]], +) -> None: + # This is quadratic in the number of extensions + for e in extensions: + if e.oid == extension.oid: + raise ValueError("This extension has already been set.") + + +def _reject_duplicate_attribute( + oid: ObjectIdentifier, + attributes: typing.List[ + typing.Tuple[ObjectIdentifier, bytes, typing.Optional[int]] + ], +) -> None: + # This is quadratic in the number of attributes + for attr_oid, _, _ in attributes: + if attr_oid == oid: + raise ValueError("This attribute has already been set.") + + +def _convert_to_naive_utc_time(time: datetime.datetime) -> datetime.datetime: + """Normalizes a datetime to a naive datetime in UTC. + + time -- datetime to normalize. Assumed to be in UTC if not timezone + aware. + """ + if time.tzinfo is not None: + offset = time.utcoffset() + offset = offset if offset else datetime.timedelta() + return time.replace(tzinfo=None) - offset + else: + return time + + +class Attribute: + def __init__( + self, + oid: ObjectIdentifier, + value: bytes, + _type: int = _ASN1Type.UTF8String.value, + ) -> None: + self._oid = oid + self._value = value + self._type = _type + + @property + def oid(self) -> ObjectIdentifier: + return self._oid + + @property + def value(self) -> bytes: + return self._value + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Attribute): + return NotImplemented + + return ( + self.oid == other.oid + and self.value == other.value + and self._type == other._type + ) + + def __hash__(self) -> int: + return hash((self.oid, self.value, self._type)) + + +class Attributes: + def __init__( + self, + attributes: typing.Iterable[Attribute], + ) -> None: + self._attributes = list(attributes) + + __len__, __iter__, __getitem__ = _make_sequence_methods("_attributes") + + def __repr__(self) -> str: + return f"" + + def get_attribute_for_oid(self, oid: ObjectIdentifier) -> Attribute: + for attr in self: + if attr.oid == oid: + return attr + + raise AttributeNotFound(f"No {oid} attribute was found", oid) + + +class Version(utils.Enum): + v1 = 0 + v3 = 2 + + +class InvalidVersion(Exception): + def __init__(self, msg: str, parsed_version: int) -> None: + super().__init__(msg) + self.parsed_version = parsed_version + + +class Certificate(metaclass=abc.ABCMeta): + @abc.abstractmethod + def fingerprint(self, algorithm: hashes.HashAlgorithm) -> bytes: + """ + Returns bytes using digest passed. + """ + + @property + @abc.abstractmethod + def serial_number(self) -> int: + """ + Returns certificate serial number + """ + + @property + @abc.abstractmethod + def version(self) -> Version: + """ + Returns the certificate version + """ + + @abc.abstractmethod + def public_key(self) -> CertificatePublicKeyTypes: + """ + Returns the public key + """ + + @property + @abc.abstractmethod + def not_valid_before(self) -> datetime.datetime: + """ + Not before time (represented as UTC datetime) + """ + + @property + @abc.abstractmethod + def not_valid_after(self) -> datetime.datetime: + """ + Not after time (represented as UTC datetime) + """ + + @property + @abc.abstractmethod + def issuer(self) -> Name: + """ + Returns the issuer name object. + """ + + @property + @abc.abstractmethod + def subject(self) -> Name: + """ + Returns the subject name object. + """ + + @property + @abc.abstractmethod + def signature_hash_algorithm( + self, + ) -> typing.Optional[hashes.HashAlgorithm]: + """ + Returns a HashAlgorithm corresponding to the type of the digest signed + in the certificate. + """ + + @property + @abc.abstractmethod + def signature_algorithm_oid(self) -> ObjectIdentifier: + """ + Returns the ObjectIdentifier of the signature algorithm. + """ + + @property + @abc.abstractmethod + def signature_algorithm_parameters( + self, + ) -> typing.Union[None, padding.PSS, padding.PKCS1v15, ec.ECDSA]: + """ + Returns the signature algorithm parameters. + """ + + @property + @abc.abstractmethod + def extensions(self) -> Extensions: + """ + Returns an Extensions object. + """ + + @property + @abc.abstractmethod + def signature(self) -> bytes: + """ + Returns the signature bytes. + """ + + @property + @abc.abstractmethod + def tbs_certificate_bytes(self) -> bytes: + """ + Returns the tbsCertificate payload bytes as defined in RFC 5280. + """ + + @property + @abc.abstractmethod + def tbs_precertificate_bytes(self) -> bytes: + """ + Returns the tbsCertificate payload bytes with the SCT list extension + stripped. + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + @abc.abstractmethod + def __hash__(self) -> int: + """ + Computes a hash. + """ + + @abc.abstractmethod + def public_bytes(self, encoding: serialization.Encoding) -> bytes: + """ + Serializes the certificate to PEM or DER format. + """ + + @abc.abstractmethod + def verify_directly_issued_by(self, issuer: Certificate) -> None: + """ + This method verifies that certificate issuer name matches the + issuer subject name and that the certificate is signed by the + issuer's private key. No other validation is performed. + """ + + +# Runtime isinstance checks need this since the rust class is not a subclass. +Certificate.register(rust_x509.Certificate) + + +class RevokedCertificate(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def serial_number(self) -> int: + """ + Returns the serial number of the revoked certificate. + """ + + @property + @abc.abstractmethod + def revocation_date(self) -> datetime.datetime: + """ + Returns the date of when this certificate was revoked. + """ + + @property + @abc.abstractmethod + def extensions(self) -> Extensions: + """ + Returns an Extensions object containing a list of Revoked extensions. + """ + + +# Runtime isinstance checks need this since the rust class is not a subclass. +RevokedCertificate.register(rust_x509.RevokedCertificate) + + +class _RawRevokedCertificate(RevokedCertificate): + def __init__( + self, + serial_number: int, + revocation_date: datetime.datetime, + extensions: Extensions, + ): + self._serial_number = serial_number + self._revocation_date = revocation_date + self._extensions = extensions + + @property + def serial_number(self) -> int: + return self._serial_number + + @property + def revocation_date(self) -> datetime.datetime: + return self._revocation_date + + @property + def extensions(self) -> Extensions: + return self._extensions + + +class CertificateRevocationList(metaclass=abc.ABCMeta): + @abc.abstractmethod + def public_bytes(self, encoding: serialization.Encoding) -> bytes: + """ + Serializes the CRL to PEM or DER format. + """ + + @abc.abstractmethod + def fingerprint(self, algorithm: hashes.HashAlgorithm) -> bytes: + """ + Returns bytes using digest passed. + """ + + @abc.abstractmethod + def get_revoked_certificate_by_serial_number( + self, serial_number: int + ) -> typing.Optional[RevokedCertificate]: + """ + Returns an instance of RevokedCertificate or None if the serial_number + is not in the CRL. + """ + + @property + @abc.abstractmethod + def signature_hash_algorithm( + self, + ) -> typing.Optional[hashes.HashAlgorithm]: + """ + Returns a HashAlgorithm corresponding to the type of the digest signed + in the certificate. + """ + + @property + @abc.abstractmethod + def signature_algorithm_oid(self) -> ObjectIdentifier: + """ + Returns the ObjectIdentifier of the signature algorithm. + """ + + @property + @abc.abstractmethod + def issuer(self) -> Name: + """ + Returns the X509Name with the issuer of this CRL. + """ + + @property + @abc.abstractmethod + def next_update(self) -> typing.Optional[datetime.datetime]: + """ + Returns the date of next update for this CRL. + """ + + @property + @abc.abstractmethod + def last_update(self) -> datetime.datetime: + """ + Returns the date of last update for this CRL. + """ + + @property + @abc.abstractmethod + def extensions(self) -> Extensions: + """ + Returns an Extensions object containing a list of CRL extensions. + """ + + @property + @abc.abstractmethod + def signature(self) -> bytes: + """ + Returns the signature bytes. + """ + + @property + @abc.abstractmethod + def tbs_certlist_bytes(self) -> bytes: + """ + Returns the tbsCertList payload bytes as defined in RFC 5280. + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + @abc.abstractmethod + def __len__(self) -> int: + """ + Number of revoked certificates in the CRL. + """ + + @typing.overload + def __getitem__(self, idx: int) -> RevokedCertificate: + ... + + @typing.overload + def __getitem__(self, idx: slice) -> typing.List[RevokedCertificate]: + ... + + @abc.abstractmethod + def __getitem__( + self, idx: typing.Union[int, slice] + ) -> typing.Union[RevokedCertificate, typing.List[RevokedCertificate]]: + """ + Returns a revoked certificate (or slice of revoked certificates). + """ + + @abc.abstractmethod + def __iter__(self) -> typing.Iterator[RevokedCertificate]: + """ + Iterator over the revoked certificates + """ + + @abc.abstractmethod + def is_signature_valid( + self, public_key: CertificateIssuerPublicKeyTypes + ) -> bool: + """ + Verifies signature of revocation list against given public key. + """ + + +CertificateRevocationList.register(rust_x509.CertificateRevocationList) + + +class CertificateSigningRequest(metaclass=abc.ABCMeta): + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Checks equality. + """ + + @abc.abstractmethod + def __hash__(self) -> int: + """ + Computes a hash. + """ + + @abc.abstractmethod + def public_key(self) -> CertificatePublicKeyTypes: + """ + Returns the public key + """ + + @property + @abc.abstractmethod + def subject(self) -> Name: + """ + Returns the subject name object. + """ + + @property + @abc.abstractmethod + def signature_hash_algorithm( + self, + ) -> typing.Optional[hashes.HashAlgorithm]: + """ + Returns a HashAlgorithm corresponding to the type of the digest signed + in the certificate. + """ + + @property + @abc.abstractmethod + def signature_algorithm_oid(self) -> ObjectIdentifier: + """ + Returns the ObjectIdentifier of the signature algorithm. + """ + + @property + @abc.abstractmethod + def extensions(self) -> Extensions: + """ + Returns the extensions in the signing request. + """ + + @property + @abc.abstractmethod + def attributes(self) -> Attributes: + """ + Returns an Attributes object. + """ + + @abc.abstractmethod + def public_bytes(self, encoding: serialization.Encoding) -> bytes: + """ + Encodes the request to PEM or DER format. + """ + + @property + @abc.abstractmethod + def signature(self) -> bytes: + """ + Returns the signature bytes. + """ + + @property + @abc.abstractmethod + def tbs_certrequest_bytes(self) -> bytes: + """ + Returns the PKCS#10 CertificationRequestInfo bytes as defined in RFC + 2986. + """ + + @property + @abc.abstractmethod + def is_signature_valid(self) -> bool: + """ + Verifies signature of signing request. + """ + + @abc.abstractmethod + def get_attribute_for_oid(self, oid: ObjectIdentifier) -> bytes: + """ + Get the attribute value for a given OID. + """ + + +# Runtime isinstance checks need this since the rust class is not a subclass. +CertificateSigningRequest.register(rust_x509.CertificateSigningRequest) + + +# Backend argument preserved for API compatibility, but ignored. +def load_pem_x509_certificate( + data: bytes, backend: typing.Any = None +) -> Certificate: + return rust_x509.load_pem_x509_certificate(data) + + +def load_pem_x509_certificates(data: bytes) -> typing.List[Certificate]: + return rust_x509.load_pem_x509_certificates(data) + + +# Backend argument preserved for API compatibility, but ignored. +def load_der_x509_certificate( + data: bytes, backend: typing.Any = None +) -> Certificate: + return rust_x509.load_der_x509_certificate(data) + + +# Backend argument preserved for API compatibility, but ignored. +def load_pem_x509_csr( + data: bytes, backend: typing.Any = None +) -> CertificateSigningRequest: + return rust_x509.load_pem_x509_csr(data) + + +# Backend argument preserved for API compatibility, but ignored. +def load_der_x509_csr( + data: bytes, backend: typing.Any = None +) -> CertificateSigningRequest: + return rust_x509.load_der_x509_csr(data) + + +# Backend argument preserved for API compatibility, but ignored. +def load_pem_x509_crl( + data: bytes, backend: typing.Any = None +) -> CertificateRevocationList: + return rust_x509.load_pem_x509_crl(data) + + +# Backend argument preserved for API compatibility, but ignored. +def load_der_x509_crl( + data: bytes, backend: typing.Any = None +) -> CertificateRevocationList: + return rust_x509.load_der_x509_crl(data) + + +class CertificateSigningRequestBuilder: + def __init__( + self, + subject_name: typing.Optional[Name] = None, + extensions: typing.List[Extension[ExtensionType]] = [], + attributes: typing.List[ + typing.Tuple[ObjectIdentifier, bytes, typing.Optional[int]] + ] = [], + ): + """ + Creates an empty X.509 certificate request (v1). + """ + self._subject_name = subject_name + self._extensions = extensions + self._attributes = attributes + + def subject_name(self, name: Name) -> CertificateSigningRequestBuilder: + """ + Sets the certificate requestor's distinguished name. + """ + if not isinstance(name, Name): + raise TypeError("Expecting x509.Name object.") + if self._subject_name is not None: + raise ValueError("The subject name may only be set once.") + return CertificateSigningRequestBuilder( + name, self._extensions, self._attributes + ) + + def add_extension( + self, extval: ExtensionType, critical: bool + ) -> CertificateSigningRequestBuilder: + """ + Adds an X.509 extension to the certificate request. + """ + if not isinstance(extval, ExtensionType): + raise TypeError("extension must be an ExtensionType") + + extension = Extension(extval.oid, critical, extval) + _reject_duplicate_extension(extension, self._extensions) + + return CertificateSigningRequestBuilder( + self._subject_name, + self._extensions + [extension], + self._attributes, + ) + + def add_attribute( + self, + oid: ObjectIdentifier, + value: bytes, + *, + _tag: typing.Optional[_ASN1Type] = None, + ) -> CertificateSigningRequestBuilder: + """ + Adds an X.509 attribute with an OID and associated value. + """ + if not isinstance(oid, ObjectIdentifier): + raise TypeError("oid must be an ObjectIdentifier") + + if not isinstance(value, bytes): + raise TypeError("value must be bytes") + + if _tag is not None and not isinstance(_tag, _ASN1Type): + raise TypeError("tag must be _ASN1Type") + + _reject_duplicate_attribute(oid, self._attributes) + + if _tag is not None: + tag = _tag.value + else: + tag = None + + return CertificateSigningRequestBuilder( + self._subject_name, + self._extensions, + self._attributes + [(oid, value, tag)], + ) + + def sign( + self, + private_key: CertificateIssuerPrivateKeyTypes, + algorithm: typing.Optional[_AllowedHashTypes], + backend: typing.Any = None, + ) -> CertificateSigningRequest: + """ + Signs the request using the requestor's private key. + """ + if self._subject_name is None: + raise ValueError("A CertificateSigningRequest must have a subject") + return rust_x509.create_x509_csr(self, private_key, algorithm) + + +class CertificateBuilder: + _extensions: typing.List[Extension[ExtensionType]] + + def __init__( + self, + issuer_name: typing.Optional[Name] = None, + subject_name: typing.Optional[Name] = None, + public_key: typing.Optional[CertificatePublicKeyTypes] = None, + serial_number: typing.Optional[int] = None, + not_valid_before: typing.Optional[datetime.datetime] = None, + not_valid_after: typing.Optional[datetime.datetime] = None, + extensions: typing.List[Extension[ExtensionType]] = [], + ) -> None: + self._version = Version.v3 + self._issuer_name = issuer_name + self._subject_name = subject_name + self._public_key = public_key + self._serial_number = serial_number + self._not_valid_before = not_valid_before + self._not_valid_after = not_valid_after + self._extensions = extensions + + def issuer_name(self, name: Name) -> CertificateBuilder: + """ + Sets the CA's distinguished name. + """ + if not isinstance(name, Name): + raise TypeError("Expecting x509.Name object.") + if self._issuer_name is not None: + raise ValueError("The issuer name may only be set once.") + return CertificateBuilder( + name, + self._subject_name, + self._public_key, + self._serial_number, + self._not_valid_before, + self._not_valid_after, + self._extensions, + ) + + def subject_name(self, name: Name) -> CertificateBuilder: + """ + Sets the requestor's distinguished name. + """ + if not isinstance(name, Name): + raise TypeError("Expecting x509.Name object.") + if self._subject_name is not None: + raise ValueError("The subject name may only be set once.") + return CertificateBuilder( + self._issuer_name, + name, + self._public_key, + self._serial_number, + self._not_valid_before, + self._not_valid_after, + self._extensions, + ) + + def public_key( + self, + key: CertificatePublicKeyTypes, + ) -> CertificateBuilder: + """ + Sets the requestor's public key (as found in the signing request). + """ + if not isinstance( + key, + ( + dsa.DSAPublicKey, + rsa.RSAPublicKey, + ec.EllipticCurvePublicKey, + ed25519.Ed25519PublicKey, + ed448.Ed448PublicKey, + x25519.X25519PublicKey, + x448.X448PublicKey, + ), + ): + raise TypeError( + "Expecting one of DSAPublicKey, RSAPublicKey," + " EllipticCurvePublicKey, Ed25519PublicKey," + " Ed448PublicKey, X25519PublicKey, or " + "X448PublicKey." + ) + if self._public_key is not None: + raise ValueError("The public key may only be set once.") + return CertificateBuilder( + self._issuer_name, + self._subject_name, + key, + self._serial_number, + self._not_valid_before, + self._not_valid_after, + self._extensions, + ) + + def serial_number(self, number: int) -> CertificateBuilder: + """ + Sets the certificate serial number. + """ + if not isinstance(number, int): + raise TypeError("Serial number must be of integral type.") + if self._serial_number is not None: + raise ValueError("The serial number may only be set once.") + if number <= 0: + raise ValueError("The serial number should be positive.") + + # ASN.1 integers are always signed, so most significant bit must be + # zero. + if number.bit_length() >= 160: # As defined in RFC 5280 + raise ValueError( + "The serial number should not be more than 159 " "bits." + ) + return CertificateBuilder( + self._issuer_name, + self._subject_name, + self._public_key, + number, + self._not_valid_before, + self._not_valid_after, + self._extensions, + ) + + def not_valid_before(self, time: datetime.datetime) -> CertificateBuilder: + """ + Sets the certificate activation time. + """ + if not isinstance(time, datetime.datetime): + raise TypeError("Expecting datetime object.") + if self._not_valid_before is not None: + raise ValueError("The not valid before may only be set once.") + time = _convert_to_naive_utc_time(time) + if time < _EARLIEST_UTC_TIME: + raise ValueError( + "The not valid before date must be on or after" + " 1950 January 1)." + ) + if self._not_valid_after is not None and time > self._not_valid_after: + raise ValueError( + "The not valid before date must be before the not valid after " + "date." + ) + return CertificateBuilder( + self._issuer_name, + self._subject_name, + self._public_key, + self._serial_number, + time, + self._not_valid_after, + self._extensions, + ) + + def not_valid_after(self, time: datetime.datetime) -> CertificateBuilder: + """ + Sets the certificate expiration time. + """ + if not isinstance(time, datetime.datetime): + raise TypeError("Expecting datetime object.") + if self._not_valid_after is not None: + raise ValueError("The not valid after may only be set once.") + time = _convert_to_naive_utc_time(time) + if time < _EARLIEST_UTC_TIME: + raise ValueError( + "The not valid after date must be on or after" + " 1950 January 1." + ) + if ( + self._not_valid_before is not None + and time < self._not_valid_before + ): + raise ValueError( + "The not valid after date must be after the not valid before " + "date." + ) + return CertificateBuilder( + self._issuer_name, + self._subject_name, + self._public_key, + self._serial_number, + self._not_valid_before, + time, + self._extensions, + ) + + def add_extension( + self, extval: ExtensionType, critical: bool + ) -> CertificateBuilder: + """ + Adds an X.509 extension to the certificate. + """ + if not isinstance(extval, ExtensionType): + raise TypeError("extension must be an ExtensionType") + + extension = Extension(extval.oid, critical, extval) + _reject_duplicate_extension(extension, self._extensions) + + return CertificateBuilder( + self._issuer_name, + self._subject_name, + self._public_key, + self._serial_number, + self._not_valid_before, + self._not_valid_after, + self._extensions + [extension], + ) + + def sign( + self, + private_key: CertificateIssuerPrivateKeyTypes, + algorithm: typing.Optional[_AllowedHashTypes], + backend: typing.Any = None, + *, + rsa_padding: typing.Optional[ + typing.Union[padding.PSS, padding.PKCS1v15] + ] = None, + ) -> Certificate: + """ + Signs the certificate using the CA's private key. + """ + if self._subject_name is None: + raise ValueError("A certificate must have a subject name") + + if self._issuer_name is None: + raise ValueError("A certificate must have an issuer name") + + if self._serial_number is None: + raise ValueError("A certificate must have a serial number") + + if self._not_valid_before is None: + raise ValueError("A certificate must have a not valid before time") + + if self._not_valid_after is None: + raise ValueError("A certificate must have a not valid after time") + + if self._public_key is None: + raise ValueError("A certificate must have a public key") + + if rsa_padding is not None: + if not isinstance(rsa_padding, (padding.PSS, padding.PKCS1v15)): + raise TypeError("Padding must be PSS or PKCS1v15") + if not isinstance(private_key, rsa.RSAPrivateKey): + raise TypeError("Padding is only supported for RSA keys") + + return rust_x509.create_x509_certificate( + self, private_key, algorithm, rsa_padding + ) + + +class CertificateRevocationListBuilder: + _extensions: typing.List[Extension[ExtensionType]] + _revoked_certificates: typing.List[RevokedCertificate] + + def __init__( + self, + issuer_name: typing.Optional[Name] = None, + last_update: typing.Optional[datetime.datetime] = None, + next_update: typing.Optional[datetime.datetime] = None, + extensions: typing.List[Extension[ExtensionType]] = [], + revoked_certificates: typing.List[RevokedCertificate] = [], + ): + self._issuer_name = issuer_name + self._last_update = last_update + self._next_update = next_update + self._extensions = extensions + self._revoked_certificates = revoked_certificates + + def issuer_name( + self, issuer_name: Name + ) -> CertificateRevocationListBuilder: + if not isinstance(issuer_name, Name): + raise TypeError("Expecting x509.Name object.") + if self._issuer_name is not None: + raise ValueError("The issuer name may only be set once.") + return CertificateRevocationListBuilder( + issuer_name, + self._last_update, + self._next_update, + self._extensions, + self._revoked_certificates, + ) + + def last_update( + self, last_update: datetime.datetime + ) -> CertificateRevocationListBuilder: + if not isinstance(last_update, datetime.datetime): + raise TypeError("Expecting datetime object.") + if self._last_update is not None: + raise ValueError("Last update may only be set once.") + last_update = _convert_to_naive_utc_time(last_update) + if last_update < _EARLIEST_UTC_TIME: + raise ValueError( + "The last update date must be on or after" " 1950 January 1." + ) + if self._next_update is not None and last_update > self._next_update: + raise ValueError( + "The last update date must be before the next update date." + ) + return CertificateRevocationListBuilder( + self._issuer_name, + last_update, + self._next_update, + self._extensions, + self._revoked_certificates, + ) + + def next_update( + self, next_update: datetime.datetime + ) -> CertificateRevocationListBuilder: + if not isinstance(next_update, datetime.datetime): + raise TypeError("Expecting datetime object.") + if self._next_update is not None: + raise ValueError("Last update may only be set once.") + next_update = _convert_to_naive_utc_time(next_update) + if next_update < _EARLIEST_UTC_TIME: + raise ValueError( + "The last update date must be on or after" " 1950 January 1." + ) + if self._last_update is not None and next_update < self._last_update: + raise ValueError( + "The next update date must be after the last update date." + ) + return CertificateRevocationListBuilder( + self._issuer_name, + self._last_update, + next_update, + self._extensions, + self._revoked_certificates, + ) + + def add_extension( + self, extval: ExtensionType, critical: bool + ) -> CertificateRevocationListBuilder: + """ + Adds an X.509 extension to the certificate revocation list. + """ + if not isinstance(extval, ExtensionType): + raise TypeError("extension must be an ExtensionType") + + extension = Extension(extval.oid, critical, extval) + _reject_duplicate_extension(extension, self._extensions) + return CertificateRevocationListBuilder( + self._issuer_name, + self._last_update, + self._next_update, + self._extensions + [extension], + self._revoked_certificates, + ) + + def add_revoked_certificate( + self, revoked_certificate: RevokedCertificate + ) -> CertificateRevocationListBuilder: + """ + Adds a revoked certificate to the CRL. + """ + if not isinstance(revoked_certificate, RevokedCertificate): + raise TypeError("Must be an instance of RevokedCertificate") + + return CertificateRevocationListBuilder( + self._issuer_name, + self._last_update, + self._next_update, + self._extensions, + self._revoked_certificates + [revoked_certificate], + ) + + def sign( + self, + private_key: CertificateIssuerPrivateKeyTypes, + algorithm: typing.Optional[_AllowedHashTypes], + backend: typing.Any = None, + ) -> CertificateRevocationList: + if self._issuer_name is None: + raise ValueError("A CRL must have an issuer name") + + if self._last_update is None: + raise ValueError("A CRL must have a last update time") + + if self._next_update is None: + raise ValueError("A CRL must have a next update time") + + return rust_x509.create_x509_crl(self, private_key, algorithm) + + +class RevokedCertificateBuilder: + def __init__( + self, + serial_number: typing.Optional[int] = None, + revocation_date: typing.Optional[datetime.datetime] = None, + extensions: typing.List[Extension[ExtensionType]] = [], + ): + self._serial_number = serial_number + self._revocation_date = revocation_date + self._extensions = extensions + + def serial_number(self, number: int) -> RevokedCertificateBuilder: + if not isinstance(number, int): + raise TypeError("Serial number must be of integral type.") + if self._serial_number is not None: + raise ValueError("The serial number may only be set once.") + if number <= 0: + raise ValueError("The serial number should be positive") + + # ASN.1 integers are always signed, so most significant bit must be + # zero. + if number.bit_length() >= 160: # As defined in RFC 5280 + raise ValueError( + "The serial number should not be more than 159 " "bits." + ) + return RevokedCertificateBuilder( + number, self._revocation_date, self._extensions + ) + + def revocation_date( + self, time: datetime.datetime + ) -> RevokedCertificateBuilder: + if not isinstance(time, datetime.datetime): + raise TypeError("Expecting datetime object.") + if self._revocation_date is not None: + raise ValueError("The revocation date may only be set once.") + time = _convert_to_naive_utc_time(time) + if time < _EARLIEST_UTC_TIME: + raise ValueError( + "The revocation date must be on or after" " 1950 January 1." + ) + return RevokedCertificateBuilder( + self._serial_number, time, self._extensions + ) + + def add_extension( + self, extval: ExtensionType, critical: bool + ) -> RevokedCertificateBuilder: + if not isinstance(extval, ExtensionType): + raise TypeError("extension must be an ExtensionType") + + extension = Extension(extval.oid, critical, extval) + _reject_duplicate_extension(extension, self._extensions) + return RevokedCertificateBuilder( + self._serial_number, + self._revocation_date, + self._extensions + [extension], + ) + + def build(self, backend: typing.Any = None) -> RevokedCertificate: + if self._serial_number is None: + raise ValueError("A revoked certificate must have a serial number") + if self._revocation_date is None: + raise ValueError( + "A revoked certificate must have a revocation date" + ) + return _RawRevokedCertificate( + self._serial_number, + self._revocation_date, + Extensions(self._extensions), + ) + + +def random_serial_number() -> int: + return int.from_bytes(os.urandom(20), "big") >> 1 diff --git a/dist/ba_data/python-site-packages/cryptography/x509/certificate_transparency.py b/dist/ba_data/python-site-packages/cryptography/x509/certificate_transparency.py new file mode 100644 index 0000000..73647ee --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/x509/certificate_transparency.py @@ -0,0 +1,97 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import datetime + +from cryptography import utils +from cryptography.hazmat.bindings._rust import x509 as rust_x509 +from cryptography.hazmat.primitives.hashes import HashAlgorithm + + +class LogEntryType(utils.Enum): + X509_CERTIFICATE = 0 + PRE_CERTIFICATE = 1 + + +class Version(utils.Enum): + v1 = 0 + + +class SignatureAlgorithm(utils.Enum): + """ + Signature algorithms that are valid for SCTs. + + These are exactly the same as SignatureAlgorithm in RFC 5246 (TLS 1.2). + + See: + """ + + ANONYMOUS = 0 + RSA = 1 + DSA = 2 + ECDSA = 3 + + +class SignedCertificateTimestamp(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def version(self) -> Version: + """ + Returns the SCT version. + """ + + @property + @abc.abstractmethod + def log_id(self) -> bytes: + """ + Returns an identifier indicating which log this SCT is for. + """ + + @property + @abc.abstractmethod + def timestamp(self) -> datetime.datetime: + """ + Returns the timestamp for this SCT. + """ + + @property + @abc.abstractmethod + def entry_type(self) -> LogEntryType: + """ + Returns whether this is an SCT for a certificate or pre-certificate. + """ + + @property + @abc.abstractmethod + def signature_hash_algorithm(self) -> HashAlgorithm: + """ + Returns the hash algorithm used for the SCT's signature. + """ + + @property + @abc.abstractmethod + def signature_algorithm(self) -> SignatureAlgorithm: + """ + Returns the signing algorithm used for the SCT's signature. + """ + + @property + @abc.abstractmethod + def signature(self) -> bytes: + """ + Returns the signature for this SCT. + """ + + @property + @abc.abstractmethod + def extension_bytes(self) -> bytes: + """ + Returns the raw bytes of any extensions for this SCT. + """ + + +SignedCertificateTimestamp.register(rust_x509.Sct) diff --git a/dist/ba_data/python-site-packages/cryptography/x509/extensions.py b/dist/ba_data/python-site-packages/cryptography/x509/extensions.py new file mode 100644 index 0000000..ac99592 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/x509/extensions.py @@ -0,0 +1,2215 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import datetime +import hashlib +import ipaddress +import typing + +from cryptography import utils +from cryptography.hazmat.bindings._rust import asn1 +from cryptography.hazmat.bindings._rust import x509 as rust_x509 +from cryptography.hazmat.primitives import constant_time, serialization +from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey +from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey +from cryptography.hazmat.primitives.asymmetric.types import ( + CertificateIssuerPublicKeyTypes, + CertificatePublicKeyTypes, +) +from cryptography.x509.certificate_transparency import ( + SignedCertificateTimestamp, +) +from cryptography.x509.general_name import ( + DirectoryName, + DNSName, + GeneralName, + IPAddress, + OtherName, + RegisteredID, + RFC822Name, + UniformResourceIdentifier, + _IPAddressTypes, +) +from cryptography.x509.name import Name, RelativeDistinguishedName +from cryptography.x509.oid import ( + CRLEntryExtensionOID, + ExtensionOID, + ObjectIdentifier, + OCSPExtensionOID, +) + +ExtensionTypeVar = typing.TypeVar( + "ExtensionTypeVar", bound="ExtensionType", covariant=True +) + + +def _key_identifier_from_public_key( + public_key: CertificatePublicKeyTypes, +) -> bytes: + if isinstance(public_key, RSAPublicKey): + data = public_key.public_bytes( + serialization.Encoding.DER, + serialization.PublicFormat.PKCS1, + ) + elif isinstance(public_key, EllipticCurvePublicKey): + data = public_key.public_bytes( + serialization.Encoding.X962, + serialization.PublicFormat.UncompressedPoint, + ) + else: + # This is a very slow way to do this. + serialized = public_key.public_bytes( + serialization.Encoding.DER, + serialization.PublicFormat.SubjectPublicKeyInfo, + ) + data = asn1.parse_spki_for_data(serialized) + + return hashlib.sha1(data).digest() + + +def _make_sequence_methods(field_name: str): + def len_method(self) -> int: + return len(getattr(self, field_name)) + + def iter_method(self): + return iter(getattr(self, field_name)) + + def getitem_method(self, idx): + return getattr(self, field_name)[idx] + + return len_method, iter_method, getitem_method + + +class DuplicateExtension(Exception): + def __init__(self, msg: str, oid: ObjectIdentifier) -> None: + super().__init__(msg) + self.oid = oid + + +class ExtensionNotFound(Exception): + def __init__(self, msg: str, oid: ObjectIdentifier) -> None: + super().__init__(msg) + self.oid = oid + + +class ExtensionType(metaclass=abc.ABCMeta): + oid: typing.ClassVar[ObjectIdentifier] + + def public_bytes(self) -> bytes: + """ + Serializes the extension type to DER. + """ + raise NotImplementedError( + "public_bytes is not implemented for extension type {!r}".format( + self + ) + ) + + +class Extensions: + def __init__( + self, extensions: typing.Iterable[Extension[ExtensionType]] + ) -> None: + self._extensions = list(extensions) + + def get_extension_for_oid( + self, oid: ObjectIdentifier + ) -> Extension[ExtensionType]: + for ext in self: + if ext.oid == oid: + return ext + + raise ExtensionNotFound(f"No {oid} extension was found", oid) + + def get_extension_for_class( + self, extclass: typing.Type[ExtensionTypeVar] + ) -> Extension[ExtensionTypeVar]: + if extclass is UnrecognizedExtension: + raise TypeError( + "UnrecognizedExtension can't be used with " + "get_extension_for_class because more than one instance of the" + " class may be present." + ) + + for ext in self: + if isinstance(ext.value, extclass): + return ext + + raise ExtensionNotFound( + f"No {extclass} extension was found", extclass.oid + ) + + __len__, __iter__, __getitem__ = _make_sequence_methods("_extensions") + + def __repr__(self) -> str: + return f"" + + +class CRLNumber(ExtensionType): + oid = ExtensionOID.CRL_NUMBER + + def __init__(self, crl_number: int) -> None: + if not isinstance(crl_number, int): + raise TypeError("crl_number must be an integer") + + self._crl_number = crl_number + + def __eq__(self, other: object) -> bool: + if not isinstance(other, CRLNumber): + return NotImplemented + + return self.crl_number == other.crl_number + + def __hash__(self) -> int: + return hash(self.crl_number) + + def __repr__(self) -> str: + return f"" + + @property + def crl_number(self) -> int: + return self._crl_number + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class AuthorityKeyIdentifier(ExtensionType): + oid = ExtensionOID.AUTHORITY_KEY_IDENTIFIER + + def __init__( + self, + key_identifier: typing.Optional[bytes], + authority_cert_issuer: typing.Optional[typing.Iterable[GeneralName]], + authority_cert_serial_number: typing.Optional[int], + ) -> None: + if (authority_cert_issuer is None) != ( + authority_cert_serial_number is None + ): + raise ValueError( + "authority_cert_issuer and authority_cert_serial_number " + "must both be present or both None" + ) + + if authority_cert_issuer is not None: + authority_cert_issuer = list(authority_cert_issuer) + if not all( + isinstance(x, GeneralName) for x in authority_cert_issuer + ): + raise TypeError( + "authority_cert_issuer must be a list of GeneralName " + "objects" + ) + + if authority_cert_serial_number is not None and not isinstance( + authority_cert_serial_number, int + ): + raise TypeError("authority_cert_serial_number must be an integer") + + self._key_identifier = key_identifier + self._authority_cert_issuer = authority_cert_issuer + self._authority_cert_serial_number = authority_cert_serial_number + + # This takes a subset of CertificatePublicKeyTypes because an issuer + # cannot have an X25519/X448 key. This introduces some unfortunate + # asymmetry that requires typing users to explicitly + # narrow their type, but we should make this accurate and not just + # convenient. + @classmethod + def from_issuer_public_key( + cls, public_key: CertificateIssuerPublicKeyTypes + ) -> AuthorityKeyIdentifier: + digest = _key_identifier_from_public_key(public_key) + return cls( + key_identifier=digest, + authority_cert_issuer=None, + authority_cert_serial_number=None, + ) + + @classmethod + def from_issuer_subject_key_identifier( + cls, ski: SubjectKeyIdentifier + ) -> AuthorityKeyIdentifier: + return cls( + key_identifier=ski.digest, + authority_cert_issuer=None, + authority_cert_serial_number=None, + ) + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, AuthorityKeyIdentifier): + return NotImplemented + + return ( + self.key_identifier == other.key_identifier + and self.authority_cert_issuer == other.authority_cert_issuer + and self.authority_cert_serial_number + == other.authority_cert_serial_number + ) + + def __hash__(self) -> int: + if self.authority_cert_issuer is None: + aci = None + else: + aci = tuple(self.authority_cert_issuer) + return hash( + (self.key_identifier, aci, self.authority_cert_serial_number) + ) + + @property + def key_identifier(self) -> typing.Optional[bytes]: + return self._key_identifier + + @property + def authority_cert_issuer( + self, + ) -> typing.Optional[typing.List[GeneralName]]: + return self._authority_cert_issuer + + @property + def authority_cert_serial_number(self) -> typing.Optional[int]: + return self._authority_cert_serial_number + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class SubjectKeyIdentifier(ExtensionType): + oid = ExtensionOID.SUBJECT_KEY_IDENTIFIER + + def __init__(self, digest: bytes) -> None: + self._digest = digest + + @classmethod + def from_public_key( + cls, public_key: CertificatePublicKeyTypes + ) -> SubjectKeyIdentifier: + return cls(_key_identifier_from_public_key(public_key)) + + @property + def digest(self) -> bytes: + return self._digest + + @property + def key_identifier(self) -> bytes: + return self._digest + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, SubjectKeyIdentifier): + return NotImplemented + + return constant_time.bytes_eq(self.digest, other.digest) + + def __hash__(self) -> int: + return hash(self.digest) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class AuthorityInformationAccess(ExtensionType): + oid = ExtensionOID.AUTHORITY_INFORMATION_ACCESS + + def __init__( + self, descriptions: typing.Iterable[AccessDescription] + ) -> None: + descriptions = list(descriptions) + if not all(isinstance(x, AccessDescription) for x in descriptions): + raise TypeError( + "Every item in the descriptions list must be an " + "AccessDescription" + ) + + self._descriptions = descriptions + + __len__, __iter__, __getitem__ = _make_sequence_methods("_descriptions") + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, AuthorityInformationAccess): + return NotImplemented + + return self._descriptions == other._descriptions + + def __hash__(self) -> int: + return hash(tuple(self._descriptions)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class SubjectInformationAccess(ExtensionType): + oid = ExtensionOID.SUBJECT_INFORMATION_ACCESS + + def __init__( + self, descriptions: typing.Iterable[AccessDescription] + ) -> None: + descriptions = list(descriptions) + if not all(isinstance(x, AccessDescription) for x in descriptions): + raise TypeError( + "Every item in the descriptions list must be an " + "AccessDescription" + ) + + self._descriptions = descriptions + + __len__, __iter__, __getitem__ = _make_sequence_methods("_descriptions") + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, SubjectInformationAccess): + return NotImplemented + + return self._descriptions == other._descriptions + + def __hash__(self) -> int: + return hash(tuple(self._descriptions)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class AccessDescription: + def __init__( + self, access_method: ObjectIdentifier, access_location: GeneralName + ) -> None: + if not isinstance(access_method, ObjectIdentifier): + raise TypeError("access_method must be an ObjectIdentifier") + + if not isinstance(access_location, GeneralName): + raise TypeError("access_location must be a GeneralName") + + self._access_method = access_method + self._access_location = access_location + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, AccessDescription): + return NotImplemented + + return ( + self.access_method == other.access_method + and self.access_location == other.access_location + ) + + def __hash__(self) -> int: + return hash((self.access_method, self.access_location)) + + @property + def access_method(self) -> ObjectIdentifier: + return self._access_method + + @property + def access_location(self) -> GeneralName: + return self._access_location + + +class BasicConstraints(ExtensionType): + oid = ExtensionOID.BASIC_CONSTRAINTS + + def __init__(self, ca: bool, path_length: typing.Optional[int]) -> None: + if not isinstance(ca, bool): + raise TypeError("ca must be a boolean value") + + if path_length is not None and not ca: + raise ValueError("path_length must be None when ca is False") + + if path_length is not None and ( + not isinstance(path_length, int) or path_length < 0 + ): + raise TypeError( + "path_length must be a non-negative integer or None" + ) + + self._ca = ca + self._path_length = path_length + + @property + def ca(self) -> bool: + return self._ca + + @property + def path_length(self) -> typing.Optional[int]: + return self._path_length + + def __repr__(self) -> str: + return ( + "" + ).format(self) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, BasicConstraints): + return NotImplemented + + return self.ca == other.ca and self.path_length == other.path_length + + def __hash__(self) -> int: + return hash((self.ca, self.path_length)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class DeltaCRLIndicator(ExtensionType): + oid = ExtensionOID.DELTA_CRL_INDICATOR + + def __init__(self, crl_number: int) -> None: + if not isinstance(crl_number, int): + raise TypeError("crl_number must be an integer") + + self._crl_number = crl_number + + @property + def crl_number(self) -> int: + return self._crl_number + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DeltaCRLIndicator): + return NotImplemented + + return self.crl_number == other.crl_number + + def __hash__(self) -> int: + return hash(self.crl_number) + + def __repr__(self) -> str: + return f"" + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class CRLDistributionPoints(ExtensionType): + oid = ExtensionOID.CRL_DISTRIBUTION_POINTS + + def __init__( + self, distribution_points: typing.Iterable[DistributionPoint] + ) -> None: + distribution_points = list(distribution_points) + if not all( + isinstance(x, DistributionPoint) for x in distribution_points + ): + raise TypeError( + "distribution_points must be a list of DistributionPoint " + "objects" + ) + + self._distribution_points = distribution_points + + __len__, __iter__, __getitem__ = _make_sequence_methods( + "_distribution_points" + ) + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, CRLDistributionPoints): + return NotImplemented + + return self._distribution_points == other._distribution_points + + def __hash__(self) -> int: + return hash(tuple(self._distribution_points)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class FreshestCRL(ExtensionType): + oid = ExtensionOID.FRESHEST_CRL + + def __init__( + self, distribution_points: typing.Iterable[DistributionPoint] + ) -> None: + distribution_points = list(distribution_points) + if not all( + isinstance(x, DistributionPoint) for x in distribution_points + ): + raise TypeError( + "distribution_points must be a list of DistributionPoint " + "objects" + ) + + self._distribution_points = distribution_points + + __len__, __iter__, __getitem__ = _make_sequence_methods( + "_distribution_points" + ) + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, FreshestCRL): + return NotImplemented + + return self._distribution_points == other._distribution_points + + def __hash__(self) -> int: + return hash(tuple(self._distribution_points)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class DistributionPoint: + def __init__( + self, + full_name: typing.Optional[typing.Iterable[GeneralName]], + relative_name: typing.Optional[RelativeDistinguishedName], + reasons: typing.Optional[typing.FrozenSet[ReasonFlags]], + crl_issuer: typing.Optional[typing.Iterable[GeneralName]], + ) -> None: + if full_name and relative_name: + raise ValueError( + "You cannot provide both full_name and relative_name, at " + "least one must be None." + ) + if not full_name and not relative_name and not crl_issuer: + raise ValueError( + "Either full_name, relative_name or crl_issuer must be " + "provided." + ) + + if full_name is not None: + full_name = list(full_name) + if not all(isinstance(x, GeneralName) for x in full_name): + raise TypeError( + "full_name must be a list of GeneralName objects" + ) + + if relative_name: + if not isinstance(relative_name, RelativeDistinguishedName): + raise TypeError( + "relative_name must be a RelativeDistinguishedName" + ) + + if crl_issuer is not None: + crl_issuer = list(crl_issuer) + if not all(isinstance(x, GeneralName) for x in crl_issuer): + raise TypeError( + "crl_issuer must be None or a list of general names" + ) + + if reasons and ( + not isinstance(reasons, frozenset) + or not all(isinstance(x, ReasonFlags) for x in reasons) + ): + raise TypeError("reasons must be None or frozenset of ReasonFlags") + + if reasons and ( + ReasonFlags.unspecified in reasons + or ReasonFlags.remove_from_crl in reasons + ): + raise ValueError( + "unspecified and remove_from_crl are not valid reasons in a " + "DistributionPoint" + ) + + self._full_name = full_name + self._relative_name = relative_name + self._reasons = reasons + self._crl_issuer = crl_issuer + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DistributionPoint): + return NotImplemented + + return ( + self.full_name == other.full_name + and self.relative_name == other.relative_name + and self.reasons == other.reasons + and self.crl_issuer == other.crl_issuer + ) + + def __hash__(self) -> int: + if self.full_name is not None: + fn: typing.Optional[typing.Tuple[GeneralName, ...]] = tuple( + self.full_name + ) + else: + fn = None + + if self.crl_issuer is not None: + crl_issuer: typing.Optional[ + typing.Tuple[GeneralName, ...] + ] = tuple(self.crl_issuer) + else: + crl_issuer = None + + return hash((fn, self.relative_name, self.reasons, crl_issuer)) + + @property + def full_name(self) -> typing.Optional[typing.List[GeneralName]]: + return self._full_name + + @property + def relative_name(self) -> typing.Optional[RelativeDistinguishedName]: + return self._relative_name + + @property + def reasons(self) -> typing.Optional[typing.FrozenSet[ReasonFlags]]: + return self._reasons + + @property + def crl_issuer(self) -> typing.Optional[typing.List[GeneralName]]: + return self._crl_issuer + + +class ReasonFlags(utils.Enum): + unspecified = "unspecified" + key_compromise = "keyCompromise" + ca_compromise = "cACompromise" + affiliation_changed = "affiliationChanged" + superseded = "superseded" + cessation_of_operation = "cessationOfOperation" + certificate_hold = "certificateHold" + privilege_withdrawn = "privilegeWithdrawn" + aa_compromise = "aACompromise" + remove_from_crl = "removeFromCRL" + + +# These are distribution point bit string mappings. Not to be confused with +# CRLReason reason flags bit string mappings. +# ReasonFlags ::= BIT STRING { +# unused (0), +# keyCompromise (1), +# cACompromise (2), +# affiliationChanged (3), +# superseded (4), +# cessationOfOperation (5), +# certificateHold (6), +# privilegeWithdrawn (7), +# aACompromise (8) } +_REASON_BIT_MAPPING = { + 1: ReasonFlags.key_compromise, + 2: ReasonFlags.ca_compromise, + 3: ReasonFlags.affiliation_changed, + 4: ReasonFlags.superseded, + 5: ReasonFlags.cessation_of_operation, + 6: ReasonFlags.certificate_hold, + 7: ReasonFlags.privilege_withdrawn, + 8: ReasonFlags.aa_compromise, +} + +_CRLREASONFLAGS = { + ReasonFlags.key_compromise: 1, + ReasonFlags.ca_compromise: 2, + ReasonFlags.affiliation_changed: 3, + ReasonFlags.superseded: 4, + ReasonFlags.cessation_of_operation: 5, + ReasonFlags.certificate_hold: 6, + ReasonFlags.privilege_withdrawn: 7, + ReasonFlags.aa_compromise: 8, +} + + +class PolicyConstraints(ExtensionType): + oid = ExtensionOID.POLICY_CONSTRAINTS + + def __init__( + self, + require_explicit_policy: typing.Optional[int], + inhibit_policy_mapping: typing.Optional[int], + ) -> None: + if require_explicit_policy is not None and not isinstance( + require_explicit_policy, int + ): + raise TypeError( + "require_explicit_policy must be a non-negative integer or " + "None" + ) + + if inhibit_policy_mapping is not None and not isinstance( + inhibit_policy_mapping, int + ): + raise TypeError( + "inhibit_policy_mapping must be a non-negative integer or None" + ) + + if inhibit_policy_mapping is None and require_explicit_policy is None: + raise ValueError( + "At least one of require_explicit_policy and " + "inhibit_policy_mapping must not be None" + ) + + self._require_explicit_policy = require_explicit_policy + self._inhibit_policy_mapping = inhibit_policy_mapping + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, PolicyConstraints): + return NotImplemented + + return ( + self.require_explicit_policy == other.require_explicit_policy + and self.inhibit_policy_mapping == other.inhibit_policy_mapping + ) + + def __hash__(self) -> int: + return hash( + (self.require_explicit_policy, self.inhibit_policy_mapping) + ) + + @property + def require_explicit_policy(self) -> typing.Optional[int]: + return self._require_explicit_policy + + @property + def inhibit_policy_mapping(self) -> typing.Optional[int]: + return self._inhibit_policy_mapping + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class CertificatePolicies(ExtensionType): + oid = ExtensionOID.CERTIFICATE_POLICIES + + def __init__(self, policies: typing.Iterable[PolicyInformation]) -> None: + policies = list(policies) + if not all(isinstance(x, PolicyInformation) for x in policies): + raise TypeError( + "Every item in the policies list must be a " + "PolicyInformation" + ) + + self._policies = policies + + __len__, __iter__, __getitem__ = _make_sequence_methods("_policies") + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, CertificatePolicies): + return NotImplemented + + return self._policies == other._policies + + def __hash__(self) -> int: + return hash(tuple(self._policies)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class PolicyInformation: + def __init__( + self, + policy_identifier: ObjectIdentifier, + policy_qualifiers: typing.Optional[ + typing.Iterable[typing.Union[str, UserNotice]] + ], + ) -> None: + if not isinstance(policy_identifier, ObjectIdentifier): + raise TypeError("policy_identifier must be an ObjectIdentifier") + + self._policy_identifier = policy_identifier + + if policy_qualifiers is not None: + policy_qualifiers = list(policy_qualifiers) + if not all( + isinstance(x, (str, UserNotice)) for x in policy_qualifiers + ): + raise TypeError( + "policy_qualifiers must be a list of strings and/or " + "UserNotice objects or None" + ) + + self._policy_qualifiers = policy_qualifiers + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, PolicyInformation): + return NotImplemented + + return ( + self.policy_identifier == other.policy_identifier + and self.policy_qualifiers == other.policy_qualifiers + ) + + def __hash__(self) -> int: + if self.policy_qualifiers is not None: + pq: typing.Optional[ + typing.Tuple[typing.Union[str, UserNotice], ...] + ] = tuple(self.policy_qualifiers) + else: + pq = None + + return hash((self.policy_identifier, pq)) + + @property + def policy_identifier(self) -> ObjectIdentifier: + return self._policy_identifier + + @property + def policy_qualifiers( + self, + ) -> typing.Optional[typing.List[typing.Union[str, UserNotice]]]: + return self._policy_qualifiers + + +class UserNotice: + def __init__( + self, + notice_reference: typing.Optional[NoticeReference], + explicit_text: typing.Optional[str], + ) -> None: + if notice_reference and not isinstance( + notice_reference, NoticeReference + ): + raise TypeError( + "notice_reference must be None or a NoticeReference" + ) + + self._notice_reference = notice_reference + self._explicit_text = explicit_text + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, UserNotice): + return NotImplemented + + return ( + self.notice_reference == other.notice_reference + and self.explicit_text == other.explicit_text + ) + + def __hash__(self) -> int: + return hash((self.notice_reference, self.explicit_text)) + + @property + def notice_reference(self) -> typing.Optional[NoticeReference]: + return self._notice_reference + + @property + def explicit_text(self) -> typing.Optional[str]: + return self._explicit_text + + +class NoticeReference: + def __init__( + self, + organization: typing.Optional[str], + notice_numbers: typing.Iterable[int], + ) -> None: + self._organization = organization + notice_numbers = list(notice_numbers) + if not all(isinstance(x, int) for x in notice_numbers): + raise TypeError("notice_numbers must be a list of integers") + + self._notice_numbers = notice_numbers + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, NoticeReference): + return NotImplemented + + return ( + self.organization == other.organization + and self.notice_numbers == other.notice_numbers + ) + + def __hash__(self) -> int: + return hash((self.organization, tuple(self.notice_numbers))) + + @property + def organization(self) -> typing.Optional[str]: + return self._organization + + @property + def notice_numbers(self) -> typing.List[int]: + return self._notice_numbers + + +class ExtendedKeyUsage(ExtensionType): + oid = ExtensionOID.EXTENDED_KEY_USAGE + + def __init__(self, usages: typing.Iterable[ObjectIdentifier]) -> None: + usages = list(usages) + if not all(isinstance(x, ObjectIdentifier) for x in usages): + raise TypeError( + "Every item in the usages list must be an ObjectIdentifier" + ) + + self._usages = usages + + __len__, __iter__, __getitem__ = _make_sequence_methods("_usages") + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, ExtendedKeyUsage): + return NotImplemented + + return self._usages == other._usages + + def __hash__(self) -> int: + return hash(tuple(self._usages)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class OCSPNoCheck(ExtensionType): + oid = ExtensionOID.OCSP_NO_CHECK + + def __eq__(self, other: object) -> bool: + if not isinstance(other, OCSPNoCheck): + return NotImplemented + + return True + + def __hash__(self) -> int: + return hash(OCSPNoCheck) + + def __repr__(self) -> str: + return "" + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class PrecertPoison(ExtensionType): + oid = ExtensionOID.PRECERT_POISON + + def __eq__(self, other: object) -> bool: + if not isinstance(other, PrecertPoison): + return NotImplemented + + return True + + def __hash__(self) -> int: + return hash(PrecertPoison) + + def __repr__(self) -> str: + return "" + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class TLSFeature(ExtensionType): + oid = ExtensionOID.TLS_FEATURE + + def __init__(self, features: typing.Iterable[TLSFeatureType]) -> None: + features = list(features) + if ( + not all(isinstance(x, TLSFeatureType) for x in features) + or len(features) == 0 + ): + raise TypeError( + "features must be a list of elements from the TLSFeatureType " + "enum" + ) + + self._features = features + + __len__, __iter__, __getitem__ = _make_sequence_methods("_features") + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, TLSFeature): + return NotImplemented + + return self._features == other._features + + def __hash__(self) -> int: + return hash(tuple(self._features)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class TLSFeatureType(utils.Enum): + # status_request is defined in RFC 6066 and is used for what is commonly + # called OCSP Must-Staple when present in the TLS Feature extension in an + # X.509 certificate. + status_request = 5 + # status_request_v2 is defined in RFC 6961 and allows multiple OCSP + # responses to be provided. It is not currently in use by clients or + # servers. + status_request_v2 = 17 + + +_TLS_FEATURE_TYPE_TO_ENUM = {x.value: x for x in TLSFeatureType} + + +class InhibitAnyPolicy(ExtensionType): + oid = ExtensionOID.INHIBIT_ANY_POLICY + + def __init__(self, skip_certs: int) -> None: + if not isinstance(skip_certs, int): + raise TypeError("skip_certs must be an integer") + + if skip_certs < 0: + raise ValueError("skip_certs must be a non-negative integer") + + self._skip_certs = skip_certs + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, InhibitAnyPolicy): + return NotImplemented + + return self.skip_certs == other.skip_certs + + def __hash__(self) -> int: + return hash(self.skip_certs) + + @property + def skip_certs(self) -> int: + return self._skip_certs + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class KeyUsage(ExtensionType): + oid = ExtensionOID.KEY_USAGE + + def __init__( + self, + digital_signature: bool, + content_commitment: bool, + key_encipherment: bool, + data_encipherment: bool, + key_agreement: bool, + key_cert_sign: bool, + crl_sign: bool, + encipher_only: bool, + decipher_only: bool, + ) -> None: + if not key_agreement and (encipher_only or decipher_only): + raise ValueError( + "encipher_only and decipher_only can only be true when " + "key_agreement is true" + ) + + self._digital_signature = digital_signature + self._content_commitment = content_commitment + self._key_encipherment = key_encipherment + self._data_encipherment = data_encipherment + self._key_agreement = key_agreement + self._key_cert_sign = key_cert_sign + self._crl_sign = crl_sign + self._encipher_only = encipher_only + self._decipher_only = decipher_only + + @property + def digital_signature(self) -> bool: + return self._digital_signature + + @property + def content_commitment(self) -> bool: + return self._content_commitment + + @property + def key_encipherment(self) -> bool: + return self._key_encipherment + + @property + def data_encipherment(self) -> bool: + return self._data_encipherment + + @property + def key_agreement(self) -> bool: + return self._key_agreement + + @property + def key_cert_sign(self) -> bool: + return self._key_cert_sign + + @property + def crl_sign(self) -> bool: + return self._crl_sign + + @property + def encipher_only(self) -> bool: + if not self.key_agreement: + raise ValueError( + "encipher_only is undefined unless key_agreement is true" + ) + else: + return self._encipher_only + + @property + def decipher_only(self) -> bool: + if not self.key_agreement: + raise ValueError( + "decipher_only is undefined unless key_agreement is true" + ) + else: + return self._decipher_only + + def __repr__(self) -> str: + try: + encipher_only = self.encipher_only + decipher_only = self.decipher_only + except ValueError: + # Users found None confusing because even though encipher/decipher + # have no meaning unless key_agreement is true, to construct an + # instance of the class you still need to pass False. + encipher_only = False + decipher_only = False + + return ( + "" + ).format(self, encipher_only, decipher_only) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, KeyUsage): + return NotImplemented + + return ( + self.digital_signature == other.digital_signature + and self.content_commitment == other.content_commitment + and self.key_encipherment == other.key_encipherment + and self.data_encipherment == other.data_encipherment + and self.key_agreement == other.key_agreement + and self.key_cert_sign == other.key_cert_sign + and self.crl_sign == other.crl_sign + and self._encipher_only == other._encipher_only + and self._decipher_only == other._decipher_only + ) + + def __hash__(self) -> int: + return hash( + ( + self.digital_signature, + self.content_commitment, + self.key_encipherment, + self.data_encipherment, + self.key_agreement, + self.key_cert_sign, + self.crl_sign, + self._encipher_only, + self._decipher_only, + ) + ) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class NameConstraints(ExtensionType): + oid = ExtensionOID.NAME_CONSTRAINTS + + def __init__( + self, + permitted_subtrees: typing.Optional[typing.Iterable[GeneralName]], + excluded_subtrees: typing.Optional[typing.Iterable[GeneralName]], + ) -> None: + if permitted_subtrees is not None: + permitted_subtrees = list(permitted_subtrees) + if not permitted_subtrees: + raise ValueError( + "permitted_subtrees must be a non-empty list or None" + ) + if not all(isinstance(x, GeneralName) for x in permitted_subtrees): + raise TypeError( + "permitted_subtrees must be a list of GeneralName objects " + "or None" + ) + + self._validate_tree(permitted_subtrees) + + if excluded_subtrees is not None: + excluded_subtrees = list(excluded_subtrees) + if not excluded_subtrees: + raise ValueError( + "excluded_subtrees must be a non-empty list or None" + ) + if not all(isinstance(x, GeneralName) for x in excluded_subtrees): + raise TypeError( + "excluded_subtrees must be a list of GeneralName objects " + "or None" + ) + + self._validate_tree(excluded_subtrees) + + if permitted_subtrees is None and excluded_subtrees is None: + raise ValueError( + "At least one of permitted_subtrees and excluded_subtrees " + "must not be None" + ) + + self._permitted_subtrees = permitted_subtrees + self._excluded_subtrees = excluded_subtrees + + def __eq__(self, other: object) -> bool: + if not isinstance(other, NameConstraints): + return NotImplemented + + return ( + self.excluded_subtrees == other.excluded_subtrees + and self.permitted_subtrees == other.permitted_subtrees + ) + + def _validate_tree(self, tree: typing.Iterable[GeneralName]) -> None: + self._validate_ip_name(tree) + self._validate_dns_name(tree) + + def _validate_ip_name(self, tree: typing.Iterable[GeneralName]) -> None: + if any( + isinstance(name, IPAddress) + and not isinstance( + name.value, (ipaddress.IPv4Network, ipaddress.IPv6Network) + ) + for name in tree + ): + raise TypeError( + "IPAddress name constraints must be an IPv4Network or" + " IPv6Network object" + ) + + def _validate_dns_name(self, tree: typing.Iterable[GeneralName]) -> None: + if any( + isinstance(name, DNSName) and "*" in name.value for name in tree + ): + raise ValueError( + "DNSName name constraints must not contain the '*' wildcard" + " character" + ) + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __hash__(self) -> int: + if self.permitted_subtrees is not None: + ps: typing.Optional[typing.Tuple[GeneralName, ...]] = tuple( + self.permitted_subtrees + ) + else: + ps = None + + if self.excluded_subtrees is not None: + es: typing.Optional[typing.Tuple[GeneralName, ...]] = tuple( + self.excluded_subtrees + ) + else: + es = None + + return hash((ps, es)) + + @property + def permitted_subtrees( + self, + ) -> typing.Optional[typing.List[GeneralName]]: + return self._permitted_subtrees + + @property + def excluded_subtrees( + self, + ) -> typing.Optional[typing.List[GeneralName]]: + return self._excluded_subtrees + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class Extension(typing.Generic[ExtensionTypeVar]): + def __init__( + self, oid: ObjectIdentifier, critical: bool, value: ExtensionTypeVar + ) -> None: + if not isinstance(oid, ObjectIdentifier): + raise TypeError( + "oid argument must be an ObjectIdentifier instance." + ) + + if not isinstance(critical, bool): + raise TypeError("critical must be a boolean value") + + self._oid = oid + self._critical = critical + self._value = value + + @property + def oid(self) -> ObjectIdentifier: + return self._oid + + @property + def critical(self) -> bool: + return self._critical + + @property + def value(self) -> ExtensionTypeVar: + return self._value + + def __repr__(self) -> str: + return ( + "" + ).format(self) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Extension): + return NotImplemented + + return ( + self.oid == other.oid + and self.critical == other.critical + and self.value == other.value + ) + + def __hash__(self) -> int: + return hash((self.oid, self.critical, self.value)) + + +class GeneralNames: + def __init__(self, general_names: typing.Iterable[GeneralName]) -> None: + general_names = list(general_names) + if not all(isinstance(x, GeneralName) for x in general_names): + raise TypeError( + "Every item in the general_names list must be an " + "object conforming to the GeneralName interface" + ) + + self._general_names = general_names + + __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") + + @typing.overload + def get_values_for_type( + self, + type: typing.Union[ + typing.Type[DNSName], + typing.Type[UniformResourceIdentifier], + typing.Type[RFC822Name], + ], + ) -> typing.List[str]: + ... + + @typing.overload + def get_values_for_type( + self, + type: typing.Type[DirectoryName], + ) -> typing.List[Name]: + ... + + @typing.overload + def get_values_for_type( + self, + type: typing.Type[RegisteredID], + ) -> typing.List[ObjectIdentifier]: + ... + + @typing.overload + def get_values_for_type( + self, type: typing.Type[IPAddress] + ) -> typing.List[_IPAddressTypes]: + ... + + @typing.overload + def get_values_for_type( + self, type: typing.Type[OtherName] + ) -> typing.List[OtherName]: + ... + + def get_values_for_type( + self, + type: typing.Union[ + typing.Type[DNSName], + typing.Type[DirectoryName], + typing.Type[IPAddress], + typing.Type[OtherName], + typing.Type[RFC822Name], + typing.Type[RegisteredID], + typing.Type[UniformResourceIdentifier], + ], + ) -> typing.Union[ + typing.List[_IPAddressTypes], + typing.List[str], + typing.List[OtherName], + typing.List[Name], + typing.List[ObjectIdentifier], + ]: + # Return the value of each GeneralName, except for OtherName instances + # which we return directly because it has two important properties not + # just one value. + objs = (i for i in self if isinstance(i, type)) + if type != OtherName: + return [i.value for i in objs] + return list(objs) + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, GeneralNames): + return NotImplemented + + return self._general_names == other._general_names + + def __hash__(self) -> int: + return hash(tuple(self._general_names)) + + +class SubjectAlternativeName(ExtensionType): + oid = ExtensionOID.SUBJECT_ALTERNATIVE_NAME + + def __init__(self, general_names: typing.Iterable[GeneralName]) -> None: + self._general_names = GeneralNames(general_names) + + __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") + + @typing.overload + def get_values_for_type( + self, + type: typing.Union[ + typing.Type[DNSName], + typing.Type[UniformResourceIdentifier], + typing.Type[RFC822Name], + ], + ) -> typing.List[str]: + ... + + @typing.overload + def get_values_for_type( + self, + type: typing.Type[DirectoryName], + ) -> typing.List[Name]: + ... + + @typing.overload + def get_values_for_type( + self, + type: typing.Type[RegisteredID], + ) -> typing.List[ObjectIdentifier]: + ... + + @typing.overload + def get_values_for_type( + self, type: typing.Type[IPAddress] + ) -> typing.List[_IPAddressTypes]: + ... + + @typing.overload + def get_values_for_type( + self, type: typing.Type[OtherName] + ) -> typing.List[OtherName]: + ... + + def get_values_for_type( + self, + type: typing.Union[ + typing.Type[DNSName], + typing.Type[DirectoryName], + typing.Type[IPAddress], + typing.Type[OtherName], + typing.Type[RFC822Name], + typing.Type[RegisteredID], + typing.Type[UniformResourceIdentifier], + ], + ) -> typing.Union[ + typing.List[_IPAddressTypes], + typing.List[str], + typing.List[OtherName], + typing.List[Name], + typing.List[ObjectIdentifier], + ]: + return self._general_names.get_values_for_type(type) + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, SubjectAlternativeName): + return NotImplemented + + return self._general_names == other._general_names + + def __hash__(self) -> int: + return hash(self._general_names) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class IssuerAlternativeName(ExtensionType): + oid = ExtensionOID.ISSUER_ALTERNATIVE_NAME + + def __init__(self, general_names: typing.Iterable[GeneralName]) -> None: + self._general_names = GeneralNames(general_names) + + __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") + + @typing.overload + def get_values_for_type( + self, + type: typing.Union[ + typing.Type[DNSName], + typing.Type[UniformResourceIdentifier], + typing.Type[RFC822Name], + ], + ) -> typing.List[str]: + ... + + @typing.overload + def get_values_for_type( + self, + type: typing.Type[DirectoryName], + ) -> typing.List[Name]: + ... + + @typing.overload + def get_values_for_type( + self, + type: typing.Type[RegisteredID], + ) -> typing.List[ObjectIdentifier]: + ... + + @typing.overload + def get_values_for_type( + self, type: typing.Type[IPAddress] + ) -> typing.List[_IPAddressTypes]: + ... + + @typing.overload + def get_values_for_type( + self, type: typing.Type[OtherName] + ) -> typing.List[OtherName]: + ... + + def get_values_for_type( + self, + type: typing.Union[ + typing.Type[DNSName], + typing.Type[DirectoryName], + typing.Type[IPAddress], + typing.Type[OtherName], + typing.Type[RFC822Name], + typing.Type[RegisteredID], + typing.Type[UniformResourceIdentifier], + ], + ) -> typing.Union[ + typing.List[_IPAddressTypes], + typing.List[str], + typing.List[OtherName], + typing.List[Name], + typing.List[ObjectIdentifier], + ]: + return self._general_names.get_values_for_type(type) + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, IssuerAlternativeName): + return NotImplemented + + return self._general_names == other._general_names + + def __hash__(self) -> int: + return hash(self._general_names) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class CertificateIssuer(ExtensionType): + oid = CRLEntryExtensionOID.CERTIFICATE_ISSUER + + def __init__(self, general_names: typing.Iterable[GeneralName]) -> None: + self._general_names = GeneralNames(general_names) + + __len__, __iter__, __getitem__ = _make_sequence_methods("_general_names") + + @typing.overload + def get_values_for_type( + self, + type: typing.Union[ + typing.Type[DNSName], + typing.Type[UniformResourceIdentifier], + typing.Type[RFC822Name], + ], + ) -> typing.List[str]: + ... + + @typing.overload + def get_values_for_type( + self, + type: typing.Type[DirectoryName], + ) -> typing.List[Name]: + ... + + @typing.overload + def get_values_for_type( + self, + type: typing.Type[RegisteredID], + ) -> typing.List[ObjectIdentifier]: + ... + + @typing.overload + def get_values_for_type( + self, type: typing.Type[IPAddress] + ) -> typing.List[_IPAddressTypes]: + ... + + @typing.overload + def get_values_for_type( + self, type: typing.Type[OtherName] + ) -> typing.List[OtherName]: + ... + + def get_values_for_type( + self, + type: typing.Union[ + typing.Type[DNSName], + typing.Type[DirectoryName], + typing.Type[IPAddress], + typing.Type[OtherName], + typing.Type[RFC822Name], + typing.Type[RegisteredID], + typing.Type[UniformResourceIdentifier], + ], + ) -> typing.Union[ + typing.List[_IPAddressTypes], + typing.List[str], + typing.List[OtherName], + typing.List[Name], + typing.List[ObjectIdentifier], + ]: + return self._general_names.get_values_for_type(type) + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, CertificateIssuer): + return NotImplemented + + return self._general_names == other._general_names + + def __hash__(self) -> int: + return hash(self._general_names) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class CRLReason(ExtensionType): + oid = CRLEntryExtensionOID.CRL_REASON + + def __init__(self, reason: ReasonFlags) -> None: + if not isinstance(reason, ReasonFlags): + raise TypeError("reason must be an element from ReasonFlags") + + self._reason = reason + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, CRLReason): + return NotImplemented + + return self.reason == other.reason + + def __hash__(self) -> int: + return hash(self.reason) + + @property + def reason(self) -> ReasonFlags: + return self._reason + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class InvalidityDate(ExtensionType): + oid = CRLEntryExtensionOID.INVALIDITY_DATE + + def __init__(self, invalidity_date: datetime.datetime) -> None: + if not isinstance(invalidity_date, datetime.datetime): + raise TypeError("invalidity_date must be a datetime.datetime") + + self._invalidity_date = invalidity_date + + def __repr__(self) -> str: + return "".format( + self._invalidity_date + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, InvalidityDate): + return NotImplemented + + return self.invalidity_date == other.invalidity_date + + def __hash__(self) -> int: + return hash(self.invalidity_date) + + @property + def invalidity_date(self) -> datetime.datetime: + return self._invalidity_date + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class PrecertificateSignedCertificateTimestamps(ExtensionType): + oid = ExtensionOID.PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS + + def __init__( + self, + signed_certificate_timestamps: typing.Iterable[ + SignedCertificateTimestamp + ], + ) -> None: + signed_certificate_timestamps = list(signed_certificate_timestamps) + if not all( + isinstance(sct, SignedCertificateTimestamp) + for sct in signed_certificate_timestamps + ): + raise TypeError( + "Every item in the signed_certificate_timestamps list must be " + "a SignedCertificateTimestamp" + ) + self._signed_certificate_timestamps = signed_certificate_timestamps + + __len__, __iter__, __getitem__ = _make_sequence_methods( + "_signed_certificate_timestamps" + ) + + def __repr__(self) -> str: + return "".format( + list(self) + ) + + def __hash__(self) -> int: + return hash(tuple(self._signed_certificate_timestamps)) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, PrecertificateSignedCertificateTimestamps): + return NotImplemented + + return ( + self._signed_certificate_timestamps + == other._signed_certificate_timestamps + ) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class SignedCertificateTimestamps(ExtensionType): + oid = ExtensionOID.SIGNED_CERTIFICATE_TIMESTAMPS + + def __init__( + self, + signed_certificate_timestamps: typing.Iterable[ + SignedCertificateTimestamp + ], + ) -> None: + signed_certificate_timestamps = list(signed_certificate_timestamps) + if not all( + isinstance(sct, SignedCertificateTimestamp) + for sct in signed_certificate_timestamps + ): + raise TypeError( + "Every item in the signed_certificate_timestamps list must be " + "a SignedCertificateTimestamp" + ) + self._signed_certificate_timestamps = signed_certificate_timestamps + + __len__, __iter__, __getitem__ = _make_sequence_methods( + "_signed_certificate_timestamps" + ) + + def __repr__(self) -> str: + return f"" + + def __hash__(self) -> int: + return hash(tuple(self._signed_certificate_timestamps)) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, SignedCertificateTimestamps): + return NotImplemented + + return ( + self._signed_certificate_timestamps + == other._signed_certificate_timestamps + ) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class OCSPNonce(ExtensionType): + oid = OCSPExtensionOID.NONCE + + def __init__(self, nonce: bytes) -> None: + if not isinstance(nonce, bytes): + raise TypeError("nonce must be bytes") + + self._nonce = nonce + + def __eq__(self, other: object) -> bool: + if not isinstance(other, OCSPNonce): + return NotImplemented + + return self.nonce == other.nonce + + def __hash__(self) -> int: + return hash(self.nonce) + + def __repr__(self) -> str: + return f"" + + @property + def nonce(self) -> bytes: + return self._nonce + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class OCSPAcceptableResponses(ExtensionType): + oid = OCSPExtensionOID.ACCEPTABLE_RESPONSES + + def __init__(self, responses: typing.Iterable[ObjectIdentifier]) -> None: + responses = list(responses) + if any(not isinstance(r, ObjectIdentifier) for r in responses): + raise TypeError("All responses must be ObjectIdentifiers") + + self._responses = responses + + def __eq__(self, other: object) -> bool: + if not isinstance(other, OCSPAcceptableResponses): + return NotImplemented + + return self._responses == other._responses + + def __hash__(self) -> int: + return hash(tuple(self._responses)) + + def __repr__(self) -> str: + return f"" + + def __iter__(self) -> typing.Iterator[ObjectIdentifier]: + return iter(self._responses) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class IssuingDistributionPoint(ExtensionType): + oid = ExtensionOID.ISSUING_DISTRIBUTION_POINT + + def __init__( + self, + full_name: typing.Optional[typing.Iterable[GeneralName]], + relative_name: typing.Optional[RelativeDistinguishedName], + only_contains_user_certs: bool, + only_contains_ca_certs: bool, + only_some_reasons: typing.Optional[typing.FrozenSet[ReasonFlags]], + indirect_crl: bool, + only_contains_attribute_certs: bool, + ) -> None: + if full_name is not None: + full_name = list(full_name) + + if only_some_reasons and ( + not isinstance(only_some_reasons, frozenset) + or not all(isinstance(x, ReasonFlags) for x in only_some_reasons) + ): + raise TypeError( + "only_some_reasons must be None or frozenset of ReasonFlags" + ) + + if only_some_reasons and ( + ReasonFlags.unspecified in only_some_reasons + or ReasonFlags.remove_from_crl in only_some_reasons + ): + raise ValueError( + "unspecified and remove_from_crl are not valid reasons in an " + "IssuingDistributionPoint" + ) + + if not ( + isinstance(only_contains_user_certs, bool) + and isinstance(only_contains_ca_certs, bool) + and isinstance(indirect_crl, bool) + and isinstance(only_contains_attribute_certs, bool) + ): + raise TypeError( + "only_contains_user_certs, only_contains_ca_certs, " + "indirect_crl and only_contains_attribute_certs " + "must all be boolean." + ) + + crl_constraints = [ + only_contains_user_certs, + only_contains_ca_certs, + indirect_crl, + only_contains_attribute_certs, + ] + + if len([x for x in crl_constraints if x]) > 1: + raise ValueError( + "Only one of the following can be set to True: " + "only_contains_user_certs, only_contains_ca_certs, " + "indirect_crl, only_contains_attribute_certs" + ) + + if not any( + [ + only_contains_user_certs, + only_contains_ca_certs, + indirect_crl, + only_contains_attribute_certs, + full_name, + relative_name, + only_some_reasons, + ] + ): + raise ValueError( + "Cannot create empty extension: " + "if only_contains_user_certs, only_contains_ca_certs, " + "indirect_crl, and only_contains_attribute_certs are all False" + ", then either full_name, relative_name, or only_some_reasons " + "must have a value." + ) + + self._only_contains_user_certs = only_contains_user_certs + self._only_contains_ca_certs = only_contains_ca_certs + self._indirect_crl = indirect_crl + self._only_contains_attribute_certs = only_contains_attribute_certs + self._only_some_reasons = only_some_reasons + self._full_name = full_name + self._relative_name = relative_name + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, IssuingDistributionPoint): + return NotImplemented + + return ( + self.full_name == other.full_name + and self.relative_name == other.relative_name + and self.only_contains_user_certs == other.only_contains_user_certs + and self.only_contains_ca_certs == other.only_contains_ca_certs + and self.only_some_reasons == other.only_some_reasons + and self.indirect_crl == other.indirect_crl + and self.only_contains_attribute_certs + == other.only_contains_attribute_certs + ) + + def __hash__(self) -> int: + return hash( + ( + self.full_name, + self.relative_name, + self.only_contains_user_certs, + self.only_contains_ca_certs, + self.only_some_reasons, + self.indirect_crl, + self.only_contains_attribute_certs, + ) + ) + + @property + def full_name(self) -> typing.Optional[typing.List[GeneralName]]: + return self._full_name + + @property + def relative_name(self) -> typing.Optional[RelativeDistinguishedName]: + return self._relative_name + + @property + def only_contains_user_certs(self) -> bool: + return self._only_contains_user_certs + + @property + def only_contains_ca_certs(self) -> bool: + return self._only_contains_ca_certs + + @property + def only_some_reasons( + self, + ) -> typing.Optional[typing.FrozenSet[ReasonFlags]]: + return self._only_some_reasons + + @property + def indirect_crl(self) -> bool: + return self._indirect_crl + + @property + def only_contains_attribute_certs(self) -> bool: + return self._only_contains_attribute_certs + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class MSCertificateTemplate(ExtensionType): + oid = ExtensionOID.MS_CERTIFICATE_TEMPLATE + + def __init__( + self, + template_id: ObjectIdentifier, + major_version: typing.Optional[int], + minor_version: typing.Optional[int], + ) -> None: + if not isinstance(template_id, ObjectIdentifier): + raise TypeError("oid must be an ObjectIdentifier") + self._template_id = template_id + if ( + major_version is not None and not isinstance(major_version, int) + ) or ( + minor_version is not None and not isinstance(minor_version, int) + ): + raise TypeError( + "major_version and minor_version must be integers or None" + ) + self._major_version = major_version + self._minor_version = minor_version + + @property + def template_id(self) -> ObjectIdentifier: + return self._template_id + + @property + def major_version(self) -> typing.Optional[int]: + return self._major_version + + @property + def minor_version(self) -> typing.Optional[int]: + return self._minor_version + + def __repr__(self) -> str: + return ( + f"" + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, MSCertificateTemplate): + return NotImplemented + + return ( + self.template_id == other.template_id + and self.major_version == other.major_version + and self.minor_version == other.minor_version + ) + + def __hash__(self) -> int: + return hash((self.template_id, self.major_version, self.minor_version)) + + def public_bytes(self) -> bytes: + return rust_x509.encode_extension_value(self) + + +class UnrecognizedExtension(ExtensionType): + def __init__(self, oid: ObjectIdentifier, value: bytes) -> None: + if not isinstance(oid, ObjectIdentifier): + raise TypeError("oid must be an ObjectIdentifier") + self._oid = oid + self._value = value + + @property + def oid(self) -> ObjectIdentifier: # type: ignore[override] + return self._oid + + @property + def value(self) -> bytes: + return self._value + + def __repr__(self) -> str: + return ( + "".format(self) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, UnrecognizedExtension): + return NotImplemented + + return self.oid == other.oid and self.value == other.value + + def __hash__(self) -> int: + return hash((self.oid, self.value)) + + def public_bytes(self) -> bytes: + return self.value diff --git a/dist/ba_data/python-site-packages/cryptography/x509/general_name.py b/dist/ba_data/python-site-packages/cryptography/x509/general_name.py new file mode 100644 index 0000000..79271af --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/x509/general_name.py @@ -0,0 +1,283 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import ipaddress +import typing +from email.utils import parseaddr + +from cryptography.x509.name import Name +from cryptography.x509.oid import ObjectIdentifier + +_IPAddressTypes = typing.Union[ + ipaddress.IPv4Address, + ipaddress.IPv6Address, + ipaddress.IPv4Network, + ipaddress.IPv6Network, +] + + +class UnsupportedGeneralNameType(Exception): + pass + + +class GeneralName(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def value(self) -> typing.Any: + """ + Return the value of the object + """ + + +class RFC822Name(GeneralName): + def __init__(self, value: str) -> None: + if isinstance(value, str): + try: + value.encode("ascii") + except UnicodeEncodeError: + raise ValueError( + "RFC822Name values should be passed as an A-label string. " + "This means unicode characters should be encoded via " + "a library like idna." + ) + else: + raise TypeError("value must be string") + + name, address = parseaddr(value) + if name or not address: + # parseaddr has found a name (e.g. Name ) or the entire + # value is an empty string. + raise ValueError("Invalid rfc822name value") + + self._value = value + + @property + def value(self) -> str: + return self._value + + @classmethod + def _init_without_validation(cls, value: str) -> RFC822Name: + instance = cls.__new__(cls) + instance._value = value + return instance + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, RFC822Name): + return NotImplemented + + return self.value == other.value + + def __hash__(self) -> int: + return hash(self.value) + + +class DNSName(GeneralName): + def __init__(self, value: str) -> None: + if isinstance(value, str): + try: + value.encode("ascii") + except UnicodeEncodeError: + raise ValueError( + "DNSName values should be passed as an A-label string. " + "This means unicode characters should be encoded via " + "a library like idna." + ) + else: + raise TypeError("value must be string") + + self._value = value + + @property + def value(self) -> str: + return self._value + + @classmethod + def _init_without_validation(cls, value: str) -> DNSName: + instance = cls.__new__(cls) + instance._value = value + return instance + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DNSName): + return NotImplemented + + return self.value == other.value + + def __hash__(self) -> int: + return hash(self.value) + + +class UniformResourceIdentifier(GeneralName): + def __init__(self, value: str) -> None: + if isinstance(value, str): + try: + value.encode("ascii") + except UnicodeEncodeError: + raise ValueError( + "URI values should be passed as an A-label string. " + "This means unicode characters should be encoded via " + "a library like idna." + ) + else: + raise TypeError("value must be string") + + self._value = value + + @property + def value(self) -> str: + return self._value + + @classmethod + def _init_without_validation(cls, value: str) -> UniformResourceIdentifier: + instance = cls.__new__(cls) + instance._value = value + return instance + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, UniformResourceIdentifier): + return NotImplemented + + return self.value == other.value + + def __hash__(self) -> int: + return hash(self.value) + + +class DirectoryName(GeneralName): + def __init__(self, value: Name) -> None: + if not isinstance(value, Name): + raise TypeError("value must be a Name") + + self._value = value + + @property + def value(self) -> Name: + return self._value + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, DirectoryName): + return NotImplemented + + return self.value == other.value + + def __hash__(self) -> int: + return hash(self.value) + + +class RegisteredID(GeneralName): + def __init__(self, value: ObjectIdentifier) -> None: + if not isinstance(value, ObjectIdentifier): + raise TypeError("value must be an ObjectIdentifier") + + self._value = value + + @property + def value(self) -> ObjectIdentifier: + return self._value + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, RegisteredID): + return NotImplemented + + return self.value == other.value + + def __hash__(self) -> int: + return hash(self.value) + + +class IPAddress(GeneralName): + def __init__(self, value: _IPAddressTypes) -> None: + if not isinstance( + value, + ( + ipaddress.IPv4Address, + ipaddress.IPv6Address, + ipaddress.IPv4Network, + ipaddress.IPv6Network, + ), + ): + raise TypeError( + "value must be an instance of ipaddress.IPv4Address, " + "ipaddress.IPv6Address, ipaddress.IPv4Network, or " + "ipaddress.IPv6Network" + ) + + self._value = value + + @property + def value(self) -> _IPAddressTypes: + return self._value + + def _packed(self) -> bytes: + if isinstance( + self.value, (ipaddress.IPv4Address, ipaddress.IPv6Address) + ): + return self.value.packed + else: + return ( + self.value.network_address.packed + self.value.netmask.packed + ) + + def __repr__(self) -> str: + return f"" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, IPAddress): + return NotImplemented + + return self.value == other.value + + def __hash__(self) -> int: + return hash(self.value) + + +class OtherName(GeneralName): + def __init__(self, type_id: ObjectIdentifier, value: bytes) -> None: + if not isinstance(type_id, ObjectIdentifier): + raise TypeError("type_id must be an ObjectIdentifier") + if not isinstance(value, bytes): + raise TypeError("value must be a binary string") + + self._type_id = type_id + self._value = value + + @property + def type_id(self) -> ObjectIdentifier: + return self._type_id + + @property + def value(self) -> bytes: + return self._value + + def __repr__(self) -> str: + return "".format( + self.type_id, self.value + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, OtherName): + return NotImplemented + + return self.type_id == other.type_id and self.value == other.value + + def __hash__(self) -> int: + return hash((self.type_id, self.value)) diff --git a/dist/ba_data/python-site-packages/cryptography/x509/name.py b/dist/ba_data/python-site-packages/cryptography/x509/name.py new file mode 100644 index 0000000..ff98e87 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/x509/name.py @@ -0,0 +1,462 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import binascii +import re +import sys +import typing +import warnings + +from cryptography import utils +from cryptography.hazmat.bindings._rust import x509 as rust_x509 +from cryptography.x509.oid import NameOID, ObjectIdentifier + + +class _ASN1Type(utils.Enum): + BitString = 3 + OctetString = 4 + UTF8String = 12 + NumericString = 18 + PrintableString = 19 + T61String = 20 + IA5String = 22 + UTCTime = 23 + GeneralizedTime = 24 + VisibleString = 26 + UniversalString = 28 + BMPString = 30 + + +_ASN1_TYPE_TO_ENUM = {i.value: i for i in _ASN1Type} +_NAMEOID_DEFAULT_TYPE: typing.Dict[ObjectIdentifier, _ASN1Type] = { + NameOID.COUNTRY_NAME: _ASN1Type.PrintableString, + NameOID.JURISDICTION_COUNTRY_NAME: _ASN1Type.PrintableString, + NameOID.SERIAL_NUMBER: _ASN1Type.PrintableString, + NameOID.DN_QUALIFIER: _ASN1Type.PrintableString, + NameOID.EMAIL_ADDRESS: _ASN1Type.IA5String, + NameOID.DOMAIN_COMPONENT: _ASN1Type.IA5String, +} + +# Type alias +_OidNameMap = typing.Mapping[ObjectIdentifier, str] +_NameOidMap = typing.Mapping[str, ObjectIdentifier] + +#: Short attribute names from RFC 4514: +#: https://tools.ietf.org/html/rfc4514#page-7 +_NAMEOID_TO_NAME: _OidNameMap = { + NameOID.COMMON_NAME: "CN", + NameOID.LOCALITY_NAME: "L", + NameOID.STATE_OR_PROVINCE_NAME: "ST", + NameOID.ORGANIZATION_NAME: "O", + NameOID.ORGANIZATIONAL_UNIT_NAME: "OU", + NameOID.COUNTRY_NAME: "C", + NameOID.STREET_ADDRESS: "STREET", + NameOID.DOMAIN_COMPONENT: "DC", + NameOID.USER_ID: "UID", +} +_NAME_TO_NAMEOID = {v: k for k, v in _NAMEOID_TO_NAME.items()} + + +def _escape_dn_value(val: typing.Union[str, bytes]) -> str: + """Escape special characters in RFC4514 Distinguished Name value.""" + + if not val: + return "" + + # RFC 4514 Section 2.4 defines the value as being the # (U+0023) character + # followed by the hexadecimal encoding of the octets. + if isinstance(val, bytes): + return "#" + binascii.hexlify(val).decode("utf8") + + # See https://tools.ietf.org/html/rfc4514#section-2.4 + val = val.replace("\\", "\\\\") + val = val.replace('"', '\\"') + val = val.replace("+", "\\+") + val = val.replace(",", "\\,") + val = val.replace(";", "\\;") + val = val.replace("<", "\\<") + val = val.replace(">", "\\>") + val = val.replace("\0", "\\00") + + if val[0] in ("#", " "): + val = "\\" + val + if val[-1] == " ": + val = val[:-1] + "\\ " + + return val + + +def _unescape_dn_value(val: str) -> str: + if not val: + return "" + + # See https://tools.ietf.org/html/rfc4514#section-3 + + # special = escaped / SPACE / SHARP / EQUALS + # escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE + def sub(m): + val = m.group(1) + # Regular escape + if len(val) == 1: + return val + # Hex-value scape + return chr(int(val, 16)) + + return _RFC4514NameParser._PAIR_RE.sub(sub, val) + + +class NameAttribute: + def __init__( + self, + oid: ObjectIdentifier, + value: typing.Union[str, bytes], + _type: typing.Optional[_ASN1Type] = None, + *, + _validate: bool = True, + ) -> None: + if not isinstance(oid, ObjectIdentifier): + raise TypeError( + "oid argument must be an ObjectIdentifier instance." + ) + if _type == _ASN1Type.BitString: + if oid != NameOID.X500_UNIQUE_IDENTIFIER: + raise TypeError( + "oid must be X500_UNIQUE_IDENTIFIER for BitString type." + ) + if not isinstance(value, bytes): + raise TypeError("value must be bytes for BitString") + else: + if not isinstance(value, str): + raise TypeError("value argument must be a str") + + if ( + oid == NameOID.COUNTRY_NAME + or oid == NameOID.JURISDICTION_COUNTRY_NAME + ): + assert isinstance(value, str) + c_len = len(value.encode("utf8")) + if c_len != 2 and _validate is True: + raise ValueError( + "Country name must be a 2 character country code" + ) + elif c_len != 2: + warnings.warn( + "Country names should be two characters, but the " + "attribute is {} characters in length.".format(c_len), + stacklevel=2, + ) + + # The appropriate ASN1 string type varies by OID and is defined across + # multiple RFCs including 2459, 3280, and 5280. In general UTF8String + # is preferred (2459), but 3280 and 5280 specify several OIDs with + # alternate types. This means when we see the sentinel value we need + # to look up whether the OID has a non-UTF8 type. If it does, set it + # to that. Otherwise, UTF8! + if _type is None: + _type = _NAMEOID_DEFAULT_TYPE.get(oid, _ASN1Type.UTF8String) + + if not isinstance(_type, _ASN1Type): + raise TypeError("_type must be from the _ASN1Type enum") + + self._oid = oid + self._value = value + self._type = _type + + @property + def oid(self) -> ObjectIdentifier: + return self._oid + + @property + def value(self) -> typing.Union[str, bytes]: + return self._value + + @property + def rfc4514_attribute_name(self) -> str: + """ + The short attribute name (for example "CN") if available, + otherwise the OID dotted string. + """ + return _NAMEOID_TO_NAME.get(self.oid, self.oid.dotted_string) + + def rfc4514_string( + self, attr_name_overrides: typing.Optional[_OidNameMap] = None + ) -> str: + """ + Format as RFC4514 Distinguished Name string. + + Use short attribute name if available, otherwise fall back to OID + dotted string. + """ + attr_name = ( + attr_name_overrides.get(self.oid) if attr_name_overrides else None + ) + if attr_name is None: + attr_name = self.rfc4514_attribute_name + + return f"{attr_name}={_escape_dn_value(self.value)}" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, NameAttribute): + return NotImplemented + + return self.oid == other.oid and self.value == other.value + + def __hash__(self) -> int: + return hash((self.oid, self.value)) + + def __repr__(self) -> str: + return "".format(self) + + +class RelativeDistinguishedName: + def __init__(self, attributes: typing.Iterable[NameAttribute]): + attributes = list(attributes) + if not attributes: + raise ValueError("a relative distinguished name cannot be empty") + if not all(isinstance(x, NameAttribute) for x in attributes): + raise TypeError("attributes must be an iterable of NameAttribute") + + # Keep list and frozenset to preserve attribute order where it matters + self._attributes = attributes + self._attribute_set = frozenset(attributes) + + if len(self._attribute_set) != len(attributes): + raise ValueError("duplicate attributes are not allowed") + + def get_attributes_for_oid( + self, oid: ObjectIdentifier + ) -> typing.List[NameAttribute]: + return [i for i in self if i.oid == oid] + + def rfc4514_string( + self, attr_name_overrides: typing.Optional[_OidNameMap] = None + ) -> str: + """ + Format as RFC4514 Distinguished Name string. + + Within each RDN, attributes are joined by '+', although that is rarely + used in certificates. + """ + return "+".join( + attr.rfc4514_string(attr_name_overrides) + for attr in self._attributes + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, RelativeDistinguishedName): + return NotImplemented + + return self._attribute_set == other._attribute_set + + def __hash__(self) -> int: + return hash(self._attribute_set) + + def __iter__(self) -> typing.Iterator[NameAttribute]: + return iter(self._attributes) + + def __len__(self) -> int: + return len(self._attributes) + + def __repr__(self) -> str: + return f"" + + +class Name: + @typing.overload + def __init__(self, attributes: typing.Iterable[NameAttribute]) -> None: + ... + + @typing.overload + def __init__( + self, attributes: typing.Iterable[RelativeDistinguishedName] + ) -> None: + ... + + def __init__( + self, + attributes: typing.Iterable[ + typing.Union[NameAttribute, RelativeDistinguishedName] + ], + ) -> None: + attributes = list(attributes) + if all(isinstance(x, NameAttribute) for x in attributes): + self._attributes = [ + RelativeDistinguishedName([typing.cast(NameAttribute, x)]) + for x in attributes + ] + elif all(isinstance(x, RelativeDistinguishedName) for x in attributes): + self._attributes = typing.cast( + typing.List[RelativeDistinguishedName], attributes + ) + else: + raise TypeError( + "attributes must be a list of NameAttribute" + " or a list RelativeDistinguishedName" + ) + + @classmethod + def from_rfc4514_string( + cls, + data: str, + attr_name_overrides: typing.Optional[_NameOidMap] = None, + ) -> Name: + return _RFC4514NameParser(data, attr_name_overrides or {}).parse() + + def rfc4514_string( + self, attr_name_overrides: typing.Optional[_OidNameMap] = None + ) -> str: + """ + Format as RFC4514 Distinguished Name string. + For example 'CN=foobar.com,O=Foo Corp,C=US' + + An X.509 name is a two-level structure: a list of sets of attributes. + Each list element is separated by ',' and within each list element, set + elements are separated by '+'. The latter is almost never used in + real world certificates. According to RFC4514 section 2.1 the + RDNSequence must be reversed when converting to string representation. + """ + return ",".join( + attr.rfc4514_string(attr_name_overrides) + for attr in reversed(self._attributes) + ) + + def get_attributes_for_oid( + self, oid: ObjectIdentifier + ) -> typing.List[NameAttribute]: + return [i for i in self if i.oid == oid] + + @property + def rdns(self) -> typing.List[RelativeDistinguishedName]: + return self._attributes + + def public_bytes(self, backend: typing.Any = None) -> bytes: + return rust_x509.encode_name_bytes(self) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Name): + return NotImplemented + + return self._attributes == other._attributes + + def __hash__(self) -> int: + # TODO: this is relatively expensive, if this looks like a bottleneck + # for you, consider optimizing! + return hash(tuple(self._attributes)) + + def __iter__(self) -> typing.Iterator[NameAttribute]: + for rdn in self._attributes: + for ava in rdn: + yield ava + + def __len__(self) -> int: + return sum(len(rdn) for rdn in self._attributes) + + def __repr__(self) -> str: + rdns = ",".join(attr.rfc4514_string() for attr in self._attributes) + return f"" + + +class _RFC4514NameParser: + _OID_RE = re.compile(r"(0|([1-9]\d*))(\.(0|([1-9]\d*)))+") + _DESCR_RE = re.compile(r"[a-zA-Z][a-zA-Z\d-]*") + + _PAIR = r"\\([\\ #=\"\+,;<>]|[\da-zA-Z]{2})" + _PAIR_RE = re.compile(_PAIR) + _LUTF1 = r"[\x01-\x1f\x21\x24-\x2A\x2D-\x3A\x3D\x3F-\x5B\x5D-\x7F]" + _SUTF1 = r"[\x01-\x21\x23-\x2A\x2D-\x3A\x3D\x3F-\x5B\x5D-\x7F]" + _TUTF1 = r"[\x01-\x1F\x21\x23-\x2A\x2D-\x3A\x3D\x3F-\x5B\x5D-\x7F]" + _UTFMB = rf"[\x80-{chr(sys.maxunicode)}]" + _LEADCHAR = rf"{_LUTF1}|{_UTFMB}" + _STRINGCHAR = rf"{_SUTF1}|{_UTFMB}" + _TRAILCHAR = rf"{_TUTF1}|{_UTFMB}" + _STRING_RE = re.compile( + rf""" + ( + ({_LEADCHAR}|{_PAIR}) + ( + ({_STRINGCHAR}|{_PAIR})* + ({_TRAILCHAR}|{_PAIR}) + )? + )? + """, + re.VERBOSE, + ) + _HEXSTRING_RE = re.compile(r"#([\da-zA-Z]{2})+") + + def __init__(self, data: str, attr_name_overrides: _NameOidMap) -> None: + self._data = data + self._idx = 0 + + self._attr_name_overrides = attr_name_overrides + + def _has_data(self) -> bool: + return self._idx < len(self._data) + + def _peek(self) -> typing.Optional[str]: + if self._has_data(): + return self._data[self._idx] + return None + + def _read_char(self, ch: str) -> None: + if self._peek() != ch: + raise ValueError + self._idx += 1 + + def _read_re(self, pat) -> str: + match = pat.match(self._data, pos=self._idx) + if match is None: + raise ValueError + val = match.group() + self._idx += len(val) + return val + + def parse(self) -> Name: + """ + Parses the `data` string and converts it to a Name. + + According to RFC4514 section 2.1 the RDNSequence must be + reversed when converting to string representation. So, when + we parse it, we need to reverse again to get the RDNs on the + correct order. + """ + rdns = [self._parse_rdn()] + + while self._has_data(): + self._read_char(",") + rdns.append(self._parse_rdn()) + + return Name(reversed(rdns)) + + def _parse_rdn(self) -> RelativeDistinguishedName: + nas = [self._parse_na()] + while self._peek() == "+": + self._read_char("+") + nas.append(self._parse_na()) + + return RelativeDistinguishedName(nas) + + def _parse_na(self) -> NameAttribute: + try: + oid_value = self._read_re(self._OID_RE) + except ValueError: + name = self._read_re(self._DESCR_RE) + oid = self._attr_name_overrides.get( + name, _NAME_TO_NAMEOID.get(name) + ) + if oid is None: + raise ValueError + else: + oid = ObjectIdentifier(oid_value) + + self._read_char("=") + if self._peek() == "#": + value = self._read_re(self._HEXSTRING_RE) + value = binascii.unhexlify(value[1:]).decode() + else: + raw_value = self._read_re(self._STRING_RE) + value = _unescape_dn_value(raw_value) + + return NameAttribute(oid, value) diff --git a/dist/ba_data/python-site-packages/cryptography/x509/ocsp.py b/dist/ba_data/python-site-packages/cryptography/x509/ocsp.py new file mode 100644 index 0000000..7054795 --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/x509/ocsp.py @@ -0,0 +1,622 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import abc +import datetime +import typing + +from cryptography import utils, x509 +from cryptography.hazmat.bindings._rust import ocsp +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric.types import ( + CertificateIssuerPrivateKeyTypes, +) +from cryptography.x509.base import ( + _EARLIEST_UTC_TIME, + _convert_to_naive_utc_time, + _reject_duplicate_extension, +) + + +class OCSPResponderEncoding(utils.Enum): + HASH = "By Hash" + NAME = "By Name" + + +class OCSPResponseStatus(utils.Enum): + SUCCESSFUL = 0 + MALFORMED_REQUEST = 1 + INTERNAL_ERROR = 2 + TRY_LATER = 3 + SIG_REQUIRED = 5 + UNAUTHORIZED = 6 + + +_ALLOWED_HASHES = ( + hashes.SHA1, + hashes.SHA224, + hashes.SHA256, + hashes.SHA384, + hashes.SHA512, +) + + +def _verify_algorithm(algorithm: hashes.HashAlgorithm) -> None: + if not isinstance(algorithm, _ALLOWED_HASHES): + raise ValueError( + "Algorithm must be SHA1, SHA224, SHA256, SHA384, or SHA512" + ) + + +class OCSPCertStatus(utils.Enum): + GOOD = 0 + REVOKED = 1 + UNKNOWN = 2 + + +class _SingleResponse: + def __init__( + self, + cert: x509.Certificate, + issuer: x509.Certificate, + algorithm: hashes.HashAlgorithm, + cert_status: OCSPCertStatus, + this_update: datetime.datetime, + next_update: typing.Optional[datetime.datetime], + revocation_time: typing.Optional[datetime.datetime], + revocation_reason: typing.Optional[x509.ReasonFlags], + ): + if not isinstance(cert, x509.Certificate) or not isinstance( + issuer, x509.Certificate + ): + raise TypeError("cert and issuer must be a Certificate") + + _verify_algorithm(algorithm) + if not isinstance(this_update, datetime.datetime): + raise TypeError("this_update must be a datetime object") + if next_update is not None and not isinstance( + next_update, datetime.datetime + ): + raise TypeError("next_update must be a datetime object or None") + + self._cert = cert + self._issuer = issuer + self._algorithm = algorithm + self._this_update = this_update + self._next_update = next_update + + if not isinstance(cert_status, OCSPCertStatus): + raise TypeError( + "cert_status must be an item from the OCSPCertStatus enum" + ) + if cert_status is not OCSPCertStatus.REVOKED: + if revocation_time is not None: + raise ValueError( + "revocation_time can only be provided if the certificate " + "is revoked" + ) + if revocation_reason is not None: + raise ValueError( + "revocation_reason can only be provided if the certificate" + " is revoked" + ) + else: + if not isinstance(revocation_time, datetime.datetime): + raise TypeError("revocation_time must be a datetime object") + + revocation_time = _convert_to_naive_utc_time(revocation_time) + if revocation_time < _EARLIEST_UTC_TIME: + raise ValueError( + "The revocation_time must be on or after" + " 1950 January 1." + ) + + if revocation_reason is not None and not isinstance( + revocation_reason, x509.ReasonFlags + ): + raise TypeError( + "revocation_reason must be an item from the ReasonFlags " + "enum or None" + ) + + self._cert_status = cert_status + self._revocation_time = revocation_time + self._revocation_reason = revocation_reason + + +class OCSPRequest(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def issuer_key_hash(self) -> bytes: + """ + The hash of the issuer public key + """ + + @property + @abc.abstractmethod + def issuer_name_hash(self) -> bytes: + """ + The hash of the issuer name + """ + + @property + @abc.abstractmethod + def hash_algorithm(self) -> hashes.HashAlgorithm: + """ + The hash algorithm used in the issuer name and key hashes + """ + + @property + @abc.abstractmethod + def serial_number(self) -> int: + """ + The serial number of the cert whose status is being checked + """ + + @abc.abstractmethod + def public_bytes(self, encoding: serialization.Encoding) -> bytes: + """ + Serializes the request to DER + """ + + @property + @abc.abstractmethod + def extensions(self) -> x509.Extensions: + """ + The list of request extensions. Not single request extensions. + """ + + +class OCSPSingleResponse(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def certificate_status(self) -> OCSPCertStatus: + """ + The status of the certificate (an element from the OCSPCertStatus enum) + """ + + @property + @abc.abstractmethod + def revocation_time(self) -> typing.Optional[datetime.datetime]: + """ + The date of when the certificate was revoked or None if not + revoked. + """ + + @property + @abc.abstractmethod + def revocation_reason(self) -> typing.Optional[x509.ReasonFlags]: + """ + The reason the certificate was revoked or None if not specified or + not revoked. + """ + + @property + @abc.abstractmethod + def this_update(self) -> datetime.datetime: + """ + The most recent time at which the status being indicated is known by + the responder to have been correct + """ + + @property + @abc.abstractmethod + def next_update(self) -> typing.Optional[datetime.datetime]: + """ + The time when newer information will be available + """ + + @property + @abc.abstractmethod + def issuer_key_hash(self) -> bytes: + """ + The hash of the issuer public key + """ + + @property + @abc.abstractmethod + def issuer_name_hash(self) -> bytes: + """ + The hash of the issuer name + """ + + @property + @abc.abstractmethod + def hash_algorithm(self) -> hashes.HashAlgorithm: + """ + The hash algorithm used in the issuer name and key hashes + """ + + @property + @abc.abstractmethod + def serial_number(self) -> int: + """ + The serial number of the cert whose status is being checked + """ + + +class OCSPResponse(metaclass=abc.ABCMeta): + @property + @abc.abstractmethod + def responses(self) -> typing.Iterator[OCSPSingleResponse]: + """ + An iterator over the individual SINGLERESP structures in the + response + """ + + @property + @abc.abstractmethod + def response_status(self) -> OCSPResponseStatus: + """ + The status of the response. This is a value from the OCSPResponseStatus + enumeration + """ + + @property + @abc.abstractmethod + def signature_algorithm_oid(self) -> x509.ObjectIdentifier: + """ + The ObjectIdentifier of the signature algorithm + """ + + @property + @abc.abstractmethod + def signature_hash_algorithm( + self, + ) -> typing.Optional[hashes.HashAlgorithm]: + """ + Returns a HashAlgorithm corresponding to the type of the digest signed + """ + + @property + @abc.abstractmethod + def signature(self) -> bytes: + """ + The signature bytes + """ + + @property + @abc.abstractmethod + def tbs_response_bytes(self) -> bytes: + """ + The tbsResponseData bytes + """ + + @property + @abc.abstractmethod + def certificates(self) -> typing.List[x509.Certificate]: + """ + A list of certificates used to help build a chain to verify the OCSP + response. This situation occurs when the OCSP responder uses a delegate + certificate. + """ + + @property + @abc.abstractmethod + def responder_key_hash(self) -> typing.Optional[bytes]: + """ + The responder's key hash or None + """ + + @property + @abc.abstractmethod + def responder_name(self) -> typing.Optional[x509.Name]: + """ + The responder's Name or None + """ + + @property + @abc.abstractmethod + def produced_at(self) -> datetime.datetime: + """ + The time the response was produced + """ + + @property + @abc.abstractmethod + def certificate_status(self) -> OCSPCertStatus: + """ + The status of the certificate (an element from the OCSPCertStatus enum) + """ + + @property + @abc.abstractmethod + def revocation_time(self) -> typing.Optional[datetime.datetime]: + """ + The date of when the certificate was revoked or None if not + revoked. + """ + + @property + @abc.abstractmethod + def revocation_reason(self) -> typing.Optional[x509.ReasonFlags]: + """ + The reason the certificate was revoked or None if not specified or + not revoked. + """ + + @property + @abc.abstractmethod + def this_update(self) -> datetime.datetime: + """ + The most recent time at which the status being indicated is known by + the responder to have been correct + """ + + @property + @abc.abstractmethod + def next_update(self) -> typing.Optional[datetime.datetime]: + """ + The time when newer information will be available + """ + + @property + @abc.abstractmethod + def issuer_key_hash(self) -> bytes: + """ + The hash of the issuer public key + """ + + @property + @abc.abstractmethod + def issuer_name_hash(self) -> bytes: + """ + The hash of the issuer name + """ + + @property + @abc.abstractmethod + def hash_algorithm(self) -> hashes.HashAlgorithm: + """ + The hash algorithm used in the issuer name and key hashes + """ + + @property + @abc.abstractmethod + def serial_number(self) -> int: + """ + The serial number of the cert whose status is being checked + """ + + @property + @abc.abstractmethod + def extensions(self) -> x509.Extensions: + """ + The list of response extensions. Not single response extensions. + """ + + @property + @abc.abstractmethod + def single_extensions(self) -> x509.Extensions: + """ + The list of single response extensions. Not response extensions. + """ + + @abc.abstractmethod + def public_bytes(self, encoding: serialization.Encoding) -> bytes: + """ + Serializes the response to DER + """ + + +class OCSPRequestBuilder: + def __init__( + self, + request: typing.Optional[ + typing.Tuple[ + x509.Certificate, x509.Certificate, hashes.HashAlgorithm + ] + ] = None, + request_hash: typing.Optional[ + typing.Tuple[bytes, bytes, int, hashes.HashAlgorithm] + ] = None, + extensions: typing.List[x509.Extension[x509.ExtensionType]] = [], + ) -> None: + self._request = request + self._request_hash = request_hash + self._extensions = extensions + + def add_certificate( + self, + cert: x509.Certificate, + issuer: x509.Certificate, + algorithm: hashes.HashAlgorithm, + ) -> OCSPRequestBuilder: + if self._request is not None or self._request_hash is not None: + raise ValueError("Only one certificate can be added to a request") + + _verify_algorithm(algorithm) + if not isinstance(cert, x509.Certificate) or not isinstance( + issuer, x509.Certificate + ): + raise TypeError("cert and issuer must be a Certificate") + + return OCSPRequestBuilder( + (cert, issuer, algorithm), self._request_hash, self._extensions + ) + + def add_certificate_by_hash( + self, + issuer_name_hash: bytes, + issuer_key_hash: bytes, + serial_number: int, + algorithm: hashes.HashAlgorithm, + ) -> OCSPRequestBuilder: + if self._request is not None or self._request_hash is not None: + raise ValueError("Only one certificate can be added to a request") + + if not isinstance(serial_number, int): + raise TypeError("serial_number must be an integer") + + _verify_algorithm(algorithm) + utils._check_bytes("issuer_name_hash", issuer_name_hash) + utils._check_bytes("issuer_key_hash", issuer_key_hash) + if algorithm.digest_size != len( + issuer_name_hash + ) or algorithm.digest_size != len(issuer_key_hash): + raise ValueError( + "issuer_name_hash and issuer_key_hash must be the same length " + "as the digest size of the algorithm" + ) + + return OCSPRequestBuilder( + self._request, + (issuer_name_hash, issuer_key_hash, serial_number, algorithm), + self._extensions, + ) + + def add_extension( + self, extval: x509.ExtensionType, critical: bool + ) -> OCSPRequestBuilder: + if not isinstance(extval, x509.ExtensionType): + raise TypeError("extension must be an ExtensionType") + + extension = x509.Extension(extval.oid, critical, extval) + _reject_duplicate_extension(extension, self._extensions) + + return OCSPRequestBuilder( + self._request, self._request_hash, self._extensions + [extension] + ) + + def build(self) -> OCSPRequest: + if self._request is None and self._request_hash is None: + raise ValueError("You must add a certificate before building") + + return ocsp.create_ocsp_request(self) + + +class OCSPResponseBuilder: + def __init__( + self, + response: typing.Optional[_SingleResponse] = None, + responder_id: typing.Optional[ + typing.Tuple[x509.Certificate, OCSPResponderEncoding] + ] = None, + certs: typing.Optional[typing.List[x509.Certificate]] = None, + extensions: typing.List[x509.Extension[x509.ExtensionType]] = [], + ): + self._response = response + self._responder_id = responder_id + self._certs = certs + self._extensions = extensions + + def add_response( + self, + cert: x509.Certificate, + issuer: x509.Certificate, + algorithm: hashes.HashAlgorithm, + cert_status: OCSPCertStatus, + this_update: datetime.datetime, + next_update: typing.Optional[datetime.datetime], + revocation_time: typing.Optional[datetime.datetime], + revocation_reason: typing.Optional[x509.ReasonFlags], + ) -> OCSPResponseBuilder: + if self._response is not None: + raise ValueError("Only one response per OCSPResponse.") + + singleresp = _SingleResponse( + cert, + issuer, + algorithm, + cert_status, + this_update, + next_update, + revocation_time, + revocation_reason, + ) + return OCSPResponseBuilder( + singleresp, + self._responder_id, + self._certs, + self._extensions, + ) + + def responder_id( + self, encoding: OCSPResponderEncoding, responder_cert: x509.Certificate + ) -> OCSPResponseBuilder: + if self._responder_id is not None: + raise ValueError("responder_id can only be set once") + if not isinstance(responder_cert, x509.Certificate): + raise TypeError("responder_cert must be a Certificate") + if not isinstance(encoding, OCSPResponderEncoding): + raise TypeError( + "encoding must be an element from OCSPResponderEncoding" + ) + + return OCSPResponseBuilder( + self._response, + (responder_cert, encoding), + self._certs, + self._extensions, + ) + + def certificates( + self, certs: typing.Iterable[x509.Certificate] + ) -> OCSPResponseBuilder: + if self._certs is not None: + raise ValueError("certificates may only be set once") + certs = list(certs) + if len(certs) == 0: + raise ValueError("certs must not be an empty list") + if not all(isinstance(x, x509.Certificate) for x in certs): + raise TypeError("certs must be a list of Certificates") + return OCSPResponseBuilder( + self._response, + self._responder_id, + certs, + self._extensions, + ) + + def add_extension( + self, extval: x509.ExtensionType, critical: bool + ) -> OCSPResponseBuilder: + if not isinstance(extval, x509.ExtensionType): + raise TypeError("extension must be an ExtensionType") + + extension = x509.Extension(extval.oid, critical, extval) + _reject_duplicate_extension(extension, self._extensions) + + return OCSPResponseBuilder( + self._response, + self._responder_id, + self._certs, + self._extensions + [extension], + ) + + def sign( + self, + private_key: CertificateIssuerPrivateKeyTypes, + algorithm: typing.Optional[hashes.HashAlgorithm], + ) -> OCSPResponse: + if self._response is None: + raise ValueError("You must add a response before signing") + if self._responder_id is None: + raise ValueError("You must add a responder_id before signing") + + return ocsp.create_ocsp_response( + OCSPResponseStatus.SUCCESSFUL, self, private_key, algorithm + ) + + @classmethod + def build_unsuccessful( + cls, response_status: OCSPResponseStatus + ) -> OCSPResponse: + if not isinstance(response_status, OCSPResponseStatus): + raise TypeError( + "response_status must be an item from OCSPResponseStatus" + ) + if response_status is OCSPResponseStatus.SUCCESSFUL: + raise ValueError("response_status cannot be SUCCESSFUL") + + return ocsp.create_ocsp_response(response_status, None, None, None) + + +def load_der_ocsp_request(data: bytes) -> OCSPRequest: + return ocsp.load_der_ocsp_request(data) + + +def load_der_ocsp_response(data: bytes) -> OCSPResponse: + return ocsp.load_der_ocsp_response(data) diff --git a/dist/ba_data/python-site-packages/cryptography/x509/oid.py b/dist/ba_data/python-site-packages/cryptography/x509/oid.py new file mode 100644 index 0000000..cda50cc --- /dev/null +++ b/dist/ba_data/python-site-packages/cryptography/x509/oid.py @@ -0,0 +1,33 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +from cryptography.hazmat._oid import ( + AttributeOID, + AuthorityInformationAccessOID, + CertificatePoliciesOID, + CRLEntryExtensionOID, + ExtendedKeyUsageOID, + ExtensionOID, + NameOID, + ObjectIdentifier, + OCSPExtensionOID, + SignatureAlgorithmOID, + SubjectInformationAccessOID, +) + +__all__ = [ + "AttributeOID", + "AuthorityInformationAccessOID", + "CRLEntryExtensionOID", + "CertificatePoliciesOID", + "ExtendedKeyUsageOID", + "ExtensionOID", + "NameOID", + "OCSPExtensionOID", + "ObjectIdentifier", + "SignatureAlgorithmOID", + "SubjectInformationAccessOID", +] diff --git a/dist/ba_data/python-site-packages/discord/__init__.py b/dist/ba_data/python-site-packages/discord/__init__.py new file mode 100644 index 0000000..e2c8101 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/__init__.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- + +""" +Discord API Wrapper +~~~~~~~~~~~~~~~~~~~ + +A basic wrapper for the Discord API. + +:copyright: (c) 2015-present Rapptz +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'discord' +__author__ = 'Rapptz' +__license__ = 'MIT' +__copyright__ = 'Copyright 2015-present Rapptz' +__version__ = '1.7.3' + +__path__ = __import__('pkgutil').extend_path(__path__, __name__) + +from collections import namedtuple +import logging + +from .client import Client +from .appinfo import AppInfo +from .user import User, ClientUser, Profile +from .emoji import Emoji +from .partial_emoji import PartialEmoji +from .activity import * +from .channel import * +from .guild import Guild +from .flags import * +from .relationship import Relationship +from .member import Member, VoiceState +from .message import * +from .asset import Asset +from .errors import * +from .calls import CallMessage, GroupCall +from .permissions import Permissions, PermissionOverwrite +from .role import Role, RoleTags +from .file import File +from .colour import Color, Colour +from .integrations import Integration, IntegrationAccount +from .invite import Invite, PartialInviteChannel, PartialInviteGuild +from .template import Template +from .widget import Widget, WidgetMember, WidgetChannel +from .object import Object +from .reaction import Reaction +from . import utils, opus, abc +from .enums import * +from .embeds import Embed +from .mentions import AllowedMentions +from .shard import AutoShardedClient, ShardInfo +from .player import * +from .webhook import * +from .voice_client import VoiceClient, VoiceProtocol +from .audit_logs import AuditLogChanges, AuditLogEntry, AuditLogDiff +from .raw_models import * +from .team import * +from .sticker import Sticker + +VersionInfo = namedtuple('VersionInfo', 'major minor micro releaselevel serial') + +version_info = VersionInfo(major=1, minor=7, micro=3, releaselevel='final', serial=0) + +logging.getLogger(__name__).addHandler(logging.NullHandler()) diff --git a/dist/ba_data/python-site-packages/discord/__main__.py b/dist/ba_data/python-site-packages/discord/__main__.py new file mode 100644 index 0000000..9252835 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/__main__.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import argparse +import sys +from pathlib import Path + +import discord +import pkg_resources +import aiohttp +import platform + +def show_version(): + entries = [] + + entries.append('- Python v{0.major}.{0.minor}.{0.micro}-{0.releaselevel}'.format(sys.version_info)) + version_info = discord.version_info + entries.append('- discord.py v{0.major}.{0.minor}.{0.micro}-{0.releaselevel}'.format(version_info)) + if version_info.releaselevel != 'final': + pkg = pkg_resources.get_distribution('discord.py') + if pkg: + entries.append(' - discord.py pkg_resources: v{0}'.format(pkg.version)) + + entries.append('- aiohttp v{0.__version__}'.format(aiohttp)) + uname = platform.uname() + entries.append('- system info: {0.system} {0.release} {0.version}'.format(uname)) + print('\n'.join(entries)) + +def core(parser, args): + if args.version: + show_version() + +bot_template = """#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from discord.ext import commands +import discord +import config + +class Bot(commands.{base}): + def __init__(self, **kwargs): + super().__init__(command_prefix=commands.when_mentioned_or('{prefix}'), **kwargs) + for cog in config.cogs: + try: + self.load_extension(cog) + except Exception as exc: + print('Could not load extension {{0}} due to {{1.__class__.__name__}}: {{1}}'.format(cog, exc)) + + async def on_ready(self): + print('Logged on as {{0}} (ID: {{0.id}})'.format(self.user)) + + +bot = Bot() + +# write general commands here + +bot.run(config.token) +""" + +gitignore_template = """# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# Our configuration files +config.py +""" + +cog_template = '''# -*- coding: utf-8 -*- + +from discord.ext import commands +import discord + +class {name}(commands.Cog{attrs}): + """The description for {name} goes here.""" + + def __init__(self, bot): + self.bot = bot +{extra} +def setup(bot): + bot.add_cog({name}(bot)) +''' + +cog_extras = ''' + def cog_unload(self): + # clean up logic goes here + pass + + async def cog_check(self, ctx): + # checks that apply to every command in here + return True + + async def bot_check(self, ctx): + # checks that apply to every command to the bot + return True + + async def bot_check_once(self, ctx): + # check that apply to every command but is guaranteed to be called only once + return True + + async def cog_command_error(self, ctx, error): + # error handling to every command in here + pass + + async def cog_before_invoke(self, ctx): + # called before a command is called here + pass + + async def cog_after_invoke(self, ctx): + # called after a command is called here + pass + +''' + + +# certain file names and directory names are forbidden +# see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx +# although some of this doesn't apply to Linux, we might as well be consistent +_base_table = { + '<': '-', + '>': '-', + ':': '-', + '"': '-', + # '/': '-', these are fine + # '\\': '-', + '|': '-', + '?': '-', + '*': '-', +} + +# NUL (0) and 1-31 are disallowed +_base_table.update((chr(i), None) for i in range(32)) + +translation_table = str.maketrans(_base_table) + +def to_path(parser, name, *, replace_spaces=False): + if isinstance(name, Path): + return name + + if sys.platform == 'win32': + forbidden = ('CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', \ + 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9') + if len(name) <= 4 and name.upper() in forbidden: + parser.error('invalid directory name given, use a different one') + + name = name.translate(translation_table) + if replace_spaces: + name = name.replace(' ', '-') + return Path(name) + +def newbot(parser, args): + new_directory = to_path(parser, args.directory) / to_path(parser, args.name) + + # as a note exist_ok for Path is a 3.5+ only feature + # since we already checked above that we're >3.5 + try: + new_directory.mkdir(exist_ok=True, parents=True) + except OSError as exc: + parser.error('could not create our bot directory ({})'.format(exc)) + + cogs = new_directory / 'cogs' + + try: + cogs.mkdir(exist_ok=True) + init = cogs / '__init__.py' + init.touch() + except OSError as exc: + print('warning: could not create cogs directory ({})'.format(exc)) + + try: + with open(str(new_directory / 'config.py'), 'w', encoding='utf-8') as fp: + fp.write('token = "place your token here"\ncogs = []\n') + except OSError as exc: + parser.error('could not create config file ({})'.format(exc)) + + try: + with open(str(new_directory / 'bot.py'), 'w', encoding='utf-8') as fp: + base = 'Bot' if not args.sharded else 'AutoShardedBot' + fp.write(bot_template.format(base=base, prefix=args.prefix)) + except OSError as exc: + parser.error('could not create bot file ({})'.format(exc)) + + if not args.no_git: + try: + with open(str(new_directory / '.gitignore'), 'w', encoding='utf-8') as fp: + fp.write(gitignore_template) + except OSError as exc: + print('warning: could not create .gitignore file ({})'.format(exc)) + + print('successfully made bot at', new_directory) + +def newcog(parser, args): + cog_dir = to_path(parser, args.directory) + try: + cog_dir.mkdir(exist_ok=True) + except OSError as exc: + print('warning: could not create cogs directory ({})'.format(exc)) + + directory = cog_dir / to_path(parser, args.name) + directory = directory.with_suffix('.py') + try: + with open(str(directory), 'w', encoding='utf-8') as fp: + attrs = '' + extra = cog_extras if args.full else '' + if args.class_name: + name = args.class_name + else: + name = str(directory.stem) + if '-' in name or '_' in name: + translation = str.maketrans('-_', ' ') + name = name.translate(translation).title().replace(' ', '') + else: + name = name.title() + + if args.display_name: + attrs += ', name="{}"'.format(args.display_name) + if args.hide_commands: + attrs += ', command_attrs=dict(hidden=True)' + fp.write(cog_template.format(name=name, extra=extra, attrs=attrs)) + except OSError as exc: + parser.error('could not create cog file ({})'.format(exc)) + else: + print('successfully made cog at', directory) + +def add_newbot_args(subparser): + parser = subparser.add_parser('newbot', help='creates a command bot project quickly') + parser.set_defaults(func=newbot) + + parser.add_argument('name', help='the bot project name') + parser.add_argument('directory', help='the directory to place it in (default: .)', nargs='?', default=Path.cwd()) + parser.add_argument('--prefix', help='the bot prefix (default: $)', default='$', metavar='') + parser.add_argument('--sharded', help='whether to use AutoShardedBot', action='store_true') + parser.add_argument('--no-git', help='do not create a .gitignore file', action='store_true', dest='no_git') + +def add_newcog_args(subparser): + parser = subparser.add_parser('newcog', help='creates a new cog template quickly') + parser.set_defaults(func=newcog) + + parser.add_argument('name', help='the cog name') + parser.add_argument('directory', help='the directory to place it in (default: cogs)', nargs='?', default=Path('cogs')) + parser.add_argument('--class-name', help='the class name of the cog (default: )', dest='class_name') + parser.add_argument('--display-name', help='the cog name (default: )') + parser.add_argument('--hide-commands', help='whether to hide all commands in the cog', action='store_true') + parser.add_argument('--full', help='add all special methods as well', action='store_true') + +def parse_args(): + parser = argparse.ArgumentParser(prog='discord', description='Tools for helping with discord.py') + parser.add_argument('-v', '--version', action='store_true', help='shows the library version') + parser.set_defaults(func=core) + + subparser = parser.add_subparsers(dest='subcommand', title='subcommands') + add_newbot_args(subparser) + add_newcog_args(subparser) + return parser, parser.parse_args() + +def main(): + parser, args = parse_args() + args.func(parser, args) + +if __name__ == '__main__': + main() diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d49455c Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/abc.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/abc.cpython-310.opt-1.pyc new file mode 100644 index 0000000..0e56894 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/abc.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/activity.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/activity.cpython-310.opt-1.pyc new file mode 100644 index 0000000..153dfdc Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/activity.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/appinfo.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/appinfo.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9d92586 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/appinfo.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/asset.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/asset.cpython-310.opt-1.pyc new file mode 100644 index 0000000..ff2526f Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/asset.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/audit_logs.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/audit_logs.cpython-310.opt-1.pyc new file mode 100644 index 0000000..428db82 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/audit_logs.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/backoff.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/backoff.cpython-310.opt-1.pyc new file mode 100644 index 0000000..dd90c6a Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/backoff.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/calls.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/calls.cpython-310.opt-1.pyc new file mode 100644 index 0000000..29e9852 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/calls.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/channel.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/channel.cpython-310.opt-1.pyc new file mode 100644 index 0000000..67b9bd0 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/channel.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/client.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/client.cpython-310.opt-1.pyc new file mode 100644 index 0000000..b77055a Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/client.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/colour.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/colour.cpython-310.opt-1.pyc new file mode 100644 index 0000000..e23cd1d Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/colour.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/context_managers.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/context_managers.cpython-310.opt-1.pyc new file mode 100644 index 0000000..2ce56e6 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/context_managers.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/embeds.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/embeds.cpython-310.opt-1.pyc new file mode 100644 index 0000000..229e5c4 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/embeds.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/emoji.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/emoji.cpython-310.opt-1.pyc new file mode 100644 index 0000000..3bb0482 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/emoji.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/enums.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/enums.cpython-310.opt-1.pyc new file mode 100644 index 0000000..9dee7de Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/enums.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/errors.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/errors.cpython-310.opt-1.pyc new file mode 100644 index 0000000..54535ce Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/errors.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/file.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/file.cpython-310.opt-1.pyc new file mode 100644 index 0000000..f07bb61 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/file.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/flags.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/flags.cpython-310.opt-1.pyc new file mode 100644 index 0000000..7b59cc3 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/flags.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/gateway.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/gateway.cpython-310.opt-1.pyc new file mode 100644 index 0000000..15b3079 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/gateway.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/guild.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/guild.cpython-310.opt-1.pyc new file mode 100644 index 0000000..986f672 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/guild.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/http.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/http.cpython-310.opt-1.pyc new file mode 100644 index 0000000..4e0713a Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/http.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/integrations.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/integrations.cpython-310.opt-1.pyc new file mode 100644 index 0000000..b422de4 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/integrations.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/invite.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/invite.cpython-310.opt-1.pyc new file mode 100644 index 0000000..055152a Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/invite.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/iterators.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/iterators.cpython-310.opt-1.pyc new file mode 100644 index 0000000..fd658f0 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/iterators.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/member.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/member.cpython-310.opt-1.pyc new file mode 100644 index 0000000..902a48d Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/member.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/mentions.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/mentions.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d54b604 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/mentions.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/message.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/message.cpython-310.opt-1.pyc new file mode 100644 index 0000000..b3ed6da Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/message.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/mixins.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/mixins.cpython-310.opt-1.pyc new file mode 100644 index 0000000..518ee20 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/mixins.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/object.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/object.cpython-310.opt-1.pyc new file mode 100644 index 0000000..d08f38e Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/object.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/oggparse.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/oggparse.cpython-310.opt-1.pyc new file mode 100644 index 0000000..1b0299b Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/oggparse.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/opus.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/opus.cpython-310.opt-1.pyc new file mode 100644 index 0000000..b49c348 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/opus.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/partial_emoji.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/partial_emoji.cpython-310.opt-1.pyc new file mode 100644 index 0000000..6c0366b Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/partial_emoji.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/permissions.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/permissions.cpython-310.opt-1.pyc new file mode 100644 index 0000000..a403674 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/permissions.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/player.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/player.cpython-310.opt-1.pyc new file mode 100644 index 0000000..ab08752 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/player.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/raw_models.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/raw_models.cpython-310.opt-1.pyc new file mode 100644 index 0000000..20d9766 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/raw_models.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/reaction.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/reaction.cpython-310.opt-1.pyc new file mode 100644 index 0000000..63adae6 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/reaction.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/relationship.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/relationship.cpython-310.opt-1.pyc new file mode 100644 index 0000000..69c89f2 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/relationship.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/role.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/role.cpython-310.opt-1.pyc new file mode 100644 index 0000000..e66902f Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/role.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/shard.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/shard.cpython-310.opt-1.pyc new file mode 100644 index 0000000..44d757b Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/shard.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/state.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/state.cpython-310.opt-1.pyc new file mode 100644 index 0000000..f8d661f Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/state.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/sticker.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/sticker.cpython-310.opt-1.pyc new file mode 100644 index 0000000..958965c Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/sticker.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/team.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/team.cpython-310.opt-1.pyc new file mode 100644 index 0000000..dc1bbb2 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/team.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/template.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/template.cpython-310.opt-1.pyc new file mode 100644 index 0000000..72154fb Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/template.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/user.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/user.cpython-310.opt-1.pyc new file mode 100644 index 0000000..11b876c Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/user.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/utils.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/utils.cpython-310.opt-1.pyc new file mode 100644 index 0000000..fde8821 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/utils.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/voice_client.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/voice_client.cpython-310.opt-1.pyc new file mode 100644 index 0000000..473311e Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/voice_client.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/webhook.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/webhook.cpython-310.opt-1.pyc new file mode 100644 index 0000000..2369892 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/webhook.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/__pycache__/widget.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/__pycache__/widget.cpython-310.opt-1.pyc new file mode 100644 index 0000000..5343859 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/__pycache__/widget.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/abc.py b/dist/ba_data/python-site-packages/discord/abc.py new file mode 100644 index 0000000..0e48a2f --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/abc.py @@ -0,0 +1,1294 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import abc +import sys +import copy +import asyncio + +from .iterators import HistoryIterator +from .context_managers import Typing +from .enums import ChannelType +from .errors import InvalidArgument, ClientException +from .mentions import AllowedMentions +from .permissions import PermissionOverwrite, Permissions +from .role import Role +from .invite import Invite +from .file import File +from .voice_client import VoiceClient, VoiceProtocol +from . import utils + +class _Undefined: + def __repr__(self): + return 'see-below' + +_undefined = _Undefined() + +class Snowflake(metaclass=abc.ABCMeta): + """An ABC that details the common operations on a Discord model. + + Almost all :ref:`Discord models ` meet this + abstract base class. + + If you want to create a snowflake on your own, consider using + :class:`.Object`. + + Attributes + ----------- + id: :class:`int` + The model's unique ID. + """ + __slots__ = () + + @property + @abc.abstractmethod + def created_at(self): + """:class:`datetime.datetime`: Returns the model's creation time as a naive datetime in UTC.""" + raise NotImplementedError + + @classmethod + def __subclasshook__(cls, C): + if cls is Snowflake: + mro = C.__mro__ + for attr in ('created_at', 'id'): + for base in mro: + if attr in base.__dict__: + break + else: + return NotImplemented + return True + return NotImplemented + +class User(metaclass=abc.ABCMeta): + """An ABC that details the common operations on a Discord user. + + The following implement this ABC: + + - :class:`~discord.User` + - :class:`~discord.ClientUser` + - :class:`~discord.Member` + + This ABC must also implement :class:`~discord.abc.Snowflake`. + + Attributes + ----------- + name: :class:`str` + The user's username. + discriminator: :class:`str` + The user's discriminator. + avatar: Optional[:class:`str`] + The avatar hash the user has. + bot: :class:`bool` + If the user is a bot account. + """ + __slots__ = () + + @property + @abc.abstractmethod + def display_name(self): + """:class:`str`: Returns the user's display name.""" + raise NotImplementedError + + @property + @abc.abstractmethod + def mention(self): + """:class:`str`: Returns a string that allows you to mention the given user.""" + raise NotImplementedError + + @classmethod + def __subclasshook__(cls, C): + if cls is User: + if Snowflake.__subclasshook__(C) is NotImplemented: + return NotImplemented + + mro = C.__mro__ + for attr in ('display_name', 'mention', 'name', 'avatar', 'discriminator', 'bot'): + for base in mro: + if attr in base.__dict__: + break + else: + return NotImplemented + return True + return NotImplemented + +class PrivateChannel(metaclass=abc.ABCMeta): + """An ABC that details the common operations on a private Discord channel. + + The following implement this ABC: + + - :class:`~discord.DMChannel` + - :class:`~discord.GroupChannel` + + This ABC must also implement :class:`~discord.abc.Snowflake`. + + Attributes + ----------- + me: :class:`~discord.ClientUser` + The user presenting yourself. + """ + __slots__ = () + + @classmethod + def __subclasshook__(cls, C): + if cls is PrivateChannel: + if Snowflake.__subclasshook__(C) is NotImplemented: + return NotImplemented + + mro = C.__mro__ + for base in mro: + if 'me' in base.__dict__: + return True + return NotImplemented + return NotImplemented + +class _Overwrites: + __slots__ = ('id', 'allow', 'deny', 'type') + + def __init__(self, **kwargs): + self.id = kwargs.pop('id') + self.allow = int(kwargs.pop('allow_new', 0)) + self.deny = int(kwargs.pop('deny_new', 0)) + self.type = sys.intern(kwargs.pop('type')) + + def _asdict(self): + return { + 'id': self.id, + 'allow': str(self.allow), + 'deny': str(self.deny), + 'type': self.type, + } + +class GuildChannel: + """An ABC that details the common operations on a Discord guild channel. + + The following implement this ABC: + + - :class:`~discord.TextChannel` + - :class:`~discord.VoiceChannel` + - :class:`~discord.CategoryChannel` + - :class:`~discord.StageChannel` + + This ABC must also implement :class:`~discord.abc.Snowflake`. + + Attributes + ----------- + name: :class:`str` + The channel name. + guild: :class:`~discord.Guild` + The guild the channel belongs to. + position: :class:`int` + The position in the channel list. This is a number that starts at 0. + e.g. the top channel is position 0. + """ + __slots__ = () + + def __str__(self): + return self.name + + @property + def _sorting_bucket(self): + raise NotImplementedError + + async def _move(self, position, parent_id=None, lock_permissions=False, *, reason): + if position < 0: + raise InvalidArgument('Channel position cannot be less than 0.') + + http = self._state.http + bucket = self._sorting_bucket + channels = [c for c in self.guild.channels if c._sorting_bucket == bucket] + + channels.sort(key=lambda c: c.position) + + try: + # remove ourselves from the channel list + channels.remove(self) + except ValueError: + # not there somehow lol + return + else: + index = next((i for i, c in enumerate(channels) if c.position >= position), len(channels)) + # add ourselves at our designated position + channels.insert(index, self) + + payload = [] + for index, c in enumerate(channels): + d = {'id': c.id, 'position': index} + if parent_id is not _undefined and c.id == self.id: + d.update(parent_id=parent_id, lock_permissions=lock_permissions) + payload.append(d) + + await http.bulk_channel_update(self.guild.id, payload, reason=reason) + self.position = position + if parent_id is not _undefined: + self.category_id = int(parent_id) if parent_id else None + + async def _edit(self, options, reason): + try: + parent = options.pop('category') + except KeyError: + parent_id = _undefined + else: + parent_id = parent and parent.id + + try: + options['rate_limit_per_user'] = options.pop('slowmode_delay') + except KeyError: + pass + + try: + rtc_region = options.pop('rtc_region') + except KeyError: + pass + else: + options['rtc_region'] = None if rtc_region is None else str(rtc_region) + + lock_permissions = options.pop('sync_permissions', False) + + try: + position = options.pop('position') + except KeyError: + if parent_id is not _undefined: + if lock_permissions: + category = self.guild.get_channel(parent_id) + options['permission_overwrites'] = [c._asdict() for c in category._overwrites] + options['parent_id'] = parent_id + elif lock_permissions and self.category_id is not None: + # if we're syncing permissions on a pre-existing channel category without changing it + # we need to update the permissions to point to the pre-existing category + category = self.guild.get_channel(self.category_id) + options['permission_overwrites'] = [c._asdict() for c in category._overwrites] + else: + await self._move(position, parent_id=parent_id, lock_permissions=lock_permissions, reason=reason) + + overwrites = options.get('overwrites', None) + if overwrites is not None: + perms = [] + for target, perm in overwrites.items(): + if not isinstance(perm, PermissionOverwrite): + raise InvalidArgument('Expected PermissionOverwrite received {0.__name__}'.format(type(perm))) + + allow, deny = perm.pair() + payload = { + 'allow': allow.value, + 'deny': deny.value, + 'id': target.id + } + + if isinstance(target, Role): + payload['type'] = 'role' + else: + payload['type'] = 'member' + + perms.append(payload) + options['permission_overwrites'] = perms + + try: + ch_type = options['type'] + except KeyError: + pass + else: + if not isinstance(ch_type, ChannelType): + raise InvalidArgument('type field must be of type ChannelType') + options['type'] = ch_type.value + + if options: + data = await self._state.http.edit_channel(self.id, reason=reason, **options) + self._update(self.guild, data) + + def _fill_overwrites(self, data): + self._overwrites = [] + everyone_index = 0 + everyone_id = self.guild.id + + for index, overridden in enumerate(data.get('permission_overwrites', [])): + overridden_id = int(overridden.pop('id')) + self._overwrites.append(_Overwrites(id=overridden_id, **overridden)) + + if overridden['type'] == 'member': + continue + + if overridden_id == everyone_id: + # the @everyone role is not guaranteed to be the first one + # in the list of permission overwrites, however the permission + # resolution code kind of requires that it is the first one in + # the list since it is special. So we need the index so we can + # swap it to be the first one. + everyone_index = index + + # do the swap + tmp = self._overwrites + if tmp: + tmp[everyone_index], tmp[0] = tmp[0], tmp[everyone_index] + + @property + def changed_roles(self): + """List[:class:`~discord.Role`]: Returns a list of roles that have been overridden from + their default values in the :attr:`~discord.Guild.roles` attribute.""" + ret = [] + g = self.guild + for overwrite in filter(lambda o: o.type == 'role', self._overwrites): + role = g.get_role(overwrite.id) + if role is None: + continue + + role = copy.copy(role) + role.permissions.handle_overwrite(overwrite.allow, overwrite.deny) + ret.append(role) + return ret + + @property + def mention(self): + """:class:`str`: The string that allows you to mention the channel.""" + return '<#%s>' % self.id + + @property + def created_at(self): + """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" + return utils.snowflake_time(self.id) + + def overwrites_for(self, obj): + """Returns the channel-specific overwrites for a member or a role. + + Parameters + ----------- + obj: Union[:class:`~discord.Role`, :class:`~discord.abc.User`] + The role or user denoting + whose overwrite to get. + + Returns + --------- + :class:`~discord.PermissionOverwrite` + The permission overwrites for this object. + """ + + if isinstance(obj, User): + predicate = lambda p: p.type == 'member' + elif isinstance(obj, Role): + predicate = lambda p: p.type == 'role' + else: + predicate = lambda p: True + + for overwrite in filter(predicate, self._overwrites): + if overwrite.id == obj.id: + allow = Permissions(overwrite.allow) + deny = Permissions(overwrite.deny) + return PermissionOverwrite.from_pair(allow, deny) + + return PermissionOverwrite() + + @property + def overwrites(self): + """Returns all of the channel's overwrites. + + This is returned as a dictionary where the key contains the target which + can be either a :class:`~discord.Role` or a :class:`~discord.Member` and the value is the + overwrite as a :class:`~discord.PermissionOverwrite`. + + Returns + -------- + Mapping[Union[:class:`~discord.Role`, :class:`~discord.Member`], :class:`~discord.PermissionOverwrite`] + The channel's permission overwrites. + """ + ret = {} + for ow in self._overwrites: + allow = Permissions(ow.allow) + deny = Permissions(ow.deny) + overwrite = PermissionOverwrite.from_pair(allow, deny) + + if ow.type == 'role': + target = self.guild.get_role(ow.id) + elif ow.type == 'member': + target = self.guild.get_member(ow.id) + + # TODO: There is potential data loss here in the non-chunked + # case, i.e. target is None because get_member returned nothing. + # This can be fixed with a slight breaking change to the return type, + # i.e. adding discord.Object to the list of it + # However, for now this is an acceptable compromise. + if target is not None: + ret[target] = overwrite + return ret + + @property + def category(self): + """Optional[:class:`~discord.CategoryChannel`]: The category this channel belongs to. + + If there is no category then this is ``None``. + """ + return self.guild.get_channel(self.category_id) + + @property + def permissions_synced(self): + """:class:`bool`: Whether or not the permissions for this channel are synced with the + category it belongs to. + + If there is no category then this is ``False``. + + .. versionadded:: 1.3 + """ + category = self.guild.get_channel(self.category_id) + return bool(category and category.overwrites == self.overwrites) + + def permissions_for(self, member): + """Handles permission resolution for the current :class:`~discord.Member`. + + This function takes into consideration the following cases: + + - Guild owner + - Guild roles + - Channel overrides + - Member overrides + + Parameters + ---------- + member: :class:`~discord.Member` + The member to resolve permissions for. + + Returns + ------- + :class:`~discord.Permissions` + The resolved permissions for the member. + """ + + # The current cases can be explained as: + # Guild owner get all permissions -- no questions asked. Otherwise... + # The @everyone role gets the first application. + # After that, the applied roles that the user has in the channel + # (or otherwise) are then OR'd together. + # After the role permissions are resolved, the member permissions + # have to take into effect. + # After all that is done.. you have to do the following: + + # If manage permissions is True, then all permissions are set to True. + + # The operation first takes into consideration the denied + # and then the allowed. + + if self.guild.owner_id == member.id: + return Permissions.all() + + default = self.guild.default_role + base = Permissions(default.permissions.value) + roles = member._roles + get_role = self.guild.get_role + + # Apply guild roles that the member has. + for role_id in roles: + role = get_role(role_id) + if role is not None: + base.value |= role._permissions + + # Guild-wide Administrator -> True for everything + # Bypass all channel-specific overrides + if base.administrator: + return Permissions.all() + + # Apply @everyone allow/deny first since it's special + try: + maybe_everyone = self._overwrites[0] + if maybe_everyone.id == self.guild.id: + base.handle_overwrite(allow=maybe_everyone.allow, deny=maybe_everyone.deny) + remaining_overwrites = self._overwrites[1:] + else: + remaining_overwrites = self._overwrites + except IndexError: + remaining_overwrites = self._overwrites + + denies = 0 + allows = 0 + + # Apply channel specific role permission overwrites + for overwrite in remaining_overwrites: + if overwrite.type == 'role' and roles.has(overwrite.id): + denies |= overwrite.deny + allows |= overwrite.allow + + base.handle_overwrite(allow=allows, deny=denies) + + # Apply member specific permission overwrites + for overwrite in remaining_overwrites: + if overwrite.type == 'member' and overwrite.id == member.id: + base.handle_overwrite(allow=overwrite.allow, deny=overwrite.deny) + break + + # if you can't send a message in a channel then you can't have certain + # permissions as well + if not base.send_messages: + base.send_tts_messages = False + base.mention_everyone = False + base.embed_links = False + base.attach_files = False + + # if you can't read a channel then you have no permissions there + if not base.read_messages: + denied = Permissions.all_channel() + base.value &= ~denied.value + + return base + + async def delete(self, *, reason=None): + """|coro| + + Deletes the channel. + + You must have :attr:`~Permissions.manage_channels` permission to use this. + + Parameters + ----------- + reason: Optional[:class:`str`] + The reason for deleting this channel. + Shows up on the audit log. + + Raises + ------- + ~discord.Forbidden + You do not have proper permissions to delete the channel. + ~discord.NotFound + The channel was not found or was already deleted. + ~discord.HTTPException + Deleting the channel failed. + """ + await self._state.http.delete_channel(self.id, reason=reason) + + async def set_permissions(self, target, *, overwrite=_undefined, reason=None, **permissions): + r"""|coro| + + Sets the channel specific permission overwrites for a target in the + channel. + + The ``target`` parameter should either be a :class:`~discord.Member` or a + :class:`~discord.Role` that belongs to guild. + + The ``overwrite`` parameter, if given, must either be ``None`` or + :class:`~discord.PermissionOverwrite`. For convenience, you can pass in + keyword arguments denoting :class:`~discord.Permissions` attributes. If this is + done, then you cannot mix the keyword arguments with the ``overwrite`` + parameter. + + If the ``overwrite`` parameter is ``None``, then the permission + overwrites are deleted. + + You must have the :attr:`~Permissions.manage_roles` permission to use this. + + Examples + ---------- + + Setting allow and deny: :: + + await message.channel.set_permissions(message.author, read_messages=True, + send_messages=False) + + Deleting overwrites :: + + await channel.set_permissions(member, overwrite=None) + + Using :class:`~discord.PermissionOverwrite` :: + + overwrite = discord.PermissionOverwrite() + overwrite.send_messages = False + overwrite.read_messages = True + await channel.set_permissions(member, overwrite=overwrite) + + Parameters + ----------- + target: Union[:class:`~discord.Member`, :class:`~discord.Role`] + The member or role to overwrite permissions for. + overwrite: Optional[:class:`~discord.PermissionOverwrite`] + The permissions to allow and deny to the target, or ``None`` to + delete the overwrite. + \*\*permissions + A keyword argument list of permissions to set for ease of use. + Cannot be mixed with ``overwrite``. + reason: Optional[:class:`str`] + The reason for doing this action. Shows up on the audit log. + + Raises + ------- + ~discord.Forbidden + You do not have permissions to edit channel specific permissions. + ~discord.HTTPException + Editing channel specific permissions failed. + ~discord.NotFound + The role or member being edited is not part of the guild. + ~discord.InvalidArgument + The overwrite parameter invalid or the target type was not + :class:`~discord.Role` or :class:`~discord.Member`. + """ + + http = self._state.http + + if isinstance(target, User): + perm_type = 'member' + elif isinstance(target, Role): + perm_type = 'role' + else: + raise InvalidArgument('target parameter must be either Member or Role') + + if isinstance(overwrite, _Undefined): + if len(permissions) == 0: + raise InvalidArgument('No overwrite provided.') + try: + overwrite = PermissionOverwrite(**permissions) + except (ValueError, TypeError): + raise InvalidArgument('Invalid permissions given to keyword arguments.') + else: + if len(permissions) > 0: + raise InvalidArgument('Cannot mix overwrite and keyword arguments.') + + # TODO: wait for event + + if overwrite is None: + await http.delete_channel_permissions(self.id, target.id, reason=reason) + elif isinstance(overwrite, PermissionOverwrite): + (allow, deny) = overwrite.pair() + await http.edit_channel_permissions(self.id, target.id, allow.value, deny.value, perm_type, reason=reason) + else: + raise InvalidArgument('Invalid overwrite type provided.') + + async def _clone_impl(self, base_attrs, *, name=None, reason=None): + base_attrs['permission_overwrites'] = [ + x._asdict() for x in self._overwrites + ] + base_attrs['parent_id'] = self.category_id + base_attrs['name'] = name or self.name + guild_id = self.guild.id + cls = self.__class__ + data = await self._state.http.create_channel(guild_id, self.type.value, reason=reason, **base_attrs) + obj = cls(state=self._state, guild=self.guild, data=data) + + # temporarily add it to the cache + self.guild._channels[obj.id] = obj + return obj + + async def clone(self, *, name=None, reason=None): + """|coro| + + Clones this channel. This creates a channel with the same properties + as this channel. + + You must have the :attr:`~discord.Permissions.manage_channels` permission to + do this. + + .. versionadded:: 1.1 + + Parameters + ------------ + name: Optional[:class:`str`] + The name of the new channel. If not provided, defaults to this + channel name. + reason: Optional[:class:`str`] + The reason for cloning this channel. Shows up on the audit log. + + Raises + ------- + ~discord.Forbidden + You do not have the proper permissions to create this channel. + ~discord.HTTPException + Creating the channel failed. + + Returns + -------- + :class:`.abc.GuildChannel` + The channel that was created. + """ + raise NotImplementedError + + async def move(self, **kwargs): + """|coro| + + A rich interface to help move a channel relative to other channels. + + If exact position movement is required, :meth:`edit` should be used instead. + + You must have the :attr:`~discord.Permissions.manage_channels` permission to + do this. + + .. note:: + + Voice channels will always be sorted below text channels. + This is a Discord limitation. + + .. versionadded:: 1.7 + + Parameters + ------------ + beginning: :class:`bool` + Whether to move the channel to the beginning of the + channel list (or category if given). + This is mutually exclusive with ``end``, ``before``, and ``after``. + end: :class:`bool` + Whether to move the channel to the end of the + channel list (or category if given). + This is mutually exclusive with ``beginning``, ``before``, and ``after``. + before: :class:`~discord.abc.Snowflake` + The channel that should be before our current channel. + This is mutually exclusive with ``beginning``, ``end``, and ``after``. + after: :class:`~discord.abc.Snowflake` + The channel that should be after our current channel. + This is mutually exclusive with ``beginning``, ``end``, and ``before``. + offset: :class:`int` + The number of channels to offset the move by. For example, + an offset of ``2`` with ``beginning=True`` would move + it 2 after the beginning. A positive number moves it below + while a negative number moves it above. Note that this + number is relative and computed after the ``beginning``, + ``end``, ``before``, and ``after`` parameters. + category: Optional[:class:`~discord.abc.Snowflake`] + The category to move this channel under. + If ``None`` is given then it moves it out of the category. + This parameter is ignored if moving a category channel. + sync_permissions: :class:`bool` + Whether to sync the permissions with the category (if given). + reason: :class:`str` + The reason for the move. + + Raises + ------- + InvalidArgument + An invalid position was given or a bad mix of arguments were passed. + Forbidden + You do not have permissions to move the channel. + HTTPException + Moving the channel failed. + """ + + if not kwargs: + return + + beginning, end = kwargs.get('beginning'), kwargs.get('end') + before, after = kwargs.get('before'), kwargs.get('after') + offset = kwargs.get('offset', 0) + if sum(bool(a) for a in (beginning, end, before, after)) > 1: + raise InvalidArgument('Only one of [before, after, end, beginning] can be used.') + + bucket = self._sorting_bucket + parent_id = kwargs.get('category', ...) + if parent_id not in (..., None): + parent_id = parent_id.id + channels = [ + ch + for ch in self.guild.channels + if ch._sorting_bucket == bucket + and ch.category_id == parent_id + ] + else: + channels = [ + ch + for ch in self.guild.channels + if ch._sorting_bucket == bucket + and ch.category_id == self.category_id + ] + + channels.sort(key=lambda c: (c.position, c.id)) + + try: + # Try to remove ourselves from the channel list + channels.remove(self) + except ValueError: + # If we're not there then it's probably due to not being in the category + pass + + index = None + if beginning: + index = 0 + elif end: + index = len(channels) + elif before: + index = next((i for i, c in enumerate(channels) if c.id == before.id), None) + elif after: + index = next((i + 1 for i, c in enumerate(channels) if c.id == after.id), None) + + if index is None: + raise InvalidArgument('Could not resolve appropriate move position') + + channels.insert(max((index + offset), 0), self) + payload = [] + lock_permissions = kwargs.get('sync_permissions', False) + reason = kwargs.get('reason') + for index, channel in enumerate(channels): + d = { 'id': channel.id, 'position': index } + if parent_id is not ... and channel.id == self.id: + d.update(parent_id=parent_id, lock_permissions=lock_permissions) + payload.append(d) + + await self._state.http.bulk_channel_update(self.guild.id, payload, reason=reason) + + + async def create_invite(self, *, reason=None, **fields): + """|coro| + + Creates an instant invite from a text or voice channel. + + You must have the :attr:`~Permissions.create_instant_invite` permission to + do this. + + Parameters + ------------ + max_age: :class:`int` + How long the invite should last in seconds. If it's 0 then the invite + doesn't expire. Defaults to ``0``. + max_uses: :class:`int` + How many uses the invite could be used for. If it's 0 then there + are unlimited uses. Defaults to ``0``. + temporary: :class:`bool` + Denotes that the invite grants temporary membership + (i.e. they get kicked after they disconnect). Defaults to ``False``. + unique: :class:`bool` + Indicates if a unique invite URL should be created. Defaults to True. + If this is set to ``False`` then it will return a previously created + invite. + reason: Optional[:class:`str`] + The reason for creating this invite. Shows up on the audit log. + + Raises + ------- + ~discord.HTTPException + Invite creation failed. + + ~discord.NotFound + The channel that was passed is a category or an invalid channel. + + Returns + -------- + :class:`~discord.Invite` + The invite that was created. + """ + + data = await self._state.http.create_invite(self.id, reason=reason, **fields) + return Invite.from_incomplete(data=data, state=self._state) + + async def invites(self): + """|coro| + + Returns a list of all active instant invites from this channel. + + You must have :attr:`~Permissions.manage_channels` to get this information. + + Raises + ------- + ~discord.Forbidden + You do not have proper permissions to get the information. + ~discord.HTTPException + An error occurred while fetching the information. + + Returns + ------- + List[:class:`~discord.Invite`] + The list of invites that are currently active. + """ + + state = self._state + data = await state.http.invites_from_channel(self.id) + result = [] + + for invite in data: + invite['channel'] = self + invite['guild'] = self.guild + result.append(Invite(state=state, data=invite)) + + return result + +class Messageable(metaclass=abc.ABCMeta): + """An ABC that details the common operations on a model that can send messages. + + The following implement this ABC: + + - :class:`~discord.TextChannel` + - :class:`~discord.DMChannel` + - :class:`~discord.GroupChannel` + - :class:`~discord.User` + - :class:`~discord.Member` + - :class:`~discord.ext.commands.Context` + """ + + __slots__ = () + + @abc.abstractmethod + async def _get_channel(self): + raise NotImplementedError + + async def send(self, content=None, *, tts=False, embed=None, file=None, + files=None, delete_after=None, nonce=None, + allowed_mentions=None, reference=None, + mention_author=None): + """|coro| + + Sends a message to the destination with the content given. + + The content must be a type that can convert to a string through ``str(content)``. + If the content is set to ``None`` (the default), then the ``embed`` parameter must + be provided. + + To upload a single file, the ``file`` parameter should be used with a + single :class:`~discord.File` object. To upload multiple files, the ``files`` + parameter should be used with a :class:`list` of :class:`~discord.File` objects. + **Specifying both parameters will lead to an exception**. + + If the ``embed`` parameter is provided, it must be of type :class:`~discord.Embed` and + it must be a rich embed type. + + Parameters + ------------ + content: :class:`str` + The content of the message to send. + tts: :class:`bool` + Indicates if the message should be sent using text-to-speech. + embed: :class:`~discord.Embed` + The rich embed for the content. + file: :class:`~discord.File` + The file to upload. + files: List[:class:`~discord.File`] + A list of files to upload. Must be a maximum of 10. + nonce: :class:`int` + The nonce to use for sending this message. If the message was successfully sent, + then the message will have a nonce with this value. + delete_after: :class:`float` + If provided, the number of seconds to wait in the background + before deleting the message we just sent. If the deletion fails, + then it is silently ignored. + allowed_mentions: :class:`~discord.AllowedMentions` + Controls the mentions being processed in this message. If this is + passed, then the object is merged with :attr:`~discord.Client.allowed_mentions`. + The merging behaviour only overrides attributes that have been explicitly passed + to the object, otherwise it uses the attributes set in :attr:`~discord.Client.allowed_mentions`. + If no object is passed at all then the defaults given by :attr:`~discord.Client.allowed_mentions` + are used instead. + + .. versionadded:: 1.4 + + reference: Union[:class:`~discord.Message`, :class:`~discord.MessageReference`] + A reference to the :class:`~discord.Message` to which you are replying, this can be created using + :meth:`~discord.Message.to_reference` or passed directly as a :class:`~discord.Message`. You can control + whether this mentions the author of the referenced message using the :attr:`~discord.AllowedMentions.replied_user` + attribute of ``allowed_mentions`` or by setting ``mention_author``. + + .. versionadded:: 1.6 + + mention_author: Optional[:class:`bool`] + If set, overrides the :attr:`~discord.AllowedMentions.replied_user` attribute of ``allowed_mentions``. + + .. versionadded:: 1.6 + + Raises + -------- + ~discord.HTTPException + Sending the message failed. + ~discord.Forbidden + You do not have the proper permissions to send the message. + ~discord.InvalidArgument + The ``files`` list is not of the appropriate size, + you specified both ``file`` and ``files``, + or the ``reference`` object is not a :class:`~discord.Message` + or :class:`~discord.MessageReference`. + + Returns + --------- + :class:`~discord.Message` + The message that was sent. + """ + + channel = await self._get_channel() + state = self._state + content = str(content) if content is not None else None + if embed is not None: + embed = embed.to_dict() + + if allowed_mentions is not None: + if state.allowed_mentions is not None: + allowed_mentions = state.allowed_mentions.merge(allowed_mentions).to_dict() + else: + allowed_mentions = allowed_mentions.to_dict() + else: + allowed_mentions = state.allowed_mentions and state.allowed_mentions.to_dict() + + if mention_author is not None: + allowed_mentions = allowed_mentions or AllowedMentions().to_dict() + allowed_mentions['replied_user'] = bool(mention_author) + + if reference is not None: + try: + reference = reference.to_message_reference_dict() + except AttributeError: + raise InvalidArgument('reference parameter must be Message or MessageReference') from None + + if file is not None and files is not None: + raise InvalidArgument('cannot pass both file and files parameter to send()') + + if file is not None: + if not isinstance(file, File): + raise InvalidArgument('file parameter must be File') + + try: + data = await state.http.send_files(channel.id, files=[file], allowed_mentions=allowed_mentions, + content=content, tts=tts, embed=embed, nonce=nonce, + message_reference=reference) + finally: + file.close() + + elif files is not None: + if len(files) > 10: + raise InvalidArgument('files parameter must be a list of up to 10 elements') + elif not all(isinstance(file, File) for file in files): + raise InvalidArgument('files parameter must be a list of File') + + try: + data = await state.http.send_files(channel.id, files=files, content=content, tts=tts, + embed=embed, nonce=nonce, allowed_mentions=allowed_mentions, + message_reference=reference) + finally: + for f in files: + f.close() + else: + data = await state.http.send_message(channel.id, content, tts=tts, embed=embed, + nonce=nonce, allowed_mentions=allowed_mentions, + message_reference=reference) + + ret = state.create_message(channel=channel, data=data) + if delete_after is not None: + await ret.delete(delay=delete_after) + return ret + + async def trigger_typing(self): + """|coro| + + Triggers a *typing* indicator to the destination. + + *Typing* indicator will go away after 10 seconds, or after a message is sent. + """ + + channel = await self._get_channel() + await self._state.http.send_typing(channel.id) + + def typing(self): + """Returns a context manager that allows you to type for an indefinite period of time. + + This is useful for denoting long computations in your bot. + + .. note:: + + This is both a regular context manager and an async context manager. + This means that both ``with`` and ``async with`` work with this. + + Example Usage: :: + + async with channel.typing(): + # do expensive stuff here + await channel.send('done!') + + """ + return Typing(self) + + async def fetch_message(self, id): + """|coro| + + Retrieves a single :class:`~discord.Message` from the destination. + + This can only be used by bot accounts. + + Parameters + ------------ + id: :class:`int` + The message ID to look for. + + Raises + -------- + ~discord.NotFound + The specified message was not found. + ~discord.Forbidden + You do not have the permissions required to get a message. + ~discord.HTTPException + Retrieving the message failed. + + Returns + -------- + :class:`~discord.Message` + The message asked for. + """ + + channel = await self._get_channel() + data = await self._state.http.get_message(channel.id, id) + return self._state.create_message(channel=channel, data=data) + + async def pins(self): + """|coro| + + Retrieves all messages that are currently pinned in the channel. + + .. note:: + + Due to a limitation with the Discord API, the :class:`.Message` + objects returned by this method do not contain complete + :attr:`.Message.reactions` data. + + Raises + ------- + ~discord.HTTPException + Retrieving the pinned messages failed. + + Returns + -------- + List[:class:`~discord.Message`] + The messages that are currently pinned. + """ + + channel = await self._get_channel() + state = self._state + data = await state.http.pins_from(channel.id) + return [state.create_message(channel=channel, data=m) for m in data] + + def history(self, *, limit=100, before=None, after=None, around=None, oldest_first=None): + """Returns an :class:`~discord.AsyncIterator` that enables receiving the destination's message history. + + You must have :attr:`~Permissions.read_message_history` permissions to use this. + + Examples + --------- + + Usage :: + + counter = 0 + async for message in channel.history(limit=200): + if message.author == client.user: + counter += 1 + + Flattening into a list: :: + + messages = await channel.history(limit=123).flatten() + # messages is now a list of Message... + + All parameters are optional. + + Parameters + ----------- + limit: Optional[:class:`int`] + The number of messages to retrieve. + If ``None``, retrieves every message in the channel. Note, however, + that this would make it a slow operation. + before: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]] + Retrieve messages before this date or message. + If a date is provided it must be a timezone-naive datetime representing UTC time. + after: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]] + Retrieve messages after this date or message. + If a date is provided it must be a timezone-naive datetime representing UTC time. + around: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]] + Retrieve messages around this date or message. + If a date is provided it must be a timezone-naive datetime representing UTC time. + When using this argument, the maximum limit is 101. Note that if the limit is an + even number then this will return at most limit + 1 messages. + oldest_first: Optional[:class:`bool`] + If set to ``True``, return messages in oldest->newest order. Defaults to ``True`` if + ``after`` is specified, otherwise ``False``. + + Raises + ------ + ~discord.Forbidden + You do not have permissions to get channel message history. + ~discord.HTTPException + The request to get message history failed. + + Yields + ------- + :class:`~discord.Message` + The message with the message data parsed. + """ + return HistoryIterator(self, limit=limit, before=before, after=after, around=around, oldest_first=oldest_first) + +class Connectable(metaclass=abc.ABCMeta): + """An ABC that details the common operations on a channel that can + connect to a voice server. + + The following implement this ABC: + + - :class:`~discord.VoiceChannel` + """ + __slots__ = () + + @abc.abstractmethod + def _get_voice_client_key(self): + raise NotImplementedError + + @abc.abstractmethod + def _get_voice_state_pair(self): + raise NotImplementedError + + async def connect(self, *, timeout=60.0, reconnect=True, cls=VoiceClient): + """|coro| + + Connects to voice and creates a :class:`VoiceClient` to establish + your connection to the voice server. + + Parameters + ----------- + timeout: :class:`float` + The timeout in seconds to wait for the voice endpoint. + reconnect: :class:`bool` + Whether the bot should automatically attempt + a reconnect if a part of the handshake fails + or the gateway goes down. + cls: Type[:class:`VoiceProtocol`] + A type that subclasses :class:`~discord.VoiceProtocol` to connect with. + Defaults to :class:`~discord.VoiceClient`. + + Raises + ------- + asyncio.TimeoutError + Could not connect to the voice channel in time. + ~discord.ClientException + You are already connected to a voice channel. + ~discord.opus.OpusNotLoaded + The opus library has not been loaded. + + Returns + -------- + :class:`~discord.VoiceProtocol` + A voice client that is fully connected to the voice server. + """ + + key_id, _ = self._get_voice_client_key() + state = self._state + + if state._get_voice_client(key_id): + raise ClientException('Already connected to a voice channel.') + + client = state._get_client() + voice = cls(client, self) + + if not isinstance(voice, VoiceProtocol): + raise TypeError('Type must meet VoiceProtocol abstract base class.') + + state._add_voice_client(key_id, voice) + + try: + await voice.connect(timeout=timeout, reconnect=reconnect) + except asyncio.TimeoutError: + try: + await voice.disconnect(force=True) + except Exception: + # we don't care if disconnect failed because connection failed + pass + raise # re-raise + + return voice diff --git a/dist/ba_data/python-site-packages/discord/activity.py b/dist/ba_data/python-site-packages/discord/activity.py new file mode 100644 index 0000000..cf5192a --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/activity.py @@ -0,0 +1,773 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import datetime + +from .asset import Asset +from .enums import ActivityType, try_enum +from .colour import Colour +from .partial_emoji import PartialEmoji +from .utils import _get_as_snowflake + +__all__ = ( + 'BaseActivity', + 'Activity', + 'Streaming', + 'Game', + 'Spotify', + 'CustomActivity', +) + +"""If curious, this is the current schema for an activity. + +It's fairly long so I will document it here: + +All keys are optional. + +state: str (max: 128), +details: str (max: 128) +timestamps: dict + start: int (min: 1) + end: int (min: 1) +assets: dict + large_image: str (max: 32) + large_text: str (max: 128) + small_image: str (max: 32) + small_text: str (max: 128) +party: dict + id: str (max: 128), + size: List[int] (max-length: 2) + elem: int (min: 1) +secrets: dict + match: str (max: 128) + join: str (max: 128) + spectate: str (max: 128) +instance: bool +application_id: str +name: str (max: 128) +url: str +type: int +sync_id: str +session_id: str +flags: int + +There are also activity flags which are mostly uninteresting for the library atm. + +t.ActivityFlags = { + INSTANCE: 1, + JOIN: 2, + SPECTATE: 4, + JOIN_REQUEST: 8, + SYNC: 16, + PLAY: 32 +} +""" + +class BaseActivity: + """The base activity that all user-settable activities inherit from. + A user-settable activity is one that can be used in :meth:`Client.change_presence`. + + The following types currently count as user-settable: + + - :class:`Activity` + - :class:`Game` + - :class:`Streaming` + - :class:`CustomActivity` + + Note that although these types are considered user-settable by the library, + Discord typically ignores certain combinations of activity depending on + what is currently set. This behaviour may change in the future so there are + no guarantees on whether Discord will actually let you set these types. + + .. versionadded:: 1.3 + """ + __slots__ = ('_created_at',) + + def __init__(self, **kwargs): + self._created_at = kwargs.pop('created_at', None) + + @property + def created_at(self): + """Optional[:class:`datetime.datetime`]: When the user started doing this activity in UTC. + + .. versionadded:: 1.3 + """ + if self._created_at is not None: + return datetime.datetime.utcfromtimestamp(self._created_at / 1000) + +class Activity(BaseActivity): + """Represents an activity in Discord. + + This could be an activity such as streaming, playing, listening + or watching. + + For memory optimisation purposes, some activities are offered in slimmed + down versions: + + - :class:`Game` + - :class:`Streaming` + + Attributes + ------------ + application_id: :class:`int` + The application ID of the game. + name: :class:`str` + The name of the activity. + url: :class:`str` + A stream URL that the activity could be doing. + type: :class:`ActivityType` + The type of activity currently being done. + state: :class:`str` + The user's current state. For example, "In Game". + details: :class:`str` + The detail of the user's current activity. + timestamps: :class:`dict` + A dictionary of timestamps. It contains the following optional keys: + + - ``start``: Corresponds to when the user started doing the + activity in milliseconds since Unix epoch. + - ``end``: Corresponds to when the user will finish doing the + activity in milliseconds since Unix epoch. + + assets: :class:`dict` + A dictionary representing the images and their hover text of an activity. + It contains the following optional keys: + + - ``large_image``: A string representing the ID for the large image asset. + - ``large_text``: A string representing the text when hovering over the large image asset. + - ``small_image``: A string representing the ID for the small image asset. + - ``small_text``: A string representing the text when hovering over the small image asset. + + party: :class:`dict` + A dictionary representing the activity party. It contains the following optional keys: + + - ``id``: A string representing the party ID. + - ``size``: A list of up to two integer elements denoting (current_size, maximum_size). + emoji: Optional[:class:`PartialEmoji`] + The emoji that belongs to this activity. + """ + + __slots__ = ('state', 'details', '_created_at', 'timestamps', 'assets', 'party', + 'flags', 'sync_id', 'session_id', 'type', 'name', 'url', + 'application_id', 'emoji') + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.state = kwargs.pop('state', None) + self.details = kwargs.pop('details', None) + self.timestamps = kwargs.pop('timestamps', {}) + self.assets = kwargs.pop('assets', {}) + self.party = kwargs.pop('party', {}) + self.application_id = _get_as_snowflake(kwargs, 'application_id') + self.name = kwargs.pop('name', None) + self.url = kwargs.pop('url', None) + self.flags = kwargs.pop('flags', 0) + self.sync_id = kwargs.pop('sync_id', None) + self.session_id = kwargs.pop('session_id', None) + self.type = try_enum(ActivityType, kwargs.pop('type', -1)) + emoji = kwargs.pop('emoji', None) + if emoji is not None: + self.emoji = PartialEmoji.from_dict(emoji) + else: + self.emoji = None + + def __repr__(self): + attrs = ( + 'type', + 'name', + 'url', + 'details', + 'application_id', + 'session_id', + 'emoji', + ) + mapped = ' '.join('%s=%r' % (attr, getattr(self, attr)) for attr in attrs) + return '' % mapped + + def to_dict(self): + ret = {} + for attr in self.__slots__: + value = getattr(self, attr, None) + if value is None: + continue + + if isinstance(value, dict) and len(value) == 0: + continue + + ret[attr] = value + ret['type'] = int(self.type) + if self.emoji: + ret['emoji'] = self.emoji.to_dict() + return ret + + @property + def start(self): + """Optional[:class:`datetime.datetime`]: When the user started doing this activity in UTC, if applicable.""" + try: + return datetime.datetime.utcfromtimestamp(self.timestamps['start'] / 1000) + except KeyError: + return None + + @property + def end(self): + """Optional[:class:`datetime.datetime`]: When the user will stop doing this activity in UTC, if applicable.""" + try: + return datetime.datetime.utcfromtimestamp(self.timestamps['end'] / 1000) + except KeyError: + return None + + @property + def large_image_url(self): + """Optional[:class:`str`]: Returns a URL pointing to the large image asset of this activity if applicable.""" + if self.application_id is None: + return None + + try: + large_image = self.assets['large_image'] + except KeyError: + return None + else: + return Asset.BASE + '/app-assets/{0}/{1}.png'.format(self.application_id, large_image) + + @property + def small_image_url(self): + """Optional[:class:`str`]: Returns a URL pointing to the small image asset of this activity if applicable.""" + if self.application_id is None: + return None + + try: + small_image = self.assets['small_image'] + except KeyError: + return None + else: + return Asset.BASE + '/app-assets/{0}/{1}.png'.format(self.application_id, small_image) + @property + def large_image_text(self): + """Optional[:class:`str`]: Returns the large image asset hover text of this activity if applicable.""" + return self.assets.get('large_text', None) + + @property + def small_image_text(self): + """Optional[:class:`str`]: Returns the small image asset hover text of this activity if applicable.""" + return self.assets.get('small_text', None) + + +class Game(BaseActivity): + """A slimmed down version of :class:`Activity` that represents a Discord game. + + This is typically displayed via **Playing** on the official Discord client. + + .. container:: operations + + .. describe:: x == y + + Checks if two games are equal. + + .. describe:: x != y + + Checks if two games are not equal. + + .. describe:: hash(x) + + Returns the game's hash. + + .. describe:: str(x) + + Returns the game's name. + + Parameters + ----------- + name: :class:`str` + The game's name. + start: Optional[:class:`datetime.datetime`] + A naive UTC timestamp representing when the game started. Keyword-only parameter. Ignored for bots. + end: Optional[:class:`datetime.datetime`] + A naive UTC timestamp representing when the game ends. Keyword-only parameter. Ignored for bots. + + Attributes + ----------- + name: :class:`str` + The game's name. + """ + + __slots__ = ('name', '_end', '_start') + + def __init__(self, name, **extra): + super().__init__(**extra) + self.name = name + + try: + timestamps = extra['timestamps'] + except KeyError: + self._extract_timestamp(extra, 'start') + self._extract_timestamp(extra, 'end') + else: + self._start = timestamps.get('start', 0) + self._end = timestamps.get('end', 0) + + def _extract_timestamp(self, data, key): + try: + dt = data[key] + except KeyError: + setattr(self, '_' + key, 0) + else: + setattr(self, '_' + key, dt.timestamp() * 1000.0) + + @property + def type(self): + """:class:`ActivityType`: Returns the game's type. This is for compatibility with :class:`Activity`. + + It always returns :attr:`ActivityType.playing`. + """ + return ActivityType.playing + + @property + def start(self): + """Optional[:class:`datetime.datetime`]: When the user started playing this game in UTC, if applicable.""" + if self._start: + return datetime.datetime.utcfromtimestamp(self._start / 1000) + return None + + @property + def end(self): + """Optional[:class:`datetime.datetime`]: When the user will stop playing this game in UTC, if applicable.""" + if self._end: + return datetime.datetime.utcfromtimestamp(self._end / 1000) + return None + + def __str__(self): + return str(self.name) + + def __repr__(self): + return ''.format(self) + + def to_dict(self): + timestamps = {} + if self._start: + timestamps['start'] = self._start + + if self._end: + timestamps['end'] = self._end + + return { + 'type': ActivityType.playing.value, + 'name': str(self.name), + 'timestamps': timestamps + } + + def __eq__(self, other): + return isinstance(other, Game) and other.name == self.name + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash(self.name) + +class Streaming(BaseActivity): + """A slimmed down version of :class:`Activity` that represents a Discord streaming status. + + This is typically displayed via **Streaming** on the official Discord client. + + .. container:: operations + + .. describe:: x == y + + Checks if two streams are equal. + + .. describe:: x != y + + Checks if two streams are not equal. + + .. describe:: hash(x) + + Returns the stream's hash. + + .. describe:: str(x) + + Returns the stream's name. + + Attributes + ----------- + platform: :class:`str` + Where the user is streaming from (ie. YouTube, Twitch). + + .. versionadded:: 1.3 + + name: Optional[:class:`str`] + The stream's name. + details: Optional[:class:`str`] + An alias for :attr:`name` + game: Optional[:class:`str`] + The game being streamed. + + .. versionadded:: 1.3 + + url: :class:`str` + The stream's URL. + assets: :class:`dict` + A dictionary comprising of similar keys than those in :attr:`Activity.assets`. + """ + + __slots__ = ('platform', 'name', 'game', 'url', 'details', 'assets') + + def __init__(self, *, name, url, **extra): + super().__init__(**extra) + self.platform = name + self.name = extra.pop('details', name) + self.game = extra.pop('state', None) + self.url = url + self.details = extra.pop('details', self.name) # compatibility + self.assets = extra.pop('assets', {}) + + @property + def type(self): + """:class:`ActivityType`: Returns the game's type. This is for compatibility with :class:`Activity`. + + It always returns :attr:`ActivityType.streaming`. + """ + return ActivityType.streaming + + def __str__(self): + return str(self.name) + + def __repr__(self): + return ''.format(self) + + @property + def twitch_name(self): + """Optional[:class:`str`]: If provided, the twitch name of the user streaming. + + This corresponds to the ``large_image`` key of the :attr:`Streaming.assets` + dictionary if it starts with ``twitch:``. Typically set by the Discord client. + """ + + try: + name = self.assets['large_image'] + except KeyError: + return None + else: + return name[7:] if name[:7] == 'twitch:' else None + + def to_dict(self): + ret = { + 'type': ActivityType.streaming.value, + 'name': str(self.name), + 'url': str(self.url), + 'assets': self.assets + } + if self.details: + ret['details'] = self.details + return ret + + def __eq__(self, other): + return isinstance(other, Streaming) and other.name == self.name and other.url == self.url + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash(self.name) + +class Spotify: + """Represents a Spotify listening activity from Discord. This is a special case of + :class:`Activity` that makes it easier to work with the Spotify integration. + + .. container:: operations + + .. describe:: x == y + + Checks if two activities are equal. + + .. describe:: x != y + + Checks if two activities are not equal. + + .. describe:: hash(x) + + Returns the activity's hash. + + .. describe:: str(x) + + Returns the string 'Spotify'. + """ + + __slots__ = ('_state', '_details', '_timestamps', '_assets', '_party', '_sync_id', '_session_id', + '_created_at') + + def __init__(self, **data): + self._state = data.pop('state', None) + self._details = data.pop('details', None) + self._timestamps = data.pop('timestamps', {}) + self._assets = data.pop('assets', {}) + self._party = data.pop('party', {}) + self._sync_id = data.pop('sync_id') + self._session_id = data.pop('session_id') + self._created_at = data.pop('created_at', None) + + @property + def type(self): + """:class:`ActivityType`: Returns the activity's type. This is for compatibility with :class:`Activity`. + + It always returns :attr:`ActivityType.listening`. + """ + return ActivityType.listening + + @property + def created_at(self): + """Optional[:class:`datetime.datetime`]: When the user started listening in UTC. + + .. versionadded:: 1.3 + """ + if self._created_at is not None: + return datetime.datetime.utcfromtimestamp(self._created_at / 1000) + + @property + def colour(self): + """:class:`Colour`: Returns the Spotify integration colour, as a :class:`Colour`. + + There is an alias for this named :attr:`color`""" + return Colour(0x1db954) + + @property + def color(self): + """:class:`Colour`: Returns the Spotify integration colour, as a :class:`Colour`. + + There is an alias for this named :attr:`colour`""" + return self.colour + + def to_dict(self): + return { + 'flags': 48, # SYNC | PLAY + 'name': 'Spotify', + 'assets': self._assets, + 'party': self._party, + 'sync_id': self._sync_id, + 'session_id': self._session_id, + 'timestamps': self._timestamps, + 'details': self._details, + 'state': self._state + } + + @property + def name(self): + """:class:`str`: The activity's name. This will always return "Spotify".""" + return 'Spotify' + + def __eq__(self, other): + return (isinstance(other, Spotify) and other._session_id == self._session_id + and other._sync_id == self._sync_id and other.start == self.start) + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash(self._session_id) + + def __str__(self): + return 'Spotify' + + def __repr__(self): + return ''.format(self) + + @property + def title(self): + """:class:`str`: The title of the song being played.""" + return self._details + + @property + def artists(self): + """List[:class:`str`]: The artists of the song being played.""" + return self._state.split('; ') + + @property + def artist(self): + """:class:`str`: The artist of the song being played. + + This does not attempt to split the artist information into + multiple artists. Useful if there's only a single artist. + """ + return self._state + + @property + def album(self): + """:class:`str`: The album that the song being played belongs to.""" + return self._assets.get('large_text', '') + + @property + def album_cover_url(self): + """:class:`str`: The album cover image URL from Spotify's CDN.""" + large_image = self._assets.get('large_image', '') + if large_image[:8] != 'spotify:': + return '' + album_image_id = large_image[8:] + return 'https://i.scdn.co/image/' + album_image_id + + @property + def track_id(self): + """:class:`str`: The track ID used by Spotify to identify this song.""" + return self._sync_id + + @property + def start(self): + """:class:`datetime.datetime`: When the user started playing this song in UTC.""" + return datetime.datetime.utcfromtimestamp(self._timestamps['start'] / 1000) + + @property + def end(self): + """:class:`datetime.datetime`: When the user will stop playing this song in UTC.""" + return datetime.datetime.utcfromtimestamp(self._timestamps['end'] / 1000) + + @property + def duration(self): + """:class:`datetime.timedelta`: The duration of the song being played.""" + return self.end - self.start + + @property + def party_id(self): + """:class:`str`: The party ID of the listening party.""" + return self._party.get('id', '') + +class CustomActivity(BaseActivity): + """Represents a Custom activity from Discord. + + .. container:: operations + + .. describe:: x == y + + Checks if two activities are equal. + + .. describe:: x != y + + Checks if two activities are not equal. + + .. describe:: hash(x) + + Returns the activity's hash. + + .. describe:: str(x) + + Returns the custom status text. + + .. versionadded:: 1.3 + + Attributes + ----------- + name: Optional[:class:`str`] + The custom activity's name. + emoji: Optional[:class:`PartialEmoji`] + The emoji to pass to the activity, if any. + """ + + __slots__ = ('name', 'emoji', 'state') + + def __init__(self, name, *, emoji=None, **extra): + super().__init__(**extra) + self.name = name + self.state = extra.pop('state', None) + if self.name == 'Custom Status': + self.name = self.state + + if emoji is None: + self.emoji = emoji + elif isinstance(emoji, dict): + self.emoji = PartialEmoji.from_dict(emoji) + elif isinstance(emoji, str): + self.emoji = PartialEmoji(name=emoji) + elif isinstance(emoji, PartialEmoji): + self.emoji = emoji + else: + raise TypeError('Expected str, PartialEmoji, or None, received {0!r} instead.'.format(type(emoji))) + + @property + def type(self): + """:class:`ActivityType`: Returns the activity's type. This is for compatibility with :class:`Activity`. + + It always returns :attr:`ActivityType.custom`. + """ + return ActivityType.custom + + def to_dict(self): + if self.name == self.state: + o = { + 'type': ActivityType.custom.value, + 'state': self.name, + 'name': 'Custom Status', + } + else: + o = { + 'type': ActivityType.custom.value, + 'name': self.name, + } + + if self.emoji: + o['emoji'] = self.emoji.to_dict() + return o + + def __eq__(self, other): + return (isinstance(other, CustomActivity) and other.name == self.name and other.emoji == self.emoji) + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash((self.name, str(self.emoji))) + + def __str__(self): + if self.emoji: + if self.name: + return '%s %s' % (self.emoji, self.name) + return str(self.emoji) + else: + return str(self.name) + + def __repr__(self): + return ''.format(self) + + +def create_activity(data): + if not data: + return None + + game_type = try_enum(ActivityType, data.get('type', -1)) + if game_type is ActivityType.playing: + if 'application_id' in data or 'session_id' in data: + return Activity(**data) + return Game(**data) + elif game_type is ActivityType.custom: + try: + name = data.pop('name') + except KeyError: + return Activity(**data) + else: + return CustomActivity(name=name, **data) + elif game_type is ActivityType.streaming: + if 'url' in data: + return Streaming(**data) + return Activity(**data) + elif game_type is ActivityType.listening and 'sync_id' in data and 'session_id' in data: + return Spotify(**data) + return Activity(**data) diff --git a/dist/ba_data/python-site-packages/discord/appinfo.py b/dist/ba_data/python-site-packages/discord/appinfo.py new file mode 100644 index 0000000..cbc0056 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/appinfo.py @@ -0,0 +1,217 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +from . import utils +from .user import User +from .asset import Asset +from .team import Team + + +class AppInfo: + """Represents the application info for the bot provided by Discord. + + + Attributes + ------------- + id: :class:`int` + The application ID. + name: :class:`str` + The application name. + owner: :class:`User` + The application owner. + team: Optional[:class:`Team`] + The application's team. + + .. versionadded:: 1.3 + + icon: Optional[:class:`str`] + The icon hash, if it exists. + description: Optional[:class:`str`] + The application description. + bot_public: :class:`bool` + Whether the bot can be invited by anyone or if it is locked + to the application owner. + bot_require_code_grant: :class:`bool` + Whether the bot requires the completion of the full oauth2 code + grant flow to join. + rpc_origins: Optional[List[:class:`str`]] + A list of RPC origin URLs, if RPC is enabled. + summary: :class:`str` + If this application is a game sold on Discord, + this field will be the summary field for the store page of its primary SKU. + + .. versionadded:: 1.3 + + verify_key: :class:`str` + The hex encoded key for verification in interactions and the + GameSDK's `GetTicket `_. + + .. versionadded:: 1.3 + + guild_id: Optional[:class:`int`] + If this application is a game sold on Discord, + this field will be the guild to which it has been linked to. + + .. versionadded:: 1.3 + + primary_sku_id: Optional[:class:`int`] + If this application is a game sold on Discord, + this field will be the id of the "Game SKU" that is created, + if it exists. + + .. versionadded:: 1.3 + + slug: Optional[:class:`str`] + If this application is a game sold on Discord, + this field will be the URL slug that links to the store page. + + .. versionadded:: 1.3 + + cover_image: Optional[:class:`str`] + If this application is a game sold on Discord, + this field will be the hash of the image on store embeds + + .. versionadded:: 1.3 + """ + __slots__ = ('_state', 'description', 'id', 'name', 'rpc_origins', + 'bot_public', 'bot_require_code_grant', 'owner', 'icon', + 'summary', 'verify_key', 'team', 'guild_id', 'primary_sku_id', + 'slug', 'cover_image') + + def __init__(self, state, data): + self._state = state + + self.id = int(data['id']) + self.name = data['name'] + self.description = data['description'] + self.icon = data['icon'] + self.rpc_origins = data['rpc_origins'] + self.bot_public = data['bot_public'] + self.bot_require_code_grant = data['bot_require_code_grant'] + self.owner = User(state=self._state, data=data['owner']) + + team = data.get('team') + self.team = Team(state, team) if team else None + + self.summary = data['summary'] + self.verify_key = data['verify_key'] + + self.guild_id = utils._get_as_snowflake(data, 'guild_id') + + self.primary_sku_id = utils._get_as_snowflake(data, 'primary_sku_id') + self.slug = data.get('slug') + self.cover_image = data.get('cover_image') + + def __repr__(self): + return '<{0.__class__.__name__} id={0.id} name={0.name!r} description={0.description!r} public={0.bot_public} ' \ + 'owner={0.owner!r}>'.format(self) + + @property + def icon_url(self): + """:class:`.Asset`: Retrieves the application's icon asset. + + This is equivalent to calling :meth:`icon_url_as` with + the default parameters ('webp' format and a size of 1024). + + .. versionadded:: 1.3 + """ + return self.icon_url_as() + + def icon_url_as(self, *, format='webp', size=1024): + """Returns an :class:`Asset` for the icon the application has. + + The format must be one of 'webp', 'jpeg', 'jpg' or 'png'. + The size must be a power of 2 between 16 and 4096. + + .. versionadded:: 1.6 + + Parameters + ----------- + format: :class:`str` + The format to attempt to convert the icon to. Defaults to 'webp'. + size: :class:`int` + The size of the image to display. + + Raises + ------ + InvalidArgument + Bad image format passed to ``format`` or invalid ``size``. + + Returns + -------- + :class:`Asset` + The resulting CDN asset. + """ + return Asset._from_icon(self._state, self, 'app', format=format, size=size) + + + @property + def cover_image_url(self): + """:class:`.Asset`: Retrieves the cover image on a store embed. + + This is equivalent to calling :meth:`cover_image_url_as` with + the default parameters ('webp' format and a size of 1024). + + .. versionadded:: 1.3 + """ + return self.cover_image_url_as() + + def cover_image_url_as(self, *, format='webp', size=1024): + """Returns an :class:`Asset` for the image on store embeds + if this application is a game sold on Discord. + + The format must be one of 'webp', 'jpeg', 'jpg' or 'png'. + The size must be a power of 2 between 16 and 4096. + + .. versionadded:: 1.6 + + Parameters + ----------- + format: :class:`str` + The format to attempt to convert the image to. Defaults to 'webp'. + size: :class:`int` + The size of the image to display. + + Raises + ------ + InvalidArgument + Bad image format passed to ``format`` or invalid ``size``. + + Returns + -------- + :class:`Asset` + The resulting CDN asset. + """ + return Asset._from_cover_image(self._state, self, format=format, size=size) + + @property + def guild(self): + """Optional[:class:`Guild`]: If this application is a game sold on Discord, + this field will be the guild to which it has been linked + + .. versionadded:: 1.3 + """ + return self._state._get_guild(int(self.guild_id)) diff --git a/dist/ba_data/python-site-packages/discord/asset.py b/dist/ba_data/python-site-packages/discord/asset.py new file mode 100644 index 0000000..ea45729 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/asset.py @@ -0,0 +1,262 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import io +from .errors import DiscordException +from .errors import InvalidArgument +from . import utils + +VALID_STATIC_FORMATS = frozenset({"jpeg", "jpg", "webp", "png"}) +VALID_AVATAR_FORMATS = VALID_STATIC_FORMATS | {"gif"} + +class Asset: + """Represents a CDN asset on Discord. + + .. container:: operations + + .. describe:: str(x) + + Returns the URL of the CDN asset. + + .. describe:: len(x) + + Returns the length of the CDN asset's URL. + + .. describe:: bool(x) + + Checks if the Asset has a URL. + + .. describe:: x == y + + Checks if the asset is equal to another asset. + + .. describe:: x != y + + Checks if the asset is not equal to another asset. + + .. describe:: hash(x) + + Returns the hash of the asset. + """ + __slots__ = ('_state', '_url') + + BASE = 'https://cdn.discordapp.com' + + def __init__(self, state, url=None): + self._state = state + self._url = url + + @classmethod + def _from_avatar(cls, state, user, *, format=None, static_format='webp', size=1024): + if not utils.valid_icon_size(size): + raise InvalidArgument("size must be a power of 2 between 16 and 4096") + if format is not None and format not in VALID_AVATAR_FORMATS: + raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS)) + if format == "gif" and not user.is_avatar_animated(): + raise InvalidArgument("non animated avatars do not support gif format") + if static_format not in VALID_STATIC_FORMATS: + raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS)) + + if user.avatar is None: + return user.default_avatar_url + + if format is None: + format = 'gif' if user.is_avatar_animated() else static_format + + return cls(state, '/avatars/{0.id}/{0.avatar}.{1}?size={2}'.format(user, format, size)) + + @classmethod + def _from_icon(cls, state, object, path, *, format='webp', size=1024): + if object.icon is None: + return cls(state) + + if not utils.valid_icon_size(size): + raise InvalidArgument("size must be a power of 2 between 16 and 4096") + if format not in VALID_STATIC_FORMATS: + raise InvalidArgument("format must be None or one of {}".format(VALID_STATIC_FORMATS)) + + url = '/{0}-icons/{1.id}/{1.icon}.{2}?size={3}'.format(path, object, format, size) + return cls(state, url) + + @classmethod + def _from_cover_image(cls, state, obj, *, format='webp', size=1024): + if obj.cover_image is None: + return cls(state) + + if not utils.valid_icon_size(size): + raise InvalidArgument("size must be a power of 2 between 16 and 4096") + if format not in VALID_STATIC_FORMATS: + raise InvalidArgument("format must be None or one of {}".format(VALID_STATIC_FORMATS)) + + url = '/app-assets/{0.id}/store/{0.cover_image}.{1}?size={2}'.format(obj, format, size) + return cls(state, url) + + @classmethod + def _from_guild_image(cls, state, id, hash, key, *, format='webp', size=1024): + if not utils.valid_icon_size(size): + raise InvalidArgument("size must be a power of 2 between 16 and 4096") + if format not in VALID_STATIC_FORMATS: + raise InvalidArgument("format must be one of {}".format(VALID_STATIC_FORMATS)) + + if hash is None: + return cls(state) + + url = '/{key}/{0}/{1}.{2}?size={3}' + return cls(state, url.format(id, hash, format, size, key=key)) + + @classmethod + def _from_guild_icon(cls, state, guild, *, format=None, static_format='webp', size=1024): + if not utils.valid_icon_size(size): + raise InvalidArgument("size must be a power of 2 between 16 and 4096") + if format is not None and format not in VALID_AVATAR_FORMATS: + raise InvalidArgument("format must be one of {}".format(VALID_AVATAR_FORMATS)) + if format == "gif" and not guild.is_icon_animated(): + raise InvalidArgument("non animated guild icons do not support gif format") + if static_format not in VALID_STATIC_FORMATS: + raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS)) + + if guild.icon is None: + return cls(state) + + if format is None: + format = 'gif' if guild.is_icon_animated() else static_format + + return cls(state, '/icons/{0.id}/{0.icon}.{1}?size={2}'.format(guild, format, size)) + + @classmethod + def _from_sticker_url(cls, state, sticker, *, size=1024): + if not utils.valid_icon_size(size): + raise InvalidArgument("size must be a power of 2 between 16 and 4096") + + return cls(state, '/stickers/{0.id}/{0.image}.png?size={2}'.format(sticker, format, size)) + + @classmethod + def _from_emoji(cls, state, emoji, *, format=None, static_format='png'): + if format is not None and format not in VALID_AVATAR_FORMATS: + raise InvalidArgument("format must be None or one of {}".format(VALID_AVATAR_FORMATS)) + if format == "gif" and not emoji.animated: + raise InvalidArgument("non animated emoji's do not support gif format") + if static_format not in VALID_STATIC_FORMATS: + raise InvalidArgument("static_format must be one of {}".format(VALID_STATIC_FORMATS)) + if format is None: + format = 'gif' if emoji.animated else static_format + + return cls(state, '/emojis/{0.id}.{1}'.format(emoji, format)) + + def __str__(self): + return self.BASE + self._url if self._url is not None else '' + + def __len__(self): + if self._url: + return len(self.BASE + self._url) + return 0 + + def __bool__(self): + return self._url is not None + + def __repr__(self): + return ''.format(self) + + def __eq__(self, other): + return isinstance(other, Asset) and self._url == other._url + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash(self._url) + + async def read(self): + """|coro| + + Retrieves the content of this asset as a :class:`bytes` object. + + .. warning:: + + :class:`PartialEmoji` won't have a connection state if user created, + and a URL won't be present if a custom image isn't associated with + the asset, e.g. a guild with no custom icon. + + .. versionadded:: 1.1 + + Raises + ------ + DiscordException + There was no valid URL or internal connection state. + HTTPException + Downloading the asset failed. + NotFound + The asset was deleted. + + Returns + ------- + :class:`bytes` + The content of the asset. + """ + if not self._url: + raise DiscordException('Invalid asset (no URL provided)') + + if self._state is None: + raise DiscordException('Invalid state (no ConnectionState provided)') + + return await self._state.http.get_from_cdn(self.BASE + self._url) + + async def save(self, fp, *, seek_begin=True): + """|coro| + + Saves this asset into a file-like object. + + Parameters + ---------- + fp: Union[BinaryIO, :class:`os.PathLike`] + Same as in :meth:`Attachment.save`. + seek_begin: :class:`bool` + Same as in :meth:`Attachment.save`. + + Raises + ------ + DiscordException + There was no valid URL or internal connection state. + HTTPException + Downloading the asset failed. + NotFound + The asset was deleted. + + Returns + -------- + :class:`int` + The number of bytes written. + """ + + data = await self.read() + if isinstance(fp, io.IOBase) and fp.writable(): + written = fp.write(data) + if seek_begin: + fp.seek(0) + return written + else: + with open(fp, 'wb') as f: + return f.write(data) diff --git a/dist/ba_data/python-site-packages/discord/audit_logs.py b/dist/ba_data/python-site-packages/discord/audit_logs.py new file mode 100644 index 0000000..7d70a93 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/audit_logs.py @@ -0,0 +1,382 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +from . import utils, enums +from .object import Object +from .permissions import PermissionOverwrite, Permissions +from .colour import Colour +from .invite import Invite +from .mixins import Hashable + +def _transform_verification_level(entry, data): + return enums.try_enum(enums.VerificationLevel, data) + +def _transform_default_notifications(entry, data): + return enums.try_enum(enums.NotificationLevel, data) + +def _transform_explicit_content_filter(entry, data): + return enums.try_enum(enums.ContentFilter, data) + +def _transform_permissions(entry, data): + return Permissions(data) + +def _transform_color(entry, data): + return Colour(data) + +def _transform_snowflake(entry, data): + return int(data) + +def _transform_channel(entry, data): + if data is None: + return None + return entry.guild.get_channel(int(data)) or Object(id=data) + +def _transform_owner_id(entry, data): + if data is None: + return None + return entry._get_member(int(data)) + +def _transform_inviter_id(entry, data): + if data is None: + return None + return entry._get_member(int(data)) + +def _transform_overwrites(entry, data): + overwrites = [] + for elem in data: + allow = Permissions(elem['allow']) + deny = Permissions(elem['deny']) + ow = PermissionOverwrite.from_pair(allow, deny) + + ow_type = elem['type'] + ow_id = int(elem['id']) + if ow_type == 'role': + target = entry.guild.get_role(ow_id) + else: + target = entry._get_member(ow_id) + + if target is None: + target = Object(id=ow_id) + + overwrites.append((target, ow)) + + return overwrites + +class AuditLogDiff: + def __len__(self): + return len(self.__dict__) + + def __iter__(self): + return iter(self.__dict__.items()) + + def __repr__(self): + values = ' '.join('%s=%r' % item for item in self.__dict__.items()) + return '' % values + +class AuditLogChanges: + TRANSFORMERS = { + 'verification_level': (None, _transform_verification_level), + 'explicit_content_filter': (None, _transform_explicit_content_filter), + 'allow': (None, _transform_permissions), + 'deny': (None, _transform_permissions), + 'permissions': (None, _transform_permissions), + 'id': (None, _transform_snowflake), + 'color': ('colour', _transform_color), + 'owner_id': ('owner', _transform_owner_id), + 'inviter_id': ('inviter', _transform_inviter_id), + 'channel_id': ('channel', _transform_channel), + 'afk_channel_id': ('afk_channel', _transform_channel), + 'system_channel_id': ('system_channel', _transform_channel), + 'widget_channel_id': ('widget_channel', _transform_channel), + 'permission_overwrites': ('overwrites', _transform_overwrites), + 'splash_hash': ('splash', None), + 'icon_hash': ('icon', None), + 'avatar_hash': ('avatar', None), + 'rate_limit_per_user': ('slowmode_delay', None), + 'default_message_notifications': ('default_notifications', _transform_default_notifications), + } + + def __init__(self, entry, data): + self.before = AuditLogDiff() + self.after = AuditLogDiff() + + for elem in data: + attr = elem['key'] + + # special cases for role add/remove + if attr == '$add': + self._handle_role(self.before, self.after, entry, elem['new_value']) + continue + elif attr == '$remove': + self._handle_role(self.after, self.before, entry, elem['new_value']) + continue + + transformer = self.TRANSFORMERS.get(attr) + if transformer: + key, transformer = transformer + if key: + attr = key + + try: + before = elem['old_value'] + except KeyError: + before = None + else: + if transformer: + before = transformer(entry, before) + + setattr(self.before, attr, before) + + try: + after = elem['new_value'] + except KeyError: + after = None + else: + if transformer: + after = transformer(entry, after) + + setattr(self.after, attr, after) + + # add an alias + if hasattr(self.after, 'colour'): + self.after.color = self.after.colour + self.before.color = self.before.colour + + def __repr__(self): + return '' % (self.before, self.after) + + def _handle_role(self, first, second, entry, elem): + if not hasattr(first, 'roles'): + setattr(first, 'roles', []) + + data = [] + g = entry.guild + + for e in elem: + role_id = int(e['id']) + role = g.get_role(role_id) + + if role is None: + role = Object(id=role_id) + role.name = e['name'] + + data.append(role) + + setattr(second, 'roles', data) + +class AuditLogEntry(Hashable): + r"""Represents an Audit Log entry. + + You retrieve these via :meth:`Guild.audit_logs`. + + .. container:: operations + + .. describe:: x == y + + Checks if two entries are equal. + + .. describe:: x != y + + Checks if two entries are not equal. + + .. describe:: hash(x) + + Returns the entry's hash. + + .. versionchanged:: 1.7 + Audit log entries are now comparable and hashable. + + Attributes + ----------- + action: :class:`AuditLogAction` + The action that was done. + user: :class:`abc.User` + The user who initiated this action. Usually a :class:`Member`\, unless gone + then it's a :class:`User`. + id: :class:`int` + The entry ID. + target: Any + The target that got changed. The exact type of this depends on + the action being done. + reason: Optional[:class:`str`] + The reason this action was done. + extra: Any + Extra information that this entry has that might be useful. + For most actions, this is ``None``. However in some cases it + contains extra information. See :class:`AuditLogAction` for + which actions have this field filled out. + """ + + def __init__(self, *, users, data, guild): + self._state = guild._state + self.guild = guild + self._users = users + self._from_data(data) + + def _from_data(self, data): + self.action = enums.try_enum(enums.AuditLogAction, data['action_type']) + self.id = int(data['id']) + + # this key is technically not usually present + self.reason = data.get('reason') + self.extra = data.get('options') + + if isinstance(self.action, enums.AuditLogAction) and self.extra: + if self.action is enums.AuditLogAction.member_prune: + # member prune has two keys with useful information + self.extra = type('_AuditLogProxy', (), {k: int(v) for k, v in self.extra.items()})() + elif self.action is enums.AuditLogAction.member_move or self.action is enums.AuditLogAction.message_delete: + channel_id = int(self.extra['channel_id']) + elems = { + 'count': int(self.extra['count']), + 'channel': self.guild.get_channel(channel_id) or Object(id=channel_id) + } + self.extra = type('_AuditLogProxy', (), elems)() + elif self.action is enums.AuditLogAction.member_disconnect: + # The member disconnect action has a dict with some information + elems = { + 'count': int(self.extra['count']), + } + self.extra = type('_AuditLogProxy', (), elems)() + elif self.action.name.endswith('pin'): + # the pin actions have a dict with some information + channel_id = int(self.extra['channel_id']) + message_id = int(self.extra['message_id']) + elems = { + 'channel': self.guild.get_channel(channel_id) or Object(id=channel_id), + 'message_id': message_id + } + self.extra = type('_AuditLogProxy', (), elems)() + elif self.action.name.startswith('overwrite_'): + # the overwrite_ actions have a dict with some information + instance_id = int(self.extra['id']) + the_type = self.extra.get('type') + if the_type == 'member': + self.extra = self._get_member(instance_id) + else: + role = self.guild.get_role(instance_id) + if role is None: + role = Object(id=instance_id) + role.name = self.extra.get('role_name') + self.extra = role + + # this key is not present when the above is present, typically. + # It's a list of { new_value: a, old_value: b, key: c } + # where new_value and old_value are not guaranteed to be there depending + # on the action type, so let's just fetch it for now and only turn it + # into meaningful data when requested + self._changes = data.get('changes', []) + + self.user = self._get_member(utils._get_as_snowflake(data, 'user_id')) + self._target_id = utils._get_as_snowflake(data, 'target_id') + + def _get_member(self, user_id): + return self.guild.get_member(user_id) or self._users.get(user_id) + + def __repr__(self): + return ''.format(self) + + @utils.cached_property + def created_at(self): + """:class:`datetime.datetime`: Returns the entry's creation time in UTC.""" + return utils.snowflake_time(self.id) + + @utils.cached_property + def target(self): + try: + converter = getattr(self, '_convert_target_' + self.action.target_type) + except AttributeError: + return Object(id=self._target_id) + else: + return converter(self._target_id) + + @utils.cached_property + def category(self): + """Optional[:class:`AuditLogActionCategory`]: The category of the action, if applicable.""" + return self.action.category + + @utils.cached_property + def changes(self): + """:class:`AuditLogChanges`: The list of changes this entry has.""" + obj = AuditLogChanges(self, self._changes) + del self._changes + return obj + + @utils.cached_property + def before(self): + """:class:`AuditLogDiff`: The target's prior state.""" + return self.changes.before + + @utils.cached_property + def after(self): + """:class:`AuditLogDiff`: The target's subsequent state.""" + return self.changes.after + + def _convert_target_guild(self, target_id): + return self.guild + + def _convert_target_channel(self, target_id): + ch = self.guild.get_channel(target_id) + if ch is None: + return Object(id=target_id) + return ch + + def _convert_target_user(self, target_id): + return self._get_member(target_id) + + def _convert_target_role(self, target_id): + role = self.guild.get_role(target_id) + if role is None: + return Object(id=target_id) + return role + + def _convert_target_invite(self, target_id): + # invites have target_id set to null + # so figure out which change has the full invite data + changeset = self.before if self.action is enums.AuditLogAction.invite_delete else self.after + + fake_payload = { + 'max_age': changeset.max_age, + 'max_uses': changeset.max_uses, + 'code': changeset.code, + 'temporary': changeset.temporary, + 'channel': changeset.channel, + 'uses': changeset.uses, + 'guild': self.guild, + } + + obj = Invite(state=self._state, data=fake_payload) + try: + obj.inviter = changeset.inviter + except AttributeError: + pass + return obj + + def _convert_target_emoji(self, target_id): + return self._state.get_emoji(target_id) or Object(id=target_id) + + def _convert_target_message(self, target_id): + return self._get_member(target_id) diff --git a/dist/ba_data/python-site-packages/discord/backoff.py b/dist/ba_data/python-site-packages/discord/backoff.py new file mode 100644 index 0000000..0f49d15 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/backoff.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import time +import random + +class ExponentialBackoff: + """An implementation of the exponential backoff algorithm + + Provides a convenient interface to implement an exponential backoff + for reconnecting or retrying transmissions in a distributed network. + + Once instantiated, the delay method will return the next interval to + wait for when retrying a connection or transmission. The maximum + delay increases exponentially with each retry up to a maximum of + 2^10 * base, and is reset if no more attempts are needed in a period + of 2^11 * base seconds. + + Parameters + ---------- + base: :class:`int` + The base delay in seconds. The first retry-delay will be up to + this many seconds. + integral: :class:`bool` + Set to ``True`` if whole periods of base is desirable, otherwise any + number in between may be returned. + """ + + def __init__(self, base=1, *, integral=False): + self._base = base + + self._exp = 0 + self._max = 10 + self._reset_time = base * 2 ** 11 + self._last_invocation = time.monotonic() + + # Use our own random instance to avoid messing with global one + rand = random.Random() + rand.seed() + + self._randfunc = rand.randrange if integral else rand.uniform + + def delay(self): + """Compute the next delay + + Returns the next delay to wait according to the exponential + backoff algorithm. This is a value between 0 and base * 2^exp + where exponent starts off at 1 and is incremented at every + invocation of this method up to a maximum of 10. + + If a period of more than base * 2^11 has passed since the last + retry, the exponent is reset to 1. + """ + invocation = time.monotonic() + interval = invocation - self._last_invocation + self._last_invocation = invocation + + if interval > self._reset_time: + self._exp = 0 + + self._exp = min(self._exp + 1, self._max) + return self._randfunc(0, self._base * 2 ** self._exp) diff --git a/dist/ba_data/python-site-packages/discord/bin/libopus-0.x64.dll b/dist/ba_data/python-site-packages/discord/bin/libopus-0.x64.dll new file mode 100644 index 0000000..74a8e35 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/bin/libopus-0.x64.dll differ diff --git a/dist/ba_data/python-site-packages/discord/bin/libopus-0.x86.dll b/dist/ba_data/python-site-packages/discord/bin/libopus-0.x86.dll new file mode 100644 index 0000000..ee71317 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/bin/libopus-0.x86.dll differ diff --git a/dist/ba_data/python-site-packages/discord/calls.py b/dist/ba_data/python-site-packages/discord/calls.py new file mode 100644 index 0000000..2006b30 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/calls.py @@ -0,0 +1,176 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import datetime + +from . import utils +from .enums import VoiceRegion, try_enum +from .member import VoiceState + +class CallMessage: + """Represents a group call message from Discord. + + This is only received in cases where the message type is equivalent to + :attr:`MessageType.call`. + + .. deprecated:: 1.7 + + Attributes + ----------- + ended_timestamp: Optional[:class:`datetime.datetime`] + A naive UTC datetime object that represents the time that the call has ended. + participants: List[:class:`User`] + The list of users that are participating in this call. + message: :class:`Message` + The message associated with this call message. + """ + + def __init__(self, message, **kwargs): + self.message = message + self.ended_timestamp = utils.parse_time(kwargs.get('ended_timestamp')) + self.participants = kwargs.get('participants') + + @property + def call_ended(self): + """:class:`bool`: Indicates if the call has ended. + + .. deprecated:: 1.7 + """ + return self.ended_timestamp is not None + + @property + def channel(self): + r""":class:`GroupChannel`\: The private channel associated with this message. + + .. deprecated:: 1.7 + """ + return self.message.channel + + @property + def duration(self): + """Queries the duration of the call. + + If the call has not ended then the current duration will + be returned. + + .. deprecated:: 1.7 + + Returns + --------- + :class:`datetime.timedelta` + The timedelta object representing the duration. + """ + if self.ended_timestamp is None: + return datetime.datetime.utcnow() - self.message.created_at + else: + return self.ended_timestamp - self.message.created_at + +class GroupCall: + """Represents the actual group call from Discord. + + This is accompanied with a :class:`CallMessage` denoting the information. + + .. deprecated:: 1.7 + + Attributes + ----------- + call: :class:`CallMessage` + The call message associated with this group call. + unavailable: :class:`bool` + Denotes if this group call is unavailable. + ringing: List[:class:`User`] + A list of users that are currently being rung to join the call. + region: :class:`VoiceRegion` + The guild region the group call is being hosted on. + """ + + def __init__(self, **kwargs): + self.call = kwargs.get('call') + self.unavailable = kwargs.get('unavailable') + self._voice_states = {} + + for state in kwargs.get('voice_states', []): + self._update_voice_state(state) + + self._update(**kwargs) + + def _update(self, **kwargs): + self.region = try_enum(VoiceRegion, kwargs.get('region')) + lookup = {u.id: u for u in self.call.channel.recipients} + me = self.call.channel.me + lookup[me.id] = me + self.ringing = list(filter(None, map(lookup.get, kwargs.get('ringing', [])))) + + def _update_voice_state(self, data): + user_id = int(data['user_id']) + # left the voice channel? + if data['channel_id'] is None: + self._voice_states.pop(user_id, None) + else: + self._voice_states[user_id] = VoiceState(data=data, channel=self.channel) + + @property + def connected(self): + """List[:class:`User`]: A property that returns all users that are currently in this call. + + .. deprecated:: 1.7 + """ + ret = [u for u in self.channel.recipients if self.voice_state_for(u) is not None] + me = self.channel.me + if self.voice_state_for(me) is not None: + ret.append(me) + + return ret + + @property + def channel(self): + r""":class:`GroupChannel`\: Returns the channel the group call is in. + + .. deprecated:: 1.7 + """ + return self.call.channel + + @utils.deprecated() + def voice_state_for(self, user): + """Retrieves the :class:`VoiceState` for a specified :class:`User`. + + If the :class:`User` has no voice state then this function returns + ``None``. + + .. deprecated:: 1.7 + + Parameters + ------------ + user: :class:`User` + The user to retrieve the voice state for. + + Returns + -------- + Optional[:class:`VoiceState`] + The voice state associated with this user. + """ + + return self._voice_states.get(user.id) diff --git a/dist/ba_data/python-site-packages/discord/channel.py b/dist/ba_data/python-site-packages/discord/channel.py new file mode 100644 index 0000000..3510b80 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/channel.py @@ -0,0 +1,1569 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import time +import asyncio + +import discord.abc +from .permissions import Permissions +from .enums import ChannelType, try_enum, VoiceRegion +from .mixins import Hashable +from . import utils +from .asset import Asset +from .errors import ClientException, NoMoreItems, InvalidArgument + +__all__ = ( + 'TextChannel', + 'VoiceChannel', + 'StageChannel', + 'DMChannel', + 'CategoryChannel', + 'StoreChannel', + 'GroupChannel', + '_channel_factory', +) + +async def _single_delete_strategy(messages): + for m in messages: + await m.delete() + +class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable): + """Represents a Discord guild text channel. + + .. container:: operations + + .. describe:: x == y + + Checks if two channels are equal. + + .. describe:: x != y + + Checks if two channels are not equal. + + .. describe:: hash(x) + + Returns the channel's hash. + + .. describe:: str(x) + + Returns the channel's name. + + Attributes + ----------- + name: :class:`str` + The channel name. + guild: :class:`Guild` + The guild the channel belongs to. + id: :class:`int` + The channel ID. + category_id: Optional[:class:`int`] + The category channel ID this channel belongs to, if applicable. + topic: Optional[:class:`str`] + The channel's topic. ``None`` if it doesn't exist. + position: :class:`int` + The position in the channel list. This is a number that starts at 0. e.g. the + top channel is position 0. + last_message_id: Optional[:class:`int`] + The last message ID of the message sent to this channel. It may + *not* point to an existing or valid message. + slowmode_delay: :class:`int` + The number of seconds a member must wait between sending messages + in this channel. A value of `0` denotes that it is disabled. + Bots and users with :attr:`~Permissions.manage_channels` or + :attr:`~Permissions.manage_messages` bypass slowmode. + """ + + __slots__ = ('name', 'id', 'guild', 'topic', '_state', 'nsfw', + 'category_id', 'position', 'slowmode_delay', '_overwrites', + '_type', 'last_message_id') + + def __init__(self, *, state, guild, data): + self._state = state + self.id = int(data['id']) + self._type = data['type'] + self._update(guild, data) + + def __repr__(self): + attrs = [ + ('id', self.id), + ('name', self.name), + ('position', self.position), + ('nsfw', self.nsfw), + ('news', self.is_news()), + ('category_id', self.category_id) + ] + return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) + + def _update(self, guild, data): + self.guild = guild + self.name = data['name'] + self.category_id = utils._get_as_snowflake(data, 'parent_id') + self.topic = data.get('topic') + self.position = data['position'] + self.nsfw = data.get('nsfw', False) + # Does this need coercion into `int`? No idea yet. + self.slowmode_delay = data.get('rate_limit_per_user', 0) + self._type = data.get('type', self._type) + self.last_message_id = utils._get_as_snowflake(data, 'last_message_id') + self._fill_overwrites(data) + + async def _get_channel(self): + return self + + @property + def type(self): + """:class:`ChannelType`: The channel's Discord type.""" + return try_enum(ChannelType, self._type) + + @property + def _sorting_bucket(self): + return ChannelType.text.value + + @utils.copy_doc(discord.abc.GuildChannel.permissions_for) + def permissions_for(self, member): + base = super().permissions_for(member) + + # text channels do not have voice related permissions + denied = Permissions.voice() + base.value &= ~denied.value + return base + + @property + def members(self): + """List[:class:`Member`]: Returns all members that can see this channel.""" + return [m for m in self.guild.members if self.permissions_for(m).read_messages] + + def is_nsfw(self): + """:class:`bool`: Checks if the channel is NSFW.""" + return self.nsfw + + def is_news(self): + """:class:`bool`: Checks if the channel is a news channel.""" + return self._type == ChannelType.news.value + + @property + def last_message(self): + """Fetches the last message from this channel in cache. + + The message might not be valid or point to an existing message. + + .. admonition:: Reliable Fetching + :class: helpful + + For a slightly more reliable method of fetching the + last message, consider using either :meth:`history` + or :meth:`fetch_message` with the :attr:`last_message_id` + attribute. + + Returns + --------- + Optional[:class:`Message`] + The last message in this channel or ``None`` if not found. + """ + return self._state._get_message(self.last_message_id) if self.last_message_id else None + + async def edit(self, *, reason=None, **options): + """|coro| + + Edits the channel. + + You must have the :attr:`~Permissions.manage_channels` permission to + use this. + + .. versionchanged:: 1.3 + The ``overwrites`` keyword-only parameter was added. + + .. versionchanged:: 1.4 + The ``type`` keyword-only parameter was added. + + Parameters + ---------- + name: :class:`str` + The new channel name. + topic: :class:`str` + The new channel's topic. + position: :class:`int` + The new channel's position. + nsfw: :class:`bool` + To mark the channel as NSFW or not. + sync_permissions: :class:`bool` + Whether to sync permissions with the channel's new or pre-existing + category. Defaults to ``False``. + category: Optional[:class:`CategoryChannel`] + The new category for this channel. Can be ``None`` to remove the + category. + slowmode_delay: :class:`int` + Specifies the slowmode rate limit for user in this channel, in seconds. + A value of `0` disables slowmode. The maximum value possible is `21600`. + type: :class:`ChannelType` + Change the type of this text channel. Currently, only conversion between + :attr:`ChannelType.text` and :attr:`ChannelType.news` is supported. This + is only available to guilds that contain ``NEWS`` in :attr:`Guild.features`. + reason: Optional[:class:`str`] + The reason for editing this channel. Shows up on the audit log. + overwrites: :class:`dict` + A :class:`dict` of target (either a role or a member) to + :class:`PermissionOverwrite` to apply to the channel. + + Raises + ------ + InvalidArgument + If position is less than 0 or greater than the number of channels, or if + the permission overwrite information is not in proper form. + Forbidden + You do not have permissions to edit the channel. + HTTPException + Editing the channel failed. + """ + await self._edit(options, reason=reason) + + @utils.copy_doc(discord.abc.GuildChannel.clone) + async def clone(self, *, name=None, reason=None): + return await self._clone_impl({ + 'topic': self.topic, + 'nsfw': self.nsfw, + 'rate_limit_per_user': self.slowmode_delay + }, name=name, reason=reason) + + async def delete_messages(self, messages): + """|coro| + + Deletes a list of messages. This is similar to :meth:`Message.delete` + except it bulk deletes multiple messages. + + As a special case, if the number of messages is 0, then nothing + is done. If the number of messages is 1 then single message + delete is done. If it's more than two, then bulk delete is used. + + You cannot bulk delete more than 100 messages or messages that + are older than 14 days old. + + You must have the :attr:`~Permissions.manage_messages` permission to + use this. + + Usable only by bot accounts. + + Parameters + ----------- + messages: Iterable[:class:`abc.Snowflake`] + An iterable of messages denoting which ones to bulk delete. + + Raises + ------ + ClientException + The number of messages to delete was more than 100. + Forbidden + You do not have proper permissions to delete the messages or + you're not using a bot account. + NotFound + If single delete, then the message was already deleted. + HTTPException + Deleting the messages failed. + """ + if not isinstance(messages, (list, tuple)): + messages = list(messages) + + if len(messages) == 0: + return # do nothing + + if len(messages) == 1: + message_id = messages[0].id + await self._state.http.delete_message(self.id, message_id) + return + + if len(messages) > 100: + raise ClientException('Can only bulk delete messages up to 100 messages') + + message_ids = [m.id for m in messages] + await self._state.http.delete_messages(self.id, message_ids) + + async def purge(self, *, limit=100, check=None, before=None, after=None, around=None, oldest_first=False, bulk=True): + """|coro| + + Purges a list of messages that meet the criteria given by the predicate + ``check``. If a ``check`` is not provided then all messages are deleted + without discrimination. + + You must have the :attr:`~Permissions.manage_messages` permission to + delete messages even if they are your own (unless you are a user + account). The :attr:`~Permissions.read_message_history` permission is + also needed to retrieve message history. + + Internally, this employs a different number of strategies depending + on the conditions met such as if a bulk delete is possible or if + the account is a user bot or not. + + Examples + --------- + + Deleting bot's messages :: + + def is_me(m): + return m.author == client.user + + deleted = await channel.purge(limit=100, check=is_me) + await channel.send('Deleted {} message(s)'.format(len(deleted))) + + Parameters + ----------- + limit: Optional[:class:`int`] + The number of messages to search through. This is not the number + of messages that will be deleted, though it can be. + check: Callable[[:class:`Message`], :class:`bool`] + The function used to check if a message should be deleted. + It must take a :class:`Message` as its sole parameter. + before: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Same as ``before`` in :meth:`history`. + after: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Same as ``after`` in :meth:`history`. + around: Optional[Union[:class:`abc.Snowflake`, :class:`datetime.datetime`]] + Same as ``around`` in :meth:`history`. + oldest_first: Optional[:class:`bool`] + Same as ``oldest_first`` in :meth:`history`. + bulk: :class:`bool` + If ``True``, use bulk delete. Setting this to ``False`` is useful for mass-deleting + a bot's own messages without :attr:`Permissions.manage_messages`. When ``True``, will + fall back to single delete if current account is a user bot (now deprecated), or if messages are + older than two weeks. + + Raises + ------- + Forbidden + You do not have proper permissions to do the actions required. + HTTPException + Purging the messages failed. + + Returns + -------- + List[:class:`.Message`] + The list of messages that were deleted. + """ + + if check is None: + check = lambda m: True + + iterator = self.history(limit=limit, before=before, after=after, oldest_first=oldest_first, around=around) + ret = [] + count = 0 + + minimum_time = int((time.time() - 14 * 24 * 60 * 60) * 1000.0 - 1420070400000) << 22 + strategy = self.delete_messages if self._state.is_bot and bulk else _single_delete_strategy + + while True: + try: + msg = await iterator.next() + except NoMoreItems: + # no more messages to poll + if count >= 2: + # more than 2 messages -> bulk delete + to_delete = ret[-count:] + await strategy(to_delete) + elif count == 1: + # delete a single message + await ret[-1].delete() + + return ret + else: + if count == 100: + # we've reached a full 'queue' + to_delete = ret[-100:] + await strategy(to_delete) + count = 0 + await asyncio.sleep(1) + + if check(msg): + if msg.id < minimum_time: + # older than 14 days old + if count == 1: + await ret[-1].delete() + elif count >= 2: + to_delete = ret[-count:] + await strategy(to_delete) + + count = 0 + strategy = _single_delete_strategy + + count += 1 + ret.append(msg) + + async def webhooks(self): + """|coro| + + Gets the list of webhooks from this channel. + + Requires :attr:`~.Permissions.manage_webhooks` permissions. + + Raises + ------- + Forbidden + You don't have permissions to get the webhooks. + + Returns + -------- + List[:class:`Webhook`] + The webhooks for this channel. + """ + + from .webhook import Webhook + data = await self._state.http.channel_webhooks(self.id) + return [Webhook.from_state(d, state=self._state) for d in data] + + async def create_webhook(self, *, name, avatar=None, reason=None): + """|coro| + + Creates a webhook for this channel. + + Requires :attr:`~.Permissions.manage_webhooks` permissions. + + .. versionchanged:: 1.1 + Added the ``reason`` keyword-only parameter. + + Parameters + ------------- + name: :class:`str` + The webhook's name. + avatar: Optional[:class:`bytes`] + A :term:`py:bytes-like object` representing the webhook's default avatar. + This operates similarly to :meth:`~ClientUser.edit`. + reason: Optional[:class:`str`] + The reason for creating this webhook. Shows up in the audit logs. + + Raises + ------- + HTTPException + Creating the webhook failed. + Forbidden + You do not have permissions to create a webhook. + + Returns + -------- + :class:`Webhook` + The created webhook. + """ + + from .webhook import Webhook + if avatar is not None: + avatar = utils._bytes_to_base64_data(avatar) + + data = await self._state.http.create_webhook(self.id, name=str(name), avatar=avatar, reason=reason) + return Webhook.from_state(data, state=self._state) + + async def follow(self, *, destination, reason=None): + """ + Follows a channel using a webhook. + + Only news channels can be followed. + + .. note:: + + The webhook returned will not provide a token to do webhook + actions, as Discord does not provide it. + + .. versionadded:: 1.3 + + Parameters + ----------- + destination: :class:`TextChannel` + The channel you would like to follow from. + reason: Optional[:class:`str`] + The reason for following the channel. Shows up on the destination guild's audit log. + + .. versionadded:: 1.4 + + Raises + ------- + HTTPException + Following the channel failed. + Forbidden + You do not have the permissions to create a webhook. + + Returns + -------- + :class:`Webhook` + The created webhook. + """ + + if not self.is_news(): + raise ClientException('The channel must be a news channel.') + + if not isinstance(destination, TextChannel): + raise InvalidArgument('Expected TextChannel received {0.__name__}'.format(type(destination))) + + from .webhook import Webhook + data = await self._state.http.follow_webhook(self.id, webhook_channel_id=destination.id, reason=reason) + return Webhook._as_follower(data, channel=destination, user=self._state.user) + + def get_partial_message(self, message_id): + """Creates a :class:`PartialMessage` from the message ID. + + This is useful if you want to work with a message and only have its ID without + doing an unnecessary API call. + + .. versionadded:: 1.6 + + Parameters + ------------ + message_id: :class:`int` + The message ID to create a partial message for. + + Returns + --------- + :class:`PartialMessage` + The partial message. + """ + + from .message import PartialMessage + return PartialMessage(channel=self, id=message_id) + +class VocalGuildChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hashable): + __slots__ = ('name', 'id', 'guild', 'bitrate', 'user_limit', + '_state', 'position', '_overwrites', 'category_id', + 'rtc_region') + + def __init__(self, *, state, guild, data): + self._state = state + self.id = int(data['id']) + self._update(guild, data) + + def _get_voice_client_key(self): + return self.guild.id, 'guild_id' + + def _get_voice_state_pair(self): + return self.guild.id, self.id + + def _update(self, guild, data): + self.guild = guild + self.name = data['name'] + self.rtc_region = data.get('rtc_region') + if self.rtc_region: + self.rtc_region = try_enum(VoiceRegion, self.rtc_region) + self.category_id = utils._get_as_snowflake(data, 'parent_id') + self.position = data['position'] + self.bitrate = data.get('bitrate') + self.user_limit = data.get('user_limit') + self._fill_overwrites(data) + + @property + def _sorting_bucket(self): + return ChannelType.voice.value + + @property + def members(self): + """List[:class:`Member`]: Returns all members that are currently inside this voice channel.""" + ret = [] + for user_id, state in self.guild._voice_states.items(): + if state.channel and state.channel.id == self.id: + member = self.guild.get_member(user_id) + if member is not None: + ret.append(member) + return ret + + @property + def voice_states(self): + """Returns a mapping of member IDs who have voice states in this channel. + + .. versionadded:: 1.3 + + .. note:: + + This function is intentionally low level to replace :attr:`members` + when the member cache is unavailable. + + Returns + -------- + Mapping[:class:`int`, :class:`VoiceState`] + The mapping of member ID to a voice state. + """ + return {key: value for key, value in self.guild._voice_states.items() if value.channel.id == self.id} + + @utils.copy_doc(discord.abc.GuildChannel.permissions_for) + def permissions_for(self, member): + base = super().permissions_for(member) + + # voice channels cannot be edited by people who can't connect to them + # It also implicitly denies all other voice perms + if not base.connect: + denied = Permissions.voice() + denied.update(manage_channels=True, manage_roles=True) + base.value &= ~denied.value + return base + +class VoiceChannel(VocalGuildChannel): + """Represents a Discord guild voice channel. + + .. container:: operations + + .. describe:: x == y + + Checks if two channels are equal. + + .. describe:: x != y + + Checks if two channels are not equal. + + .. describe:: hash(x) + + Returns the channel's hash. + + .. describe:: str(x) + + Returns the channel's name. + + Attributes + ----------- + name: :class:`str` + The channel name. + guild: :class:`Guild` + The guild the channel belongs to. + id: :class:`int` + The channel ID. + category_id: Optional[:class:`int`] + The category channel ID this channel belongs to, if applicable. + position: :class:`int` + The position in the channel list. This is a number that starts at 0. e.g. the + top channel is position 0. + bitrate: :class:`int` + The channel's preferred audio bitrate in bits per second. + user_limit: :class:`int` + The channel's limit for number of members that can be in a voice channel. + rtc_region: Optional[:class:`VoiceRegion`] + The region for the voice channel's voice communication. + A value of ``None`` indicates automatic voice region detection. + + .. versionadded:: 1.7 + """ + + __slots__ = () + + def __repr__(self): + attrs = [ + ('id', self.id), + ('name', self.name), + ('rtc_region', self.rtc_region), + ('position', self.position), + ('bitrate', self.bitrate), + ('user_limit', self.user_limit), + ('category_id', self.category_id) + ] + return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) + + @property + def type(self): + """:class:`ChannelType`: The channel's Discord type.""" + return ChannelType.voice + + @utils.copy_doc(discord.abc.GuildChannel.clone) + async def clone(self, *, name=None, reason=None): + return await self._clone_impl({ + 'bitrate': self.bitrate, + 'user_limit': self.user_limit + }, name=name, reason=reason) + + async def edit(self, *, reason=None, **options): + """|coro| + + Edits the channel. + + You must have the :attr:`~Permissions.manage_channels` permission to + use this. + + .. versionchanged:: 1.3 + The ``overwrites`` keyword-only parameter was added. + + Parameters + ---------- + name: :class:`str` + The new channel's name. + bitrate: :class:`int` + The new channel's bitrate. + user_limit: :class:`int` + The new channel's user limit. + position: :class:`int` + The new channel's position. + sync_permissions: :class:`bool` + Whether to sync permissions with the channel's new or pre-existing + category. Defaults to ``False``. + category: Optional[:class:`CategoryChannel`] + The new category for this channel. Can be ``None`` to remove the + category. + reason: Optional[:class:`str`] + The reason for editing this channel. Shows up on the audit log. + overwrites: :class:`dict` + A :class:`dict` of target (either a role or a member) to + :class:`PermissionOverwrite` to apply to the channel. + rtc_region: Optional[:class:`VoiceRegion`] + The new region for the voice channel's voice communication. + A value of ``None`` indicates automatic voice region detection. + + .. versionadded:: 1.7 + + Raises + ------ + InvalidArgument + If the permission overwrite information is not in proper form. + Forbidden + You do not have permissions to edit the channel. + HTTPException + Editing the channel failed. + """ + + await self._edit(options, reason=reason) + +class StageChannel(VocalGuildChannel): + """Represents a Discord guild stage channel. + + .. versionadded:: 1.7 + + .. container:: operations + + .. describe:: x == y + + Checks if two channels are equal. + + .. describe:: x != y + + Checks if two channels are not equal. + + .. describe:: hash(x) + + Returns the channel's hash. + + .. describe:: str(x) + + Returns the channel's name. + + Attributes + ----------- + name: :class:`str` + The channel name. + guild: :class:`Guild` + The guild the channel belongs to. + id: :class:`int` + The channel ID. + topic: Optional[:class:`str`] + The channel's topic. ``None`` if it isn't set. + category_id: Optional[:class:`int`] + The category channel ID this channel belongs to, if applicable. + position: :class:`int` + The position in the channel list. This is a number that starts at 0. e.g. the + top channel is position 0. + bitrate: :class:`int` + The channel's preferred audio bitrate in bits per second. + user_limit: :class:`int` + The channel's limit for number of members that can be in a stage channel. + rtc_region: Optional[:class:`VoiceRegion`] + The region for the stage channel's voice communication. + A value of ``None`` indicates automatic voice region detection. + """ + __slots__ = ('topic',) + + def __repr__(self): + attrs = [ + ('id', self.id), + ('name', self.name), + ('topic', self.topic), + ('rtc_region', self.rtc_region), + ('position', self.position), + ('bitrate', self.bitrate), + ('user_limit', self.user_limit), + ('category_id', self.category_id) + ] + return '<%s %s>' % (self.__class__.__name__, ' '.join('%s=%r' % t for t in attrs)) + + def _update(self, guild, data): + super()._update(guild, data) + self.topic = data.get('topic') + + @property + def requesting_to_speak(self): + """List[:class:`Member`]: A list of members who are requesting to speak in the stage channel.""" + return [member for member in self.members if member.voice.requested_to_speak_at is not None] + + @property + def type(self): + """:class:`ChannelType`: The channel's Discord type.""" + return ChannelType.stage_voice + + @utils.copy_doc(discord.abc.GuildChannel.clone) + async def clone(self, *, name=None, reason=None): + return await self._clone_impl({ + 'topic': self.topic, + }, name=name, reason=reason) + + async def edit(self, *, reason=None, **options): + """|coro| + + Edits the channel. + + You must have the :attr:`~Permissions.manage_channels` permission to + use this. + + Parameters + ---------- + name: :class:`str` + The new channel's name. + topic: :class:`str` + The new channel's topic. + position: :class:`int` + The new channel's position. + sync_permissions: :class:`bool` + Whether to sync permissions with the channel's new or pre-existing + category. Defaults to ``False``. + category: Optional[:class:`CategoryChannel`] + The new category for this channel. Can be ``None`` to remove the + category. + reason: Optional[:class:`str`] + The reason for editing this channel. Shows up on the audit log. + overwrites: :class:`dict` + A :class:`dict` of target (either a role or a member) to + :class:`PermissionOverwrite` to apply to the channel. + rtc_region: Optional[:class:`VoiceRegion`] + The new region for the stage channel's voice communication. + A value of ``None`` indicates automatic voice region detection. + + Raises + ------ + InvalidArgument + If the permission overwrite information is not in proper form. + Forbidden + You do not have permissions to edit the channel. + HTTPException + Editing the channel failed. + """ + + await self._edit(options, reason=reason) + +class CategoryChannel(discord.abc.GuildChannel, Hashable): + """Represents a Discord channel category. + + These are useful to group channels to logical compartments. + + .. container:: operations + + .. describe:: x == y + + Checks if two channels are equal. + + .. describe:: x != y + + Checks if two channels are not equal. + + .. describe:: hash(x) + + Returns the category's hash. + + .. describe:: str(x) + + Returns the category's name. + + Attributes + ----------- + name: :class:`str` + The category name. + guild: :class:`Guild` + The guild the category belongs to. + id: :class:`int` + The category channel ID. + position: :class:`int` + The position in the category list. This is a number that starts at 0. e.g. the + top category is position 0. + """ + + __slots__ = ('name', 'id', 'guild', 'nsfw', '_state', 'position', '_overwrites', 'category_id') + + def __init__(self, *, state, guild, data): + self._state = state + self.id = int(data['id']) + self._update(guild, data) + + def __repr__(self): + return ''.format(self) + + def _update(self, guild, data): + self.guild = guild + self.name = data['name'] + self.category_id = utils._get_as_snowflake(data, 'parent_id') + self.nsfw = data.get('nsfw', False) + self.position = data['position'] + self._fill_overwrites(data) + + @property + def _sorting_bucket(self): + return ChannelType.category.value + + @property + def type(self): + """:class:`ChannelType`: The channel's Discord type.""" + return ChannelType.category + + def is_nsfw(self): + """:class:`bool`: Checks if the category is NSFW.""" + return self.nsfw + + @utils.copy_doc(discord.abc.GuildChannel.clone) + async def clone(self, *, name=None, reason=None): + return await self._clone_impl({ + 'nsfw': self.nsfw + }, name=name, reason=reason) + + async def edit(self, *, reason=None, **options): + """|coro| + + Edits the channel. + + You must have the :attr:`~Permissions.manage_channels` permission to + use this. + + .. versionchanged:: 1.3 + The ``overwrites`` keyword-only parameter was added. + + Parameters + ---------- + name: :class:`str` + The new category's name. + position: :class:`int` + The new category's position. + nsfw: :class:`bool` + To mark the category as NSFW or not. + reason: Optional[:class:`str`] + The reason for editing this category. Shows up on the audit log. + overwrites: :class:`dict` + A :class:`dict` of target (either a role or a member) to + :class:`PermissionOverwrite` to apply to the channel. + + Raises + ------ + InvalidArgument + If position is less than 0 or greater than the number of categories. + Forbidden + You do not have permissions to edit the category. + HTTPException + Editing the category failed. + """ + + await self._edit(options=options, reason=reason) + + @utils.copy_doc(discord.abc.GuildChannel.move) + async def move(self, **kwargs): + kwargs.pop('category', None) + await super().move(**kwargs) + + @property + def channels(self): + """List[:class:`abc.GuildChannel`]: Returns the channels that are under this category. + + These are sorted by the official Discord UI, which places voice channels below the text channels. + """ + def comparator(channel): + return (not isinstance(channel, TextChannel), channel.position) + + ret = [c for c in self.guild.channels if c.category_id == self.id] + ret.sort(key=comparator) + return ret + + @property + def text_channels(self): + """List[:class:`TextChannel`]: Returns the text channels that are under this category.""" + ret = [c for c in self.guild.channels + if c.category_id == self.id + and isinstance(c, TextChannel)] + ret.sort(key=lambda c: (c.position, c.id)) + return ret + + @property + def voice_channels(self): + """List[:class:`VoiceChannel`]: Returns the voice channels that are under this category.""" + ret = [c for c in self.guild.channels + if c.category_id == self.id + and isinstance(c, VoiceChannel)] + ret.sort(key=lambda c: (c.position, c.id)) + return ret + + @property + def stage_channels(self): + """List[:class:`StageChannel`]: Returns the voice channels that are under this category. + + .. versionadded:: 1.7 + """ + ret = [c for c in self.guild.channels + if c.category_id == self.id + and isinstance(c, StageChannel)] + ret.sort(key=lambda c: (c.position, c.id)) + return ret + + async def create_text_channel(self, name, *, overwrites=None, reason=None, **options): + """|coro| + + A shortcut method to :meth:`Guild.create_text_channel` to create a :class:`TextChannel` in the category. + + Returns + ------- + :class:`TextChannel` + The channel that was just created. + """ + return await self.guild.create_text_channel(name, overwrites=overwrites, category=self, reason=reason, **options) + + async def create_voice_channel(self, name, *, overwrites=None, reason=None, **options): + """|coro| + + A shortcut method to :meth:`Guild.create_voice_channel` to create a :class:`VoiceChannel` in the category. + + Returns + ------- + :class:`VoiceChannel` + The channel that was just created. + """ + return await self.guild.create_voice_channel(name, overwrites=overwrites, category=self, reason=reason, **options) + + async def create_stage_channel(self, name, *, overwrites=None, reason=None, **options): + """|coro| + + A shortcut method to :meth:`Guild.create_stage_channel` to create a :class:`StageChannel` in the category. + + .. versionadded:: 1.7 + + Returns + ------- + :class:`StageChannel` + The channel that was just created. + """ + return await self.guild.create_stage_channel(name, overwrites=overwrites, category=self, reason=reason, **options) + +class StoreChannel(discord.abc.GuildChannel, Hashable): + """Represents a Discord guild store channel. + + .. container:: operations + + .. describe:: x == y + + Checks if two channels are equal. + + .. describe:: x != y + + Checks if two channels are not equal. + + .. describe:: hash(x) + + Returns the channel's hash. + + .. describe:: str(x) + + Returns the channel's name. + + Attributes + ----------- + name: :class:`str` + The channel name. + guild: :class:`Guild` + The guild the channel belongs to. + id: :class:`int` + The channel ID. + category_id: :class:`int` + The category channel ID this channel belongs to. + position: :class:`int` + The position in the channel list. This is a number that starts at 0. e.g. the + top channel is position 0. + """ + __slots__ = ('name', 'id', 'guild', '_state', 'nsfw', + 'category_id', 'position', '_overwrites',) + + def __init__(self, *, state, guild, data): + self._state = state + self.id = int(data['id']) + self._update(guild, data) + + def __repr__(self): + return ''.format(self) + + def _update(self, guild, data): + self.guild = guild + self.name = data['name'] + self.category_id = utils._get_as_snowflake(data, 'parent_id') + self.position = data['position'] + self.nsfw = data.get('nsfw', False) + self._fill_overwrites(data) + + @property + def _sorting_bucket(self): + return ChannelType.text.value + + @property + def type(self): + """:class:`ChannelType`: The channel's Discord type.""" + return ChannelType.store + + @utils.copy_doc(discord.abc.GuildChannel.permissions_for) + def permissions_for(self, member): + base = super().permissions_for(member) + + # store channels do not have voice related permissions + denied = Permissions.voice() + base.value &= ~denied.value + return base + + def is_nsfw(self): + """:class:`bool`: Checks if the channel is NSFW.""" + return self.nsfw + + @utils.copy_doc(discord.abc.GuildChannel.clone) + async def clone(self, *, name=None, reason=None): + return await self._clone_impl({ + 'nsfw': self.nsfw + }, name=name, reason=reason) + + async def edit(self, *, reason=None, **options): + """|coro| + + Edits the channel. + + You must have the :attr:`~Permissions.manage_channels` permission to + use this. + + Parameters + ---------- + name: :class:`str` + The new channel name. + position: :class:`int` + The new channel's position. + nsfw: :class:`bool` + To mark the channel as NSFW or not. + sync_permissions: :class:`bool` + Whether to sync permissions with the channel's new or pre-existing + category. Defaults to ``False``. + category: Optional[:class:`CategoryChannel`] + The new category for this channel. Can be ``None`` to remove the + category. + reason: Optional[:class:`str`] + The reason for editing this channel. Shows up on the audit log. + overwrites: :class:`dict` + A :class:`dict` of target (either a role or a member) to + :class:`PermissionOverwrite` to apply to the channel. + + .. versionadded:: 1.3 + + Raises + ------ + InvalidArgument + If position is less than 0 or greater than the number of channels, or if + the permission overwrite information is not in proper form. + Forbidden + You do not have permissions to edit the channel. + HTTPException + Editing the channel failed. + """ + await self._edit(options, reason=reason) + +class DMChannel(discord.abc.Messageable, Hashable): + """Represents a Discord direct message channel. + + .. container:: operations + + .. describe:: x == y + + Checks if two channels are equal. + + .. describe:: x != y + + Checks if two channels are not equal. + + .. describe:: hash(x) + + Returns the channel's hash. + + .. describe:: str(x) + + Returns a string representation of the channel + + Attributes + ---------- + recipient: :class:`User` + The user you are participating with in the direct message channel. + me: :class:`ClientUser` + The user presenting yourself. + id: :class:`int` + The direct message channel ID. + """ + + __slots__ = ('id', 'recipient', 'me', '_state') + + def __init__(self, *, me, state, data): + self._state = state + self.recipient = state.store_user(data['recipients'][0]) + self.me = me + self.id = int(data['id']) + + async def _get_channel(self): + return self + + def __str__(self): + return 'Direct Message with %s' % self.recipient + + def __repr__(self): + return ''.format(self) + + @property + def type(self): + """:class:`ChannelType`: The channel's Discord type.""" + return ChannelType.private + + @property + def created_at(self): + """:class:`datetime.datetime`: Returns the direct message channel's creation time in UTC.""" + return utils.snowflake_time(self.id) + + def permissions_for(self, user=None): + """Handles permission resolution for a :class:`User`. + + This function is there for compatibility with other channel types. + + Actual direct messages do not really have the concept of permissions. + + This returns all the Text related permissions set to ``True`` except: + + - :attr:`~Permissions.send_tts_messages`: You cannot send TTS messages in a DM. + - :attr:`~Permissions.manage_messages`: You cannot delete others messages in a DM. + + Parameters + ----------- + user: :class:`User` + The user to check permissions for. This parameter is ignored + but kept for compatibility. + + Returns + -------- + :class:`Permissions` + The resolved permissions. + """ + + base = Permissions.text() + base.read_messages = True + base.send_tts_messages = False + base.manage_messages = False + return base + + def get_partial_message(self, message_id): + """Creates a :class:`PartialMessage` from the message ID. + + This is useful if you want to work with a message and only have its ID without + doing an unnecessary API call. + + .. versionadded:: 1.6 + + Parameters + ------------ + message_id: :class:`int` + The message ID to create a partial message for. + + Returns + --------- + :class:`PartialMessage` + The partial message. + """ + + from .message import PartialMessage + return PartialMessage(channel=self, id=message_id) + +class GroupChannel(discord.abc.Messageable, Hashable): + """Represents a Discord group channel. + + .. container:: operations + + .. describe:: x == y + + Checks if two channels are equal. + + .. describe:: x != y + + Checks if two channels are not equal. + + .. describe:: hash(x) + + Returns the channel's hash. + + .. describe:: str(x) + + Returns a string representation of the channel + + Attributes + ---------- + recipients: List[:class:`User`] + The users you are participating with in the group channel. + me: :class:`ClientUser` + The user presenting yourself. + id: :class:`int` + The group channel ID. + owner: :class:`User` + The user that owns the group channel. + icon: Optional[:class:`str`] + The group channel's icon hash if provided. + name: Optional[:class:`str`] + The group channel's name if provided. + """ + + __slots__ = ('id', 'recipients', 'owner', 'icon', 'name', 'me', '_state') + + def __init__(self, *, me, state, data): + self._state = state + self.id = int(data['id']) + self.me = me + self._update_group(data) + + def _update_group(self, data): + owner_id = utils._get_as_snowflake(data, 'owner_id') + self.icon = data.get('icon') + self.name = data.get('name') + + try: + self.recipients = [self._state.store_user(u) for u in data['recipients']] + except KeyError: + pass + + if owner_id == self.me.id: + self.owner = self.me + else: + self.owner = utils.find(lambda u: u.id == owner_id, self.recipients) + + async def _get_channel(self): + return self + + def __str__(self): + if self.name: + return self.name + + if len(self.recipients) == 0: + return 'Unnamed' + + return ', '.join(map(lambda x: x.name, self.recipients)) + + def __repr__(self): + return ''.format(self) + + @property + def type(self): + """:class:`ChannelType`: The channel's Discord type.""" + return ChannelType.group + + @property + def icon_url(self): + """:class:`Asset`: Returns the channel's icon asset if available. + + This is equivalent to calling :meth:`icon_url_as` with + the default parameters ('webp' format and a size of 1024). + """ + return self.icon_url_as() + + def icon_url_as(self, *, format='webp', size=1024): + """Returns an :class:`Asset` for the icon the channel has. + + The format must be one of 'webp', 'jpeg', 'jpg' or 'png'. + The size must be a power of 2 between 16 and 4096. + + .. versionadded:: 2.0 + + Parameters + ----------- + format: :class:`str` + The format to attempt to convert the icon to. Defaults to 'webp'. + size: :class:`int` + The size of the image to display. + + Raises + ------ + InvalidArgument + Bad image format passed to ``format`` or invalid ``size``. + + Returns + -------- + :class:`Asset` + The resulting CDN asset. + """ + return Asset._from_icon(self._state, self, 'channel', format=format, size=size) + + @property + def created_at(self): + """:class:`datetime.datetime`: Returns the channel's creation time in UTC.""" + return utils.snowflake_time(self.id) + + def permissions_for(self, user): + """Handles permission resolution for a :class:`User`. + + This function is there for compatibility with other channel types. + + Actual direct messages do not really have the concept of permissions. + + This returns all the Text related permissions set to ``True`` except: + + - :attr:`~Permissions.send_tts_messages`: You cannot send TTS messages in a DM. + - :attr:`~Permissions.manage_messages`: You cannot delete others messages in a DM. + + This also checks the kick_members permission if the user is the owner. + + Parameters + ----------- + user: :class:`User` + The user to check permissions for. + + Returns + -------- + :class:`Permissions` + The resolved permissions for the user. + """ + + base = Permissions.text() + base.read_messages = True + base.send_tts_messages = False + base.manage_messages = False + base.mention_everyone = True + + if user.id == self.owner.id: + base.kick_members = True + + return base + + @utils.deprecated() + async def add_recipients(self, *recipients): + r"""|coro| + + Adds recipients to this group. + + A group can only have a maximum of 10 members. + Attempting to add more ends up in an exception. To + add a recipient to the group, you must have a relationship + with the user of type :attr:`RelationshipType.friend`. + + .. deprecated:: 1.7 + + Parameters + ----------- + \*recipients: :class:`User` + An argument list of users to add to this group. + + Raises + ------- + HTTPException + Adding a recipient to this group failed. + """ + + # TODO: wait for the corresponding WS event + + req = self._state.http.add_group_recipient + for recipient in recipients: + await req(self.id, recipient.id) + + @utils.deprecated() + async def remove_recipients(self, *recipients): + r"""|coro| + + Removes recipients from this group. + + .. deprecated:: 1.7 + + Parameters + ----------- + \*recipients: :class:`User` + An argument list of users to remove from this group. + + Raises + ------- + HTTPException + Removing a recipient from this group failed. + """ + + # TODO: wait for the corresponding WS event + + req = self._state.http.remove_group_recipient + for recipient in recipients: + await req(self.id, recipient.id) + + @utils.deprecated() + async def edit(self, **fields): + """|coro| + + Edits the group. + + .. deprecated:: 1.7 + + Parameters + ----------- + name: Optional[:class:`str`] + The new name to change the group to. + Could be ``None`` to remove the name. + icon: Optional[:class:`bytes`] + A :term:`py:bytes-like object` representing the new icon. + Could be ``None`` to remove the icon. + + Raises + ------- + HTTPException + Editing the group failed. + """ + + try: + icon_bytes = fields['icon'] + except KeyError: + pass + else: + if icon_bytes is not None: + fields['icon'] = utils._bytes_to_base64_data(icon_bytes) + + data = await self._state.http.edit_group(self.id, **fields) + self._update_group(data) + + async def leave(self): + """|coro| + + Leave the group. + + If you are the only one in the group, this deletes it as well. + + Raises + ------- + HTTPException + Leaving the group failed. + """ + + await self._state.http.leave_group(self.id) + +def _channel_factory(channel_type): + value = try_enum(ChannelType, channel_type) + if value is ChannelType.text: + return TextChannel, value + elif value is ChannelType.voice: + return VoiceChannel, value + elif value is ChannelType.private: + return DMChannel, value + elif value is ChannelType.category: + return CategoryChannel, value + elif value is ChannelType.group: + return GroupChannel, value + elif value is ChannelType.news: + return TextChannel, value + elif value is ChannelType.store: + return StoreChannel, value + elif value is ChannelType.stage_voice: + return StageChannel, value + else: + return None, value diff --git a/dist/ba_data/python-site-packages/discord/client.py b/dist/ba_data/python-site-packages/discord/client.py new file mode 100644 index 0000000..1c35fdd --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/client.py @@ -0,0 +1,1494 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import asyncio +import logging +import signal +import sys +import traceback + +import aiohttp + +from .user import User, Profile +from .invite import Invite +from .template import Template +from .widget import Widget +from .guild import Guild +from .channel import _channel_factory +from .enums import ChannelType +from .mentions import AllowedMentions +from .errors import * +from .enums import Status, VoiceRegion +from .gateway import * +from .activity import BaseActivity, create_activity +from .voice_client import VoiceClient +from .http import HTTPClient +from .state import ConnectionState +from . import utils +from .object import Object +from .backoff import ExponentialBackoff +from .webhook import Webhook +from .iterators import GuildIterator +from .appinfo import AppInfo + +log = logging.getLogger(__name__) + +def _cancel_tasks(loop): + try: + task_retriever = asyncio.Task.all_tasks + except AttributeError: + # future proofing for 3.9 I guess + task_retriever = asyncio.all_tasks + + tasks = {t for t in task_retriever(loop=loop) if not t.done()} + + if not tasks: + return + + log.info('Cleaning up after %d tasks.', len(tasks)) + for task in tasks: + task.cancel() + + loop.run_until_complete(asyncio.gather(*tasks, return_exceptions=True)) + log.info('All tasks finished cancelling.') + + for task in tasks: + if task.cancelled(): + continue + if task.exception() is not None: + loop.call_exception_handler({ + 'message': 'Unhandled exception during Client.run shutdown.', + 'exception': task.exception(), + 'task': task + }) + +def _cleanup_loop(loop): + try: + _cancel_tasks(loop) + if sys.version_info >= (3, 6): + loop.run_until_complete(loop.shutdown_asyncgens()) + finally: + log.info('Closing the event loop.') + loop.close() + +class _ClientEventTask(asyncio.Task): + def __init__(self, original_coro, event_name, coro, *, loop): + super().__init__(coro, loop=loop) + self.__event_name = event_name + self.__original_coro = original_coro + + def __repr__(self): + info = [ + ('state', self._state.lower()), + ('event', self.__event_name), + ('coro', repr(self.__original_coro)), + ] + if self._exception is not None: + info.append(('exception', repr(self._exception))) + return ''.format(' '.join('%s=%s' % t for t in info)) + +class Client: + r"""Represents a client connection that connects to Discord. + This class is used to interact with the Discord WebSocket and API. + + A number of options can be passed to the :class:`Client`. + + Parameters + ----------- + max_messages: Optional[:class:`int`] + The maximum number of messages to store in the internal message cache. + This defaults to ``1000``. Passing in ``None`` disables the message cache. + + .. versionchanged:: 1.3 + Allow disabling the message cache and change the default size to ``1000``. + loop: Optional[:class:`asyncio.AbstractEventLoop`] + The :class:`asyncio.AbstractEventLoop` to use for asynchronous operations. + Defaults to ``None``, in which case the default event loop is used via + :func:`asyncio.get_event_loop()`. + connector: :class:`aiohttp.BaseConnector` + The connector to use for connection pooling. + proxy: Optional[:class:`str`] + Proxy URL. + proxy_auth: Optional[:class:`aiohttp.BasicAuth`] + An object that represents proxy HTTP Basic Authorization. + shard_id: Optional[:class:`int`] + Integer starting at ``0`` and less than :attr:`.shard_count`. + shard_count: Optional[:class:`int`] + The total number of shards. + intents: :class:`Intents` + The intents that you want to enable for the session. This is a way of + disabling and enabling certain gateway events from triggering and being sent. + If not given, defaults to a regularly constructed :class:`Intents` class. + + .. versionadded:: 1.5 + member_cache_flags: :class:`MemberCacheFlags` + Allows for finer control over how the library caches members. + If not given, defaults to cache as much as possible with the + currently selected intents. + + .. versionadded:: 1.5 + fetch_offline_members: :class:`bool` + A deprecated alias of ``chunk_guilds_at_startup``. + chunk_guilds_at_startup: :class:`bool` + Indicates if :func:`.on_ready` should be delayed to chunk all guilds + at start-up if necessary. This operation is incredibly slow for large + amounts of guilds. The default is ``True`` if :attr:`Intents.members` + is ``True``. + + .. versionadded:: 1.5 + status: Optional[:class:`.Status`] + A status to start your presence with upon logging on to Discord. + activity: Optional[:class:`.BaseActivity`] + An activity to start your presence with upon logging on to Discord. + allowed_mentions: Optional[:class:`AllowedMentions`] + Control how the client handles mentions by default on every message sent. + + .. versionadded:: 1.4 + heartbeat_timeout: :class:`float` + The maximum numbers of seconds before timing out and restarting the + WebSocket in the case of not receiving a HEARTBEAT_ACK. Useful if + processing the initial packets take too long to the point of disconnecting + you. The default timeout is 60 seconds. + guild_ready_timeout: :class:`float` + The maximum number of seconds to wait for the GUILD_CREATE stream to end before + preparing the member cache and firing READY. The default timeout is 2 seconds. + + .. versionadded:: 1.4 + guild_subscriptions: :class:`bool` + Whether to dispatch presence or typing events. Defaults to ``True``. + + .. versionadded:: 1.3 + + .. warning:: + + If this is set to ``False`` then the following features will be disabled: + + - No user related updates (:func:`on_user_update` will not dispatch) + - All member related events will be disabled. + - :func:`on_member_update` + - :func:`on_member_join` + - :func:`on_member_remove` + + - Typing events will be disabled (:func:`on_typing`). + - If ``fetch_offline_members`` is set to ``False`` then the user cache will not exist. + This makes it difficult or impossible to do many things, for example: + + - Computing permissions + - Querying members in a voice channel via :attr:`VoiceChannel.members` will be empty. + - Most forms of receiving :class:`Member` will be + receiving :class:`User` instead, except for message events. + - :attr:`Guild.owner` will usually resolve to ``None``. + - :meth:`Guild.get_member` will usually be unavailable. + - Anything that involves using :class:`Member`. + - :attr:`users` will not be as populated. + - etc. + + In short, this makes it so the only member you can reliably query is the + message author. Useful for bots that do not require any state. + assume_unsync_clock: :class:`bool` + Whether to assume the system clock is unsynced. This applies to the ratelimit handling + code. If this is set to ``True``, the default, then the library uses the time to reset + a rate limit bucket given by Discord. If this is ``False`` then your system clock is + used to calculate how long to sleep for. If this is set to ``False`` it is recommended to + sync your system clock to Google's NTP server. + + .. versionadded:: 1.3 + + Attributes + ----------- + ws + The websocket gateway the client is currently connected to. Could be ``None``. + loop: :class:`asyncio.AbstractEventLoop` + The event loop that the client uses for HTTP requests and websocket operations. + """ + def __init__(self, *, loop=None, **options): + self.ws = None + self.loop = asyncio.get_event_loop() if loop is None else loop + self._listeners = {} + self.shard_id = options.get('shard_id') + self.shard_count = options.get('shard_count') + + connector = options.pop('connector', None) + proxy = options.pop('proxy', None) + proxy_auth = options.pop('proxy_auth', None) + unsync_clock = options.pop('assume_unsync_clock', True) + self.http = HTTPClient(connector, proxy=proxy, proxy_auth=proxy_auth, unsync_clock=unsync_clock, loop=self.loop) + + self._handlers = { + 'ready': self._handle_ready + } + + self._hooks = { + 'before_identify': self._call_before_identify_hook + } + + self._connection = self._get_state(**options) + self._connection.shard_count = self.shard_count + self._closed = False + self._ready = asyncio.Event() + self._connection._get_websocket = self._get_websocket + self._connection._get_client = lambda: self + + if VoiceClient.warn_nacl: + VoiceClient.warn_nacl = False + log.warning("PyNaCl is not installed, voice will NOT be supported") + + # internals + + def _get_websocket(self, guild_id=None, *, shard_id=None): + return self.ws + + def _get_state(self, **options): + return ConnectionState(dispatch=self.dispatch, handlers=self._handlers, + hooks=self._hooks, syncer=self._syncer, http=self.http, loop=self.loop, **options) + + async def _syncer(self, guilds): + await self.ws.request_sync(guilds) + + def _handle_ready(self): + self._ready.set() + + @property + def latency(self): + """:class:`float`: Measures latency between a HEARTBEAT and a HEARTBEAT_ACK in seconds. + + This could be referred to as the Discord WebSocket protocol latency. + """ + ws = self.ws + return float('nan') if not ws else ws.latency + + def is_ws_ratelimited(self): + """:class:`bool`: Whether the websocket is currently rate limited. + + This can be useful to know when deciding whether you should query members + using HTTP or via the gateway. + + .. versionadded:: 1.6 + """ + if self.ws: + return self.ws.is_ratelimited() + return False + + @property + def user(self): + """Optional[:class:`.ClientUser`]: Represents the connected client. ``None`` if not logged in.""" + return self._connection.user + + @property + def guilds(self): + """List[:class:`.Guild`]: The guilds that the connected client is a member of.""" + return self._connection.guilds + + @property + def emojis(self): + """List[:class:`.Emoji`]: The emojis that the connected client has.""" + return self._connection.emojis + + @property + def cached_messages(self): + """Sequence[:class:`.Message`]: Read-only list of messages the connected client has cached. + + .. versionadded:: 1.1 + """ + return utils.SequenceProxy(self._connection._messages or []) + + @property + def private_channels(self): + """List[:class:`.abc.PrivateChannel`]: The private channels that the connected client is participating on. + + .. note:: + + This returns only up to 128 most recent private channels due to an internal working + on how Discord deals with private channels. + """ + return self._connection.private_channels + + @property + def voice_clients(self): + """List[:class:`.VoiceProtocol`]: Represents a list of voice connections. + + These are usually :class:`.VoiceClient` instances. + """ + return self._connection.voice_clients + + def is_ready(self): + """:class:`bool`: Specifies if the client's internal cache is ready for use.""" + return self._ready.is_set() + + async def _run_event(self, coro, event_name, *args, **kwargs): + try: + await coro(*args, **kwargs) + except asyncio.CancelledError: + pass + except Exception: + try: + await self.on_error(event_name, *args, **kwargs) + except asyncio.CancelledError: + pass + + def _schedule_event(self, coro, event_name, *args, **kwargs): + wrapped = self._run_event(coro, event_name, *args, **kwargs) + # Schedules the task + return _ClientEventTask(original_coro=coro, event_name=event_name, coro=wrapped, loop=self.loop) + + def dispatch(self, event, *args, **kwargs): + log.debug('Dispatching event %s', event) + method = 'on_' + event + + listeners = self._listeners.get(event) + if listeners: + removed = [] + for i, (future, condition) in enumerate(listeners): + if future.cancelled(): + removed.append(i) + continue + + try: + result = condition(*args) + except Exception as exc: + future.set_exception(exc) + removed.append(i) + else: + if result: + if len(args) == 0: + future.set_result(None) + elif len(args) == 1: + future.set_result(args[0]) + else: + future.set_result(args) + removed.append(i) + + if len(removed) == len(listeners): + self._listeners.pop(event) + else: + for idx in reversed(removed): + del listeners[idx] + + try: + coro = getattr(self, method) + except AttributeError: + pass + else: + self._schedule_event(coro, method, *args, **kwargs) + + async def on_error(self, event_method, *args, **kwargs): + """|coro| + + The default error handler provided by the client. + + By default this prints to :data:`sys.stderr` however it could be + overridden to have a different implementation. + Check :func:`~discord.on_error` for more details. + """ + print('Ignoring exception in {}'.format(event_method), file=sys.stderr) + traceback.print_exc() + + @utils.deprecated('Guild.chunk') + async def request_offline_members(self, *guilds): + r"""|coro| + + Requests previously offline members from the guild to be filled up + into the :attr:`.Guild.members` cache. This function is usually not + called. It should only be used if you have the ``fetch_offline_members`` + parameter set to ``False``. + + When the client logs on and connects to the websocket, Discord does + not provide the library with offline members if the number of members + in the guild is larger than 250. You can check if a guild is large + if :attr:`.Guild.large` is ``True``. + + .. warning:: + + This method is deprecated. Use :meth:`Guild.chunk` instead. + + Parameters + ----------- + \*guilds: :class:`.Guild` + An argument list of guilds to request offline members for. + + Raises + ------- + :exc:`.InvalidArgument` + If any guild is unavailable in the collection. + """ + if any(g.unavailable for g in guilds): + raise InvalidArgument('An unavailable guild was passed.') + + for guild in guilds: + await self._connection.chunk_guild(guild) + + # hooks + + async def _call_before_identify_hook(self, shard_id, *, initial=False): + # This hook is an internal hook that actually calls the public one. + # It allows the library to have its own hook without stepping on the + # toes of those who need to override their own hook. + await self.before_identify_hook(shard_id, initial=initial) + + async def before_identify_hook(self, shard_id, *, initial=False): + """|coro| + + A hook that is called before IDENTIFYing a session. This is useful + if you wish to have more control over the synchronization of multiple + IDENTIFYing clients. + + The default implementation sleeps for 5 seconds. + + .. versionadded:: 1.4 + + Parameters + ------------ + shard_id: :class:`int` + The shard ID that requested being IDENTIFY'd + initial: :class:`bool` + Whether this IDENTIFY is the first initial IDENTIFY. + """ + + if not initial: + await asyncio.sleep(5.0) + + # login state management + + async def login(self, token, *, bot=True): + """|coro| + + Logs in the client with the specified credentials. + + This function can be used in two different ways. + + .. warning:: + + Logging on with a user token is against the Discord + `Terms of Service `_ + and doing so might potentially get your account banned. + Use this at your own risk. + + Parameters + ----------- + token: :class:`str` + The authentication token. Do not prefix this token with + anything as the library will do it for you. + bot: :class:`bool` + Keyword argument that specifies if the account logging on is a bot + token or not. + + .. deprecated:: 1.7 + + Raises + ------ + :exc:`.LoginFailure` + The wrong credentials are passed. + :exc:`.HTTPException` + An unknown HTTP related error occurred, + usually when it isn't 200 or the known incorrect credentials + passing status code. + """ + + log.info('logging in using static token') + await self.http.static_login(token.strip(), bot=bot) + self._connection.is_bot = bot + + @utils.deprecated('Client.close') + async def logout(self): + """|coro| + + Logs out of Discord and closes all connections. + + .. deprecated:: 1.7 + + .. note:: + + This is just an alias to :meth:`close`. If you want + to do extraneous cleanup when subclassing, it is suggested + to override :meth:`close` instead. + """ + await self.close() + + async def connect(self, *, reconnect=True): + """|coro| + + Creates a websocket connection and lets the websocket listen + to messages from Discord. This is a loop that runs the entire + event system and miscellaneous aspects of the library. Control + is not resumed until the WebSocket connection is terminated. + + Parameters + ----------- + reconnect: :class:`bool` + If we should attempt reconnecting, either due to internet + failure or a specific failure on Discord's part. Certain + disconnects that lead to bad state will not be handled (such as + invalid sharding payloads or bad tokens). + + Raises + ------- + :exc:`.GatewayNotFound` + If the gateway to connect to Discord is not found. Usually if this + is thrown then there is a Discord API outage. + :exc:`.ConnectionClosed` + The websocket connection has been terminated. + """ + + backoff = ExponentialBackoff() + ws_params = { + 'initial': True, + 'shard_id': self.shard_id, + } + while not self.is_closed(): + try: + coro = DiscordWebSocket.from_client(self, **ws_params) + self.ws = await asyncio.wait_for(coro, timeout=60.0) + ws_params['initial'] = False + while True: + await self.ws.poll_event() + except ReconnectWebSocket as e: + log.info('Got a request to %s the websocket.', e.op) + self.dispatch('disconnect') + ws_params.update(sequence=self.ws.sequence, resume=e.resume, session=self.ws.session_id) + continue + except (OSError, + HTTPException, + GatewayNotFound, + ConnectionClosed, + aiohttp.ClientError, + asyncio.TimeoutError) as exc: + + self.dispatch('disconnect') + if not reconnect: + await self.close() + if isinstance(exc, ConnectionClosed) and exc.code == 1000: + # clean close, don't re-raise this + return + raise + + if self.is_closed(): + return + + # If we get connection reset by peer then try to RESUME + if isinstance(exc, OSError) and exc.errno in (54, 10054): + ws_params.update(sequence=self.ws.sequence, initial=False, resume=True, session=self.ws.session_id) + continue + + # We should only get this when an unhandled close code happens, + # such as a clean disconnect (1000) or a bad state (bad token, no sharding, etc) + # sometimes, discord sends us 1000 for unknown reasons so we should reconnect + # regardless and rely on is_closed instead + if isinstance(exc, ConnectionClosed): + if exc.code == 4014: + raise PrivilegedIntentsRequired(exc.shard_id) from None + if exc.code != 1000: + await self.close() + raise + + retry = backoff.delay() + log.exception("Attempting a reconnect in %.2fs", retry) + await asyncio.sleep(retry) + # Always try to RESUME the connection + # If the connection is not RESUME-able then the gateway will invalidate the session. + # This is apparently what the official Discord client does. + ws_params.update(sequence=self.ws.sequence, resume=True, session=self.ws.session_id) + + async def close(self): + """|coro| + + Closes the connection to Discord. + """ + if self._closed: + return + + await self.http.close() + self._closed = True + + for voice in self.voice_clients: + try: + await voice.disconnect() + except Exception: + # if an error happens during disconnects, disregard it. + pass + + if self.ws is not None and self.ws.open: + await self.ws.close(code=1000) + + self._ready.clear() + + def clear(self): + """Clears the internal state of the bot. + + After this, the bot can be considered "re-opened", i.e. :meth:`is_closed` + and :meth:`is_ready` both return ``False`` along with the bot's internal + cache cleared. + """ + self._closed = False + self._ready.clear() + self._connection.clear() + self.http.recreate() + + async def start(self, *args, **kwargs): + """|coro| + + A shorthand coroutine for :meth:`login` + :meth:`connect`. + + Raises + ------- + TypeError + An unexpected keyword argument was received. + """ + bot = kwargs.pop('bot', True) + reconnect = kwargs.pop('reconnect', True) + + if kwargs: + raise TypeError("unexpected keyword argument(s) %s" % list(kwargs.keys())) + + await self.login(*args, bot=bot) + await self.connect(reconnect=reconnect) + + def run(self, *args, **kwargs): + """A blocking call that abstracts away the event loop + initialisation from you. + + If you want more control over the event loop then this + function should not be used. Use :meth:`start` coroutine + or :meth:`connect` + :meth:`login`. + + Roughly Equivalent to: :: + + try: + loop.run_until_complete(start(*args, **kwargs)) + except KeyboardInterrupt: + loop.run_until_complete(close()) + # cancel all tasks lingering + finally: + loop.close() + + .. warning:: + + This function must be the last function to call due to the fact that it + is blocking. That means that registration of events or anything being + called after this function call will not execute until it returns. + """ + loop = self.loop + + try: + loop.add_signal_handler(signal.SIGINT, lambda: loop.stop()) + loop.add_signal_handler(signal.SIGTERM, lambda: loop.stop()) + except NotImplementedError: + pass + + async def runner(): + try: + await self.start(*args, **kwargs) + finally: + if not self.is_closed(): + await self.close() + + def stop_loop_on_completion(f): + loop.stop() + + future = asyncio.ensure_future(runner(), loop=loop) + future.add_done_callback(stop_loop_on_completion) + try: + loop.run_forever() + except KeyboardInterrupt: + log.info('Received signal to terminate bot and event loop.') + finally: + future.remove_done_callback(stop_loop_on_completion) + log.info('Cleaning up tasks.') + _cleanup_loop(loop) + + if not future.cancelled(): + try: + return future.result() + except KeyboardInterrupt: + # I am unsure why this gets raised here but suppress it anyway + return None + + # properties + + def is_closed(self): + """:class:`bool`: Indicates if the websocket connection is closed.""" + return self._closed + + @property + def activity(self): + """Optional[:class:`.BaseActivity`]: The activity being used upon + logging in. + """ + return create_activity(self._connection._activity) + + @activity.setter + def activity(self, value): + if value is None: + self._connection._activity = None + elif isinstance(value, BaseActivity): + self._connection._activity = value.to_dict() + else: + raise TypeError('activity must derive from BaseActivity.') + + @property + def allowed_mentions(self): + """Optional[:class:`~discord.AllowedMentions`]: The allowed mention configuration. + + .. versionadded:: 1.4 + """ + return self._connection.allowed_mentions + + @allowed_mentions.setter + def allowed_mentions(self, value): + if value is None or isinstance(value, AllowedMentions): + self._connection.allowed_mentions = value + else: + raise TypeError('allowed_mentions must be AllowedMentions not {0.__class__!r}'.format(value)) + + @property + def intents(self): + """:class:`~discord.Intents`: The intents configured for this connection. + + .. versionadded:: 1.5 + """ + return self._connection.intents + + # helpers/getters + + @property + def users(self): + """List[:class:`~discord.User`]: Returns a list of all the users the bot can see.""" + return list(self._connection._users.values()) + + def get_channel(self, id): + """Returns a channel with the given ID. + + Parameters + ----------- + id: :class:`int` + The ID to search for. + + Returns + -------- + Optional[Union[:class:`.abc.GuildChannel`, :class:`.abc.PrivateChannel`]] + The returned channel or ``None`` if not found. + """ + return self._connection.get_channel(id) + + def get_guild(self, id): + """Returns a guild with the given ID. + + Parameters + ----------- + id: :class:`int` + The ID to search for. + + Returns + -------- + Optional[:class:`.Guild`] + The guild or ``None`` if not found. + """ + return self._connection._get_guild(id) + + def get_user(self, id): + """Returns a user with the given ID. + + Parameters + ----------- + id: :class:`int` + The ID to search for. + + Returns + -------- + Optional[:class:`~discord.User`] + The user or ``None`` if not found. + """ + return self._connection.get_user(id) + + def get_emoji(self, id): + """Returns an emoji with the given ID. + + Parameters + ----------- + id: :class:`int` + The ID to search for. + + Returns + -------- + Optional[:class:`.Emoji`] + The custom emoji or ``None`` if not found. + """ + return self._connection.get_emoji(id) + + def get_all_channels(self): + """A generator that retrieves every :class:`.abc.GuildChannel` the client can 'access'. + + This is equivalent to: :: + + for guild in client.guilds: + for channel in guild.channels: + yield channel + + .. note:: + + Just because you receive a :class:`.abc.GuildChannel` does not mean that + you can communicate in said channel. :meth:`.abc.GuildChannel.permissions_for` should + be used for that. + + Yields + ------ + :class:`.abc.GuildChannel` + A channel the client can 'access'. + """ + + for guild in self.guilds: + for channel in guild.channels: + yield channel + + def get_all_members(self): + """Returns a generator with every :class:`.Member` the client can see. + + This is equivalent to: :: + + for guild in client.guilds: + for member in guild.members: + yield member + + Yields + ------ + :class:`.Member` + A member the client can see. + """ + for guild in self.guilds: + for member in guild.members: + yield member + + # listeners/waiters + + async def wait_until_ready(self): + """|coro| + + Waits until the client's internal cache is all ready. + """ + await self._ready.wait() + + def wait_for(self, event, *, check=None, timeout=None): + """|coro| + + Waits for a WebSocket event to be dispatched. + + This could be used to wait for a user to reply to a message, + or to react to a message, or to edit a message in a self-contained + way. + + The ``timeout`` parameter is passed onto :func:`asyncio.wait_for`. By default, + it does not timeout. Note that this does propagate the + :exc:`asyncio.TimeoutError` for you in case of timeout and is provided for + ease of use. + + In case the event returns multiple arguments, a :class:`tuple` containing those + arguments is returned instead. Please check the + :ref:`documentation ` for a list of events and their + parameters. + + This function returns the **first event that meets the requirements**. + + Examples + --------- + + Waiting for a user reply: :: + + @client.event + async def on_message(message): + if message.content.startswith('$greet'): + channel = message.channel + await channel.send('Say hello!') + + def check(m): + return m.content == 'hello' and m.channel == channel + + msg = await client.wait_for('message', check=check) + await channel.send('Hello {.author}!'.format(msg)) + + Waiting for a thumbs up reaction from the message author: :: + + @client.event + async def on_message(message): + if message.content.startswith('$thumb'): + channel = message.channel + await channel.send('Send me that \N{THUMBS UP SIGN} reaction, mate') + + def check(reaction, user): + return user == message.author and str(reaction.emoji) == '\N{THUMBS UP SIGN}' + + try: + reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check) + except asyncio.TimeoutError: + await channel.send('\N{THUMBS DOWN SIGN}') + else: + await channel.send('\N{THUMBS UP SIGN}') + + + Parameters + ------------ + event: :class:`str` + The event name, similar to the :ref:`event reference `, + but without the ``on_`` prefix, to wait for. + check: Optional[Callable[..., :class:`bool`]] + A predicate to check what to wait for. The arguments must meet the + parameters of the event being waited for. + timeout: Optional[:class:`float`] + The number of seconds to wait before timing out and raising + :exc:`asyncio.TimeoutError`. + + Raises + ------- + asyncio.TimeoutError + If a timeout is provided and it was reached. + + Returns + -------- + Any + Returns no arguments, a single argument, or a :class:`tuple` of multiple + arguments that mirrors the parameters passed in the + :ref:`event reference `. + """ + + future = self.loop.create_future() + if check is None: + def _check(*args): + return True + check = _check + + ev = event.lower() + try: + listeners = self._listeners[ev] + except KeyError: + listeners = [] + self._listeners[ev] = listeners + + listeners.append((future, check)) + return asyncio.wait_for(future, timeout) + + # event registration + + def event(self, coro): + """A decorator that registers an event to listen to. + + You can find more info about the events on the :ref:`documentation below `. + + The events must be a :ref:`coroutine `, if not, :exc:`TypeError` is raised. + + Example + --------- + + .. code-block:: python3 + + @client.event + async def on_ready(): + print('Ready!') + + Raises + -------- + TypeError + The coroutine passed is not actually a coroutine. + """ + + if not asyncio.iscoroutinefunction(coro): + raise TypeError('event registered must be a coroutine function') + + setattr(self, coro.__name__, coro) + log.debug('%s has successfully been registered as an event', coro.__name__) + return coro + + async def change_presence(self, *, activity=None, status=None, afk=False): + """|coro| + + Changes the client's presence. + + Example + --------- + + .. code-block:: python3 + + game = discord.Game("with the API") + await client.change_presence(status=discord.Status.idle, activity=game) + + Parameters + ---------- + activity: Optional[:class:`.BaseActivity`] + The activity being done. ``None`` if no currently active activity is done. + status: Optional[:class:`.Status`] + Indicates what status to change to. If ``None``, then + :attr:`.Status.online` is used. + afk: Optional[:class:`bool`] + Indicates if you are going AFK. This allows the discord + client to know how to handle push notifications better + for you in case you are actually idle and not lying. + + Raises + ------ + :exc:`.InvalidArgument` + If the ``activity`` parameter is not the proper type. + """ + + if status is None: + status = 'online' + status_enum = Status.online + elif status is Status.offline: + status = 'invisible' + status_enum = Status.offline + else: + status_enum = status + status = str(status) + + await self.ws.change_presence(activity=activity, status=status, afk=afk) + + for guild in self._connection.guilds: + me = guild.me + if me is None: + continue + + if activity is not None: + me.activities = (activity,) + else: + me.activities = () + + me.status = status_enum + + # Guild stuff + + def fetch_guilds(self, *, limit=100, before=None, after=None): + """Retrieves an :class:`.AsyncIterator` that enables receiving your guilds. + + .. note:: + + Using this, you will only receive :attr:`.Guild.owner`, :attr:`.Guild.icon`, + :attr:`.Guild.id`, and :attr:`.Guild.name` per :class:`.Guild`. + + .. note:: + + This method is an API call. For general usage, consider :attr:`guilds` instead. + + Examples + --------- + + Usage :: + + async for guild in client.fetch_guilds(limit=150): + print(guild.name) + + Flattening into a list :: + + guilds = await client.fetch_guilds(limit=150).flatten() + # guilds is now a list of Guild... + + All parameters are optional. + + Parameters + ----------- + limit: Optional[:class:`int`] + The number of guilds to retrieve. + If ``None``, it retrieves every guild you have access to. Note, however, + that this would make it a slow operation. + Defaults to ``100``. + before: Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`] + Retrieves guilds before this date or object. + If a date is provided it must be a timezone-naive datetime representing UTC time. + after: Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`] + Retrieve guilds after this date or object. + If a date is provided it must be a timezone-naive datetime representing UTC time. + + Raises + ------ + :exc:`.HTTPException` + Getting the guilds failed. + + Yields + -------- + :class:`.Guild` + The guild with the guild data parsed. + """ + return GuildIterator(self, limit=limit, before=before, after=after) + + async def fetch_template(self, code): + """|coro| + + Gets a :class:`.Template` from a discord.new URL or code. + + Parameters + ----------- + code: Union[:class:`.Template`, :class:`str`] + The Discord Template Code or URL (must be a discord.new URL). + + Raises + ------- + :exc:`.NotFound` + The template is invalid. + :exc:`.HTTPException` + Getting the template failed. + + Returns + -------- + :class:`.Template` + The template from the URL/code. + """ + code = utils.resolve_template(code) + data = await self.http.get_template(code) + return Template(data=data, state=self._connection) + + async def fetch_guild(self, guild_id): + """|coro| + + Retrieves a :class:`.Guild` from an ID. + + .. note:: + + Using this, you will **not** receive :attr:`.Guild.channels`, :attr:`.Guild.members`, + :attr:`.Member.activity` and :attr:`.Member.voice` per :class:`.Member`. + + .. note:: + + This method is an API call. For general usage, consider :meth:`get_guild` instead. + + Parameters + ----------- + guild_id: :class:`int` + The guild's ID to fetch from. + + Raises + ------ + :exc:`.Forbidden` + You do not have access to the guild. + :exc:`.HTTPException` + Getting the guild failed. + + Returns + -------- + :class:`.Guild` + The guild from the ID. + """ + data = await self.http.get_guild(guild_id) + return Guild(data=data, state=self._connection) + + async def create_guild(self, name, region=None, icon=None, *, code=None): + """|coro| + + Creates a :class:`.Guild`. + + Bot accounts in more than 10 guilds are not allowed to create guilds. + + Parameters + ---------- + name: :class:`str` + The name of the guild. + region: :class:`.VoiceRegion` + The region for the voice communication server. + Defaults to :attr:`.VoiceRegion.us_west`. + icon: :class:`bytes` + The :term:`py:bytes-like object` representing the icon. See :meth:`.ClientUser.edit` + for more details on what is expected. + code: Optional[:class:`str`] + The code for a template to create the guild with. + + .. versionadded:: 1.4 + + Raises + ------ + :exc:`.HTTPException` + Guild creation failed. + :exc:`.InvalidArgument` + Invalid icon image format given. Must be PNG or JPG. + + Returns + ------- + :class:`.Guild` + The guild created. This is not the same guild that is + added to cache. + """ + if icon is not None: + icon = utils._bytes_to_base64_data(icon) + + region = region or VoiceRegion.us_west + region_value = region.value + + if code: + data = await self.http.create_from_template(code, name, region_value, icon) + else: + data = await self.http.create_guild(name, region_value, icon) + return Guild(data=data, state=self._connection) + + # Invite management + + async def fetch_invite(self, url, *, with_counts=True): + """|coro| + + Gets an :class:`.Invite` from a discord.gg URL or ID. + + .. note:: + + If the invite is for a guild you have not joined, the guild and channel + attributes of the returned :class:`.Invite` will be :class:`.PartialInviteGuild` and + :class:`.PartialInviteChannel` respectively. + + Parameters + ----------- + url: Union[:class:`.Invite`, :class:`str`] + The Discord invite ID or URL (must be a discord.gg URL). + with_counts: :class:`bool` + Whether to include count information in the invite. This fills the + :attr:`.Invite.approximate_member_count` and :attr:`.Invite.approximate_presence_count` + fields. + + Raises + ------- + :exc:`.NotFound` + The invite has expired or is invalid. + :exc:`.HTTPException` + Getting the invite failed. + + Returns + -------- + :class:`.Invite` + The invite from the URL/ID. + """ + + invite_id = utils.resolve_invite(url) + data = await self.http.get_invite(invite_id, with_counts=with_counts) + return Invite.from_incomplete(state=self._connection, data=data) + + async def delete_invite(self, invite): + """|coro| + + Revokes an :class:`.Invite`, URL, or ID to an invite. + + You must have the :attr:`~.Permissions.manage_channels` permission in + the associated guild to do this. + + Parameters + ---------- + invite: Union[:class:`.Invite`, :class:`str`] + The invite to revoke. + + Raises + ------- + :exc:`.Forbidden` + You do not have permissions to revoke invites. + :exc:`.NotFound` + The invite is invalid or expired. + :exc:`.HTTPException` + Revoking the invite failed. + """ + + invite_id = utils.resolve_invite(invite) + await self.http.delete_invite(invite_id) + + # Miscellaneous stuff + + async def fetch_widget(self, guild_id): + """|coro| + + Gets a :class:`.Widget` from a guild ID. + + .. note:: + + The guild must have the widget enabled to get this information. + + Parameters + ----------- + guild_id: :class:`int` + The ID of the guild. + + Raises + ------- + :exc:`.Forbidden` + The widget for this guild is disabled. + :exc:`.HTTPException` + Retrieving the widget failed. + + Returns + -------- + :class:`.Widget` + The guild's widget. + """ + data = await self.http.get_widget(guild_id) + + return Widget(state=self._connection, data=data) + + async def application_info(self): + """|coro| + + Retrieves the bot's application information. + + Raises + ------- + :exc:`.HTTPException` + Retrieving the information failed somehow. + + Returns + -------- + :class:`.AppInfo` + The bot's application information. + """ + data = await self.http.application_info() + if 'rpc_origins' not in data: + data['rpc_origins'] = None + return AppInfo(self._connection, data) + + async def fetch_user(self, user_id): + """|coro| + + Retrieves a :class:`~discord.User` based on their ID. This can only + be used by bot accounts. You do not have to share any guilds + with the user to get this information, however many operations + do require that you do. + + .. note:: + + This method is an API call. If you have :attr:`Intents.members` and member cache enabled, consider :meth:`get_user` instead. + + Parameters + ----------- + user_id: :class:`int` + The user's ID to fetch from. + + Raises + ------- + :exc:`.NotFound` + A user with this ID does not exist. + :exc:`.HTTPException` + Fetching the user failed. + + Returns + -------- + :class:`~discord.User` + The user you requested. + """ + data = await self.http.get_user(user_id) + return User(state=self._connection, data=data) + + @utils.deprecated() + async def fetch_user_profile(self, user_id): + """|coro| + + Gets an arbitrary user's profile. + + .. deprecated:: 1.7 + + .. note:: + + This can only be used by non-bot accounts. + + Parameters + ------------ + user_id: :class:`int` + The ID of the user to fetch their profile for. + + Raises + ------- + :exc:`.Forbidden` + Not allowed to fetch profiles. + :exc:`.HTTPException` + Fetching the profile failed. + + Returns + -------- + :class:`.Profile` + The profile of the user. + """ + + state = self._connection + data = await self.http.get_user_profile(user_id) + + def transform(d): + return state._get_guild(int(d['id'])) + + since = data.get('premium_since') + mutual_guilds = list(filter(None, map(transform, data.get('mutual_guilds', [])))) + user = data['user'] + return Profile(flags=user.get('flags', 0), + premium_since=utils.parse_time(since), + mutual_guilds=mutual_guilds, + user=User(data=user, state=state), + connected_accounts=data['connected_accounts']) + + async def fetch_channel(self, channel_id): + """|coro| + + Retrieves a :class:`.abc.GuildChannel` or :class:`.abc.PrivateChannel` with the specified ID. + + .. note:: + + This method is an API call. For general usage, consider :meth:`get_channel` instead. + + .. versionadded:: 1.2 + + Raises + ------- + :exc:`.InvalidData` + An unknown channel type was received from Discord. + :exc:`.HTTPException` + Retrieving the channel failed. + :exc:`.NotFound` + Invalid Channel ID. + :exc:`.Forbidden` + You do not have permission to fetch this channel. + + Returns + -------- + Union[:class:`.abc.GuildChannel`, :class:`.abc.PrivateChannel`] + The channel from the ID. + """ + data = await self.http.get_channel(channel_id) + + factory, ch_type = _channel_factory(data['type']) + if factory is None: + raise InvalidData('Unknown channel type {type} for channel ID {id}.'.format_map(data)) + + if ch_type in (ChannelType.group, ChannelType.private): + channel = factory(me=self.user, data=data, state=self._connection) + else: + guild_id = int(data['guild_id']) + guild = self.get_guild(guild_id) or Object(id=guild_id) + channel = factory(guild=guild, state=self._connection, data=data) + + return channel + + async def fetch_webhook(self, webhook_id): + """|coro| + + Retrieves a :class:`.Webhook` with the specified ID. + + Raises + -------- + :exc:`.HTTPException` + Retrieving the webhook failed. + :exc:`.NotFound` + Invalid webhook ID. + :exc:`.Forbidden` + You do not have permission to fetch this webhook. + + Returns + --------- + :class:`.Webhook` + The webhook you requested. + """ + data = await self.http.get_webhook(webhook_id) + return Webhook.from_state(data, state=self._connection) diff --git a/dist/ba_data/python-site-packages/discord/colour.py b/dist/ba_data/python-site-packages/discord/colour.py new file mode 100644 index 0000000..fbf9aae --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/colour.py @@ -0,0 +1,269 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import colorsys +import random + +class Colour: + """Represents a Discord role colour. This class is similar + to a (red, green, blue) :class:`tuple`. + + There is an alias for this called Color. + + .. container:: operations + + .. describe:: x == y + + Checks if two colours are equal. + + .. describe:: x != y + + Checks if two colours are not equal. + + .. describe:: hash(x) + + Return the colour's hash. + + .. describe:: str(x) + + Returns the hex format for the colour. + + Attributes + ------------ + value: :class:`int` + The raw integer colour value. + """ + + __slots__ = ('value',) + + def __init__(self, value): + if not isinstance(value, int): + raise TypeError('Expected int parameter, received %s instead.' % value.__class__.__name__) + + self.value = value + + def _get_byte(self, byte): + return (self.value >> (8 * byte)) & 0xff + + def __eq__(self, other): + return isinstance(other, Colour) and self.value == other.value + + def __ne__(self, other): + return not self.__eq__(other) + + def __str__(self): + return '#{:0>6x}'.format(self.value) + + def __repr__(self): + return '' % self.value + + def __hash__(self): + return hash(self.value) + + @property + def r(self): + """:class:`int`: Returns the red component of the colour.""" + return self._get_byte(2) + + @property + def g(self): + """:class:`int`: Returns the green component of the colour.""" + return self._get_byte(1) + + @property + def b(self): + """:class:`int`: Returns the blue component of the colour.""" + return self._get_byte(0) + + def to_rgb(self): + """Tuple[:class:`int`, :class:`int`, :class:`int`]: Returns an (r, g, b) tuple representing the colour.""" + return (self.r, self.g, self.b) + + @classmethod + def from_rgb(cls, r, g, b): + """Constructs a :class:`Colour` from an RGB tuple.""" + return cls((r << 16) + (g << 8) + b) + + @classmethod + def from_hsv(cls, h, s, v): + """Constructs a :class:`Colour` from an HSV tuple.""" + rgb = colorsys.hsv_to_rgb(h, s, v) + return cls.from_rgb(*(int(x * 255) for x in rgb)) + + @classmethod + def default(cls): + """A factory method that returns a :class:`Colour` with a value of ``0``.""" + return cls(0) + + @classmethod + def random(cls, *, seed=None): + """A factory method that returns a :class:`Colour` with a random hue. + + .. note:: + + The random algorithm works by choosing a colour with a random hue but + with maxed out saturation and value. + + .. versionadded:: 1.6 + + Parameters + ------------ + seed: Optional[Union[:class:`int`, :class:`str`, :class:`float`, :class:`bytes`, :class:`bytearray`]] + The seed to initialize the RNG with. If ``None`` is passed the default RNG is used. + + .. versionadded:: 1.7 + """ + rand = random if seed is None else random.Random(seed) + return cls.from_hsv(rand.random(), 1, 1) + + @classmethod + def teal(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x1abc9c``.""" + return cls(0x1abc9c) + + @classmethod + def dark_teal(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x11806a``.""" + return cls(0x11806a) + + @classmethod + def green(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x2ecc71``.""" + return cls(0x2ecc71) + + @classmethod + def dark_green(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x1f8b4c``.""" + return cls(0x1f8b4c) + + @classmethod + def blue(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x3498db``.""" + return cls(0x3498db) + + @classmethod + def dark_blue(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x206694``.""" + return cls(0x206694) + + @classmethod + def purple(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x9b59b6``.""" + return cls(0x9b59b6) + + @classmethod + def dark_purple(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x71368a``.""" + return cls(0x71368a) + + @classmethod + def magenta(cls): + """A factory method that returns a :class:`Colour` with a value of ``0xe91e63``.""" + return cls(0xe91e63) + + @classmethod + def dark_magenta(cls): + """A factory method that returns a :class:`Colour` with a value of ``0xad1457``.""" + return cls(0xad1457) + + @classmethod + def gold(cls): + """A factory method that returns a :class:`Colour` with a value of ``0xf1c40f``.""" + return cls(0xf1c40f) + + @classmethod + def dark_gold(cls): + """A factory method that returns a :class:`Colour` with a value of ``0xc27c0e``.""" + return cls(0xc27c0e) + + @classmethod + def orange(cls): + """A factory method that returns a :class:`Colour` with a value of ``0xe67e22``.""" + return cls(0xe67e22) + + @classmethod + def dark_orange(cls): + """A factory method that returns a :class:`Colour` with a value of ``0xa84300``.""" + return cls(0xa84300) + + @classmethod + def red(cls): + """A factory method that returns a :class:`Colour` with a value of ``0xe74c3c``.""" + return cls(0xe74c3c) + + @classmethod + def dark_red(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x992d22``.""" + return cls(0x992d22) + + @classmethod + def lighter_grey(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x95a5a6``.""" + return cls(0x95a5a6) + + lighter_gray = lighter_grey + + @classmethod + def dark_grey(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x607d8b``.""" + return cls(0x607d8b) + + dark_gray = dark_grey + + @classmethod + def light_grey(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x979c9f``.""" + return cls(0x979c9f) + + light_gray = light_grey + + @classmethod + def darker_grey(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x546e7a``.""" + return cls(0x546e7a) + + darker_gray = darker_grey + + @classmethod + def blurple(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x7289da``.""" + return cls(0x7289da) + + @classmethod + def greyple(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x99aab5``.""" + return cls(0x99aab5) + + @classmethod + def dark_theme(cls): + """A factory method that returns a :class:`Colour` with a value of ``0x36393F``. + This will appear transparent on Discord's dark theme. + + .. versionadded:: 1.5 + """ + return cls(0x36393F) + +Color = Colour diff --git a/dist/ba_data/python-site-packages/discord/context_managers.py b/dist/ba_data/python-site-packages/discord/context_managers.py new file mode 100644 index 0000000..e4fde6b --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/context_managers.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import asyncio + +def _typing_done_callback(fut): + # just retrieve any exception and call it a day + try: + fut.exception() + except (asyncio.CancelledError, Exception): + pass + +class Typing: + def __init__(self, messageable): + self.loop = messageable._state.loop + self.messageable = messageable + + async def do_typing(self): + try: + channel = self._channel + except AttributeError: + channel = await self.messageable._get_channel() + + typing = channel._state.http.send_typing + + while True: + await typing(channel.id) + await asyncio.sleep(5) + + def __enter__(self): + self.task = asyncio.ensure_future(self.do_typing(), loop=self.loop) + self.task.add_done_callback(_typing_done_callback) + return self + + def __exit__(self, exc_type, exc, tb): + self.task.cancel() + + async def __aenter__(self): + self._channel = channel = await self.messageable._get_channel() + await channel._state.http.send_typing(channel.id) + return self.__enter__() + + async def __aexit__(self, exc_type, exc, tb): + self.task.cancel() diff --git a/dist/ba_data/python-site-packages/discord/embeds.py b/dist/ba_data/python-site-packages/discord/embeds.py new file mode 100644 index 0000000..cbe1146 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/embeds.py @@ -0,0 +1,618 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import datetime + +from . import utils +from .colour import Colour + +class _EmptyEmbed: + def __bool__(self): + return False + + def __repr__(self): + return 'Embed.Empty' + + def __len__(self): + return 0 + +EmptyEmbed = _EmptyEmbed() + +class EmbedProxy: + def __init__(self, layer): + self.__dict__.update(layer) + + def __len__(self): + return len(self.__dict__) + + def __repr__(self): + return 'EmbedProxy(%s)' % ', '.join(('%s=%r' % (k, v) for k, v in self.__dict__.items() if not k.startswith('_'))) + + def __getattr__(self, attr): + return EmptyEmbed + +class Embed: + """Represents a Discord embed. + + .. container:: operations + + .. describe:: len(x) + + Returns the total size of the embed. + Useful for checking if it's within the 6000 character limit. + + Certain properties return an ``EmbedProxy``, a type + that acts similar to a regular :class:`dict` except using dotted access, + e.g. ``embed.author.icon_url``. If the attribute + is invalid or empty, then a special sentinel value is returned, + :attr:`Embed.Empty`. + + For ease of use, all parameters that expect a :class:`str` are implicitly + casted to :class:`str` for you. + + Attributes + ----------- + title: :class:`str` + The title of the embed. + This can be set during initialisation. + type: :class:`str` + The type of embed. Usually "rich". + This can be set during initialisation. + Possible strings for embed types can be found on discord's + `api docs `_ + description: :class:`str` + The description of the embed. + This can be set during initialisation. + url: :class:`str` + The URL of the embed. + This can be set during initialisation. + timestamp: :class:`datetime.datetime` + The timestamp of the embed content. This could be a naive or aware datetime. + colour: Union[:class:`Colour`, :class:`int`] + The colour code of the embed. Aliased to ``color`` as well. + This can be set during initialisation. + Empty + A special sentinel value used by ``EmbedProxy`` and this class + to denote that the value or attribute is empty. + """ + + __slots__ = ('title', 'url', 'type', '_timestamp', '_colour', '_footer', + '_image', '_thumbnail', '_video', '_provider', '_author', + '_fields', 'description') + + Empty = EmptyEmbed + + def __init__(self, **kwargs): + # swap the colour/color aliases + try: + colour = kwargs['colour'] + except KeyError: + colour = kwargs.get('color', EmptyEmbed) + + self.colour = colour + self.title = kwargs.get('title', EmptyEmbed) + self.type = kwargs.get('type', 'rich') + self.url = kwargs.get('url', EmptyEmbed) + self.description = kwargs.get('description', EmptyEmbed) + + if self.title is not EmptyEmbed: + self.title = str(self.title) + + if self.description is not EmptyEmbed: + self.description = str(self.description) + + if self.url is not EmptyEmbed: + self.url = str(self.url) + + try: + timestamp = kwargs['timestamp'] + except KeyError: + pass + else: + self.timestamp = timestamp + + @classmethod + def from_dict(cls, data): + """Converts a :class:`dict` to a :class:`Embed` provided it is in the + format that Discord expects it to be in. + + You can find out about this format in the `official Discord documentation`__. + + .. _DiscordDocs: https://discord.com/developers/docs/resources/channel#embed-object + + __ DiscordDocs_ + + Parameters + ----------- + data: :class:`dict` + The dictionary to convert into an embed. + """ + # we are bypassing __init__ here since it doesn't apply here + self = cls.__new__(cls) + + # fill in the basic fields + + self.title = data.get('title', EmptyEmbed) + self.type = data.get('type', EmptyEmbed) + self.description = data.get('description', EmptyEmbed) + self.url = data.get('url', EmptyEmbed) + + if self.title is not EmptyEmbed: + self.title = str(self.title) + + if self.description is not EmptyEmbed: + self.description = str(self.description) + + if self.url is not EmptyEmbed: + self.url = str(self.url) + + # try to fill in the more rich fields + + try: + self._colour = Colour(value=data['color']) + except KeyError: + pass + + try: + self._timestamp = utils.parse_time(data['timestamp']) + except KeyError: + pass + + for attr in ('thumbnail', 'video', 'provider', 'author', 'fields', 'image', 'footer'): + try: + value = data[attr] + except KeyError: + continue + else: + setattr(self, '_' + attr, value) + + return self + + def copy(self): + """Returns a shallow copy of the embed.""" + return Embed.from_dict(self.to_dict()) + + def __len__(self): + total = len(self.title) + len(self.description) + for field in getattr(self, '_fields', []): + total += len(field['name']) + len(field['value']) + + try: + footer = self._footer + except AttributeError: + pass + else: + total += len(footer['text']) + + try: + author = self._author + except AttributeError: + pass + else: + total += len(author['name']) + + return total + + @property + def colour(self): + return getattr(self, '_colour', EmptyEmbed) + + @colour.setter + def colour(self, value): + if isinstance(value, (Colour, _EmptyEmbed)): + self._colour = value + elif isinstance(value, int): + self._colour = Colour(value=value) + else: + raise TypeError('Expected discord.Colour, int, or Embed.Empty but received %s instead.' % value.__class__.__name__) + + color = colour + + @property + def timestamp(self): + return getattr(self, '_timestamp', EmptyEmbed) + + @timestamp.setter + def timestamp(self, value): + if isinstance(value, (datetime.datetime, _EmptyEmbed)): + self._timestamp = value + else: + raise TypeError("Expected datetime.datetime or Embed.Empty received %s instead" % value.__class__.__name__) + + @property + def footer(self): + """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the footer contents. + + See :meth:`set_footer` for possible values you can access. + + If the attribute has no value then :attr:`Empty` is returned. + """ + return EmbedProxy(getattr(self, '_footer', {})) + + def set_footer(self, *, text=EmptyEmbed, icon_url=EmptyEmbed): + """Sets the footer for the embed content. + + This function returns the class instance to allow for fluent-style + chaining. + + Parameters + ----------- + text: :class:`str` + The footer text. + icon_url: :class:`str` + The URL of the footer icon. Only HTTP(S) is supported. + """ + + self._footer = {} + if text is not EmptyEmbed: + self._footer['text'] = str(text) + + if icon_url is not EmptyEmbed: + self._footer['icon_url'] = str(icon_url) + + return self + + @property + def image(self): + """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the image contents. + + Possible attributes you can access are: + + - ``url`` + - ``proxy_url`` + - ``width`` + - ``height`` + + If the attribute has no value then :attr:`Empty` is returned. + """ + return EmbedProxy(getattr(self, '_image', {})) + + def set_image(self, *, url): + """Sets the image for the embed content. + + This function returns the class instance to allow for fluent-style + chaining. + + .. versionchanged:: 1.4 + Passing :attr:`Empty` removes the image. + + Parameters + ----------- + url: :class:`str` + The source URL for the image. Only HTTP(S) is supported. + """ + + if url is EmptyEmbed: + try: + del self._image + except AttributeError: + pass + else: + self._image = { + 'url': str(url) + } + + return self + + @property + def thumbnail(self): + """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the thumbnail contents. + + Possible attributes you can access are: + + - ``url`` + - ``proxy_url`` + - ``width`` + - ``height`` + + If the attribute has no value then :attr:`Empty` is returned. + """ + return EmbedProxy(getattr(self, '_thumbnail', {})) + + def set_thumbnail(self, *, url): + """Sets the thumbnail for the embed content. + + This function returns the class instance to allow for fluent-style + chaining. + + .. versionchanged:: 1.4 + Passing :attr:`Empty` removes the thumbnail. + + Parameters + ----------- + url: :class:`str` + The source URL for the thumbnail. Only HTTP(S) is supported. + """ + + if url is EmptyEmbed: + try: + del self._thumbnail + except AttributeError: + pass + else: + self._thumbnail = { + 'url': str(url) + } + + return self + + @property + def video(self): + """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the video contents. + + Possible attributes include: + + - ``url`` for the video URL. + - ``height`` for the video height. + - ``width`` for the video width. + + If the attribute has no value then :attr:`Empty` is returned. + """ + return EmbedProxy(getattr(self, '_video', {})) + + @property + def provider(self): + """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the provider contents. + + The only attributes that might be accessed are ``name`` and ``url``. + + If the attribute has no value then :attr:`Empty` is returned. + """ + return EmbedProxy(getattr(self, '_provider', {})) + + @property + def author(self): + """Union[:class:`EmbedProxy`, :attr:`Empty`]: Returns an ``EmbedProxy`` denoting the author contents. + + See :meth:`set_author` for possible values you can access. + + If the attribute has no value then :attr:`Empty` is returned. + """ + return EmbedProxy(getattr(self, '_author', {})) + + def set_author(self, *, name, url=EmptyEmbed, icon_url=EmptyEmbed): + """Sets the author for the embed content. + + This function returns the class instance to allow for fluent-style + chaining. + + Parameters + ----------- + name: :class:`str` + The name of the author. + url: :class:`str` + The URL for the author. + icon_url: :class:`str` + The URL of the author icon. Only HTTP(S) is supported. + """ + + self._author = { + 'name': str(name) + } + + if url is not EmptyEmbed: + self._author['url'] = str(url) + + if icon_url is not EmptyEmbed: + self._author['icon_url'] = str(icon_url) + + return self + + def remove_author(self): + """Clears embed's author information. + + This function returns the class instance to allow for fluent-style + chaining. + + .. versionadded:: 1.4 + """ + try: + del self._author + except AttributeError: + pass + + return self + + @property + def fields(self): + """List[Union[``EmbedProxy``, :attr:`Empty`]]: Returns a :class:`list` of ``EmbedProxy`` denoting the field contents. + + See :meth:`add_field` for possible values you can access. + + If the attribute has no value then :attr:`Empty` is returned. + """ + return [EmbedProxy(d) for d in getattr(self, '_fields', [])] + + def add_field(self, *, name, value, inline=True): + """Adds a field to the embed object. + + This function returns the class instance to allow for fluent-style + chaining. + + Parameters + ----------- + name: :class:`str` + The name of the field. + value: :class:`str` + The value of the field. + inline: :class:`bool` + Whether the field should be displayed inline. + """ + + field = { + 'inline': inline, + 'name': str(name), + 'value': str(value) + } + + try: + self._fields.append(field) + except AttributeError: + self._fields = [field] + + return self + + def insert_field_at(self, index, *, name, value, inline=True): + """Inserts a field before a specified index to the embed. + + This function returns the class instance to allow for fluent-style + chaining. + + .. versionadded:: 1.2 + + Parameters + ----------- + index: :class:`int` + The index of where to insert the field. + name: :class:`str` + The name of the field. + value: :class:`str` + The value of the field. + inline: :class:`bool` + Whether the field should be displayed inline. + """ + + field = { + 'inline': inline, + 'name': str(name), + 'value': str(value) + } + + try: + self._fields.insert(index, field) + except AttributeError: + self._fields = [field] + + return self + + def clear_fields(self): + """Removes all fields from this embed.""" + try: + self._fields.clear() + except AttributeError: + self._fields = [] + + def remove_field(self, index): + """Removes a field at a specified index. + + If the index is invalid or out of bounds then the error is + silently swallowed. + + .. note:: + + When deleting a field by index, the index of the other fields + shift to fill the gap just like a regular list. + + Parameters + ----------- + index: :class:`int` + The index of the field to remove. + """ + try: + del self._fields[index] + except (AttributeError, IndexError): + pass + + def set_field_at(self, index, *, name, value, inline=True): + """Modifies a field to the embed object. + + The index must point to a valid pre-existing field. + + This function returns the class instance to allow for fluent-style + chaining. + + Parameters + ----------- + index: :class:`int` + The index of the field to modify. + name: :class:`str` + The name of the field. + value: :class:`str` + The value of the field. + inline: :class:`bool` + Whether the field should be displayed inline. + + Raises + ------- + IndexError + An invalid index was provided. + """ + + try: + field = self._fields[index] + except (TypeError, IndexError, AttributeError): + raise IndexError('field index out of range') + + field['name'] = str(name) + field['value'] = str(value) + field['inline'] = inline + return self + + def to_dict(self): + """Converts this embed object into a dict.""" + + # add in the raw data into the dict + result = { + key[1:]: getattr(self, key) + for key in self.__slots__ + if key[0] == '_' and hasattr(self, key) + } + + # deal with basic convenience wrappers + + try: + colour = result.pop('colour') + except KeyError: + pass + else: + if colour: + result['color'] = colour.value + + try: + timestamp = result.pop('timestamp') + except KeyError: + pass + else: + if timestamp: + if timestamp.tzinfo: + result['timestamp'] = timestamp.astimezone(tz=datetime.timezone.utc).isoformat() + else: + result['timestamp'] = timestamp.replace(tzinfo=datetime.timezone.utc).isoformat() + + # add in the non raw attribute ones + if self.type: + result['type'] = self.type + + if self.description: + result['description'] = self.description + + if self.url: + result['url'] = self.url + + if self.title: + result['title'] = self.title + + return result diff --git a/dist/ba_data/python-site-packages/discord/emoji.py b/dist/ba_data/python-site-packages/discord/emoji.py new file mode 100644 index 0000000..735d508 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/emoji.py @@ -0,0 +1,254 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +from .asset import Asset +from . import utils +from .partial_emoji import _EmojiTag +from .user import User + +class Emoji(_EmojiTag): + """Represents a custom emoji. + + Depending on the way this object was created, some of the attributes can + have a value of ``None``. + + .. container:: operations + + .. describe:: x == y + + Checks if two emoji are the same. + + .. describe:: x != y + + Checks if two emoji are not the same. + + .. describe:: hash(x) + + Return the emoji's hash. + + .. describe:: iter(x) + + Returns an iterator of ``(field, value)`` pairs. This allows this class + to be used as an iterable in list/dict/etc constructions. + + .. describe:: str(x) + + Returns the emoji rendered for discord. + + Attributes + ----------- + name: :class:`str` + The name of the emoji. + id: :class:`int` + The emoji's ID. + require_colons: :class:`bool` + If colons are required to use this emoji in the client (:PJSalt: vs PJSalt). + animated: :class:`bool` + Whether an emoji is animated or not. + managed: :class:`bool` + If this emoji is managed by a Twitch integration. + guild_id: :class:`int` + The guild ID the emoji belongs to. + available: :class:`bool` + Whether the emoji is available for use. + user: Optional[:class:`User`] + The user that created the emoji. This can only be retrieved using :meth:`Guild.fetch_emoji` and + having the :attr:`~Permissions.manage_emojis` permission. + """ + __slots__ = ('require_colons', 'animated', 'managed', 'id', 'name', '_roles', 'guild_id', + '_state', 'user', 'available') + + def __init__(self, *, guild, state, data): + self.guild_id = guild.id + self._state = state + self._from_data(data) + + def _from_data(self, emoji): + self.require_colons = emoji['require_colons'] + self.managed = emoji['managed'] + self.id = int(emoji['id']) + self.name = emoji['name'] + self.animated = emoji.get('animated', False) + self.available = emoji.get('available', True) + self._roles = utils.SnowflakeList(map(int, emoji.get('roles', []))) + user = emoji.get('user') + self.user = User(state=self._state, data=user) if user else None + + def _iterator(self): + for attr in self.__slots__: + if attr[0] != '_': + value = getattr(self, attr, None) + if value is not None: + yield (attr, value) + + def __iter__(self): + return self._iterator() + + def __str__(self): + if self.animated: + return ''.format(self) + return "<:{0.name}:{0.id}>".format(self) + + def __repr__(self): + return ''.format(self) + + def __eq__(self, other): + return isinstance(other, _EmojiTag) and self.id == other.id + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return self.id >> 22 + + @property + def created_at(self): + """:class:`datetime.datetime`: Returns the emoji's creation time in UTC.""" + return utils.snowflake_time(self.id) + + @property + def url(self): + """:class:`Asset`: Returns the asset of the emoji. + + This is equivalent to calling :meth:`url_as` with + the default parameters (i.e. png/gif detection). + """ + return self.url_as(format=None) + + @property + def roles(self): + """List[:class:`Role`]: A :class:`list` of roles that is allowed to use this emoji. + + If roles is empty, the emoji is unrestricted. + """ + guild = self.guild + if guild is None: + return [] + + return [role for role in guild.roles if self._roles.has(role.id)] + + @property + def guild(self): + """:class:`Guild`: The guild this emoji belongs to.""" + return self._state._get_guild(self.guild_id) + + + def url_as(self, *, format=None, static_format="png"): + """Returns an :class:`Asset` for the emoji's url. + + The format must be one of 'webp', 'jpeg', 'jpg', 'png' or 'gif'. + 'gif' is only valid for animated emojis. + + .. versionadded:: 1.6 + + Parameters + ----------- + format: Optional[:class:`str`] + The format to attempt to convert the emojis to. + If the format is ``None``, then it is automatically + detected as either 'gif' or static_format, depending on whether the + emoji is animated or not. + static_format: Optional[:class:`str`] + Format to attempt to convert only non-animated emoji's to. + Defaults to 'png' + + Raises + ------- + InvalidArgument + Bad image format passed to ``format`` or ``static_format``. + + Returns + -------- + :class:`Asset` + The resulting CDN asset. + """ + return Asset._from_emoji(self._state, self, format=format, static_format=static_format) + + + def is_usable(self): + """:class:`bool`: Whether the bot can use this emoji. + + .. versionadded:: 1.3 + """ + if not self.available: + return False + if not self._roles: + return True + emoji_roles, my_roles = self._roles, self.guild.me._roles + return any(my_roles.has(role_id) for role_id in emoji_roles) + + async def delete(self, *, reason=None): + """|coro| + + Deletes the custom emoji. + + You must have :attr:`~Permissions.manage_emojis` permission to + do this. + + Parameters + ----------- + reason: Optional[:class:`str`] + The reason for deleting this emoji. Shows up on the audit log. + + Raises + ------- + Forbidden + You are not allowed to delete emojis. + HTTPException + An error occurred deleting the emoji. + """ + + await self._state.http.delete_custom_emoji(self.guild.id, self.id, reason=reason) + + async def edit(self, *, name=None, roles=None, reason=None): + r"""|coro| + + Edits the custom emoji. + + You must have :attr:`~Permissions.manage_emojis` permission to + do this. + + Parameters + ----------- + name: :class:`str` + The new emoji name. + roles: Optional[list[:class:`Role`]] + A :class:`list` of :class:`Role`\s that can use this emoji. Leave empty to make it available to everyone. + reason: Optional[:class:`str`] + The reason for editing this emoji. Shows up on the audit log. + + Raises + ------- + Forbidden + You are not allowed to edit emojis. + HTTPException + An error occurred editing the emoji. + """ + + name = name or self.name + if roles: + roles = [role.id for role in roles] + await self._state.http.edit_custom_emoji(self.guild.id, self.id, name=name, roles=roles, reason=reason) diff --git a/dist/ba_data/python-site-packages/discord/enums.py b/dist/ba_data/python-site-packages/discord/enums.py new file mode 100644 index 0000000..91592a6 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/enums.py @@ -0,0 +1,471 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import types +from collections import namedtuple + +__all__ = ( + 'Enum', + 'ChannelType', + 'MessageType', + 'VoiceRegion', + 'SpeakingState', + 'VerificationLevel', + 'ContentFilter', + 'Status', + 'DefaultAvatar', + 'RelationshipType', + 'AuditLogAction', + 'AuditLogActionCategory', + 'UserFlags', + 'ActivityType', + 'HypeSquadHouse', + 'NotificationLevel', + 'PremiumType', + 'UserContentFilter', + 'FriendFlags', + 'TeamMembershipState', + 'Theme', + 'WebhookType', + 'ExpireBehaviour', + 'ExpireBehavior', + 'StickerType', +) + +def _create_value_cls(name): + cls = namedtuple('_EnumValue_' + name, 'name value') + cls.__repr__ = lambda self: '<%s.%s: %r>' % (name, self.name, self.value) + cls.__str__ = lambda self: '%s.%s' % (name, self.name) + return cls + +def _is_descriptor(obj): + return hasattr(obj, '__get__') or hasattr(obj, '__set__') or hasattr(obj, '__delete__') + +class EnumMeta(type): + def __new__(cls, name, bases, attrs): + value_mapping = {} + member_mapping = {} + member_names = [] + + value_cls = _create_value_cls(name) + for key, value in list(attrs.items()): + is_descriptor = _is_descriptor(value) + if key[0] == '_' and not is_descriptor: + continue + + # Special case classmethod to just pass through + if isinstance(value, classmethod): + continue + + if is_descriptor: + setattr(value_cls, key, value) + del attrs[key] + continue + + try: + new_value = value_mapping[value] + except KeyError: + new_value = value_cls(name=key, value=value) + value_mapping[value] = new_value + member_names.append(key) + + member_mapping[key] = new_value + attrs[key] = new_value + + attrs['_enum_value_map_'] = value_mapping + attrs['_enum_member_map_'] = member_mapping + attrs['_enum_member_names_'] = member_names + actual_cls = super().__new__(cls, name, bases, attrs) + value_cls._actual_enum_cls_ = actual_cls + return actual_cls + + def __iter__(cls): + return (cls._enum_member_map_[name] for name in cls._enum_member_names_) + + def __reversed__(cls): + return (cls._enum_member_map_[name] for name in reversed(cls._enum_member_names_)) + + def __len__(cls): + return len(cls._enum_member_names_) + + def __repr__(cls): + return '' % cls.__name__ + + @property + def __members__(cls): + return types.MappingProxyType(cls._enum_member_map_) + + def __call__(cls, value): + try: + return cls._enum_value_map_[value] + except (KeyError, TypeError): + raise ValueError("%r is not a valid %s" % (value, cls.__name__)) + + def __getitem__(cls, key): + return cls._enum_member_map_[key] + + def __setattr__(cls, name, value): + raise TypeError('Enums are immutable.') + + def __delattr__(cls, attr): + raise TypeError('Enums are immutable') + + def __instancecheck__(self, instance): + # isinstance(x, Y) + # -> __instancecheck__(Y, x) + try: + return instance._actual_enum_cls_ is self + except AttributeError: + return False + +class Enum(metaclass=EnumMeta): + @classmethod + def try_value(cls, value): + try: + return cls._enum_value_map_[value] + except (KeyError, TypeError): + return value + + +class ChannelType(Enum): + text = 0 + private = 1 + voice = 2 + group = 3 + category = 4 + news = 5 + store = 6 + stage_voice = 13 + + def __str__(self): + return self.name + +class MessageType(Enum): + default = 0 + recipient_add = 1 + recipient_remove = 2 + call = 3 + channel_name_change = 4 + channel_icon_change = 5 + pins_add = 6 + new_member = 7 + premium_guild_subscription = 8 + premium_guild_tier_1 = 9 + premium_guild_tier_2 = 10 + premium_guild_tier_3 = 11 + channel_follow_add = 12 + guild_stream = 13 + guild_discovery_disqualified = 14 + guild_discovery_requalified = 15 + guild_discovery_grace_period_initial_warning = 16 + guild_discovery_grace_period_final_warning = 17 + +class VoiceRegion(Enum): + us_west = 'us-west' + us_east = 'us-east' + us_south = 'us-south' + us_central = 'us-central' + eu_west = 'eu-west' + eu_central = 'eu-central' + singapore = 'singapore' + london = 'london' + sydney = 'sydney' + amsterdam = 'amsterdam' + frankfurt = 'frankfurt' + brazil = 'brazil' + hongkong = 'hongkong' + russia = 'russia' + japan = 'japan' + southafrica = 'southafrica' + south_korea = 'south-korea' + india = 'india' + europe = 'europe' + dubai = 'dubai' + vip_us_east = 'vip-us-east' + vip_us_west = 'vip-us-west' + vip_amsterdam = 'vip-amsterdam' + + def __str__(self): + return self.value + +class SpeakingState(Enum): + none = 0 + voice = 1 + soundshare = 2 + priority = 4 + + def __str__(self): + return self.name + + def __int__(self): + return self.value + +class VerificationLevel(Enum): + none = 0 + low = 1 + medium = 2 + high = 3 + table_flip = 3 + extreme = 4 + double_table_flip = 4 + very_high = 4 + + def __str__(self): + return self.name + +class ContentFilter(Enum): + disabled = 0 + no_role = 1 + all_members = 2 + + def __str__(self): + return self.name + +class UserContentFilter(Enum): + disabled = 0 + friends = 1 + all_messages = 2 + +class FriendFlags(Enum): + noone = 0 + mutual_guilds = 1 + mutual_friends = 2 + guild_and_friends = 3 + everyone = 4 + +class Theme(Enum): + light = 'light' + dark = 'dark' + +class Status(Enum): + online = 'online' + offline = 'offline' + idle = 'idle' + dnd = 'dnd' + do_not_disturb = 'dnd' + invisible = 'invisible' + + def __str__(self): + return self.value + +class DefaultAvatar(Enum): + blurple = 0 + grey = 1 + gray = 1 + green = 2 + orange = 3 + red = 4 + + def __str__(self): + return self.name + +class RelationshipType(Enum): + friend = 1 + blocked = 2 + incoming_request = 3 + outgoing_request = 4 + +class NotificationLevel(Enum): + all_messages = 0 + only_mentions = 1 + +class AuditLogActionCategory(Enum): + create = 1 + delete = 2 + update = 3 + +class AuditLogAction(Enum): + guild_update = 1 + channel_create = 10 + channel_update = 11 + channel_delete = 12 + overwrite_create = 13 + overwrite_update = 14 + overwrite_delete = 15 + kick = 20 + member_prune = 21 + ban = 22 + unban = 23 + member_update = 24 + member_role_update = 25 + member_move = 26 + member_disconnect = 27 + bot_add = 28 + role_create = 30 + role_update = 31 + role_delete = 32 + invite_create = 40 + invite_update = 41 + invite_delete = 42 + webhook_create = 50 + webhook_update = 51 + webhook_delete = 52 + emoji_create = 60 + emoji_update = 61 + emoji_delete = 62 + message_delete = 72 + message_bulk_delete = 73 + message_pin = 74 + message_unpin = 75 + integration_create = 80 + integration_update = 81 + integration_delete = 82 + + @property + def category(self): + lookup = { + AuditLogAction.guild_update: AuditLogActionCategory.update, + AuditLogAction.channel_create: AuditLogActionCategory.create, + AuditLogAction.channel_update: AuditLogActionCategory.update, + AuditLogAction.channel_delete: AuditLogActionCategory.delete, + AuditLogAction.overwrite_create: AuditLogActionCategory.create, + AuditLogAction.overwrite_update: AuditLogActionCategory.update, + AuditLogAction.overwrite_delete: AuditLogActionCategory.delete, + AuditLogAction.kick: None, + AuditLogAction.member_prune: None, + AuditLogAction.ban: None, + AuditLogAction.unban: None, + AuditLogAction.member_update: AuditLogActionCategory.update, + AuditLogAction.member_role_update: AuditLogActionCategory.update, + AuditLogAction.member_move: None, + AuditLogAction.member_disconnect: None, + AuditLogAction.bot_add: None, + AuditLogAction.role_create: AuditLogActionCategory.create, + AuditLogAction.role_update: AuditLogActionCategory.update, + AuditLogAction.role_delete: AuditLogActionCategory.delete, + AuditLogAction.invite_create: AuditLogActionCategory.create, + AuditLogAction.invite_update: AuditLogActionCategory.update, + AuditLogAction.invite_delete: AuditLogActionCategory.delete, + AuditLogAction.webhook_create: AuditLogActionCategory.create, + AuditLogAction.webhook_update: AuditLogActionCategory.update, + AuditLogAction.webhook_delete: AuditLogActionCategory.delete, + AuditLogAction.emoji_create: AuditLogActionCategory.create, + AuditLogAction.emoji_update: AuditLogActionCategory.update, + AuditLogAction.emoji_delete: AuditLogActionCategory.delete, + AuditLogAction.message_delete: AuditLogActionCategory.delete, + AuditLogAction.message_bulk_delete: AuditLogActionCategory.delete, + AuditLogAction.message_pin: None, + AuditLogAction.message_unpin: None, + AuditLogAction.integration_create: AuditLogActionCategory.create, + AuditLogAction.integration_update: AuditLogActionCategory.update, + AuditLogAction.integration_delete: AuditLogActionCategory.delete, + } + return lookup[self] + + @property + def target_type(self): + v = self.value + if v == -1: + return 'all' + elif v < 10: + return 'guild' + elif v < 20: + return 'channel' + elif v < 30: + return 'user' + elif v < 40: + return 'role' + elif v < 50: + return 'invite' + elif v < 60: + return 'webhook' + elif v < 70: + return 'emoji' + elif v == 73: + return 'channel' + elif v < 80: + return 'message' + elif v < 90: + return 'integration' + +class UserFlags(Enum): + staff = 1 + partner = 2 + hypesquad = 4 + bug_hunter = 8 + mfa_sms = 16 + premium_promo_dismissed = 32 + hypesquad_bravery = 64 + hypesquad_brilliance = 128 + hypesquad_balance = 256 + early_supporter = 512 + team_user = 1024 + system = 4096 + has_unread_urgent_messages = 8192 + bug_hunter_level_2 = 16384 + verified_bot = 65536 + verified_bot_developer = 131072 + +class ActivityType(Enum): + unknown = -1 + playing = 0 + streaming = 1 + listening = 2 + watching = 3 + custom = 4 + competing = 5 + + def __int__(self): + return self.value + +class HypeSquadHouse(Enum): + bravery = 1 + brilliance = 2 + balance = 3 + +class PremiumType(Enum): + nitro_classic = 1 + nitro = 2 + +class TeamMembershipState(Enum): + invited = 1 + accepted = 2 + +class WebhookType(Enum): + incoming = 1 + channel_follower = 2 + +class ExpireBehaviour(Enum): + remove_role = 0 + kick = 1 + +ExpireBehavior = ExpireBehaviour + +class StickerType(Enum): + png = 1 + apng = 2 + lottie = 3 + +def try_enum(cls, val): + """A function that tries to turn the value into enum ``cls``. + + If it fails it returns the value instead. + """ + + try: + return cls._enum_value_map_[val] + except (KeyError, TypeError, AttributeError): + return val diff --git a/dist/ba_data/python-site-packages/discord/errors.py b/dist/ba_data/python-site-packages/discord/errors.py new file mode 100644 index 0000000..7247051 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/errors.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +class DiscordException(Exception): + """Base exception class for discord.py + + Ideally speaking, this could be caught to handle any exceptions thrown from this library. + """ + pass + +class ClientException(DiscordException): + """Exception that's thrown when an operation in the :class:`Client` fails. + + These are usually for exceptions that happened due to user input. + """ + pass + +class NoMoreItems(DiscordException): + """Exception that is thrown when an async iteration operation has no more + items.""" + pass + +class GatewayNotFound(DiscordException): + """An exception that is usually thrown when the gateway hub + for the :class:`Client` websocket is not found.""" + def __init__(self): + message = 'The gateway to connect to discord was not found.' + super(GatewayNotFound, self).__init__(message) + +def flatten_error_dict(d, key=''): + items = [] + for k, v in d.items(): + new_key = key + '.' + k if key else k + + if isinstance(v, dict): + try: + _errors = v['_errors'] + except KeyError: + items.extend(flatten_error_dict(v, new_key).items()) + else: + items.append((new_key, ' '.join(x.get('message', '') for x in _errors))) + else: + items.append((new_key, v)) + + return dict(items) + +class HTTPException(DiscordException): + """Exception that's thrown when an HTTP request operation fails. + + Attributes + ------------ + response: :class:`aiohttp.ClientResponse` + The response of the failed HTTP request. This is an + instance of :class:`aiohttp.ClientResponse`. In some cases + this could also be a :class:`requests.Response`. + + text: :class:`str` + The text of the error. Could be an empty string. + status: :class:`int` + The status code of the HTTP request. + code: :class:`int` + The Discord specific error code for the failure. + """ + + def __init__(self, response, message): + self.response = response + self.status = response.status + if isinstance(message, dict): + self.code = message.get('code', 0) + base = message.get('message', '') + errors = message.get('errors') + if errors: + errors = flatten_error_dict(errors) + helpful = '\n'.join('In %s: %s' % t for t in errors.items()) + self.text = base + '\n' + helpful + else: + self.text = base + else: + self.text = message + self.code = 0 + + fmt = '{0.status} {0.reason} (error code: {1})' + if len(self.text): + fmt += ': {2}' + + super().__init__(fmt.format(self.response, self.code, self.text)) + +class Forbidden(HTTPException): + """Exception that's thrown for when status code 403 occurs. + + Subclass of :exc:`HTTPException` + """ + pass + +class NotFound(HTTPException): + """Exception that's thrown for when status code 404 occurs. + + Subclass of :exc:`HTTPException` + """ + pass + +class DiscordServerError(HTTPException): + """Exception that's thrown for when a 500 range status code occurs. + + Subclass of :exc:`HTTPException`. + + .. versionadded:: 1.5 + """ + pass + +class InvalidData(ClientException): + """Exception that's raised when the library encounters unknown + or invalid data from Discord. + """ + pass + +class InvalidArgument(ClientException): + """Exception that's thrown when an argument to a function + is invalid some way (e.g. wrong value or wrong type). + + This could be considered the analogous of ``ValueError`` and + ``TypeError`` except inherited from :exc:`ClientException` and thus + :exc:`DiscordException`. + """ + pass + +class LoginFailure(ClientException): + """Exception that's thrown when the :meth:`Client.login` function + fails to log you in from improper credentials or some other misc. + failure. + """ + pass + +class ConnectionClosed(ClientException): + """Exception that's thrown when the gateway connection is + closed for reasons that could not be handled internally. + + Attributes + ----------- + code: :class:`int` + The close code of the websocket. + reason: :class:`str` + The reason provided for the closure. + shard_id: Optional[:class:`int`] + The shard ID that got closed if applicable. + """ + def __init__(self, socket, *, shard_id, code=None): + # This exception is just the same exception except + # reconfigured to subclass ClientException for users + self.code = code or socket.close_code + # aiohttp doesn't seem to consistently provide close reason + self.reason = '' + self.shard_id = shard_id + super().__init__('Shard ID %s WebSocket closed with %s' % (self.shard_id, self.code)) + +class PrivilegedIntentsRequired(ClientException): + """Exception that's thrown when the gateway is requesting privileged intents + but they're not ticked in the developer page yet. + + Go to https://discord.com/developers/applications/ and enable the intents + that are required. Currently these are as follows: + + - :attr:`Intents.members` + - :attr:`Intents.presences` + + Attributes + ----------- + shard_id: Optional[:class:`int`] + The shard ID that got closed if applicable. + """ + + def __init__(self, shard_id): + self.shard_id = shard_id + msg = 'Shard ID %s is requesting privileged intents that have not been explicitly enabled in the ' \ + 'developer portal. It is recommended to go to https://discord.com/developers/applications/ ' \ + 'and explicitly enable the privileged intents within your application\'s page. If this is not ' \ + 'possible, then consider disabling the privileged intents instead.' + super().__init__(msg % shard_id) diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__init__.py b/dist/ba_data/python-site-packages/discord/ext/commands/__init__.py new file mode 100644 index 0000000..6f356c5 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/ext/commands/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +""" +discord.ext.commands +~~~~~~~~~~~~~~~~~~~~~ + +An extension module to facilitate creation of bot commands. + +:copyright: (c) 2015-present Rapptz +:license: MIT, see LICENSE for more details. +""" + +from .bot import Bot, AutoShardedBot, when_mentioned, when_mentioned_or +from .context import Context +from .core import * +from .errors import * +from .help import * +from .converter import * +from .cooldowns import * +from .cog import * diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/__init__.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/__init__.cpython-310.opt-1.pyc new file mode 100644 index 0000000..8fa0115 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/__init__.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/_types.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/_types.cpython-310.opt-1.pyc new file mode 100644 index 0000000..f73f636 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/_types.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/bot.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/bot.cpython-310.opt-1.pyc new file mode 100644 index 0000000..88fb22d Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/bot.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/cog.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/cog.cpython-310.opt-1.pyc new file mode 100644 index 0000000..7c593c6 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/cog.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/context.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/context.cpython-310.opt-1.pyc new file mode 100644 index 0000000..3786ae1 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/context.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/converter.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/converter.cpython-310.opt-1.pyc new file mode 100644 index 0000000..51b01bd Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/converter.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/cooldowns.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/cooldowns.cpython-310.opt-1.pyc new file mode 100644 index 0000000..1644c10 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/cooldowns.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/core.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/core.cpython-310.opt-1.pyc new file mode 100644 index 0000000..a106c39 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/core.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/errors.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/errors.cpython-310.opt-1.pyc new file mode 100644 index 0000000..c649351 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/errors.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/help.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/help.cpython-310.opt-1.pyc new file mode 100644 index 0000000..4faa531 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/help.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/view.cpython-310.opt-1.pyc b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/view.cpython-310.opt-1.pyc new file mode 100644 index 0000000..b5e2548 Binary files /dev/null and b/dist/ba_data/python-site-packages/discord/ext/commands/__pycache__/view.cpython-310.opt-1.pyc differ diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/_types.py b/dist/ba_data/python-site-packages/discord/ext/commands/_types.py new file mode 100644 index 0000000..36d0efc --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/ext/commands/_types.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +# This is merely a tag type to avoid circular import issues. +# Yes, this is a terrible solution but ultimately it is the only solution. +class _BaseCommand: + __slots__ = () diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/bot.py b/dist/ba_data/python-site-packages/discord/ext/commands/bot.py new file mode 100644 index 0000000..ee0308e --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/ext/commands/bot.py @@ -0,0 +1,1061 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import asyncio +import collections +import inspect +import importlib.util +import sys +import traceback +import types + +import discord + +from .core import GroupMixin +from .view import StringView +from .context import Context +from . import errors +from .help import HelpCommand, DefaultHelpCommand +from .cog import Cog + +def when_mentioned(bot, msg): + """A callable that implements a command prefix equivalent to being mentioned. + + These are meant to be passed into the :attr:`.Bot.command_prefix` attribute. + """ + return [bot.user.mention + ' ', '<@!%s> ' % bot.user.id] + +def when_mentioned_or(*prefixes): + """A callable that implements when mentioned or other prefixes provided. + + These are meant to be passed into the :attr:`.Bot.command_prefix` attribute. + + Example + -------- + + .. code-block:: python3 + + bot = commands.Bot(command_prefix=commands.when_mentioned_or('!')) + + + .. note:: + + This callable returns another callable, so if this is done inside a custom + callable, you must call the returned callable, for example: + + .. code-block:: python3 + + async def get_prefix(bot, message): + extras = await prefixes_for(message.guild) # returns a list + return commands.when_mentioned_or(*extras)(bot, message) + + + See Also + ---------- + :func:`.when_mentioned` + """ + def inner(bot, msg): + r = list(prefixes) + r = when_mentioned(bot, msg) + r + return r + + return inner + +def _is_submodule(parent, child): + return parent == child or child.startswith(parent + ".") + +class _DefaultRepr: + def __repr__(self): + return '' + +_default = _DefaultRepr() + +class BotBase(GroupMixin): + def __init__(self, command_prefix, help_command=_default, description=None, **options): + super().__init__(**options) + self.command_prefix = command_prefix + self.extra_events = {} + self.__cogs = {} + self.__extensions = {} + self._checks = [] + self._check_once = [] + self._before_invoke = None + self._after_invoke = None + self._help_command = None + self.description = inspect.cleandoc(description) if description else '' + self.owner_id = options.get('owner_id') + self.owner_ids = options.get('owner_ids', set()) + self.strip_after_prefix = options.get('strip_after_prefix', False) + + if self.owner_id and self.owner_ids: + raise TypeError('Both owner_id and owner_ids are set.') + + if self.owner_ids and not isinstance(self.owner_ids, collections.abc.Collection): + raise TypeError('owner_ids must be a collection not {0.__class__!r}'.format(self.owner_ids)) + + if options.pop('self_bot', False): + self._skip_check = lambda x, y: x != y + else: + self._skip_check = lambda x, y: x == y + + if help_command is _default: + self.help_command = DefaultHelpCommand() + else: + self.help_command = help_command + + # internal helpers + + def dispatch(self, event_name, *args, **kwargs): + super().dispatch(event_name, *args, **kwargs) + ev = 'on_' + event_name + for event in self.extra_events.get(ev, []): + self._schedule_event(event, ev, *args, **kwargs) + + async def close(self): + for extension in tuple(self.__extensions): + try: + self.unload_extension(extension) + except Exception: + pass + + for cog in tuple(self.__cogs): + try: + self.remove_cog(cog) + except Exception: + pass + + await super().close() + + async def on_command_error(self, context, exception): + """|coro| + + The default command error handler provided by the bot. + + By default this prints to :data:`sys.stderr` however it could be + overridden to have a different implementation. + + This only fires if you do not specify any listeners for command error. + """ + if self.extra_events.get('on_command_error', None): + return + + if hasattr(context.command, 'on_error'): + return + + cog = context.cog + if cog and Cog._get_overridden_method(cog.cog_command_error) is not None: + return + + print('Ignoring exception in command {}:'.format(context.command), file=sys.stderr) + traceback.print_exception(type(exception), exception, exception.__traceback__, file=sys.stderr) + + # global check registration + + def check(self, func): + r"""A decorator that adds a global check to the bot. + + A global check is similar to a :func:`.check` that is applied + on a per command basis except it is run before any command checks + have been verified and applies to every command the bot has. + + .. note:: + + This function can either be a regular function or a coroutine. + + Similar to a command :func:`.check`\, this takes a single parameter + of type :class:`.Context` and can only raise exceptions inherited from + :exc:`.CommandError`. + + Example + --------- + + .. code-block:: python3 + + @bot.check + def check_commands(ctx): + return ctx.command.qualified_name in allowed_commands + + """ + self.add_check(func) + return func + + def add_check(self, func, *, call_once=False): + """Adds a global check to the bot. + + This is the non-decorator interface to :meth:`.check` + and :meth:`.check_once`. + + Parameters + ----------- + func + The function that was used as a global check. + call_once: :class:`bool` + If the function should only be called once per + :meth:`.Command.invoke` call. + """ + + if call_once: + self._check_once.append(func) + else: + self._checks.append(func) + + def remove_check(self, func, *, call_once=False): + """Removes a global check from the bot. + + This function is idempotent and will not raise an exception + if the function is not in the global checks. + + Parameters + ----------- + func + The function to remove from the global checks. + call_once: :class:`bool` + If the function was added with ``call_once=True`` in + the :meth:`.Bot.add_check` call or using :meth:`.check_once`. + """ + l = self._check_once if call_once else self._checks + + try: + l.remove(func) + except ValueError: + pass + + def check_once(self, func): + r"""A decorator that adds a "call once" global check to the bot. + + Unlike regular global checks, this one is called only once + per :meth:`.Command.invoke` call. + + Regular global checks are called whenever a command is called + or :meth:`.Command.can_run` is called. This type of check + bypasses that and ensures that it's called only once, even inside + the default help command. + + .. note:: + + When using this function the :class:`.Context` sent to a group subcommand + may only parse the parent command and not the subcommands due to it + being invoked once per :meth:`.Bot.invoke` call. + + .. note:: + + This function can either be a regular function or a coroutine. + + Similar to a command :func:`.check`\, this takes a single parameter + of type :class:`.Context` and can only raise exceptions inherited from + :exc:`.CommandError`. + + Example + --------- + + .. code-block:: python3 + + @bot.check_once + def whitelist(ctx): + return ctx.message.author.id in my_whitelist + + """ + self.add_check(func, call_once=True) + return func + + async def can_run(self, ctx, *, call_once=False): + data = self._check_once if call_once else self._checks + + if len(data) == 0: + return True + + return await discord.utils.async_all(f(ctx) for f in data) + + async def is_owner(self, user): + """|coro| + + Checks if a :class:`~discord.User` or :class:`~discord.Member` is the owner of + this bot. + + If an :attr:`owner_id` is not set, it is fetched automatically + through the use of :meth:`~.Bot.application_info`. + + .. versionchanged:: 1.3 + The function also checks if the application is team-owned if + :attr:`owner_ids` is not set. + + Parameters + ----------- + user: :class:`.abc.User` + The user to check for. + + Returns + -------- + :class:`bool` + Whether the user is the owner. + """ + + if self.owner_id: + return user.id == self.owner_id + elif self.owner_ids: + return user.id in self.owner_ids + else: + app = await self.application_info() + if app.team: + self.owner_ids = ids = {m.id for m in app.team.members} + return user.id in ids + else: + self.owner_id = owner_id = app.owner.id + return user.id == owner_id + + def before_invoke(self, coro): + """A decorator that registers a coroutine as a pre-invoke hook. + + A pre-invoke hook is called directly before the command is + called. This makes it a useful function to set up database + connections or any type of set up required. + + This pre-invoke hook takes a sole parameter, a :class:`.Context`. + + .. note:: + + The :meth:`~.Bot.before_invoke` and :meth:`~.Bot.after_invoke` hooks are + only called if all checks and argument parsing procedures pass + without error. If any check or argument parsing procedures fail + then the hooks are not called. + + Parameters + ----------- + coro: :ref:`coroutine ` + The coroutine to register as the pre-invoke hook. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine. + """ + if not asyncio.iscoroutinefunction(coro): + raise TypeError('The pre-invoke hook must be a coroutine.') + + self._before_invoke = coro + return coro + + def after_invoke(self, coro): + r"""A decorator that registers a coroutine as a post-invoke hook. + + A post-invoke hook is called directly after the command is + called. This makes it a useful function to clean-up database + connections or any type of clean up required. + + This post-invoke hook takes a sole parameter, a :class:`.Context`. + + .. note:: + + Similar to :meth:`~.Bot.before_invoke`\, this is not called unless + checks and argument parsing procedures succeed. This hook is, + however, **always** called regardless of the internal command + callback raising an error (i.e. :exc:`.CommandInvokeError`\). + This makes it ideal for clean-up scenarios. + + Parameters + ----------- + coro: :ref:`coroutine ` + The coroutine to register as the post-invoke hook. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine. + """ + if not asyncio.iscoroutinefunction(coro): + raise TypeError('The post-invoke hook must be a coroutine.') + + self._after_invoke = coro + return coro + + # listener registration + + def add_listener(self, func, name=None): + """The non decorator alternative to :meth:`.listen`. + + Parameters + ----------- + func: :ref:`coroutine ` + The function to call. + name: Optional[:class:`str`] + The name of the event to listen for. Defaults to ``func.__name__``. + + Example + -------- + + .. code-block:: python3 + + async def on_ready(): pass + async def my_message(message): pass + + bot.add_listener(on_ready) + bot.add_listener(my_message, 'on_message') + + """ + name = func.__name__ if name is None else name + + if not asyncio.iscoroutinefunction(func): + raise TypeError('Listeners must be coroutines') + + if name in self.extra_events: + self.extra_events[name].append(func) + else: + self.extra_events[name] = [func] + + def remove_listener(self, func, name=None): + """Removes a listener from the pool of listeners. + + Parameters + ----------- + func + The function that was used as a listener to remove. + name: :class:`str` + The name of the event we want to remove. Defaults to + ``func.__name__``. + """ + + name = func.__name__ if name is None else name + + if name in self.extra_events: + try: + self.extra_events[name].remove(func) + except ValueError: + pass + + def listen(self, name=None): + """A decorator that registers another function as an external + event listener. Basically this allows you to listen to multiple + events from different places e.g. such as :func:`.on_ready` + + The functions being listened to must be a :ref:`coroutine `. + + Example + -------- + + .. code-block:: python3 + + @bot.listen() + async def on_message(message): + print('one') + + # in some other file... + + @bot.listen('on_message') + async def my_message(message): + print('two') + + Would print one and two in an unspecified order. + + Raises + ------- + TypeError + The function being listened to is not a coroutine. + """ + + def decorator(func): + self.add_listener(func, name) + return func + + return decorator + + # cogs + + def add_cog(self, cog): + """Adds a "cog" to the bot. + + A cog is a class that has its own event listeners and commands. + + Parameters + ----------- + cog: :class:`.Cog` + The cog to register to the bot. + + Raises + ------- + TypeError + The cog does not inherit from :class:`.Cog`. + CommandError + An error happened during loading. + """ + + if not isinstance(cog, Cog): + raise TypeError('cogs must derive from Cog') + + cog = cog._inject(self) + self.__cogs[cog.__cog_name__] = cog + + def get_cog(self, name): + """Gets the cog instance requested. + + If the cog is not found, ``None`` is returned instead. + + Parameters + ----------- + name: :class:`str` + The name of the cog you are requesting. + This is equivalent to the name passed via keyword + argument in class creation or the class name if unspecified. + + Returns + -------- + Optional[:class:`Cog`] + The cog that was requested. If not found, returns ``None``. + """ + return self.__cogs.get(name) + + def remove_cog(self, name): + """Removes a cog from the bot. + + All registered commands and event listeners that the + cog has registered will be removed as well. + + If no cog is found then this method has no effect. + + Parameters + ----------- + name: :class:`str` + The name of the cog to remove. + """ + + cog = self.__cogs.pop(name, None) + if cog is None: + return + + help_command = self._help_command + if help_command and help_command.cog is cog: + help_command.cog = None + cog._eject(self) + + @property + def cogs(self): + """Mapping[:class:`str`, :class:`Cog`]: A read-only mapping of cog name to cog.""" + return types.MappingProxyType(self.__cogs) + + # extensions + + def _remove_module_references(self, name): + # find all references to the module + # remove the cogs registered from the module + for cogname, cog in self.__cogs.copy().items(): + if _is_submodule(name, cog.__module__): + self.remove_cog(cogname) + + # remove all the commands from the module + for cmd in self.all_commands.copy().values(): + if cmd.module is not None and _is_submodule(name, cmd.module): + if isinstance(cmd, GroupMixin): + cmd.recursively_remove_all_commands() + self.remove_command(cmd.name) + + # remove all the listeners from the module + for event_list in self.extra_events.copy().values(): + remove = [] + for index, event in enumerate(event_list): + if event.__module__ is not None and _is_submodule(name, event.__module__): + remove.append(index) + + for index in reversed(remove): + del event_list[index] + + def _call_module_finalizers(self, lib, key): + try: + func = getattr(lib, 'teardown') + except AttributeError: + pass + else: + try: + func(self) + except Exception: + pass + finally: + self.__extensions.pop(key, None) + sys.modules.pop(key, None) + name = lib.__name__ + for module in list(sys.modules.keys()): + if _is_submodule(name, module): + del sys.modules[module] + + def _load_from_module_spec(self, spec, key): + # precondition: key not in self.__extensions + lib = importlib.util.module_from_spec(spec) + sys.modules[key] = lib + try: + spec.loader.exec_module(lib) + except Exception as e: + del sys.modules[key] + raise errors.ExtensionFailed(key, e) from e + + try: + setup = getattr(lib, 'setup') + except AttributeError: + del sys.modules[key] + raise errors.NoEntryPointError(key) + + try: + setup(self) + except Exception as e: + del sys.modules[key] + self._remove_module_references(lib.__name__) + self._call_module_finalizers(lib, key) + raise errors.ExtensionFailed(key, e) from e + else: + self.__extensions[key] = lib + + def _resolve_name(self, name, package): + try: + return importlib.util.resolve_name(name, package) + except ImportError: + raise errors.ExtensionNotFound(name) + + def load_extension(self, name, *, package=None): + """Loads an extension. + + An extension is a python module that contains commands, cogs, or + listeners. + + An extension must have a global function, ``setup`` defined as + the entry point on what to do when the extension is loaded. This entry + point must have a single argument, the ``bot``. + + Parameters + ------------ + name: :class:`str` + The extension name to load. It must be dot separated like + regular Python imports if accessing a sub-module. e.g. + ``foo.test`` if you want to import ``foo/test.py``. + package: Optional[:class:`str`] + The package name to resolve relative imports with. + This is required when loading an extension using a relative path, e.g ``.foo.test``. + Defaults to ``None``. + + .. versionadded:: 1.7 + + Raises + -------- + ExtensionNotFound + The extension could not be imported. + This is also raised if the name of the extension could not + be resolved using the provided ``package`` parameter. + ExtensionAlreadyLoaded + The extension is already loaded. + NoEntryPointError + The extension does not have a setup function. + ExtensionFailed + The extension or its setup function had an execution error. + """ + + name = self._resolve_name(name, package) + if name in self.__extensions: + raise errors.ExtensionAlreadyLoaded(name) + + spec = importlib.util.find_spec(name) + if spec is None: + raise errors.ExtensionNotFound(name) + + self._load_from_module_spec(spec, name) + + def unload_extension(self, name, *, package=None): + """Unloads an extension. + + When the extension is unloaded, all commands, listeners, and cogs are + removed from the bot and the module is un-imported. + + The extension can provide an optional global function, ``teardown``, + to do miscellaneous clean-up if necessary. This function takes a single + parameter, the ``bot``, similar to ``setup`` from + :meth:`~.Bot.load_extension`. + + Parameters + ------------ + name: :class:`str` + The extension name to unload. It must be dot separated like + regular Python imports if accessing a sub-module. e.g. + ``foo.test`` if you want to import ``foo/test.py``. + package: Optional[:class:`str`] + The package name to resolve relative imports with. + This is required when unloading an extension using a relative path, e.g ``.foo.test``. + Defaults to ``None``. + + .. versionadded:: 1.7 + + Raises + ------- + ExtensionNotFound + The name of the extension could not + be resolved using the provided ``package`` parameter. + ExtensionNotLoaded + The extension was not loaded. + """ + + name = self._resolve_name(name, package) + lib = self.__extensions.get(name) + if lib is None: + raise errors.ExtensionNotLoaded(name) + + self._remove_module_references(lib.__name__) + self._call_module_finalizers(lib, name) + + def reload_extension(self, name, *, package=None): + """Atomically reloads an extension. + + This replaces the extension with the same extension, only refreshed. This is + equivalent to a :meth:`unload_extension` followed by a :meth:`load_extension` + except done in an atomic way. That is, if an operation fails mid-reload then + the bot will roll-back to the prior working state. + + Parameters + ------------ + name: :class:`str` + The extension name to reload. It must be dot separated like + regular Python imports if accessing a sub-module. e.g. + ``foo.test`` if you want to import ``foo/test.py``. + package: Optional[:class:`str`] + The package name to resolve relative imports with. + This is required when reloading an extension using a relative path, e.g ``.foo.test``. + Defaults to ``None``. + + .. versionadded:: 1.7 + + Raises + ------- + ExtensionNotLoaded + The extension was not loaded. + ExtensionNotFound + The extension could not be imported. + This is also raised if the name of the extension could not + be resolved using the provided ``package`` parameter. + NoEntryPointError + The extension does not have a setup function. + ExtensionFailed + The extension setup function had an execution error. + """ + + name = self._resolve_name(name, package) + lib = self.__extensions.get(name) + if lib is None: + raise errors.ExtensionNotLoaded(name) + + # get the previous module states from sys modules + modules = { + name: module + for name, module in sys.modules.items() + if _is_submodule(lib.__name__, name) + } + + try: + # Unload and then load the module... + self._remove_module_references(lib.__name__) + self._call_module_finalizers(lib, name) + self.load_extension(name) + except Exception: + # if the load failed, the remnants should have been + # cleaned from the load_extension function call + # so let's load it from our old compiled library. + lib.setup(self) + self.__extensions[name] = lib + + # revert sys.modules back to normal and raise back to caller + sys.modules.update(modules) + raise + + @property + def extensions(self): + """Mapping[:class:`str`, :class:`py:types.ModuleType`]: A read-only mapping of extension name to extension.""" + return types.MappingProxyType(self.__extensions) + + # help command stuff + + @property + def help_command(self): + return self._help_command + + @help_command.setter + def help_command(self, value): + if value is not None: + if not isinstance(value, HelpCommand): + raise TypeError('help_command must be a subclass of HelpCommand') + if self._help_command is not None: + self._help_command._remove_from_bot(self) + self._help_command = value + value._add_to_bot(self) + elif self._help_command is not None: + self._help_command._remove_from_bot(self) + self._help_command = None + else: + self._help_command = None + + # command processing + + async def get_prefix(self, message): + """|coro| + + Retrieves the prefix the bot is listening to + with the message as a context. + + Parameters + ----------- + message: :class:`discord.Message` + The message context to get the prefix of. + + Returns + -------- + Union[List[:class:`str`], :class:`str`] + A list of prefixes or a single prefix that the bot is + listening for. + """ + prefix = ret = self.command_prefix + if callable(prefix): + ret = await discord.utils.maybe_coroutine(prefix, self, message) + + if not isinstance(ret, str): + try: + ret = list(ret) + except TypeError: + # It's possible that a generator raised this exception. Don't + # replace it with our own error if that's the case. + if isinstance(ret, collections.abc.Iterable): + raise + + raise TypeError("command_prefix must be plain string, iterable of strings, or callable " + "returning either of these, not {}".format(ret.__class__.__name__)) + + if not ret: + raise ValueError("Iterable command_prefix must contain at least one prefix") + + return ret + + async def get_context(self, message, *, cls=Context): + r"""|coro| + + Returns the invocation context from the message. + + This is a more low-level counter-part for :meth:`.process_commands` + to allow users more fine grained control over the processing. + + The returned context is not guaranteed to be a valid invocation + context, :attr:`.Context.valid` must be checked to make sure it is. + If the context is not valid then it is not a valid candidate to be + invoked under :meth:`~.Bot.invoke`. + + Parameters + ----------- + message: :class:`discord.Message` + The message to get the invocation context from. + cls + The factory class that will be used to create the context. + By default, this is :class:`.Context`. Should a custom + class be provided, it must be similar enough to :class:`.Context`\'s + interface. + + Returns + -------- + :class:`.Context` + The invocation context. The type of this can change via the + ``cls`` parameter. + """ + + view = StringView(message.content) + ctx = cls(prefix=None, view=view, bot=self, message=message) + + if self._skip_check(message.author.id, self.user.id): + return ctx + + prefix = await self.get_prefix(message) + invoked_prefix = prefix + + if isinstance(prefix, str): + if not view.skip_string(prefix): + return ctx + else: + try: + # if the context class' __init__ consumes something from the view this + # will be wrong. That seems unreasonable though. + if message.content.startswith(tuple(prefix)): + invoked_prefix = discord.utils.find(view.skip_string, prefix) + else: + return ctx + + except TypeError: + if not isinstance(prefix, list): + raise TypeError("get_prefix must return either a string or a list of string, " + "not {}".format(prefix.__class__.__name__)) + + # It's possible a bad command_prefix got us here. + for value in prefix: + if not isinstance(value, str): + raise TypeError("Iterable command_prefix or list returned from get_prefix must " + "contain only strings, not {}".format(value.__class__.__name__)) + + # Getting here shouldn't happen + raise + + if self.strip_after_prefix: + view.skip_ws() + + invoker = view.get_word() + ctx.invoked_with = invoker + ctx.prefix = invoked_prefix + ctx.command = self.all_commands.get(invoker) + return ctx + + async def invoke(self, ctx): + """|coro| + + Invokes the command given under the invocation context and + handles all the internal event dispatch mechanisms. + + Parameters + ----------- + ctx: :class:`.Context` + The invocation context to invoke. + """ + if ctx.command is not None: + self.dispatch('command', ctx) + try: + if await self.can_run(ctx, call_once=True): + await ctx.command.invoke(ctx) + else: + raise errors.CheckFailure('The global check once functions failed.') + except errors.CommandError as exc: + await ctx.command.dispatch_error(ctx, exc) + else: + self.dispatch('command_completion', ctx) + elif ctx.invoked_with: + exc = errors.CommandNotFound('Command "{}" is not found'.format(ctx.invoked_with)) + self.dispatch('command_error', ctx, exc) + + async def process_commands(self, message): + """|coro| + + This function processes the commands that have been registered + to the bot and other groups. Without this coroutine, none of the + commands will be triggered. + + By default, this coroutine is called inside the :func:`.on_message` + event. If you choose to override the :func:`.on_message` event, then + you should invoke this coroutine as well. + + This is built using other low level tools, and is equivalent to a + call to :meth:`~.Bot.get_context` followed by a call to :meth:`~.Bot.invoke`. + + This also checks if the message's author is a bot and doesn't + call :meth:`~.Bot.get_context` or :meth:`~.Bot.invoke` if so. + + Parameters + ----------- + message: :class:`discord.Message` + The message to process commands for. + """ + if message.author.bot: + return + + ctx = await self.get_context(message) + await self.invoke(ctx) + + async def on_message(self, message): + await self.process_commands(message) + +class Bot(BotBase, discord.Client): + """Represents a discord bot. + + This class is a subclass of :class:`discord.Client` and as a result + anything that you can do with a :class:`discord.Client` you can do with + this bot. + + This class also subclasses :class:`.GroupMixin` to provide the functionality + to manage commands. + + Attributes + ----------- + command_prefix + The command prefix is what the message content must contain initially + to have a command invoked. This prefix could either be a string to + indicate what the prefix should be, or a callable that takes in the bot + as its first parameter and :class:`discord.Message` as its second + parameter and returns the prefix. This is to facilitate "dynamic" + command prefixes. This callable can be either a regular function or + a coroutine. + + An empty string as the prefix always matches, enabling prefix-less + command invocation. While this may be useful in DMs it should be avoided + in servers, as it's likely to cause performance issues and unintended + command invocations. + + The command prefix could also be an iterable of strings indicating that + multiple checks for the prefix should be used and the first one to + match will be the invocation prefix. You can get this prefix via + :attr:`.Context.prefix`. To avoid confusion empty iterables are not + allowed. + + .. note:: + + When passing multiple prefixes be careful to not pass a prefix + that matches a longer prefix occurring later in the sequence. For + example, if the command prefix is ``('!', '!?')`` the ``'!?'`` + prefix will never be matched to any message as the previous one + matches messages starting with ``!?``. This is especially important + when passing an empty string, it should always be last as no prefix + after it will be matched. + case_insensitive: :class:`bool` + Whether the commands should be case insensitive. Defaults to ``False``. This + attribute does not carry over to groups. You must set it to every group if + you require group commands to be case insensitive as well. + description: :class:`str` + The content prefixed into the default help message. + self_bot: :class:`bool` + If ``True``, the bot will only listen to commands invoked by itself rather + than ignoring itself. If ``False`` (the default) then the bot will ignore + itself. This cannot be changed once initialised. + help_command: Optional[:class:`.HelpCommand`] + The help command implementation to use. This can be dynamically + set at runtime. To remove the help command pass ``None``. For more + information on implementing a help command, see :ref:`ext_commands_help_command`. + owner_id: Optional[:class:`int`] + The user ID that owns the bot. If this is not set and is then queried via + :meth:`.is_owner` then it is fetched automatically using + :meth:`~.Bot.application_info`. + owner_ids: Optional[Collection[:class:`int`]] + The user IDs that owns the bot. This is similar to :attr:`owner_id`. + If this is not set and the application is team based, then it is + fetched automatically using :meth:`~.Bot.application_info`. + For performance reasons it is recommended to use a :class:`set` + for the collection. You cannot set both ``owner_id`` and ``owner_ids``. + + .. versionadded:: 1.3 + strip_after_prefix: :class:`bool` + Whether to strip whitespace characters after encountering the command + prefix. This allows for ``! hello`` and ``!hello`` to both work if + the ``command_prefix`` is set to ``!``. Defaults to ``False``. + + .. versionadded:: 1.7 + """ + pass + +class AutoShardedBot(BotBase, discord.AutoShardedClient): + """This is similar to :class:`.Bot` except that it is inherited from + :class:`discord.AutoShardedClient` instead. + """ + pass diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/cog.py b/dist/ba_data/python-site-packages/discord/ext/commands/cog.py new file mode 100644 index 0000000..e12b239 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/ext/commands/cog.py @@ -0,0 +1,451 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import inspect +import copy +from ._types import _BaseCommand + +__all__ = ( + 'CogMeta', + 'Cog', +) + +class CogMeta(type): + """A metaclass for defining a cog. + + Note that you should probably not use this directly. It is exposed + purely for documentation purposes along with making custom metaclasses to intermix + with other metaclasses such as the :class:`abc.ABCMeta` metaclass. + + For example, to create an abstract cog mixin class, the following would be done. + + .. code-block:: python3 + + import abc + + class CogABCMeta(commands.CogMeta, abc.ABCMeta): + pass + + class SomeMixin(metaclass=abc.ABCMeta): + pass + + class SomeCogMixin(SomeMixin, commands.Cog, metaclass=CogABCMeta): + pass + + .. note:: + + When passing an attribute of a metaclass that is documented below, note + that you must pass it as a keyword-only argument to the class creation + like the following example: + + .. code-block:: python3 + + class MyCog(commands.Cog, name='My Cog'): + pass + + Attributes + ----------- + name: :class:`str` + The cog name. By default, it is the name of the class with no modification. + description: :class:`str` + The cog description. By default, it is the cleaned docstring of the class. + + .. versionadded:: 1.6 + + command_attrs: :class:`dict` + A list of attributes to apply to every command inside this cog. The dictionary + is passed into the :class:`Command` options at ``__init__``. + If you specify attributes inside the command attribute in the class, it will + override the one specified inside this attribute. For example: + + .. code-block:: python3 + + class MyCog(commands.Cog, command_attrs=dict(hidden=True)): + @commands.command() + async def foo(self, ctx): + pass # hidden -> True + + @commands.command(hidden=False) + async def bar(self, ctx): + pass # hidden -> False + """ + + def __new__(cls, *args, **kwargs): + name, bases, attrs = args + attrs['__cog_name__'] = kwargs.pop('name', name) + attrs['__cog_settings__'] = kwargs.pop('command_attrs', {}) + + description = kwargs.pop('description', None) + if description is None: + description = inspect.cleandoc(attrs.get('__doc__', '')) + attrs['__cog_description__'] = description + + commands = {} + listeners = {} + no_bot_cog = 'Commands or listeners must not start with cog_ or bot_ (in method {0.__name__}.{1})' + + new_cls = super().__new__(cls, name, bases, attrs, **kwargs) + for base in reversed(new_cls.__mro__): + for elem, value in base.__dict__.items(): + if elem in commands: + del commands[elem] + if elem in listeners: + del listeners[elem] + + is_static_method = isinstance(value, staticmethod) + if is_static_method: + value = value.__func__ + if isinstance(value, _BaseCommand): + if is_static_method: + raise TypeError('Command in method {0}.{1!r} must not be staticmethod.'.format(base, elem)) + if elem.startswith(('cog_', 'bot_')): + raise TypeError(no_bot_cog.format(base, elem)) + commands[elem] = value + elif inspect.iscoroutinefunction(value): + try: + getattr(value, '__cog_listener__') + except AttributeError: + continue + else: + if elem.startswith(('cog_', 'bot_')): + raise TypeError(no_bot_cog.format(base, elem)) + listeners[elem] = value + + new_cls.__cog_commands__ = list(commands.values()) # this will be copied in Cog.__new__ + + listeners_as_list = [] + for listener in listeners.values(): + for listener_name in listener.__cog_listener_names__: + # I use __name__ instead of just storing the value so I can inject + # the self attribute when the time comes to add them to the bot + listeners_as_list.append((listener_name, listener.__name__)) + + new_cls.__cog_listeners__ = listeners_as_list + return new_cls + + def __init__(self, *args, **kwargs): + super().__init__(*args) + + @classmethod + def qualified_name(cls): + return cls.__cog_name__ + +def _cog_special_method(func): + func.__cog_special_method__ = None + return func + +class Cog(metaclass=CogMeta): + """The base class that all cogs must inherit from. + + A cog is a collection of commands, listeners, and optional state to + help group commands together. More information on them can be found on + the :ref:`ext_commands_cogs` page. + + When inheriting from this class, the options shown in :class:`CogMeta` + are equally valid here. + """ + + def __new__(cls, *args, **kwargs): + # For issue 426, we need to store a copy of the command objects + # since we modify them to inject `self` to them. + # To do this, we need to interfere with the Cog creation process. + self = super().__new__(cls) + cmd_attrs = cls.__cog_settings__ + + # Either update the command with the cog provided defaults or copy it. + self.__cog_commands__ = tuple(c._update_copy(cmd_attrs) for c in cls.__cog_commands__) + + lookup = { + cmd.qualified_name: cmd + for cmd in self.__cog_commands__ + } + + # Update the Command instances dynamically as well + for command in self.__cog_commands__: + setattr(self, command.callback.__name__, command) + parent = command.parent + if parent is not None: + # Get the latest parent reference + parent = lookup[parent.qualified_name] + + # Update our parent's reference to our self + parent.remove_command(command.name) + parent.add_command(command) + + return self + + def get_commands(self): + r""" + Returns + -------- + List[:class:`.Command`] + A :class:`list` of :class:`.Command`\s that are + defined inside this cog. + + .. note:: + + This does not include subcommands. + """ + return [c for c in self.__cog_commands__ if c.parent is None] + + @property + def qualified_name(self): + """:class:`str`: Returns the cog's specified name, not the class name.""" + return self.__cog_name__ + + @property + def description(self): + """:class:`str`: Returns the cog's description, typically the cleaned docstring.""" + return self.__cog_description__ + + @description.setter + def description(self, description): + self.__cog_description__ = description + + def walk_commands(self): + """An iterator that recursively walks through this cog's commands and subcommands. + + Yields + ------ + Union[:class:`.Command`, :class:`.Group`] + A command or group from the cog. + """ + from .core import GroupMixin + for command in self.__cog_commands__: + if command.parent is None: + yield command + if isinstance(command, GroupMixin): + yield from command.walk_commands() + + def get_listeners(self): + """Returns a :class:`list` of (name, function) listener pairs that are defined in this cog. + + Returns + -------- + List[Tuple[:class:`str`, :ref:`coroutine `]] + The listeners defined in this cog. + """ + return [(name, getattr(self, method_name)) for name, method_name in self.__cog_listeners__] + + @classmethod + def _get_overridden_method(cls, method): + """Return None if the method is not overridden. Otherwise returns the overridden method.""" + return getattr(method.__func__, '__cog_special_method__', method) + + @classmethod + def listener(cls, name=None): + """A decorator that marks a function as a listener. + + This is the cog equivalent of :meth:`.Bot.listen`. + + Parameters + ------------ + name: :class:`str` + The name of the event being listened to. If not provided, it + defaults to the function's name. + + Raises + -------- + TypeError + The function is not a coroutine function or a string was not passed as + the name. + """ + + if name is not None and not isinstance(name, str): + raise TypeError('Cog.listener expected str but received {0.__class__.__name__!r} instead.'.format(name)) + + def decorator(func): + actual = func + if isinstance(actual, staticmethod): + actual = actual.__func__ + if not inspect.iscoroutinefunction(actual): + raise TypeError('Listener function must be a coroutine function.') + actual.__cog_listener__ = True + to_assign = name or actual.__name__ + try: + actual.__cog_listener_names__.append(to_assign) + except AttributeError: + actual.__cog_listener_names__ = [to_assign] + # we have to return `func` instead of `actual` because + # we need the type to be `staticmethod` for the metaclass + # to pick it up but the metaclass unfurls the function and + # thus the assignments need to be on the actual function + return func + return decorator + + def has_error_handler(self): + """:class:`bool`: Checks whether the cog has an error handler. + + .. versionadded:: 1.7 + """ + return not hasattr(self.cog_command_error.__func__, '__cog_special_method__') + + @_cog_special_method + def cog_unload(self): + """A special method that is called when the cog gets removed. + + This function **cannot** be a coroutine. It must be a regular + function. + + Subclasses must replace this if they want special unloading behaviour. + """ + pass + + @_cog_special_method + def bot_check_once(self, ctx): + """A special method that registers as a :meth:`.Bot.check_once` + check. + + This function **can** be a coroutine and must take a sole parameter, + ``ctx``, to represent the :class:`.Context`. + """ + return True + + @_cog_special_method + def bot_check(self, ctx): + """A special method that registers as a :meth:`.Bot.check` + check. + + This function **can** be a coroutine and must take a sole parameter, + ``ctx``, to represent the :class:`.Context`. + """ + return True + + @_cog_special_method + def cog_check(self, ctx): + """A special method that registers as a :func:`commands.check` + for every command and subcommand in this cog. + + This function **can** be a coroutine and must take a sole parameter, + ``ctx``, to represent the :class:`.Context`. + """ + return True + + @_cog_special_method + async def cog_command_error(self, ctx, error): + """A special method that is called whenever an error + is dispatched inside this cog. + + This is similar to :func:`.on_command_error` except only applying + to the commands inside this cog. + + This **must** be a coroutine. + + Parameters + ----------- + ctx: :class:`.Context` + The invocation context where the error happened. + error: :class:`CommandError` + The error that happened. + """ + pass + + @_cog_special_method + async def cog_before_invoke(self, ctx): + """A special method that acts as a cog local pre-invoke hook. + + This is similar to :meth:`.Command.before_invoke`. + + This **must** be a coroutine. + + Parameters + ----------- + ctx: :class:`.Context` + The invocation context. + """ + pass + + @_cog_special_method + async def cog_after_invoke(self, ctx): + """A special method that acts as a cog local post-invoke hook. + + This is similar to :meth:`.Command.after_invoke`. + + This **must** be a coroutine. + + Parameters + ----------- + ctx: :class:`.Context` + The invocation context. + """ + pass + + def _inject(self, bot): + cls = self.__class__ + + # realistically, the only thing that can cause loading errors + # is essentially just the command loading, which raises if there are + # duplicates. When this condition is met, we want to undo all what + # we've added so far for some form of atomic loading. + for index, command in enumerate(self.__cog_commands__): + command.cog = self + if command.parent is None: + try: + bot.add_command(command) + except Exception as e: + # undo our additions + for to_undo in self.__cog_commands__[:index]: + if to_undo.parent is None: + bot.remove_command(to_undo.name) + raise e + + # check if we're overriding the default + if cls.bot_check is not Cog.bot_check: + bot.add_check(self.bot_check) + + if cls.bot_check_once is not Cog.bot_check_once: + bot.add_check(self.bot_check_once, call_once=True) + + # while Bot.add_listener can raise if it's not a coroutine, + # this precondition is already met by the listener decorator + # already, thus this should never raise. + # Outside of, memory errors and the like... + for name, method_name in self.__cog_listeners__: + bot.add_listener(getattr(self, method_name), name) + + return self + + def _eject(self, bot): + cls = self.__class__ + + try: + for command in self.__cog_commands__: + if command.parent is None: + bot.remove_command(command.name) + + for _, method_name in self.__cog_listeners__: + bot.remove_listener(getattr(self, method_name)) + + if cls.bot_check is not Cog.bot_check: + bot.remove_check(self.bot_check) + + if cls.bot_check_once is not Cog.bot_check_once: + bot.remove_check(self.bot_check_once, call_once=True) + finally: + try: + self.cog_unload() + except Exception: + pass diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/context.py b/dist/ba_data/python-site-packages/discord/ext/commands/context.py new file mode 100644 index 0000000..8df4f73 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/ext/commands/context.py @@ -0,0 +1,340 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import discord.abc +import discord.utils + +class Context(discord.abc.Messageable): + r"""Represents the context in which a command is being invoked under. + + This class contains a lot of meta data to help you understand more about + the invocation context. This class is not created manually and is instead + passed around to commands as the first parameter. + + This class implements the :class:`~discord.abc.Messageable` ABC. + + Attributes + ----------- + message: :class:`.Message` + The message that triggered the command being executed. + bot: :class:`.Bot` + The bot that contains the command being executed. + args: :class:`list` + The list of transformed arguments that were passed into the command. + If this is accessed during the :func:`on_command_error` event + then this list could be incomplete. + kwargs: :class:`dict` + A dictionary of transformed arguments that were passed into the command. + Similar to :attr:`args`\, if this is accessed in the + :func:`on_command_error` event then this dict could be incomplete. + prefix: :class:`str` + The prefix that was used to invoke the command. + command: :class:`Command` + The command that is being invoked currently. + invoked_with: :class:`str` + The command name that triggered this invocation. Useful for finding out + which alias called the command. + invoked_parents: List[:class:`str`] + The command names of the parents that triggered this invocation. Useful for + finding out which aliases called the command. + + For example in commands ``?a b c test``, the invoked parents are ``['a', 'b', 'c']``. + + .. versionadded:: 1.7 + + invoked_subcommand: :class:`Command` + The subcommand that was invoked. + If no valid subcommand was invoked then this is equal to ``None``. + subcommand_passed: Optional[:class:`str`] + The string that was attempted to call a subcommand. This does not have + to point to a valid registered subcommand and could just point to a + nonsense string. If nothing was passed to attempt a call to a + subcommand then this is set to ``None``. + command_failed: :class:`bool` + A boolean that indicates if the command failed to be parsed, checked, + or invoked. + """ + + def __init__(self, **attrs): + self.message = attrs.pop('message', None) + self.bot = attrs.pop('bot', None) + self.args = attrs.pop('args', []) + self.kwargs = attrs.pop('kwargs', {}) + self.prefix = attrs.pop('prefix') + self.command = attrs.pop('command', None) + self.view = attrs.pop('view', None) + self.invoked_with = attrs.pop('invoked_with', None) + self.invoked_parents = attrs.pop('invoked_parents', []) + self.invoked_subcommand = attrs.pop('invoked_subcommand', None) + self.subcommand_passed = attrs.pop('subcommand_passed', None) + self.command_failed = attrs.pop('command_failed', False) + self._state = self.message._state + + async def invoke(self, *args, **kwargs): + r"""|coro| + + Calls a command with the arguments given. + + This is useful if you want to just call the callback that a + :class:`.Command` holds internally. + + .. note:: + + This does not handle converters, checks, cooldowns, pre-invoke, + or after-invoke hooks in any matter. It calls the internal callback + directly as-if it was a regular function. + + You must take care in passing the proper arguments when + using this function. + + .. warning:: + + The first parameter passed **must** be the command being invoked. + + Parameters + ----------- + command: :class:`.Command` + The command that is going to be called. + \*args + The arguments to to use. + \*\*kwargs + The keyword arguments to use. + + Raises + ------- + TypeError + The command argument to invoke is missing. + """ + + try: + command = args[0] + except IndexError: + raise TypeError('Missing command to invoke.') from None + + arguments = [] + if command.cog is not None: + arguments.append(command.cog) + + arguments.append(self) + arguments.extend(args[1:]) + + ret = await command.callback(*arguments, **kwargs) + return ret + + async def reinvoke(self, *, call_hooks=False, restart=True): + """|coro| + + Calls the command again. + + This is similar to :meth:`~.Context.invoke` except that it bypasses + checks, cooldowns, and error handlers. + + .. note:: + + If you want to bypass :exc:`.UserInputError` derived exceptions, + it is recommended to use the regular :meth:`~.Context.invoke` + as it will work more naturally. After all, this will end up + using the old arguments the user has used and will thus just + fail again. + + Parameters + ------------ + call_hooks: :class:`bool` + Whether to call the before and after invoke hooks. + restart: :class:`bool` + Whether to start the call chain from the very beginning + or where we left off (i.e. the command that caused the error). + The default is to start where we left off. + + Raises + ------- + ValueError + The context to reinvoke is not valid. + """ + cmd = self.command + view = self.view + if cmd is None: + raise ValueError('This context is not valid.') + + # some state to revert to when we're done + index, previous = view.index, view.previous + invoked_with = self.invoked_with + invoked_subcommand = self.invoked_subcommand + invoked_parents = self.invoked_parents + subcommand_passed = self.subcommand_passed + + if restart: + to_call = cmd.root_parent or cmd + view.index = len(self.prefix) + view.previous = 0 + self.invoked_parents = [] + self.invoked_with = view.get_word() # advance to get the root command + else: + to_call = cmd + + try: + await to_call.reinvoke(self, call_hooks=call_hooks) + finally: + self.command = cmd + view.index = index + view.previous = previous + self.invoked_with = invoked_with + self.invoked_subcommand = invoked_subcommand + self.invoked_parents = invoked_parents + self.subcommand_passed = subcommand_passed + + @property + def valid(self): + """:class:`bool`: Checks if the invocation context is valid to be invoked with.""" + return self.prefix is not None and self.command is not None + + async def _get_channel(self): + return self.channel + + @property + def cog(self): + """Optional[:class:`.Cog`]: Returns the cog associated with this context's command. None if it does not exist.""" + + if self.command is None: + return None + return self.command.cog + + @discord.utils.cached_property + def guild(self): + """Optional[:class:`.Guild`]: Returns the guild associated with this context's command. None if not available.""" + return self.message.guild + + @discord.utils.cached_property + def channel(self): + """Union[:class:`.abc.Messageable`]: Returns the channel associated with this context's command. + Shorthand for :attr:`.Message.channel`. + """ + return self.message.channel + + @discord.utils.cached_property + def author(self): + """Union[:class:`~discord.User`, :class:`.Member`]: + Returns the author associated with this context's command. Shorthand for :attr:`.Message.author` + """ + return self.message.author + + @discord.utils.cached_property + def me(self): + """Union[:class:`.Member`, :class:`.ClientUser`]: + Similar to :attr:`.Guild.me` except it may return the :class:`.ClientUser` in private message contexts. + """ + return self.guild.me if self.guild is not None else self.bot.user + + @property + def voice_client(self): + r"""Optional[:class:`.VoiceProtocol`]: A shortcut to :attr:`.Guild.voice_client`\, if applicable.""" + g = self.guild + return g.voice_client if g else None + + async def send_help(self, *args): + """send_help(entity=) + + |coro| + + Shows the help command for the specified entity if given. + The entity can be a command or a cog. + + If no entity is given, then it'll show help for the + entire bot. + + If the entity is a string, then it looks up whether it's a + :class:`Cog` or a :class:`Command`. + + .. note:: + + Due to the way this function works, instead of returning + something similar to :meth:`~.commands.HelpCommand.command_not_found` + this returns :class:`None` on bad input or no help command. + + Parameters + ------------ + entity: Optional[Union[:class:`Command`, :class:`Cog`, :class:`str`]] + The entity to show help for. + + Returns + -------- + Any + The result of the help command, if any. + """ + from .core import Group, Command, wrap_callback + from .errors import CommandError + + bot = self.bot + cmd = bot.help_command + + if cmd is None: + return None + + cmd = cmd.copy() + cmd.context = self + if len(args) == 0: + await cmd.prepare_help_command(self, None) + mapping = cmd.get_bot_mapping() + injected = wrap_callback(cmd.send_bot_help) + try: + return await injected(mapping) + except CommandError as e: + await cmd.on_help_command_error(self, e) + return None + + entity = args[0] + if entity is None: + return None + + if isinstance(entity, str): + entity = bot.get_cog(entity) or bot.get_command(entity) + + try: + entity.qualified_name + except AttributeError: + # if we're here then it's not a cog, group, or command. + return None + + await cmd.prepare_help_command(self, entity.qualified_name) + + try: + if hasattr(entity, '__cog_commands__'): + injected = wrap_callback(cmd.send_cog_help) + return await injected(entity) + elif isinstance(entity, Group): + injected = wrap_callback(cmd.send_group_help) + return await injected(entity) + elif isinstance(entity, Command): + injected = wrap_callback(cmd.send_command_help) + return await injected(entity) + else: + return None + except CommandError as e: + await cmd.on_help_command_error(self, e) + + @discord.utils.copy_doc(discord.Message.reply) + async def reply(self, content=None, **kwargs): + return await self.message.reply(content, **kwargs) diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/converter.py b/dist/ba_data/python-site-packages/discord/ext/commands/converter.py new file mode 100644 index 0000000..fdc7649 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/ext/commands/converter.py @@ -0,0 +1,852 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import re +import inspect +import typing + +import discord + +from .errors import * + +__all__ = ( + 'Converter', + 'MemberConverter', + 'UserConverter', + 'MessageConverter', + 'PartialMessageConverter', + 'TextChannelConverter', + 'InviteConverter', + 'GuildConverter', + 'RoleConverter', + 'GameConverter', + 'ColourConverter', + 'ColorConverter', + 'VoiceChannelConverter', + 'StageChannelConverter', + 'EmojiConverter', + 'PartialEmojiConverter', + 'CategoryChannelConverter', + 'IDConverter', + 'StoreChannelConverter', + 'clean_content', + 'Greedy', +) + +def _get_from_guilds(bot, getter, argument): + result = None + for guild in bot.guilds: + result = getattr(guild, getter)(argument) + if result: + return result + return result + +_utils_get = discord.utils.get + +class Converter: + """The base class of custom converters that require the :class:`.Context` + to be passed to be useful. + + This allows you to implement converters that function similar to the + special cased ``discord`` classes. + + Classes that derive from this should override the :meth:`~.Converter.convert` + method to do its conversion logic. This method must be a :ref:`coroutine `. + """ + + async def convert(self, ctx, argument): + """|coro| + + The method to override to do conversion logic. + + If an error is found while converting, it is recommended to + raise a :exc:`.CommandError` derived exception as it will + properly propagate to the error handlers. + + Parameters + ----------- + ctx: :class:`.Context` + The invocation context that the argument is being used in. + argument: :class:`str` + The argument that is being converted. + + Raises + ------- + :exc:`.CommandError` + A generic exception occurred when converting the argument. + :exc:`.BadArgument` + The converter failed to convert the argument. + """ + raise NotImplementedError('Derived classes need to implement this.') + +class IDConverter(Converter): + def __init__(self): + self._id_regex = re.compile(r'([0-9]{15,20})$') + super().__init__() + + def _get_id_match(self, argument): + return self._id_regex.match(argument) + +class MemberConverter(IDConverter): + """Converts to a :class:`~discord.Member`. + + All lookups are via the local guild. If in a DM context, then the lookup + is done by the global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name#discrim + 4. Lookup by name + 5. Lookup by nickname + + .. versionchanged:: 1.5 + Raise :exc:`.MemberNotFound` instead of generic :exc:`.BadArgument` + + .. versionchanged:: 1.5.1 + This converter now lazily fetches members from the gateway and HTTP APIs, + optionally caching the result if :attr:`.MemberCacheFlags.joined` is enabled. + """ + + async def query_member_named(self, guild, argument): + cache = guild._state.member_cache_flags.joined + if len(argument) > 5 and argument[-5] == '#': + username, _, discriminator = argument.rpartition('#') + members = await guild.query_members(username, limit=100, cache=cache) + return discord.utils.get(members, name=username, discriminator=discriminator) + else: + members = await guild.query_members(argument, limit=100, cache=cache) + return discord.utils.find(lambda m: m.name == argument or m.nick == argument, members) + + async def query_member_by_id(self, bot, guild, user_id): + ws = bot._get_websocket(shard_id=guild.shard_id) + cache = guild._state.member_cache_flags.joined + if ws.is_ratelimited(): + # If we're being rate limited on the WS, then fall back to using the HTTP API + # So we don't have to wait ~60 seconds for the query to finish + try: + member = await guild.fetch_member(user_id) + except discord.HTTPException: + return None + + if cache: + guild._add_member(member) + return member + + # If we're not being rate limited then we can use the websocket to actually query + members = await guild.query_members(limit=1, user_ids=[user_id], cache=cache) + if not members: + return None + return members[0] + + async def convert(self, ctx, argument): + bot = ctx.bot + match = self._get_id_match(argument) or re.match(r'<@!?([0-9]+)>$', argument) + guild = ctx.guild + result = None + user_id = None + if match is None: + # not a mention... + if guild: + result = guild.get_member_named(argument) + else: + result = _get_from_guilds(bot, 'get_member_named', argument) + else: + user_id = int(match.group(1)) + if guild: + result = guild.get_member(user_id) or _utils_get(ctx.message.mentions, id=user_id) + else: + result = _get_from_guilds(bot, 'get_member', user_id) + + if result is None: + if guild is None: + raise MemberNotFound(argument) + + if user_id is not None: + result = await self.query_member_by_id(bot, guild, user_id) + else: + result = await self.query_member_named(guild, argument) + + if not result: + raise MemberNotFound(argument) + + return result + +class UserConverter(IDConverter): + """Converts to a :class:`~discord.User`. + + All lookups are via the global user cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name#discrim + 4. Lookup by name + + .. versionchanged:: 1.5 + Raise :exc:`.UserNotFound` instead of generic :exc:`.BadArgument` + + .. versionchanged:: 1.6 + This converter now lazily fetches users from the HTTP APIs if an ID is passed + and it's not available in cache. + """ + async def convert(self, ctx, argument): + match = self._get_id_match(argument) or re.match(r'<@!?([0-9]+)>$', argument) + result = None + state = ctx._state + + if match is not None: + user_id = int(match.group(1)) + result = ctx.bot.get_user(user_id) or _utils_get(ctx.message.mentions, id=user_id) + if result is None: + try: + result = await ctx.bot.fetch_user(user_id) + except discord.HTTPException: + raise UserNotFound(argument) from None + + return result + + arg = argument + + # Remove the '@' character if this is the first character from the argument + if arg[0] == '@': + # Remove first character + arg = arg[1:] + + # check for discriminator if it exists, + if len(arg) > 5 and arg[-5] == '#': + discrim = arg[-4:] + name = arg[:-5] + predicate = lambda u: u.name == name and u.discriminator == discrim + result = discord.utils.find(predicate, state._users.values()) + if result is not None: + return result + + predicate = lambda u: u.name == arg + result = discord.utils.find(predicate, state._users.values()) + + if result is None: + raise UserNotFound(argument) + + return result + +class PartialMessageConverter(Converter): + """Converts to a :class:`discord.PartialMessage`. + + .. versionadded:: 1.7 + + The creation strategy is as follows (in order): + + 1. By "{channel ID}-{message ID}" (retrieved by shift-clicking on "Copy ID") + 2. By message ID (The message is assumed to be in the context channel.) + 3. By message URL + """ + def _get_id_matches(self, argument): + id_regex = re.compile(r'(?:(?P[0-9]{15,20})-)?(?P[0-9]{15,20})$') + link_regex = re.compile( + r'https?://(?:(ptb|canary|www)\.)?discord(?:app)?\.com/channels/' + r'(?:[0-9]{15,20}|@me)' + r'/(?P[0-9]{15,20})/(?P[0-9]{15,20})/?$' + ) + match = id_regex.match(argument) or link_regex.match(argument) + if not match: + raise MessageNotFound(argument) + channel_id = match.group("channel_id") + return int(match.group("message_id")), int(channel_id) if channel_id else None + + async def convert(self, ctx, argument): + message_id, channel_id = self._get_id_matches(argument) + channel = ctx.bot.get_channel(channel_id) if channel_id else ctx.channel + if not channel: + raise ChannelNotFound(channel_id) + return discord.PartialMessage(channel=channel, id=message_id) + +class MessageConverter(PartialMessageConverter): + """Converts to a :class:`discord.Message`. + + .. versionadded:: 1.1 + + The lookup strategy is as follows (in order): + + 1. Lookup by "{channel ID}-{message ID}" (retrieved by shift-clicking on "Copy ID") + 2. Lookup by message ID (the message **must** be in the context channel) + 3. Lookup by message URL + + .. versionchanged:: 1.5 + Raise :exc:`.ChannelNotFound`, :exc:`.MessageNotFound` or :exc:`.ChannelNotReadable` instead of generic :exc:`.BadArgument` + """ + async def convert(self, ctx, argument): + message_id, channel_id = self._get_id_matches(argument) + message = ctx.bot._connection._get_message(message_id) + if message: + return message + channel = ctx.bot.get_channel(channel_id) if channel_id else ctx.channel + if not channel: + raise ChannelNotFound(channel_id) + try: + return await channel.fetch_message(message_id) + except discord.NotFound: + raise MessageNotFound(argument) + except discord.Forbidden: + raise ChannelNotReadable(channel) + +class TextChannelConverter(IDConverter): + """Converts to a :class:`~discord.TextChannel`. + + All lookups are via the local guild. If in a DM context, then the lookup + is done by the global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name + + .. versionchanged:: 1.5 + Raise :exc:`.ChannelNotFound` instead of generic :exc:`.BadArgument` + """ + async def convert(self, ctx, argument): + bot = ctx.bot + + match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) + result = None + guild = ctx.guild + + if match is None: + # not a mention + if guild: + result = discord.utils.get(guild.text_channels, name=argument) + else: + def check(c): + return isinstance(c, discord.TextChannel) and c.name == argument + result = discord.utils.find(check, bot.get_all_channels()) + else: + channel_id = int(match.group(1)) + if guild: + result = guild.get_channel(channel_id) + else: + result = _get_from_guilds(bot, 'get_channel', channel_id) + + if not isinstance(result, discord.TextChannel): + raise ChannelNotFound(argument) + + return result + +class VoiceChannelConverter(IDConverter): + """Converts to a :class:`~discord.VoiceChannel`. + + All lookups are via the local guild. If in a DM context, then the lookup + is done by the global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name + + .. versionchanged:: 1.5 + Raise :exc:`.ChannelNotFound` instead of generic :exc:`.BadArgument` + """ + async def convert(self, ctx, argument): + bot = ctx.bot + match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) + result = None + guild = ctx.guild + + if match is None: + # not a mention + if guild: + result = discord.utils.get(guild.voice_channels, name=argument) + else: + def check(c): + return isinstance(c, discord.VoiceChannel) and c.name == argument + result = discord.utils.find(check, bot.get_all_channels()) + else: + channel_id = int(match.group(1)) + if guild: + result = guild.get_channel(channel_id) + else: + result = _get_from_guilds(bot, 'get_channel', channel_id) + + if not isinstance(result, discord.VoiceChannel): + raise ChannelNotFound(argument) + + return result + +class StageChannelConverter(IDConverter): + """Converts to a :class:`~discord.StageChannel`. + + .. versionadded:: 1.7 + + All lookups are via the local guild. If in a DM context, then the lookup + is done by the global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name + """ + async def convert(self, ctx, argument): + bot = ctx.bot + match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) + result = None + guild = ctx.guild + + if match is None: + # not a mention + if guild: + result = discord.utils.get(guild.stage_channels, name=argument) + else: + def check(c): + return isinstance(c, discord.StageChannel) and c.name == argument + result = discord.utils.find(check, bot.get_all_channels()) + else: + channel_id = int(match.group(1)) + if guild: + result = guild.get_channel(channel_id) + else: + result = _get_from_guilds(bot, 'get_channel', channel_id) + + if not isinstance(result, discord.StageChannel): + raise ChannelNotFound(argument) + + return result + +class CategoryChannelConverter(IDConverter): + """Converts to a :class:`~discord.CategoryChannel`. + + All lookups are via the local guild. If in a DM context, then the lookup + is done by the global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name + + .. versionchanged:: 1.5 + Raise :exc:`.ChannelNotFound` instead of generic :exc:`.BadArgument` + """ + async def convert(self, ctx, argument): + bot = ctx.bot + + match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) + result = None + guild = ctx.guild + + if match is None: + # not a mention + if guild: + result = discord.utils.get(guild.categories, name=argument) + else: + def check(c): + return isinstance(c, discord.CategoryChannel) and c.name == argument + result = discord.utils.find(check, bot.get_all_channels()) + else: + channel_id = int(match.group(1)) + if guild: + result = guild.get_channel(channel_id) + else: + result = _get_from_guilds(bot, 'get_channel', channel_id) + + if not isinstance(result, discord.CategoryChannel): + raise ChannelNotFound(argument) + + return result + +class StoreChannelConverter(IDConverter): + """Converts to a :class:`~discord.StoreChannel`. + + All lookups are via the local guild. If in a DM context, then the lookup + is done by the global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name. + + .. versionadded:: 1.7 + """ + + async def convert(self, ctx, argument): + bot = ctx.bot + match = self._get_id_match(argument) or re.match(r'<#([0-9]+)>$', argument) + result = None + guild = ctx.guild + + if match is None: + # not a mention + if guild: + result = discord.utils.get(guild.channels, name=argument) + else: + def check(c): + return isinstance(c, discord.StoreChannel) and c.name == argument + result = discord.utils.find(check, bot.get_all_channels()) + else: + channel_id = int(match.group(1)) + if guild: + result = guild.get_channel(channel_id) + else: + result = _get_from_guilds(bot, 'get_channel', channel_id) + + if not isinstance(result, discord.StoreChannel): + raise ChannelNotFound(argument) + + return result + +class ColourConverter(Converter): + """Converts to a :class:`~discord.Colour`. + + .. versionchanged:: 1.5 + Add an alias named ColorConverter + + The following formats are accepted: + + - ``0x`` + - ``#`` + - ``0x#`` + - ``rgb(, , )`` + - Any of the ``classmethod`` in :class:`Colour` + + - The ``_`` in the name can be optionally replaced with spaces. + + Like CSS, ```` can be either 0-255 or 0-100% and ```` can be + either a 6 digit hex number or a 3 digit hex shortcut (e.g. #fff). + + .. versionchanged:: 1.5 + Raise :exc:`.BadColourArgument` instead of generic :exc:`.BadArgument` + + .. versionchanged:: 1.7 + Added support for ``rgb`` function and 3-digit hex shortcuts + """ + + RGB_REGEX = re.compile(r'rgb\s*\((?P[0-9]{1,3}%?)\s*,\s*(?P[0-9]{1,3}%?)\s*,\s*(?P[0-9]{1,3}%?)\s*\)') + + def parse_hex_number(self, argument): + arg = ''.join(i * 2 for i in argument) if len(argument) == 3 else argument + try: + value = int(arg, base=16) + if not (0 <= value <= 0xFFFFFF): + raise BadColourArgument(argument) + except ValueError: + raise BadColourArgument(argument) + else: + return discord.Color(value=value) + + def parse_rgb_number(self, argument, number): + if number[-1] == '%': + value = int(number[:-1]) + if not (0 <= value <= 100): + raise BadColourArgument(argument) + return round(255 * (value / 100)) + + value = int(number) + if not (0 <= value <= 255): + raise BadColourArgument(argument) + return value + + def parse_rgb(self, argument, *, regex=RGB_REGEX): + match = regex.match(argument) + if match is None: + raise BadColourArgument(argument) + + red = self.parse_rgb_number(argument, match.group('r')) + green = self.parse_rgb_number(argument, match.group('g')) + blue = self.parse_rgb_number(argument, match.group('b')) + return discord.Color.from_rgb(red, green, blue) + + async def convert(self, ctx, argument): + if argument[0] == '#': + return self.parse_hex_number(argument[1:]) + + if argument[0:2] == '0x': + rest = argument[2:] + # Legacy backwards compatible syntax + if rest.startswith('#'): + return self.parse_hex_number(rest[1:]) + return self.parse_hex_number(rest) + + arg = argument.lower() + if arg[0:3] == 'rgb': + return self.parse_rgb(arg) + + arg = arg.replace(' ', '_') + method = getattr(discord.Colour, arg, None) + if arg.startswith('from_') or method is None or not inspect.ismethod(method): + raise BadColourArgument(arg) + return method() + +ColorConverter = ColourConverter + +class RoleConverter(IDConverter): + """Converts to a :class:`~discord.Role`. + + All lookups are via the local guild. If in a DM context, the converter raises + :exc:`.NoPrivateMessage` exception. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by mention. + 3. Lookup by name + + .. versionchanged:: 1.5 + Raise :exc:`.RoleNotFound` instead of generic :exc:`.BadArgument` + """ + async def convert(self, ctx, argument): + guild = ctx.guild + if not guild: + raise NoPrivateMessage() + + match = self._get_id_match(argument) or re.match(r'<@&([0-9]+)>$', argument) + if match: + result = guild.get_role(int(match.group(1))) + else: + result = discord.utils.get(guild._roles.values(), name=argument) + + if result is None: + raise RoleNotFound(argument) + return result + +class GameConverter(Converter): + """Converts to :class:`~discord.Game`.""" + async def convert(self, ctx, argument): + return discord.Game(name=argument) + +class InviteConverter(Converter): + """Converts to a :class:`~discord.Invite`. + + This is done via an HTTP request using :meth:`.Bot.fetch_invite`. + + .. versionchanged:: 1.5 + Raise :exc:`.BadInviteArgument` instead of generic :exc:`.BadArgument` + """ + async def convert(self, ctx, argument): + try: + invite = await ctx.bot.fetch_invite(argument) + return invite + except Exception as exc: + raise BadInviteArgument() from exc + +class GuildConverter(IDConverter): + """Converts to a :class:`~discord.Guild`. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by name. (There is no disambiguation for Guilds with multiple matching names). + + .. versionadded:: 1.7 + """ + + async def convert(self, ctx, argument): + match = self._get_id_match(argument) + result = None + + if match is not None: + guild_id = int(match.group(1)) + result = ctx.bot.get_guild(guild_id) + + if result is None: + result = discord.utils.get(ctx.bot.guilds, name=argument) + + if result is None: + raise GuildNotFound(argument) + return result + +class EmojiConverter(IDConverter): + """Converts to a :class:`~discord.Emoji`. + + All lookups are done for the local guild first, if available. If that lookup + fails, then it checks the client's global cache. + + The lookup strategy is as follows (in order): + + 1. Lookup by ID. + 2. Lookup by extracting ID from the emoji. + 3. Lookup by name + + .. versionchanged:: 1.5 + Raise :exc:`.EmojiNotFound` instead of generic :exc:`.BadArgument` + """ + async def convert(self, ctx, argument): + match = self._get_id_match(argument) or re.match(r'$', argument) + result = None + bot = ctx.bot + guild = ctx.guild + + if match is None: + # Try to get the emoji by name. Try local guild first. + if guild: + result = discord.utils.get(guild.emojis, name=argument) + + if result is None: + result = discord.utils.get(bot.emojis, name=argument) + else: + emoji_id = int(match.group(1)) + + # Try to look up emoji by id. + if guild: + result = discord.utils.get(guild.emojis, id=emoji_id) + + if result is None: + result = discord.utils.get(bot.emojis, id=emoji_id) + + if result is None: + raise EmojiNotFound(argument) + + return result + +class PartialEmojiConverter(Converter): + """Converts to a :class:`~discord.PartialEmoji`. + + This is done by extracting the animated flag, name and ID from the emoji. + + .. versionchanged:: 1.5 + Raise :exc:`.PartialEmojiConversionFailure` instead of generic :exc:`.BadArgument` + """ + async def convert(self, ctx, argument): + match = re.match(r'<(a?):([a-zA-Z0-9\_]+):([0-9]+)>$', argument) + + if match: + emoji_animated = bool(match.group(1)) + emoji_name = match.group(2) + emoji_id = int(match.group(3)) + + return discord.PartialEmoji.with_state(ctx.bot._connection, animated=emoji_animated, name=emoji_name, + id=emoji_id) + + raise PartialEmojiConversionFailure(argument) + +class clean_content(Converter): + """Converts the argument to mention scrubbed version of + said content. + + This behaves similarly to :attr:`~discord.Message.clean_content`. + + Attributes + ------------ + fix_channel_mentions: :class:`bool` + Whether to clean channel mentions. + use_nicknames: :class:`bool` + Whether to use nicknames when transforming mentions. + escape_markdown: :class:`bool` + Whether to also escape special markdown characters. + remove_markdown: :class:`bool` + Whether to also remove special markdown characters. This option is not supported with ``escape_markdown`` + + .. versionadded:: 1.7 + """ + def __init__(self, *, fix_channel_mentions=False, use_nicknames=True, escape_markdown=False, remove_markdown=False): + self.fix_channel_mentions = fix_channel_mentions + self.use_nicknames = use_nicknames + self.escape_markdown = escape_markdown + self.remove_markdown = remove_markdown + + async def convert(self, ctx, argument): + message = ctx.message + transformations = {} + + if self.fix_channel_mentions and ctx.guild: + def resolve_channel(id, *, _get=ctx.guild.get_channel): + ch = _get(id) + return ('<#%s>' % id), ('#' + ch.name if ch else '#deleted-channel') + + transformations.update(resolve_channel(channel) for channel in message.raw_channel_mentions) + + if self.use_nicknames and ctx.guild: + def resolve_member(id, *, _get=ctx.guild.get_member): + m = _get(id) + return '@' + m.display_name if m else '@deleted-user' + else: + def resolve_member(id, *, _get=ctx.bot.get_user): + m = _get(id) + return '@' + m.name if m else '@deleted-user' + + + transformations.update( + ('<@%s>' % member_id, resolve_member(member_id)) + for member_id in message.raw_mentions + ) + + transformations.update( + ('<@!%s>' % member_id, resolve_member(member_id)) + for member_id in message.raw_mentions + ) + + if ctx.guild: + def resolve_role(_id, *, _find=ctx.guild.get_role): + r = _find(_id) + return '@' + r.name if r else '@deleted-role' + + transformations.update( + ('<@&%s>' % role_id, resolve_role(role_id)) + for role_id in message.raw_role_mentions + ) + + def repl(obj): + return transformations.get(obj.group(0), '') + + pattern = re.compile('|'.join(transformations.keys())) + result = pattern.sub(repl, argument) + + if self.escape_markdown: + result = discord.utils.escape_markdown(result) + elif self.remove_markdown: + result = discord.utils.remove_markdown(result) + + # Completely ensure no mentions escape: + return discord.utils.escape_mentions(result) + +class _Greedy: + __slots__ = ('converter',) + + def __init__(self, *, converter=None): + self.converter = converter + + def __getitem__(self, params): + if not isinstance(params, tuple): + params = (params,) + if len(params) != 1: + raise TypeError('Greedy[...] only takes a single argument') + converter = params[0] + + if not (callable(converter) or isinstance(converter, Converter) or hasattr(converter, '__origin__')): + raise TypeError('Greedy[...] expects a type or a Converter instance.') + + if converter is str or converter is type(None) or converter is _Greedy: + raise TypeError('Greedy[%s] is invalid.' % converter.__name__) + + if getattr(converter, '__origin__', None) is typing.Union and type(None) in converter.__args__: + raise TypeError('Greedy[%r] is invalid.' % converter) + + return self.__class__(converter=converter) + +Greedy = _Greedy() diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/cooldowns.py b/dist/ba_data/python-site-packages/discord/ext/commands/cooldowns.py new file mode 100644 index 0000000..54a5339 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/ext/commands/cooldowns.py @@ -0,0 +1,295 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +from discord.enums import Enum +import time +import asyncio +from collections import deque + +from ...abc import PrivateChannel +from .errors import MaxConcurrencyReached + +__all__ = ( + 'BucketType', + 'Cooldown', + 'CooldownMapping', + 'MaxConcurrency', +) + +class BucketType(Enum): + default = 0 + user = 1 + guild = 2 + channel = 3 + member = 4 + category = 5 + role = 6 + + def get_key(self, msg): + if self is BucketType.user: + return msg.author.id + elif self is BucketType.guild: + return (msg.guild or msg.author).id + elif self is BucketType.channel: + return msg.channel.id + elif self is BucketType.member: + return ((msg.guild and msg.guild.id), msg.author.id) + elif self is BucketType.category: + return (msg.channel.category or msg.channel).id + elif self is BucketType.role: + # we return the channel id of a private-channel as there are only roles in guilds + # and that yields the same result as for a guild with only the @everyone role + # NOTE: PrivateChannel doesn't actually have an id attribute but we assume we are + # recieving a DMChannel or GroupChannel which inherit from PrivateChannel and do + return (msg.channel if isinstance(msg.channel, PrivateChannel) else msg.author.top_role).id + + def __call__(self, msg): + return self.get_key(msg) + + +class Cooldown: + __slots__ = ('rate', 'per', 'type', '_window', '_tokens', '_last') + + def __init__(self, rate, per, type): + self.rate = int(rate) + self.per = float(per) + self.type = type + self._window = 0.0 + self._tokens = self.rate + self._last = 0.0 + + if not callable(self.type): + raise TypeError('Cooldown type must be a BucketType or callable') + + def get_tokens(self, current=None): + if not current: + current = time.time() + + tokens = self._tokens + + if current > self._window + self.per: + tokens = self.rate + return tokens + + def get_retry_after(self, current=None): + current = current or time.time() + tokens = self.get_tokens(current) + + if tokens == 0: + return self.per - (current - self._window) + + return 0.0 + + def update_rate_limit(self, current=None): + current = current or time.time() + self._last = current + + self._tokens = self.get_tokens(current) + + # first token used means that we start a new rate limit window + if self._tokens == self.rate: + self._window = current + + # check if we are rate limited + if self._tokens == 0: + return self.per - (current - self._window) + + # we're not so decrement our tokens + self._tokens -= 1 + + # see if we got rate limited due to this token change, and if + # so update the window to point to our current time frame + if self._tokens == 0: + self._window = current + + def reset(self): + self._tokens = self.rate + self._last = 0.0 + + def copy(self): + return Cooldown(self.rate, self.per, self.type) + + def __repr__(self): + return ''.format(self) + +class CooldownMapping: + def __init__(self, original): + self._cache = {} + self._cooldown = original + + def copy(self): + ret = CooldownMapping(self._cooldown) + ret._cache = self._cache.copy() + return ret + + @property + def valid(self): + return self._cooldown is not None + + @classmethod + def from_cooldown(cls, rate, per, type): + return cls(Cooldown(rate, per, type)) + + def _bucket_key(self, msg): + return self._cooldown.type(msg) + + def _verify_cache_integrity(self, current=None): + # we want to delete all cache objects that haven't been used + # in a cooldown window. e.g. if we have a command that has a + # cooldown of 60s and it has not been used in 60s then that key should be deleted + current = current or time.time() + dead_keys = [k for k, v in self._cache.items() if current > v._last + v.per] + for k in dead_keys: + del self._cache[k] + + def get_bucket(self, message, current=None): + if self._cooldown.type is BucketType.default: + return self._cooldown + + self._verify_cache_integrity(current) + key = self._bucket_key(message) + if key not in self._cache: + bucket = self._cooldown.copy() + self._cache[key] = bucket + else: + bucket = self._cache[key] + + return bucket + + def update_rate_limit(self, message, current=None): + bucket = self.get_bucket(message, current) + return bucket.update_rate_limit(current) + +class _Semaphore: + """This class is a version of a semaphore. + + If you're wondering why asyncio.Semaphore isn't being used, + it's because it doesn't expose the internal value. This internal + value is necessary because I need to support both `wait=True` and + `wait=False`. + + An asyncio.Queue could have been used to do this as well -- but it is + not as inefficient since internally that uses two queues and is a bit + overkill for what is basically a counter. + """ + + __slots__ = ('value', 'loop', '_waiters') + + def __init__(self, number): + self.value = number + self.loop = asyncio.get_event_loop() + self._waiters = deque() + + def __repr__(self): + return '<_Semaphore value={0.value} waiters={1}>'.format(self, len(self._waiters)) + + def locked(self): + return self.value == 0 + + def is_active(self): + return len(self._waiters) > 0 + + def wake_up(self): + while self._waiters: + future = self._waiters.popleft() + if not future.done(): + future.set_result(None) + return + + async def acquire(self, *, wait=False): + if not wait and self.value <= 0: + # signal that we're not acquiring + return False + + while self.value <= 0: + future = self.loop.create_future() + self._waiters.append(future) + try: + await future + except: + future.cancel() + if self.value > 0 and not future.cancelled(): + self.wake_up() + raise + + self.value -= 1 + return True + + def release(self): + self.value += 1 + self.wake_up() + +class MaxConcurrency: + __slots__ = ('number', 'per', 'wait', '_mapping') + + def __init__(self, number, *, per, wait): + self._mapping = {} + self.per = per + self.number = number + self.wait = wait + + if number <= 0: + raise ValueError('max_concurrency \'number\' cannot be less than 1') + + if not isinstance(per, BucketType): + raise TypeError('max_concurrency \'per\' must be of type BucketType not %r' % type(per)) + + def copy(self): + return self.__class__(self.number, per=self.per, wait=self.wait) + + def __repr__(self): + return ''.format(self) + + def get_key(self, message): + return self.per.get_key(message) + + async def acquire(self, message): + key = self.get_key(message) + + try: + sem = self._mapping[key] + except KeyError: + self._mapping[key] = sem = _Semaphore(self.number) + + acquired = await sem.acquire(wait=self.wait) + if not acquired: + raise MaxConcurrencyReached(self.number, self.per) + + async def release(self, message): + # Technically there's no reason for this function to be async + # But it might be more useful in the future + key = self.get_key(message) + + try: + sem = self._mapping[key] + except KeyError: + # ...? peculiar + return + else: + sem.release() + + if sem.value >= self.number and not sem.is_active(): + del self._mapping[key] diff --git a/dist/ba_data/python-site-packages/discord/ext/commands/core.py b/dist/ba_data/python-site-packages/discord/ext/commands/core.py new file mode 100644 index 0000000..1c22ec0 --- /dev/null +++ b/dist/ba_data/python-site-packages/discord/ext/commands/core.py @@ -0,0 +1,2070 @@ +# -*- coding: utf-8 -*- + +""" +The MIT License (MIT) + +Copyright (c) 2015-present Rapptz + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +""" + +import asyncio +import functools +import inspect +import typing +import datetime + +import discord + +from .errors import * +from .cooldowns import Cooldown, BucketType, CooldownMapping, MaxConcurrency +from . import converter as converters +from ._types import _BaseCommand +from .cog import Cog + +__all__ = ( + 'Command', + 'Group', + 'GroupMixin', + 'command', + 'group', + 'has_role', + 'has_permissions', + 'has_any_role', + 'check', + 'check_any', + 'before_invoke', + 'after_invoke', + 'bot_has_role', + 'bot_has_permissions', + 'bot_has_any_role', + 'cooldown', + 'max_concurrency', + 'dm_only', + 'guild_only', + 'is_owner', + 'is_nsfw', + 'has_guild_permissions', + 'bot_has_guild_permissions' +) + +def wrap_callback(coro): + @functools.wraps(coro) + async def wrapped(*args, **kwargs): + try: + ret = await coro(*args, **kwargs) + except CommandError: + raise + except asyncio.CancelledError: + return + except Exception as exc: + raise CommandInvokeError(exc) from exc + return ret + return wrapped + +def hooked_wrapped_callback(command, ctx, coro): + @functools.wraps(coro) + async def wrapped(*args, **kwargs): + try: + ret = await coro(*args, **kwargs) + except CommandError: + ctx.command_failed = True + raise + except asyncio.CancelledError: + ctx.command_failed = True + return + except Exception as exc: + ctx.command_failed = True + raise CommandInvokeError(exc) from exc + finally: + if command._max_concurrency is not None: + await command._max_concurrency.release(ctx) + + await command.call_after_hooks(ctx) + return ret + return wrapped + +def _convert_to_bool(argument): + lowered = argument.lower() + if lowered in ('yes', 'y', 'true', 't', '1', 'enable', 'on'): + return True + elif lowered in ('no', 'n', 'false', 'f', '0', 'disable', 'off'): + return False + else: + raise BadBoolArgument(lowered) + +class _CaseInsensitiveDict(dict): + def __contains__(self, k): + return super().__contains__(k.casefold()) + + def __delitem__(self, k): + return super().__delitem__(k.casefold()) + + def __getitem__(self, k): + return super().__getitem__(k.casefold()) + + def get(self, k, default=None): + return super().get(k.casefold(), default) + + def pop(self, k, default=None): + return super().pop(k.casefold(), default) + + def __setitem__(self, k, v): + super().__setitem__(k.casefold(), v) + +class Command(_BaseCommand): + r"""A class that implements the protocol for a bot text command. + + These are not created manually, instead they are created via the + decorator or functional interface. + + Attributes + ----------- + name: :class:`str` + The name of the command. + callback: :ref:`coroutine ` + The coroutine that is executed when the command is called. + help: :class:`str` + The long help text for the command. + brief: Optional[:class:`str`] + The short help text for the command. + usage: Optional[:class:`str`] + A replacement for arguments in the default help text. + aliases: Union[List[:class:`str`], Tuple[:class:`str`]] + The list of aliases the command can be invoked under. + enabled: :class:`bool` + A boolean that indicates if the command is currently enabled. + If the command is invoked while it is disabled, then + :exc:`.DisabledCommand` is raised to the :func:`.on_command_error` + event. Defaults to ``True``. + parent: Optional[:class:`Command`] + The parent command that this command belongs to. ``None`` if there + isn't one. + cog: Optional[:class:`Cog`] + The cog that this command belongs to. ``None`` if there isn't one. + checks: List[Callable[[:class:`.Context`], :class:`bool`]] + A list of predicates that verifies if the command could be executed + with the given :class:`.Context` as the sole parameter. If an exception + is necessary to be thrown to signal failure, then one inherited from + :exc:`.CommandError` should be used. Note that if the checks fail then + :exc:`.CheckFailure` exception is raised to the :func:`.on_command_error` + event. + description: :class:`str` + The message prefixed into the default help command. + hidden: :class:`bool` + If ``True``\, the default help command does not show this in the + help output. + rest_is_raw: :class:`bool` + If ``False`` and a keyword-only argument is provided then the keyword + only argument is stripped and handled as if it was a regular argument + that handles :exc:`.MissingRequiredArgument` and default values in a + regular matter rather than passing the rest completely raw. If ``True`` + then the keyword-only argument will pass in the rest of the arguments + in a completely raw matter. Defaults to ``False``. + invoked_subcommand: Optional[:class:`Command`] + The subcommand that was invoked, if any. + require_var_positional: :class:`bool` + If ``True`` and a variadic positional argument is specified, requires + the user to specify at least one argument. Defaults to ``False``. + + .. versionadded:: 1.5 + + ignore_extra: :class:`bool` + If ``True``\, ignores extraneous strings passed to a command if all its + requirements are met (e.g. ``?foo a b c`` when only expecting ``a`` + and ``b``). Otherwise :func:`.on_command_error` and local error handlers + are called with :exc:`.TooManyArguments`. Defaults to ``True``. + cooldown_after_parsing: :class:`bool` + If ``True``\, cooldown processing is done after argument parsing, + which calls converters. If ``False`` then cooldown processing is done + first and then the converters are called second. Defaults to ``False``. + """ + + def __new__(cls, *args, **kwargs): + # if you're wondering why this is done, it's because we need to ensure + # we have a complete original copy of **kwargs even for classes that + # mess with it by popping before delegating to the subclass __init__. + # In order to do this, we need to control the instance creation and + # inject the original kwargs through __new__ rather than doing it + # inside __init__. + self = super().__new__(cls) + + # we do a shallow copy because it's probably the most common use case. + # this could potentially break if someone modifies a list or something + # while it's in movement, but for now this is the cheapest and + # fastest way to do what we want. + self.__original_kwargs__ = kwargs.copy() + return self + + def __init__(self, func, **kwargs): + if not asyncio.iscoroutinefunction(func): + raise TypeError('Callback must be a coroutine.') + + self.name = name = kwargs.get('name') or func.__name__ + if not isinstance(name, str): + raise TypeError('Name of a command must be a string.') + + self.callback = func + self.enabled = kwargs.get('enabled', True) + + help_doc = kwargs.get('help') + if help_doc is not None: + help_doc = inspect.cleandoc(help_doc) + else: + help_doc = inspect.getdoc(func) + if isinstance(help_doc, bytes): + help_doc = help_doc.decode('utf-8') + + self.help = help_doc + + self.brief = kwargs.get('brief') + self.usage = kwargs.get('usage') + self.rest_is_raw = kwargs.get('rest_is_raw', False) + self.aliases = kwargs.get('aliases', []) + + if not isinstance(self.aliases, (list, tuple)): + raise TypeError("Aliases of a command must be a list or a tuple of strings.") + + self.description = inspect.cleandoc(kwargs.get('description', '')) + self.hidden = kwargs.get('hidden', False) + + try: + checks = func.__commands_checks__ + checks.reverse() + except AttributeError: + checks = kwargs.get('checks', []) + finally: + self.checks = checks + + try: + cooldown = func.__commands_cooldown__ + except AttributeError: + cooldown = kwargs.get('cooldown') + finally: + self._buckets = CooldownMapping(cooldown) + + try: + max_concurrency = func.__commands_max_concurrency__ + except AttributeError: + max_concurrency = kwargs.get('max_concurrency') + finally: + self._max_concurrency = max_concurrency + + self.require_var_positional = kwargs.get('require_var_positional', False) + self.ignore_extra = kwargs.get('ignore_extra', True) + self.cooldown_after_parsing = kwargs.get('cooldown_after_parsing', False) + self.cog = None + + # bandaid for the fact that sometimes parent can be the bot instance + parent = kwargs.get('parent') + self.parent = parent if isinstance(parent, _BaseCommand) else None + + try: + before_invoke = func.__before_invoke__ + except AttributeError: + self._before_invoke = None + else: + self.before_invoke(before_invoke) + + try: + after_invoke = func.__after_invoke__ + except AttributeError: + self._after_invoke = None + else: + self.after_invoke(after_invoke) + + @property + def callback(self): + return self._callback + + @callback.setter + def callback(self, function): + self._callback = function + self.module = function.__module__ + + signature = inspect.signature(function) + self.params = signature.parameters.copy() + + # PEP-563 allows postponing evaluation of annotations with a __future__ + # import. When postponed, Parameter.annotation will be a string and must + # be replaced with the real value for the converters to work later on + for key, value in self.params.items(): + if isinstance(value.annotation, str): + self.params[key] = value = value.replace(annotation=eval(value.annotation, function.__globals__)) + + # fail early for when someone passes an unparameterized Greedy type + if value.annotation is converters.Greedy: + raise TypeError('Unparameterized Greedy[...] is disallowed in signature.') + + def add_check(self, func): + """Adds a check to the command. + + This is the non-decorator interface to :func:`.check`. + + .. versionadded:: 1.3 + + Parameters + ----------- + func + The function that will be used as a check. + """ + + self.checks.append(func) + + def remove_check(self, func): + """Removes a check from the command. + + This function is idempotent and will not raise an exception + if the function is not in the command's checks. + + .. versionadded:: 1.3 + + Parameters + ----------- + func + The function to remove from the checks. + """ + + try: + self.checks.remove(func) + except ValueError: + pass + + def update(self, **kwargs): + """Updates :class:`Command` instance with updated attribute. + + This works similarly to the :func:`.command` decorator in terms + of parameters in that they are passed to the :class:`Command` or + subclass constructors, sans the name and callback. + """ + self.__init__(self.callback, **dict(self.__original_kwargs__, **kwargs)) + + async def __call__(self, *args, **kwargs): + """|coro| + + Calls the internal callback that the command holds. + + .. note:: + + This bypasses all mechanisms -- including checks, converters, + invoke hooks, cooldowns, etc. You must take care to pass + the proper arguments and types to this function. + + .. versionadded:: 1.3 + """ + if self.cog is not None: + return await self.callback(self.cog, *args, **kwargs) + else: + return await self.callback(*args, **kwargs) + + def _ensure_assignment_on_copy(self, other): + other._before_invoke = self._before_invoke + other._after_invoke = self._after_invoke + if self.checks != other.checks: + other.checks = self.checks.copy() + if self._buckets.valid and not other._buckets.valid: + other._buckets = self._buckets.copy() + if self._max_concurrency != other._max_concurrency: + other._max_concurrency = self._max_concurrency.copy() + + try: + other.on_error = self.on_error + except AttributeError: + pass + return other + + def copy(self): + """Creates a copy of this command. + + Returns + -------- + :class:`Command` + A new instance of this command. + """ + ret = self.__class__(self.callback, **self.__original_kwargs__) + return self._ensure_assignment_on_copy(ret) + + def _update_copy(self, kwargs): + if kwargs: + kw = kwargs.copy() + kw.update(self.__original_kwargs__) + copy = self.__class__(self.callback, **kw) + return self._ensure_assignment_on_copy(copy) + else: + return self.copy() + + async def dispatch_error(self, ctx, error): + ctx.command_failed = True + cog = self.cog + try: + coro = self.on_error + except AttributeError: + pass + else: + injected = wrap_callback(coro) + if cog is not None: + await injected(cog, ctx, error) + else: + await injected(ctx, error) + + try: + if cog is not None: + local = Cog._get_overridden_method(cog.cog_command_error) + if local is not None: + wrapped = wrap_callback(local) + await wrapped(ctx, error) + finally: + ctx.bot.dispatch('command_error', ctx, error) + + async def _actual_conversion(self, ctx, converter, argument, param): + if converter is bool: + return _convert_to_bool(argument) + + try: + module = converter.__module__ + except AttributeError: + pass + else: + if module is not None and (module.startswith('discord.') and not module.endswith('converter')): + converter = getattr(converters, converter.__name__ + 'Converter', converter) + + try: + if inspect.isclass(converter): + if issubclass(converter, converters.Converter): + instance = converter() + ret = await instance.convert(ctx, argument) + return ret + else: + method = getattr(converter, 'convert', None) + if method is not None and inspect.ismethod(method): + ret = await method(ctx, argument) + return ret + elif isinstance(converter, converters.Converter): + ret = await converter.convert(ctx, argument) + return ret + except CommandError: + raise + except Exception as exc: + raise ConversionError(converter, exc) from exc + + try: + return converter(argument) + except CommandError: + raise + except Exception as exc: + try: + name = converter.__name__ + except AttributeError: + name = converter.__class__.__name__ + + raise BadArgument('Converting to "{}" failed for parameter "{}".'.format(name, param.name)) from exc + + async def do_conversion(self, ctx, converter, argument, param): + try: + origin = converter.__origin__ + except AttributeError: + pass + else: + if origin is typing.Union: + errors = [] + _NoneType = type(None) + for conv in converter.__args__: + # if we got to this part in the code, then the previous conversions have failed + # so we should just undo the view, return the default, and allow parsing to continue + # with the other parameters + if conv is _NoneType and param.kind != param.VAR_POSITIONAL: + ctx.view.undo() + return None if param.default is param.empty else param.default + + try: + value = await self._actual_conversion(ctx, conv, argument, param) + except CommandError as exc: + errors.append(exc) + else: + return value + + # if we're here, then we failed all the converters + raise BadUnionArgument(param, converter.__args__, errors) + + return await self._actual_conversion(ctx, converter, argument, param) + + def _get_converter(self, param): + converter = param.annotation + if converter is param.empty: + if param.default is not param.empty: + converter = str if param.default is None else type(param.default) + else: + converter = str + return converter + + async def transform(self, ctx, param): + required = param.default is param.empty + converter = self._get_converter(param) + consume_rest_is_special = param.kind == param.KEYWORD_ONLY and not self.rest_is_raw + view = ctx.view + view.skip_ws() + + # The greedy converter is simple -- it keeps going until it fails in which case, + # it undos the view ready for the next parameter to use instead + if type(converter) is converters._Greedy: + if param.kind == param.POSITIONAL_OR_KEYWORD or param.kind == param.POSITIONAL_ONLY: + return await self._transform_greedy_pos(ctx, param, required, converter.converter) + elif param.kind == param.VAR_POSITIONAL: + return await self._transform_greedy_var_pos(ctx, param, converter.converter) + else: + # if we're here, then it's a KEYWORD_ONLY param type + # since this is mostly useless, we'll helpfully transform Greedy[X] + # into just X and do the parsing that way. + converter = converter.converter + + if view.eof: + if param.kind == param.VAR_POSITIONAL: + raise RuntimeError() # break the loop + if required: + if self._is_typing_optional(param.annotation): + return None + raise MissingRequiredArgument(param) + return param.default + + previous = view.index + if consume_rest_is_special: + argument = view.read_rest().strip() + else: + argument = view.get_quoted_word() + view.previous = previous + + return await self.do_conversion(ctx, converter, argument, param) + + async def _transform_greedy_pos(self, ctx, param, required, converter): + view = ctx.view + result = [] + while not view.eof: + # for use with a manual undo + previous = view.index + + view.skip_ws() + try: + argument = view.get_quoted_word() + value = await self.do_conversion(ctx, converter, argument, param) + except (CommandError, ArgumentParsingError): + view.index = previous + break + else: + result.append(value) + + if not result and not required: + return param.default + return result + + async def _transform_greedy_var_pos(self, ctx, param, converter): + view = ctx.view + previous = view.index + try: + argument = view.get_quoted_word() + value = await self.do_conversion(ctx, converter, argument, param) + except (CommandError, ArgumentParsingError): + view.index = previous + raise RuntimeError() from None # break loop + else: + return value + + @property + def clean_params(self): + """OrderedDict[:class:`str`, :class:`inspect.Parameter`]: + Retrieves the parameter OrderedDict without the context or self parameters. + + Useful for inspecting signature. + """ + result = self.params.copy() + if self.cog is not None: + # first parameter is self + result.popitem(last=False) + + try: + # first/second parameter is context + result.popitem(last=False) + except Exception: + raise ValueError('Missing context parameter') from None + + return result + + @property + def full_parent_name(self): + """:class:`str`: Retrieves the fully qualified parent command name. + + This the base command name required to execute it. For example, + in ``?one two three`` the parent name would be ``one two``. + """ + entries = [] + command = self + while command.parent is not None: + command = command.parent + entries.append(command.name) + + return ' '.join(reversed(entries)) + + @property + def parents(self): + """List[:class:`Command`]: Retrieves the parents of this command. + + If the command has no parents then it returns an empty :class:`list`. + + For example in commands ``?a b c test``, the parents are ``[c, b, a]``. + + .. versionadded:: 1.1 + """ + entries = [] + command = self + while command.parent is not None: + command = command.parent + entries.append(command) + + return entries + + @property + def root_parent(self): + """Optional[:class:`Command`]: Retrieves the root parent of this command. + + If the command has no parents then it returns ``None``. + + For example in commands ``?a b c test``, the root parent is ``a``. + """ + if not self.parent: + return None + return self.parents[-1] + + @property + def qualified_name(self): + """:class:`str`: Retrieves the fully qualified command name. + + This is the full parent name with the command name as well. + For example, in ``?one two three`` the qualified name would be + ``one two three``. + """ + + parent = self.full_parent_name + if parent: + return parent + ' ' + self.name + else: + return self.name + + def __str__(self): + return self.qualified_name + + async def _parse_arguments(self, ctx): + ctx.args = [ctx] if self.cog is None else [self.cog, ctx] + ctx.kwargs = {} + args = ctx.args + kwargs = ctx.kwargs + + view = ctx.view + iterator = iter(self.params.items()) + + if self.cog is not None: + # we have 'self' as the first parameter so just advance + # the iterator and resume parsing + try: + next(iterator) + except StopIteration: + fmt = 'Callback for {0.name} command is missing "self" parameter.' + raise discord.ClientException(fmt.format(self)) + + # next we have the 'ctx' as the next parameter + try: + next(iterator) + except StopIteration: + fmt = 'Callback for {0.name} command is missing "ctx" parameter.' + raise discord.ClientException(fmt.format(self)) + + for name, param in iterator: + if param.kind == param.POSITIONAL_OR_KEYWORD or param.kind == param.POSITIONAL_ONLY: + transformed = await self.transform(ctx, param) + args.append(transformed) + elif param.kind == param.KEYWORD_ONLY: + # kwarg only param denotes "consume rest" semantics + if self.rest_is_raw: + converter = self._get_converter(param) + argument = view.read_rest() + kwargs[name] = await self.do_conversion(ctx, converter, argument, param) + else: + kwargs[name] = await self.transform(ctx, param) + break + elif param.kind == param.VAR_POSITIONAL: + if view.eof and self.require_var_positional: + raise MissingRequiredArgument(param) + while not view.eof: + try: + transformed = await self.transform(ctx, param) + args.append(transformed) + except RuntimeError: + break + + if not self.ignore_extra and not view.eof: + raise TooManyArguments('Too many arguments passed to ' + self.qualified_name) + + async def call_before_hooks(self, ctx): + # now that we're done preparing we can call the pre-command hooks + # first, call the command local hook: + cog = self.cog + if self._before_invoke is not None: + # should be cog if @commands.before_invoke is used + instance = getattr(self._before_invoke, '__self__', cog) + # __self__ only exists for methods, not functions + # however, if @command.before_invoke is used, it will be a function + if instance: + await self._before_invoke(instance, ctx) + else: + await self._before_invoke(ctx) + + # call the cog local hook if applicable: + if cog is not None: + hook = Cog._get_overridden_method(cog.cog_before_invoke) + if hook is not None: + await hook(ctx) + + # call the bot global hook if necessary + hook = ctx.bot._before_invoke + if hook is not None: + await hook(ctx) + + async def call_after_hooks(self, ctx): + cog = self.cog + if self._after_invoke is not None: + instance = getattr(self._after_invoke, '__self__', cog) + if instance: + await self._after_invoke(instance, ctx) + else: + await self._after_invoke(ctx) + + # call the cog local hook if applicable: + if cog is not None: + hook = Cog._get_overridden_method(cog.cog_after_invoke) + if hook is not None: + await hook(ctx) + + hook = ctx.bot._after_invoke + if hook is not None: + await hook(ctx) + + def _prepare_cooldowns(self, ctx): + if self._buckets.valid: + dt = ctx.message.edited_at or ctx.message.created_at + current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() + bucket = self._buckets.get_bucket(ctx.message, current) + retry_after = bucket.update_rate_limit(current) + if retry_after: + raise CommandOnCooldown(bucket, retry_after) + + async def prepare(self, ctx): + ctx.command = self + + if not await self.can_run(ctx): + raise CheckFailure('The check functions for command {0.qualified_name} failed.'.format(self)) + + if self._max_concurrency is not None: + await self._max_concurrency.acquire(ctx) + + try: + if self.cooldown_after_parsing: + await self._parse_arguments(ctx) + self._prepare_cooldowns(ctx) + else: + self._prepare_cooldowns(ctx) + await self._parse_arguments(ctx) + + await self.call_before_hooks(ctx) + except: + if self._max_concurrency is not None: + await self._max_concurrency.release(ctx) + raise + + def is_on_cooldown(self, ctx): + """Checks whether the command is currently on cooldown. + + Parameters + ----------- + ctx: :class:`.Context` + The invocation context to use when checking the commands cooldown status. + + Returns + -------- + :class:`bool` + A boolean indicating if the command is on cooldown. + """ + if not self._buckets.valid: + return False + + bucket = self._buckets.get_bucket(ctx.message) + dt = ctx.message.edited_at or ctx.message.created_at + current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() + return bucket.get_tokens(current) == 0 + + def reset_cooldown(self, ctx): + """Resets the cooldown on this command. + + Parameters + ----------- + ctx: :class:`.Context` + The invocation context to reset the cooldown under. + """ + if self._buckets.valid: + bucket = self._buckets.get_bucket(ctx.message) + bucket.reset() + + def get_cooldown_retry_after(self, ctx): + """Retrieves the amount of seconds before this command can be tried again. + + .. versionadded:: 1.4 + + Parameters + ----------- + ctx: :class:`.Context` + The invocation context to retrieve the cooldown from. + + Returns + -------- + :class:`float` + The amount of time left on this command's cooldown in seconds. + If this is ``0.0`` then the command isn't on cooldown. + """ + if self._buckets.valid: + bucket = self._buckets.get_bucket(ctx.message) + dt = ctx.message.edited_at or ctx.message.created_at + current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() + return bucket.get_retry_after(current) + + return 0.0 + + async def invoke(self, ctx): + await self.prepare(ctx) + + # terminate the invoked_subcommand chain. + # since we're in a regular command (and not a group) then + # the invoked subcommand is None. + ctx.invoked_subcommand = None + ctx.subcommand_passed = None + injected = hooked_wrapped_callback(self, ctx, self.callback) + await injected(*ctx.args, **ctx.kwargs) + + async def reinvoke(self, ctx, *, call_hooks=False): + ctx.command = self + await self._parse_arguments(ctx) + + if call_hooks: + await self.call_before_hooks(ctx) + + ctx.invoked_subcommand = None + try: + await self.callback(*ctx.args, **ctx.kwargs) + except: + ctx.command_failed = True + raise + finally: + if call_hooks: + await self.call_after_hooks(ctx) + + def error(self, coro): + """A decorator that registers a coroutine as a local error handler. + + A local error handler is an :func:`.on_command_error` event limited to + a single command. However, the :func:`.on_command_error` is still + invoked afterwards as the catch-all. + + Parameters + ----------- + coro: :ref:`coroutine ` + The coroutine to register as the local error handler. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine. + """ + + if not asyncio.iscoroutinefunction(coro): + raise TypeError('The error handler must be a coroutine.') + + self.on_error = coro + return coro + + def has_error_handler(self): + """:class:`bool`: Checks whether the command has an error handler registered. + + .. versionadded:: 1.7 + """ + return hasattr(self, 'on_error') + + def before_invoke(self, coro): + """A decorator that registers a coroutine as a pre-invoke hook. + + A pre-invoke hook is called directly before the command is + called. This makes it a useful function to set up database + connections or any type of set up required. + + This pre-invoke hook takes a sole parameter, a :class:`.Context`. + + See :meth:`.Bot.before_invoke` for more info. + + Parameters + ----------- + coro: :ref:`coroutine ` + The coroutine to register as the pre-invoke hook. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine. + """ + if not asyncio.iscoroutinefunction(coro): + raise TypeError('The pre-invoke hook must be a coroutine.') + + self._before_invoke = coro + return coro + + def after_invoke(self, coro): + """A decorator that registers a coroutine as a post-invoke hook. + + A post-invoke hook is called directly after the command is + called. This makes it a useful function to clean-up database + connections or any type of clean up required. + + This post-invoke hook takes a sole parameter, a :class:`.Context`. + + See :meth:`.Bot.after_invoke` for more info. + + Parameters + ----------- + coro: :ref:`coroutine ` + The coroutine to register as the post-invoke hook. + + Raises + ------- + TypeError + The coroutine passed is not actually a coroutine. + """ + if not asyncio.iscoroutinefunction(coro): + raise TypeError('The post-invoke hook must be a coroutine.') + + self._after_invoke = coro + return coro + + @property + def cog_name(self): + """Optional[:class:`str`]: The name of the cog this command belongs to, if any.""" + return type(self.cog).__cog_name__ if self.cog is not None else None + + @property + def short_doc(self): + """:class:`str`: Gets the "short" documentation of a command. + + By default, this is the :attr:`brief` attribute. + If that lookup leads to an empty string then the first line of the + :attr:`help` attribute is used instead. + """ + if self.brief is not None: + return self.brief + if self.help is not None: + return self.help.split('\n', 1)[0] + return '' + + def _is_typing_optional(self, annotation): + try: + origin = annotation.__origin__ + except AttributeError: + return False + + if origin is not typing.Union: + return False + + return annotation.__args__[-1] is type(None) + + @property + def signature(self): + """:class:`str`: Returns a POSIX-like signature useful for help command output.""" + if self.usage is not None: + return self.usage + + + params = self.clean_params + if not params: + return '' + + result = [] + for name, param in params.items(): + greedy = isinstance(param.annotation, converters._Greedy) + + if param.default is not param.empty: + # We don't want None or '' to trigger the [name=value] case and instead it should + # do [name] since [name=None] or [name=] are not exactly useful for the user. + should_print = param.default if isinstance(param.default, str) else param.default is not None + if should_print: + result.append('[%s=%s]' % (name, param.default) if not greedy else + '[%s=%s]...' % (name, param.default)) + continue + else: + result.append('[%s]' % name) + + elif param.kind == param.VAR_POSITIONAL: + if self.require_var_positional: + result.append('<%s...>' % name) + else: + result.append('[%s...]' % name) + elif greedy: + result.append('[%s]...' % name) + elif self._is_typing_optional(param.annotation): + result.append('[%s]' % name) + else: + result.append('<%s>' % name) + + return ' '.join(result) + + async def can_run(self, ctx): + """|coro| + + Checks if the command can be executed by checking all the predicates + inside the :attr:`checks` attribute. This also checks whether the + command is disabled. + + .. versionchanged:: 1.3 + Checks whether the command is disabled or not + + Parameters + ----------- + ctx: :class:`.Context` + The ctx of the command currently being invoked. + + Raises + ------- + :class:`CommandError` + Any command error that was raised during a check call will be propagated + by this function. + + Returns + -------- + :class:`bool` + A boolean indicating if the command can be invoked. + """ + + if not self.enabled: + raise DisabledCommand('{0.name} command is disabled'.format(self)) + + original = ctx.command + ctx.command = self + + try: + if not await ctx.bot.can_run(ctx): + raise CheckFailure('The global check functions for command {0.qualified_name} failed.'.format(self)) + + cog = self.cog + if cog is not None: + local_check = Cog._get_overridden_method(cog.cog_check) + if local_check is not None: + ret = await discord.utils.maybe_coroutine(local_check, ctx) + if not ret: + return False + + predicates = self.checks + if not predicates: + # since we have no checks, then we just return True. + return True + + return await discord.utils.async_all(predicate(ctx) for predicate in predicates) + finally: + ctx.command = original + +class GroupMixin: + """A mixin that implements common functionality for classes that behave + similar to :class:`.Group` and are allowed to register commands. + + Attributes + ----------- + all_commands: :class:`dict` + A mapping of command name to :class:`.Command` + objects. + case_insensitive: :class:`bool` + Whether the commands should be case insensitive. Defaults to ``False``. + """ + def __init__(self, *args, **kwargs): + case_insensitive = kwargs.get('case_insensitive', False) + self.all_commands = _CaseInsensitiveDict() if case_insensitive else {} + self.case_insensitive = case_insensitive + super().__init__(*args, **kwargs) + + @property + def commands(self): + """Set[:class:`.Command`]: A unique set of commands without aliases that are registered.""" + return set(self.all_commands.values()) + + def recursively_remove_all_commands(self): + for command in self.all_commands.copy().values(): + if isinstance(command, GroupMixin): + command.recursively_remove_all_commands() + self.remove_command(command.name) + + def add_command(self, command): + """Adds a :class:`.Command` into the internal list of commands. + + This is usually not called, instead the :meth:`~.GroupMixin.command` or + :meth:`~.GroupMixin.group` shortcut decorators are used instead. + + .. versionchanged:: 1.4 + Raise :exc:`.CommandRegistrationError` instead of generic :exc:`.ClientException` + + Parameters + ----------- + command: :class:`Command` + The command to add. + + Raises + ------- + :exc:`.CommandRegistrationError` + If the command or its alias is already registered by different command. + TypeError + If the command passed is not a subclass of :class:`.Command`. + """ + + if not isinstance(command, Command): + raise TypeError('The command passed must be a subclass of Command') + + if isinstance(self, Command): + command.parent = self + + if command.name in self.all_commands: + raise CommandRegistrationError(command.name) + + self.all_commands[command.name] = command + for alias in command.aliases: + if alias in self.all_commands: + self.remove_command(command.name) + raise CommandRegistrationError(alias, alias_conflict=True) + self.all_commands[alias] = command + + def remove_command(self, name): + """Remove a :class:`.Command` from the internal list + of commands. + + This could also be used as a way to remove aliases. + + Parameters + ----------- + name: :class:`str` + The name of the command to remove. + + Returns + -------- + Optional[:class:`.Command`] + The command that was removed. If the name is not valid then + ``None`` is returned instead. + """ + command = self.all_commands.pop(name, None) + + # does not exist + if command is None: + return None + + if name in command.aliases: + # we're removing an alias so we don't want to remove the rest + return command + + # we're not removing the alias so let's delete the rest of them. + for alias in command.aliases: + cmd = self.all_commands.pop(alias, None) + # in the case of a CommandRegistrationError, an alias might conflict + # with an already existing command. If this is the case, we want to + # make sure the pre-existing command is not removed. + if cmd not in (None, command): + self.all_commands[alias] = cmd + return command + + def walk_commands(self): + """An iterator that recursively walks through all commands and subcommands. + + .. versionchanged:: 1.4 + Duplicates due to aliases are no longer returned + + Yields + ------ + Union[:class:`.Command`, :class:`.Group`] + A command or group from the internal list of commands. + """ + for command in self.commands: + yield command + if isinstance(command, GroupMixin): + yield from command.walk_commands() + + def get_command(self, name): + """Get a :class:`.Command` from the internal list + of commands. + + This could also be used as a way to get aliases. + + The name could be fully qualified (e.g. ``'foo bar'``) will get + the subcommand ``bar`` of the group command ``foo``. If a + subcommand is not found then ``None`` is returned just as usual. + + Parameters + ----------- + name: :class:`str` + The name of the command to get. + + Returns + -------- + Optional[:class:`Command`] + The command that was requested. If not found, returns ``None``. + """ + + # fast path, no space in name. + if ' ' not in name: + return self.all_commands.get(name) + + names = name.split() + if not names: + return None + obj = self.all_commands.get(names[0]) + if not isinstance(obj, GroupMixin): + return obj + + for name in names[1:]: + try: + obj = obj.all_commands[name] + except (AttributeError, KeyError): + return None + + return obj + + def command(self, *args, **kwargs): + """A shortcut decorator that invokes :func:`.command` and adds it to + the internal command list via :meth:`~.GroupMixin.add_command`. + + Returns + -------- + Callable[..., :class:`Command`] + A decorator that converts the provided method into a Command, adds it to the bot, then returns it. + """ + def decorator(func): + kwargs.setdefault('parent', self) + result = command(*args, **kwargs)(func) + self.add_command(result) + return result + + return decorator + + def group(self, *args, **kwargs): + """A shortcut decorator that invokes :func:`.group` and adds it to + the internal command list via :meth:`~.GroupMixin.add_command`. + + Returns + -------- + Callable[..., :class:`Group`] + A decorator that converts the provided method into a Group, adds it to the bot, then returns it. + """ + def decorator(func): + kwargs.setdefault('parent', self) + result = group(*args, **kwargs)(func) + self.add_command(result) + return result + + return decorator + +class Group(GroupMixin, Command): + """A class that implements a grouping protocol for commands to be + executed as subcommands. + + This class is a subclass of :class:`.Command` and thus all options + valid in :class:`.Command` are valid in here as well. + + Attributes + ----------- + invoke_without_command: :class:`bool` + Indicates if the group callback should begin parsing and + invocation only if no subcommand was found. Useful for + making it an error handling function to tell the user that + no subcommand was found or to have different functionality + in case no subcommand was found. If this is ``False``, then + the group callback will always be invoked first. This means + that the checks and the parsing dictated by its parameters + will be executed. Defaults to ``False``. + case_insensitive: :class:`bool` + Indicates if the group's commands should be case insensitive. + Defaults to ``False``. + """ + def __init__(self, *args, **attrs): + self.invoke_without_command = attrs.pop('invoke_without_command', False) + super().__init__(*args, **attrs) + + def copy(self): + """Creates a copy of this :class:`Group`. + + Returns + -------- + :class:`Group` + A new instance of this group. + """ + ret = super().copy() + for cmd in self.commands: + ret.add_command(cmd.copy()) + return ret + + async def invoke(self, ctx): + ctx.invoked_subcommand = None + ctx.subcommand_passed = None + early_invoke = not self.invoke_without_command + if early_invoke: + await self.prepare(ctx) + + view = ctx.view + previous = view.index + view.skip_ws() + trigger = view.get_word() + + if trigger: + ctx.subcommand_passed = trigger + ctx.invoked_subcommand = self.all_commands.get(trigger, None) + + if early_invoke: + injected = hooked_wrapped_callback(self, ctx, self.callback) + await injected(*ctx.args, **ctx.kwargs) + + ctx.invoked_parents.append(ctx.invoked_with) + + if trigger and ctx.invoked_subcommand: + ctx.invoked_with = trigger + await ctx.invoked_subcommand.invoke(ctx) + elif not early_invoke: + # undo the trigger parsing + view.index = previous + view.previous = previous + await super().invoke(ctx) + + async def reinvoke(self, ctx, *, call_hooks=False): + ctx.invoked_subcommand = None + early_invoke = not self.invoke_without_command + if early_invoke: + ctx.command = self + await self._parse_arguments(ctx) + + if call_hooks: + await self.call_before_hooks(ctx) + + view = ctx.view + previous = view.index + view.skip_ws() + trigger = view.get_word() + + if trigger: + ctx.subcommand_passed = trigger + ctx.invoked_subcommand = self.all_commands.get(trigger, None) + + if early_invoke: + try: + await self.callback(*ctx.args, **ctx.kwargs) + except: + ctx.command_failed = True + raise + finally: + if call_hooks: + await self.call_after_hooks(ctx) + + ctx.invoked_parents.append(ctx.invoked_with) + + if trigger and ctx.invoked_subcommand: + ctx.invoked_with = trigger + await ctx.invoked_subcommand.reinvoke(ctx, call_hooks=call_hooks) + elif not early_invoke: + # undo the trigger parsing + view.index = previous + view.previous = previous + await super().reinvoke(ctx, call_hooks=call_hooks) + +# Decorators + +def command(name=None, cls=None, **attrs): + """A decorator that transforms a function into a :class:`.Command` + or if called with :func:`.group`, :class:`.Group`. + + By default the ``help`` attribute is received automatically from the + docstring of the function and is cleaned up with the use of + ``inspect.cleandoc``. If the docstring is ``bytes``, then it is decoded + into :class:`str` using utf-8 encoding. + + All checks added using the :func:`.check` & co. decorators are added into + the function. There is no way to supply your own checks through this + decorator. + + Parameters + ----------- + name: :class:`str` + The name to create the command with. By default this uses the + function name unchanged. + cls + The class to construct with. By default this is :class:`.Command`. + You usually do not change this. + attrs + Keyword arguments to pass into the construction of the class denoted + by ``cls``. + + Raises + ------- + TypeError + If the function is not a coroutine or is already a command. + """ + if cls is None: + cls = Command + + def decorator(func): + if isinstance(func, Command): + raise TypeError('Callback is already a command.') + return cls(func, name=name, **attrs) + + return decorator + +def group(name=None, **attrs): + """A decorator that transforms a function into a :class:`.Group`. + + This is similar to the :func:`.command` decorator but the ``cls`` + parameter is set to :class:`Group` by default. + + .. versionchanged:: 1.1 + The ``cls`` parameter can now be passed. + """ + + attrs.setdefault('cls', Group) + return command(name=name, **attrs) + +def check(predicate): + r"""A decorator that adds a check to the :class:`.Command` or its + subclasses. These checks could be accessed via :attr:`.Command.checks`. + + These checks should be predicates that take in a single parameter taking + a :class:`.Context`. If the check returns a ``False``\-like value then + during invocation a :exc:`.CheckFailure` exception is raised and sent to + the :func:`.on_command_error` event. + + If an exception should be thrown in the predicate then it should be a + subclass of :exc:`.CommandError`. Any exception not subclassed from it + will be propagated while those subclassed will be sent to + :func:`.on_command_error`. + + A special attribute named ``predicate`` is bound to the value + returned by this decorator to retrieve the predicate passed to the + decorator. This allows the following introspection and chaining to be done: + + .. code-block:: python3 + + def owner_or_permissions(**perms): + original = commands.has_permissions(**perms).predicate + async def extended_check(ctx): + if ctx.guild is None: + return False + return ctx.guild.owner_id == ctx.author.id or await original(ctx) + return commands.check(extended_check) + + .. note:: + + The function returned by ``predicate`` is **always** a coroutine, + even if the original function was not a coroutine. + + .. versionchanged:: 1.3 + The ``predicate`` attribute was added. + + Examples + --------- + + Creating a basic check to see if the command invoker is you. + + .. code-block:: python3 + + def check_if_it_is_me(ctx): + return ctx.message.author.id == 85309593344815104 + + @bot.command() + @commands.check(check_if_it_is_me) + async def only_for_me(ctx): + await ctx.send('I know you!') + + Transforming common checks into its own decorator: + + .. code-block:: python3 + + def is_me(): + def predicate(ctx): + return ctx.message.author.id == 85309593344815104 + return commands.check(predicate) + + @bot.command() + @is_me() + async def only_me(ctx): + await ctx.send('Only you!') + + Parameters + ----------- + predicate: Callable[[:class:`Context`], :class:`bool`] + The predicate to check if the command should be invoked. + """ + + def decorator(func): + if isinstance(func, Command): + func.checks.append(predicate) + else: + if not hasattr(func, '__commands_checks__'): + func.__commands_checks__ = [] + + func.__commands_checks__.append(predicate) + + return func + + if inspect.iscoroutinefunction(predicate): + decorator.predicate = predicate + else: + @functools.wraps(predicate) + async def wrapper(ctx): + return predicate(ctx) + decorator.predicate = wrapper + + return decorator + +def check_any(*checks): + r"""A :func:`check` that is added that checks if any of the checks passed + will pass, i.e. using logical OR. + + If all checks fail then :exc:`.CheckAnyFailure` is raised to signal the failure. + It inherits from :exc:`.CheckFailure`. + + .. note:: + + The ``predicate`` attribute for this function **is** a coroutine. + + .. versionadded:: 1.3 + + Parameters + ------------ + \*checks: Callable[[:class:`Context`], :class:`bool`] + An argument list of checks that have been decorated with + the :func:`check` decorator. + + Raises + ------- + TypeError + A check passed has not been decorated with the :func:`check` + decorator. + + Examples + --------- + + Creating a basic check to see if it's the bot owner or + the server owner: + + .. code-block:: python3 + + def is_guild_owner(): + def predicate(ctx): + return ctx.guild is not None and ctx.guild.owner_id == ctx.author.id + return commands.check(predicate) + + @bot.command() + @commands.check_any(commands.is_owner(), is_guild_owner()) + async def only_for_owners(ctx): + await ctx.send('Hello mister owner!') + """ + + unwrapped = [] + for wrapped in checks: + try: + pred = wrapped.predicate + except AttributeError: + raise TypeError('%r must be wrapped by commands.check decorator' % wrapped) from None + else: + unwrapped.append(pred) + + async def predicate(ctx): + errors = [] + for func in unwrapped: + try: + value = await func(ctx) + except CheckFailure as e: + errors.append(e) + else: + if value: + return True + # if we're here, all checks failed + raise CheckAnyFailure(unwrapped, errors) + + return check(predicate) + +def has_role(item): + """A :func:`.check` that is added that checks if the member invoking the + command has the role specified via the name or ID specified. + + If a string is specified, you must give the exact name of the role, including + caps and spelling. + + If an integer is specified, you must give the exact snowflake ID of the role. + + If the message is invoked in a private message context then the check will + return ``False``. + + This check raises one of two special exceptions, :exc:`.MissingRole` if the user + is missing a role, or :exc:`.NoPrivateMessage` if it is used in a private message. + Both inherit from :exc:`.CheckFailure`. + + .. versionchanged:: 1.1 + + Raise :exc:`.MissingRole` or :exc:`.NoPrivateMessage` + instead of generic :exc:`.CheckFailure` + + Parameters + ----------- + item: Union[:class:`int`, :class:`str`] + The name or ID of the role to check. + """ + + def predicate(ctx): + if not isinstance(ctx.channel, discord.abc.GuildChannel): + raise NoPrivateMessage() + + if isinstance(item, int): + role = discord.utils.get(ctx.author.roles, id=item) + else: + role = discord.utils.get(ctx.author.roles, name=item) + if role is None: + raise MissingRole(item) + return True + + return check(predicate) + +def has_any_role(*items): + r"""A :func:`.check` that is added that checks if the member invoking the + command has **any** of the roles specified. This means that if they have + one out of the three roles specified, then this check will return `True`. + + Similar to :func:`.has_role`\, the names or IDs passed in must be exact. + + This check raises one of two special exceptions, :exc:`.MissingAnyRole` if the user + is missing all roles, or :exc:`.NoPrivateMessage` if it is used in a private message. + Both inherit from :exc:`.CheckFailure`. + + .. versionchanged:: 1.1 + + Raise :exc:`.MissingAnyRole` or :exc:`.NoPrivateMessage` + instead of generic :exc:`.CheckFailure` + + Parameters + ----------- + items: List[Union[:class:`str`, :class:`int`]] + An argument list of names or IDs to check that the member has roles wise. + + Example + -------- + + .. code-block:: python3 + + @bot.command() + @commands.has_any_role('Library Devs', 'Moderators', 492212595072434186) + async def cool(ctx): + await ctx.send('You are cool indeed') + """ + def predicate(ctx): + if not isinstance(ctx.channel, discord.abc.GuildChannel): + raise NoPrivateMessage() + + getter = functools.partial(discord.utils.get, ctx.author.roles) + if any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items): + return True + raise MissingAnyRole(items) + + return check(predicate) + +def bot_has_role(item): + """Similar to :func:`.has_role` except checks if the bot itself has the + role. + + This check raises one of two special exceptions, :exc:`.BotMissingRole` if the bot + is missing the role, or :exc:`.NoPrivateMessage` if it is used in a private message. + Both inherit from :exc:`.CheckFailure`. + + .. versionchanged:: 1.1 + + Raise :exc:`.BotMissingRole` or :exc:`.NoPrivateMessage` + instead of generic :exc:`.CheckFailure` + """ + + def predicate(ctx): + ch = ctx.channel + if not isinstance(ch, discord.abc.GuildChannel): + raise NoPrivateMessage() + + me = ch.guild.me + if isinstance(item, int): + role = discord.utils.get(me.roles, id=item) + else: + role = discord.utils.get(me.roles, name=item) + if role is None: + raise BotMissingRole(item) + return True + return check(predicate) + +def bot_has_any_role(*items): + """Similar to :func:`.has_any_role` except checks if the bot itself has + any of the roles listed. + + This check raises one of two special exceptions, :exc:`.BotMissingAnyRole` if the bot + is missing all roles, or :exc:`.NoPrivateMessage` if it is used in a private message. + Both inherit from :exc:`.CheckFailure`. + + .. versionchanged:: 1.1 + + Raise :exc:`.BotMissingAnyRole` or :exc:`.NoPrivateMessage` + instead of generic checkfailure + """ + def predicate(ctx): + ch = ctx.channel + if not isinstance(ch, discord.abc.GuildChannel): + raise NoPrivateMessage() + + me = ch.guild.me + getter = functools.partial(discord.utils.get, me.roles) + if any(getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items): + return True + raise BotMissingAnyRole(items) + return check(predicate) + +def has_permissions(**perms): + """A :func:`.check` that is added that checks if the member has all of + the permissions necessary. + + Note that this check operates on the current channel permissions, not the + guild wide permissions. + + The permissions passed in must be exactly like the properties shown under + :class:`.discord.Permissions`. + + This check raises a special exception, :exc:`.MissingPermissions` + that is inherited from :exc:`.CheckFailure`. + + Parameters + ------------ + perms + An argument list of permissions to check for. + + Example + --------- + + .. code-block:: python3 + + @bot.command() + @commands.has_permissions(manage_messages=True) + async def test(ctx): + await ctx.send('You can manage messages.') + + """ + + invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) + if invalid: + raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) + + def predicate(ctx): + ch = ctx.channel + permissions = ch.permissions_for(ctx.author) + + missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] + + if not missing: + return True + + raise MissingPermissions(missing) + + return check(predicate) + +def bot_has_permissions(**perms): + """Similar to :func:`.has_permissions` except checks if the bot itself has + the permissions listed. + + This check raises a special exception, :exc:`.BotMissingPermissions` + that is inherited from :exc:`.CheckFailure`. + """ + + invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) + if invalid: + raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) + + def predicate(ctx): + guild = ctx.guild + me = guild.me if guild is not None else ctx.bot.user + permissions = ctx.channel.permissions_for(me) + + missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] + + if not missing: + return True + + raise BotMissingPermissions(missing) + + return check(predicate) + +def has_guild_permissions(**perms): + """Similar to :func:`.has_permissions`, but operates on guild wide + permissions instead of the current channel permissions. + + If this check is called in a DM context, it will raise an + exception, :exc:`.NoPrivateMessage`. + + .. versionadded:: 1.3 + """ + + invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) + if invalid: + raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) + + def predicate(ctx): + if not ctx.guild: + raise NoPrivateMessage + + permissions = ctx.author.guild_permissions + missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] + + if not missing: + return True + + raise MissingPermissions(missing) + + return check(predicate) + +def bot_has_guild_permissions(**perms): + """Similar to :func:`.has_guild_permissions`, but checks the bot + members guild permissions. + + .. versionadded:: 1.3 + """ + + invalid = set(perms) - set(discord.Permissions.VALID_FLAGS) + if invalid: + raise TypeError('Invalid permission(s): %s' % (', '.join(invalid))) + + def predicate(ctx): + if not ctx.guild: + raise NoPrivateMessage + + permissions = ctx.me.guild_permissions + missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] + + if not missing: + return True + + raise BotMissingPermissions(missing) + + return check(predicate) + +def dm_only(): + """A :func:`.check` that indicates this command must only be used in a + DM context. Only private messages are allowed when + using the command. + + This check raises a special exception, :exc:`.PrivateMessageOnly` + that is inherited from :exc:`.CheckFailure`. + + .. versionadded:: 1.1 + """ + + def predicate(ctx): + if ctx.guild is not None: + raise PrivateMessageOnly() + return True + + return check(predicate) + +def guild_only(): + """A :func:`.check` that indicates this command must only be used in a + guild context only. Basically, no private messages are allowed when + using the command. + + This check raises a special exception, :exc:`.NoPrivateMessage` + that is inherited from :exc:`.CheckFailure`. + """ + + def predicate(ctx): + if ctx.guild is None: + raise NoPrivateMessage() + return True + + return check(predicate) + +def is_owner(): + """A :func:`.check` that checks if the person invoking this command is the + owner of the bot. + + This is powered by :meth:`.Bot.is_owner`. + + This check raises a special exception, :exc:`.NotOwner` that is derived + from :exc:`.CheckFailure`. + """ + + async def predicate(ctx): + if not await ctx.bot.is_owner(ctx.author): + raise NotOwner('You do not own this bot.') + return True + + return check(predicate) + +def is_nsfw(): + """A :func:`.check` that checks if the channel is a NSFW channel. + + This check raises a special exception, :exc:`.NSFWChannelRequired` + that is derived from :exc:`.CheckFailure`. + + .. versionchanged:: 1.1 + + Raise :exc:`.NSFWChannelRequired` instead of generic :exc:`.CheckFailure`. + DM channels will also now pass this check. + """ + def pred(ctx): + ch = ctx.channel + if ctx.guild is None or (isinstance(ch, discord.TextChannel) and ch.is_nsfw()): + return True + raise NSFWChannelRequired(ch) + return check(pred) + +def cooldown(rate, per, type=BucketType.default): + """A decorator that adds a cooldown to a :class:`.Command` + + A cooldown allows a command to only be used a specific amount + of times in a specific time frame. These cooldowns can be based + either on a per-guild, per-channel, per-user, per-role or global basis. + Denoted by the third argument of ``type`` which must be of enum + type :class:`.BucketType`. + + If a cooldown is triggered, then :exc:`.CommandOnCooldown` is triggered in + :func:`.on_command_error` and the local error handler. + + A command can only have a single cooldown. + + Parameters + ------------ + rate: :class:`int` + The number of times a command can be used before triggering a cooldown. + per: :class:`float` + The amount of seconds to wait for a cooldown when it's been triggered. + type: Union[:class:`.BucketType`, Callable[[:class:`.Message`], Any]] + The type of cooldown to have. If callable, should return a key for the mapping. + + .. versionchanged:: 1.7 + Callables are now supported for custom bucket types. + """ + + def decorator(func): + if isinstance(func, Command): + func._buckets = CooldownMapping(Cooldown(rate, per, type)) + else: + func.__commands_cooldown__ = Cooldown(rate, per, type) + return func + return decorator + +def max_concurrency(number, per=BucketType.default, *, wait=False): + """A decorator that adds a maximum concurrency to a :class:`.Command` or its subclasses. + + This enables you to only allow a certain number of command invocations at the same time, + for example if a command takes too long or if only one user can use it at a time. This + differs from a cooldown in that there is no set waiting period or token bucket -- only + a set number of people can run the command. + + .. versionadded:: 1.3 + + Parameters + ------------- + number: :class:`int` + The maximum number of invocations of this command that can be running at the same time. + per: :class:`.BucketType` + The bucket that this concurrency is based on, e.g. ``BucketType.guild`` would allow + it to be used up to ``number`` times per guild. + wait: :class:`bool` + Whether the command should wait for the queue to be over. If this is set to ``False`` + then instead of waiting until the command can run again, the command raises + :exc:`.MaxConcurrencyReached` to its error handler. If this is set to ``True`` + then the command waits until it can be executed. + """ + + def decorator(func): + value = MaxConcurrency(number, per=per, wait=wait) + if isinstance(func, Command): + func._max_concurrency = value + else: + func.__commands_max_concurrency__ = value + return func + return decorator + +def before_invoke(coro): + """A decorator that registers a coroutine as a pre-invoke hook. + + This allows you to refer to one before invoke hook for several commands that + do not have to be within the same cog. + + .. versionadded:: 1.4 + + Example + --------- + + .. code-block:: python3 + + async def record_usage(ctx): + print(ctx.author, 'used', ctx.command, 'at', ctx.message.created_at) + + @bot.command() + @commands.before_invoke(record_usage) + async def who(ctx): # Output: used who at