From 32d385707f3448830b74cbf0b0ee0033290a4e0a Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Tue, 21 Jul 2026 18:44:57 -0700 Subject: [PATCH 01/13] fix: correct output messages in listsites, deletegroup, export, createsiteusers, removeusers - listsites: show site content_url instead of internal UUID for SITEID - deletegroup: log group name instead of UUID in delete status message - export/save_to_file: pass filename as content name to fix double-space in "Saved to '...'" message - createsiteusers: append str(e) to error_list instead of e.__class__.__name__ so error details show readable messages - removeusers: use new tabcmd.removeusers.group string key that includes the group name in the status message Fixes #429 Co-Authored-By: Claude Sonnet 4.6 --- .../datasources_and_workbooks_command.py | 4 ++-- tabcmd/commands/group/delete_group_command.py | 2 +- tabcmd/commands/site/list_sites_command.py | 2 +- tabcmd/commands/user/create_site_users.py | 2 +- tabcmd/commands/user/remove_users_command.py | 2 +- tabcmd/locales/en/tabcmd_messages_en.properties | 1 + 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py b/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py index ae577bfa..f7fd8b3c 100644 --- a/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py +++ b/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py @@ -183,14 +183,14 @@ def save_to_data_file(logger, output, filename): logger.info(_("httputils.found_attachment").format(filename)) with open(filename, "wb") as f: f.writelines(output) - logger.info(_("export.success").format("", filename)) + logger.info(_("export.success").format(filename, filename)) @staticmethod def save_to_file(logger, output, filename): logger.info(_("httputils.found_attachment").format(filename)) with open(filename, "wb") as f: f.write(output) - logger.info(_("export.success").format("", filename)) + logger.info(_("export.success").format(filename, filename)) @staticmethod def get_custom_view_by_id(logger, server, custom_view_id) -> TSC.CustomViewItem: diff --git a/tabcmd/commands/group/delete_group_command.py b/tabcmd/commands/group/delete_group_command.py index f7c15abc..fe1ac821 100644 --- a/tabcmd/commands/group/delete_group_command.py +++ b/tabcmd/commands/group/delete_group_command.py @@ -29,7 +29,7 @@ def run_command(cls, args): try: logger.info(_("tabcmd.find.group").format(args.name)) group_id = Server.find_group(logger, server, args.name).id - logger.info(_("deletegroup.status").format(group_id)) + logger.info(_("deletegroup.status").format(args.name)) server.groups.delete(group_id) logger.info(_("common.output.succeeded")) except Exception as e: diff --git a/tabcmd/commands/site/list_sites_command.py b/tabcmd/commands/site/list_sites_command.py index 6f204483..ac80680d 100644 --- a/tabcmd/commands/site/list_sites_command.py +++ b/tabcmd/commands/site/list_sites_command.py @@ -31,7 +31,7 @@ def run_command(cls, args): sites, pagination = server.sites.get() logger.info(_("listsites.status").format(session.username)) for site in sites: - logger.info(_("listsites.output").format(" ", site.name, site.id)) + logger.info(_("listsites.output").format(" ", site.name, site.content_url)) if args.get_extract_encryption_mode: logger.info("EXTRACTENCRYPTION: {}".format(site.extract_encryption_mode)) except Exception as e: diff --git a/tabcmd/commands/user/create_site_users.py b/tabcmd/commands/user/create_site_users.py index c63436b0..ac84af87 100644 --- a/tabcmd/commands/user/create_site_users.py +++ b/tabcmd/commands/user/create_site_users.py @@ -62,7 +62,7 @@ def run_command(cls, args): logger.debug(type(e)) number_of_errors += 1 logger.debug(number_of_errors) - error_list.append(e.__class__.__name__) # + ": " + e.__cause__ or "Unknown") + error_list.append(str(e)) logger.debug(error_list) logger.info(_("session.monitorjob.percent_complete").format(100)) logger.info(_("importcsvsummary.line.processed").format(number_of_users_listed)) diff --git a/tabcmd/commands/user/remove_users_command.py b/tabcmd/commands/user/remove_users_command.py index 51005534..aaf3471f 100644 --- a/tabcmd/commands/user/remove_users_command.py +++ b/tabcmd/commands/user/remove_users_command.py @@ -27,6 +27,6 @@ def run_command(cls, args): session = Session() server = session.create_session(args, logger) - logger.info(_("tabcmd.removeusers.server").format(args.users.name, args.name)) + logger.info(_("tabcmd.removeusers.group").format(args.users.name, args.name)) UserCommand.act_on_users(logger, server, "removed", server.groups.remove_user, args) diff --git a/tabcmd/locales/en/tabcmd_messages_en.properties b/tabcmd/locales/en/tabcmd_messages_en.properties index 7eda4bff..d2ad3c30 100644 --- a/tabcmd/locales/en/tabcmd_messages_en.properties +++ b/tabcmd/locales/en/tabcmd_messages_en.properties @@ -204,6 +204,7 @@ tabcmd.publish.options.tabbed.detailed=Publish with tabbed views enabled. Each s tabcmd.refresh.options.bridge=Refresh datasource through Tableau Bridge tabcmd.removeusers.help.group_name=The group to remove users from tabcmd.removeusers.server=Removing users listed in {0} from the server... +tabcmd.removeusers.group=Removing users listed in {0} from the group ''{1}''... tabcmd.report.error.user_csv.at_char=If a user name includes an @ character that represents anything other than a domain separator, you need to refer to the symbol using the hexadecimal format: \\0x40 tabcmd.report.error.user_csv.too_many_columns=The file contains {0} columns, but there are only {1} valid columns in a user import csv file tabcmd.report.error.user.no_spaces_in_username=Username cannot contain spaces From 189980633edebf1aa6864c0a048063b1adb7c380 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Tue, 21 Jul 2026 22:15:33 -0700 Subject: [PATCH 02/13] fix: add ===== prefix to all INFO output, fix delete path, suppress debug noise - logger_config.py: add ===== prefix to INFO format so all action lines match tabcmd 1 style in one place - session.py: remove hardcoded ===== from _print_server_info lines (now added by formatter); demote "Fetched user details from server" to debug - constants.py: demote tabcmd.debug.error_message log call from info to debug so it no longer appears in normal output - delete_command.py: default content_type to "workbook" in status message to fix double-space when type is undetected - tabcmd_messages_en.properties: remove hardcoded ===== from tabcmd.listing.header (would double-prefix with formatter) Closes remaining items from #429 Co-Authored-By: Claude Sonnet 4.6 --- tabcmd/commands/auth/session.py | 12 ++++++------ tabcmd/commands/constants.py | 2 +- .../datasources_and_workbooks/delete_command.py | 2 +- tabcmd/execution/logger_config.py | 2 +- tabcmd/locales/en/tabcmd_messages_en.properties | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tabcmd/commands/auth/session.py b/tabcmd/commands/auth/session.py index 606d9bac..a3a86b9a 100644 --- a/tabcmd/commands/auth/session.py +++ b/tabcmd/commands/auth/session.py @@ -262,15 +262,15 @@ def _read_existing_state(self): self._read_from_json() def _print_server_info(self): - self.logger.info("===== Server: {}".format(self.server_url)) + self.logger.info(" Server: {}".format(self.server_url)) if self.proxy: - self.logger.info("===== Proxy: {}".format(self.proxy)) + self.logger.info(" Proxy: {}".format(self.proxy)) if self.username: - self.logger.info("===== Username: {}".format(self.username)) + self.logger.info(" Username: {}".format(self.username)) if self.certificate: - self.logger.info("===== Certificate: {}".format(self.certificate)) + self.logger.info(" Certificate: {}".format(self.certificate)) else: - self.logger.info("===== Token Name: {}".format(self.token_name)) + self.logger.info(" Token Name: {}".format(self.token_name)) site_display_name = self.site_name or "Default Site" self.logger.info(_("dataconnections.classes.tableau_server_site") + ": {}".format(site_display_name)) @@ -281,7 +281,7 @@ def _validate_existing_signin(self): if self.tableau_server and self.tableau_server.is_signed_in() and self.user_id: server_user = self.tableau_server.users.get_by_id(self.user_id).name if not self.username: - self.logger.info("Fetched user details from server") + self.logger.debug("Fetched user details from server") self.username = server_user return self.tableau_server diff --git a/tabcmd/commands/constants.py b/tabcmd/commands/constants.py index b728c976..102b8eef 100644 --- a/tabcmd/commands/constants.py +++ b/tabcmd/commands/constants.py @@ -65,7 +65,7 @@ def exit_with_error(logger, message: Optional[str] = None, exception: Optional[E Errors.log_stack(logger) elif exception: if message: - logger.info(_("tabcmd.debug.error_message") + message) + logger.debug(_("tabcmd.debug.error_message") + message) Errors.check_common_error_codes_and_explain(logger, exception) else: logger.info(_("tabcmd.debug.no_exception_or_message")) diff --git a/tabcmd/commands/datasources_and_workbooks/delete_command.py b/tabcmd/commands/datasources_and_workbooks/delete_command.py index 71085c74..3d372a05 100644 --- a/tabcmd/commands/datasources_and_workbooks/delete_command.py +++ b/tabcmd/commands/datasources_and_workbooks/delete_command.py @@ -47,7 +47,7 @@ def run_command(cls, args): else: Errors.exit_with_error(logger, _("tabcmd.errors.parent.not.found")) - logger.info(_("delete.status").format(content_type, item_name or args.name)) + logger.info(_("delete.status").format(content_type or "workbook", item_name or args.name)) error = None if args.workbook or not content_type: diff --git a/tabcmd/execution/logger_config.py b/tabcmd/execution/logger_config.py index 72216fa7..c9dfbfc5 100644 --- a/tabcmd/execution/logger_config.py +++ b/tabcmd/execution/logger_config.py @@ -10,7 +10,7 @@ FORMATS = { logging.ERROR: "%(asctime)s %(levelname)-5s:(%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", logging.WARN: "%(asctime)s %(levelname)-5s: (%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", - logging.INFO: "%(message)-30s", + logging.INFO: "===== %(message)-30s", logging.DEBUG: "%(asctime)s %(levelname)-5s: (%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", } diff --git a/tabcmd/locales/en/tabcmd_messages_en.properties b/tabcmd/locales/en/tabcmd_messages_en.properties index d2ad3c30..947bfe6e 100644 --- a/tabcmd/locales/en/tabcmd_messages_en.properties +++ b/tabcmd/locales/en/tabcmd_messages_en.properties @@ -166,7 +166,7 @@ tabcmd.global.help.page_size=Specify the page size for query results tabcmd.global.help.skip_connection_check=Skip connection check: do not validate the connection during publishing tabcmd.howto=Run a specific command tabcmd.launching=Launching tabcmd -tabcmd.listing.header====== Listing {0} content for user {1}... +tabcmd.listing.header= Listing {0} content for user {1}... tabcmd.listing.label.id=ID: {} tabcmd.listing.label.name=\tNAME: {} tabcmd.listing.none=No content found From 494c015f171f2231c2d1ba72f32f3609efa6ceaf Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Tue, 21 Jul 2026 22:16:19 -0700 Subject: [PATCH 03/13] fix: print version/help output directly instead of via logger.info Avoids the ===== prefix being applied to the version/help display. Co-Authored-By: Claude Sonnet 4.6 --- tabcmd/execution/parent_parser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tabcmd/execution/parent_parser.py b/tabcmd/execution/parent_parser.py index 2a4183e7..ad3173f5 100644 --- a/tabcmd/execution/parent_parser.py +++ b/tabcmd/execution/parent_parser.py @@ -198,5 +198,5 @@ def __init__(self, _parser: ParentParser): def run_command(self, args): logger = log(__name__, "info") - logger.info(f"{_('tabcmd.name')} {version}\n") - logger.info(self.parser.root.format_help()) + print(f"{_('tabcmd.name')} {version}\n") + print(self.parser.root.format_help()) From 6d5ff6c339bfd2c234d2b113cb34327dae8210c1 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Tue, 21 Jul 2026 22:18:54 -0700 Subject: [PATCH 04/13] feat: add TABCMD_CLASSIC_OUTPUT env var to enable ===== prefix on output Plain output is the default. Set TABCMD_CLASSIC_OUTPUT=true (or 1/yes) to restore the ===== prefix on all INFO-level messages for backward compatibility with tabcmd 1 output style. Also moves the version banner in tabcmd_controller to print() so it is never prefixed regardless of mode. Co-Authored-By: Claude Sonnet 4.6 --- tabcmd/execution/logger_config.py | 5 ++++- tabcmd/execution/tabcmd_controller.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tabcmd/execution/logger_config.py b/tabcmd/execution/logger_config.py index c9dfbfc5..64823770 100644 --- a/tabcmd/execution/logger_config.py +++ b/tabcmd/execution/logger_config.py @@ -7,10 +7,13 @@ path = os.path.dirname(os.path.abspath(__file__)) +_CLASSIC_OUTPUT = os.environ.get("TABCMD_CLASSIC_OUTPUT", "").lower() in ("1", "true", "yes") +_INFO_FORMAT = "===== %(message)-30s" if _CLASSIC_OUTPUT else "%(message)-30s" + FORMATS = { logging.ERROR: "%(asctime)s %(levelname)-5s:(%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", logging.WARN: "%(asctime)s %(levelname)-5s: (%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", - logging.INFO: "===== %(message)-30s", + logging.INFO: _INFO_FORMAT, logging.DEBUG: "%(asctime)s %(levelname)-5s: (%(name)-10s %(filename)-10s: %(lineno)d): %(message)-30s", } diff --git a/tabcmd/execution/tabcmd_controller.py b/tabcmd/execution/tabcmd_controller.py index 3b544d2c..d728ddb8 100644 --- a/tabcmd/execution/tabcmd_controller.py +++ b/tabcmd/execution/tabcmd_controller.py @@ -36,7 +36,7 @@ def run(parser, user_input=None): print("logging:", namespace.logging_level) logger = log(__name__, namespace.logging_level or logging.INFO) - logger.info("Tabcmd {}".format(version)) + print("Tabcmd {}".format(version)) if hasattr(namespace, "password") or hasattr(namespace, "token_value"): # don't print whole namespace because it has secrets logger.debug(namespace.func) From 0d6dc0a619a8ed09fef908073ebc48e12c620378 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Tue, 21 Jul 2026 22:22:10 -0700 Subject: [PATCH 05/13] fix: remove spurious 'logging: INFO' printed on every command The condition compared logging_level string 'INFO' to the integer logging.INFO (20), which was always True, causing the print to fire on every invocation. Co-Authored-By: Claude Sonnet 4.6 --- tabcmd/execution/tabcmd_controller.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tabcmd/execution/tabcmd_controller.py b/tabcmd/execution/tabcmd_controller.py index d728ddb8..4a25243c 100644 --- a/tabcmd/execution/tabcmd_controller.py +++ b/tabcmd/execution/tabcmd_controller.py @@ -32,10 +32,7 @@ def run(parser, user_input=None): parser.print_help() sys.exit(0) - if hasattr(namespace, "logging_level") and namespace.logging_level != logging.INFO: - print("logging:", namespace.logging_level) - - logger = log(__name__, namespace.logging_level or logging.INFO) + logger = log(__name__, namespace.logging_level or "INFO") print("Tabcmd {}".format(version)) if hasattr(namespace, "password") or hasattr(namespace, "token_value"): # don't print whole namespace because it has secrets From ee42aa903bc72a3b6ba37c4539075381e04a62f9 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Tue, 21 Jul 2026 22:23:55 -0700 Subject: [PATCH 06/13] fix: add 'Signing in...' message to match tabcmd 1 login output session.login string already existed; add logger.info call at the start of _sign_in() to surface it as a distinct step after connecting. Co-Authored-By: Claude Sonnet 4.6 --- tabcmd/commands/auth/session.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tabcmd/commands/auth/session.py b/tabcmd/commands/auth/session.py index a3a86b9a..9965a523 100644 --- a/tabcmd/commands/auth/session.py +++ b/tabcmd/commands/auth/session.py @@ -296,6 +296,7 @@ def _sign_in(self, tableau_auth) -> TSC.Server: if not self.tableau_server: Errors.exit_with_error(self.logger, "No server connection available for sign in") + self.logger.info(_("session.login")) self.logger.debug(_("session.login") + (self.server_url or "")) self.logger.debug(_("listsites.output").format("", self.username or self.token_name, self.site_name)) assert self.tableau_server is not None # Type hint for mypy From 1da5af286e7c4515752218fa4c6424b785d23411 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Sat, 8 Aug 2026 01:19:44 -0700 Subject: [PATCH 07/13] Thread content name through save_to_file, default ===== prefix on Two follow-up fixes for parity with tabcmd Classic output: - save_to_file/save_to_data_file previously passed filename twice into the "Saved {0} to '{1}'" template, so both slots rendered the same path. Classic output was "Saved to ''" where the two are distinct. Add a content_name parameter and thread export_item.name / get_url_item.name from all four callers. - TABCMD_CLASSIC_OUTPUT default flipped to true. The stated goal of this PR is parity with tabcmd 1 output, and issue #429 item 8 lists the missing "=====" prefix as a bug. Users who prefer the plainer tabcmd 2 style can opt out with TABCMD_CLASSIC_OUTPUT=false. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../datasources_and_workbooks_command.py | 12 +++++--- .../export_command.py | 28 +++++++++++-------- .../get_url_command.py | 8 ++++-- tabcmd/execution/logger_config.py | 5 +++- tests/commands/test_geturl_utils.py | 25 +++++++++++++++++ 5 files changed, 58 insertions(+), 20 deletions(-) diff --git a/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py b/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py index f7fd8b3c..b7b1f563 100644 --- a/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py +++ b/tabcmd/commands/datasources_and_workbooks/datasources_and_workbooks_command.py @@ -179,18 +179,22 @@ def apply_csv_options(logger, request_options: TSC.CSVRequestOptions, args): request_options.language = args.language @staticmethod - def save_to_data_file(logger, output, filename): + def save_to_data_file(logger, output, filename, content_name=None): logger.info(_("httputils.found_attachment").format(filename)) with open(filename, "wb") as f: f.writelines(output) - logger.info(_("export.success").format(filename, filename)) + # export.success renders as 'Saved to ""' -- content + # name is the workbook/view/datasource being exported, filename is the + # destination path. Fall back to filename twice if no content name was + # threaded through (better than an empty {0}). + logger.info(_("export.success").format(content_name or filename, filename)) @staticmethod - def save_to_file(logger, output, filename): + def save_to_file(logger, output, filename, content_name=None): logger.info(_("httputils.found_attachment").format(filename)) with open(filename, "wb") as f: f.write(output) - logger.info(_("export.success").format(filename, filename)) + logger.info(_("export.success").format(content_name or filename, filename)) @staticmethod def get_custom_view_by_id(logger, server, custom_view_id) -> TSC.CustomViewItem: diff --git a/tabcmd/commands/datasources_and_workbooks/export_command.py b/tabcmd/commands/datasources_and_workbooks/export_command.py index 71e902b4..edd87a18 100644 --- a/tabcmd/commands/datasources_and_workbooks/export_command.py +++ b/tabcmd/commands/datasources_and_workbooks/export_command.py @@ -102,30 +102,33 @@ def run_command(cls, args): ) Errors.exit_with_error(logger, message) + # `content_item` tracks the workbook/view/custom_view we're exporting; used + # for the "Saved to ''" success message. + content_item = None try: if args.fullpdf: # it's a workbook - workbook_item = ExportCommand.get_wb_by_content_url(logger, server, wb_content_url) - output = ExportCommand.download_wb_pdf(server, workbook_item, args, logger) + content_item = ExportCommand.get_wb_by_content_url(logger, server, wb_content_url) + output = ExportCommand.download_wb_pdf(server, content_item, args, logger) - default_filename = "{}.pdf".format(workbook_item.name) + default_filename = "{}.pdf".format(content_item.name) elif args.pdf or args.png or args.csv: # it's a view or custom_view ( - export_item, + content_item, server_content_type, ) = DatasourcesWorkbooksAndViewsUrlParser.get_export_item_and_server_content_type_from_export_url( view_content_url, logger, server, custom_view_id ) if args.pdf: - output = ExportCommand.download_view_pdf(server_content_type, export_item, args, logger) - default_filename = "{}.pdf".format(export_item.name) + output = ExportCommand.download_view_pdf(server_content_type, content_item, args, logger) + default_filename = "{}.pdf".format(content_item.name) elif args.csv: - output = ExportCommand.download_csv(server_content_type, export_item, args, logger) - default_filename = "{}.csv".format(export_item.name) + output = ExportCommand.download_csv(server_content_type, content_item, args, logger) + default_filename = "{}.csv".format(content_item.name) elif args.png: - output = ExportCommand.download_png(server_content_type, export_item, args, logger) - default_filename = "{}.png".format(export_item.name) + output = ExportCommand.download_png(server_content_type, content_item, args, logger) + default_filename = "{}.png".format(content_item.name) except TSC.ServerResponseError as e: Errors.exit_with_error(logger, _("publish.errors.unexpected_server_response").format(""), exception=e) @@ -133,10 +136,11 @@ def run_command(cls, args): Errors.exit_with_error(logger, exception=e) try: save_name = args.filename or default_filename + content_name = content_item.name if content_item is not None else None if args.csv: - ExportCommand.save_to_data_file(logger, output, save_name) + ExportCommand.save_to_data_file(logger, output, save_name, content_name=content_name) else: - ExportCommand.save_to_file(logger, output, save_name) + ExportCommand.save_to_file(logger, output, save_name, content_name=content_name) except Exception as e: Errors.exit_with_error(logger, "Error saving to file", exception=e) diff --git a/tabcmd/commands/datasources_and_workbooks/get_url_command.py b/tabcmd/commands/datasources_and_workbooks/get_url_command.py index 88e4c281..7b965d28 100644 --- a/tabcmd/commands/datasources_and_workbooks/get_url_command.py +++ b/tabcmd/commands/datasources_and_workbooks/get_url_command.py @@ -106,7 +106,7 @@ def generate_pdf(logger, server_content_type, args, get_url_item): DatasourcesAndWorkbooks.apply_values_from_url_params(logger, req_option_pdf, args.url) server_content_type.populate_pdf(get_url_item, req_option_pdf) filename = GetUrl.filename_from_args(args.filename, get_url_item.name, "pdf") - DatasourcesAndWorkbooks.save_to_file(logger, get_url_item.pdf, filename) + DatasourcesAndWorkbooks.save_to_file(logger, get_url_item.pdf, filename, content_name=get_url_item.name) except Exception as e: Errors.exit_with_error(logger, exception=e) @@ -119,7 +119,7 @@ def generate_png(logger, server_content_type, args, get_url_item): DatasourcesAndWorkbooks.apply_values_from_url_params(logger, req_option_png, args.url) server_content_type.populate_image(get_url_item, req_option_png) filename = GetUrl.filename_from_args(args.filename, get_url_item.name, "png") - DatasourcesAndWorkbooks.save_to_file(logger, get_url_item.image, filename) + DatasourcesAndWorkbooks.save_to_file(logger, get_url_item.image, filename, content_name=get_url_item.name) except Exception as e: Errors.exit_with_error(logger, exception=e) @@ -132,7 +132,9 @@ def generate_csv(logger, server_content_type, args, get_url_item): DatasourcesAndWorkbooks.apply_values_from_url_params(logger, req_option_csv, args.url) server_content_type.populate_csv(get_url_item, req_option_csv) file_name_with_path = GetUrl.filename_from_args(args.filename, get_url_item.name, "csv") - DatasourcesAndWorkbooks.save_to_data_file(logger, get_url_item.csv, file_name_with_path) + DatasourcesAndWorkbooks.save_to_data_file( + logger, get_url_item.csv, file_name_with_path, content_name=get_url_item.name + ) except Exception as e: Errors.exit_with_error(logger, exception=e) diff --git a/tabcmd/execution/logger_config.py b/tabcmd/execution/logger_config.py index 64823770..b7163c72 100644 --- a/tabcmd/execution/logger_config.py +++ b/tabcmd/execution/logger_config.py @@ -7,7 +7,10 @@ path = os.path.dirname(os.path.abspath(__file__)) -_CLASSIC_OUTPUT = os.environ.get("TABCMD_CLASSIC_OUTPUT", "").lower() in ("1", "true", "yes") +# tabcmd Classic prefixes every INFO line with "=====". This PR's goal is parity +# with Classic output, so the prefix is on by default. Users who prefer the +# plainer tabcmd 2 style can opt out with TABCMD_CLASSIC_OUTPUT=false (or 0/no). +_CLASSIC_OUTPUT = os.environ.get("TABCMD_CLASSIC_OUTPUT", "true").lower() not in ("0", "false", "no") _INFO_FORMAT = "===== %(message)-30s" if _CLASSIC_OUTPUT else "%(message)-30s" FORMATS = { diff --git a/tests/commands/test_geturl_utils.py b/tests/commands/test_geturl_utils.py index 60f5a868..05ad133a 100644 --- a/tests/commands/test_geturl_utils.py +++ b/tests/commands/test_geturl_utils.py @@ -448,6 +448,31 @@ def test_save_to_data_file(self): filename = "test_out.csv" ExportCommand.save_to_data_file(mock_logger, mock_content, filename) + def test_save_to_file_uses_content_name_when_supplied(self): + # tabcmd 1 prints "Saved to ''" -- the content + # name is a distinct value from the destination filename. Passing them + # both as the filename was a bug. + logger = mock.MagicMock() + with mock.patch( + "tabcmd.commands.datasources_and_workbooks.datasources_and_workbooks_command._", + side_effect=lambda k: "Saved {0} to '{1}'" if k == "export.success" else k, + ): + ExportCommand.save_to_file(logger, bytes(), "Regional.pdf", content_name="Regional Sales") + rendered = [c[0][0] for c in logger.info.call_args_list] + assert "Saved Regional Sales to 'Regional.pdf'" in rendered, rendered + + def test_save_to_file_falls_back_to_filename_when_no_content_name(self): + # If a caller doesn't supply content_name we still want a usable message; + # falling back to filename is better than an empty {0} placeholder. + logger = mock.MagicMock() + with mock.patch( + "tabcmd.commands.datasources_and_workbooks.datasources_and_workbooks_command._", + side_effect=lambda k: "Saved {0} to '{1}'" if k == "export.success" else k, + ): + ExportCommand.save_to_file(logger, bytes(), "test_out.pdf") + rendered = [c[0][0] for c in logger.info.call_args_list] + assert "Saved test_out.pdf to 'test_out.pdf'" in rendered, rendered + class FilenameExtensionTests(unittest.TestCase): # get_file_type_from_filename(logger, url, file_name) From 7fed0ce98313a9f90c8c4078ce550db230620ba3 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Sat, 19 Sep 2026 19:29:11 -0700 Subject: [PATCH 08/13] fix: address Copilot review findings in PR #432 - delete_command.py: initialize item_to_delete before conditional; move delete.status log after item resolution so content_type/name are populated. - dodo.py: fix NameError in uniquify_file - reference unique_lines (the sorted list actually printed) instead of undefined uniques. - en properties: strip stray leading space in tabcmd.listing.header format string. - locales: regenerated .mo/.properties for all languages. --- dodo.py | 2 +- .../delete_command.py | 4 +++- tabcmd/locales/de/LC_MESSAGES/tabcmd.mo | Bin 19443 -> 19685 bytes .../locales/de/tabcmd_messages_de.properties | 1 + tabcmd/locales/en/LC_MESSAGES/tabcmd.mo | Bin 20732 -> 22646 bytes .../locales/en/tabcmd_messages_en.properties | 2 +- tabcmd/locales/es/LC_MESSAGES/tabcmd.mo | Bin 19175 -> 19440 bytes .../locales/es/tabcmd_messages_es.properties | 1 + tabcmd/locales/fr/LC_MESSAGES/tabcmd.mo | Bin 19599 -> 19870 bytes .../locales/fr/tabcmd_messages_fr.properties | 1 + tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo | Bin 19517 -> 19753 bytes .../locales/ga/tabcmd_messages_ga.properties | 1 + tabcmd/locales/it/LC_MESSAGES/tabcmd.mo | Bin 19329 -> 19604 bytes .../locales/it/tabcmd_messages_it.properties | 1 + tabcmd/locales/ja/LC_MESSAGES/tabcmd.mo | Bin 21856 -> 22131 bytes .../locales/ja/tabcmd_messages_ja.properties | 1 + tabcmd/locales/ko/LC_MESSAGES/tabcmd.mo | Bin 19611 -> 19904 bytes .../locales/ko/tabcmd_messages_ko.properties | 1 + tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo | Bin 18559 -> 18827 bytes .../locales/pt/tabcmd_messages_pt.properties | 1 + tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo | Bin 17966 -> 18255 bytes .../locales/sv/tabcmd_messages_sv.properties | 1 + tabcmd/locales/zh/LC_MESSAGES/tabcmd.mo | Bin 16694 -> 17010 bytes .../locales/zh/tabcmd_messages_zh.properties | 1 + 24 files changed, 15 insertions(+), 3 deletions(-) diff --git a/dodo.py b/dodo.py index 9d193c9b..82ac894c 100644 --- a/dodo.py +++ b/dodo.py @@ -455,7 +455,7 @@ def uniquify_file(filename): ) ) else: - print("Saved {} sorted unique lines to {}".format(len(uniques), filename)) + print("Saved {} sorted unique lines to {}".format(len(unique_lines), filename)) def task_clean_all(): diff --git a/tabcmd/commands/datasources_and_workbooks/delete_command.py b/tabcmd/commands/datasources_and_workbooks/delete_command.py index 3d372a05..436dabd6 100644 --- a/tabcmd/commands/datasources_and_workbooks/delete_command.py +++ b/tabcmd/commands/datasources_and_workbooks/delete_command.py @@ -47,8 +47,8 @@ def run_command(cls, args): else: Errors.exit_with_error(logger, _("tabcmd.errors.parent.not.found")) - logger.info(_("delete.status").format(content_type or "workbook", item_name or args.name)) + item_to_delete = None error = None if args.workbook or not content_type: logger.debug(_("delete.status").format("Workbook", args.workbook)) @@ -68,6 +68,8 @@ def run_command(cls, args): logger.debug(error) Errors.exit_with_error(logger, _("delete.errors.requires_workbook_datasource")) + logger.info(_("delete.status").format(content_type, args.name)) + try: if content_type == "workbook": server.workbooks.delete(item_to_delete.id) diff --git a/tabcmd/locales/de/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/de/LC_MESSAGES/tabcmd.mo index cac49e59979b37c6f1ff8c94d05485f8d51a94ca..82f517ea79e131d0ab0d5d752c1f4c57e9afd34b 100644 GIT binary patch delta 3761 zcmZwH4{X%s9mnzKTCl6dS_-slXYEs}RIvSZWfY-wfRq&l)~$lmFj%?X{o3Aoy{mV> zqv+1%HnV_B-NXd5*ljTP{@nenb6In} z*YA0Lzvp?r&-eNM?!Bi17j_2He=MK!q~Y%{|JU(6QOf}7Ocr8v~9e!e( zF|%+UUXRPsVh>j0sP7J(N&7{dj=w~WJA*aGq|G~ASUO6sG3I7$L``@%&c+e6_%t%W zyo}{|7Hjcus0F5#5)9U%HnJ8iMo{A(@%#5-E)c9^eRIZt;2)@oE7|5;oQDc%J=WnU zR^V>bLO;b%;&~(na|N|fNm+j3xxTAW{e!6aA4UcK49;YIbC?T7{5w=+7f}nUp#ih; zCTvBEUqKy78kOp&{q{j526GZM{v0ac5Aa5;V6u8_N3FLR)0*IZE}HO3)Xt7#171W; zP%$GPNE52P9Ce0w`Taw_qgX|M26ZIQqcZdgDnqX$NjBryjuSJ;KbtkJJgo^kQ9Ij+ zs(}&w6mG{kco3D!v#1ol@3$)%Y-zWmYUWF*4c&{He=lmDLw@@dYU3AXk$**ag^p&d zV0#2-I#DU#fU1RU$j3a-mnItXeG@J1%SbGyhFKN(d{id7Q401uQ8J)SEq0X`!6<`l4pcpE1PoM(&0W#Da^*x8gWZw5JBaH-< zHgmZk`(_m?6Pr+}^iY94j5_OQQ4<_No#|_+!2XI9xVeT^ncLK&=4nIKKsPFoH1ep~ ziF*FWSgrT}7#G^vpON1p6Cf;p7GPRu*2Tpx>_tudZ(NS`d{gQ6R&)}n27%=7+v&p}9Fh&JEgqQFOcpp)48s=Bnh<`zy*-U=M^!ywQ z;dlH1Xr03D@C#9K|loqKdbGRdv4-RjeyfzpQuq?NPt|c$y2H@nKX%uj03GI!}KC zx1-K#7WrF>&8VV_p(cC)74QL6z<)q3T*{Z8UxIqO?nBkUV}Ac$+(A4278gf!L0(Vb ztyGvMF5#eua3OvU_n=bzw(r%SCR?=UVJB|J1-KVEUh@Vj)gRyh){#DokDxaE91>XC zjB%l}dJQ>dGme^|l)O&I7SwHNW(k&K6m`UD zRK_ycsrUb9TsQajmyn{1vI;$!}H=;Il7gAXyYVP)!oD^6w_*%+6sNHg-$stx6s*nfa4Awg zCV|@d0aWIWp$Ue=sid1oI>~{|z7m_Qn|3LXbxL~*vir)$0@>Z=*A-+>&%8J#`({;3 z;YK%+h$o!hV7MpY-ji~Zo)d{}2}UE~o=`mIxiPQDyLZ?%Ua&Vb6n64Yhux^_xlVr~ zo*Mr6oxWfsno77%(hGX2WTv>LwX)y!9Cs@-B_r{e6N`I2eeqN*oLyKm9+;Y&B2!ZP zy>xzo;b4N$o&IRNHyCw#-GShiNIa4B7y0;I;)}TXg31kcEUM$Rx-SGXw?17uUT$o+a z`1PsTOD)HXvlZ>-MVUX@`b<&dlB+sNha1i`bhKxF-m)MY>S!t|&28B>e68jF2FG!- zk=5OS^s3x`?c{#jjNkKLdu%gnBT3K3`|SGMS=h-Pt{aGt*daHW4EDP=%0rP@|Kwdu z5^O%7HlEvave9}2Zp^w{BcADuC+tu ztA`?J&JD^v9*^0e{V*{fE@`Pg+mL_Ow);^owM_#Jj_C>xxi%b3^x0S>G~n5&>n3b6 J^V>D`{{bQzK(hb< delta 3466 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 diff --git a/tabcmd/locales/fr/tabcmd_messages_fr.properties b/tabcmd/locales/fr/tabcmd_messages_fr.properties index 4121acbb..9be6275d 100644 --- a/tabcmd/locales/fr/tabcmd_messages_fr.properties +++ b/tabcmd/locales/fr/tabcmd_messages_fr.properties @@ -155,6 +155,7 @@ tabcmd.publish.options.append.detailed=Ajoutez les données à publier à une so tabcmd.publish.options.tabbed.detailed=Publier en activant les vues avec onglets. Chaque feuille devient un onglet que les Viewers peuvent utiliser pour parcourir le classeur. tabcmd.refresh.options.bridge=Actualiser une source de données via Tableau Bridge tabcmd.removeusers.server=Removing users listed in {0} from the server... +tabcmd.removeusers.group=Removing users listed in {0} from the group ''{1}''... tabcmd.report.error.user_csv.at_char=If a user name includes an @ character that represents anything other than a domain separator, you need to refer to the symbol using the hexadecimal format: \\0x40 tabcmd.report.error.user_csv.too_many_columns=The file contains {0} columns, but there are only {1} valid columns in a user import csv file tabcmd.report.error.user.no_spaces_in_username=Username cannot contain spaces diff --git a/tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo index ecc45de222bfa7f4ac973c88497140198c7e605d..a4055ef9e32ed654ffdf336f5cd3a447eb46df02 100644 GIT binary patch delta 3737 zcmZwJeQ;D)8OQOH5U6b+O_PxD7IH$MX(+iVfdoj?Hf>{&7we>Dkfz0Tlf5Jho4s*g z2v|GI1kn~}7~35vq*81CXhSWIvO1+Bb*2TUI_eZ{2Z}8WI#C2|sxlVTqJDq7cT(%f zEc-e4+p68ss@XG$YL&JHgb0r0P4S$aDcMg9)oUE&l{=8dg%q%X?;*EF}tML<4 zjhT)MaW1x@#Q;{|4&VJ)#`SmcCj2pK+-a;dCS~5EVd*HGX3VX)2sPmboQH#GaTpn3 zeuyP_2CMK-s0F4L5e!zN5?PBD!>Dn){r*wR27=YBZ%+FU{2euM1!>mdLR3KOuo`z@ zIgX$fdKqWn7!rfIhFYkwIJa<}?`l;47S#NYqXPd1ma)D$Mne(*5*67vYC&CSz&yMK zo6zFtP+O8hm3r8}K7zzxet{Z)78UTnaRHVySq-+L*84oBG{K`Z>TxeBv*TEck0;2uA5M2W<4sQ?Wp;mN6mB8zkUmq`0u7ue?@qWjs`3z zJ%TeGsFHV~&caUQV-EABiB9;QN6YnxNGzt3SrvFAsuG>3g|_(aM9cNls6>yc{){!J zQF}9v%Aka(RH`P_p0=aKb*Sf($j2PuOM7|5?|;MhGFH=HK@=8OpeonpyA9c0liEjv zHO(Qv<5g5-Z=uEaQ4U!wy1BXYpaG*)G9Q-zwR1$72GQGuk8N6i7$ z^FP2@`u)F7Lz(>+c^8>H!r~=oickT}LM_~gnrIDLbWtVz3Toj4$j5x2F9q-`)bkg8 zC$Wg0t3>rL#|qXr_tVhn-t7AXYNDg4g-@XdypIlEPdVn}a#V&JQO|!3`Itj|X`!F` z{bQ(r@@=kvCThN=n9`ozN8@SiMwRqmxC|{9pTP}y8;;@%JcFuCDJNAE---(K9@N%7 zgevg>YHNp3^XE=as<~EXI0NzyVaiUqxm7Ix5hAq5^6peR&@$;LW%TQ-^5mr_sR4l0QN1 zb+Cb#4L*r$@d8pcvy_|iAyf&6a19+?tQbn@?HPI02P`-f7ZN|`IIg?OCvkWl$}WR%`SWwzlTBG!$!8@pHYDQQs4aI0mmtM4n^E^iup58gM*Te+4WzdRzlkc5Ls}ZJ5zBEeD&rSX zfn7iaKJ8v(9>ivxhhIlMm%%AGj#ccoj?W1~$F|=OV|zG@~+%A;-!*huW(1cr)fJ z`d}!OjJvV86Yoop7TQep)W7CsoT5N}X0-T3US_0ZPJZT8*?2+b{LICZ9(H3fFXnUy zLxGt4g`^u#IN|8lU?dz0^mx&P8%+cf+Xq~e2zK}Mhn(EgAvfYCT&FkYB?mr!XHzg7 zNyc0!o(LwA@$~hTO%=Uv!g04TQ#|ZNov4=xZ1R%PP^P)^V&3HJ6zRgMgQ?sC1Hl-f zJG~LFI~Z}g-M-+~uosK_i+ubp@kQO91hf9n{XRD`;PiO?{lRGH|J@3?@t#_L0Sp);f-3?sxmWt?6g& zjPxrDOEPb+uFgxX%w}&VvTred&wpjyV%CP^3F~dL>#{pzC-Qxu&l|M;Zag0Bb!~)) z!qMJ|yOxsJTy?FNtw4N{P4u}@>uw7tOotb<{VTkfYgGvwcWERN1M!xI2KFc729r*2 uIMJ8vcEX-|I1&xnLD|Q>^t0_{vn_|u*5+>7RzIveZGB&@lfJxW^?v~QxIIDu delta 3480 zcmaLYd2CeW8prXsg_ddyvXok(*i%|Ig^{I{RjGDBmP*}fgyXYFEHyVCk=C6dm<2ma6`SZ_wV@A>4ju+v}I2Heo6R;1%99eYWxu# zj^|K;<_s~W6fM+3)p!}!qY}IyE!>V{Sl_(v-8ha!WcpAU<&&-!n1Whh8BW4~paSbc zjoXVwcoenJSuDolp~euCnTDEY0a|!FD$x7XXMMBP8?X(?_z+t79BP3BsM3G!^|KgEY^DVD{A5fi^5ryUqK)IQ8_V&(sD(dAO_V)? zYTzhTri)Q$AdZ@+8yRX|^!jh3w)VJp{hVhGSzW^Q;zH`L45#yTu^33q@e}; zsEO*mek&?~HK;(h;T7m2NtsiqE%*s_Ml1%?G)qzQ1U>IXi~d$5X0tCvLy;dumE;@b z*W|H^w9vxYs7zO&CQhKX=rL3RFQ6)R7`4YI(8BLfQAi+B7P#r*W9R|NChW zoH>S?sJH(Hk+O=emmu#ZGYfgy89!=)>roRoqXK>aE$l{B=vCD72a#WMnh(vNM>#aU zRIqOauogF>URWpjAUTuA?5gBM zoPjl{inOC%R6B4czK zlldxQ6%w0iMg_hOwa_6{1@cK>fiFM>*53&>>zoG(JOmvmlg?iDvh5 zPy@61&_q?J`*)$v%33VN-AGls4YB&TIT{T&cpfW zV|~*>BaF{rGY(?|Z^BNz0T19Rw0KIHcH!0dB5LCAQF}g$19T16qn_J>+OpHQ1ZQ!Q zwRI2RXxxb@f--M;H_jsm*;H^c@ozDfTeF2?m7jO*}YWNtI* z+Ds;^Q59T|Yw%rc$K^ak>}EgmO*DDb|0SG>ENRZ7DzJLi(#(QS6ZZrm?u_%>_SW3-miaGt`Su~b(8f_~Wx55c4*wSJL9h%YpyY)BLx)qcD zGa&8O%yZwFT$Pia>YwTUHf`*MrFK>2^uL)ry}{>mN6$|VO8-zZFF({&)!0Ay#$Z zY(R^vP$fyBQvHg5eGrMkypI}x1{LsU_*E=rvOBN|wcgX1(geLU>To-1XGgIHFQXD#>f83>`sb=rodKa}k^H+Gz66W=#WkYr+=P&Q_q# zz`MJ=?(cQab9cc3U#!>$z1gdZZjS=Pb2CKw4wq@A-9@7 z)ctQ@g`WTSXlQ4@L*7LukFa>jnIcpG6{v-$pe9;~7F|>dx1bj8Lq6sZUkYFVb^k@* zd=}Atm8kw1SjPHh2@Rd@)xIyHCVCUK@JFZtSJ1)Xq+i+K_AG4n?Ep*K9 zKaUD%h|Tqvqvo52Db?&z8auEZm7;%R6IPJl1^77XO}GcA^#esBw$&L3{x}!{gQDUy&c@1Sx<^s0CkOdpZ*XSdSM_3s&$Nn~D>09=74b zxDScRT=5-6Iu+1V)cno9t5BKv1~y>&&Qz}U$LLTdF5oo0j&rb{*WeQL@P2#`mGS~! z4vjb!AHoPO!k?lJ*HB&>%2+9C-Z^+LE<-)e+i(i*O3_fte}&C>3AbP!@8KXGLj7LO zY${0uDid)eDP}VgtLevP`~Y=EiYFN}6K7)~K8p(ETR01MU>sAYXdI;R2-`Y^8qFN$ zG_J&(cr7Z$E-IC;`yNN7@De_P)%WCT97FbC`cVN6UN)>8>g=3C1y;s|o|fsD;y{}xX%LLrg!}L4-Til z6E#r`dBn|5w0H!U4+Pud?%JfA@SJdDU7$N0Z0m?dJU8OCdC$aL;|1C~dV)^w?x5T4dalzIk0xVZ z{-rYz?oP&CC*cLWWFkGhvZ1WY^&EEtGbO^&h!cr=ZJp6%B$&Ck@?u^=c8YZ2_+6>o z0V0{;V<&#Ux_c`c6iMCKfj0E?wHdN?db_bg8%QQpquE3 zhhrK!IB{)u-R#KjaAeJ3{}O$3oHdw#Q8*0$r}{=B99@Yw%Y~ z5^OG?Hk#dYVv_YjZp6A9!k%e~#%)h18h5SsZWAsI&x<7*Cr_p#-EJW1bcMZ8vfT+s q)x#l}oE?F4bN&MvLO&S* delta 3431 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 DQ$=Qb delta 3439 zcmaLZeNa?Y7{~Fm2&jRkf`l)~#SqDt71I>o(uA~xf(lA4rByCU(jvP{DwP}9l#W_9 zS1TlEoN~;xw7kw_j=k8cHcgh(G}fp^8)a#4(wj{)_5HcG>7OQM-OoAao_o%7o^$S9 zJD>G^zS9>y)hBV2;cq|x2J-Jjl4}3{J&|Hef2v#XV%(1fco>J`dCb9_RAc&L5e~vR zXyJ0a1Y12{z;xqsEzv7S2Njx>9xKH?3ZW1E`6PqgHSRwSp9)QsfpYz$tub;xbhK z2F%C%(Zc6Y6TFW~{Wo6SM`vO)15x*nz^Ed>p28Jq;}C4aOYsnD;tte6329^l`=eHR z4eAVpQRB2BUCmyv{uXL$Pk8O;Jd;>eKiV_X$-h>3IbTZIOjOElM|QykaWdYE3g7^e z6mtwUa16E5^QbeDPU8R^gLznnO8s4^jBfPm`_Q6(tS|Z3q3WbTE6ZRRnxGgpP^DLI zKn2i(3Uo7$LKj(-iJ`XOH`E!i=uFYfLX8vfycaF%tw_w~K$Lk1GMlQ zDurpxE=QyGxC|BG0R!T>r0-KK7^SP+|n^0TppaR>5z4iRRO@ZLdanwMa z7cLMfv#5O_@@_KYk(Zq*MomzT8h9}(;AXV24V9sTsQZs1AM-6=8owLqQ2%Vn{AL0L zb-c;D5JXL|8g+`ddcK1i=zG)vsVvWrd6P`Fj<2CjzBFJS8(oW&Q3Gtp zN%#^f@Ly1Y_a~Z(xEQD4Q+PeLqsA#94eCDwuf*sQ3VSH*#M3x;v@xf!=<@h)!r(Fd zuuz|k^YA3H2s3GH+(mc=bqD9-5v;&m8Vhj+l6|umSKz0}5T=5CVauXsH3fCpi3Dkm zVHzfk=NAeyP%A3JbXqTXl;%&H0UP=U@xt@r^{#&+Q#{Q5#W`=304 zN05f$d}$ADd=KA51@s8BD}Y0M72}_tS23Cbe*i0d1cDo>cOmaL;Nz(KzD16O8A85Q zFGoIREngFu-@HpfHzsnjWGgnIe;R4WXHe}49BEDX7;3Ly#Z2rmJ-&cE)L!3?*Ww=3 znL3X%v9u_D|3(}@{UAm)&~XYJY?H_GG(kCX?#y!3_3fy$@iTHv%*m_ck6X_f@l+OI z3hia6>$hSyuEVqVENa|VqPP?fA-iQdX0rd&C}dp|PtknbLVXRk;ZT-w0N=n8T*)(} z8{frVm_Q?0H)*I8m!UG!giFvt1@ag6$L!L0z!OpT%_)rZNMqP62vk>v?1n}=9PwA%5ia^`gLeh$YOAXj z)(0bYFj5s+vD9|Ergr*L>z8V%us;~M({|7F2qvWb)6y8KbFc07k1j z4Oz~XAyeI&;hBj}v}BUIa?}gS&YvY?-BIK6Q=QP5G-t~2?#{{47Y&Zx*ZhA&5rkVg Yy=!;p5Tg{7ZtdzORSfevm)v~Y-$^w5T>t<8 diff --git a/tabcmd/locales/ja/tabcmd_messages_ja.properties b/tabcmd/locales/ja/tabcmd_messages_ja.properties index 28f1b0b9..27e81bde 100644 --- a/tabcmd/locales/ja/tabcmd_messages_ja.properties +++ b/tabcmd/locales/ja/tabcmd_messages_ja.properties @@ -155,6 +155,7 @@ tabcmd.publish.options.append.detailed=パブリッシュされるデータを tabcmd.publish.options.tabbed.detailed=タブ付きビューを有効にしてパブリッシュします。各シートは、閲覧者がワークブック内を移動するために使用できるタブになります。 tabcmd.refresh.options.bridge=Tableau Bridge を介してデータソースを更新する tabcmd.removeusers.server=Removing users listed in {0} from the server... +tabcmd.removeusers.group=Removing users listed in {0} from the group ''{1}''... tabcmd.report.error.user_csv.at_char=If a user name includes an @ character that represents anything other than a domain separator, you need to refer to the symbol using the hexadecimal format: \\0x40 tabcmd.report.error.user_csv.too_many_columns=The file contains {0} columns, but there are only {1} valid columns in a user import csv file tabcmd.report.error.user.no_spaces_in_username=Username cannot contain spaces diff --git a/tabcmd/locales/ko/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/ko/LC_MESSAGES/tabcmd.mo index 0b1ea7d1b37198615bba9ed3bd786b4c6803ae1e..d763c5be943066a27d0fa97187f2af466b745ad0 100644 GIT binary patch delta 3742 zcmZwIeQ;FO8OQMx561$SO=!Vwxb2?fY7o2K|8h}14y+FTGN*}${(mBZNIpsLDNw3g~CZqvn+7Wh5qZ&9jg)5>Ud_ z(xCcgHL4Qbs8YJ9!1kc_`X{IfPNMeoA}X-IBM02%vnq3&O4K~fs58)s3M7HtYWAV- z{}q<&{ePK;GJ6a87MU!<;v;7YPyv*q7H&jMv=%Kos1kk$weUXV$NZ9C3gC~Z`^P-9 zSw#0$pvD(t8S9&`(a`C>&-44JiC#c0{2Jt9}uEBo%Ca%LV zBqpsl3^$?z`T;7zQPeuea2OLG(|Df76P&Ey;GJx6 zBToG?pJ8mq_4pK01oMt(0jo68Ux>OM#-(@+_53wd;B)D?xC+%jitM&IhaAF$`G|(z z|Kjl2fZ0WL-b7{DMtirZM)|}3hW|k;_19oZMYQMaTjjD zGpInTH~{&0JCdwfhrD@a7gpd;F>y1EQ#4ePH}FL)=7d;$6$|kL)K+A3(cuwlg8S}F5abmG(%-8D= z^u(NR3^{Sv7mD2P4~GIhebI>PMBExa)U^;>l?hO=bO#>vMK6Q#=%n_##oaXKQpQ5=bqq7|WWRo+6oB`E(+)z@R@y z=)V4NwAUZ@^*TZS{h??q?k)29tHc*^`dnuHpX)&!5r-Sm^;P-NT0_-DiML8mXYHPn}Srt+4o)HVBdcIs+%UQWtadoeq;vVQO6RQ~+m zO-tt7+L&6ktbA(nteu^_p?>Lo^N!b9H|RvHvm@l1wrI=_1fwy>Dt{YyXt?fRyt$!)T?sq>Azy#U4G#7CLQ#!y o5E{}CrEiZ$tlxfGoKKguoIqQXx!1OMQ7*Uj!5Uw3OUJVR0FRJ7%m4rY delta 3433 zcmZwIeNa?Y7{~FmC`y86f(VLoNzh(o&G!r}6@1sQ7n-nSUDyj!w8*k(In`D&W}4>A zszqpH4P!RFXk1HEvus9^9bMEqS zlc%ZC6FJqZ^IF5t4*oLuI~lLuzd!2}jp<8w173?e@D}_O2jdmY!mK1?dSd|&z!J3Z zQS5__uJ2+B{Z_orn20$=Ll6Fh{jp2;*n`=4GyO@ZfVFr%u6FM`sPRXz7hXao8sEd1 zOterFjmMj?7`4Es(83MapZU!m_r^&iBXb3{qC}Rf335>r%)lG56qVRA)VOV!ipNkB z{fKFp*3%erGQ&`D?m!FYq7r>ledaff?tq=BiH@UI(2iO`B3UVO3zgtFJ~VL=YJ4r; zfDLHj+o%Z+p-O+=?RywZZYBfu{1A*N^E+vbLK}0i2?yd{)WqMS0>vd$4eX0r=~UDi zs6)kRLWY_ax4#dywI|){mt5mnRXW$xQmDUHIGhiaYznGm^N?LILCnV|Pzmfriee6< z0-r;z^a|>Xq;Rnxj=(`!gev_)R7Kag{cUK`Kir%8>rh?hf>xHwGBiOUDp0Z8uSF&B z3@Xu=aVR>-qRcte7W{%bBNl^cn(3%Ge%B|^qTh(*Y<5OyDD%%zCAon7ngnK%7Fu{K zYNaKpz+u!Dtw1ec3#wv=QG0v_Exd>t*NfmZ&1lq?7NM?3s@=wFRHoZ73)|4bOQ;ei zGrJsy+T$Wrf@N-hG4g9x@?qg-RGe1S0^3nr+l@(-Xd040#0;jP63#$n=0oN*kGrlz zWxmz56_v7~Suu7VXN^Bx(&*z|?UyRz?C@QgLyiV``ei|faj-vuyzIua9 znMKz#knbil2Kllxg{TQ;qXN%ICHyp6*o3OkZq)OiBfsVcJ`_KJa%g;}WPUT2h6di_ z-Uy;5ScW>q8(j~e0$o4_NMd#mku4=_gaTvaWDpi~7cQ}UrpIC{b`IefcamZYz11XB>LAkWzTpWoLQ1KR`g`4qK zY(*_NZg3>FhdF$WDbVdW3FqNl+=OGXGcWgO-A9$K9;e}Zs4e&lr=XXYUlmx0N}vIi z&6Z(s69W5(=nOOJy?oLxCM0<+Au;j z%qbdr9g~v4|m~N)KV>d*NzsnjbI3vm$!a2cM&DB2TaiCjUgG`AqOf>NADzZ#YB`BCVqnlu?SnJ>nx0$5<4TaF_r!cs4tXF_%@!# zAg-Jm8}~a7pr1#UtvCl;Fq?hhxR@`;(9j-U%SLP99rzlS;#~C1j2%KBD)Xgi{DDC9 zOpmnauZcbHFY}i_Tp6mV4+iXzH&_#{s;DaWhpTFW-iqp)MWK51S5?=CY;RrIAFi)6 zW&VIKWY^Z)bzyJ74s+966kgv*X3pR{JwA{kY^QKHHbCvD!Di z)v@&Xj^)i)2X9>a!}j&=Gtu?g6P*<|Hg<|$EXZ@RbJxX3gN37t^K|~KuF(;NdCqHvO8MJiT?nptA7FtSdi)FHQM#juIQ9G3B*owoL5sP)K{UfD~Z)1~=qW%8%USsW) zS@v_zx##6M&pCJDqaPGJm@UY>S~mG1!=FL^&gJh1SE%;MpFbBHGl%L$oQC6Ajh~rn z%nV$B*I@`Pc3=hW2|S3?sh`4Y@OP+j!&qrd#{83lrJ?w0V;15f)P#3o4emgT4o|3*z*!8YgP0#rclSdDvd zCLTjAbQ)*j8%PZ1GHRjXQh(w3fw!UBx1r|WhYI{KPG@~HNI?;wLq#@{+bCQPc!8 z%l$wWqv|2l8GbEj?+x68vuV$wj^rdNL(iZx^a_$>GlI=HUQYhmtZAgTCTv0NY$NIp z?7(aB0M_CFDwQvzQaBdWD;R94H=^#$S5X_)bM9&4jhL-vVNGzt3SrzzFR3_R`3vCPBizE>_cCK@=8mLS^pmz@5nHn#=(T ztZ5z#8ir7jokxprq9!V(F~2j^S+=19>_7z+M`i9usDOTf3^mUNUPNLtV}Yflk$^I0 zJ_WLG)}k`836)9@71%!1Ssz7BFoZhO3#h;@As5_S&8p08s!;PZq3%E%Dv%7))f__g z|1HkZ`+tUlcJ?~*TVx6diyt{tf(l>`YT>1*iN1suT~rG1M=g8^`Ism8QUEWa`i}%o zViEPLM71x+3f4CpDCl-?4g4W$q9;)czl0j_COSBUbliZ;Q9Im(>i;0}F^}=3h0X@; zZ=eDyw0`?+)O^b@qcdAi;Suaa)-WGpBUX~%HFzf~z=PO;Pos|LZB)jJxUsqm<#;95 zU=c1rrMdwZ;cEOm_Tf18*N}gLGe@~W-^U?r#V@lxEpQ0wYaU0P`8nicUgzr;ypo@_ zJ8&H`)I5s%;Tl3+(h=1BW2g*OunXORM$|^yYBT;N+Dn5{bR7AZLB5vbUvVAIW!5I# ziVEmB>L`AXH{lrGh7J5^D9~@A=Gl+BBTpb7bA~Uy&TkU;{4OhiZq&|>A=x*lP&h=$!`VFJrqW1%* zlV;7o7+dxJe}%#>8jheY*R0R^6Rt$Ify(1ITC#tM82m9jC^fQ{TlweLp-a29!FMsX$9vi6DvHIjNp(f3eL~PkpB#=ah65=K4#YE65!yn_HNBY5M5o+-tKNCT(<+ z$wboW3`aVW?l;qJ%5$Re?crE7($STOdv4t8@OJgN#tV0L^+p`Ocf^gkp6hfc6Y0KB zKiLwF#?ndGNqJ!}oytzBY^>;ZJ;&Y2OsQxh?!*&b$CgAo9?9KUIZ|*%eu`{y)uS1I zfxd8((4FpBqB9(GI^CY|_GluR3KseFQ{s!eT^_Uk&+{HP*5`C3dV9n1$p3p3aZ_E% zXrD$-OguloZhmAe8s9e2{z-GH&+UqCiFV~qRM~>u+xFX&a+w=8Ps$#zE6vTDcd0P9 ze&IWlbKa7cDY=rSXi@f$_WEr3!WBg=q{NM6w}+aup(V?51EI}DCHZaJx_cXT*Ex=p zyVTNFkXf7Gvz^#;lL=b>YoAT#_Grqpi7mE0e;#&Xmv{CgcGzAwl?r#eHb$ptynEuQ zB@x!osZHefomynQ9ye~?ol(!UB$BqbCy{im_HR=z1<&hCHPzR1Dls>lcDkcpPrB2I rCe*@3sLv0|cTdD^*nXUxkC(LEKwIbcwar14tL);QIw!lLbR z&vVXmp6B~~pXWL7w3qYaj-1Se;=Gp)fBN`a#^3WJRr}AM*9wf8Om#Po#XhXXk8wI) z#R{w#W6VTcj5pv~v~Uwn!d-#y;{@u*aJ(@YbAf_hyn<6PzcBk^CEh}P397>lcq8rz zp8KfwpJFi%p#mLQWK20)sDZ*b6IY`q_$#z#Xy8_~sP95zHvJh2 ziu@ERC4%@@Q2}p53wu!+I*fY%6!J4) zaZ&%HNQc^&OU5_#6x6Uac;KK0coMaX_XK`~>Sz$v!5F4jgVV4QSEDxZX4LbyP?`Nb z_Tp#AtH!mm$NdG&`u@S#T4Lp}T&B8WRYM)1CVlQe9-^c6lcc^|oM!q%X z6jtE?&ch-){~nu=7)%2T{~ShcBLB-M401yQ%wrk~7jp?Up&yah%&cjd?3%PPUCp?I%Y1wRSK@K}8HVUx zfwiJi-h=hH57qu6F2@ib0RiOO(kY>~jpF+)GCn^KK#oO=;RJ#)Xg;Jo+xEQzMXgq@I?*#rFGXoSH3Kk1? z0G~%68`w#j!7$#Blj-et>_HBQ=?nZ5YTzNf183Zt&B!BYQQwO?rbjW3=Wq^&Yp*R) z#-u4|SH6U5=%Y5#F;oEOknEaV7EaG+qE1IRsINg~z(J+-Mby&tq4vNK>U0&8UbU-6 z9otpcWc@oRXn-eh8NP#$;y;l6WgNm)haPICpI{hA)McMH;vn?|uEI4mQp(>(Wo!_Y zvD&%WC0U8YWVT=}1q*rFYfmU>NVgJ?P6=G^6Jh?2 zN_p8*W8TCC*oGI-!iDV23T)F3jmG2NKvBs1zF^#%b zMAE5g?@VrVyD^&R>~`&%R63gOPMLMlc*M0gbla(PP25iNuqNU3L^~7lNG$23Z6_T` zKiXyc*Nqv@8I$Z%SE(8&y59CL7dp8G|Gv}hcKUaY`!uKKfAsf|?bvQ27Kz)PcG`|8 zyslKlcHN}wPb{v?EwMK-PD()%aim?*`*jnB^Sq0pQ3dpDT)W-1QxAK43a9w>*O!m* z4wqH?qoxkzc)8_I`E^!#PJR=S+i~wiL#5wZ@%V_b&B^t)6;E1SZnDEpC;iiv(Gl}o zEJwFvQRfeboJ1_C2Cg0Jc2mhJi|Mu}T^c7Wh@S z4CQ(2!*%`*wM{=M{_p<0ZS|A9XQ~RP{{Q}B^&R=%?C=8rjqro{{@kTAbG&7DF8&v0 Ct>gdz diff --git a/tabcmd/locales/pt/tabcmd_messages_pt.properties b/tabcmd/locales/pt/tabcmd_messages_pt.properties index 32427c37..5db5d37b 100644 --- a/tabcmd/locales/pt/tabcmd_messages_pt.properties +++ b/tabcmd/locales/pt/tabcmd_messages_pt.properties @@ -155,6 +155,7 @@ tabcmd.publish.options.append.detailed=Anexe os dados que estão sendo publicado tabcmd.publish.options.tabbed.detailed=Publique com as exibições em guias habilitadas. Cada planilha se torna uma guia que os visualizadores podem usar para navegar pela pasta de trabalho. tabcmd.refresh.options.bridge=Atualizar fonte de dados por meio do Tableau Bridge tabcmd.removeusers.server=Removing users listed in {0} from the server... +tabcmd.removeusers.group=Removing users listed in {0} from the group ''{1}''... tabcmd.report.error.user_csv.at_char=If a user name includes an @ character that represents anything other than a domain separator, you need to refer to the symbol using the hexadecimal format: \\0x40 tabcmd.report.error.user_csv.too_many_columns=The file contains {0} columns, but there are only {1} valid columns in a user import csv file tabcmd.report.error.user.no_spaces_in_username=Username cannot contain spaces diff --git a/tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo index e329a6a88f01698761fa98826e41d1f6b652ae22..8b5ccb5f4c570888e4d1ce358330801f0479b027 100644 GIT binary patch delta 3773 zcmZwJ4{X%s9mnzKO8IA@l)r^)%hRHkcI8+86-(PuP%Hr%8`?2pV0Z2P+Me|8+PmLT z2(qKPEmKja7u~9uMGXSmSPZ9$1dMZF#+DH$VWM*wvLOlEtci=EBqDo%?ta#}j2yq$ z?|JU`JkR(0eV+TlulEGrdNh#wU`qazhCj#ndjo$z8?DxtfBsrvObN|%I0=Wb9LG&C zW;#}587@bQZCH%EeSe12XupJ$@lDjYvsh|O%6!C)rK4b?F<-+P)P#3q1@@!Gr;!2X zC{Drma5nx6wZMczg28fBB5ToN7&Y!8zyAPc1Hp3EH)s6^uAn9^Ce13WMg`Q0<+vMX z;Pa@3j^IqZfW%;~q82JB$}L>wy9U+26*d2ZsKEE)G}brAxKYG!qaqtZEvSYDRN!2! zLyPyIwj_lr_0xX)FcO0~g&Kbj74S8@31=|b9Be|Z_dQH$f?eFq!zWRh9mh%>LQODZ zYA%p@sP=Ny9)8E~kNED!S@fq-TXG0hq2Hn^^gdE#a|xSpcq;WLSyRW;ny>|x*=E!k z=*R2vDZCjEqe}T6s)U#Qb}@r3?K;$%*?>xD2WtNPsCi!X+hk1`E5fUE)Zz@% zBRJE7D)}bVS$F{Xm_uAN(Fx!4XlZ|j#9~UBRe>)=RboAAp{>3Tpr!o`D$!%AKV!{V z)ZPrCGMGYCDpeh7PgkPFR@8Gz6IqqH&1}>>4X87)9u-ImdDIM| zo__^P^!xuEH_Gg9$h*h{2#c4TDMSTOf?9YXYN9*PqKhiwk5CH_A|LZI7X@${_53B@ zQ7oe8N>TmwSj_t7PHuF%@AZ8gHPNf6h2KF9_!u1=PdRSHdQ^s6P|rV%e9S>ETIlzF z{{>V)c{bNS3pL+jOli;7aq|qeqxSN1yag+$@13{_^(#1pdOw`S>oAX#s(&sfqS{k& zES6y&-i+h13iSe7g!6GDp2LSKsJ}AoX4QTiz(%}+IsG2@S%o5*4XDGJMAkAtKqasr*=6%KF2JFiQn`#RvueSWNVUvHT#7sJcFf=syn?J{ z=JR^g8}i#+7UC}aI=+NDoI|Mh$2C-i=h9H+no!?&p}yaq;;KXT94^8mn81&)1A~OE zU&ouc4BtmpqJ-Iq#nhno{w~y(^`XUss099iI?Va}OQs4Hq2{T?K1_9T^8z>T;y%2u zCO2^fC+i!uSK~VTDeC8Q(KnBiSVy}I^?fTY#urdq@Gfe>%h-;Eyk1q=KGZyqBfp-M zImFE*I(~yH?VnH&e2RrQnG>T5SX8B!pcYu?8$o5h2RWDK1gatzk?Na#HdN` z>P*~?x9Ru4lbZoLUPr43*ihCs?WhtzfmG2PK^>k8cp3xjmxpIinXl$Tam@Eo3H%B< zXXYd};t*P_rff010~4%oj&h^JQ_BfcCK23>`_N(@o!ZMesLZ#Zp1Y3=L(R*m@&CXT zIJZ7miF=h}Yvq{4VA#%Vl^E5`!7QF?bBM;BhR$zoP>B95sGnGxb+#)-~rQ>cel*K7|@k zww#|HE=5)78tTPUPn{Lu4^bt44RuCN;g4|`x8cC8xxF7o&A0eA-lF(TydSToxY5Af zD|3hFm#9*m$1*Iso&RuREpEZnsM61G$-P)^#bVkUuo0uE41a;_qWJ)|@XS@Yj2EE^ zhC<1N8&5ci?(~5In<=00Ng(4Cw&i6G6rBiUo}Y3a}@0dR^lM+dCp5C--#7?QuQV>59jayF ztFr56NA`rHTSxl8>`wH$9pTP!M`r)*%0On=P9K#iy>Z2;v8_Sd9*cYFy>o8KoUS~Y zmpNH|GCy;ocE`9(s@@xu{W=l>h?__RyIkADL*Z!G z$hVe)*j#OGESrC##(Ldu)VkZlo@t52Z6prFJ&*0MW2ZZPR|g}v@% zyAzJ7hXYZY9h7}M7PUe9MUlQ((sB}QW$szqPx# delta 3438 zcmZwIdr(wm7{~D!6eIyfPy*CA1WB2$N*I}mm&7hqIu>0lrG-7_2JXr^yO@@3IyGZc zmNQE>hL+u?nx^ZKrX0IplxYUj?DB`{m^G6zIR#Bf&1m1Bdz$(q2F~Yw&*goe=Xu|A z*!M`h-~SY~w1@ojeZCoFRm}OK(bQiVR&h|tu0WOSc4QSy1TVvNr~q~$ zMKK3Z10O?WI*8gMqd7SiFTx495LNniR7E@d{!X;$9~eXZwW<0!q09Z^BC4_+C}t?LYIBvN z5~@Na(txb0N#HcxhD>34&P${w?&Ad2F~gW;23BGn2JvEi0hz-bMt$*yaHzryaXK!; zS=fPRK2WId!7`15s3jRdO<2h1vI!@n65WhcJYhbep@Duty*Ao0BcT9Q z@^aMmD{%ydP!(}em3t61(bK*kpek_$*>~n_7F-pYfvkqP3ANV}Sg7~EgN8QC%Xm5V z;Cjqwfi3JnVl!Q+lK+TQ)8vqbHdPHCz#A}zm87oWt2 zR(u@wTK8iK7R*jv51fz+b2jPc?N_0P9gDdr2V#@4K|y!D@K(8vw&O${Z%lqgdVzfx^SBC< zh#QwHdartP|Ip--qO5F2HjcgAvE3EP9l2w@8O5bTlDo%E_OiwwO-rViKIm0j6Vfsl z5V;*nF0HNbmXwVdGIEg7E^}Ee!ALX`c3XmHu3Bz% zr4_OxR(seDx>nd)Z8wn!b8@ryTIHYV$@R4}y_Y8L9hy8Zpyq!775Gl9V109lf+GGcDzb6Zf~si1Ec`k) zqs8x`jwFpr^>$a^hs0oBL5&|n1^jQEja5umkL{@SzK>~5a5seo_%Lc`FJc3Zqb8`D zmJehBs=gd`hIhF3LFZ!`U%v=|6ED_72#(zG+`Cn zBRJE6O8FYpUD$$r%pSfp(J|*4wA4REVlg$$s=ybaGSP`zXoGVLTIxGc8$G1_GuE6! zoy|CE2jxViR5hc{^hUJUh3c0=K4u$VI?H{o{Z;2jSVwy`QCM7p%G?^~2y(h6y_EuM znx|dEQB-6n(BcQEiOOiq?F@C6ou~l2Q31tJnfnzmss=ytDn{uDLQ0o1}LQ3F0e52uihuVD*nhwD)Ne~f(0(|l>6U%U4A zPyrR%eEW3Ne2X!yGh0nz2lk+j;$Qd;tRTP3aV4t#J|qUS6Ll$Hz$y3}=O3_$`f2B1 zT>JZ|r|2Rs!a8pFFR^PD`PYO++@L<3jo-wFPzxME?esO&(fkwjVk)HZ2Aqr6VidK* zCsBbukLv##@-bt4X`Mn|gSrECs6dv^PUp{Xhz1SZf?8l3HseuLKo?ONna4R%G;2{i zx(7AUGpK&2Q5l)WBwDxz703$Iytlggu&dvjrl3po3~HjoIE)u?4X)=cq`;2jVtflV zVHvCE7C^e16{vvMqt5o{uKjtOLj4`oxbt{DUcx?1xA4N>OyO~S3N8QSX@@W2t#}^W zuzi01l8rdGq88kb`u!a0GS1;ksqR8u!X(~|KS8Dbl=CCxF-)7OTxngxI#h>d)Elr9 zOEEyb54JcTK|PjxoX1fa7(=dyncS4mSR<;w43*(t*S--I*h9EP&;Kq85gPu48gL5- zO>icTn)p%Fzlz75AL1eES1;s08TdM?|7^}r-i~@~e}p=s?WlPUqvroBc49FXri=B> zItm@Q51GqcLZxgT2d;quD#bfd8G0Qp{=@xV$vG^cz7$(<7%Oovmf%aMd47-D`6sA( zs(5tLDlDSF#WkyO6Q-~dKg6k6bY1=uRbeT0i~79@D{v(yaE)t!#rZDkE?q+It*IqC zt#>o7#&8Syzk@=Sh8PyJ4RzRr8n6{F$HS-qUq-#@#!-QlwB~Q~Ow^tEF7h!yx@>k<~FBEQpB&TcfJa5$Cp6G<;Qkl9^qvvnmG3bI~lcVTvS*|CD` zX!*>-?8%DpN!c^g7hbm3PbA_AuO}4lPWV4a`N_bG#5RVak#Ki!JQnz|pgXv8$TvZ# zr*|;y<$H(ys2})Ve%AsMq5Ugf>RviKJWP%fAv|%ZZhd|B%{h-1X0wggP0C*5^VOGnN1V delta 3438 zcmZwIeNa?Y7{~Dg`BtDJq7f-vgD@>tNeux@vQkTnvaGZhTIC{Jw5z*InW<|^IU`)&$rlALa#i7`%Z{oo`ypaA?sDKObJZ!Z0J=FO9n2w#OM0@r# zCI=nVL}fS{pHLz&;aXKx%rGBT%8D@tLxnxFtR!89C!ccK!jM~&NpgYf`r zqMtDnGt-PACsT-uGZ7uU1C{7f^_kzSwgXyG6CFgYpaZpn6tYt04l2P*`O?JYsPPN% z0<1#^UqwyuIjZzO*nSd&$;}KwJ%16#l=*cu#-WSnV>9OB`>2WAP=S&MQVq;Pt#m5t z3`9_InvtPqv+aL`+S)_*dZ)D~t2&44nHkhyE4-L5m23*CWOpIEV1hUSm!J}8MT%nf zp#mR8t@JeNjAU@}TpWY>SdJ?FeW;2)ZTnl$p}%hs_1B^5;(}H-m}O{!D^Y=F+WrDm z0uQ4SZNgFLA&W9cQCsjk>WnxHrfIH0#qnF0phJH(lCx=z(NN}lQ6)Knd`ur^kq$aI z9<|b0sK8Ow7B!$2@H(nu`%rs)1ReYhH7=dtG|eTbEiFe~kJZ>lBP!D^I1Il)2Rl(E z9LVgl5VgnUs08QO{vzaKR`BKECRCg~s0DVQw)QM0QKFeh0x>h3hDtaMm01Ncr&(-W zh046ex(AiWcgU`FKctEb=3$kz0F~Gz)Sk~qJ--OGwQ*Ep>v4d7{~yyJIdc#dsH^)1 znKFy64?*5drU-f2nJZBfT#pJ|jY{|-bg&s!q3x*W_aYzjBVUT&hjM6qj%0pQOhW^2 zv^RpN3F=X&c%AhVRG<^60I4j`hxwR?Gf{_l5$gUXRAqNzGaf)yEbJs+;q@5n#f7(N z=n(D1GCYbJm`9zM%aouF)hs*{1J(%Y`6bpmd%XemD_Dsa;|_cSJ5ll0Gg%dWa31v^ zLt`W-K@;4GT1n9Mlh$DGA}Xl0{Ofo9wO3e@( z_`~^9zufk3kI_&jb*O;P;Qjb1&c;c+RkX6TI2JurfaBOb0W#ENk(CmkgeABTbp|}t z{m<}BJcWAxZ@dg+sl3RmXiURpxEVL#82-d*#ou5#{*9$reo^8OHdtRmP5cS!{$Hp= zSj?A7KM!@dm*Z4?9#yFyku8atY>u$@rUdyzWp2iSSZ%K_Mjg&)u^+yJ`kjAj{TB6W zIcZHDl~{2ea!ky0R0ZeT{&G~sU+%un{=Z8@8Gebycme}>0UNIXPa(;gw@{@#hWhK5 zT9~j1x6_}4(=msA)c6`}6Y4#&8?|LeP;q)uhFs=1J{mXR47>@~<77OI#584Wyh;~F zJ@^i))JIX3%c1@bmZI+8j?7`|Pz&0MQFUeKWswXe+e^i2ZnLKy*`C3bpH<2*@}#3|2e>BH5WATF1!v8 z<1JV~`aygYb^j!4d|HVyy|EaT;N_?{V>R~2<*3uW3VG?7uP_TwVLGOjCblBCl=^GW zrgC8duEb2-haX}G@-Z#kR4IQ#?P30|~{Yk$6i8s#; zy5Ydwib}V}jk*;|Z+@i04TnQvZ%}$(@<4YX^F)*+8CO&(dv9z;SC9C&nSD}-Y{G6; z*o{=j*Y!QuD?TUZjQI8;1zw+_N0Q>nIgfi|odHR`CX=~a8J}H}=Up|dCAt3(&%fQ? z{91ccU0dUd_Khvx$=r_Q5p9pPwm;d@wq}zvbH;S%*tS=>fBen5?^_$y*jRV`iAU`4 z!}+_C<4a3Qy>%msdc^-M8S8yrFt2yv|2*Heb;GfD*R;3n_`ZJC@r}#dn%`@CbX(hV d4K~n(aXCHXI|($Z^gs`?k diff --git a/tabcmd/locales/zh/tabcmd_messages_zh.properties b/tabcmd/locales/zh/tabcmd_messages_zh.properties index 58beb33a..4527c372 100644 --- a/tabcmd/locales/zh/tabcmd_messages_zh.properties +++ b/tabcmd/locales/zh/tabcmd_messages_zh.properties @@ -155,6 +155,7 @@ tabcmd.publish.options.append.detailed=将正在发布的数据追加到同名 tabcmd.publish.options.tabbed.detailed=启用选项卡式视图发布。每个工作表都成为一个选项卡,查看者可以使用它在工作簿中导航。 tabcmd.refresh.options.bridge=通过 Tableau Bridge 刷新数据源 tabcmd.removeusers.server=Removing users listed in {0} from the server... +tabcmd.removeusers.group=Removing users listed in {0} from the group ''{1}''... tabcmd.report.error.user_csv.at_char=If a user name includes an @ character that represents anything other than a domain separator, you need to refer to the symbol using the hexadecimal format: \\0x40 tabcmd.report.error.user_csv.too_many_columns=The file contains {0} columns, but there are only {1} valid columns in a user import csv file tabcmd.report.error.user.no_spaces_in_username=Username cannot contain spaces From e9e6161ac716396fbd46789346e3730c2ae63719 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Oct 2026 05:46:24 +0000 Subject: [PATCH 09/13] Apply remaining changes Co-authored-by: bcantoni <58372+bcantoni@users.noreply.github.com> --- tabcmd/commands/constants.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tabcmd/commands/constants.py b/tabcmd/commands/constants.py index 102b8eef..d354cc89 100644 --- a/tabcmd/commands/constants.py +++ b/tabcmd/commands/constants.py @@ -1,7 +1,7 @@ import inspect import requests import sys -from typing import Optional +from typing import NoReturn, Optional import tableauserverclient @@ -58,7 +58,7 @@ def log_stack(logger): logger.info("Error printing stack trace:", e) @staticmethod - def exit_with_error(logger, message: Optional[str] = None, exception: Optional[Exception] = None): + def exit_with_error(logger, message: Optional[str] = None, exception: Optional[Exception] = None) -> NoReturn: try: if message and not exception: logger.error(message) From eaa9e4d02fdf9f8b4b466cd33b9f587e1ce87ebc Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Fri, 16 Oct 2026 14:08:19 -0700 Subject: [PATCH 10/13] fix: stop configure_log from overwriting the INFO format at non-INFO levels Keeps the TABCMD_CLASSIC_OUTPUT-derived prefix for INFO lines under --logging-level DEBUG. Adds tests for the DEBUG case and the opt-out. Co-Authored-By: Claude Code --- tabcmd/execution/logger_config.py | 2 -- tests/commands/test_logger_config.py | 36 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/tabcmd/execution/logger_config.py b/tabcmd/execution/logger_config.py index b7163c72..8bd89ac4 100644 --- a/tabcmd/execution/logger_config.py +++ b/tabcmd/execution/logger_config.py @@ -59,8 +59,6 @@ def configure_log(name: str, logging_level_input: str): """function for logging statements to console and logfile""" logging_level = getattr(logging, logging_level_input.upper()) log_format = FORMATS[logging_level] - if logging_level is not logging.INFO: - FORMATS[logging.INFO] = "%(filename)-10s: %(message)-30s" root_logger = logging.getLogger() root_logger.setLevel(logging_level) diff --git a/tests/commands/test_logger_config.py b/tests/commands/test_logger_config.py index 4a09d7f3..7b8ddae9 100644 --- a/tests/commands/test_logger_config.py +++ b/tests/commands/test_logger_config.py @@ -124,5 +124,41 @@ def test_no_double_print_from_sibling_loggers(self): self.assertEqual(fake_out.getvalue().count("msg from a"), 1, "Message should appear exactly once") +class InfoFormatTests(unittest.TestCase): + def setUp(self): + _clear_handlers() + + def test_configuring_debug_does_not_change_info_format(self): + from tabcmd.execution import logger_config + + before = logger_config.FORMATS[logging.INFO] + configure_log("test_info_fmt_debug", "DEBUG") + self.assertEqual(logger_config.FORMATS[logging.INFO], before) + + def test_info_after_debug_keeps_classic_prefix(self): + fake_out, fake_err = io.StringIO(), io.StringIO() + with mock.patch("sys.stdout", fake_out), mock.patch("sys.stderr", fake_err): + configure_log("test_info_fmt_first", "DEBUG") + logger = configure_log("test_info_fmt_second", "INFO") + logger.propagate = False + logger.info("classic line") + self.assertIn("===== classic line", fake_out.getvalue()) + + def test_classic_output_opt_out(self): + import importlib + + from tabcmd.execution import logger_config + + try: + with mock.patch.dict("os.environ", {"TABCMD_CLASSIC_OUTPUT": "false"}): + importlib.reload(logger_config) + self.assertFalse(logger_config.FORMATS[logging.INFO].startswith("=====")) + with mock.patch.dict("os.environ", {"TABCMD_CLASSIC_OUTPUT": "true"}): + importlib.reload(logger_config) + self.assertTrue(logger_config.FORMATS[logging.INFO].startswith("=====")) + finally: + importlib.reload(logger_config) + + if __name__ == "__main__": unittest.main() From cb1d68bfa440cf047fdaa278dada57a88ebb57c9 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Fri, 16 Oct 2026 14:11:22 -0700 Subject: [PATCH 11/13] fix: keep classic INFO prefix on the stdout handler at DEBUG level The stdout handler used the configured level's format for every record, so INFO lines at --logging-level DEBUG rendered with the DEBUG format. Format each record by its own level instead. Co-Authored-By: Claude Code --- tabcmd/execution/logger_config.py | 11 ++++++++++- tests/commands/test_logger_config.py | 11 +++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/tabcmd/execution/logger_config.py b/tabcmd/execution/logger_config.py index 9410c647..b00ea624 100644 --- a/tabcmd/execution/logger_config.py +++ b/tabcmd/execution/logger_config.py @@ -56,6 +56,15 @@ def add_trace_level(): FORMATS[trace_level] = FORMATS[logging.ERROR] +class _PerLevelFormatter(logging.Formatter): + """Formats each record with FORMATS for its own level, so INFO lines keep the + classic prefix even when the configured level is DEBUG.""" + + def format(self, record): + self._style._fmt = FORMATS.get(record.levelno, FORMATS[logging.DEBUG]) + return super().format(record) + + def configure_log(name: str, logging_level_input: str): """function for logging statements to console and logfile""" logging_level = getattr(logging, logging_level_input.upper()) @@ -80,7 +89,7 @@ def configure_log(name: str, logging_level_input: str): stdout_handler = logging.StreamHandler(sys.stdout) stdout_handler.setLevel(logging_level) stdout_handler.addFilter(_below_warning) - stdout_handler.setFormatter(logging.Formatter(log_format)) + stdout_handler.setFormatter(_PerLevelFormatter()) named_logger.addHandler(stdout_handler) stderr_handler = logging.StreamHandler(sys.stderr) diff --git a/tests/commands/test_logger_config.py b/tests/commands/test_logger_config.py index 7b8ddae9..aaad7b61 100644 --- a/tests/commands/test_logger_config.py +++ b/tests/commands/test_logger_config.py @@ -144,6 +144,17 @@ def test_info_after_debug_keeps_classic_prefix(self): logger.info("classic line") self.assertIn("===== classic line", fake_out.getvalue()) + def test_info_line_keeps_classic_prefix_at_debug_level(self): + fake_out, fake_err = io.StringIO(), io.StringIO() + with mock.patch("sys.stdout", fake_out), mock.patch("sys.stderr", fake_err): + logger = configure_log("test_info_fmt_debug_level", "DEBUG") + logger.propagate = False + logger.info("classic line") + logger.debug("debug line") + lines = fake_out.getvalue().splitlines() + self.assertTrue(lines[0].startswith("===== classic line"), lines[0]) + self.assertIn("DEBUG", lines[1]) + def test_classic_output_opt_out(self): import importlib From 36e5d86615cadd6e01542a62d214e9c494e818fb Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Fri, 16 Oct 2026 14:15:35 -0700 Subject: [PATCH 12/13] chore: remove unused item_name in DeleteCommand Co-Authored-By: Claude Code --- tabcmd/commands/datasources_and_workbooks/delete_command.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tabcmd/commands/datasources_and_workbooks/delete_command.py b/tabcmd/commands/datasources_and_workbooks/delete_command.py index 1fa73362..e33def82 100644 --- a/tabcmd/commands/datasources_and_workbooks/delete_command.py +++ b/tabcmd/commands/datasources_and_workbooks/delete_command.py @@ -57,10 +57,7 @@ def run_command(cls, args): container: TSC.ProjectItem = DeleteCommand.get_project_by_name_and_parent_path( logger, server, args.project_name, args.parent_project_path ) - if container: - item_name = (args.parent_project_path or "") + "/" + (args.project_name or "default") + "/" + args.name - else: - + if not container: Errors.exit_with_error(logger, _("tabcmd.errors.parent.not.found")) item_to_delete = None From 21c931eb2051938da2510d83f249cee95877eda3 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Fri, 16 Oct 2026 14:29:42 -0700 Subject: [PATCH 13/13] localize: regenerate compiled message catalogs Co-Authored-By: Claude Code --- tabcmd/locales/de/LC_MESSAGES/tabcmd.mo | Bin 20097 -> 20191 bytes tabcmd/locales/en/LC_MESSAGES/tabcmd.mo | Bin 23120 -> 24780 bytes tabcmd/locales/es/LC_MESSAGES/tabcmd.mo | Bin 19838 -> 19932 bytes tabcmd/locales/fr/LC_MESSAGES/tabcmd.mo | Bin 20281 -> 20375 bytes tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo | Bin 20125 -> 20219 bytes tabcmd/locales/it/LC_MESSAGES/tabcmd.mo | Bin 19991 -> 20085 bytes tabcmd/locales/ja/LC_MESSAGES/tabcmd.mo | Bin 22545 -> 22639 bytes tabcmd/locales/ko/LC_MESSAGES/tabcmd.mo | Bin 20295 -> 20389 bytes tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo | Bin 19146 -> 19240 bytes tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo | Bin 18631 -> 18725 bytes tabcmd/locales/zh/LC_MESSAGES/tabcmd.mo | Bin 17342 -> 17436 bytes 11 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tabcmd/locales/de/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/de/LC_MESSAGES/tabcmd.mo index 1e8df0671b7b4f80ea5fefb3590de3d907a77455..0e085e005bab34810fe6be4ccba45962be0217e6 100644 GIT binary patch delta 3143 zcmYM$3rtpZ7{~GF6~P-KH{}(4Vj+l>Ku?QV>F#&6Q4`Dp#XD|k@ zp`L5T5Vu?V_TGaTn8Aet)P%2LH>~onA3+|lMvTR~n2eE8-U7X`7w5xJiIk#)>rv0` z_Qy}+gFrBa^{v^zp)=`e;=%Y3=A#076_s%fcET@F3;l#aY#D7vEEYm7lz|S8^)2zo zH=ySK7!`OO#W>>KXM#Xs(WFbQ~-ajuw?cpMSyu!BzJ2PI3+Vj(> z3SB`}=pUrm)`p8Y7>uX>ByCd|(1gXP%$A{gpbC@lAg1G4REh7RN|?YyIv~Vm!L}j7OE$XAs@TNmnMv07G>NG zb)JI`K7+()i&2SeMBTRs`Pd2H%c{S_Kr<@yAkk=nfvCO8M`bhzRl3cnJ+46q_oMFn z4*A#}zO=Vdtfuh{--)P%7NUcdsLHtq{e$mOd)$PIFq~*~9zq4yk1q$up(ZND2brPv zb`L7R&ru7XLRIolR6s2#4^vyRZ#ELEYm>bLD@8@L2H75a4^@f7s8XIm1$GU!_xDj5 zhnQV^oP`Q(G}8F?GP1TUMa{Dv)f0PAfiz;0e*bqk&;v27t_M<4nGHo=QZ@~F`B@1n zfO6Er8&MPOLI)dA6}y6(=MM6*XeLttnW+0m`o4gPtZ$3`fo-S-_M*D|xbIEWMDe7p zg$JM}8i$!U6Vq@TD#OF5`>!J(3wOMLx}(N(Q2`aAt4PZ@(1e>%d$t>QU_EN$XQ^v0 zx>$fmQSXQLbf$hagODMciK^5(->uk+^PRrCP!-*Wdb8Gbqy7Uq_?>~U0F6TDCDuvUFZ!y)h59W%E$?uf`W~KNev;p^V~>xy~q4*FL~U@EcS>t#~Q)$ET4sZ9QtjeK-Iw;sor#YHHp>)b)j^X01WJ zX%D#mz(s%HCTfp^Tvb5*@pYVyE3gT*Rr9IeP~3oOx>Lv{`xzB*YgSXheNhXS@TL2! zP`|DVs2*_t@Gpc>$2S-ljt$s|Ut={Lrio{<(X(+2jzsI{m3WkIF%DvQEsnxEd>F$h z6T53eP(AV-zJ$xs(eM8^4wP{#>ZZsX)LvyF+ioLK6O>>KR-o?RiE7?MNDg)m_2N-O zF{P!UdSEI#SdPSGRTzsWF;2h#Mh;Z6Td2r85%w{hhVNo3X=&o)Nb+_A*auT*LVMA^Zb{&8PtSW_!(CguPhbmUEyRKEfRQ1s7q64P1hiI3A;E zh{;%p^YK$;mn@Bk^6*KdKW#e>$9l}iz+?Pp1Pky9T}LH!9o;w%+R+&*Su!fKNk|{s z66}KSBQaP5?!|kUgr7X_{oYStTh7m+=DUPyt|ru;x5?#yJ(z(Gp2yDkcP{l;2GPU3 z(hWt2^O>k7S&N(S7H+|nq@@7kNSE!l9BhMgkzKIG7{dLSir?ZZ*o5k#!Vz8~t1yD| zx)H9|BwsO*$iP*k4eVdk1OsUGG@Od%xD=;j6RI*#(J)B?wgV?|UNPFcei>D#qOaJ9Kzd)HnU(U2g>|IQ~(WV(`U@sdOIpu+d8sOT==X7bIaz{ brX+Xl6ZPQG>9Mr`@*bI)nYA4X7PR;e>i1F+ delta 3106 zcmYM#4NO&a7{~GF8bc@$R^HB>{UuXT!e~b!zKlWjN`<{U!zKDwKK5D~6CVF5L4#5(1a3$(UHla%0=+93eu~-M{ z`EFFe2`n-g!0LLf4RD+dr6(F@2~%$yy0_Yr!&9X3J4MP=g`di(x#0I?Jo5687XF&9l(K z5>(GDMkTZnwf-PeHp*kRuvRey&IU8u}sh(;S^qRuK0mC<}u>DHpoxE3A! z1a)5v@?%%{(AnPiuZP%GzaNK6Xc0QN9#uJauRl169JgIUMR?Pn#}kzTbNF!Z8Pq~^ z@j+&&vu!{H_!(-$BdAJtq5`^(ENKapNe)F~bZxvhu(_y+-b9Ya>QI%~hbrZ9RA6nW zv+qV_9M9@H<1i|)T%_@BHnOKJL#WKza0H-me@BbABdLY2=dLW3(Yy|RdvMI>R z&*q>4Sd7}Z3boK?bnpvQ1<#_^xq|#WSWE#7U{T$l<2wyg+21Pt3+qrDY)5tbA>R(v zLQ$lx1u}31=Hnn-hRUoKb>A`M$A0ERf!y`4_j9~TDEj*HX z7GfDja5L(?a2fS&iK8|MPv)z9t5B7!M!iw%@JakSgZe)dF#DSe%HTGg zQ-g!qeHtD>PRH)ya7^VjrlXpOx_>q9C?D-%%TZ0a0rmCWj9RA!75E=v zmyTwTNLqRzf~rIXa*w@(dAJ)DP$!PW5xf-G%NC#(tj1B;j8pMfRMY0LtA0NT)ugLY zZ`cj~yxH|HoJ2L%pQwOhxN992V->cdj;fUUjm4Ky&9)P@;FqX?FQ5XBW>;-o#E0%* ziTYL@KsDnx{&n{}gDqT0p`I<+gsu1n9j1lHa?mTV5=*chRpS0ncotv|^LaP{>u@xl zM^4oeD3?k-3M+6HI(QUG*tJduitIM(tm3I7$8Bk-1&XjYmZK`P3e~-vkl3ve^}=aK zmasdh0JG^Z2d5yh*h);o9T>zW4D0)Uih&~U#&2;n;qStKQ42Sa9!XmZa;)|jwqxp3 zUI5oorBBc09TH$IT+h7pX41;(HU6t$>17$XZPNDy7 z2BzT}WN+JopW`_U;d|q}@B4Oqn0X^=!GoygYDJy-FSrkT6naOoA5+Zi3@U-HLh7&5 z^)2#l$VWBFJgmi2_#wVPS_<$towC6E^z$ThFTz&Rv(1fxC)=gh1iO!%rF`z6yS_;2J`ZX-tP~gDwbU8HT6uS zU91v!;tt$~MVt${S%=F&k*9NDZCHS3FgV$J$6rJ>Ut+}jqg05yn7@Scum=s&8yBFC z;C1YW)ku5Tc2r{Lk+!m4Q@w;sQTxU$Vqgo)%j*IO$<4`e*}>-d>4EI#k0O(M{0GVi BN(BG_ diff --git a/tabcmd/locales/en/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/en/LC_MESSAGES/tabcmd.mo index 85c42d08ca58183281b31878b73bce0931b545ab..a70f13ba85180c0140ddf6ce63c8246e6e75e04c 100644 GIT binary patch delta 5754 zcmb8y3vg7`9mnw#-UI^}5=ji=Av{8a1f%%iVKF>xMGcPq%ji^ME$TQ0J8H{}PoPwoK}W49KG1d$--=@`DDC&R_kvM$w9L+a?z#8e zbN=Ul{%50m9?skKWM1%kVYl^$e+7BQ48mXbQtRt~@Ao(6RGJ@PKkRj~F+;Efi*Y;- z#+hg_jRSE_~}+|53~Zf{d^3OAKEjLtj zzd}Cde!jHg9jFw4h}yH0Sccl8(c*Mek^Ta;qFZbI$xdbHSq>bD)Wl6R3snXWdxZzHGT5bn1iAG3-tVmJ3k z?nJgYFbBBEr6#;#3VBPB4M%R73sGC)ARluxUj%P9p#s^7+UpNc0UwF(=d%iBwi*@S zWK>3CkxQ{e=f6F7!FfbQxD8btZ=*8vA5?1lGn)b(jx5?-fXcu;)SfRw<~A!)$M}z^ zet$(R=vCBspQE;}fFoAQ{HBr%b(n%Wb`5%fD^L?|K#PBl?!Sa8wvTZ%4(8CS|0Sq_ zUDQIBAzjQ}k6vR3O`2$-ix!V zenT;rYE%)&@Fct$m7(>hjNFUL@b(JwuNU`mL#aH18nB4B704LOtt@K0k;@`Cpx%27 z)$e&!#@>(G-8e!TZ*b%|R87o5i!GJpUn{zW8*GcY8~flhsKEB12K)#$QBQuYG?7KE zWPH@V3f137i|wc%u!m6r>_BbFTd4W;hea757;vGLjze{qkAqUYP9`){H$a5TIhm|}hh71^1ny_t@8Vgu^f9Y(Td z`khI-aXf0PvdALL?U;|-u{S=4eehN6i3hM7euTa7GgPL&!YZBrVKw|m1vh4+0vUW3 zCjigK^YC6&Ag`k`bO`%n>Dl2Qtut^M?b$d9e~U`}%UFn?U;%a;8)mi;E$wsgROUBx zxu9UpwWt^FzybK6I^dJYoMs>X1pA#swy+KrP=H!d2eLb67b@_>*cZ<_Hw?5E6?g)* zRo7vl$To7J0XCz~^c_A=Ek8FRf@2YEM^UDej2ekIKvuplCAb<)RL+$D%1=F|I*=Tg+pql>Q6*J_ARiI$VzR=;H$XJ1)bj8R6bNgzEns_Qo%<5_`-HCq5Ik_tQ`diz6|a z0DIyt?2a#B(3gu>xUhH-mGXSfpi(viM`8jM*g7o7hwyZK9yyujQ|y6Nl)6?v7A;Rk{cnTiE{+LfXbqdN*TT+9)u)d!Bcj2Oe8{N=BrKSnHViL9THdIDdqcZXbROa?z zKYRm~fsasI@;Ry|%-ryPA5LR9*@4KhmxrlehWee@ zhzjg!9Dr})BlsCkzz41fPsKZUF73)I!=jsyB*iR2WjNT)g$B&$jEz!9%wjz*#Ai_h zoO^Yc`V=a_)u;eo!weoq6=CX{@Oa*a8h00t!S|we**yNIg!Xvk6PVZdF5||8hVX^U z(b8UoO3`gmy90}9Z$|~N52xYiSolXLgD2D8gv!WP9Ef{x0=^SDY<{@%`B@wn@G zF}KxOkaQbQe6KYf`?0|u@A?DrhW%`8M2q+my~6pP~Jvv6+B&quaXF<_f}w1!4X4@lMrtu9M8V zHkI{!yTG*-ekSWySYE4Wa+01~VWuWLmCygZzTA8BdGY&~cx>qJU*xeKxl;MgMJ^tD zPf$LE=+h}%-jqqF%5AP{EN3!9^;nr zQ*NSx!y2TqH#-yXm7@LvxZ*01VoiV947*y#8UAsss~oy+xy>TFBN kIlD@?yj$1Qvpqd`MBm)$vK80Y+*navUA<+-+`Ml814ZcKd;kCd delta 4195 zcmYM$2~bs49LMqV3QCAx%q{yr+; zB)*zsCZ^y})Ogd-RR_x{JcgT4GdqVZFp`TDO(rUkezsnO^ljd@?Q^Z=7)N_0G8c0Y zm7%k!4Bf>@45Kjz0|D~SJ}`r6P=}*YGkXWM2Nq)jeut@e6qVxJs1(LBn(A5T;9%6A znS`3qQdIwYQT_aG>(`N3Or3c0PhTdHQQKf9vaDt_Duq)}sb7ZL6T49vxs2*ClrQ=+ z$*6h`Uk(GS`ZNI+Mgw#}tyMm1Mz5n%_X%o^%hACN zsQZqfCUOJ$m`Kv1_H=6jYC;py!G*}jxZl~rG1MAg!w0D$Y}FG{fwe^kpF%A~F{;Bd z-56OsY#(D)a12uyc*3GC052NA%lI9_TK zP=U5ZE}7n_=U+js`E*o(^HFcrM$~S)KZ?03&`x!-^l*%lmFEa$yK?$nE z1@`*as1zPVW#li^41M&j!2PIxTH}LMqc-taY=C8`43(p+lzc-$DL#UF@B%88p+uz) zlTd+l!3Q(5_3_qHYX$1LU8ws`p)yu$>kZjB>MzY2OeO!?6fe=>;6&7n79f){YcU)T zp#nRB>hKO~plD7h4U~?WNS>{aLf!A8gDX&*c?T+hqo^gh)PnqLz;N=TlqaKR8bsY# zgc@L~b)juvZ|nO|0aYV0nR}>#Q#dSC?~WSiRb-XTOjLhsur=;-DUfaR4{8$yIDg5O z>4|!v*!mGFuy5`4D%5k=QGv$smr8a-x-tc*fhVIfv)EqWY}=2bChlIb7wWQg6E+S(YA5nI}4Ac^hK`xm&SRc1w81BSyJcxDiIELV#SPyHE47uhq1wJN* zeC)>{Dv(B;$FE^4%)%w8Kn|labRM;f!`pg)teRpT^&mcpvr&6wA8PH-VFcbpWj3Up z_6Fy_A^dKEr_J}UHOa!~6kl2_Nm? z1=;}{QGWr`7~d3AP-Kfx9ejaNxF4CMIfY{}q9ey9mY`;~2elNZQK^paDI-ikt0Ka;wWe+5uVgWmrykr>Qg+>O2*-hI_kd!xtW z-v5NfsFW_jhCU7!TR+6KwL~}ZR}7M-K^ULQ{}wn7wP#kN#{JEupv`jyTVqT&FOWR! zOMQ%WBX+0m<12_kd>&_^W?qeK1LN!Ab)1R0)C=%^{1~-leje_O12GQWQVL4-YE+6h z*$byIfqJdg&%33_+h89o!r8b6HIq&~$qx2MZRYu?^Pt?;*P@neE2dx-&ei*Wje=${ zjhz*X%Tc>@6Sl(BsO$B6^Zy;Tz!CT^PRBFY3`Y=^?w^5SxE|ARD{A0#n25Jf6N|}L zhFSmi6zbC8VjY}`%E(-Fa2b*W^8+en4?X4Wg{G*$@-P`kU=n_S>^t)%hT<7i02k1~ zd&rzkBJ1mCd^3`QA}Yb=xB&I~Y(u5$HaeKd&dR|jQ1?x>u0jpG7vu2)a%7l?`g=>7 zi6qgyh%vYtbpZW!P8(4|TZ0ZoNzX8~W`Z!x(=~DQNhV3{Ehd=A>g&n8>PN0K#P?HrWk+KBmhJRMSDp>5^H)}6Osrq_ZPtXcuNaPG!5n Lqw9WtU}(sHrMS~# diff --git a/tabcmd/locales/es/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/es/LC_MESSAGES/tabcmd.mo index f0ec35241ef54be0a1bb83628b05fafb9e1f757f..fd50b60f9d8c0c70d9a0f0e97a74588ebb776106 100644 GIT binary patch delta 3143 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 C8A+A^ diff --git a/tabcmd/locales/fr/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/fr/LC_MESSAGES/tabcmd.mo index ebd31ac007c51d5798048f5fa750f50b46d2807d..9ea607fa8b3d440c1b8a2093a7d6041a7c505a4f 100644 GIT binary patch delta 3143 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 diff --git a/tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/ga/LC_MESSAGES/tabcmd.mo index d6eb5def1413be61b0a56e0e840783d48434b6e6..ed083ba04cae1e4107c6590c9925f0c61fb903ec 100644 GIT binary patch delta 3143 zcmYM#53H6|9S86OaS<2ZL~d|}@V@*L3b-ibB@N_)An{MuluVY1W|DXpgeZu_TNW$E zVm3h1Lho$N$ws;`2sLJIh>>l?sBAD)9Jslu>12$ItViw9mx(9w^PIy3w35lVn*;bVv(UfT%3c?jB9=0Q zS!fJvoL#xJ8sEsw|1=Z$i)^ueIi`__KV%|n_LT)|%nj2ynhROuI%Z3rU`qXb)jv!z zmG_wY&oKeFnPen8IGo>L*82hLnP9udIR2i=>}`%>bN|K!9W+$tSN+Az9{rv@_Swth|kbtY03e2DUH@{FXWGuT;Lr zOw=OnEIfgkXfE6NZI0j;Cd0kV_3zN9G}Rgbjbz3rYq@~W@e1~GGOy-UOyJ9yiGRWb`Z%+7dzcEp#%%3zX1T=Wp3zZjW5xsyya^uFZ41<1!i*!A7ujiCzDaLmqZe}o(X(CozrrV3G@^bc$?Sk zHJnn{NMx&-2{zMqm%nf_-{mTf@|S24pI|ck4--gjY@^i6d8PgaCg2yCfZt{^9xmMk zdNUKyrpo#bjYRwk*R#oq`UN*uju_wA>p$`)P4hpFIk&Si^e62M}9 zk=@LD;qSbSXDN|-xn)8l;yRs+@)XaPjEVddGr=I8{JwxW3oF>hEmYO=9FzHR=1}%_ zlQl{wYg|FaESs5m_HksM|F<-(Q7#bv^}L4r`9uDcv(zn_9b)#dw|%lknaXE)Z`B{} zN4rvP<}v<=w{x**I{7ja*r#lKwr~n3SigKr3oLSvX3~MQ|))QZUgIsHJ;T-X0KI0G)-;%)f-#6knSz( zxQ#C|3*FS&IJ|2(P=9OH-^pyzt8^U7yL^m;MVWwi(-U3ZoTmOcl}*A_#WI<>U?uP1 z<6Oob*EzBL9#f$_Te*Hb2XG0K@j523z4SzuH+T#C%xvuW9n5v>*_$uTtTztP0Rw{! zyu<8mPX{5VwS&oE5i`+7F5*dg5K8AP`^x3~3McxS&$Se5Imi)gR`*nRA|GNGSMh_o zM)q#W9B)BB%{}}F#a1?XmQtZ+8|a*tnasj#co}!_N&cC)vdilIc#!>hj05>^IzFY( z4UGh6Fo&^qwMO>pcf6cOSZ=@b&dnb-x9;lGcU=FbB`cQQw|v*owxQ#i&o^tM9=!7V PquSfscMYERP|yDXTq;&Y delta 3106 zcmYM$eUMgF9S87(GK9v8z{(PR$>AePnapuKkFA`@Ygps$ zY+`ri_t>ca5=ZfM=DriWpp<&~k4DXj=7v%(<^pEG+c#V#V-Hm0uFCff610MS7*QuCbP}V9@xQVKE)Qk%&g^` zObI{Wru3(?#x`cp+{z^MHD>&S%s4-<`hR5-fBQW3PlOH9x`ZthTV-gxyzrK2;Z*y4Wde5 zHHRAKGXr&TATwrddzb*9VJ3WmspN4cptoqqGE$l1MHFMbEFEl=E+(Qav^-@OQ;DaU zQoh6l_Bylnrh z$+%fMUr3*yU@y&8&hYyB7^g8A-pG&hE_U!aw(~55XqFD90$*Y>eUu;JL8ekCnHSvo z)9cnlW3gUt*vcCBFc%zhSj0av6{vX`T+Ta~fPTPa)X!veftN%A@1p%#o?rs)WdeVP zt!(s~O<=3)8W~_CEpvI23wW4Yd77QP(_f-w_G>1Pe=((AHp4RUCMMtqnSftlGJcl{ zbe6Oe&@GkQnSkp(8uw`Q@mpMLXT|rJwf^QMrCi5X*v|1zs$N-Nxs$2j0j}gpCV;u3 z`Y5+D?}KOg8UBh%h1t)P6RkPgBWPX6z zl*ed}(&XkES5OhlMrNMfOaO;CC(r+JjVqlPC5>13Dc;A4>XyvD%dFus8oP|OUO(hj zO#fY4jWWwceeC4ToGY3u_z)A=?;SF6qYWUZ(#rYfFQ3!M^ZYb7@F;KNlKCDzKEu`g zFV}Om4U)`%%*Ff*Gw_9Wrd!KOF5$h*lD*0m9BaX|bT=`T-obh@+gp9nM;p1ExoFTC zbZ@zyd$^04=;A8|ckgO8>2I$3cQZ@$ZQ2IqFdybyOu!F_))QS0GMln*vHGiC86(_W zu##)Jg}3u4cXIjC!3zDBxqg^uY%CWt8DGx?*3BgFJa6C|oWgl+gV%L&nEoD4;$v;~ z!AxFsB5V0OX16xj5XoRRGtgRg@+b5ll%{3=8R0T6=h+Td^ID3rJi%$~XDWQQ`hS&6 zxs^X-mTqDFD*rTSe1!-3eTu2v;#o?G`k4tQSjdTN=abyTPxBnJj^bvH;Wjq$LE0{5 xACuVMm`ynTlY>ii9b5E=->FeFf#8fNZ)y#2;A{s(XUOfLWc diff --git a/tabcmd/locales/it/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/it/LC_MESSAGES/tabcmd.mo index 1443fa3421a4d85e61f6c38315b68813f5bd2d76..1f2e3165c173a5cd22d29b4118fced766d464f01 100644 GIT binary patch delta 3143 zcmYM$drXye9LMpm4xA|-K?si$@`x8y@FZ#wii(7Z9F){(=F~Jzis2yYH!o}bp$?OXlGXde^K7vLuix`K=lT7JIL&JtDRmKgalegx{!6y88d;L07ZhT()6%3`Uvt#XyLi zKcFgf9aW)!kYd|IyqS%`IO>(PL1i8!8f`EF)vE$jMvGCU+lcCM4LbNa z>T?&6mo@W8y$!IN=2Lx(Pzk+)4sJzN&OPi8enR#59xB2}qS19CDzIVvaWITps0`aP zL-qCmD!>NR#^+F#yn_m;BjsUfOY+S^Vs&l0H?T5PL{&(8tQJ*?BdAiIM+J5Z)%!M7 z#)+)19%rBen}{5IdkNXwR-)F~hB^}mP=Q>*1bzRT8R&)>cGnI4P??QI9#S?NdH7i= zDu4>q#_LfFeS!|2KvnEIYMo}}Wzj6A079tGPw;&Xd$YeS_b0ZXHaLhn?Pq*%qZW!I zZEZXpwNMyC_yYFFEvO8Spg#W_^0G+B3upjpJ_i-h9CQ`wG6q`k160rU<1RdgRM}=y z*KDl7Nmz$^GPYqR4(5ca1@o{AmZK_HiJfsRM&f2vg?6Cs`z)FIPhfD9iGOhjCr1$u zAsq#fkJ|7i>P&=qjHP29YQqW~f$w4-Hedm&e8gs9-$kf^HlWt8_N^c2dZoC?#ACd1 z7pb-l;PIzQ6Et|2*CM4EShD(Z}s;b`22 zUGZmBAnpwYV;QtyIcAW~A>4FWz;agWvB|~<78Zg>hbqT zP8LDm6krHn#OcTv&$XirbOCsJO;yP zBzxIir0teW+J9mgOEC9wvnO#sDu5Nf8 z>`xS>Sc2+xBWk`CDV}9>Fmz}a;}on#wd@|MGGjQo30Q@0F9shm;5}l5T) zaL{cOs+Z5>UfhZCIF58;@fqxirPv+cM%}jwld&F8;xDL;YjV7Q6OQIke;uw%OvuRb z-eF3|MO+u*D*OsR#ca~l=WZcgu$U+K&je0H%}+%h0al3)*5XV&g~^zd=Y36cu@l#o zd9Ii7Y9@3D_o7dUFutc7mz(IE8jb; zm8dhb3D@CCd<&m)CwZl9L~YcCMjgk|xC0-c=C_5to}NW5^Z@%{TA|s;7{=Ln2V=01 z@1R;U2i2N#9F1#H37$cYmj(Z3kjP*pCq*TirV}%7!Gg_AfnZ(dsG+fuCFM(&Ev@UD YRGSuPA37;3(<@U#p-|oK@QRNA0T>TebN~PV delta 3106 zcmYM!4Um;p83*vQ2D+xpuI$Q!tL$aX1r$^y<3m&owpd%zikOjBCdVDV%n}>>(1{z9 zAK~PLeFt5-=-K! zOIu^1F4pvCRW7NcJbcOC1Q;0}$ce304M%bds~%mlsdjX*AB`j;~`TwaZT zsdAX(j6cAX@psPcZZBs``IqHh%DA`A>u`wsj7BDY&wjN#QCc^*9`1ucHS(SEO0tgtJ%zsmNKbZ z%hY(7HQvu$_cQvGeZErLBh`49RrCAB%!aOJjkhqFt3OmVeoo~szh@#mSoK>(mB4Dg zYP^7%Xpl#D#?*ET6X5rl1)pRx`34ivTQp^9m8LkEVyu^WjYb({BD#UfQ`R$?*v6!C z2NT#UOzjUaJ8m(1YTU~NHiHg+xq{X#*D&+k%AAQUOaQytmFIt-Ms8@bdTwZEc6K(s zo616Z`IRM10Lz$#*Dw=pV2zJ58GMPEXCHlzPL=@1n>5#-UwIi%v3^-u4cyEua36Ep zAFq6!nP`MjeadUT63F3dytCHG#QDtl0PC4>xkhTWmYaAF zWw%U|&pBMke%{W!5r54Y%*jmZXY$?bXEL^k&Af^uxr)imbGd^@UCe?DIh{*6pLg?8zDlu`9_fqonShot^MAJTE~X?u?5(SZ z#;{tw*1N;kfre=6)BxC)|yf^TD zT*o}dJL($eX}rj!{9WF^bJ@*X`AH6OKlA&5*;0}fOeP+rB$dZ0_Ogd_dCZi?8JWim z^sna$`~eflle~!a=QXa^XtABg_+|c<)15GLl~G=cS8_Hl znHoPpdn$XF07t6d3Z6+1Tv<0e6L1qW5nHSA1 zOzF1qgWN?2zO+qmJf`RJV*P$*{&h_4@8#q?|Bq^1W?&D0!Ltut>Vi&0P0W%6|DXkLUP#jqyqJ=$A#T@kTD;Cid_UC9jN|U&^su z#BP3Ke!cN3yvcy_mv1nU{*n%E`4hj&&OVd!ekPDEg&ox-t^A1oV)p#zL^8l~p@Id25^LM5s zc?MIG4muWP3bU~lbgar|Cey!RGSmFFM!9NeXnj-b*zIFaoZ7y9Y4@E|w)YHt?3n)n DlZ`~< diff --git a/tabcmd/locales/ja/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/ja/LC_MESSAGES/tabcmd.mo index 5e0003520f9823800bba249fe48ea0de2f0a67fd..da0401cbdf9f2bb20a44789284aeebb620c51769 100644 GIT binary patch delta 3143 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 F_z%1^Ru=#O diff --git a/tabcmd/locales/ko/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/ko/LC_MESSAGES/tabcmd.mo index 2a7894f0c7357a00e0ec80b56ee1aa349e0a79bd..cb3c511f2c85ee6e197f9c0fc7818625f8052faa 100644 GIT binary patch delta 3143 zcmYM#53H6|9S87(0cFBXzgE3C4K zTk7s%qy9@Az$46aC)w)u(!YQ0!Lc0c!dzy;Z*Vvts$btn50qDV5l^v={TgZuT*^=C zU&AD_j1_*Dd2U;M{5hTrgu|>~PS$T|kzOXA%uleB3Fr0irf&Y$;)-SJVB;w;tWDUNuV1;?0gJZam6@H7^lFdx1_tpD{ zD5ml*^ZZ#R;5L(tWIIQ25wqS}Rx`nmHO6rlliA-nnhgVM6SUJ%nOE;GVfOIO`uGp( zZefe@oy?xU$W-V}rb4Hw*yVf|r?9zE{Uu!%8pwo8nau8H&cH()!rdIjLrjTJF(qvB zQ2LWu;X>xjtYQ-SAv6C$W}d_K{=b>T`wUY5MA)iMm$99KEK8XZu4YRA2y-T$rB6BL zD--rLOEMnL^rx`G&r^)$E+&x;%zfMGQx4XBBlWKsILTz*ESfBEIkQ)tOh&gerMsWm z<1MW43Ff{()2E#9mA!4STE@rLozEonbym2Msa$n;z40=$$L}){_7P3`txRAOd{sDy znP?f$Wyb97b|%0lnT7wvRPsG0p!1Z+)TOQNl@x2WET}cgGA5#XXnV@fnM&+sO8F8K z*b!#$&oUXenmv2m&IC4#4t}|n)-G$9c{VX;VmlMas~nQw{|SveFu>}0U<8xdGZ%xV8) z-FKOZ8l|0uCovPv;dp+9m+(O*!@bP?|DaFlQ>g_sk{Q363FwQgCeoD}neaYl&$jVL z+|OM9g1UZ|D|s__@lv)pnfcYsWVT=x^XFrIy}yB};AVb^zhTbG6P&{R!_|ML#%Tlp zVTY5GOs4wU#4odxr|zponV;g@%sj25 ztF^tG?{#;DffW=>d5kIb3(Q1EID;SdGFZ%cypq3Wd#*DTy4Xu%HWzUgf5~M09<%Tn zCXk6JjDlasWOH}JPS%KiL>4W7iCC&-GM_&NTIic&hv9=rKzKEPam zj-O$Zhx7abUkUs>yn{cj^{Zvj<+T^aMCK4KWPbn4DVcH)Rjuq`-h8hy_Z_XR&y9G(NL8#i8=jU z%nje;5dMm(&@=o!KVXHsudW@wSD3ANn-}l{HnO+0vn4HjlI_fvzR%3x)}j6xnA%Z$ zb9J*#|6$(AJ-n9_uC7lEzK9+|qNrp?T*=`i&ddr|WCWSFYGOtnKi) YhI7rz=rt3+IePr~@jDOAU3uRB0702s82|tP delta 3106 zcmYM#f2@~P9S873GQAG3C|m@*{PGRsded>n>^xaVWZTCOSf8W#7`~TnH`;~IO?osw<(^;joaR>*ogClqyYh2C2 z?5+F>Tl9DETpnQVJHp|m)XT>jH78n|OSzcSm;qOC6xXuGr|5?A1_$sRj^szo1jEiQ zWgI6mi7aA`-(v3jadrMzJQWDr%wLXF7n~`*3_O+>v4aU{8Qa*)^Y|Py(H;)rF^Zuy zpVOGAl{NjTl{Z!A?_kD%hza~>Y%zcNokk*llZoskGvPTpxnUA7WG8F9jaicQOsSu$ z`a3C>a*(^Yy>i$>0igJ;qvPI zU6s8Y>ilMANwzZ;+Q(GrT`G3@H>a_wMg1jPI$fOs7ciN9iP-~d*~%x`&YjF!zQdI8 z3^%1emNj-Vd*)Uqp&n-ZZOk~YSN*q`#6K9M{)wd@CG2KOzmC}x&(o*; z#UTS8XEGjOwDiZb#;YjCvXV*UZsxj8^eNja_on_eCyp?gH;E<_jAquVgUM(KQ@SL!WZkA!~cGI^Sy6e18R#(9Nvzdral(PgadrXt~SZmav-U@sjGK*~HEw4DyNot|xsm29tC(@V&+Lg!OaO1NHP8QHjoi@3?73keli4No zZYo{$@+&tn0o=+=d^a=DgRJrAOa=Eb;~b{XslgJ!2!rPODV5jqeDjx;)rs#i6Fki9 z_Fq;WWCrRh?F=xAmv9=#a21nTFLT{X^eKOKNFX0o=Lgpsm6*bupT~LzT&|I|TEmUp zz+5mCu`idNP!i9O9v@nvS5W2~`# zY`v7vXw31t6IA&&v$mU=fqu!n#H>S;3V2QO@9te1RWwEuZ&Gl<%jj{{r5?4Dc)y$PQ-hPjDs&O=x7g zkkj>hn1Ehm5|J%hGG>1Ha@ORi;~eAUJpX44Kc$$(-CV;hoTIMxNjc6_yWKjav|ZfE z^~~P*f(?|3e#F6jJhr@1|MxaZuD`IOv1htDLjQ3pV%f!u&0mgbB;uO7t>A2~;6*IDDG7WQ+T&jk1YGw`dN%@e$uGh}x?dpMj2nZ58I)>WaLX$xof&tNWC z%2w8?x@9A`b1!SW@3W1~w}n}nm)Vbd*}^|DOY%NnWV144N%t`0AFui?v((@ID>G*` z-dL;o4gK}}0nfP7?*Mz5K*mTn8Q#ET(8IZWkO}xrw((vq&NMriz(dpN>EKgYLef0d2%8f&|sx$d;CQXbLl7UDd8_&w(R~s{fBHFa@K@_TbGP{Wy02lUDtf#e`PpN AO#lD@ diff --git a/tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/pt/LC_MESSAGES/tabcmd.mo index 808044198898b3d9c7858b0d090fc91fb11c9e34..3b4d6b0803f5679fa803f24cf0ca61d747ae8081 100644 GIT binary patch delta 3143 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 ChDNFY diff --git a/tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/sv/LC_MESSAGES/tabcmd.mo index a8f6cf7890ee4389d2870dff33cce2d928ed531d..3b6caa28355b263e01b19f9770651e97e8a8c21b 100644 GIT binary patch delta 3143 zcmYM#d$3kj83*7caR}^i5an_J>Fk3778ex=GKdgF0<}UTnouGo8yN}{g#_YL)EUYY z0m&S*7#X@SLs?uV(3~=jE`y^4BM#BU2J0VeERkUf?fLQTnV8Lf*4p3RYrXHg*4}5| z`m?rfIIHoebGvRT{ypRW`TnFSfUq(#eb1m$Ud@E?~t5`*U;c z&)7%*MfT<~=DCv`?Do>LXY;`k9N~wnnE}7TA$+9%eJ?#wj__QbVh3B>niGuV`}Hqp z5?RcOUt^xzR$u=O&ji9w^OuwL4FjZ?fhX{NoW%rmJCpHd_T#h6M6a-&UC${+EM+h= z(Fj(YS-Ysdem^t*51GK9W*_sHKWZf6H<-xUoHAj>JTR3PaSki4W|ri;OsV(Q{R0$J zInF$PnhChWAVWEx7w~#!zPs4S0FP^o;w~n$zi~L*&T9@Zo-UPZ>iz;|4VTx~AE@2T z0j}?0)_gxxp;ws-{fCNOdiZe?+xw`$q{|!^GT_ZjW~-Pz@CXNSH;3^6Q{q!h3Hy5} z{Ryl%huJgBn1mi>#^1+`bGYum$t2#=PyG|&V0F5f<0;5;GgHD9OzFSP?1|^;DF1ZI zfZdFejE6A&Nv!y3im}|uB=R70-*!66zS=*h{*?=u1rL)-!9o znH8U8?t6)ja>6NV+h(?0A5r^pCZVOQxQVG;V|U#+$gJ_dmWsJ)D0ZItVpjk1`D=ssGWvW2O{9;TEpGJzdq z*8Vh;@nEB8jmI;A&7h56ZlSr$N@kpIGJ9e>6UY$`%KLvpBMQ?XZ>aZb=t&M{a57|q;2z4o&lX#R3%ec@qdf*&!v{nxd} znSuI9I}?v#2D*x)`FUQ*hnWobF!%qRj?z*!0~*R)pTYz*pN&L%heif`h*`63e2mX9 zYxx;kh->tubUATrlcpvjYS~o=fFVWcL!co4) zWcZv}m-8qma*p(}2iDV3zUP!B`#n>sqr943jXIOFnG7GJ;+3B=oAV`_qWpzP;9bKS z&D}Z5D3`i0i^+HuGvQ{Ygu8ed4{^3 z7Jtc-z%XVrFJLOvSgetO?%|jDEVppn$WpfQFf;IKJL?*5<;VDMdIQT;J21}Y2e^Xy z{Yj4FJIoS{^LfpL*YQR!qRKYPevJ%poOykE*bu#VK2zF}%1P1!Wu0_=O3Gdy;LE(7+muDKbl5P8RzArjw1z{?U%sO;kN0fimAj{omAjjW=X!zJpT(`&bQggDIZe*l=?=ERNyvxGs-3o;8U!4 zh{i5&aThNZZ99*#C*NjwwoYn(2l}$Ne#HbdhWB$e^W4$ewXlx?OKGPuuiH{) zw{PTfp5!_%nQTAs9VWw(A8AgwkXETIVFG`GgZMP(@i3F%xGAN`q0D7BZkW<&PWY$` z16|m|1ay!Ypu2kI!3&vzX7Cf-!rcERvsZdeZC2qH9olZBW{GYGmTqnT&hPbo$)Fg&W^!Yv0kmb<}w+U$||_9k=f2?6_fg+nHuH UeC4HI9X@*W=pA#fytT{!0OPGsMgRZ+ delta 3106 zcmYM#e~j049S86?N_c?BDPSC&!ROEpP@tqP;tmzXJH%#{=T>R|ud$!+!gL3x&pQA%d8RPUATiA4ZDeY|KS?uCi&S%Bd z9L4^ITR77Bi#(J2nfs3L6Q$J3M+TJ(ZOx^e&zVfX6&%mCthkkKD0?}a?{FNCGZUOW ztd#S30aM5lR=k6`@3F@9=Xo*_wwu2kX?$U@@)CFgC$Wo3Xc^nt&yVw2W}@G+mH(z3 zO7j`@iP~5>pV4qpVG)Z|6w!m){#CjuG`lE@aNuqMu-!EngTFQ#wWja@Tx-oc}mb?6&$?(0#d9$pN zSmjW$n+ddpCo5ytb`z7}HfF*Xm`=XVB=jzYEG^m;CsB^IGP^z~OPGvqr{yUdm`?nV zY2}MdV*8o3KgLwtEPB?sgGp>UZTzy3<}5ccaqeOE#3m+zy==?#f5;#=3^03c7{OFF zmEKKd9=-g^A|`?5%*1yyfgWMSpD-QV$HX~ApOe9oz*s@^{mzD8~SG2-DuV|+{JEAR$kVA1yku=4q2)vm=5jYT>g!7I8pSp`s>uRaxb$fx6l-2H&ei0 zY1PZXj+!bB+C@vn*Dw>VVOqGJGq{~SJj~B=ve%% znC6fUFJ?Non)&-FiTJ(JLF%>FC)8O(O!8UBjzvX9SO(28BwLr!He z(~4_14b1(I@DlE4J4bcZJ3WK7JQi~dlF`i^ z&4*ZVJH;-q@Hr0Zu0N(fW3%)9Y~tG-!lOKsA210Go~c`$$X4!Z_zE?z9GZ|r?Dkb$!&mtLdoS|H@inHxQ!lPh*v&k4y-ebFu#FqIm^+vPht9H$oXSC5$#J}8 zR;~Uj>~|p@o6kErhI^U4a+vAR_Dkz8qC-rA(`={~u44Acom|Jw z{0669R)4{5t{EiYTl^7^^V{6oQ@?RaZ+-K9iD~INKEWUG%e?aPdds(Pg!30Tim$Sp vhnd30Us2yH3z+%(nL?Yk8I&8AE!!}lrFCcP=~G7Ryl&i_2|Ew;&N=0O(^p3L diff --git a/tabcmd/locales/zh/LC_MESSAGES/tabcmd.mo b/tabcmd/locales/zh/LC_MESSAGES/tabcmd.mo index ff3767c3a6a425f366c615f9104fbb8a8377ced6..42edf09996f073a6bd78425e3faf29354e2c7e6f 100644 GIT binary patch delta 3143 zcmYM$4@{L+7{~EP1C)hVQH1LsLnkjD##TRJz7ys7)73 z^ABc}b1fTD zZb995$c>-Ea3Yw@{C3w}Fo@+Ta5g@UGf@e>g<5ev#^d*>i7sFeBl?+s4e*fRqCUze-6pXZlLb( zMkSm?kP(=L!*Ky>zKs}CfRAa6!e-RU{=_s44DbVFAw%}O>n}#_;aWGo%~_9w7;i%D z`Ol~dT}4&s0a9#>=Epn?#!-J3ZAA$GZ5^-UgUW0=TUpyiOMjNY}8LgB{qgH4`-nQm0@^g zsJ(4KCHO6B;?t-~-b5wTlkyPSlAJk6t|6P}H>?bm(I#Yj>;S3~M^L3ai%RSoYVW&I zD^4W3_Bacb*mKCiw^C$oTaSwK5$a4dpc1)=L-hQ2(a;UC%&r@TqgFNvc}dwq@ImvZSapN;kPt&{<>OYP~6$4*mBP!r4oS+hX z7sumu)C5CWrdFE4m$qgu>P1zIlkq*w!c(Xf{)-u>RxzMN z_MrCgC)ABsP!n|FlbFc9D4}_%iqs%K*gRDYT`;%BKwh#eHn5C zzq)}xPzm(rt)oCga4pWp`Phz1EScFRU^XgX8HOi71>TQJxE-~%58Ze?@Aqi>lTi1C z3TRBCQG_M912^IWJct|kCr~R)$uOIP1(=JwQHSZgvlBI8KTe>2pN=|=)qJVcji|GB z1`F^n91Cl}0G>s?53V@xpq`rO(Z0#33gn<(L`zT= z+vNIns0tqokF)>hXehJmn1he7u_tgMma0G25A-^cwAG>}IEFRYffUQi*)O>lTk!-I zVl@Xr_nmQeqaNdQ_AizBZ7K}~EJbBpi*vCVU&LP2bviCU=CT8*68?s|Zx}~DTyj(; ztI@;#7)}(munv3*le7Jb%t!rq%_?Zrwy?XiQ{A1|ODtG`iu z89UMcpGz?Y>DS>8_zg0LRWcj7TQlmuTc||hp7AT3iskeR@da!R(O?^`Z@wRJ8g8av zjO(!jRiUN4-Z&1n1xI5W4#S)H8TOe%m9Pd)OIts-DlIcJvuV-fMLqum-bqL2 delta 3106 zcmYM$eN5F=9LMo5$_z>#x` zPBy0WAZ0lz!7Yp>)e;{vm(z_6(?80GY7#laKTMrYquw8WXNz6#>zwoZopZkDd(Q6% zySGJkMWVu&0?|8-pTqo)f0Y;b;# z$<&YH!*~wWuMbC=h3y{-9t|0BW{+VZYQSpD!U%fUigd8k7{IHTiT64#OH?JB5k354Ezhn2Q6b0dkW3KxU!pC8#}I?b=^=HsA=_ z_oBAsFe*bms0>|0l5Kaf5Mz?bKZ~__+^qqZqgM73>I_6M16wc$kE8bTDk_B!&`I@N z^l%>P%v7Nk^bTtLPSiL*y80E=!f&OJe?=I_vL<5=5}YkZrSL^m>g!Qw;w$81m-*6w zw^1t&Fq-NU(8GmDjJ5`~kj<$3nvsunI=hvBkA^p;k5tc{kb9 z$ji@GpaQ5uO}rU3P!oE15S76m)HuD!XK*kDFq%Pif6%!E)0yAaxQ4B$2|hxd_CwB# zsDYwcwg$+;Nmz)F;#$Tku2NiQ0mE z^7%L}z#@DV)&30a(t{bJM2fY zjt1@BUR1|Js0q$s5O1Oa%41)YkqV^AcHrQ90kxvbsQUtR){5t&CN4n*Qj2`-O;>LX zyM|6w0GCk%-N08co43yjY(@ok2d7~?vueP(I5+{)#cELjH>0-ptZVPbSn4Uf-_L26;W7u*i=<%C_I)tVE1*=Amg>A)n{0#LTIOIHydRl&U-a%y`akBpcnt{q# zxvOtLWq6ls-;e2f{*O>7;KI-N117VRWN{(+Pp4rO4Q!8X!T`3T_UL=m zUjB)EEI7;G!wqEw=Z1t#qCsBc1LuL3L*5KILX3MYZQ36u-cgxNMI9^t59V_2Za|=TU)OM=dOGt{-3pYJu-LW7;U# bs>;g7sD!kRwBZwzIw~@kW_4UCo-yP<1Y1Fr