<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki.3dtank.net/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3ABatchUpload.js</id>
	<title>MediaWiki:BatchUpload.js - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.3dtank.net/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3ABatchUpload.js"/>
	<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;action=history"/>
	<updated>2026-10-14T04:28:57Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=21031&amp;oldid=prev</id>
		<title>2026年10月4日 (日) 16:18 Wiki-editor-3dtank</title>
		<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=21031&amp;oldid=prev"/>
		<updated>2026-10-04T16:18:54Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年10月4日 (日) 16:18的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;第1行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第1行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/* Wiki 批量上传工具 — duplicate-archive 白名单补丁&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * 替换 MediaWiki:BatchUpload.js；基于源站修订 20890，仅改变允许自动确认的警告及对应文案。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * 自动确认仅限 duplicate / duplicate-archive / exists-normalized，且须启用界面复选框。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * 第一次请求不忽略警告；确认时必须有 filekey，并再次检查目标不存在。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * 完全同名文件、说明页及共享文件仍会跳过；其他警告仍需人工处理。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * 不恢复或清理删除存档，不绕过上传权限，不向外站发送文件。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; */&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;(function () {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;(function () {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     &amp;#039;use strict&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     &amp;#039;use strict&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l97&quot;&gt;第97行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第104行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;lt;section class=&amp;quot;bu-panel&amp;quot; aria-label=&amp;quot;批量上传文件&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;lt;section class=&amp;quot;bu-panel&amp;quot; aria-label=&amp;quot;批量上传文件&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div class=&amp;quot;bu-heading&amp;quot;&amp;gt;批量上传文件&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div class=&amp;quot;bu-heading&amp;quot;&amp;gt;批量上传文件&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;p class=&quot;bu-note&quot;&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;内容重复、同名不同扩展名（exists&lt;/del&gt;-normalized）可自动确认；已有完全同名文件会跳过。大批量任务建议使用电脑并保持此页打开。&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;p class=&quot;bu-note&quot;&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;内容重复（duplicate）、与已删除存档内容重复（duplicate-archive）、同名不同扩展名（exists&lt;/ins&gt;-normalized）可自动确认；已有完全同名文件会跳过。大批量任务建议使用电脑并保持此页打开。&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div data-el=&amp;quot;message&amp;quot; class=&amp;quot;bu-message&amp;quot; role=&amp;quot;status&amp;quot; aria-live=&amp;quot;polite&amp;quot;&amp;gt;正在检查登录状态和上传权限……&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div data-el=&amp;quot;message&amp;quot; class=&amp;quot;bu-message&amp;quot; role=&amp;quot;status&amp;quot; aria-live=&amp;quot;polite&amp;quot;&amp;gt;正在检查登录状态和上传权限……&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div data-el=&amp;quot;drop&amp;quot; class=&amp;quot;bu-drop&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div data-el=&amp;quot;drop&amp;quot; class=&amp;quot;bu-drop&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l108&quot;&gt;第108行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第115行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     &amp;lt;label&amp;gt;API 请求启动间隔（毫秒）&amp;lt;input type=&amp;quot;number&amp;quot; data-el=&amp;quot;gap&amp;quot; min=&amp;quot;0&amp;quot; max=&amp;quot;60000&amp;quot; step=&amp;quot;100&amp;quot; disabled&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     &amp;lt;label&amp;gt;API 请求启动间隔（毫秒）&amp;lt;input type=&amp;quot;number&amp;quot; data-el=&amp;quot;gap&amp;quot; min=&amp;quot;0&amp;quot; max=&amp;quot;60000&amp;quot; step=&amp;quot;100&amp;quot; disabled&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;label class=&quot;bu-check&quot;&amp;gt;&amp;lt;input type=&quot;checkbox&quot; data-el=&quot;duplicates&quot; disabled&amp;gt;&amp;lt;span&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;自动确认内容重复（duplicate）与同名不同扩展名（exists&lt;/del&gt;-&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;normalized）警告&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;label class=&quot;bu-check&quot;&amp;gt;&amp;lt;input type=&quot;checkbox&quot; data-el=&quot;duplicates&quot; disabled&amp;gt;&amp;lt;span&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;自动确认 duplicate、duplicate&lt;/ins&gt;-&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;archive 与 exists-normalized 警告&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;span class=&quot;bu-note&quot;&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;exists&lt;/del&gt;-normalized：站内已有同名但扩展名不同的文件（如已有 X.jpg 时上传 X.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;png）。完全同名文件仍会跳过；不修改已有文件说明。&lt;/del&gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;span class=&quot;bu-note&quot;&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;duplicate-archive：上传内容与曾被删除并进入存档的文件内容相同。允许以当前目标名重新上传，不会恢复或清理原删除存档；不应据此重新上传因侵权、隐私等原因被删除的内容。exists&lt;/ins&gt;-normalized：站内已有同名但扩展名不同的文件（如已有 X.jpg 时上传 X.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;png）。完全同名文件仍会跳过；不修改已有文件说明。目标名称本身曾被删除的 was-deleted 警告仍需人工处理。&lt;/ins&gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div class=&amp;quot;bu-fields&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div class=&amp;quot;bu-fields&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     &amp;lt;label&amp;gt;统一文件说明（维基语法）&amp;lt;textarea data-el=&amp;quot;description&amp;quot; placeholder=&amp;quot;填写真实来源、作者和授权说明。许可模板需使用本站已有且确实适用的模板。&amp;quot; disabled&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     &amp;lt;label&amp;gt;统一文件说明（维基语法）&amp;lt;textarea data-el=&amp;quot;description&amp;quot; placeholder=&amp;quot;填写真实来源、作者和授权说明。许可模板需使用本站已有且确实适用的模板。&amp;quot; disabled&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l559&quot;&gt;第559行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第566行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (typeof upload.filekey === &amp;#039;string&amp;#039; &amp;amp;&amp;amp; upload.filekey) { item.stashKey = upload.filekey; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (typeof upload.filekey === &amp;#039;string&amp;#039; &amp;amp;&amp;amp; upload.filekey) { item.stashKey = upload.filekey; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var keys = warningKeys(upload);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var keys = warningKeys(upload);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             // &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;可自动确认的警告：duplicate（内容重复）、exists&lt;/del&gt;-&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;normalized（已有同名但扩展名不同的文件）。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             // &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;只自动确认以下内容重复 / 近似名称警告；必须整组警告都在白名单内。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             // 其余警告（完全同名 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;exists、曾删除 &lt;/del&gt;deleted、非法文件名等）仍需人工处理。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            // duplicate&lt;/ins&gt;-&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;archive：内容与已删除存档中的文件相同，不代表当前目标名已存在。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             // 其余警告（完全同名 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;exists、目标曾删除 was-&lt;/ins&gt;deleted、非法文件名等）仍需人工处理。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var autoConfirmable = keys.length &amp;gt; 0 &amp;amp;&amp;amp; keys.every(function (key) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var autoConfirmable = keys.length &amp;gt; 0 &amp;amp;&amp;amp; keys.every(function (key) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 return key === &#039;duplicate&#039; || key === &#039;exists-normalized&#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 return key === &#039;duplicate&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039; || key === &#039;duplicate-archive&lt;/ins&gt;&#039; || key === &#039;exists-normalized&#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             });&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             });&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!run.settings.duplicates || !autoConfirmable) { recordWarning(item, upload); return; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!run.settings.duplicates || !autoConfirmable) { recordWarning(item, upload); return; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l631&quot;&gt;第631行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第639行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             session = run; busy = true;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             session = run; busy = true;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             notice(&amp;#039;正在处理 &amp;#039; + number(pending.length) + &amp;#039; 项，并发上限 &amp;#039; + settings.concurrency + &amp;#039;。&amp;#039; +&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             notice(&amp;#039;正在处理 &amp;#039; + number(pending.length) + &amp;#039; 项，并发上限 &amp;#039; + settings.concurrency + &amp;#039;。&amp;#039; +&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 (settings.duplicates ? &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;duplicate &lt;/del&gt;与 exists-normalized &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;警告会自动确认。&lt;/del&gt;&#039; : &#039;所有上传警告均需人工处理。&#039;) +&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 (settings.duplicates ? &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;duplicate、duplicate-archive &lt;/ins&gt;与 exists-normalized &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;警告会自动确认；其他警告不自动忽略。&lt;/ins&gt;&#039; : &#039;所有上传警告均需人工处理。&#039;) +&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;#039;\n不要关闭页面；如触发限流会统一等待，不会通过增加并发绕过。&amp;#039;);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;#039;\n不要关闭页面；如触发限流会统一等待，不会通过增加并发绕过。&amp;#039;);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             flushRender();&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             flushRender();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l673&quot;&gt;第673行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第681行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         function exportResults() {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         function exportResults() {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!items.length) { return; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!items.length) { return; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var columns = [&#039;队列ID&#039;, &#039;本地文件名&#039;, &#039;目标文件名&#039;, &#039;大小（字节）&#039;, &#039;本地修改时间&#039;, &#039;状态&#039;, &#039;提示&#039;, &#039;错误码&#039;, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;已自动确认重复&lt;/del&gt;&#039;, &#039;目标页面&#039;];&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var columns = [&#039;队列ID&#039;, &#039;本地文件名&#039;, &#039;目标文件名&#039;, &#039;大小（字节）&#039;, &#039;本地修改时间&#039;, &#039;状态&#039;, &#039;提示&#039;, &#039;错误码&#039;, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;已自动确认白名单警告&lt;/ins&gt;&#039;, &#039;目标页面&#039;];&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var lines = [columns.map(csvCell).join(&amp;#039;,&amp;#039;)];&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var lines = [columns.map(csvCell).join(&amp;#039;,&amp;#039;)];&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             items.forEach(function (item) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             items.forEach(function (item) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l747&quot;&gt;第747行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第755行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!info.rights.includes(&amp;#039;upload&amp;#039;)) { notice(&amp;#039;当前账号没有 upload 权限。站点脚本不能授予上传权限。&amp;#039;); return; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!info.rights.includes(&amp;#039;upload&amp;#039;)) { notice(&amp;#039;当前账号没有 upload 权限。站点脚本不能授予上传权限。&amp;#039;); return; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             ready = true;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             ready = true;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             notice(&#039;当前账号：&#039; + userName + &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;。duplicate &lt;/del&gt;与 exists-normalized 警告默认自动确认，并发默认 &#039; + CONFIG.defaultConcurrency + &#039; 路。建议先用 10～20 个小文件测试，再添加大批量文件。&#039;);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             notice(&#039;当前账号：&#039; + userName + &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;。duplicate、duplicate-archive &lt;/ins&gt;与 exists-normalized 警告默认自动确认，并发默认 &#039; + CONFIG.defaultConcurrency + &#039; 路。建议先用 10～20 个小文件测试，再添加大批量文件。&#039;);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             flushRender();&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             flushRender();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         }).catch(function (error) { notice(&amp;#039;初始化失败：&amp;#039; + error.message + &amp;#039;。请检查登录状态及 API，再刷新。&amp;#039;); });&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         }).catch(function (error) { notice(&amp;#039;初始化失败：&amp;#039; + error.message + &amp;#039;。请检查登录状态及 API，再刷新。&amp;#039;); });&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}());&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}());&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key wiki_db:diff:1.41:old-20890:rev-21031:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Wiki-editor-3dtank</name></author>
	</entry>
	<entry>
		<id>https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=20890&amp;oldid=prev</id>
		<title>2026年10月1日 (四) 09:12 Wiki-editor-3dtank</title>
		<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=20890&amp;oldid=prev"/>
		<updated>2026-10-01T09:12:32Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年10月1日 (四) 09:12的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l357&quot;&gt;第357行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第357行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 });&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 });&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 if (!name || /[\[\]{}|&amp;lt;&amp;gt;#\u0000-\u001f\u007f]/.test(name)) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 if (!name || /[\[\]{}|&amp;lt;&amp;gt;#\u0000-\u001f\u007f]/.test(name)) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     throw new Error(&#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;分类请每行只填一个名称，不要填写 [[Category:…]] 等维基代码。&lt;/del&gt;&#039;);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     throw new Error(&#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;分类请每行只填一个名称。&lt;/ins&gt;&#039;);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 if (!categories.includes(name)) { categories.push(name); }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 if (!categories.includes(name)) { categories.push(name); }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Wiki-editor-3dtank</name></author>
	</entry>
	<entry>
		<id>https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=17501&amp;oldid=prev</id>
		<title>2026年9月12日 (六) 12:47 Wiki-editor-3dtank</title>
		<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=17501&amp;oldid=prev"/>
		<updated>2026-09-12T12:47:10Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年9月12日 (六) 12:47的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;第1行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第1行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/*&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * MediaWiki 批量上传页面 v2.0.0&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * 保存到 MediaWiki:BatchUpload.js；不要加 &amp;lt;script&amp;gt; 标签。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * 保持原入口 Project:批量上传、容器 #mw-batch-upload 不变。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * 10,000 项队列 / 有限并发 / 分页 / duplicate 自动确认 / 限流退避 / CSV 导出。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; * 仅使用本站 API 和当前账号；不保存密码，不将文件发送到第三方。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; */&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;(function () {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;(function () {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     &amp;#039;use strict&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     &amp;#039;use strict&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l36&quot;&gt;第36行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第29行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var root = document.getElementById(CONFIG.containerId);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var root = document.getElementById(CONFIG.containerId);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!root || root.dataset.batchUploadReady) { return; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!root || root.dataset.batchUploadReady) { return; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             root.dataset.batchUploadReady = &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;2.0.0&lt;/del&gt;&#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             root.dataset.batchUploadReady = &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;1&lt;/ins&gt;&#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             mount(root);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             mount(root);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         });&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         });&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l52&quot;&gt;第52行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第45行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;#039;#mw-batch-upload .bu-panel{background:var(--background-color-base,#fff);border:1px solid var(--bu-border);border-radius:8px;padding:20px;min-width:0}&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;#039;#mw-batch-upload .bu-panel{background:var(--background-color-base,#fff);border:1px solid var(--bu-border);border-radius:8px;padding:20px;min-width:0}&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;#039;#mw-batch-upload .bu-heading{font-size:22px;font-weight:700;margin:0 0 4px}&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;#039;#mw-batch-upload .bu-heading{font-size:22px;font-weight:700;margin:0 0 4px}&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            &#039;#mw-batch-upload .bu-version{font-size:12px;font-weight:400;margin-left:8px;color:var(--bu-muted)}&#039;,&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;#039;#mw-batch-upload .bu-note{font-size:13px;color:var(--bu-muted);margin:6px 0 12px}&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;#039;#mw-batch-upload .bu-note{font-size:13px;color:var(--bu-muted);margin:6px 0 12px}&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;#039;#mw-batch-upload .bu-drop{padding:22px 12px;text-align:center;border:2px dashed var(--bu-border);border-radius:6px;margin:16px 0;background:var(--background-color-interactive-subtle,#f8f9fa)}&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;#039;#mw-batch-upload .bu-drop{padding:22px 12px;text-align:center;border:2px dashed var(--bu-border);border-radius:6px;margin:16px 0;background:var(--background-color-interactive-subtle,#f8f9fa)}&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l104&quot;&gt;第104行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第96行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         root.innerHTML = `&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         root.innerHTML = `&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;lt;section class=&amp;quot;bu-panel&amp;quot; aria-label=&amp;quot;批量上传文件&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             &amp;lt;section class=&amp;quot;bu-panel&amp;quot; aria-label=&amp;quot;批量上传文件&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div class=&quot;bu-heading&quot;&amp;gt;批量上传文件 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;span class=&quot;bu-version&quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;/del&gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div class=&quot;bu-heading&quot;&amp;gt;批量上传文件&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;p class=&quot;bu-note&quot;&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;内容重复可自动确认，已有同名文件会跳过。大批量任务建议使用电脑并保持此页打开。&lt;/del&gt;&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;p class=&quot;bu-note&quot;&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;内容重复、同名不同扩展名（exists-normalized）可自动确认；已有完全同名文件会跳过。大批量任务建议使用电脑并保持此页打开。&lt;/ins&gt;&amp;lt;/p&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div data-el=&amp;quot;message&amp;quot; class=&amp;quot;bu-message&amp;quot; role=&amp;quot;status&amp;quot; aria-live=&amp;quot;polite&amp;quot;&amp;gt;正在检查登录状态和上传权限……&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div data-el=&amp;quot;message&amp;quot; class=&amp;quot;bu-message&amp;quot; role=&amp;quot;status&amp;quot; aria-live=&amp;quot;polite&amp;quot;&amp;gt;正在检查登录状态和上传权限……&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div data-el=&amp;quot;drop&amp;quot; class=&amp;quot;bu-drop&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div data-el=&amp;quot;drop&amp;quot; class=&amp;quot;bu-drop&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l116&quot;&gt;第116行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第108行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     &amp;lt;label&amp;gt;API 请求启动间隔（毫秒）&amp;lt;input type=&amp;quot;number&amp;quot; data-el=&amp;quot;gap&amp;quot; min=&amp;quot;0&amp;quot; max=&amp;quot;60000&amp;quot; step=&amp;quot;100&amp;quot; disabled&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     &amp;lt;label&amp;gt;API 请求启动间隔（毫秒）&amp;lt;input type=&amp;quot;number&amp;quot; data-el=&amp;quot;gap&amp;quot; min=&amp;quot;0&amp;quot; max=&amp;quot;60000&amp;quot; step=&amp;quot;100&amp;quot; disabled&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;label class=&quot;bu-check&quot;&amp;gt;&amp;lt;input type=&quot;checkbox&quot; data-el=&quot;duplicates&quot; disabled&amp;gt;&amp;lt;span&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;全局自动确认内容重复（duplicate）警告&amp;lt;br&amp;gt;&lt;/del&gt;&amp;lt;span class=&quot;bu-note&quot;&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;不自动确认重名、曾删除、非法文件名等其他警告；不修改已有文件说明。&lt;/del&gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;label class=&quot;bu-check&quot;&amp;gt;&amp;lt;input type=&quot;checkbox&quot; data-el=&quot;duplicates&quot; disabled&amp;gt;&amp;lt;span&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;自动确认内容重复（duplicate）与同名不同扩展名（exists-normalized）警告&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;span class=&quot;bu-note&quot;&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;exists-normalized：站内已有同名但扩展名不同的文件（如已有 X.jpg 时上传 X.png）。完全同名文件仍会跳过；不修改已有文件说明。&lt;/ins&gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div class=&amp;quot;bu-fields&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;lt;div class=&amp;quot;bu-fields&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     &amp;lt;label&amp;gt;统一文件说明（维基语法）&amp;lt;textarea data-el=&amp;quot;description&amp;quot; placeholder=&amp;quot;填写真实来源、作者和授权说明。许可模板需使用本站已有且确实适用的模板。&amp;quot; disabled&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     &amp;lt;label&amp;gt;统一文件说明（维基语法）&amp;lt;textarea data-el=&amp;quot;description&amp;quot; placeholder=&amp;quot;填写真实来源、作者和授权说明。许可模板需使用本站已有且确实适用的模板。&amp;quot; disabled&amp;gt;&amp;lt;/textarea&amp;gt;&amp;lt;/label&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l477&quot;&gt;第477行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第470行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         async function inspectTarget(item, run) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         async function inspectTarget(item, run) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var name = item.target.trim();&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var name = item.target.trim();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!name || /[\\/:#&amp;lt;&amp;gt;\[\]|{}\u0000-\u001f\u007f]/.test(name) || !/\.[^.\s]+$/.test(name)) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!name || /[&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;\&lt;/ins&gt;\\/:#&amp;lt;&amp;gt;\[\]|{}\u0000-\u001f\u007f]/.test(name) || !/\.[^.\s]+$/.test(name)) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 throw userError(&amp;#039;目标名需包含扩展名，不能含路径、命名空间或非法字符（如 / : # [ ]）。&amp;#039;);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 throw userError(&amp;#039;目标名需包含扩展名，不能含路径、命名空间或非法字符（如 / : # [ ]）。&amp;#039;);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l519&quot;&gt;第519行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第512行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 item.target = upload.filename || item.target;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 item.target = upload.filename || item.target;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 item.autoConfirmed = autoConfirmed;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 item.autoConfirmed = autoConfirmed;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 state(item, &#039;success&#039;, autoConfirmed ? &#039;成功 · &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;内容重复已自动确认&lt;/del&gt;&#039; : &#039;成功&#039;);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 state(item, &#039;success&#039;, autoConfirmed ? &#039;成功 · &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;服务器警告已自动确认&lt;/ins&gt;&#039; : &#039;成功&#039;);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 return true;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 return true;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l566&quot;&gt;第566行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第559行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (typeof upload.filekey === &amp;#039;string&amp;#039; &amp;amp;&amp;amp; upload.filekey) { item.stashKey = upload.filekey; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (typeof upload.filekey === &amp;#039;string&amp;#039; &amp;amp;&amp;amp; upload.filekey) { item.stashKey = upload.filekey; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var keys = warningKeys(upload);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var keys = warningKeys(upload);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;onlyDuplicate &lt;/del&gt;= keys.length &amp;gt; 0 &amp;amp;&amp;amp; keys.every(function (key) { return key === &#039;duplicate&#039;; });&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            // 可自动确认的警告：duplicate（内容重复）、exists-normalized（已有同名但扩展名不同的文件）。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!run.settings.duplicates || !&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;onlyDuplicate&lt;/del&gt;) { recordWarning(item, upload); return; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            // 其余警告（完全同名 exists、曾删除 deleted、非法文件名等）仍需人工处理。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;autoConfirmable &lt;/ins&gt;= keys.length &amp;gt; 0 &amp;amp;&amp;amp; keys.every(function (key) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                &lt;/ins&gt;return key === &#039;duplicate&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039; || key === &#039;exists-normalized&lt;/ins&gt;&#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            &lt;/ins&gt;});&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!run.settings.duplicates || !&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;autoConfirmable&lt;/ins&gt;) { recordWarning(item, upload); return; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!item.stashKey) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!item.stashKey) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 recordWarning(item, upload, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;只有内容重复警告，但服务器未返回 &lt;/del&gt;filekey，无法安全自动确认。&#039;);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 recordWarning(item, upload, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;存在可自动确认的警告，但服务器未返回 &lt;/ins&gt;filekey，无法安全自动确认。&#039;);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 return;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 return;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             // &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;自动处理 duplicate，而不是对首次请求无条件设置 ignorewarnings=1。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             // &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;自动确认前再查一次目标，并用本页互斥表防止多个 &lt;/ins&gt;worker 同时发布同一名称。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            // 再查同名目标，并用本页互斥表防止多个 &lt;/del&gt;worker 同时发布同一名称。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             // 跨客户端竞态仍需服务器 reupload &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;权限控制；API &lt;/ins&gt;没有逐项忽略参数。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             // 跨客户端竞态仍需服务器 reupload &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;权限控制，详见 README；API &lt;/del&gt;没有逐项忽略参数。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             phase(item, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;存在可自动确认的警告，先再次检查目标……&lt;/ins&gt;&#039;, null);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             phase(item, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;内容重复：自动确认前再次检查目标……&lt;/del&gt;&#039;, null);&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!await inspectTarget(item, run)) { return; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!await inspectTarget(item, run)) { return; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             phase(item, &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;正在自动确认内容重复并发布……&lt;/del&gt;&#039;, null);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             phase(item, &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;正在自动确认并发布……&lt;/ins&gt;&#039;, null);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var confirm = uploadParameters(item, run);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             var confirm = uploadParameters(item, run);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             confirm.filekey = item.stashKey;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             confirm.filekey = item.stashKey;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l635&quot;&gt;第635行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第631行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             session = run; busy = true;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             session = run; busy = true;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             notice(&amp;#039;正在处理 &amp;#039; + number(pending.length) + &amp;#039; 项，并发上限 &amp;#039; + settings.concurrency + &amp;#039;。&amp;#039; +&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             notice(&amp;#039;正在处理 &amp;#039; + number(pending.length) + &amp;#039; 项，并发上限 &amp;#039; + settings.concurrency + &amp;#039;。&amp;#039; +&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 (settings.duplicates ? &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;仅 &lt;/del&gt;duplicate &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;内容重复警告会自动确认。&lt;/del&gt;&#039; : &#039;所有上传警告均需人工处理。&#039;) +&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 (settings.duplicates ? &#039;duplicate &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;与 exists-normalized 警告会自动确认。&lt;/ins&gt;&#039; : &#039;所有上传警告均需人工处理。&#039;) +&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;#039;\n不要关闭页面；如触发限流会统一等待，不会通过增加并发绕过。&amp;#039;);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 &amp;#039;\n不要关闭页面；如触发限流会统一等待，不会通过增加并发绕过。&amp;#039;);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             flushRender();&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             flushRender();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l744&quot;&gt;第744行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第740行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         api = new mw.Api({&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         api = new mw.Api({&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             parameters: { formatversion: 2, errorformat: &amp;#039;plaintext&amp;#039;, assert: &amp;#039;user&amp;#039;, assertuser: userName, maxlag: 5 },&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             parameters: { formatversion: 2, errorformat: &amp;#039;plaintext&amp;#039;, assert: &amp;#039;user&amp;#039;, assertuser: userName, maxlag: 5 },&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             ajax: { headers: { &#039;Api-User-Agent&#039;: &#039;MediaWikiBatchUpload&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;/2.0.0 &lt;/del&gt;(&#039; + new URL(mw.util.getUrl(mw.config.get(&#039;wgPageName&#039;)), window.location.href).href + &#039;)&#039; } }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             ajax: { headers: { &#039;Api-User-Agent&#039;: &#039;MediaWikiBatchUpload (&#039; + new URL(mw.util.getUrl(mw.config.get(&#039;wgPageName&#039;)), window.location.href).href + &#039;)&#039; } }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         });&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         });&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         request(api.get({ action: &amp;#039;query&amp;#039;, meta: &amp;#039;userinfo&amp;#039;, uiprop: &amp;#039;rights&amp;#039; })).then(function (data) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         request(api.get({ action: &amp;#039;query&amp;#039;, meta: &amp;#039;userinfo&amp;#039;, uiprop: &amp;#039;rights&amp;#039; })).then(function (data) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l751&quot;&gt;第751行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第747行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!info.rights.includes(&amp;#039;upload&amp;#039;)) { notice(&amp;#039;当前账号没有 upload 权限。站点脚本不能授予上传权限。&amp;#039;); return; }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             if (!info.rights.includes(&amp;#039;upload&amp;#039;)) { notice(&amp;#039;当前账号没有 upload 权限。站点脚本不能授予上传权限。&amp;#039;); return; }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             ready = true;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             ready = true;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             notice(&#039;当前账号：&#039; + userName + &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;。内容重复默认自动确认，并发默认 &lt;/del&gt;&#039; + CONFIG.defaultConcurrency + &#039; 路。建议先用 10～20 个小文件测试，再添加大批量文件。&#039;);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             notice(&#039;当前账号：&#039; + userName + &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;。duplicate 与 exists-normalized 警告默认自动确认，并发默认 &lt;/ins&gt;&#039; + CONFIG.defaultConcurrency + &#039; 路。建议先用 10～20 个小文件测试，再添加大批量文件。&#039;);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             flushRender();&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             flushRender();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         }).catch(function (error) { notice(&amp;#039;初始化失败：&amp;#039; + error.message + &amp;#039;。请检查登录状态及 API，再刷新。&amp;#039;); });&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         }).catch(function (error) { notice(&amp;#039;初始化失败：&amp;#039; + error.message + &amp;#039;。请检查登录状态及 API，再刷新。&amp;#039;); });&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}());&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}());&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Wiki-editor-3dtank</name></author>
	</entry>
	<entry>
		<id>https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=11146&amp;oldid=prev</id>
		<title>2026年9月11日 (五) 11:45 Wiki-editor-3dtank</title>
		<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=11146&amp;oldid=prev"/>
		<updated>2026-09-11T11:45:35Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;amp;diff=11146&amp;amp;oldid=10937&quot;&gt;显示更改&lt;/a&gt;</summary>
		<author><name>Wiki-editor-3dtank</name></author>
	</entry>
	<entry>
		<id>https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=10937&amp;oldid=prev</id>
		<title>2026年9月11日 (五) 08:57 Wiki-editor-3dtank</title>
		<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=10937&amp;oldid=prev"/>
		<updated>2026-09-11T08:57:03Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年9月11日 (五) 08:57的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l13&quot;&gt;第13行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第13行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         pageTitle: &amp;#039;批量上传&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         pageTitle: &amp;#039;批量上传&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         containerId: &amp;#039;mw-batch-upload&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         containerId: &amp;#039;mw-batch-upload&amp;#039;,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         maxFiles: &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;200&lt;/del&gt;,       // 本地队列上限，不是服务器限制&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         maxFiles: &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;250&lt;/ins&gt;,       // 本地队列上限，不是服务器限制&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         intervalMs: 500     // 两个文件之间的间隔；上传始终串行&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         intervalMs: 500     // 两个文件之间的间隔；上传始终串行&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     };&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     };&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Wiki-editor-3dtank</name></author>
	</entry>
	<entry>
		<id>https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=10935&amp;oldid=prev</id>
		<title>Wiki-editor-3dtank：​创建页面，内容为“/*  * MediaWiki 批量上传页面 v1.0  * 将本文件全文保存到 MediaWiki:BatchUpload.js（不要加 &lt;script&gt; 标签）。  * 入口：Project:批量上传；加载片段见 Common.js.snippet.js。  * 依赖：MediaWiki 自带 mediawiki.api / mediawiki.util / jQuery；现代浏览器。  * 不使用外部服务、不保存密码、不请求忽略上传警告。  */ (function () {     &#039;use strict&#039;;      var CONFIG = {         namespace: 4,         pageTit…”</title>
		<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchUpload.js&amp;diff=10935&amp;oldid=prev"/>
		<updated>2026-09-11T08:50:46Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“&lt;span class=&quot;autocomment&quot;&gt;* MediaWiki 批量上传页面 v1.0  * 将本文件全文保存到 MediaWiki:BatchUpload.js（不要加 &amp;lt;script&amp;gt; 标签）。  * 入口：Project:批量上传；加载片段见 Common.js.snippet.js。  * 依赖：MediaWiki 自带 mediawiki.api / mediawiki.util / jQuery；现代浏览器。  * 不使用外部服务、不保存密码、不请求忽略上传警告。：​&lt;/span&gt; (function () {     &amp;#039;use strict&amp;#039;;      var CONFIG = {         namespace: 4,         pageTit…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/*&lt;br /&gt;
 * MediaWiki 批量上传页面 v1.0&lt;br /&gt;
 * 将本文件全文保存到 MediaWiki:BatchUpload.js（不要加 &amp;lt;script&amp;gt; 标签）。&lt;br /&gt;
 * 入口：Project:批量上传；加载片段见 Common.js.snippet.js。&lt;br /&gt;
 * 依赖：MediaWiki 自带 mediawiki.api / mediawiki.util / jQuery；现代浏览器。&lt;br /&gt;
 * 不使用外部服务、不保存密码、不请求忽略上传警告。&lt;br /&gt;
 */&lt;br /&gt;
(function () {&lt;br /&gt;
    &amp;#039;use strict&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
    var CONFIG = {&lt;br /&gt;
        namespace: 4,&lt;br /&gt;
        pageTitle: &amp;#039;批量上传&amp;#039;,&lt;br /&gt;
        containerId: &amp;#039;mw-batch-upload&amp;#039;,&lt;br /&gt;
        maxFiles: 200,       // 本地队列上限，不是服务器限制&lt;br /&gt;
        intervalMs: 500     // 两个文件之间的间隔；上传始终串行&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    if (mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;) !== CONFIG.namespace ||&lt;br /&gt;
        mw.config.get(&amp;#039;wgTitle&amp;#039;) !== CONFIG.pageTitle ||&lt;br /&gt;
        mw.config.get(&amp;#039;wgAction&amp;#039;) !== &amp;#039;view&amp;#039; ||&lt;br /&gt;
        mw.config.get(&amp;#039;wgDiffNewId&amp;#039;)) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    mw.loader.using([&amp;#039;mediawiki.api&amp;#039;, &amp;#039;mediawiki.util&amp;#039;]).then(function () {&lt;br /&gt;
        jQuery(function () {&lt;br /&gt;
            var root = document.getElementById(CONFIG.containerId);&lt;br /&gt;
            if (!root || root.dataset.batchUploadReady) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            root.dataset.batchUploadReady = &amp;#039;1&amp;#039;;&lt;br /&gt;
            mount(root);&lt;br /&gt;
        });&lt;br /&gt;
    }, function () {&lt;br /&gt;
        jQuery(function () {&lt;br /&gt;
            var root = document.getElementById(CONFIG.containerId);&lt;br /&gt;
            if (root) {&lt;br /&gt;
                root.textContent = &amp;#039;无法加载 MediaWiki API 模块。请强制刷新，或联系界面管理员。&amp;#039;;&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    function mount(root) {&lt;br /&gt;
        mw.util.addCSS([&lt;br /&gt;
            &amp;#039;#mw-batch-upload{--bu-border:var(--border-color-subtle,#c8ccd1);color:var(--color-base,#202122);font-size:14px;line-height:1.6;margin:1em 0}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload *{box-sizing:border-box}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-panel{border:1px solid var(--bu-border);border-radius:8px;padding:20px;background:var(--background-color-base,#fff)}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-heading{font-size:21px;font-weight:700;margin:0 0 6px}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-note{color:var(--color-subtle,#54595d);margin:6px 0 12px;font-size:13px}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-drop{padding:24px 16px;text-align:center;border:2px dashed var(--bu-border);border-radius:6px;margin:16px 0;background:var(--background-color-interactive-subtle,#f8f9fa)}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-drop.bu-over{border-color:#36c;background:#eaf3ff;color:#202122}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-fields{display:grid;grid-template-columns:2fr 1fr;gap:16px;margin-bottom:14px}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload label{display:block;font-weight:600}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload input[type=text],#mw-batch-upload textarea{width:100%;padding:8px;border:1px solid var(--bu-border);border-radius:4px;color:inherit;background:var(--background-color-base,#fff);font:inherit;font-weight:400}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload textarea{min-height:100px;resize:vertical}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-inline{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:8px 0 16px}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-inline input{flex:1;min-width:140px}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload button{padding:7px 13px;border:1px solid var(--bu-border);border-radius:4px;font:inherit;font-weight:600;cursor:pointer;background:var(--background-color-interactive,#eaecf0);color:inherit}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload button.bu-primary{background:#36c;border-color:#36c;color:#fff}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload button:disabled{opacity:.5;cursor:not-allowed}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload button:focus-visible,#mw-batch-upload input:focus-visible,#mw-batch-upload textarea:focus-visible{outline:2px solid #36c;outline-offset:2px}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-toolbar{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-message{padding:10px 12px;margin:10px 0;border-left:3px solid #36c;background:var(--background-color-interactive-subtle,#f8f9fa);white-space:pre-wrap;overflow-wrap:anywhere}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-scroll{overflow-x:auto}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload table{width:100%;min-width:630px;border-collapse:collapse;margin-top:12px}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload th,#mw-batch-upload td{padding:10px 8px;border-bottom:1px solid var(--bu-border);text-align:left;vertical-align:top}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload th{font-weight:600;background:var(--background-color-interactive-subtle,#f8f9fa)}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-original{width:23%;overflow-wrap:anywhere}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-target{width:31%}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-result{width:36%;overflow-wrap:anywhere}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-size{font-size:12px;color:var(--color-subtle,#54595d)}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-status{white-space:pre-wrap}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload tr[data-state=success] .bu-status{color:var(--color-success,#14866d)}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload tr[data-state=warning] .bu-status{color:var(--color-warning,#8b5a00)}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload tr[data-state=failed] .bu-status{color:var(--color-error,#b32424)}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload progress{display:block;width:100%;height:8px;accent-color:#36c;margin:7px 0}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload .bu-empty{text-align:center;color:var(--color-subtle,#54595d);padding:24px}&amp;#039;,&lt;br /&gt;
            &amp;#039;#mw-batch-upload [hidden]{display:none!important}&amp;#039;,&lt;br /&gt;
            &amp;#039;@media(max-width:650px){#mw-batch-upload .bu-fields{grid-template-columns:1fr}#mw-batch-upload .bu-panel{padding:14px}}&amp;#039;&lt;br /&gt;
        ].join(&amp;#039;\n&amp;#039;));&lt;br /&gt;
&lt;br /&gt;
        // HTML 全部为静态字符串。文件名、API 错误、用户输入只以 textContent/value 写入。&lt;br /&gt;
        root.innerHTML = `&lt;br /&gt;
            &amp;lt;section class=&amp;quot;bu-panel&amp;quot; aria-label=&amp;quot;批量上传文件&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;bu-heading&amp;quot;&amp;gt;批量上传文件&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;p class=&amp;quot;bu-note&amp;quot;&amp;gt;上传到当前 Wiki，使用当前账号的权限。遇到警告不自动确认，不主动覆盖已有文件。&amp;lt;/p&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;bu-message&amp;quot; data-el=&amp;quot;message&amp;quot; role=&amp;quot;status&amp;quot; aria-live=&amp;quot;polite&amp;quot;&amp;gt;正在检查登录状态和上传权限……&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;bu-drop&amp;quot; data-el=&amp;quot;drop&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;button type=&amp;quot;button&amp;quot; data-el=&amp;quot;choose&amp;quot; disabled&amp;gt;选择多个文件&amp;lt;/button&amp;gt;&lt;br /&gt;
                    &amp;lt;span&amp;gt; 或将文件拖到这里&amp;lt;/span&amp;gt;&lt;br /&gt;
                    &amp;lt;input type=&amp;quot;file&amp;quot; multiple hidden data-el=&amp;quot;files&amp;quot; aria-label=&amp;quot;选择待上传文件&amp;quot; disabled&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;bu-note&amp;quot;&amp;gt;可以分多次添加。类型和大小由本站设置决定；本工具不支持目录或分片上传。&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;bu-fields&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;label&amp;gt;统一文件说明（维基语法）&lt;br /&gt;
                        &amp;lt;textarea data-el=&amp;quot;description&amp;quot; placeholder=&amp;quot;填写来源、作者和授权说明。若使用许可模板，请填写本站已有、且确实适用的模板。&amp;quot; disabled&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
                    &amp;lt;/label&amp;gt;&lt;br /&gt;
                    &amp;lt;label&amp;gt;分类（可选，每行一个名称）&lt;br /&gt;
                        &amp;lt;textarea data-el=&amp;quot;categories&amp;quot; placeholder=&amp;quot;活动照片&amp;amp;#10;2026年资料&amp;quot; disabled&amp;gt;&amp;lt;/textarea&amp;gt;&lt;br /&gt;
                    &amp;lt;/label&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;label for=&amp;quot;bu-prefix&amp;quot;&amp;gt;文件名前缀（可选）&amp;lt;/label&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;bu-inline&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;input id=&amp;quot;bu-prefix&amp;quot; data-el=&amp;quot;prefix&amp;quot; type=&amp;quot;text&amp;quot; placeholder=&amp;quot;例如：项目A-&amp;quot; disabled&amp;gt;&lt;br /&gt;
                    &amp;lt;button type=&amp;quot;button&amp;quot; data-el=&amp;quot;applyPrefix&amp;quot; disabled&amp;gt;应用到未成功项&amp;lt;/button&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;p class=&amp;quot;bu-note&amp;quot;&amp;gt;应用前缀会按“前缀 + 原始文件名”重建未成功项的名称，替换手工改名；不会重复叠加前缀。请保留正确的扩展名。&amp;lt;/p&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;bu-toolbar&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;bu-primary&amp;quot; data-el=&amp;quot;start&amp;quot; disabled&amp;gt;开始上传&amp;lt;/button&amp;gt;&lt;br /&gt;
                    &amp;lt;button type=&amp;quot;button&amp;quot; data-el=&amp;quot;pause&amp;quot; disabled&amp;gt;本项完成后暂停&amp;lt;/button&amp;gt;&lt;br /&gt;
                    &amp;lt;button type=&amp;quot;button&amp;quot; data-el=&amp;quot;retry&amp;quot; disabled&amp;gt;重试失败 / 警告项&amp;lt;/button&amp;gt;&lt;br /&gt;
                    &amp;lt;button type=&amp;quot;button&amp;quot; data-el=&amp;quot;clear&amp;quot; disabled&amp;gt;清空列表&amp;lt;/button&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div data-el=&amp;quot;summary&amp;quot; role=&amp;quot;status&amp;quot; aria-live=&amp;quot;polite&amp;quot;&amp;gt;尚未选择文件&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;progress data-el=&amp;quot;overall&amp;quot; max=&amp;quot;1&amp;quot; value=&amp;quot;0&amp;quot; aria-label=&amp;quot;处理进度（按文件数量）&amp;quot;&amp;gt;&amp;lt;/progress&amp;gt;&lt;br /&gt;
                &amp;lt;div class=&amp;quot;bu-scroll&amp;quot;&amp;gt;&lt;br /&gt;
                    &amp;lt;table&amp;gt;&lt;br /&gt;
                        &amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;本地文件&amp;lt;/th&amp;gt;&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;目标文件名&amp;lt;/th&amp;gt;&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;状态 / 传输进度&amp;lt;/th&amp;gt;&amp;lt;th scope=&amp;quot;col&amp;quot;&amp;gt;操作&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&lt;br /&gt;
                        &amp;lt;tbody data-el=&amp;quot;rows&amp;quot;&amp;gt;&amp;lt;/tbody&amp;gt;&lt;br /&gt;
                    &amp;lt;/table&amp;gt;&lt;br /&gt;
                    &amp;lt;div class=&amp;quot;bu-empty&amp;quot; data-el=&amp;quot;empty&amp;quot;&amp;gt;选择文件后，会在这里显示上传队列。&amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;p class=&amp;quot;bu-note&amp;quot;&amp;gt;进度条表示传输或已处理数量，不代表上传成功；以“成功”状态为准。暂停不会中断正在处理的文件。清空列表不会删除站内文件。&amp;lt;/p&amp;gt;&lt;br /&gt;
            &amp;lt;/section&amp;gt;`;&lt;br /&gt;
&lt;br /&gt;
        var ui = {};&lt;br /&gt;
        root.querySelectorAll(&amp;#039;[data-el]&amp;#039;).forEach(function (el) { ui[el.dataset.el] = el; });&lt;br /&gt;
        var items = [];&lt;br /&gt;
        var busy = false;&lt;br /&gt;
        var pauseRequested = false;&lt;br /&gt;
        var ready = false;&lt;br /&gt;
        var userName = mw.config.get(&amp;#039;wgUserName&amp;#039;);&lt;br /&gt;
        var api;&lt;br /&gt;
        var fileNamespace = (mw.config.get(&amp;#039;wgFormattedNamespaces&amp;#039;) || {})[6] || &amp;#039;File&amp;#039;;&lt;br /&gt;
        var categoryNamespace = (mw.config.get(&amp;#039;wgFormattedNamespaces&amp;#039;) || {})[14] || &amp;#039;Category&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
        function message(text) { ui.message.textContent = text; }&lt;br /&gt;
        function fileUrl(name) { return mw.util.getUrl(fileNamespace + &amp;#039;:&amp;#039; + name); }&lt;br /&gt;
        function sleep(ms) { return new Promise(function (resolve) { window.setTimeout(resolve, ms); }); }&lt;br /&gt;
        function sizeText(bytes) {&lt;br /&gt;
            if (bytes &amp;lt; 1024) { return bytes + &amp;#039; B&amp;#039;; }&lt;br /&gt;
            if (bytes &amp;lt; 1048576) { return (bytes / 1024).toFixed(1) + &amp;#039; KiB&amp;#039;; }&lt;br /&gt;
            return (bytes / 1048576).toFixed(1) + &amp;#039; MiB&amp;#039;;&lt;br /&gt;
        }&lt;br /&gt;
        function counts() {&lt;br /&gt;
            var result = { queued: 0, uploading: 0, success: 0, warning: 0, failed: 0 };&lt;br /&gt;
            items.forEach(function (item) { result[item.state]++; });&lt;br /&gt;
            return result;&lt;br /&gt;
        }&lt;br /&gt;
        function refresh() {&lt;br /&gt;
            var c = counts();&lt;br /&gt;
            var locked = busy || !ready;&lt;br /&gt;
            [&amp;#039;choose&amp;#039;, &amp;#039;files&amp;#039;, &amp;#039;description&amp;#039;, &amp;#039;categories&amp;#039;, &amp;#039;prefix&amp;#039;].forEach(function (key) {&lt;br /&gt;
                ui[key].disabled = locked;&lt;br /&gt;
            });&lt;br /&gt;
            ui.applyPrefix.disabled = locked || !items.some(function (item) { return item.state !== &amp;#039;success&amp;#039;; });&lt;br /&gt;
            ui.start.disabled = locked || !c.queued;&lt;br /&gt;
            ui.pause.disabled = !busy || pauseRequested;&lt;br /&gt;
            ui.retry.disabled = locked || !(c.failed + c.warning);&lt;br /&gt;
            ui.clear.disabled = busy || !items.length;&lt;br /&gt;
            ui.empty.hidden = items.length &amp;gt; 0;&lt;br /&gt;
            ui.overall.max = Math.max(items.length, 1);&lt;br /&gt;
            ui.overall.value = c.success + c.warning + c.failed;&lt;br /&gt;
            ui.summary.textContent = items.length ?&lt;br /&gt;
                &amp;#039;共 &amp;#039; + items.length + &amp;#039; 项 · 成功 &amp;#039; + c.success + &amp;#039; · 警告 &amp;#039; + c.warning +&lt;br /&gt;
                &amp;#039; · 失败 &amp;#039; + c.failed + &amp;#039; · 待处理 &amp;#039; + c.queued + (busy ? &amp;#039; · 正在处理&amp;#039; : &amp;#039;&amp;#039;) : &amp;#039;尚未选择文件&amp;#039;;&lt;br /&gt;
            items.forEach(function (item) {&lt;br /&gt;
                item.input.disabled = locked || item.state === &amp;#039;success&amp;#039;;&lt;br /&gt;
                item.remove.disabled = busy;&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
        function setState(item, state, text) {&lt;br /&gt;
            item.state = state;&lt;br /&gt;
            item.row.dataset.state = state;&lt;br /&gt;
            item.status.textContent = text;&lt;br /&gt;
            item.progress.hidden = state !== &amp;#039;uploading&amp;#039; &amp;amp;&amp;amp; state !== &amp;#039;success&amp;#039;;&lt;br /&gt;
            if (state === &amp;#039;queued&amp;#039;) { item.progress.value = 0; }&lt;br /&gt;
            if (state === &amp;#039;success&amp;#039;) { item.progress.value = 100; }&lt;br /&gt;
            item.link.hidden = state !== &amp;#039;success&amp;#039; &amp;amp;&amp;amp; state !== &amp;#039;warning&amp;#039; &amp;amp;&amp;amp; state !== &amp;#039;failed&amp;#039;;&lt;br /&gt;
            item.link.href = fileUrl(item.input.value.trim());&lt;br /&gt;
            item.link.textContent = state === &amp;#039;success&amp;#039; ? &amp;#039;查看文件&amp;#039; : &amp;#039;检查目标页面&amp;#039;;&lt;br /&gt;
            refresh();&lt;br /&gt;
        }&lt;br /&gt;
        function resetItem(item) {&lt;br /&gt;
            if (item.state !== &amp;#039;success&amp;#039;) { setState(item, &amp;#039;queued&amp;#039;, &amp;#039;等待上传&amp;#039;); }&lt;br /&gt;
        }&lt;br /&gt;
        function addFiles(files) {&lt;br /&gt;
            if (busy || !ready) { return; }&lt;br /&gt;
            var added = 0;&lt;br /&gt;
            var excess = 0;&lt;br /&gt;
            Array.from(files).forEach(function (file) {&lt;br /&gt;
                if (items.length &amp;gt;= CONFIG.maxFiles) { excess++; return; }&lt;br /&gt;
                var tr = document.createElement(&amp;#039;tr&amp;#039;);&lt;br /&gt;
                tr.dataset.state = &amp;#039;queued&amp;#039;;&lt;br /&gt;
                tr.innerHTML = &amp;#039;&amp;lt;td class=&amp;quot;bu-original&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;bu-name&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;div class=&amp;quot;bu-size&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&amp;#039; +&lt;br /&gt;
                    &amp;#039;&amp;lt;td class=&amp;quot;bu-target&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;#039; +&lt;br /&gt;
                    &amp;#039;&amp;lt;td class=&amp;quot;bu-result&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;bu-status&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;progress max=&amp;quot;100&amp;quot; value=&amp;quot;0&amp;quot; hidden&amp;gt;&amp;lt;/progress&amp;gt;&amp;lt;a target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot; hidden&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&amp;#039; +&lt;br /&gt;
                    &amp;#039;&amp;lt;td&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; title=&amp;quot;只移出队列，不删除站内文件&amp;quot;&amp;gt;移除&amp;lt;/button&amp;gt;&amp;lt;/td&amp;gt;&amp;#039;;&lt;br /&gt;
                tr.querySelector(&amp;#039;.bu-name&amp;#039;).textContent = file.name;&lt;br /&gt;
                tr.querySelector(&amp;#039;.bu-size&amp;#039;).textContent = sizeText(file.size);&lt;br /&gt;
                var item = {&lt;br /&gt;
                    file: file, state: &amp;#039;queued&amp;#039;, row: tr,&lt;br /&gt;
                    input: tr.querySelector(&amp;#039;input&amp;#039;), status: tr.querySelector(&amp;#039;.bu-status&amp;#039;),&lt;br /&gt;
                    progress: tr.querySelector(&amp;#039;progress&amp;#039;), link: tr.querySelector(&amp;#039;a&amp;#039;),&lt;br /&gt;
                    remove: tr.querySelector(&amp;#039;button&amp;#039;)&lt;br /&gt;
                };&lt;br /&gt;
                item.input.value = ui.prefix.value + file.name;&lt;br /&gt;
                item.input.setAttribute(&amp;#039;aria-label&amp;#039;, file.name + &amp;#039; 的目标文件名&amp;#039;);&lt;br /&gt;
                item.progress.setAttribute(&amp;#039;aria-label&amp;#039;, file.name + &amp;#039; 的传输进度&amp;#039;);&lt;br /&gt;
                item.status.textContent = &amp;#039;等待上传&amp;#039;;&lt;br /&gt;
                item.input.addEventListener(&amp;#039;input&amp;#039;, function () { resetItem(item); });&lt;br /&gt;
                item.remove.addEventListener(&amp;#039;click&amp;#039;, function () {&lt;br /&gt;
                    if (busy) { return; }&lt;br /&gt;
                    items = items.filter(function (other) { return other !== item; });&lt;br /&gt;
                    tr.remove();&lt;br /&gt;
                    refresh();&lt;br /&gt;
                });&lt;br /&gt;
                items.push(item);&lt;br /&gt;
                ui.rows.appendChild(tr);&lt;br /&gt;
                added++;&lt;br /&gt;
            });&lt;br /&gt;
            message(&amp;#039;已添加 &amp;#039; + added + &amp;#039; 个文件。请检查文件名、来源和授权说明后点击“开始上传”。&amp;#039; +&lt;br /&gt;
                (excess ? &amp;#039;\n另有 &amp;#039; + excess + &amp;#039; 个文件未添加：本地队列上限为 &amp;#039; + CONFIG.maxFiles + &amp;#039; 个。&amp;#039; : &amp;#039;&amp;#039;));&lt;br /&gt;
            refresh();&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // 将 mw.Api 的多参数拒绝转换为 Error；不丢失服务器的错误信息。&lt;br /&gt;
        function apiError(code, data) {&lt;br /&gt;
            var raw = data &amp;amp;&amp;amp; (data.error || (data.errors &amp;amp;&amp;amp; data.errors[0]));&lt;br /&gt;
            var text = raw &amp;amp;&amp;amp; (raw.info || raw.text || raw[&amp;#039;*&amp;#039;]);&lt;br /&gt;
            var status = data &amp;amp;&amp;amp; data.xhr &amp;amp;&amp;amp; data.xhr.status;&lt;br /&gt;
            if (code === &amp;#039;http&amp;#039;) {&lt;br /&gt;
                text = &amp;#039;网络 / HTTP 异常&amp;#039; + (status ? &amp;#039;（HTTP &amp;#039; + status + &amp;#039;）&amp;#039; : &amp;#039;&amp;#039;) +&lt;br /&gt;
                    &amp;#039;。若上传请求已发出，结果可能未确认；请先检查目标页面，再决定是否重试。&amp;#039;;&lt;br /&gt;
            }&lt;br /&gt;
            var error = new Error(text || String(code || &amp;#039;未知 API 错误&amp;#039;));&lt;br /&gt;
            error.code = String(code || &amp;#039;unknown&amp;#039;);&lt;br /&gt;
            error.stopQueue = code === &amp;#039;http&amp;#039; || /assert|badtoken|notloggedin|read.?only|upload.*disabled|ratelimited|maxlag|permissiondenied|blocked/i.test(error.code);&lt;br /&gt;
            return error;&lt;br /&gt;
        }&lt;br /&gt;
        function request(jqPromise) {&lt;br /&gt;
            return new Promise(function (resolve, reject) {&lt;br /&gt;
                jqPromise.done(resolve).fail(function (code, data) { reject(apiError(code, data)); });&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
        function warningError(text) {&lt;br /&gt;
            var error = new Error(text);&lt;br /&gt;
            error.isWarning = true;&lt;br /&gt;
            return error;&lt;br /&gt;
        }&lt;br /&gt;
        function warningText(warnings) {&lt;br /&gt;
            var labels = {&lt;br /&gt;
                exists: &amp;#039;同名文件已存在&amp;#039;,&lt;br /&gt;
                &amp;#039;exists-normalized&amp;#039;: &amp;#039;规范化后的文件名已存在&amp;#039;,&lt;br /&gt;
                &amp;#039;page-exists&amp;#039;: &amp;#039;同名文件说明页已存在&amp;#039;,&lt;br /&gt;
                duplicate: &amp;#039;相同内容的文件已存在&amp;#039;,&lt;br /&gt;
                &amp;#039;no-change&amp;#039;: &amp;#039;内容与现有文件一致&amp;#039;,&lt;br /&gt;
                duplicateversions: &amp;#039;内容与已有历史版本一致&amp;#039;,&lt;br /&gt;
                &amp;#039;was-deleted&amp;#039;: &amp;#039;这个文件名曾被删除&amp;#039;,&lt;br /&gt;
                &amp;#039;duplicate-archive&amp;#039;: &amp;#039;相同内容的文件曾被删除&amp;#039;,&lt;br /&gt;
                badfilename: &amp;#039;文件名需要调整&amp;#039;,&lt;br /&gt;
                &amp;#039;bad-prefix&amp;#039;: &amp;#039;文件名前缀不符合站点要求&amp;#039;,&lt;br /&gt;
                &amp;#039;large-file&amp;#039;: &amp;#039;文件大小触发站点警告&amp;#039;&lt;br /&gt;
            };&lt;br /&gt;
            return Object.keys(warnings || {}).map(function (key) {&lt;br /&gt;
                var value = warnings[key];&lt;br /&gt;
                var detail = typeof value === &amp;#039;string&amp;#039; ? value : JSON.stringify(value);&lt;br /&gt;
                return (labels[key] || &amp;#039;站点警告&amp;#039;) + &amp;#039; [&amp;#039; + key + &amp;#039;]&amp;#039; + (detail ? &amp;#039;：&amp;#039; + detail.slice(0, 500) : &amp;#039;&amp;#039;);&lt;br /&gt;
            }).join(&amp;#039;\n&amp;#039;) || &amp;#039;服务器返回上传警告。&amp;#039;;&lt;br /&gt;
        }&lt;br /&gt;
        function pageText() {&lt;br /&gt;
            var categories = [];&lt;br /&gt;
            ui.categories.value.split(/\r?\n/).forEach(function (line) {&lt;br /&gt;
                var name = line.trim();&lt;br /&gt;
                if (!name) { return; }&lt;br /&gt;
                [categoryNamespace, &amp;#039;Category&amp;#039;, &amp;#039;分类&amp;#039;, &amp;#039;分類&amp;#039;].forEach(function (ns) {&lt;br /&gt;
                    if (name.slice(0, ns.length + 1).toLowerCase() === (ns + &amp;#039;:&amp;#039;).toLowerCase()) {&lt;br /&gt;
                        name = name.slice(ns.length + 1).trim();&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
                if (!name || /[\[\]{}|&amp;lt;&amp;gt;#\u0000-\u001f\u007f]/.test(name)) {&lt;br /&gt;
                    throw new Error(&amp;#039;分类请每行只填一个名称，不要填写 [[Category:…]] 等维基代码。&amp;#039;);&lt;br /&gt;
                }&lt;br /&gt;
                if (categories.indexOf(name) === -1) { categories.push(name); }&lt;br /&gt;
            });&lt;br /&gt;
            var text = ui.description.value.trim();&lt;br /&gt;
            if (categories.length) {&lt;br /&gt;
                text += (text ? &amp;#039;\n\n&amp;#039; : &amp;#039;&amp;#039;) + categories.map(function (name) {&lt;br /&gt;
                    return &amp;#039;[[&amp;#039; + categoryNamespace + &amp;#039;:&amp;#039; + name + &amp;#039;]]&amp;#039;;&lt;br /&gt;
                }).join(&amp;#039;\n&amp;#039;);&lt;br /&gt;
            }&lt;br /&gt;
            return text;&lt;br /&gt;
        }&lt;br /&gt;
        async function uploadOne(item, text) {&lt;br /&gt;
            var name = item.input.value.trim();&lt;br /&gt;
            if (!name || /[\\/:#&amp;lt;&amp;gt;\[\]|{}\u0000-\u001f\u007f]/.test(name) || !/\.[^.\s]+$/.test(name)) {&lt;br /&gt;
                throw new Error(&amp;#039;目标名称需包含扩展名，且不能包含路径、命名空间或非法字符（如 / : # [ ]）。&amp;#039;);&lt;br /&gt;
            }&lt;br /&gt;
            if (!item.file.size) {&lt;br /&gt;
                throw new Error(&amp;#039;文件为空，或浏览器无法读取。请使用文件选择器选择普通文件，不要拖入文件夹。&amp;#039;);&lt;br /&gt;
            }&lt;br /&gt;
            item.input.value = name;&lt;br /&gt;
            setState(item, &amp;#039;uploading&amp;#039;, &amp;#039;正在检查目标文件名……&amp;#039;);&lt;br /&gt;
            item.progress.removeAttribute(&amp;#039;value&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
            // 同时检查本地文件说明页及共享仓库文件；避免无意遮蔽共享文件。&lt;br /&gt;
            var check = await request(api.get({&lt;br /&gt;
                action: &amp;#039;query&amp;#039;, titles: fileNamespace + &amp;#039;:&amp;#039; + name,&lt;br /&gt;
                prop: &amp;#039;imageinfo&amp;#039;, iiprop: &amp;#039;timestamp&amp;#039;&lt;br /&gt;
            }));&lt;br /&gt;
            var page = check.query &amp;amp;&amp;amp; check.query.pages &amp;amp;&amp;amp; check.query.pages[0];&lt;br /&gt;
            if (!page || page.invalid || page.ns !== 6) {&lt;br /&gt;
                throw new Error(&amp;#039;服务器不接受这个文件名，或未能返回有效的文件页面信息。&amp;#039;);&lt;br /&gt;
            }&lt;br /&gt;
            if (!page.missing || (page.imageinfo &amp;amp;&amp;amp; page.imageinfo.length) ||&lt;br /&gt;
                (page.imagerepository &amp;amp;&amp;amp; page.imagerepository !== &amp;#039;&amp;#039;)) {&lt;br /&gt;
                throw warningError(&amp;#039;目标文件或文件说明页已存在（可能来自共享仓库）。未发送文件；请改名或使用已有文件。&amp;#039;);&lt;br /&gt;
            }&lt;br /&gt;
            // 使用服务器规范化的首字母、空格与名称。&lt;br /&gt;
            name = page.title.slice(page.title.indexOf(&amp;#039;:&amp;#039;) + 1);&lt;br /&gt;
            item.input.value = name;&lt;br /&gt;
            item.progress.value = 0;&lt;br /&gt;
            item.status.textContent = &amp;#039;正在获取令牌并上传……&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
            var result = await request(api.postWithToken(&amp;#039;csrf&amp;#039;, {&lt;br /&gt;
                action: &amp;#039;upload&amp;#039;, filename: name, file: item.file,&lt;br /&gt;
                text: text, comment: &amp;#039;使用批量上传页面上传&amp;#039;, watchlist: &amp;#039;nochange&amp;#039;&lt;br /&gt;
                // 刻意不传 ignorewarnings，也不根据 filekey 自动确认警告。&lt;br /&gt;
            }, {&lt;br /&gt;
                contentType: &amp;#039;multipart/form-data&amp;#039;, // mw.Api 会构造 FormData 并设置 boundary&lt;br /&gt;
                timeout: 0,&lt;br /&gt;
                xhr: function () {&lt;br /&gt;
                    var xhr = jQuery.ajaxSettings.xhr();&lt;br /&gt;
                    if (xhr.upload) {&lt;br /&gt;
                        xhr.upload.addEventListener(&amp;#039;progress&amp;#039;, function (event) {&lt;br /&gt;
                            if (event.lengthComputable) {&lt;br /&gt;
                                var percent = Math.min(100, Math.round(event.loaded / event.total * 100));&lt;br /&gt;
                                item.progress.value = percent;&lt;br /&gt;
                                item.status.textContent = percent &amp;lt; 100 ? &amp;#039;正在传输 &amp;#039; + percent + &amp;#039;%&amp;#039; : &amp;#039;传输完成，等待服务器确认……&amp;#039;;&lt;br /&gt;
                            }&lt;br /&gt;
                        });&lt;br /&gt;
                    }&lt;br /&gt;
                    return xhr;&lt;br /&gt;
                }&lt;br /&gt;
            }));&lt;br /&gt;
            var upload = result &amp;amp;&amp;amp; result.upload;&lt;br /&gt;
            // 只以 API 的 Success 为成功；HTTP 200 或传输到 100% 都不是成功确认。&lt;br /&gt;
            if (upload &amp;amp;&amp;amp; upload.result === &amp;#039;Success&amp;#039;) {&lt;br /&gt;
                item.input.value = upload.filename || name;&lt;br /&gt;
                setState(item, &amp;#039;success&amp;#039;, &amp;#039;成功&amp;#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (upload &amp;amp;&amp;amp; (upload.result === &amp;#039;Warning&amp;#039; || upload.warnings)) {&lt;br /&gt;
                throw warningError(warningText(upload.warnings) + &amp;#039;\n本工具没有确认警告，未完成正式发布。&amp;#039;);&lt;br /&gt;
            }&lt;br /&gt;
            var unknown = new Error(&amp;#039;服务器返回了未识别的上传结果。请先检查目标文件页面，不要直接重复上传。&amp;#039;);&lt;br /&gt;
            unknown.stopQueue = true;&lt;br /&gt;
            throw unknown;&lt;br /&gt;
        }&lt;br /&gt;
        async function run() {&lt;br /&gt;
            if (busy || !ready || !items.some(function (item) { return item.state === &amp;#039;queued&amp;#039;; })) { return; }&lt;br /&gt;
            var text;&lt;br /&gt;
            try { text = pageText(); }&lt;br /&gt;
            catch (error) { message(error.message); return; }&lt;br /&gt;
            busy = true;&lt;br /&gt;
            pauseRequested = false;&lt;br /&gt;
            refresh();&lt;br /&gt;
            message(&amp;#039;正在逐个上传。请保持页面打开；“本项完成后暂停”不会中断已发出的请求。&amp;#039;);&lt;br /&gt;
            try {&lt;br /&gt;
                for (var i = 0; i &amp;lt; items.length; i++) {&lt;br /&gt;
                    if (pauseRequested) { break; }&lt;br /&gt;
                    var item = items[i];&lt;br /&gt;
                    if (item.state !== &amp;#039;queued&amp;#039;) { continue; }&lt;br /&gt;
                    try {&lt;br /&gt;
                        await uploadOne(item, text);&lt;br /&gt;
                    } catch (error) {&lt;br /&gt;
                        setState(item, error.isWarning ? &amp;#039;warning&amp;#039; : &amp;#039;failed&amp;#039;,&lt;br /&gt;
                            (error.message || String(error)) + (error.code ? &amp;#039; [&amp;#039; + error.code + &amp;#039;]&amp;#039; : &amp;#039;&amp;#039;));&lt;br /&gt;
                        if (error.stopQueue) { pauseRequested = true; }&lt;br /&gt;
                    }&lt;br /&gt;
                    if (!pauseRequested &amp;amp;&amp;amp; i &amp;lt; items.length - 1) { await sleep(CONFIG.intervalMs); }&lt;br /&gt;
                }&lt;br /&gt;
            } finally {&lt;br /&gt;
                busy = false;&lt;br /&gt;
                refresh();&lt;br /&gt;
                message(pauseRequested ?&lt;br /&gt;
                    &amp;#039;队列已暂停。当前请求已返回，未处理项仍在队列中。请检查错误或账号状态，再点击“开始上传”继续；失败项需手动重试。&amp;#039; :&lt;br /&gt;
                    &amp;#039;本轮处理结束。请检查各项状态；成功项不会被本工具再次上传。警告项未自动确认，失败项可在排查后重试。&amp;#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        ui.choose.addEventListener(&amp;#039;click&amp;#039;, function () { ui.files.click(); });&lt;br /&gt;
        ui.files.addEventListener(&amp;#039;change&amp;#039;, function () { addFiles(ui.files.files); ui.files.value = &amp;#039;&amp;#039;; });&lt;br /&gt;
        [&amp;#039;dragenter&amp;#039;, &amp;#039;dragover&amp;#039;].forEach(function (type) {&lt;br /&gt;
            ui.drop.addEventListener(type, function (event) {&lt;br /&gt;
                event.preventDefault();&lt;br /&gt;
                if (ready &amp;amp;&amp;amp; !busy) { ui.drop.classList.add(&amp;#039;bu-over&amp;#039;); }&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
        ui.drop.addEventListener(&amp;#039;dragleave&amp;#039;, function (event) {&lt;br /&gt;
            if (!ui.drop.contains(event.relatedTarget)) { ui.drop.classList.remove(&amp;#039;bu-over&amp;#039;); }&lt;br /&gt;
        });&lt;br /&gt;
        ui.drop.addEventListener(&amp;#039;drop&amp;#039;, function (event) {&lt;br /&gt;
            event.preventDefault();&lt;br /&gt;
            ui.drop.classList.remove(&amp;#039;bu-over&amp;#039;);&lt;br /&gt;
            if (event.dataTransfer) { addFiles(event.dataTransfer.files); }&lt;br /&gt;
        });&lt;br /&gt;
        ui.applyPrefix.addEventListener(&amp;#039;click&amp;#039;, function () {&lt;br /&gt;
            if (busy || !ready) { return; }&lt;br /&gt;
            items.forEach(function (item) {&lt;br /&gt;
                if (item.state !== &amp;#039;success&amp;#039;) { item.input.value = ui.prefix.value + item.file.name; resetItem(item); }&lt;br /&gt;
            });&lt;br /&gt;
            message(&amp;#039;已按“前缀 + 原始文件名”更新未成功项。请检查后再开始上传。&amp;#039;);&lt;br /&gt;
        });&lt;br /&gt;
        ui.start.addEventListener(&amp;#039;click&amp;#039;, function () { run(); });&lt;br /&gt;
        ui.pause.addEventListener(&amp;#039;click&amp;#039;, function () {&lt;br /&gt;
            pauseRequested = true;&lt;br /&gt;
            message(&amp;#039;将在当前文件处理完成后暂停；当前请求不会中止。&amp;#039;);&lt;br /&gt;
            refresh();&lt;br /&gt;
        });&lt;br /&gt;
        ui.retry.addEventListener(&amp;#039;click&amp;#039;, function () {&lt;br /&gt;
            if (busy || !ready) { return; }&lt;br /&gt;
            items.forEach(function (item) {&lt;br /&gt;
                if (item.state === &amp;#039;failed&amp;#039; || item.state === &amp;#039;warning&amp;#039;) { resetItem(item); }&lt;br /&gt;
            });&lt;br /&gt;
            run();&lt;br /&gt;
        });&lt;br /&gt;
        ui.clear.addEventListener(&amp;#039;click&amp;#039;, function () {&lt;br /&gt;
            if (busy) { return; }&lt;br /&gt;
            items = [];&lt;br /&gt;
            ui.rows.textContent = &amp;#039;&amp;#039;;&lt;br /&gt;
            message(&amp;#039;已清空本地列表。此前上传到本站的文件不会被删除。&amp;#039;);&lt;br /&gt;
            refresh();&lt;br /&gt;
        });&lt;br /&gt;
        window.addEventListener(&amp;#039;beforeunload&amp;#039;, function (event) {&lt;br /&gt;
            if (busy || items.some(function (item) { return item.state !== &amp;#039;success&amp;#039;; })) {&lt;br /&gt;
                event.preventDefault();&lt;br /&gt;
                event.returnValue = &amp;#039;&amp;#039;; // 浏览器显示自己的离开页面提示文字&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        if (!window.File || !window.FormData || !window.Promise) {&lt;br /&gt;
            message(&amp;#039;浏览器不支持所需的文件上传功能，请使用较新的 Chrome、Firefox、Edge 或 Safari。&amp;#039;);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        if (!userName) {&lt;br /&gt;
            message(&amp;#039;请先登录，再打开此页面。本工具不提供匿名上传。&amp;#039;);&lt;br /&gt;
            var login = document.createElement(&amp;#039;a&amp;#039;);&lt;br /&gt;
            login.href = mw.util.getUrl(&amp;#039;Special:UserLogin&amp;#039;, { returnto: mw.config.get(&amp;#039;wgPageName&amp;#039;).replace(/_/g, &amp;#039; &amp;#039;) });&lt;br /&gt;
            login.textContent = &amp;#039; 前往登录&amp;#039;;&lt;br /&gt;
            ui.message.appendChild(login);&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        api = new mw.Api({ parameters: {&lt;br /&gt;
            formatversion: 2, errorformat: &amp;#039;plaintext&amp;#039;,&lt;br /&gt;
            assert: &amp;#039;user&amp;#039;, assertuser: userName, maxlag: 5&lt;br /&gt;
        } });&lt;br /&gt;
        request(api.get({ action: &amp;#039;query&amp;#039;, meta: &amp;#039;userinfo&amp;#039;, uiprop: &amp;#039;rights&amp;#039; })).then(function (data) {&lt;br /&gt;
            var info = data.query &amp;amp;&amp;amp; data.query.userinfo;&lt;br /&gt;
            if (!info || !Array.isArray(info.rights)) {&lt;br /&gt;
                throw new Error(&amp;#039;未能确认账号的上传权限，请刷新或联系管理员。&amp;#039;);&lt;br /&gt;
            }&lt;br /&gt;
            if (info.rights.indexOf(&amp;#039;upload&amp;#039;) === -1) {&lt;br /&gt;
                message(&amp;#039;当前账号没有 upload 权限。界面脚本不能授予上传权限，请联系站点管理员。&amp;#039;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            ready = true;&lt;br /&gt;
            message(&amp;#039;当前账号：&amp;#039; + userName + &amp;#039;。请选择文件。建议先用 2～3 个小文件测试。&amp;#039;);&lt;br /&gt;
            refresh();&lt;br /&gt;
        }).catch(function (error) {&lt;br /&gt;
            message(&amp;#039;初始化失败：&amp;#039; + error.message + &amp;#039;。请检查登录状态或 API 是否可用，再刷新页面。&amp;#039;);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;/div&gt;</summary>
		<author><name>Wiki-editor-3dtank</name></author>
	</entry>
</feed>